frontend-slides
PublicRepository: zarazhangrui/frontend-slides
Low Risk with warnings
2 findings
Skill manifest does not include a 'license' field. Specifying a license helps users understand usage terms.
Remediation Add 'license' field to SKILL.md frontmatter (e.g., MIT, Apache-2.0)
Detects protocol manipulation via capability inflation in skill discovery: Perfect
Remediation Review and remove skill discovery abuse pattern
Description
Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.
Skill Files
# Frontend Slides
Create zero-dependency, animation-rich HTML presentations that run entirely in the browser.
## Core Principles
1. **Zero Dependencies** — Single HTML files with inline CSS/JS. No npm, no build tools.
2. **Show, Don't Tell** — Generate visual previews, not abstract choices. People discover what they want by seeing it.
3. **Distinctive Design** — No generic "AI slop." Every presentation must feel custom-crafted.
4. **Progressive Disclosure** — Read lightweight style indexes first. For bold templates, use small preview cards for style previews and load the full `design.md` only after the user picks that template.
5. **Fixed 16:9 Stage (NON-NEGOTIABLE)** — Every deck uses a 1920×1080 slide canvas scaled as a whole to the viewport. Slides must stay 16:9 on every screen, including phones. Do not reflow slide content to fit the device.
## Design Aesthetics
You tend to converge toward generic, "on distribution" outputs. In frontend design, this creates what users call the "AI slop" aesthetic. Avoid this: make creative, distinctive frontends that surprise and delight.
Focus on:
- Typography: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics.
- Color & Theme: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes. Draw from IDE themes and cultural aesthetics for inspiration.
- Motion: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions.
- Backgrounds: Create atmosphere and depth rather than defaulting to solid colors. Layer CSS gradients, use geometric patterns, or add contextual effects that match the overall aesthetic.
Avoid generic AI-generated aesthetics:
- Overused font families (Inter, Roboto, Arial, system fonts)
- Cliched color schemes (particularly purple gradients on white backgrounds)
- Predictable layouts and component patterns
- Cookie-cutter design that lacks context-specific character
Interpret creatively and make unexpected choices that feel genuinely designed for the context. Vary between light and dark themes, different fonts, different aesthetics. You still tend to converge on common choices (Space Grotesk, for example) across generations. Avoid this: it is critical that you think outside the box!
## Fixed Stage Rules
These invariants apply to EVERY slide in EVERY presentation:
- Every deck has a viewport wrapper that fills the browser window.
- Every slide is authored inside a fixed 1920×1080 stage.
- The stage scales uniformly to fit the viewport. It may letterbox/pillarbox; it must not re-layout content.
- Do not use responsive breakpoints to rearrange slide content for phones.
- Use fixed internal slide measurements at the 1920×1080 design size.
- Slide visibility must be controlled by `.active` / `.visible` using `visibility`, `opacity`, and `pointer-events` from `viewport-base.css`. Do not use `display: none` / `display: block` for slide switching; later layout classes such as `.slide-content { display: flex; }` can override them and make every slide visible at once.
- Use `clamp()` only for non-slide UI outside the stage, or for small fallback previews where a full stage is impractical.
- Include `prefers-reduced-motion` support
- Never negate CSS functions directly (`-clamp()`, `-min()`, `-max()` are silently ignored) — use `calc(-1 * clamp(...))` instead
**When generating, read `viewport-base.css` and include its full contents in every presentation.**
### Content Density Modes
Ask the user whether this is primarily a reading deck or a speaking deck, then design around that answer:
| Density mode | Best for | Design behavior |
| ------------- | -------- | --------------- |
| **Low density / speaker-led** | Public talks, keynote-style sharing, live explanation | One idea per slide, large type, strong visual hierarchy, generous negative space, 1-3 bullets max, more slides if needed |
| **High density / reading-first** | Reports, handouts, async review, detailed internal docs | More self-contained slides, structured grids/tables/annotations, 4-8 bullets or 4-6 cards when readable, tighter but still intentional spacing |
Baseline limits still apply: no scrolling, no overflow, no overlapping panels, and no text below comfortable reading size. If content exceeds the selected density mode, split it into more slides instead of shrinking until it becomes cramped.
---
## Phase 0: Detect Mode
Determine what the user wants:
- **Mode A: New Presentation** — Create from scratch. Go to Phase 1.
- **Mode B: PPT Conversion** — Convert a .pptx file. Go to Phase 4.
- **Mode C: Enhancement** — Improve an existing HTML presentation. Read it, understand it, enhance. **Follow Mode C modification rules below.**
### Mode C: Modification Rules
When enhancing existing presentations, fixed-stage fitting is the biggest risk:
1. **Before adding content:** Count existing elements, check against density limits
2. **Adding images:** Fit them inside the 1920×1080 slide canvas. If slide already has max content, split into two slides
3. **Adding text:** Max 4-6 bullets per slide. Exceeds limits? Split into continuation slides
4. **After ANY modification, verify:** the slide stage remains 16:9, no text overflows its card, no panels overlap, and screenshots look correct at 1280×720 plus one phone viewport
5. **Proactively reorganize:** If modifications will cause overflow, automatically split content and inform the user. Don't wait to be asked
**When adding images to existing slides:** Move image to a new slide or reduce other content first. Never add images without checking if existing content already fills the 1920×1080 slide stage.
---
## Phase 1: Content Discovery (New Presentations)
**Ask ALL questions together** so the user fills everything out at once. If the current environment provides a native structured-question UI, use it; otherwise ask in one concise message with clearly numbered choices:
**Question 1 — Purpose** (header: "Purpose"):
What is this presentation for? Options: Pitch deck / Teaching-Tutorial / Conference talk / Internal presentation
**Question 2 — Length** (header: "Length"):
Approximately how many slides? Options: Short 5-10 / Medium 10-20 / Long 20+
**Question 3 — Content** (header: "Content"):
Do you have content ready? Options: All content ready / Rough notes / Topic only
**Question 4 — Density** (header: "Density"):
How dense should the deck feel? Options:
- "Low density / speaker-led" — Big ideas, fewer words, more visual breathing room
- "High density / reading-first" — More self-contained detail for async reading
**Do not ask about inline editing during Phase 1.** Users should not have to choose editing behavior before seeing a draft. Inline editing is a post-draft affordance: include it by default unless the user explicitly asks for a locked/export-only file.
Remember the user's density choice. It affects slide count, typography scale, amount of text per slide, layout density, and whether to favor cinematic presenter slides or self-contained reading slides.
If user has content, ask them to share it.
### Step 1.2: Image Evaluation (if images provided)
If user selected "No images" → skip to Phase 2.
If user provides an image folder:
1. **Scan** — List all image files (.png, .jpg, .svg, .webp, etc.)
2. **Inspect each image** — Use the agent's available image-understanding capability. If image reading is unavailable, use filenames/metadata and ask the user to clarify only when needed
3. **Evaluate** — For each: what it shows, USABLE or NOT USABLE (with reason), what concept it represents, dominant colors
4. **Co-design the outline** — Curated images inform slide structure alongside text. This is NOT "plan slides then add images" — design around both from the start (e.g., 3 screenshots → 3 feature slides, 1 logo → title/closing slide)
5. **Confirm the outline** using the same structured-question mechanism when available: "Does this slide outline and image selection look right?" Options: Looks good / Adjust images / Adjust outline
**Logo in previews:** If a usable logo was identified, embed it (base64) into each style preview in Phase 2 — the user sees their brand styled three different ways.
---
## Phase 2: Style Discovery
**This is the "show, don't tell" phase.** Most people can't articulate design preferences in words.
### Step 2.0: Generate 3 Style Previews Directly
Based on purpose, audience, mood, and content density, generate 3 distinct single-slide HTML previews showing typography, colors, animation, and overall aesthetic.
Do not ask the user whether they want options or a preset picker. The default discovery experience is always visual comparison.
If the user already gave a vibe, use it. If they did not, infer the likely mood from the occasion, audience, content, and stakes. Keep the options diverse enough that the user can react visually instead of needing to articulate taste up front.
If the user explicitly names a preset or bold template, honor that as one option and generate the remaining preview slots around it.
Read [STYLE_PRESETS.md](STYLE_PRESETS.md) for safe preset candidates. If [bold-template-pack/selection-index.json](bold-template-pack/selection-index.json) exists, read that compact index too, but do not read any `design.md` files yet.
| Mood | Suggested Presets |
| ------------------- | -------------------------------------------------- |
| Impressed/Confident | Bold Signal, Electric Studio, Dark Botanical |
| Excited/Energized | Creative Voltage, Neon Cyber, Split Pastel |
| Calm/Focused | Notebook Tabs, Paper & Ink, Swiss Modern |
| Inspired/Moved | Dark Botanical, Vintage Editorial, Pastel Geometry |
**Preview mix rules:**
- Generate 3 previews by default: 1 safe preset from `STYLE_PRESETS.md`, at least 1 bold template from `bold-template-pack/selection-index.json`, and 1 wildcard.
- The wildcard may be either a second bold template or a self-generated custom design. Choose whichever creates the strongest, most useful contrast for the user's occasion, audience, mood, and content.
- Do not force every expressive option to come from the template library. If the brief has a sharper, more specific design opportunity than the available templates, use the wildcard slot to design freely.
- For conservative or high-stakes decks, make the safe preset especially restrained; choose a calm, higher-formality bold template; make the wildcard either another restrained template or a custom design that feels authoritative rather than decorative.
- For expressive decks, keep the safe preset as a readable fallback; choose one strong bold template; make the wildcard adventurous, context-specific, and clearly different from both other previews.
- If bold template matches feel weak, use the wildcard as a custom design or fall back to another safe preset instead of forcing a template.
**Custom wildcard design rules:**
- Follow the Design Aesthetics section above: no generic "AI slop", no default font/color/layout choices, no purple-gradient-on-white clichés, no cookie-cutter dashboard/card look.
- Match the user's stated occasion, audience, mood/vibe, and content density. The custom design should feel authored for this deck, not merely "stylish."
- Make a deliberate visual thesis: distinctive typography, a committed palette, a recognizable layout system, and one strong atmospheric or graphic device.
- Keep it feasible for a full deck. The preview must imply a design system that can expand into section, content, quote, comparison, and closing slides.
- Use fixed 1920×1080 stage rules and pass the same preview authenticity checks as every other option.
- Never render "custom", "wildcard", "AI-generated", or design-process labels on the slide itself.
**Bold template selection rules:**
- Match user purpose and mood against `mood`, `tone`, `best_for`, `avoid_for`, `formality`, `density`, and `scheme`.
- Treat `best_for` examples as soft signals, not strict industry filters.
- Keep the three previews genuinely different from each other.
- After choosing bold template candidate(s), read only those candidate(s)' `preview.md` files from the `preview_md` paths in the selection index.
- Use `preview.md` only for title-slide previews. Do not read full `design.md` files until the user picks the final template.
- Do not read or copy `template.html` unless the selected final `design.md` is missing a critical implementation detail.
**Preview authenticity rules (NON-NEGOTIABLE):**
- Every style preview must look like a real first slide from the user's deck, not a diagnostic card.
- Never render internal workflow text on a slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never render template names or slug names on the slide itself. Template/style names belong only in the message to the user.
- Never render user requirement notes as slide content, such as "sharp and provocative", "safe option", "bold option", "for internal sharing", or "audience: ...", unless the user explicitly wants that exact phrase to appear in the deck.
- If the slide needs chrome, use real deck chrome only: the deck title, section title, date, author, company, page number, or a genuine content phrase from the user's material.
- Before opening previews, inspect the visible text and revise if any internal metadata appears.
Save previews to `.frontend-slides/slide-previews/` (style-a.html, style-b.html, style-c.html). Each should be self-contained and compact, showing one animated title slide.
Open each preview automatically for the user.
### Step 2.1: User Picks
Ask (header: "Style"):
Which style preview do you prefer? Options: Style A: [Name] / Style B: [Name] / Style C: [Name] / Mix elements
If "Mix elements", ask for specifics.
---
## Phase 3: Generate Presentation
Generate the full presentation using content from Phase 1 (text, or text + curated images) and style from Phase 2.
If images were provided, the slide outline already incorporates them from Step 1.2. If not, CSS-generated visuals (gradients, shapes, patterns) provide visual interest — this is a fully supported first-class path.
Apply the user's density choice throughout the deck:
- **Low density / speaker-led:** Use more slides with fewer ideas per slide. Favor large headings, short phrases, visual metaphors, section beats, quote/statement slides, and presenter-friendly pacing.
- **High density / reading-first:** Make slides more self-contained. Use structured grids, comparison tables, annotated diagrams, captions, and concise explanatory copy. Keep hierarchy strong so it feels designed, not like a document pasted onto slides.
If the user's stated needs are mixed, choose the closer of the two modes instead of inventing a middle option: live audience persuasion defaults low-density; async circulation or detailed review defaults high-density.
Never let high density become visual clutter. If a high-density slide starts to overflow, split it or redesign it into a clearer structure.
If the user selected a bold template from `bold-template-pack`, read that one template's full `design.md` before generating. Do not read the other bold templates. Treat `design.md` as the design recipe:
- Preserve its fonts, palette, decorative vocabulary, spacing rhythm, and component grammar.
- Generate the final deck as a fixed 1920×1080 stage scaled uniformly to the viewport, regardless of whether the source template originally used `deck-stage.js` or viewport-fluid CSS.
- Treat viewport-fluid values in `design.md` as design proportions to translate into 1920×1080 stage coordinates. Do not keep them as live viewport reflow rules in the final deck.
- Keep the output as a single self-contained Frontend Slides HTML file.
- Do not copy demo slide content or mimic the source template too literally.
- Use `template.html` only as a last-resort implementation reference for the selected template.
- After generating, verify both content overflow and panel overlap in rendered browser screenshots. `scrollHeight` checks alone are not enough because grid panels can visually cover each other.
If the user selected a self-generated custom wildcard, treat that preview's CSS and layout as the design recipe:
- Preserve its fonts, palette, decorative vocabulary, spacing rhythm, grid logic, and component grammar.
- Expand the same visual system across the full deck. Do not switch to a preset or bold template after the user has chosen the custom direction.
- Design any missing slide layouts from that system rather than importing patterns from another style.
- Keep the output fixed-stage, single-file, and visually verified like every other deck.
**Before generating, read these supporting files:**
- [html-template.md](html-template.md) — HTML architecture and JS features
- [viewport-base.css](viewport-base.css) — Mandatory CSS (include in full)
- [animation-patterns.md](animation-patterns.md) — Animation reference for the chosen feeling
**Key requirements:**
- Single self-contained HTML file, all CSS/JS inline
- Include the FULL contents of viewport-base.css in the `<style>` block
- Use fonts from Fontshare or Google Fonts — never system fonts
- Add detailed comments explaining each section
- Every section needs a clear `/* === SECTION NAME === */` comment block
---
## Phase 4: PPT Conversion
When converting PowerPoint files:
1. **Extract content** — Run `python scripts/extract-pptx.py <input.pptx> <output_dir>` (install python-pptx if needed: `pip install python-pptx`)
2. **Confirm with user** — Present extracted slide titles, content summaries, and image counts
3. **Style selection** — Proceed to Phase 2 for style discovery
4. **Generate HTML** — Convert to chosen style, preserving all text, images (from assets/), slide order, and speaker notes (as HTML comments)
---
## Phase 5: Delivery
1. **Clean up** — Delete `.frontend-slides/slide-previews/` if it exists
2. **Open** — Use `open [filename].html` to launch in browser
3. **Summarize** — Tell the user:
- File location, style name, slide count
- Navigation: Arrow keys, Space, swipe/tap if enabled
- How to customize: `:root` CSS variables for colors, font link for typography, `.reveal` class for animations
- Inline text editing is available: Hover top-left corner or press E to enter edit mode, click any text to edit, Ctrl+S to save
- Offer the natural post-draft actions: ask for revisions, edit text directly in the browser, or export/share
---
## Phase 6: Share & Export (Optional)
After delivery, **ask the user:** _"Would you like to share this presentation? I can deploy it to a live URL (works on any device including phones) or export it as a PDF."_
Options:
- **Deploy to URL** — Shareable link that works on any device
- **Export to PDF** — Universal file for email, Slack, print
- **Both**
- **No thanks**
If the user declines, stop here. If they choose one or both, proceed below.
### 6A: Deploy to a Live URL (Vercel)
This deploys the presentation to Vercel — a free hosting platform. The link works on any device (phones, tablets, laptops) and stays live until the user takes it down.
**If the user has never deployed before, guide them step by step:**
1. **Check if Vercel CLI is installed** — Run `npx vercel --version`. If not found, install Node.js first (`brew install node` on macOS, or download from https://nodejs.org).
2. **Check if user is logged in** — Run `npx vercel whoami`.
- If NOT logged in, explain: _"Vercel is a free hosting service. You need an account to deploy. Let me walk you through it:"_
- Step 1: Ask user to go to https://vercel.com/signup in their browser
- Step 2: They can sign up with GitHub, Google, email — whatever is easiest
- Step 3: Once signed up, run `vercel login` and follow the prompts (it opens a browser window to authorize)
- Step 4: Confirm login with `vercel whoami`
- Wait for the user to confirm they're logged in before proceeding.
3. **Deploy** — Run the deploy script:
```bash
bash scripts/deploy.sh <path-to-presentation>
```
The script accepts either a folder (with index.html) or a single HTML file.
4. **Share the URL** — Tell the user:
- The live URL (from the script output)
- That it works on any device — they can text it, Slack it, email it
- To take it down later: visit https://vercel.com/dashboard and delete the project
- The Vercel free tier is generous — they won't be charged
**⚠ Deployment gotchas:**
- **Local images/videos must travel with the HTML.** The deploy script auto-detects files referenced via `src="..."` in the HTML and bundles them. But if the presentation references files via CSS `background-image` or unusual paths, those may be missed. **Before deploying, verify:** open the deployed URL and check that all images load. If any are broken, the safest fix is to put the HTML and all its assets into a single folder and deploy the folder instead of a standalone HTML file.
- **Prefer folder deployments when the presentation has many assets.** If the presentation lives in a folder with images alongside it (e.g., `my-deck/index.html` + `my-deck/logo.png`), deploy the folder directly: `bash scripts/deploy.sh ./my-deck/`. This is more reliable than deploying a single HTML file because the entire folder contents are uploaded as-is.
- **Filenames with spaces work but can cause issues.** The script handles spaces in filenames, but Vercel URLs encode spaces as `%20`. If possible, avoid spaces in image filenames. If the user's images have spaces, the script handles it — but if images still break, renaming files to use hyphens instead of spaces is the fix.
- **Redeploying updates the same URL.** Running the deploy script again on the same presentation overwrites the previous deployment. The URL stays the same — no need to share a new link.
### 6B: Export to PDF
This captures each slide as a screenshot and combines them into a PDF. Perfect for email attachments, embedding in documents, or printing.
**Note:** Animations and interactivity are not preserved — the PDF is a static snapshot. This is normal and expected; mention it to the user so they're not surprised.
1. **Run the export script:**
```bash
bash scripts/export-pdf.sh <path-to-html> [output.pdf]
```
If no output path is given, the PDF is saved next to the HTML file.
2. **What happens behind the scenes** (explain briefly to the user):
- A headless browser opens the presentation at 1920×1080 (standard widescreen)
- It screenshots each slide one by one
- All screenshots are combined into a single PDF
- The script needs Playwright (a browser automation tool) — it will install automatically if missing
3. **If Playwright installation fails:**
- The most common issue is Chromium not downloading. Run: `npx playwright install chromium`
- If that fails too, it may be a network/firewall issue. Ask the user to try on a different network.
4. **Deliver the PDF** — The script auto-opens it. Tell the user:
- The file location and size
- That it works everywhere — email, Slack, Notion, Google Docs, print
- Animations are replaced by their final visual state (still looks great, just static)
**⚠ PDF export gotchas:**
- **First run is slow.** The script installs Playwright and downloads a Chromium browser (~150MB) into a temp directory. This happens once per run. Warn the user it may take 30-60 seconds the first time — subsequent exports within the same session are faster.
- **Slides must use `class="slide"`.** The export script finds slides by querying `.slide` elements. If the presentation uses a different class name, the script will report "0 slides found" and fail. All presentations generated by this skill use `.slide`, so this only matters for externally-created HTML.
- **Local images must be loadable via HTTP.** The script starts a local server and loads the HTML through it (so Google Fonts and relative image paths work). If images use absolute filesystem paths (e.g., `src="/Users/name/photo.png"`) instead of relative paths (e.g., `src="photo.png"`), they won't load. Generated presentations always use relative paths, but converted or user-provided decks might not — check and fix if needed.
- **Local images appear in the PDF** as long as they are in the same directory as (or relative to) the HTML file. The export script serves the HTML's parent directory over HTTP, so relative paths like `src="photo.png"` resolve correctly — including filenames with spaces. If images still don't appear, check: (1) the image files actually exist at the referenced path, (2) the paths are relative, not absolute filesystem paths like `/Users/name/photo.png`.
- **Large presentations produce large PDFs.** Each slide is captured as a full 1920×1080 PNG screenshot. An 18-slide deck can produce a ~20MB PDF. If the PDF exceeds 10MB, ask the user: _"The PDF is [size]. Would you like me to compress it? It'll look slightly less sharp but the file will be much smaller."_ If yes, re-run the export with the `--compact` flag:
```bash
bash scripts/export-pdf.sh <path-to-html> [output.pdf] --compact
```
This renders at 1280×720 instead of 1920×1080, typically cutting file size by 50-70% with minimal visual difference.
---
## Supporting Files
| File | Purpose | When to Read |
| -------------------------------------------------- | -------------------------------------------------------------------- | ------------------------- |
| [STYLE_PRESETS.md](STYLE_PRESETS.md) | 12 curated visual presets with colors, fonts, and signature elements | Phase 2 (style selection) |
| [bold-template-pack/selection-index.json](bold-template-pack/selection-index.json) | Compact bold template metadata for candidate selection | Phase 2 (style selection) |
| [bold-template-pack/templates/*/preview.md](bold-template-pack/templates/) | Lightweight style cards for shortlisted bold title previews | Phase 2 after shortlisting |
| [bold-template-pack/templates/*/design.md](bold-template-pack/templates/) | Detailed design-system docs for the selected bold template only | Phase 3 after user selection |
| [viewport-base.css](viewport-base.css) | Mandatory fixed-stage CSS — copy into every presentation | Phase 3 (generation) |
| [html-template.md](html-template.md) | HTML structure, JS features, code quality standards | Phase 3 (generation) |
| [animation-patterns.md](animation-patterns.md) | CSS/JS animation snippets and effect-to-feeling guide | Phase 3 (generation) |
| [scripts/extract-pptx.py](scripts/extract-pptx.py) | Python script for PPT content extraction | Phase 4 (conversion) |
| [scripts/deploy.sh](scripts/deploy.sh) | Deploy slides to Vercel for instant sharing | Phase 6 (sharing) |
| [scripts/export-pdf.sh](scripts/export-pdf.sh) | Export slides to PDF | Phase 6 (sharing) |
# Style Presets Reference
Curated visual styles for Frontend Slides. Each preset is inspired by real design references — no generic "AI slop" aesthetics. **Abstract shapes only — no illustrations.**
**Viewport CSS:** For mandatory base styles, see [viewport-base.css](viewport-base.css). Include in every presentation.
---
## Dark Themes
### 1. Bold Signal
**Vibe:** Confident, bold, modern, high-impact
**Layout:** Colored card on dark gradient. Number top-left, navigation top-right, title bottom-left.
**Typography:**
- Display: `Archivo Black` (900)
- Body: `Space Grotesk` (400/500)
**Colors:**
```css
:root {
--bg-primary: #1a1a1a;
--bg-gradient: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 50%, #1a1a1a 100%);
--card-bg: #FF5722;
--text-primary: #ffffff;
--text-on-card: #1a1a1a;
}
```
**Signature Elements:**
- Bold colored card as focal point (orange, coral, or vibrant accent)
- Large section numbers (01, 02, etc.)
- Navigation breadcrumbs with active/inactive opacity states
- Grid-based layout for precise alignment
---
### 2. Electric Studio
**Vibe:** Bold, clean, professional, high contrast
**Layout:** Split panel—white top, blue bottom. Brand marks in corners.
**Typography:**
- Display: `Manrope` (800)
- Body: `Manrope` (400/500)
**Colors:**
```css
:root {
--bg-dark: #0a0a0a;
--bg-white: #ffffff;
--accent-blue: #4361ee;
--text-dark: #0a0a0a;
--text-light: #ffffff;
}
```
**Signature Elements:**
- Two-panel vertical split
- Accent bar on panel edge
- Quote typography as hero element
- Minimal, confident spacing
---
### 3. Creative Voltage
**Vibe:** Bold, creative, energetic, retro-modern
**Layout:** Split panels—electric blue left, dark right. Script accents.
**Typography:**
- Display: `Syne` (700/800)
- Mono: `Space Mono` (400/700)
**Colors:**
```css
:root {
--bg-primary: #0066ff;
--bg-dark: #1a1a2e;
--accent-neon: #d4ff00;
--text-light: #ffffff;
}
```
**Signature Elements:**
- Electric blue + neon yellow contrast
- Halftone texture patterns
- Neon badges/callouts
- Script typography for creative flair
---
### 4. Dark Botanical
**Vibe:** Elegant, sophisticated, artistic, premium
**Layout:** Centered content on dark. Abstract soft shapes in corner.
**Typography:**
- Display: `Cormorant` (400/600) — elegant serif
- Body: `IBM Plex Sans` (300/400)
**Colors:**
```css
:root {
--bg-primary: #0f0f0f;
--text-primary: #e8e4df;
--text-secondary: #9a9590;
--accent-warm: #d4a574;
--accent-pink: #e8b4b8;
--accent-gold: #c9b896;
}
```
**Signature Elements:**
- Abstract soft gradient circles (blurred, overlapping)
- Warm color accents (pink, gold, terracotta)
- Thin vertical accent lines
- Italic signature typography
- **No illustrations—only abstract CSS shapes**
---
## Light Themes
### 5. Notebook Tabs
**Vibe:** Editorial, organized, elegant, tactile
**Layout:** Cream paper card on dark background. Colorful tabs on right edge.
**Typography:**
- Display: `Bodoni Moda` (400/700) — classic editorial
- Body: `DM Sans` (400/500)
**Colors:**
```css
:root {
--bg-outer: #2d2d2d;
--bg-page: #f8f6f1;
--text-primary: #1a1a1a;
--tab-1: #98d4bb; /* Mint */
--tab-2: #c7b8ea; /* Lavender */
--tab-3: #f4b8c5; /* Pink */
--tab-4: #a8d8ea; /* Sky */
--tab-5: #ffe6a7; /* Cream */
}
```
**Signature Elements:**
- Paper container with subtle shadow
- Colorful section tabs on right edge (vertical text)
- Binder hole decorations on left
- Tab text must scale with viewport: `font-size: clamp(0.5rem, 1vh, 0.7rem)`
---
### 6. Pastel Geometry
**Vibe:** Friendly, organized, modern, approachable
**Layout:** White card on pastel background. Vertical pills on right edge.
**Typography:**
- Display: `Plus Jakarta Sans` (700/800)
- Body: `Plus Jakarta Sans` (400/500)
**Colors:**
```css
:root {
--bg-primary: #c8d9e6;
--card-bg: #faf9f7;
--pill-pink: #f0b4d4;
--pill-mint: #a8d4c4;
--pill-sage: #5a7c6a;
--pill-lavender: #9b8dc4;
--pill-violet: #7c6aad;
}
```
**Signature Elements:**
- Rounded card with soft shadow
- **Vertical pills on right edge** with varying heights (like tabs)
- Consistent pill width, heights: short → medium → tall → medium → short
- Download/action icon in corner
---
### 7. Split Pastel
**Vibe:** Playful, modern, friendly, creative
**Layout:** Two-color vertical split (peach left, lavender right).
**Typography:**
- Display: `Outfit` (700/800)
- Body: `Outfit` (400/500)
**Colors:**
```css
:root {
--bg-peach: #f5e6dc;
--bg-lavender: #e4dff0;
--text-dark: #1a1a1a;
--badge-mint: #c8f0d8;
--badge-yellow: #f0f0c8;
--badge-pink: #f0d4e0;
}
```
**Signature Elements:**
- Split background colors
- Playful badge pills with icons
- Grid pattern overlay on right panel
- Rounded CTA buttons
---
### 8. Vintage Editorial
**Vibe:** Witty, confident, editorial, personality-driven
**Layout:** Centered content on cream. Abstract geometric shapes as accent.
**Typography:**
- Display: `Fraunces` (700/900) — distinctive serif
- Body: `Work Sans` (400/500)
**Colors:**
```css
:root {
--bg-cream: #f5f3ee;
--text-primary: #1a1a1a;
--text-secondary: #555;
--accent-warm: #e8d4c0;
}
```
**Signature Elements:**
- Abstract geometric shapes (circle outline + line + dot)
- Bold bordered CTA boxes
- Witty, conversational copy style
- **No illustrations—only geometric CSS shapes**
---
## Specialty Themes
### 9. Neon Cyber
**Vibe:** Futuristic, techy, confident
**Typography:** `Clash Display` + `Satoshi` (Fontshare)
**Colors:** Deep navy (#0a0f1c), cyan accent (#00ffcc), magenta (#ff00aa)
**Signature:** Particle backgrounds, neon glow, grid patterns
---
### 10. Terminal Green
**Vibe:** Developer-focused, hacker aesthetic
**Typography:** `JetBrains Mono` (monospace only)
**Colors:** GitHub dark (#0d1117), terminal green (#39d353)
**Signature:** Scan lines, blinking cursor, code syntax styling
---
### 11. Swiss Modern
**Vibe:** Clean, precise, Bauhaus-inspired
**Typography:** `Archivo` (800) + `Nunito` (400)
**Colors:** Pure white, pure black, red accent (#ff3300)
**Signature:** Visible grid, asymmetric layouts, geometric shapes
---
### 12. Paper & Ink
**Vibe:** Editorial, literary, thoughtful
**Typography:** `Cormorant Garamond` + `Source Serif 4`
**Colors:** Warm cream (#faf9f7), charcoal (#1a1a1a), crimson accent (#c41e3a)
**Signature:** Drop caps, pull quotes, elegant horizontal rules
---
## Font Pairing Quick Reference
| Preset | Display Font | Body Font | Source |
|--------|--------------|-----------|--------|
| Bold Signal | Archivo Black | Space Grotesk | Google |
| Electric Studio | Manrope | Manrope | Google |
| Creative Voltage | Syne | Space Mono | Google |
| Dark Botanical | Cormorant | IBM Plex Sans | Google |
| Notebook Tabs | Bodoni Moda | DM Sans | Google |
| Pastel Geometry | Plus Jakarta Sans | Plus Jakarta Sans | Google |
| Split Pastel | Outfit | Outfit | Google |
| Vintage Editorial | Fraunces | Work Sans | Google |
| Neon Cyber | Clash Display | Satoshi | Fontshare |
| Terminal Green | JetBrains Mono | JetBrains Mono | JetBrains |
---
## DO NOT USE (Generic AI Patterns)
**Fonts:** Inter, Roboto, Arial, system fonts as display
**Colors:** `#6366f1` (generic indigo), purple gradients on white
**Layouts:** Everything centered, generic hero sections, identical card grids
**Decorations:** Realistic illustrations, gratuitous glassmorphism, drop shadows without purpose
---
## CSS Gotchas
### Negating CSS Functions
**WRONG — silently ignored by browsers (no console error):**
```css
right: -clamp(28px, 3.5vw, 44px); /* Browser ignores this */
margin-left: -min(10vw, 100px); /* Browser ignores this */
```
**CORRECT — wrap in `calc()`:**
```css
right: calc(-1 * clamp(28px, 3.5vw, 44px)); /* Works */
margin-left: calc(-1 * min(10vw, 100px)); /* Works */
```
CSS does not allow a leading `-` before function names. The browser silently discards the entire declaration — no error, the element just appears in the wrong position. **Always use `calc(-1 * ...)` to negate CSS function values.**
# Animation Patterns Reference
Use this reference when generating presentations. Match animations to the intended feeling.
## Effect-to-Feeling Guide
| Feeling | Animations | Visual Cues |
|---------|-----------|-------------|
| **Dramatic / Cinematic** | Slow fade-ins (1-1.5s), large scale transitions (0.9 to 1), parallax scrolling | Dark backgrounds, spotlight effects, full-bleed images |
| **Techy / Futuristic** | Neon glow (box-shadow), glitch/scramble text, grid reveals | Particle systems (canvas), grid patterns, monospace accents, cyan/magenta/electric blue |
| **Playful / Friendly** | Bouncy easing (spring physics), floating/bobbing | Rounded corners, pastel/bright colors, hand-drawn elements |
| **Professional / Corporate** | Subtle fast animations (200-300ms), clean slides | Navy/slate/charcoal, precise spacing, data visualization focus |
| **Calm / Minimal** | Very slow subtle motion, gentle fades | High whitespace, muted palette, serif typography, generous padding |
| **Editorial / Magazine** | Staggered text reveals, image-text interplay | Strong type hierarchy, pull quotes, grid-breaking layouts, serif headlines + sans body |
## Entrance Animations
```css
/* Fade + Slide Up (most versatile) */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s var(--ease-out-expo),
transform 0.6s var(--ease-out-expo);
}
.visible .reveal {
opacity: 1;
transform: translateY(0);
}
/* Scale In */
.reveal-scale {
opacity: 0;
transform: scale(0.9);
transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}
/* Slide from Left */
.reveal-left {
opacity: 0;
transform: translateX(-50px);
transition: opacity 0.6s, transform 0.6s var(--ease-out-expo);
}
/* Blur In */
.reveal-blur {
opacity: 0;
filter: blur(10px);
transition: opacity 0.8s, filter 0.8s var(--ease-out-expo);
}
```
## Background Effects
```css
/* Gradient Mesh — layered radial gradients for depth */
.gradient-bg {
background:
radial-gradient(ellipse at 20% 80%, rgba(120, 0, 255, 0.3) 0%, transparent 50%),
radial-gradient(ellipse at 80% 20%, rgba(0, 255, 200, 0.2) 0%, transparent 50%),
var(--bg-primary);
}
/* Noise Texture — inline SVG for grain */
.noise-bg {
background-image: url("data:image/svg+xml,..."); /* Inline SVG noise */
}
/* Grid Pattern — subtle structural lines */
.grid-bg {
background-image:
linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
background-size: 50px 50px;
}
```
## Interactive Effects
```javascript
/* 3D Tilt on Hover — adds depth to cards/panels */
class TiltEffect {
constructor(element) {
this.element = element;
this.element.style.transformStyle = 'preserve-3d';
this.element.style.perspective = '1000px';
this.element.addEventListener('mousemove', (e) => {
const rect = this.element.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width - 0.5;
const y = (e.clientY - rect.top) / rect.height - 0.5;
this.element.style.transform = `rotateY(${x * 10}deg) rotateX(${-y * 10}deg)`;
});
this.element.addEventListener('mouseleave', () => {
this.element.style.transform = 'rotateY(0) rotateX(0)';
});
}
}
```
## Troubleshooting
| Problem | Fix |
|---------|-----|
| Fonts not loading | Check Fontshare/Google Fonts URL; ensure font names match in CSS |
| Animations not triggering | Verify Intersection Observer is running; check `.visible` class is being added |
| Scroll snap not working | Ensure `scroll-snap-type: y mandatory` on html; each slide needs `scroll-snap-align: start` |
| Mobile issues | Disable heavy effects at 768px breakpoint; test touch events; reduce particle count |
| Performance issues | Use `will-change` sparingly; prefer `transform`/`opacity` animations; throttle scroll handlers |
# Bold Template Pack This pack brings the `beautiful-html-templates` design systems into the `frontend-slides` skill without making them the default for every deck. ## What To Read 1. Read `bold-template-pack/selection-index.json` first. 2. Shortlist candidates from metadata only: - `mood` - `tone` - `best_for` - `avoid_for` - `formality` - `density` - `scheme` 3. For title-slide previews, read only the relevant candidate `preview.md` files. 4. After the user chooses a bold template, read exactly that one template's full `design.md`. 5. Do not read every `design.md` in the pack. 6. Do not read or copy `template.html` from the source template library unless a selected `design.md` is missing a critical implementation detail. The full source metadata index is not bundled in the user-facing skill. Normal generation should use `selection-index.json` only. ## How To Use In Frontend Slides Preview mix: - 1 safe option from `STYLE_PRESETS.md` - at least 1 bold option from this pack - 1 wildcard option, which may be another bold template from this pack or a self-generated custom design Adjust the tone inside that default mix: - For board, legal, regulatory, healthcare, investor-update, or highly formal internal decks, make the safe option very restrained and choose calmer, higher-formality bold templates. The wildcard should feel authoritative and specific, not merely decorative. - For bold, editorial, expressive, experimental, or highly designed decks, keep the safe option as a readable fallback, choose one strong bold template, and use the wildcard for either a second adventurous template or a custom design that better matches the user's occasion and vibe. If the wildcard is custom, it must follow Frontend Slides' no-slop aesthetics: distinctive typography, a committed palette, a recognizable layout system, a context-specific visual idea, fixed 16:9 stage behavior, and no visible process labels such as "custom", "wildcard", "template", or "preview". ## Implementation Contract `design.md` is the design-system reference. Treat it as a style recipe, not as content to copy. `preview.md` is only a lightweight style card for generating the three title-slide options. Preview slides must be real title slides for the user's deck. Do not render template names, option labels, file names, paths, `preview.md`, "generated from", or user requirement notes on the slide itself. When generating final slides: - Keep `frontend-slides` output as one self-contained HTML file. - Include the full contents of `viewport-base.css`. - Generate every deck as a fixed 1920×1080 stage scaled uniformly to the viewport. This applies even if the source template was originally viewport-fluid. - Treat `vw`, `vh`, and `clamp()` values in a source `design.md` as design proportions to translate into fixed 1920×1080 stage coordinates. - Preserve the selected template's fonts, palette, decorative vocabulary, spacing rhythm, and component grammar. - Keep the user's actual slide content primary. The template style should shape presentation, not override message or structure. - Verify rendered output for both text overflow and panel overlap. A card can pass `scrollHeight` checks while still being covered by another grid panel.
/**
* <deck-stage> — reusable web component for HTML decks.
*
* Handles:
* (a) speaker notes — reads <script type="application/json" id="speaker-notes">
* and posts {slideIndexChanged: N} to the parent window on nav.
* (b) keyboard navigation — ←/→, PgUp/PgDn, Space, Home/End, number keys.
* (c) press R to reset to slide 0 (with a tasteful keyboard hint).
* (d) bottom-center overlay showing slide count + hints, fades out on idle.
* (e) auto-scaling — inner canvas is a fixed design size (default 1920×1080)
* scaled with `transform: scale()` to fit the viewport, letterboxed.
* Set the `noscale` attribute to render at authored size (1:1) — the
* PPTX exporter sets this so its DOM capture sees unscaled geometry.
* (f) print — `@media print` lays every slide out as its own page at the
* design size, so the browser's Print → Save as PDF produces a clean
* one-page-per-slide PDF with no extra setup.
*
* Slides are HIDDEN, not unmounted. Non-active slides stay in the DOM with
* `visibility: hidden` + `opacity: 0`, so their state (videos, iframes,
* form inputs, React trees) is preserved across navigation.
*
* Lifecycle event — the component dispatches a `slidechange` CustomEvent on
* itself whenever the active slide changes (including the initial mount).
* The event bubbles and composes out of shadow DOM, so you can listen on
* the <deck-stage> element or on document:
*
* document.querySelector('deck-stage').addEventListener('slidechange', (e) => {
* e.detail.index // new 0-based index
* e.detail.previousIndex // previous index, or -1 on init
* e.detail.total // total slide count
* e.detail.slide // the new active slide element
* e.detail.previousSlide // the prior slide element, or null on init
* e.detail.reason // 'init' | 'keyboard' | 'click' | 'tap' | 'api'
* });
*
* Persistence: none at the deck level. The host app keeps the current slide
* in its own URL (?slide=) and re-delivers it via location.hash on load, so a
* bare load with no hash always starts at slide 1.
*
* Usage:
* <deck-stage width="1920" height="1080">
* <section data-label="Title">...</section>
* <section data-label="Agenda">...</section>
* </deck-stage>
*
* Slides are the direct element children of <deck-stage>. Each slide is
* automatically tagged with:
* - data-screen-label="NN Label" (1-indexed, for comment flow)
* - data-om-validate="no_overflowing_text,no_overlapping_text,slide_sized_text"
*/
(() => {
const DESIGN_W_DEFAULT = 1920;
const DESIGN_H_DEFAULT = 1080;
const OVERLAY_HIDE_MS = 1800;
const VALIDATE_ATTR = 'no_overflowing_text,no_overlapping_text,slide_sized_text';
const pad2 = (n) => String(n).padStart(2, '0');
const stylesheet = `
:host {
position: fixed;
inset: 0;
display: block;
background: #000;
color: #fff;
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
overflow: hidden;
}
.stage {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.canvas {
position: relative;
transform-origin: center center;
flex-shrink: 0;
background: #fff;
will-change: transform;
}
/* Slides live in light DOM (via <slot>) so authored CSS still applies.
We absolutely position each slotted child to stack them. */
::slotted(*) {
position: absolute !important;
inset: 0 !important;
width: 100% !important;
height: 100% !important;
box-sizing: border-box !important;
overflow: hidden;
opacity: 0;
pointer-events: none;
visibility: hidden;
}
::slotted([data-deck-active]) {
opacity: 1;
pointer-events: auto;
visibility: visible;
}
/* Tap zones for mobile — back/forward thirds like Stories.
Transparent, no visible UI, don't block the overlay. */
.tapzones {
position: fixed;
inset: 0;
display: flex;
z-index: 2147482000;
pointer-events: none;
}
.tapzone {
flex: 1;
pointer-events: auto;
-webkit-tap-highlight-color: transparent;
}
/* Only activate tap zones on coarse pointers (touch devices). */
@media (hover: hover) and (pointer: fine) {
.tapzones { display: none; }
}
.overlay {
position: fixed;
left: 50%;
bottom: 22px;
transform: translate(-50%, 6px) scale(0.92);
filter: blur(6px);
display: flex;
align-items: center;
gap: 4px;
padding: 4px;
background: #000;
color: #fff;
border-radius: 999px;
font-size: 12px;
font-feature-settings: "tnum" 1;
letter-spacing: 0.01em;
opacity: 0;
pointer-events: none;
transition: opacity 260ms ease, transform 260ms cubic-bezier(.2,.8,.2,1), filter 260ms ease;
transform-origin: center bottom;
z-index: 2147483000;
user-select: none;
}
.overlay[data-visible] {
opacity: 1;
pointer-events: auto;
transform: translate(-50%, 0) scale(1);
filter: blur(0);
}
.btn {
appearance: none;
-webkit-appearance: none;
background: transparent;
border: 0;
margin: 0;
padding: 0;
color: inherit;
font: inherit;
cursor: default;
display: inline-flex;
align-items: center;
justify-content: center;
height: 28px;
min-width: 28px;
border-radius: 999px;
color: rgba(255,255,255,0.72);
transition: background 140ms ease, color 140ms ease;
-webkit-tap-highlight-color: transparent;
}
.btn:hover { background: rgba(255,255,255,0.12); color: #fff; }
.btn:active { background: rgba(255,255,255,0.18); }
.btn:focus { outline: none; }
.btn:focus-visible { outline: none; }
.btn::-moz-focus-inner { border: 0; }
.btn svg { width: 14px; height: 14px; display: block; }
.btn.reset {
font-size: 11px;
font-weight: 500;
letter-spacing: 0.02em;
padding: 0 10px 0 12px;
gap: 6px;
color: rgba(255,255,255,0.72);
}
.btn.reset .kbd {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 16px;
height: 16px;
padding: 0 4px;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
font-size: 10px;
line-height: 1;
color: rgba(255,255,255,0.88);
background: rgba(255,255,255,0.12);
border-radius: 4px;
}
.count {
font-variant-numeric: tabular-nums;
color: #fff;
font-weight: 500;
padding: 0 8px;
min-width: 42px;
text-align: center;
font-size: 12px;
}
.count .sep { color: rgba(255,255,255,0.45); margin: 0 3px; font-weight: 400; }
.count .total { color: rgba(255,255,255,0.55); }
.divider {
width: 1px;
height: 14px;
background: rgba(255,255,255,0.18);
margin: 0 2px;
}
/* ── Print: one page per slide, no chrome ────────────────────────────
The screen layout stacks every slide at inset:0 inside a scaled
canvas; for print we want them in document flow at the authored
design size so the browser paginates one slide per sheet. The
@page size is set from the width/height attributes via the inline
<style id="deck-stage-print-page"> that connectedCallback injects
into <head> (the @page at-rule has no effect inside shadow DOM). */
@media print {
:host {
position: static;
inset: auto;
background: none;
overflow: visible;
color: inherit;
}
.stage { position: static; display: block; }
.canvas {
transform: none !important;
width: auto !important;
height: auto !important;
background: none;
will-change: auto;
}
::slotted(*) {
position: relative !important;
inset: auto !important;
width: var(--deck-design-w) !important;
height: var(--deck-design-h) !important;
box-sizing: border-box !important;
opacity: 1 !important;
visibility: visible !important;
pointer-events: auto;
break-after: page;
page-break-after: always;
break-inside: avoid;
overflow: hidden;
}
::slotted(*:last-child) {
break-after: auto;
page-break-after: auto;
}
.overlay, .tapzones { display: none !important; }
}
`;
class DeckStage extends HTMLElement {
static get observedAttributes() { return ['width', 'height', 'noscale']; }
constructor() {
super();
this._root = this.attachShadow({ mode: 'open' });
this._index = 0;
this._slides = [];
this._notes = [];
this._hideTimer = null;
this._mouseIdleTimer = null;
this._onKey = this._onKey.bind(this);
this._onResize = this._onResize.bind(this);
this._onSlotChange = this._onSlotChange.bind(this);
this._onMouseMove = this._onMouseMove.bind(this);
this._onTapBack = this._onTapBack.bind(this);
this._onTapForward = this._onTapForward.bind(this);
}
get designWidth() {
return parseInt(this.getAttribute('width'), 10) || DESIGN_W_DEFAULT;
}
get designHeight() {
return parseInt(this.getAttribute('height'), 10) || DESIGN_H_DEFAULT;
}
connectedCallback() {
this._render();
this._loadNotes();
this._syncPrintPageRule();
window.addEventListener('keydown', this._onKey);
window.addEventListener('resize', this._onResize);
window.addEventListener('mousemove', this._onMouseMove, { passive: true });
// Initial collection + layout happens via slotchange, which fires on mount.
}
disconnectedCallback() {
window.removeEventListener('keydown', this._onKey);
window.removeEventListener('resize', this._onResize);
window.removeEventListener('mousemove', this._onMouseMove);
if (this._hideTimer) clearTimeout(this._hideTimer);
if (this._mouseIdleTimer) clearTimeout(this._mouseIdleTimer);
}
attributeChangedCallback() {
if (this._canvas) {
this._canvas.style.width = this.designWidth + 'px';
this._canvas.style.height = this.designHeight + 'px';
this._canvas.style.setProperty('--deck-design-w', this.designWidth + 'px');
this._canvas.style.setProperty('--deck-design-h', this.designHeight + 'px');
this._fit();
this._syncPrintPageRule();
}
}
_render() {
const style = document.createElement('style');
style.textContent = stylesheet;
const stage = document.createElement('div');
stage.className = 'stage';
const canvas = document.createElement('div');
canvas.className = 'canvas';
canvas.style.width = this.designWidth + 'px';
canvas.style.height = this.designHeight + 'px';
canvas.style.setProperty('--deck-design-w', this.designWidth + 'px');
canvas.style.setProperty('--deck-design-h', this.designHeight + 'px');
const slot = document.createElement('slot');
slot.addEventListener('slotchange', this._onSlotChange);
canvas.appendChild(slot);
stage.appendChild(canvas);
// Tap zones (mobile): left third = back, right third = forward.
const tapzones = document.createElement('div');
tapzones.className = 'tapzones export-hidden';
tapzones.setAttribute('aria-hidden', 'true');
tapzones.setAttribute('data-noncommentable', '');
const tzBack = document.createElement('div');
tzBack.className = 'tapzone tapzone--back';
const tzMid = document.createElement('div');
tzMid.className = 'tapzone tapzone--mid';
tzMid.style.pointerEvents = 'none';
const tzFwd = document.createElement('div');
tzFwd.className = 'tapzone tapzone--fwd';
tzBack.addEventListener('click', this._onTapBack);
tzFwd.addEventListener('click', this._onTapForward);
tapzones.append(tzBack, tzMid, tzFwd);
// Overlay: compact, solid black, with clickable controls.
const overlay = document.createElement('div');
overlay.className = 'overlay export-hidden';
overlay.setAttribute('role', 'toolbar');
overlay.setAttribute('aria-label', 'Deck controls');
overlay.setAttribute('data-noncommentable', '');
overlay.innerHTML = `
<button class="btn prev" type="button" aria-label="Previous slide" title="Previous (←)">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 3L5 8l5 5"/></svg>
</button>
<span class="count" aria-live="polite"><span class="current">1</span><span class="sep">/</span><span class="total">1</span></span>
<button class="btn next" type="button" aria-label="Next slide" title="Next (→)">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 3l5 5-5 5"/></svg>
</button>
<span class="divider"></span>
<button class="btn reset" type="button" aria-label="Reset to first slide" title="Reset (R)">Reset<span class="kbd">R</span></button>
`;
overlay.querySelector('.prev').addEventListener('click', () => this._go(this._index - 1, 'click'));
overlay.querySelector('.next').addEventListener('click', () => this._go(this._index + 1, 'click'));
overlay.querySelector('.reset').addEventListener('click', () => this._go(0, 'click'));
this._root.append(style, stage, tapzones, overlay);
this._canvas = canvas;
this._slot = slot;
this._overlay = overlay;
this._countEl = overlay.querySelector('.current');
this._totalEl = overlay.querySelector('.total');
}
/** @page must live in the document stylesheet — it's a no-op inside
* shadow DOM. Inject/update a single <head> style tag so the print
* sheet matches the design size and Save-as-PDF yields one slide per
* page with no margins. */
_syncPrintPageRule() {
const id = 'deck-stage-print-page';
let tag = document.getElementById(id);
if (!tag) {
tag = document.createElement('style');
tag.id = id;
document.head.appendChild(tag);
}
tag.textContent =
'@page { size: ' + this.designWidth + 'px ' + this.designHeight + 'px; margin: 0; } ' +
'@media print { html, body { margin: 0 !important; padding: 0 !important; background: none !important; overflow: visible !important; height: auto !important; } ' +
'* { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }';
}
_onSlotChange() {
this._collectSlides();
this._restoreIndex();
this._applyIndex({ showOverlay: false, broadcast: true, reason: 'init' });
this._fit();
}
_collectSlides() {
const assigned = this._slot.assignedElements({ flatten: true });
this._slides = assigned.filter((el) => {
// Skip template/style/script nodes even if someone slots them.
const tag = el.tagName;
return tag !== 'TEMPLATE' && tag !== 'SCRIPT' && tag !== 'STYLE';
});
this._slides.forEach((slide, i) => {
const n = i + 1;
// Determine a label for comment flow: prefer explicit data-label,
// then an existing data-screen-label, then first heading, else "Slide".
let label = slide.getAttribute('data-label');
if (!label) {
const existing = slide.getAttribute('data-screen-label');
if (existing) {
// Strip any leading number the author may have included.
label = existing.replace(/^\s*\d+\s*/, '').trim() || existing;
}
}
if (!label) {
const h = slide.querySelector('h1, h2, h3, [data-title]');
if (h) label = (h.textContent || '').trim().slice(0, 40);
}
if (!label) label = 'Slide';
slide.setAttribute('data-screen-label', `${pad2(n)} ${label}`);
// Validation attribute for comment flow / auto-checks.
if (!slide.hasAttribute('data-om-validate')) {
slide.setAttribute('data-om-validate', VALIDATE_ATTR);
}
slide.setAttribute('data-deck-slide', String(i));
});
if (this._totalEl) this._totalEl.textContent = String(this._slides.length || 1);
if (this._index >= this._slides.length) this._index = Math.max(0, this._slides.length - 1);
}
_loadNotes() {
const tag = document.getElementById('speaker-notes');
if (!tag) { this._notes = []; return; }
try {
const parsed = JSON.parse(tag.textContent || '[]');
if (Array.isArray(parsed)) this._notes = parsed;
} catch (e) {
console.warn('[deck-stage] Failed to parse #speaker-notes JSON:', e);
this._notes = [];
}
}
_restoreIndex() {
// The host's ?slide= param is delivered as a #<int> hash (1-indexed) on
// the iframe src. No hash → slide 1; the deck itself keeps no position
// state across loads.
const h = (location.hash || '').match(/^#(\d+)$/);
if (h) {
const n = parseInt(h[1], 10) - 1;
if (n >= 0 && n < this._slides.length) this._index = n;
}
}
_applyIndex({ showOverlay = true, broadcast = true, reason = 'init' } = {}) {
if (!this._slides.length) return;
const prev = this._prevIndex == null ? -1 : this._prevIndex;
const curr = this._index;
// Keep the iframe's own hash in sync so an in-iframe location.reload()
// (reload banner path in viewer-handle.ts) lands on the current slide,
// not the stale deep-link hash from initial load.
try { history.replaceState(null, '', '#' + (curr + 1)); } catch (e) {}
this._slides.forEach((s, i) => {
if (i === curr) s.setAttribute('data-deck-active', '');
else s.removeAttribute('data-deck-active');
});
if (this._countEl) this._countEl.textContent = String(curr + 1);
if (broadcast) {
// (1) Legacy: host-window postMessage for speaker-notes renderers.
try { window.postMessage({ slideIndexChanged: curr }, '*'); } catch (e) {}
// (2) In-page CustomEvent on the <deck-stage> element itself.
// Bubbles and composes out of shadow DOM so slide code can listen:
// document.querySelector('deck-stage').addEventListener('slidechange', e => {
// e.detail.index, e.detail.previousIndex, e.detail.total, e.detail.slide, e.detail.reason
// });
const detail = {
index: curr,
previousIndex: prev,
total: this._slides.length,
slide: this._slides[curr] || null,
previousSlide: prev >= 0 ? (this._slides[prev] || null) : null,
reason: reason, // 'init' | 'keyboard' | 'click' | 'tap' | 'api'
};
this.dispatchEvent(new CustomEvent('slidechange', {
detail,
bubbles: true,
composed: true,
}));
}
this._prevIndex = curr;
if (showOverlay) this._flashOverlay();
}
_flashOverlay() {
if (!this._overlay) return;
this._overlay.setAttribute('data-visible', '');
if (this._hideTimer) clearTimeout(this._hideTimer);
this._hideTimer = setTimeout(() => {
this._overlay.removeAttribute('data-visible');
}, OVERLAY_HIDE_MS);
}
_fit() {
if (!this._canvas) return;
// PPTX export sets noscale so the DOM capture sees authored-size
// geometry — the scaled canvas is in shadow DOM, so the exporter's
// resetTransformSelector can't reach .canvas.style.transform directly.
if (this.hasAttribute('noscale')) {
this._canvas.style.transform = 'none';
return;
}
const vw = window.innerWidth;
const vh = window.innerHeight;
const s = Math.min(vw / this.designWidth, vh / this.designHeight);
this._canvas.style.transform = `scale(${s})`;
}
_onResize() { this._fit(); }
_onMouseMove() {
// Keep overlay visible while mouse moves; hide after idle.
this._flashOverlay();
}
_onTapBack(e) {
e.preventDefault();
this._go(this._index - 1, 'tap');
}
_onTapForward(e) {
e.preventDefault();
this._go(this._index + 1, 'tap');
}
_onKey(e) {
// Ignore when the user is typing.
const t = e.target;
if (t && (t.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName))) return;
if (e.metaKey || e.ctrlKey || e.altKey) return;
const key = e.key;
let handled = true;
if (key === 'ArrowRight' || key === 'PageDown' || key === ' ' || key === 'Spacebar') {
this._go(this._index + 1, 'keyboard');
} else if (key === 'ArrowLeft' || key === 'PageUp') {
this._go(this._index - 1, 'keyboard');
} else if (key === 'Home') {
this._go(0, 'keyboard');
} else if (key === 'End') {
this._go(this._slides.length - 1, 'keyboard');
} else if (key === 'r' || key === 'R') {
this._go(0, 'keyboard');
} else if (/^[0-9]$/.test(key)) {
// 1..9 jump to that slide; 0 jumps to 10.
const n = key === '0' ? 9 : parseInt(key, 10) - 1;
if (n < this._slides.length) this._go(n, 'keyboard');
} else {
handled = false;
}
if (handled) {
e.preventDefault();
this._flashOverlay();
}
}
_go(i, reason = 'api') {
if (!this._slides.length) return;
const clamped = Math.max(0, Math.min(this._slides.length - 1, i));
if (clamped === this._index) {
this._flashOverlay();
return;
}
this._index = clamped;
this._applyIndex({ showOverlay: true, broadcast: true, reason });
}
// Public API ------------------------------------------------------------
/** Current slide index (0-based). */
get index() { return this._index; }
/** Total slide count. */
get length() { return this._slides.length; }
/** Programmatically navigate. */
goTo(i) { this._go(i, 'api'); }
next() { this._go(this._index + 1, 'api'); }
prev() { this._go(this._index - 1, 'api'); }
reset() { this._go(0, 'api'); }
}
if (!customElements.get('deck-stage')) {
customElements.define('deck-stage', DeckStage);
}
})();
{
"schema_version": 1,
"pack_name": "Beautiful HTML Templates - Bold Design Pack",
"source_repo": "zarazhangrui/beautiful-html-templates",
"template_count": 34,
"usage": {
"selection": "Read this compact index first to shortlist bold templates from metadata.",
"previews": "For title-slide previews, read only the preview_md files for the shortlisted bold candidates.",
"final_generation": "After the user chooses a bold template, read exactly that template design_md before generating the full deck.",
"never": "Do not bulk-read templates/*/design.md and do not read template.html unless the selected design.md is missing a critical implementation detail."
},
"frontend_slides_policy": {
"layout_model": "fixed-stage",
"canvas_width": 1920,
"canvas_height": 1080,
"scaling": "scale-stage-to-viewport",
"mobile_behavior": "preserve 16:9 stage; letterbox or pillarbox instead of reflowing slide content"
},
"templates": [
{
"slug": "8-bit-orbit",
"name": "8-Bit Orbit",
"tagline": "Pixel-art neon arcade aesthetic on a deep navy void.",
"mood": [
"retro-tech",
"playful",
"cyberpunk",
"energetic"
],
"tone": [
"geeky",
"neon",
"rebellious",
"sci-fi"
],
"formality": "low",
"density": "medium",
"scheme": "dark",
"best_for": "Anything that should feel like a CRT screen at 2am: cyberpunk, gaming, web3, indie dev tools, hackathon demos. Just as good for a tech talk that wants to lean into nostalgic-digital craft, a synthwave brand deck, or a creative review that wants to feel like a console.",
"avoid_for": "Contexts where the dark neon palette would actively work against the message — quiet institutional finance disclosures, healthcare patient-facing materials, traditional luxury.",
"preview_md": "bold-template-pack/templates/8-bit-orbit/preview.md",
"design_md": "bold-template-pack/templates/8-bit-orbit/design.md"
},
{
"slug": "biennale-yellow",
"name": "Biennale Yellow",
"tagline": "Solar yellow on warm parchment with deep indigo serif and atmospheric sun-glow gradients.",
"mood": [
"editorial",
"atmospheric",
"warm",
"cultural-institution",
"poster-like"
],
"tone": [
"literary",
"considered",
"contemplative",
"warm-modern",
"Dutch-editorial"
],
"formality": "high",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel like an art-biennale poster or a museum's annual programme: exhibition decks, arts-institution announcements, design conference brochures, curatorial pitches, literary publications, studio retrospectives. Equally good for any deck wanting Dutch-editorial atmosphere with an unmistakable single-color signature.",
"avoid_for": "Decks that need visual punch or saturated multi-color energy — the warm-paper canvas and one-yellow palette are intentionally quiet and atmospheric.",
"preview_md": "bold-template-pack/templates/biennale-yellow/preview.md",
"design_md": "bold-template-pack/templates/biennale-yellow/design.md"
},
{
"slug": "block-frame",
"name": "BlockFrame",
"tagline": "Neobrutalist deck with pastel-neon color blocks and chunky black borders.",
"mood": [
"bold",
"playful",
"graphic",
"fresh"
],
"tone": [
"confident",
"graphic",
"pop",
"design-led"
],
"formality": "medium-low",
"density": "high",
"scheme": "light",
"best_for": "Anything that should feel pop-graphic and design-led: indie SaaS launches, agency credentials, creative reviews, brand redesigns. Also a strong unexpected pick for tech, finance, or research when the speaker wants to land as confident and contemporary rather than buttoned-up.",
"avoid_for": "Contexts that require quiet institutional restraint or traditional weight (regulated disclosures, formal legal briefs).",
"preview_md": "bold-template-pack/templates/block-frame/preview.md",
"design_md": "bold-template-pack/templates/block-frame/design.md"
},
{
"slug": "blue-professional",
"name": "Blue Professional",
"tagline": "Cream paper background with electric cobalt blue accents; clean modern professional.",
"mood": [
"professional",
"modern",
"calm",
"trustworthy"
],
"tone": [
"clean",
"considered",
"polished",
"neutral"
],
"formality": "medium-high",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel modern-considered and lightly authoritative: B2B SaaS pitches, consulting deliverables, advisory updates, investor reports. Also a clean, tasteful choice whenever you want to read as professional without going stiff — research synthesis, internal reviews, brand work for service businesses.",
"avoid_for": "Contexts where the deck should feel hot, playful, or intentionally informal — the cool electric-blue restraint will read as overly polished.",
"preview_md": "bold-template-pack/templates/blue-professional/preview.md",
"design_md": "bold-template-pack/templates/blue-professional/design.md"
},
{
"slug": "bold-poster",
"name": "Bold Poster",
"tagline": "Editorial poster aesthetic with massive Shrikhand display and a single fire-engine red accent.",
"mood": [
"bold",
"editorial",
"loud",
"confident"
],
"tone": [
"dramatic",
"graphic",
"sharp",
"intentional"
],
"formality": "medium",
"density": "low",
"scheme": "light",
"best_for": "Anything that should land like a magazine cover: brand manifestos, founder vision decks, editorial / cultural pitches, creative reviews. Excellent any time you want a few words to feel like a poster — including unexpected fits like a tech keynote or a finance manifesto that wants to be quotable.",
"avoid_for": "Decks that need to communicate dense information per slide — the layout is built around a few large statements, not paragraphs of detail.",
"preview_md": "bold-template-pack/templates/bold-poster/preview.md",
"design_md": "bold-template-pack/templates/bold-poster/design.md"
},
{
"slug": "broadside",
"name": "Broadside",
"tagline": "Dark editorial canvas with a single fire orange accent and bilingual Latin/Chinese type stack.",
"mood": [
"editorial",
"dramatic",
"loud",
"newspaper"
],
"tone": [
"graphic",
"punchy",
"literary",
"considered"
],
"formality": "medium-high",
"density": "medium",
"scheme": "dark",
"best_for": "Anything that should land like a broadside newspaper headline: brand manifestos, magazine and cultural pitches, design talks, bilingual EN/CN decks, founder vision statements. Also a striking pick for tech, research, or business decks that want a dramatic single-accent editorial feel.",
"avoid_for": "Decks that need to feel quiet, warm, or institutionally traditional — the dark canvas with fire-orange accent commits to drama.",
"preview_md": "bold-template-pack/templates/broadside/preview.md",
"design_md": "bold-template-pack/templates/broadside/design.md"
},
{
"slug": "capsule",
"name": "Capsule",
"tagline": "Modular pill-shaped cards on warm bone with a full pastel-pop palette.",
"mood": [
"playful",
"modern",
"warm",
"fresh",
"fun"
],
"tone": [
"upbeat",
"graphic",
"approachable",
"cool"
],
"formality": "medium-low",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel modular, modern, and a little Y2K: lifestyle brands, creator portfolios, DTC launches, beauty / wellness, agency credentials. Also fun for a playful tech demo or a research deck that wants pop-art clarity instead of gravitas.",
"avoid_for": "Contexts that require traditional institutional weight — the capsule shapes and pastel pops actively soften authority.",
"preview_md": "bold-template-pack/templates/capsule/preview.md",
"design_md": "bold-template-pack/templates/capsule/design.md"
},
{
"slug": "cartesian",
"name": "Cartesian",
"tagline": "Quiet warm-neutral palette with classical Playfair serifs; tasteful and unhurried.",
"mood": [
"quiet",
"considered",
"elegant",
"warm-minimal"
],
"tone": [
"classical",
"literary",
"restrained",
"confident-quiet"
],
"formality": "high",
"density": "low",
"scheme": "light",
"best_for": "Anything that should feel quiet, considered, and grown-up: investment theses, white papers, advisory work, longform research, gallery / cultural decks. Also a strong choice for editorial features, founder reflections, or any deck where restraint is the message — including across tech and finance.",
"avoid_for": "Decks that need visual heat, multiple accents, or a sense of urgency — the warm-neutral palette is intentionally low-energy.",
"preview_md": "bold-template-pack/templates/cartesian/preview.md",
"design_md": "bold-template-pack/templates/cartesian/design.md"
},
{
"slug": "cobalt-grid",
"name": "Cobalt Grid",
"tagline": "Electric cobalt serifs on a graph-paper canvas, anchored by stair-stepped pixel-glitch decorations and slim hairline rules.",
"mood": [
"editorial",
"design-research",
"studious",
"modernist",
"tech-print",
"monochrome"
],
"tone": [
"considered",
"literary",
"studious",
"quietly-modern",
"editorial"
],
"formality": "high",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel like a quietly serious design / research bulletin, art publication, or curated trend report. Strong for studio annuals, agency capabilities decks, design-research publications, architecture / art / academic decks, and any deck wanting one strict accent colour and a printed-ledger calmness rather than corporate polish.",
"avoid_for": "Decks that need warmth, multi-colour energy, or a casual / playful voice — the strict cobalt + cream + grid palette is intentionally austere.",
"preview_md": "bold-template-pack/templates/cobalt-grid/preview.md",
"design_md": "bold-template-pack/templates/cobalt-grid/design.md"
},
{
"slug": "coral",
"name": "Coral",
"tagline": "Cream and coral on near-black, set in oversized Bebas Neue.",
"mood": [
"bold",
"warm",
"modern",
"confident"
],
"tone": [
"graphic",
"punchy",
"magazine"
],
"formality": "medium",
"density": "medium",
"scheme": "mixed",
"best_for": "Anything that should feel warm-graphic and editorial: fashion, beauty, fitness, F&B, lifestyle brands, agency credentials. Just as strong for a creator portfolio, a manifesto, or a tech / research deck that wants warmth and a single bold accent instead of corporate cool.",
"avoid_for": "Contexts that should feel quiet or institutional — the coral accent and oversized Bebas Neue commit hard to a confident magazine voice.",
"preview_md": "bold-template-pack/templates/coral/preview.md",
"design_md": "bold-template-pack/templates/coral/design.md"
},
{
"slug": "creative-mode",
"name": "Creative Mode",
"tagline": "Cream paper canvas with confident multi-color (green, pink, orange, yellow) accents and Archivo Black display.",
"mood": [
"creative",
"confident",
"playful",
"design-led"
],
"tone": [
"graphic",
"expressive",
"modern"
],
"formality": "medium",
"density": "medium-high",
"scheme": "light",
"best_for": "Anything that should feel design-led and confident: creative agency pitches, design studio decks, ad shop credentials, brand creative reviews, art-direction reviews. Also a great unexpected pick for a tech talk, research findings, or finance review when the speaker wants to lead with taste rather than convention.",
"avoid_for": "Contexts that demand institutional restraint and a quiet authority — the saturated multi-accent palette will read as expressive, not formal.",
"preview_md": "bold-template-pack/templates/creative-mode/preview.md",
"design_md": "bold-template-pack/templates/creative-mode/design.md"
},
{
"slug": "daisy-days",
"name": "Daisy Days",
"tagline": "Cheerful pastel deck with hand-drawn daisies, stars, and rainbows. Friendly, soft, and warm.",
"mood": [
"cheerful",
"playful",
"warm",
"sunny",
"wholesome"
],
"tone": [
"friendly",
"soft",
"encouraging",
"approachable",
"lighthearted"
],
"formality": "low",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel friendly, soft, and joyful: educational content, kids and family, wellness programs, community workshops, creator portfolios for craft / illustration. Also lovely for an unexpected playful internal kickoff, a wedding planning deck, or any moment where warmth is the message — including across tech or business contexts.",
"avoid_for": "Contexts where the audience explicitly expects authority and precision — the hand-drawn pastel SVG decorations are the opposite of buttoned-up.",
"preview_md": "bold-template-pack/templates/daisy-days/preview.md",
"design_md": "bold-template-pack/templates/daisy-days/design.md"
},
{
"slug": "editorial-forest",
"name": "Editorial Forest",
"tagline": "Forest green, dusty pink, and warm cream meet Source Serif 4 in a quiet, intentional quarterly-review deck.",
"mood": [
"editorial",
"quiet",
"considered",
"warm",
"intentional"
],
"tone": [
"literary",
"thoughtful",
"warm",
"low-pressure"
],
"formality": "medium",
"density": "medium",
"scheme": "mixed",
"best_for": "Anything that should feel like a considered editorial — quarterly reviews, internal readouts, studio updates, creative-agency presentations. Equally good for any deck that wants to feel warm and unhurried rather than corporate, including research recaps, book or program announcements, and team retrospectives.",
"avoid_for": "Contexts that need to feel urgent, punchy, or sales-driven — the palette and rhythm are intentionally quiet.",
"preview_md": "bold-template-pack/templates/editorial-forest/preview.md",
"design_md": "bold-template-pack/templates/editorial-forest/design.md"
},
{
"slug": "editorial-tri-tone",
"name": "Editorial Tri-Tone",
"tagline": "Three-color editorial system: dusty pink, mustard cream, and deep burgundy, set in Bricolage + Instrument Serif.",
"mood": [
"editorial",
"warm",
"intentional",
"moody"
],
"tone": [
"literary",
"warm",
"considered",
"stylish"
],
"formality": "medium-high",
"density": "medium",
"scheme": "mixed",
"best_for": "Anything that should feel like a fashion-magazine spread: editorial pitches, fashion brand decks, lifestyle media, art direction reviews. Equally good for any deck — including tech, research, or business — that wants tri-tone discipline and serif/sans contrast instead of the usual neutrals.",
"avoid_for": "Decks that need to read as soft or comforting — the burgundy/pink/cream tri-tone is intentionally high-contrast and styled.",
"preview_md": "bold-template-pack/templates/editorial-tri-tone/preview.md",
"design_md": "bold-template-pack/templates/editorial-tri-tone/design.md"
},
{
"slug": "emerald-editorial",
"name": "Emerald Editorial",
"tagline": "A magazine-cover business deck: emerald + navy + paper, double-rule masthead ornaments, and a bold Bodoni-style display serif.",
"mood": [
"editorial",
"considered",
"confident",
"magazine-cover"
],
"tone": [
"literary",
"authoritative",
"warm",
"designed"
],
"formality": "medium-high",
"density": "medium",
"scheme": "mixed",
"best_for": "Anything that should feel like the front of a serious magazine, including but not limited to leadership readouts, planning-office reviews, and strategy briefings. The double-rule masthead ornament gives it editorial gravitas without making it stiff — also a great unexpected pick for product launches or research recaps that want to feel considered rather than corporate.",
"avoid_for": "Contexts that need to read as quiet, neutral, or institutionally restrained — the emerald field is too saturated to disappear into the background.",
"preview_md": "bold-template-pack/templates/emerald-editorial/preview.md",
"design_md": "bold-template-pack/templates/emerald-editorial/design.md"
},
{
"slug": "grove",
"name": "Grove",
"tagline": "Forest-green canvas with cream type, classical Playfair serifs, and a single rust accent.",
"mood": [
"organic",
"considered",
"warm",
"literary",
"natural"
],
"tone": [
"classical",
"warm",
"considered",
"patient"
],
"formality": "medium-high",
"density": "medium",
"scheme": "mixed",
"best_for": "Anything that should feel organic, considered, and grown-up: sustainability and wellness brands, outdoor / nature products, wineries and restaurants, literary or arts decks, advisory deliverables, bilingual EN/CN reports. Also a calm, distinctive choice for tech, research, or business decks that want patience over urgency.",
"avoid_for": "Decks that need neon energy or rapid-fire pop — the forest-green canvas and Playfair serif commit to a slow, classical voice.",
"preview_md": "bold-template-pack/templates/grove/preview.md",
"design_md": "bold-template-pack/templates/grove/design.md"
},
{
"slug": "long-table",
"name": "Long Table",
"tagline": "Warm cream and rust-red supper-club aesthetic with bold uppercase grotesk headlines, Fraunces serifs, and pill-shaped outlined buttons.",
"mood": [
"warm",
"intimate",
"modern",
"friendly",
"small-batch",
"social",
"hospitality"
],
"tone": [
"warm",
"playful",
"considered",
"social",
"magazine-friendly",
"modern-editorial"
],
"formality": "medium",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel like a warm, intimate, modern hospitality / community brand: supper clubs, dinner series, small restaurants, creative-studio events, membership pitches, lifestyle and wine brands. Equally good for any deck wanting a single warm accent colour, mixed-weight typography, and a social-media-aware modern-editorial voice.",
"avoid_for": "Decks that need corporate polish, technical density, or a cold / minimalist register — the rust-red palette and bold serif mix are intentionally warm and people-facing.",
"preview_md": "bold-template-pack/templates/long-table/preview.md",
"design_md": "bold-template-pack/templates/long-table/design.md"
},
{
"slug": "mat",
"name": "Mat",
"tagline": "Dark sage canvas with bone paper and burnt-orange accent; mid-century modern with wood undertones.",
"mood": [
"warm-modern",
"considered",
"tactile",
"mid-century"
],
"tone": [
"warm",
"design-led",
"intentional",
"considered"
],
"formality": "medium",
"density": "medium",
"scheme": "mixed",
"best_for": "Anything that should feel mid-century, tactile, and intentional: design studio credentials, architecture / interior brands, ceramics / craft / furniture, advisory decks. Also a warm, distinctive choice for tech, research, or business decks that want a considered analog feel instead of digital-cool.",
"avoid_for": "Contexts that need fast tech energy or institutional restraint — the muted sage and burnt-orange palette is intentionally warm and slow.",
"preview_md": "bold-template-pack/templates/mat/preview.md",
"design_md": "bold-template-pack/templates/mat/design.md"
},
{
"slug": "monochrome",
"name": "Monochrome",
"tagline": "Ivory ledger paper with all-black type; Lora serif headlines, Jost body, no color at all.",
"mood": [
"restrained",
"literary",
"archival",
"ledger"
],
"tone": [
"literary",
"considered",
"neutral",
"honest"
],
"formality": "high",
"density": "high",
"scheme": "light",
"best_for": "Anything that should feel like a hand-typeset ledger: user research synthesis, white papers, longform reports, academic and policy briefs, advisory deliverables, bilingual EN/CN reports. Equally good for tech, design, or brand decks that want their words to be the only thing on the page.",
"avoid_for": "Decks that need visual personality or color-led storytelling — the all-ink palette is intentionally austere.",
"preview_md": "bold-template-pack/templates/monochrome/preview.md",
"design_md": "bold-template-pack/templates/monochrome/design.md"
},
{
"slug": "neo-grid-bold",
"name": "Neo-Grid Bold",
"tagline": "Editorial neo-brutalism with a single neon yellow accent on off-white paper.",
"mood": [
"confident",
"punchy",
"editorial",
"modern"
],
"tone": [
"bold",
"minimal",
"design-led",
"graphic"
],
"formality": "medium",
"density": "high",
"scheme": "light",
"best_for": "Anything that should feel confident and editorial-graphic: design-led pitches, brand work, founder talks, conference keynotes. Excellent for stat-heavy slides, comparisons, and process flows. Just as strong for tech, research, or finance when the speaker wants to read as design-led rather than corporate.",
"avoid_for": "Contexts that need to feel quiet, traditional, or warm — the neon-yellow accent and uppercase display commit to a confident editorial voice.",
"preview_md": "bold-template-pack/templates/neo-grid-bold/preview.md",
"design_md": "bold-template-pack/templates/neo-grid-bold/design.md"
},
{
"slug": "peoples-platform",
"name": "People's Platform (Block & Bold)",
"tagline": "Activist poster energy: blue, orange, red on cream, with Alfa Slab + Caveat Brush.",
"mood": [
"activist",
"loud",
"graphic",
"honest"
],
"tone": [
"punchy",
"direct",
"expressive",
"warm-bold"
],
"formality": "medium-low",
"density": "medium-high",
"scheme": "light",
"best_for": "Anything that should feel honest, loud, and graphic: cultural commentary, manifestos, civic and community decks, design talks, campaign pitches. Excellent for founder-vision moments, mission statements, or any deck — including across industries — that wants protest-poster energy instead of corporate polish.",
"avoid_for": "Contexts where institutional restraint is the actual goal — the saturated political-poster palette commits hard to expressive energy.",
"preview_md": "bold-template-pack/templates/peoples-platform/preview.md",
"design_md": "bold-template-pack/templates/peoples-platform/design.md"
},
{
"slug": "pin-and-paper",
"name": "Pin & Paper",
"tagline": "Yellow paper with safety-pin illustrations, ink-blue handwritten Caveat, paper-grain texture.",
"mood": [
"crafted",
"handmade",
"warm",
"thoughtful",
"literary"
],
"tone": [
"literary",
"intimate",
"warm",
"grounded"
],
"formality": "medium",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel hand-crafted, warm, and literary: qualitative research findings, founder reflections, longform brand stories, workshop debriefs. The signature safety-pin illustrations and paper-grain texture make it especially good for any deck — including tech or business — that wants personality and warmth over polish.",
"avoid_for": "Decks that need to feel digital-native polished or rigorously data-driven — handwritten Caveat is intentionally informal.",
"preview_md": "bold-template-pack/templates/pin-and-paper/preview.md",
"design_md": "bold-template-pack/templates/pin-and-paper/design.md"
},
{
"slug": "pink-script",
"name": "Pink Script — After Hours",
"tagline": "Black canvas, hot pink accent, pearl-cream paper, Instrument Serif headlines: late-night editorial luxury.",
"mood": [
"nocturnal",
"moody",
"intentional",
"luxe",
"expressive"
],
"tone": [
"literary",
"sultry",
"considered",
"magazine"
],
"formality": "medium-high",
"density": "low",
"scheme": "dark",
"best_for": "Anything that should feel nocturnal, intentional, and a little luxe: fashion brand decks, creator personal brands, after-hours / nightlife / spirits launches, luxury product reveals, editorial features. Also a striking unexpected pick for a tech keynote, research synthesis, or business pitch that wants to land with magnetic confidence.",
"avoid_for": "Daytime corporate-professional and traditional B2B contexts where the dark canvas with hot-pink accent reads as too styled or too expressive.",
"preview_md": "bold-template-pack/templates/pink-script/preview.md",
"design_md": "bold-template-pack/templates/pink-script/design.md"
},
{
"slug": "playful",
"name": "Playful",
"tagline": "Sun-warm peach background with Syne display: a friendly indie launch deck.",
"mood": [
"warm",
"approachable",
"indie",
"friendly"
],
"tone": [
"upbeat",
"informal",
"welcoming"
],
"formality": "low",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel warm, indie, and approachable: creator portfolios, indie product launches, lifestyle brands, small-business pitches, newsletter / community decks. Also welcoming for any deck — including tech or research — that wants to feel friendly and human rather than corporate.",
"avoid_for": "Contexts where institutional credibility matters more than warmth — the peach palette is intentionally informal.",
"preview_md": "bold-template-pack/templates/playful/preview.md",
"design_md": "bold-template-pack/templates/playful/design.md"
},
{
"slug": "raw-grid",
"name": "Raw Grid",
"tagline": "Neo-brutalist deck with thick borders, offset shadows, and a pink/sage/ink palette.",
"mood": [
"raw",
"punchy",
"energetic",
"confident"
],
"tone": [
"direct",
"modern",
"no-nonsense",
"graphic"
],
"formality": "medium-low",
"density": "high",
"scheme": "light",
"best_for": "Anything that should feel direct and graphic-confident: founder pitches, accelerator demos, brand decks, indie launches, creator portfolios. Strong for stat slides, comparison tables, and process flows. Equally good for tech, research, or finance when the speaker wants the deck to feel scrappy-confident rather than buttoned-up.",
"avoid_for": "Contexts that need to feel soft, warm, or intentionally quiet — the brutalist borders and offset shadows commit to a graphic voice.",
"preview_md": "bold-template-pack/templates/raw-grid/preview.md",
"design_md": "bold-template-pack/templates/raw-grid/design.md"
},
{
"slug": "retro-windows",
"name": "Retro Windows",
"tagline": "Windows 95 chrome: gray title bars, MS Sans Serif, pixel typography, full nostalgia.",
"mood": [
"nostalgic",
"retro",
"geeky",
"playful"
],
"tone": [
"winking",
"nostalgic",
"geeky",
"fun"
],
"formality": "low",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel knowingly nostalgic: retro gaming, Y2K-aesthetic brands, creator portfolios with a 90s vibe, tech-history talks, deliberately tongue-in-cheek decks. A great choice anywhere a playful retro reference is the entire point.",
"avoid_for": "Decks that need to read as modern, elegant, or institutionally credible — the Win95 chrome will always read as a costume.",
"preview_md": "bold-template-pack/templates/retro-windows/preview.md",
"design_md": "bold-template-pack/templates/retro-windows/design.md"
},
{
"slug": "retro-zine",
"name": "Retro Zine",
"tagline": "Beige paper with green accent and Bebas Neue + Caveat: a riso-printed zine in HTML form.",
"mood": [
"crafted",
"lo-fi",
"underground",
"warm-retro"
],
"tone": [
"scrappy",
"warm",
"intentional",
"DIY"
],
"formality": "medium-low",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel printed, lo-fi, and crafted: indie zines and publications, music / arts brands, creator portfolios, small-batch craft launches, community decks. Also a great underdog choice for tech, research, or business decks that want a riso-print warmth instead of digital polish.",
"avoid_for": "Contexts that demand digital-native polish or fast modern-tech energy — the layered zine aesthetic intentionally feels handmade.",
"preview_md": "bold-template-pack/templates/retro-zine/preview.md",
"design_md": "bold-template-pack/templates/retro-zine/design.md"
},
{
"slug": "sakura-chroma",
"name": "Sakura Chroma",
"tagline": "Vintage Japanese cassette-package aesthetic: cream paper, diagonal rainbow ribbons, condensed bold type, JIS-style spec checkboxes.",
"mood": [
"retro",
"playful",
"kawaii-tech",
"warm",
"tactile",
"product-catalogue"
],
"tone": [
"playful",
"confident",
"warm",
"tactile",
"80s-Japanese-tech"
],
"formality": "low",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel like a vintage Japanese cassette package or a TDK / Sony / Sakura Color product catalogue: indie hardware brand decks, music-label release schedules, analog studio retrospectives, zine and magazine pitches, kawaii-tech product launches, creative-studio annual reports. Equally good for any deck wanting bold colour, condensed display type, and a tactile printed-product personality.",
"avoid_for": "Decks that need restrained, corporate, or quiet typography — the bold condensed lockups, ribbon stripes, and primary-colour palette are intentionally loud and product-page-y.",
"preview_md": "bold-template-pack/templates/sakura-chroma/preview.md",
"design_md": "bold-template-pack/templates/sakura-chroma/design.md"
},
{
"slug": "scatterbrain",
"name": "Scatterbrain",
"tagline": "Post-it inspired: pastel sticky notes, Caveat handwriting, Shrikhand and Zilla Slab type stack.",
"mood": [
"playful",
"creative",
"warm",
"messy-on-purpose",
"workshop"
],
"tone": [
"informal",
"warm",
"expressive",
"human"
],
"formality": "low",
"density": "high",
"scheme": "light",
"best_for": "Anything that should feel like a designer's whiteboard: brainstorms, workshops, creative-agency credentials, design-thinking sessions, ideation pitches, art-direction reviews. Equally fun for any deck — including tech, research, or business — that wants to read as in-progress thinking rather than polished conclusions.",
"avoid_for": "Contexts that demand precision and institutional weight — the post-it sticky-note aesthetic intentionally reads as warm and unfinished.",
"preview_md": "bold-template-pack/templates/scatterbrain/preview.md",
"design_md": "bold-template-pack/templates/scatterbrain/design.md"
},
{
"slug": "signal",
"name": "Signal",
"tagline": "Deep navy canvas with bone paper and a single muted-gold accent; institutional with quiet weight.",
"mood": [
"institutional",
"trustworthy",
"considered",
"weighty"
],
"tone": [
"sober",
"polished",
"established",
"literary"
],
"formality": "high",
"density": "high",
"scheme": "mixed",
"best_for": "Anything that should feel weighty, considered, and credibly institutional: investor decks, board presentations, consulting deliverables, legal / policy briefs, advisory pitches. Also a strong choice for tech, research, or brand work that wants to read as quietly authoritative rather than loud.",
"avoid_for": "Contexts that should feel hot, fast, or intentionally playful — the navy + gold restraint commits to a sober voice.",
"preview_md": "bold-template-pack/templates/signal/preview.md",
"design_md": "bold-template-pack/templates/signal/design.md"
},
{
"slug": "soft-editorial",
"name": "Soft Editorial",
"tagline": "Cormorant Garamond serif on warm paper with sage, blush, and lemon accents.",
"mood": [
"literary",
"elegant",
"quiet",
"warm-classical"
],
"tone": [
"literary",
"considered",
"warm",
"magazine"
],
"formality": "high",
"density": "low",
"scheme": "light",
"best_for": "Anything that should feel literary, elegant, and unhurried: editorial features, longform brand stories, gallery / museum decks, advisory deliverables, wedding / lifestyle media, founder essays. Equally good for tech, research, or business decks that want a Sunday-supplement warmth instead of corporate polish.",
"avoid_for": "Decks that need visual heat or punch — the warm-paper palette and Cormorant serif are intentionally quiet.",
"preview_md": "bold-template-pack/templates/soft-editorial/preview.md",
"design_md": "bold-template-pack/templates/soft-editorial/design.md"
},
{
"slug": "stencil-tablet",
"name": "Stencil & Tablet",
"tagline": "Bone paper with stencil-cut headlines and a six-color earth palette: archaeology meets brand.",
"mood": [
"archival",
"earthy",
"tactile",
"considered",
"graphic"
],
"tone": [
"weighty",
"considered",
"tactile",
"literary"
],
"formality": "medium-high",
"density": "medium",
"scheme": "light",
"best_for": "Anything that should feel archival, tactile, and weighty-graphic: museum and cultural-institution decks, art / architecture brands, longform research, heritage and craft brands, manifestos. A great choice anytime — including across tech and business — when you want the deck to feel like a field manual rather than a slide deck.",
"avoid_for": "Contexts that demand digital-native polish or playful pop — the stencil-cut display and earth-tone palette commit to a deliberate analog feel.",
"preview_md": "bold-template-pack/templates/stencil-tablet/preview.md",
"design_md": "bold-template-pack/templates/stencil-tablet/design.md"
},
{
"slug": "studio",
"name": "Studio",
"tagline": "Black canvas with electric-yellow type; high-voltage design studio aesthetic.",
"mood": [
"electric",
"bold",
"graphic",
"design-led",
"high-contrast"
],
"tone": [
"graphic",
"loud",
"modern",
"intentional"
],
"formality": "medium",
"density": "medium",
"scheme": "dark",
"best_for": "Anything that should feel electric and design-led: studio credentials, creative agency pitches, brand showcases, art-direction reviews, fashion / sneaker brand work. Also a striking unexpected choice for tech, research, or business decks where the speaker wants the deck to *be* a brand statement.",
"avoid_for": "Contexts that should feel quiet or institutional — the black-and-electric-yellow palette is the loudest in the library.",
"preview_md": "bold-template-pack/templates/studio/preview.md",
"design_md": "bold-template-pack/templates/studio/design.md"
},
{
"slug": "vellum",
"name": "Vellum",
"tagline": "Deep navy canvas with warm-yellow Cormorant serifs and a single dusty teal accent. A quiet, scholarly aesthetic.",
"mood": [
"scholarly",
"literary",
"considered",
"quiet",
"intellectual"
],
"tone": [
"literary",
"considered",
"patient",
"intelligent"
],
"formality": "high",
"density": "low",
"scheme": "dark",
"best_for": "Anything that should feel scholarly, literary, and quietly intelligent: research synthesis, white papers, academic and policy briefs, advisory deliverables, longform editorial pieces, founder reflections. Equally strong for any deck — including tech, business, or creator work — that wants a calm, considered atmosphere instead of energetic visuals.",
"avoid_for": "Contexts that need visual heat or pop — the navy + warm-yellow Cormorant aesthetic is intentionally low-tempo.",
"preview_md": "bold-template-pack/templates/vellum/preview.md",
"design_md": "bold-template-pack/templates/vellum/design.md"
}
]
}
---
version: alpha
name: 8-Bit Orbit
description: A retro-futuristic pixel-art presentation system that fuses 16-bit arcade nostalgia with editorial discipline. Display type runs in Tektur (a chunky geometric display face built on pixel-grid logic) paired with Chakra Petch for body and Space Mono for code-flavored labels and tabular data. The palette pivots on a deep cosmic navy (`#0F1B3D` / `#0A0E27`) lit by three saturated neons — cyan, hot pink, and a high-key yellow — with a soft lavender pastel for warm reprieves. Depth is built from stacked hard offset shadows in 4px increments (the pixel unit), CRT scanlines, atmospheric grain, vignettes, and animated starfields. The effect sits between an arcade cabinet and a Tron-era boardroom — unmistakably digital, intentionally lo-fi, and engineered to feel as if it just booted up.
colors:
dark-void: "#0A0E27"
deep-navy: "#0F1B3D"
neon-cyan: "#5EDCF4"
neon-pink: "#F0A6CA"
neon-yellow: "#F4D03F"
soft-lavender: "#E2D5F2"
white: "#FFFFFF"
shadows:
pixel-stack-cyan-yellow: "4px 0 0 0 {colors.deep-navy}, 0 4px 0 0 {colors.deep-navy}, 4px 4px 0 0 {colors.deep-navy}, 8px 4px 0 0 {colors.neon-yellow}, 4px 8px 0 0 {colors.neon-yellow}, 8px 8px 0 0 {colors.neon-yellow}"
pixel-stack-pink-cyan: "4px 0 0 0 {colors.deep-navy}, 0 4px 0 0 {colors.deep-navy}, 4px 4px 0 0 {colors.deep-navy}, 8px 4px 0 0 {colors.neon-cyan}, 4px 8px 0 0 {colors.neon-cyan}, 8px 8px 0 0 {colors.neon-cyan}"
pixel-l-shape: "4px 0 0 0 {colors.deep-navy}, 0 4px 0 0 {colors.deep-navy}, 4px 4px 0 0 {colors.deep-navy}"
pixel-text-shadow: "4px 4px 0 {colors.neon-yellow}, 8px 8px 0 {colors.deep-navy}"
pixel-text-shadow-small: "3px 3px 0 {colors.deep-navy}"
card-offset: "6px 6px 0 rgba(15, 27, 61, 0.15)"
card-featured: "8px 8px 0 {colors.neon-yellow}"
typography:
pixel-hero:
fontFamily: "'Tektur', cursive"
fontSize: "clamp(48px, 10vw, 128px)"
fontWeight: 900
lineHeight: 1.05
letterSpacing: 0.04em
display:
fontFamily: "'Tektur', cursive"
fontSize: "clamp(32px, 5vw, 64px)"
fontWeight: 700
lineHeight: 1.15
headline:
fontFamily: "'Tektur', cursive"
fontSize: "clamp(24px, 3.5vw, 45px)"
fontWeight: 700
lineHeight: 1.15
subhead:
fontFamily: "'Tektur', cursive"
fontSize: "clamp(17.6px, 2vw, 24px)"
fontWeight: 700
lineHeight: 1.15
stat-number:
fontFamily: "'Tektur', cursive"
fontSize: "clamp(32px, 4vw, 56px)"
fontWeight: 900
lineHeight: 1
body:
fontFamily: "'Chakra Petch', sans-serif"
fontSize: "clamp(14.4px, 1.2vw, 18.4px)"
fontWeight: 400
lineHeight: 1.7
hero-tagline:
fontFamily: "'Chakra Petch', sans-serif"
fontSize: "clamp(14.4px, 1.5vw, 19.2px)"
fontWeight: 400
lineHeight: 1.8
quote-body:
fontFamily: "'Chakra Petch', sans-serif"
fontSize: "clamp(17.6px, 2.2vw, 25.6px)"
fontWeight: 500
lineHeight: 1.8
label-pill:
fontFamily: "'Space Mono', monospace"
fontSize: 12px
fontWeight: 700
lineHeight: 1
letterSpacing: 0.2em
textTransform: uppercase
label-eyebrow:
fontFamily: "'Space Mono', monospace"
fontSize: 13.6px
fontWeight: 400
lineHeight: 1
letterSpacing: 0.3em
textTransform: uppercase
badge:
fontFamily: "'Space Mono', monospace"
fontSize: 11.2px
fontWeight: 400
lineHeight: 1
letterSpacing: 0.1em
textTransform: uppercase
chart-value:
fontFamily: "'Space Mono', monospace"
fontSize: 12px
fontWeight: 700
lineHeight: 1
chart-label:
fontFamily: "'Space Mono', monospace"
fontSize: 11.2px
fontWeight: 400
lineHeight: 1
letterSpacing: 0.05em
date-chip:
fontFamily: "'Space Mono', monospace"
fontSize: 11.2px
fontWeight: 400
lineHeight: 1
counter:
fontFamily: "'Space Mono', monospace"
fontSize: 12.8px
fontWeight: 400
lineHeight: 1
letterSpacing: 0.15em
spacing:
pixel-unit: 4px
pad-slide-y: "3vh"
pad-slide-x: "4vw"
pad-card-lg: "32px 40px"
pad-card-md: "28px"
pad-card-sm: "16px 20px"
gap-grid-lg: 32px
gap-grid-md: 24px
gap-grid-sm: 16px
content-max-width: 1200px
canvas:
width: 100vw
height: 100vh
components:
label-pill:
background: "{colors.deep-navy}"
color: "{colors.neon-yellow}"
padding: "6px 14px"
fontSize: 12px
fontWeight: 700
letterSpacing: 0.2em
textTransform: uppercase
fontFamily: "'Space Mono', monospace"
description: "Universal section tag. Default fill is deep-navy with neon-yellow text. Variant fills swap text color so the pill stays legible (e.g., navy bg with cyan text, navy bg with pink text)."
pixel-button:
background: "{colors.neon-cyan}"
color: "{colors.deep-navy}"
padding: "16px 36px"
fontFamily: "'Tektur', cursive"
fontWeight: 700
letterSpacing: 0.08em
textTransform: uppercase
boxShadow: "{shadows.pixel-stack-cyan-yellow}"
description: "The signature stacked-shadow CTA. The pink variant swaps cyan body for pink and yellow shadow halo for cyan halo."
pixel-corner-bracket:
width: 24px
height: 24px
borderWidth: 4px
description: "Two outward-facing L-shapes (top-left + bottom-right) bracketing a region. Default color is neon-cyan; yellow and pink variants exist. Sits 8px outside the bracketed element."
feature-card:
background: "rgba(255, 255, 255, 0.15)"
backdropFilter: "blur(8px)"
padding: "32px 24px"
border: "2px solid rgba(15, 27, 61, 0.2)"
description: "Frosted-glass card with inset navy L-brackets (top-left + bottom-right) replacing rounded corners. Used on light-surface slides."
stat-block:
background: "rgba(94, 220, 244, 0.08)"
border: "2px solid rgba(94, 220, 244, 0.2)"
padding: "32px 16px"
description: "Cyan-tinted glass stat tile with cyan L-bracket accents at opposite corners. Used on dark surfaces. Stat numeral uses the pixel-text-shadow-small treatment."
bar-track-light:
height: 32px
background: "rgba(15, 27, 61, 0.1)"
description: "Horizontal track for hbar charts on light surfaces. Fill is solid navy/cyan/pink with a yellow offset shadow."
bar-vertical:
background: "{colors.neon-cyan}"
boxShadow: "{shadows.pixel-l-shape}"
description: "Vertical chart bar with three-piece navy L-shadow. Color cycles cyan → pink → yellow."
timeline-node:
width: 24px
height: 24px
background: "{colors.neon-cyan}"
border: "4px solid {colors.deep-navy}"
description: "Square pixel node on timeline rails. Active state swaps fill to neon-yellow."
timeline-rail:
width: 4px
background: "repeating-linear-gradient(to bottom, {colors.deep-navy} 0px, {colors.deep-navy} 16px, transparent 16px, transparent 24px)"
description: "Dashed pixel rail running between timeline nodes."
date-chip:
background: "{colors.deep-navy}"
color: "{colors.neon-cyan}"
padding: "2px 10px"
fontFamily: "'Space Mono', monospace"
fontSize: 11.2px
description: "Small inline date marker on timeline events."
hero-badge:
border: "2px solid {colors.neon-yellow}"
color: "{colors.neon-yellow}"
padding: "8px 16px"
fontFamily: "'Space Mono', monospace"
fontSize: 11.2px
letterSpacing: 0.1em
textTransform: uppercase
description: "Outline-only chip used in clusters under hero headlines."
bg-grid:
backgroundColor: "{colors.dark-void}"
backgroundImage: "linear-gradient(rgba(94, 220, 244, 0.07) 1px, transparent 1px), linear-gradient(90deg, rgba(94, 220, 244, 0.07) 1px, transparent 1px)"
backgroundSize: "40px 40px"
description: "40px cyan-on-navy grid wallpaper for dark surfaces. Pink, cyan, and lavender variants invert the relationship (colored ground with low-opacity navy grid lines)."
scanlines:
background: "repeating-linear-gradient(0deg, transparent 0px, transparent 2px, rgba(10, 14, 39, 0.04) 2px, rgba(10, 14, 39, 0.04) 4px)"
mixBlendMode: multiply
description: "Horizontal CRT scanline overlay applied via ::after at z-index 50. Always present on every slide."
grain:
opacity: 0.035
description: "SVG fractal-noise grain layer applied via ::before at z-index 49. Always present on every slide."
crt-glow:
background: "radial-gradient(ellipse at center, transparent 50%, rgba(10, 14, 39, 0.25) 100%)"
description: "Radial vignette that darkens the corners to mimic a CRT bulge. Applied to dark-surface slides via ::after at z-index 51."
starfield:
description: "Container of small 4-6px colored squares (cyan, yellow, pink) positioned absolutely with a 3s twinkle keyframe. Lives on dark surfaces only."
pixel-particles:
description: "Floating 8px colored squares with an 8s float keyframe. Decorative ambient layer on hero and CTA-type surfaces."
nav-dot:
width: 12px
height: 12px
border: "2px solid {colors.neon-cyan}"
background: transparent
description: "Hollow square pip with a 2px inset cyan fill on active state. Fixed vertical rail at right edge."
quote-line:
width: 60px
height: 4px
background: "{colors.neon-yellow}"
boxShadow: "4px 4px 0 {colors.deep-navy}"
description: "Short yellow rule with navy offset shadow, used as a separator under quote bodies."
---
## 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
8-Bit Orbit is a **retro-futuristic pixel-art presentation system**. Its foundational premise is the **4-pixel unit**: every shadow offset, every border, every corner bracket, every label height resolves to a multiple of 4px. Layouts feel as if they were rasterized on an old CRT and dragged into HTML — and atmospheric overlays (scanlines, grain, vignette glow, animated starfields) reinforce the illusion on every surface.
The type stack is three faces working in concert. **Tektur** is the display face — a chunky, geometric, semi-pixelated grotesque that carries headlines, hero text, stat numerals, and any text that needs to feel like it was drawn on the pixel grid. **Chakra Petch** is the body face — a humanist sans with subtle geometric cuts that reads cleanly at small sizes and avoids fighting Tektur for attention. **Space Mono** is the system face — used exclusively for labels, captions, badges, chart values, dates, and counters. The mono treatment + wide tracking on these elements makes them feel like HUD readouts, not editorial captions.
The palette is built around **deep navy as ground** (`{colors.dark-void}` and `{colors.deep-navy}`) lit by **three saturated neons** — cyan, hot pink, yellow — plus a soft lavender pastel. Surfaces alternate: a dark navy surface (cyan grid wallpaper, white text, neon accents glowing in front) followed by a colored surface (pink, cyan, or lavender ground with navy text and navy grid lines etched at low opacity). The neons never appear as body text — they are reserved for headlines, stat numerals, accent rules, and label fills. The result is high contrast without being harsh: the neons feel illuminated rather than printed.
Depth is the system's signature trick: **stacked hard offset shadows in the pixel unit**. The flagship pattern is a six-piece shadow on buttons — three navy offsets stepping down-right at 4px, then three colored halo offsets stepping further at 8px. Hero text gets a two-layer text shadow (yellow at +4/+4, navy at +8/+8). Cards get either a 6px navy box shadow or an 8px yellow box shadow on the featured tier. Every shadow is hard-edged, zero blur, locked to the 4px grid. Atmospheric depth comes from the always-on **scanlines + grain + CRT glow** overlay trio that subtly modulates every surface.
**Density philosophy: moderately dense, atmospherically loaded.** The system reads as broken when surfaces are clean and unaccompanied — without scanlines, grain, vignette, particles, or a colored grid behind, the type loses its arcade context and starts to look like generic web typography. Always layer the atmosphere. Within content regions, however, breathing room matters: cards are widely spaced (24-32px gaps), stat tiles get heavy internal padding, and hero text is allowed to dominate. A typical slide carries one display moment + a small constellation of supporting elements (badges, labels, a chart, or a small grid), all sitting on a fully decorated atmospheric background.
**Key Characteristics:**
- Three-font stack: Tektur (display), Chakra Petch (body), Space Mono (HUD/labels) — never substitute, never mix outside their roles.
- Navy ground (`{colors.dark-void}` / `{colors.deep-navy}`) alternates with colored-grid surfaces (pink, cyan, lavender) — both carry the 40px etched grid.
- Three neons (cyan, pink, yellow) reserved for display, stats, rules, and label fills — never for body text.
- All measurements snap to the 4px pixel unit: borders 2-4px, shadow offsets 4px / 8px, corner brackets 24×24 with 4px stroke.
- Stacked hard offset shadows are the system's depth language — never blurred, never colored on text shadows except in the yellow→navy cascade.
- Every slide carries the persistent scanline + grain + CRT-vignette trio at z-index 49-51.
- L-shaped corner brackets (`{components.pixel-corner-bracket}`) replace rounded corners and frame regions, cards, and stat tiles.
- A monospace label pill (`{components.label-pill}`) sits as the universal eyebrow on every region — navy fill, neon text, 0.2em tracking, uppercase.
- Animated starfields and floating particle squares wallpaper dark surfaces — ambient, not decorative.
## Colors
### Palette
- **Dark Void** (`{colors.dark-void}` — `#0A0E27`): The deepest ground, used on `<body>` and as the base for dark-grid surfaces. Reads as black-with-blue-bias under the CRT vignette.
- **Deep Navy** (`{colors.deep-navy}` — `#0F1B3D`): The structural color — all shadow stacks, label fills, dark cards, button text on neon surfaces, and chart bar text. Slightly warmer than the void; the two read as ground and figure when stacked.
- **Neon Cyan** (`{colors.neon-cyan}` — `#5EDCF4`): The system's primary glow. Used for headlines on dark surfaces, primary button fill, stat numerals, primary chart bars, timeline nodes, navigation dots, corner brackets, and grid lines on dark surfaces (at 7% opacity).
- **Neon Pink** (`{colors.neon-pink}` — `#F0A6CA`): The warm accent. Used as a colored surface ground (40px navy-on-pink grid), secondary button fill, secondary chart bars, mouth detail in pixel avatars, and tertiary corner brackets.
- **Neon Yellow** (`{colors.neon-yellow}` — `#F4D03F`): The high-key alert color. Used in shadow halos behind buttons and on featured tier cards, as the active timeline-node fill, on hero badges, in label-pill text variants, in the quote-line, and as Tektur text-shadow layer 1.
- **Soft Lavender** (`{colors.soft-lavender}` — `#E2D5F2`): The calm pastel surface — used as ground for slides that need a softer reprieve from the neon-on-navy intensity. Carries the same etched-navy grid wallpaper as the other colored surfaces.
- **White** (`{colors.white}` — `#FFFFFF`): Text color on dark/neon surfaces only. Never used as a slide background.
### Defaults
- **Default surface background**: `{colors.dark-void}` with the 40px cyan grid (`{components.bg-grid}`). Always apply scanlines + grain + crt-glow on top.
- **Default headline color on dark surfaces**: `{colors.neon-cyan}`, with the `{shadows.pixel-text-shadow-small}` or `{shadows.pixel-text-shadow}` treatment for hero-scale text.
- **Default headline color on colored grids (pink/cyan/lavender)**: `{colors.deep-navy}` — neon text becomes illegible on neon grounds.
- **Default body text color on dark surfaces**: `rgba(255, 255, 255, 0.7)` — softened white, not pure white.
- **Default body text color on colored grids**: `rgba(15, 27, 61, 0.75)` — softened navy.
- **Default label-pill fill**: `{colors.deep-navy}` with `{colors.neon-yellow}` text. On colored grids the text can swap to cyan or pink as long as contrast against navy holds.
- **Default accent color for callouts and stat numerals**: `{colors.neon-cyan}`.
- **Default chart palette order**: cyan → pink → yellow (in that order across series).
- **Default corner bracket color**: `{colors.neon-cyan}`. Yellow and pink variants exist for thematic accents.
When a slide needs to feel softer or warmer, switch the colored grid from cyan-on-navy (default) to navy-on-pink, navy-on-cyan, or navy-on-lavender — the structural relationship inverts (grid lines become navy at low opacity) but the typographic rules stay the same.
## Typography
### Font Family
The system runs three faces, each locked to its role.
**Tektur** is the display face — a wide-bodied, semi-geometric grotesque with subtle pixel-grid cuts. Used for every hero title, headline, stat numeral, quote mark, and large numeral. Tektur's chunky personality is what makes the system feel arcade-native; replacing it with Inter or Space Grotesk breaks the entire aesthetic.
**Chakra Petch** is the body face — a humanist sans with mild geometric/squared character that reads cleanly at 14-22px and has enough personality to sit next to Tektur without disappearing. Used for paragraphs, hero taglines, quote bodies, and any longer-form prose.
**Space Mono** is the HUD face — a monospace used exclusively for labels, badges, chart values/axes, page counters, date chips, and any element that should feel like a system readout. The mono + wide-tracked uppercase combination is the system's "interface" voice.
Never use Tektur for body, never use Chakra Petch for chrome/HUD, never use Space Mono for headlines. The three-role separation is the typographic structure.
### Typography Scale
| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.pixel-hero}` | 48–128px | Tektur | 900 | Hero or cover display title — always carries the two-layer text shadow |
| `{typography.display}` | 32–64px | Tektur | 700 | Large section opener |
| `{typography.headline}` | 24–45px | Tektur | 700 | Primary section headline |
| `{typography.subhead}` | 17.6–24px | Tektur | 700 | Region-level subheading or card title |
| `{typography.stat-number}` | 32–56px | Tektur | 900 | Stat tile numeral — pairs with the small text shadow |
| `{typography.body}` | 14.4–18.4px | Chakra Petch | 400 | Paragraph body |
| `{typography.hero-tagline}` | 14.4–19.2px | Chakra Petch | 400 | Hero subtitle / lede paragraph below a pixel-hero |
| `{typography.quote-body}` | 17.6–25.6px | Chakra Petch | 500 | Quote text |
| `{typography.label-pill}` | 12px | Space Mono | 700 | Text inside the navy label pill |
| `{typography.label-eyebrow}` | 13.6px | Space Mono | 400 | Standalone uppercase eyebrow above a headline (heavier tracking than the pill) |
| `{typography.badge}` | 11.2px | Space Mono | 400 | Outline-only hero badge text |
| `{typography.chart-value}` | 12px | Space Mono | 700 | Chart bar value numerals |
| `{typography.chart-label}` | 11.2px | Space Mono | 400 | Chart axis or category labels |
| `{typography.date-chip}` | 11.2px | Space Mono | 400 | Date marker on timeline events |
| `{typography.counter}` | 12.8px | Space Mono | 400 | Persistent slide counter (NN / NN) |
### Defaults
- **Default size for a hero or cover title**: `{typography.pixel-hero}` (48–128px clamp) — always Tektur weight 900 with the two-layer text shadow.
- **Default size for a primary section headline**: `{typography.headline}` (24–45px clamp) — Tektur weight 700.
- **Default size for paragraph body**: `{typography.body}` (14.4–18.4px clamp) — Chakra Petch weight 400.
- **Default size for a stat numeral**: `{typography.stat-number}` (32–56px clamp) — Tektur weight 900, always carries the 3px navy text shadow.
- **Default size for an eyebrow label**: `{typography.label-pill}` (12px) housed in the navy pill — or `{typography.label-eyebrow}` (13.6px) if the eyebrow sits standalone.
- **Default tracking for any Space Mono label**: 0.1em (badges) to 0.3em (eyebrow labels). Mono without wide tracking reads as code, not HUD.
- **Default body weight**: 400 for Chakra Petch, 500 for quote bodies.
- **Default display weight**: 700 for headlines, 900 for hero scale and stat numerals.
When unsure which display token to reach for, default to `{typography.headline}` — it's the section-level workhorse. Reserve `{typography.pixel-hero}` for cover and CTA moments only.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every pixel-hero element carries the stacked text-shadow.** The pattern is `4px 4px 0 {colors.neon-yellow}, 8px 8px 0 {colors.deep-navy}` on cyan text. A pixel-hero element without this two-layer cascade reads as untreated display type and breaks the arcade voice.
- **Every stat numeral carries the small text-shadow.** The pattern is `3px 3px 0 {colors.deep-navy}` on cyan text. Stat numerals on dark surfaces need this shadow to feel illuminated; without it they read flat.
- **Every Space Mono element is uppercase with wide tracking** — minimum 0.05em for chart labels, 0.08–0.2em for pills and badges, 0.3em for standalone eyebrow labels. Sentence-case mono does not exist in this system.
- **Every Tektur display element keeps its native letter-spacing or slight positive (+0.04em on hero scale).** Tektur is wide-bodied by design — adding negative tracking compresses it into something that no longer reads as the same face.
- **Every Chakra Petch body block uses line-height ≥ 1.6.** The face is dense; tighter line-height on body bleeds into unreadable.
- **Every label pill uses Space Mono at 12px with 0.2em letter-spacing.** No exceptions — the pill is the system's most recognizable small chrome and any deviation in size or tracking breaks it.
- **Every chart bar value / axis label uses Space Mono.** Numerical chrome is mono, never Tektur or Chakra Petch.
### Typography Principles
The voice contrast is **chunky display ↔ humanist body ↔ wide-tracked mono chrome**. Switching any of the three roles to a different face flattens the system into a generic dark-mode aesthetic. Italic is never used in display or body — the only italic that appears anywhere is implicit in the slight tilt on pixel-art decorative elements.
Tektur should always feel **planted** — left-aligned, generous line-height, never centered for body-length runs (centering is permitted on hero and CTA titles only). Chakra Petch should always feel **calm** — left-aligned by default, no all-caps treatment, no letter-spacing.
## Layout
### Canvas System
The system targets `100vw × 100vh` per slide. Slides are stacked vertically inside a `slides-container` and translated via `transform: translateY(...)` for navigation. Only one slide occupies the viewport at a time, with cubic-bezier `(0.22, 1, 0.36, 1)` easing on an 800ms transition.
Default slide padding is `3vh 4vw`. The inner `slide-content` caps at `max-width: 1200px` and centers, so on wide displays content keeps editorial column width while the colored background fills the viewport.
### Pixel Unit
Every measurement in the system snaps to a **4px grid**. Border widths are 2px or 4px. Shadow offsets are 4px or 8px. Corner brackets are 24×24 with 4px stroke. The background grid is 40px (10 × pixel-unit). Card padding usually resolves to multiples of 8 (16, 24, 32, 48). This discipline is what makes the system feel rasterized rather than vector.
### Persistent Chrome
Three elements appear on every slide:
- **Navigation dot rail** — vertical stack of 12×12 cyan-bordered squares, fixed at `right: 24px`, vertically centered. Active state fills the inner 8×8 with cyan.
- **Slide counter** — Space Mono `01 / 10` format, fixed at `bottom: 24px`, horizontally centered, dark-navy semi-transparent pill background.
- **Nav hint** — `USE KEYS ↑ ↓`, Space Mono 11px at 50% opacity, fixed at `bottom: 24px right: 24px`.
The cursor across the entire deck is `crosshair` — an additional arcade signal.
### Atmospheric Overlay Stack
Every slide carries (in z-order):
1. Surface background — either `{components.bg-grid}` (cyan-on-navy) or one of the colored grid variants.
2. Grain layer at z-index 49, opacity 0.035.
3. Scanlines at z-index 50, multiply blend mode.
4. CRT vignette glow at z-index 51 (dark surfaces only).
5. Optional starfield / pixel particles at z-index 1 inside the surface.
6. `.slide-content` at z-index 10 above the atmospheric layers.
This overlay stack is the system's identity. A slide rendered without it looks like a wireframe.
## Depth and Elevation
### Stacked Hard Offset Shadow (Signature)
The system uses **stacked, multi-step hard offset shadows** in the 4px pixel unit. Every shadow value is composed in one of three patterns:
- **Three-step navy L-shape** (`{shadows.pixel-l-shape}`) — three offsets at `4px 0`, `0 4px`, `4px 4px` in deep-navy, zero blur. Used on chart bars and small elevated chrome to suggest a single-layer drop.
- **Six-step button cascade** (`{shadows.pixel-stack-cyan-yellow}` / `{shadows.pixel-stack-pink-cyan}`) — three navy offsets at 4px stepping then three colored halo offsets at 8px stepping behind. Creates a two-layer pixel-bevel effect. Used exclusively on `{components.pixel-button}`.
- **Two-layer text-shadow** (`{shadows.pixel-text-shadow}` / `{shadows.pixel-text-shadow-small}`) — yellow layer at +4/+4 then navy layer at +8/+8 (or just navy at +3/+3 for stat-scale numerals). Used on every Tektur display element.
All shadows are zero-blur, hard-edged, locked to the pixel unit. A blurred drop shadow does not exist anywhere in the system.
### Card Shadows
Two simpler patterns serve cards:
- `{shadows.card-offset}` = `6px 6px 0 rgba(15, 27, 61, 0.15)` — soft navy offset for non-featured tier cards on light surfaces.
- `{shadows.card-featured}` = `8px 8px 0 {colors.neon-yellow}` — neon-yellow offset for featured tier cards, paired with a `-12px` translateY lift.
### Corner Brackets as Depth
The L-shaped corner brackets (`{components.pixel-corner-bracket}`) replace traditional border treatments on regions and cards. Two brackets at opposite corners imply a frame without enclosing it — the eye fills in the missing edges. On stat blocks and feature cards, brackets sit inset at `top: -2px / left: -2px` and `bottom: -2px / right: -2px` so they break the cell edge slightly, reinforcing the pixel-bevel feel.
### Atmospheric Depth
The scanline + grain + CRT-vignette stack provides ambient depth on every surface without requiring shadow on individual elements. Animated starfields and floating particles layer additional spatial cues behind content. None of these are decorative add-ons — they are core to the depth perception of the system.
## Shapes and Treatment
### Border Radius
Effectively zero. The only round shape that appears anywhere is the donut-style nav dot inner-fill (which is still a square in this system — the nav dots are square pips, not circles). Rounded buttons, rounded cards, or rounded pill chips break the pixel-art aesthetic immediately.
The pixel-face avatar zone uses square eyes and a rectangular mouth — anatomy rendered in pixels, not curves.
### Border Weights
- **2px solid** — used on feature-card outlines, hero badges, nav dots, stat-block frames, chart bars (inline edges).
- **3px stroke** — used for chart axes inside SVG charts (deep-navy).
- **4px solid** — used on corner brackets, timeline node borders, the quote-line, and the inner pixel-bevel of buttons.
Borders are always solid, always navy or neon, never dashed except for the timeline rail (`{components.timeline-rail}`) which is intentionally rendered as a 16px-on, 8px-off repeating linear gradient to mimic a pixel-dashed line.
### Decorative Element Types
**Pixel corner bracket** — Two outward L-shapes (top-left + bottom-right) bracketing a region. 24×24 with 4px stroke. Default color is cyan; yellow and pink variants exist. The bracket pattern is the system's most distinctive non-typographic mark.
**Label pill** — Navy rectangle with neon-yellow Space Mono text at 12px / 0.2em. The universal section eyebrow. Variants flip the text color to cyan or pink while keeping the navy fill.
**Hero badge** — Outline-only 2px yellow border with yellow Space Mono text. Appears in clusters under hero titles as feature tags.
**Stat block** — Cyan-tinted glass tile (8% cyan fill, 20% cyan border) with cyan corner brackets at top-left and bottom-right. Holds a large stat numeral over a Space Mono pink label.
**Feature card** — Frosted-glass white card (15% white fill, blur) with navy corner brackets at opposite corners. Used on colored-grid surfaces.
**Pixel button** — Cyan rectangle with the six-step stacked shadow cascade. On hover, the button translates +2/+2 and the shadow collapses to a 4-step cascade — simulating a key-press in pixel art.
**Quote-line** — A 60×4 yellow rectangle with a 4×4 navy offset shadow. Used as a separator beneath quote bodies.
**Timeline node** — 24×24 cyan square with a 4px navy border, positioned on a dashed navy rail. Active state swaps fill to yellow.
**Date chip** — Inline 2px-padded navy pill with cyan Space Mono text, used to mark timeline events.
**Pixel face** — A 120×120 grouping of square "facial features" (cyan eyes, pink mouth) rendered as absolutely positioned divs inside a navy avatar zone. Functions as both a friendly mascot and a system-signature decorative module.
**Tier card** — White rectangle, 6px navy offset shadow. Featured tier swaps fill to deep-navy and shadow to 8px yellow, with a `-12px` translateY lift. Tier features use a `+` ::before glyph in cyan instead of standard bullets.
**Pixel landscape** — A row of variable-height navy mountains at the bottom of CTA-class surfaces, opacity 0.3. Pure decoration suggesting an arcade horizon.
## Do's and Don'ts
### Do
- Apply the scanlines + grain + CRT-vignette overlay stack to every slide. The atmosphere is the design system; surfaces without it look like wireframes.
- Use `{colors.neon-cyan}` as the default headline color on dark surfaces and `{colors.deep-navy}` as the default headline color on colored grids (pink/cyan/lavender).
- Apply `{shadows.pixel-text-shadow}` to every pixel-hero element and `{shadows.pixel-text-shadow-small}` to every stat numeral. Tektur display type without its text-shadow reads flat.
- Snap every measurement to the 4px pixel unit — border widths, shadow offsets, padding, corner-bracket dimensions. Off-grid values break the rasterized feel.
- Use Tektur for display, Chakra Petch for body, Space Mono for chrome — exclusively. Cross-mixing the three voices flattens the system.
- Wrap eyebrows in the `{components.label-pill}` (navy bg, yellow Space Mono text, 0.2em tracking, uppercase) as the universal section tag.
- Pair the navy ground with at least one neon glow per region — text, chart bar, corner bracket, or button shadow halo. Pure navy without a neon accent reads as dead screen.
- Layer animated starfields and pixel-particle floaters on dark hero and CTA surfaces. The motion is part of the atmosphere.
- Render charts with cyan → pink → yellow series order and Space Mono numerals/labels. The neon trio is the chart palette.
- Bracket cards and stat tiles with the L-shaped corner brackets at opposite corners instead of fully outlining them. The implied frame is the system's signature card treatment.
### Don't
- Don't substitute fonts. Tektur, Chakra Petch, and Space Mono are the three voices — replacing any of them with Inter, Roboto, or Space Grotesk collapses the system.
- Don't round any corner. The pixel aesthetic depends on square edges. Border-radius is reserved for SVG donut chart geometry only.
- Don't blur any shadow. Every shadow is hard-edged at zero blur. `0 4px 12px rgba(0,0,0,0.1)` does not exist here.
- Don't place neon text on neon surfaces. Cyan headlines on the pink grid become illegible — switch to deep-navy on colored grounds.
- Don't use Tektur in sentence-case body runs or Chakra Petch in chrome/labels. Each face has a single role.
- Don't introduce a fourth neon. The palette is cyan + pink + yellow + lavender pastel. Adding green or orange breaks the curated neon trio.
- Don't omit the atmospheric overlay stack on any slide, even chart-heavy or table-heavy slides. The overlays are non-negotiable.
- Don't use uppercase Chakra Petch body text. Body always sentence-case; uppercase is reserved for Space Mono and Tektur display.
- Don't drop the navy label pill in favor of a plain text eyebrow. The pill is the most recognizable small chrome in the system.
- Don't shadow text or chrome with off-axis offsets. Every shadow steps down-right in 4px increments — left or upward offsets do not exist.
## Responsive Behavior
8-Bit Orbit is a **viewport-fluid system** built around `vw/vh`-based sizing and CSS `clamp()` ranges. There are no hard breakpoints for the deck itself — every font size, padding value, and gap interpolates between a minimum and maximum based on viewport width.
### Scaling Behavior
- Hero text scales 48px → 128px on viewport width.
- Stat numerals scale 32px → 56px.
- Body scales 14.4px → 18.4px.
- The 4px pixel unit, 40px grid size, scanline 4px stripe, and corner-bracket dimensions are fixed — they do not scale, which means at larger viewports the pixel chrome appears proportionally finer (intentionally — the larger the canvas, the smaller and more refined the pixels read).
### Component Breakpoints
Three component-level breakpoints exist:
- `max-width: 1024px` — feature grid collapses 4→2 columns, two-column split layouts stack.
- `max-width: 900px` — feature grid further collapses, hbar chart label column shrinks.
- `max-width: 500px` — feature grid becomes single column, stats grid stacks.
### Presenter Behavior
- Slides advance via `ArrowDown`, `ArrowRight`, or `Space`.
- Slides reverse via `ArrowUp` or `ArrowLeft`.
- `Home` jumps to first, `End` to last.
- Vertical swipe on touch devices advances/reverses with a 50px threshold.
- Mouse wheel scroll advances/reverses with an 800ms debounce lock.
- Slide transitions use 800ms cubic-bezier `(0.22, 1, 0.36, 1)` on a translateY transform.
### Animation Triggers
Chart bars and stat counters animate in on slide entry with `setTimeout` staggers (100-150ms between items). When a slide is exited, its bars/counters reset to 0 so re-entry replays the animation. The `prefers-reduced-motion` media query disables transitions and the starfield/particle twinkle keyframes.
### Print Behavior
The system has no `@media print` rule. The deck is screen-first; printing produces only the active slide. For static export, screenshots of each slide preserve all atmospheric overlays (scanlines and grain are CSS-rendered, not assets).
## CJK & International Content
When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.
### Recommended Chinese Pairing
| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| Display / hero / stat numerals | Tektur 700–900 | 思源黑体 Noto Sans SC 900 |
| Body / hero tagline / quote body | Chakra Petch 400–500 | 思源黑体 Noto Sans SC 400 |
| HUD labels / badges / chart values / counter | Space Mono 400–700 (uppercase + wide tracking) | 思源黑体 Noto Sans SC 500 (no transform, no tracking) — see Known CJK Gap below |
### Mixed-Content Strategy
**Strategy A** — single CJK family with built-in Latin glyph coverage. Set every text element to `font-family: 'Noto Sans SC', sans-serif`. 思源黑体 ships Latin glyphs that read cleanly alongside Chinese characters, so a sentence like `使用 Tektur 字体` renders in one consistent face rather than font-switching mid-word. This system normally runs three faces (display / body / HUD); collapsing to one CJK face is the right tradeoff because none of the three Latin faces have credible Chinese counterparts, and visual hierarchy still works through weight (900 / 700 / 500 / 400) plus the system's signature shadow stacks.
### Loading
Add to the template's `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (up from 1.7–1.8), display 1.15–1.25 (up from 1.05–1.15). CJK characters are square and visually full — they crowd vertically more than Latin.
- **Letter-spacing**: set to 0 on every CJK run. The template's positive tracking on Tektur display (+0.04em) and 0.1–0.3em mono tracking on Space Mono labels looks broken on square CJK glyphs — they're already evenly spaced by design.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. Every Space Mono label in this system uses `text-transform: uppercase`; remove it for CJK runs.
- **Punctuation**: use full-width Chinese punctuation (,。:;!?「」()).
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `8 位赛博 / 1989 模式` not `8位赛博/1989模式`.
- **One font per sentence**: 思源黑体 covers both CJK and Latin glyphs in a unified style — let it handle mixed sentences. Don't let the browser fall back to Tektur or Space Mono mid-sentence for ASCII characters.
### Aesthetic Notes for This System
The system's identity rests on three voices — Tektur (chunky arcade display), Chakra Petch (humanist body), Space Mono (HUD readouts) — and a CJK build cannot preserve that three-face contrast. Compensate by leaning harder on the **non-typographic** signature elements: the stacked text-shadow (yellow at +4/+4, navy at +8/+8) still works on 思源黑体 900 headlines and is what carries the arcade voice when the face itself is generic. Keep all atmospheric overlays (scanlines, grain, CRT vignette, starfields, grid wallpaper) — they do more identity work in a CJK build than in the Latin original.
The system's Space Mono label-pill (navy fill, neon-yellow text, 0.2em tracking, uppercase) is the most recognizable small chrome and translates poorly: CJK characters won't accept the wide tracking or uppercase transform. Render Chinese label-pills with 思源黑体 weight 500 at 0 tracking, no transform, and a slightly tighter fontSize (10–11px instead of 12px) to preserve the chip's compact silhouette. The colored pill background and corner-bracket framing carry the recognition load.
### Known CJK Gap
- **No CDN-loadable Chinese pixel font.** The system's arcade aesthetic depends on Tektur's semi-pixel grotesque character — there is no equivalent Chinese face on Google Fonts or major CDNs that reads as "pixel-art" while remaining legible. 思源黑体 at weight 900 gives heft but loses the pixel-grid signal entirely. The atmospheric overlays (scanlines, grain, vignette, starfields) and pixel-bevel shadow stacks must carry the arcade voice on their own.
- **No CDN Chinese monospace face for HUD labels.** Space Mono's "system readout" voice depends on monospaced rhythm + uppercase + 0.1–0.3em tracking — none of which transfer to CJK. The label-pill loses its mono character; lean on the navy fill + neon text + corner-bracket framing to keep chrome recognizable.
## Iteration Guide
1. Any new slide gets the full atmospheric overlay trio (scanlines + grain + crt-glow on dark surfaces, scanlines + grain on colored surfaces) and a 40px etched grid surface. Don't skip the overlays.
2. Any new display element uses Tektur. Any new body element uses Chakra Petch. Any new label, badge, counter, or chart value uses Space Mono. Never cross the role boundaries.
3. Any new headline gets `{colors.neon-cyan}` on dark surfaces or `{colors.deep-navy}` on colored grids — both with the appropriate Tektur weight and (for hero scale) the stacked text-shadow.
4. Any new eyebrow uses the `{components.label-pill}` — navy fill, neon-yellow Space Mono text at 12px / 0.2em / uppercase. Don't substitute a plain h-tag.
5. Any new card or region gets the L-shaped corner brackets at opposite corners (top-left + bottom-right) instead of a full outline. The implied frame is the system's signature.
6. Any new measurement snaps to the 4px pixel unit. Borders 2-4px, shadow offsets 4px / 8px, corner brackets 24px, grid 40px. Off-grid values feel wrong.
7. Any new shadow is hard-edged at zero blur. For buttons use the six-step cascade; for cards use 6px navy or 8px yellow; for text use the two-layer cascade.
8. Any new chart cycles cyan → pink → yellow in series order. Numerical labels and axis labels are always Space Mono.
9. If a surface needs to feel warmer or softer, switch to the pink, cyan, or lavender etched grid variant — but keep all typographic rules intact (navy headlines, softened-navy body).
10. Animated elements (starfield, particles, chart bar grow, counter rollup) should respect `prefers-reduced-motion`. Atmospheric overlays (scanlines, grain, vignette) are not animated and stay on always.
## Known Gaps
- **Tektur, Chakra Petch, and Space Mono are Google Fonts** loaded via a preconnect + `<link>`. The system has no fallback strategy beyond `cursive` / `sans-serif` / `monospace` — in environments where Google Fonts fail (offline, restricted networks), the aesthetic collapses to system defaults and loses its character.
- **Starfield and pixel-particle elements are generated by inline JS** that creates a fixed count of absolutely-positioned divs with random positions and animation delays. The animation keyframes are present in CSS, but the elements are only created if the JS runs successfully.
- **The chart system is hardcoded**: bar heights, hbar widths, and stat counter targets are stored in `data-*` attributes and animated via `setTimeout` staggers triggered by slide-index matching. There is no data-binding layer — adding a new chart requires copying the HTML pattern and updating the JS slide-index matcher.
- **The pixel-landscape on CTA surfaces is JS-generated** from a hardcoded heights array `[30, 50, 70, ...]`. Width varies per mountain (60 + (i % 3) * 20px). Replacing the landscape requires editing the JS heights array.
- **The CRT vignette glow uses a fixed dark-navy radial gradient.** Adjusting it requires editing the CSS gradient stops; there is no tokenized vignette intensity.
- **The cursor is set to `crosshair` deck-wide** for atmospheric reasons. This may conflict with text-selection expectations in contexts where the deck is embedded.
- **No keyboard navigation hint exists for the wheel/touch fallback.** The nav-hint reads `USE KEYS ↑ ↓` even though wheel and touch are also wired up.
- **The slide counter format is fixed at `NN / NN` zero-padded.** Decks with more than 99 slides would render with a layout-shifting counter.
- **The pixel-corner-bracket sizing is fixed at 24×24 with 4px stroke** and does not scale with viewport. On very large or very small viewports the brackets may feel proportionally off.
# 8-Bit Orbit Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/8-bit-orbit/design.md`
- Preview card: `bold-template-pack/templates/8-bit-orbit/preview.md`
## Selection Metadata
- Slug: `8-bit-orbit`
- Tagline: Pixel-art neon arcade aesthetic on a deep navy void.
- Mood: retro-tech, playful, cyberpunk, energetic
- Tone: geeky, neon, rebellious, sci-fi
- Formality: low
- Density: medium
- Scheme: dark
- Best for: Anything that should feel like a CRT screen at 2am: cyberpunk, gaming, web3, indie dev tools, hackathon demos. Just as good for a tech talk that wants to lean into nostalgic-digital craft, a synthwave brand deck, or a creative review that wants to feel like a console.
- Avoid for: Contexts where the dark neon palette would actively work against the message — quiet institutional finance disclosures, healthcare patient-facing materials, traditional luxury.
## Visual Snapshot
A retro-futuristic pixel-art presentation system that fuses 16-bit arcade nostalgia with editorial discipline. Display type runs in Tektur (a chunky geometric display face built on pixel-grid logic) paired with Chakra Petch for body and Space Mono for code-flavored labels and tabular data. The palette pivots on a deep cosmic navy (#0F1B3D / #0A0E27) lit by three saturated neons — cyan, hot pink, and a high-key yellow — with a soft lavender pastel for warm reprieves. Depth is built from stacked hard offset shadows in 4px increments (the pixel unit), CRT scanlines, atmospheric grain, vignettes, and animated starfields. The effect sits between an arcade cabinet and a Tron-era boardroom — unmistakably digital, intentionally lo-fi, and engineered to feel as if it just booted up.
8-Bit Orbit is a retro-futuristic pixel-art presentation system. Its foundational premise is the 4-pixel unit: every shadow offset, every border, every corner bracket, every label height resolves to a multiple of 4px. Layouts feel as if they were rasterized on an old CRT and dragged into HTML — and atmospheric overlays (scanlines, grain, vignette glow, animated starfields) reinforce the illusion on every surface.
## Preview Ingredients
- Palette: dark-void #0A0E27; deep-navy #0F1B3D; neon-cyan #5EDCF4; neon-pink #F0A6CA; neon-yellow #F4D03F; soft-lavender #E2D5F2; white #FFFFFF
- Typography: See full design doc after selection.
- Signature move: Three-font stack: Tektur (display), Chakra Petch (body), Space Mono (HUD/labels) — never substitute, never mix outside their roles.
- Signature move: Navy ground ({colors.dark-void} / {colors.deep-navy}) alternates with colored-grid surfaces (pink, cyan, lavender) — both carry the 40px etched grid.
- Signature move: Three neons (cyan, pink, yellow) reserved for display, stats, rules, and label fills — never for body text.
- Signature move: All measurements snap to the 4px pixel unit: borders 2-4px, shadow offsets 4px / 8px, corner brackets 24×24 with 4px stroke.
- Signature move: Stacked hard offset shadows are the system's depth language — never blurred, never colored on text shadows except in the yellow→navy cascade.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Biennale Yellow
description: A literary-editorial presentation system in the visual register of an art biennale catalogue or quiet exhibition poster. The aesthetic is built on warm parchment grounds (`#E9E5DB`) flooded with soft solar yellow (`#F1EE2E`) radial blooms, set against a single deep indigo navy ink color. Display type is Instrument Serif — a contemporary high-contrast serif with tall ascenders and elegant italics — paired with Archivo for sans-serif chrome and JetBrains Mono for numerical and metadata callouts. No drop shadows, no rounded corners, no bordered cards: the only structural lines are hairline 1px rules in ink. The mood sits between a folded museum brochure, a slow-reading literary quarterly, and a Mediterranean exhibition poster — confident, atmospheric, and deeply restrained.
colors:
paper: "#E9E5DB"
paper-deep: "#DCD6C4"
sun: "#F1EE2E"
sun-soft: "#F8F39B"
haze: "#F0DA7C"
ink: "#1B2566"
ember: "#E26B4A"
color-aliases:
line: ink
typography:
display:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(120px, min(14.6vw, 22vh), 240px)"
lineHeight: 0.86
letterSpacing: -0.018em
display-md:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(80px, min(10vw, 16vh), 200px)"
lineHeight: 0.86
letterSpacing: -0.018em
display-sm:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(110px, min(11vw, 18vh), 200px)"
lineHeight: 0.86
letterSpacing: -0.018em
display-it:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontStyle: italic
fontSize: "clamp(56px, min(7vw, 11vh), 120px)"
lineHeight: 1.04
letterSpacing: -0.005em
numeral-jumbo:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(220px, min(28vw, 64vh), 720px)"
lineHeight: 0.84
letterSpacing: -0.04em
numeral-lg:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(120px, min(15vw, 22vh), 280px)"
lineHeight: 0.9
letterSpacing: -0.04em
numeral-md:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(72px, min(7vw, 12vh), 144px)"
lineHeight: 0.92
letterSpacing: -0.01em
headline:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(40px, min(4.6vw, 7vh), 88px)"
lineHeight: 1.06
letterSpacing: -0.005em
headline-sm:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(32px, min(3.6vw, 6vh), 56px)"
lineHeight: 1
date-rail:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(48px, min(5.2vw, 9vh), 96px)"
lineHeight: 0.96
letterSpacing: -0.005em
ledger-title:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(20px, 1.6vw, 30px)"
lineHeight: 1.15
strand-title:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(22px, 1.7vw, 32px)"
lineHeight: 1.1
strand-num:
fontFamily: "'Instrument Serif', Georgia, serif"
fontWeight: 400
fontSize: "clamp(28px, 2vw, 38px)"
lineHeight: 1
body-lede:
fontFamily: "'Archivo', sans-serif"
fontWeight: 400
fontSize: "clamp(15px, 1.05vw, 18px)"
lineHeight: 1.55
body:
fontFamily: "'Archivo', sans-serif"
fontWeight: 400
fontSize: "clamp(14px, 0.95vw, 16px)"
lineHeight: 1.5
body-sm:
fontFamily: "'Archivo', sans-serif"
fontWeight: 400
fontSize: "clamp(11px, 0.78vw, 13px)"
lineHeight: 1.5
micro-label:
fontFamily: "'Archivo', sans-serif"
fontWeight: 600
fontSize: "clamp(11px, 0.85vw, 14px)"
lineHeight: 1.2
letterSpacing: 0.18em
textTransform: uppercase
micro-label-tight:
fontFamily: "'Archivo', sans-serif"
fontWeight: 600
fontSize: "clamp(10px, 0.72vw, 12px)"
lineHeight: 1.2
letterSpacing: 0.16em
textTransform: uppercase
rail-label:
fontFamily: "'Archivo', sans-serif"
fontWeight: 600
fontSize: "clamp(11px, 0.85vw, 13px)"
lineHeight: 1
letterSpacing: 0.32em
textTransform: uppercase
mono-data:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontWeight: 400
fontSize: "clamp(12px, 0.85vw, 14px)"
lineHeight: 1.4
letterSpacing: 0.04em
mono-date:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontWeight: 400
fontSize: "clamp(13px, 0.95vw, 16px)"
lineHeight: 1.4
letterSpacing: 0.02em
pagenum:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontWeight: 400
fontSize: "clamp(11px, 0.85vw, 13px)"
lineHeight: 1
letterSpacing: 0.08em
spacing:
pad-edge: "clamp(40px, 4vw, 76px)"
pad-region: "clamp(40px, 4.2vw, 80px)"
pad-foot: "clamp(56px, 5vh, 88px)"
pad-strand-y: "clamp(12px, 1.6vh, 22px)"
gap-region: "clamp(20px, 2.5vw, 48px)"
gap-strand: "clamp(14px, 1.8vh, 22px)"
gap-footer-col: "clamp(20px, 2.4vw, 44px)"
pagenum-bottom: "clamp(22px, 2.4vh, 42px)"
pagenum-right: "clamp(24px, 2.4vw, 48px)"
canvas:
width: 100vw
height: 100vh
background: "{colors.paper}"
components:
pagenum:
position: "absolute, right + bottom"
color: "{colors.ink}"
opacity: 0.75
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "clamp(11px, 0.85vw, 13px)"
letterSpacing: 0.08em
description: "Single mono pagenum NN / NN pinned to bottom-right of every slide at 75% opacity. The only persistent chrome on every surface."
hairline-rule:
border: "1px solid {colors.ink}"
description: "1px solid ink horizontal or vertical rule. The system's only border treatment — separates header bands from content, footer columns from each other, ledger rows from each other. No thicker rule exists."
hairline-rule-soft:
border: "1px solid rgba(27, 37, 102, 0.18-0.2)"
description: "1px ink at 18-20% opacity. Used for between-row separators inside dense ledger or strand lists where a full-weight rule would feel oppressive."
sun-bloom:
background: "radial-gradient using {colors.sun} {colors.sun-soft} {colors.haze} blending to transparent on {colors.paper}"
description: "Large soft radial bloom of solar yellow placed off-center or behind a focal element. The system's primary atmospheric layer. Sized 42-70% of viewport in the larger axis."
ember-bloom:
background: "radial-gradient using {colors.ember} at 15-22% opacity blending to transparent"
description: "Small warm peach bloom used as a counter-temperature accent in a corner opposite the sun bloom. Always subordinate; never dominant."
block-tile:
background: "{colors.sun} at 40-70% opacity"
description: "Geometric blocks of translucent solar yellow placed on an 8-row × 4-column grid behind cover or colophon surfaces. Suggests a layered poster underprint."
yellow-panel:
background: "{colors.sun}"
color: "{colors.ink}"
description: "Full-bleed yellow panel covering a column or third of the slide. The strongest possible color statement — used when a region needs to read as poster-fill, not paper."
bar-ink:
background: "{colors.ink}"
height: "clamp(14px, 1.6vh, 22px)"
description: "Solid ink horizontal bar for data charts. Width carries the data value."
bar-lit:
background: "{colors.sun}"
border: "1px solid {colors.ink}"
height: "clamp(14px, 1.6vh, 22px)"
description: "Highlighted variant of bar-ink — yellow fill with 1px ink stroke. Used to mark the current or featured row in a series."
strand-row:
layout: "grid 56px 1fr, gap clamp(14px, 1.4vw, 24px), border-bottom hairline-soft, padding-bottom clamp(12px, 1.6vh, 22px)"
description: "Numbered editorial list row — numeral cell + content cell separated by hairline-soft. Used for programmes, agendas, and curated lists."
ledger-row:
layout: "grid 92px 1.6fr 0.9fr 80px, gap clamp(14px, 1.4vw, 28px), border-bottom hairline-soft, padding clamp(10px, 1.3vh, 18px) 0"
description: "Four-column tabular row for calendars and itineraries. Date column is mono, title is serif, venue is sans, duration is mono right-aligned."
footer-band:
layout: "grid 4-column with hairline-rule top border on each cell, gap clamp(20px, 2.4vw, 44px)"
description: "Four-column metadata strip pinned to the bottom of cover and colophon surfaces. Each cell has a tiny uppercase tag + a brief plain-English statement."
vertical-rail:
transform: "rotate(-90deg) translateY(-50%) at left edge"
fontFamily: "'Archivo', sans-serif"
fontSize: "clamp(11px, 0.85vw, 13px)"
letterSpacing: 0.32em
textTransform: uppercase
description: "Rotated vertical text label running up the left edge. Used on chapter/divider surfaces as a section marker."
date-rail-stack:
fontFamily: "'Instrument Serif', Georgia, serif"
fontSize: "clamp(48px, min(5.2vw, 9vh), 96px)"
lineHeight: 0.96
textAlign: right
description: "Large serif date or date-range stacked at top-right of cover surfaces. Uses an en-dash to indicate spans."
---
## 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
Biennale Yellow is a **literary-editorial presentation system** modeled on the visual language of European art biennale catalogues, slow exhibition posters, and quarterly literary publications. There are no cards, no buttons, no shadows, no rounded corners. The structural vocabulary is just three things: paper, ink, and yellow.
The typographic system pivots on **Instrument Serif**, a contemporary high-contrast serif with tall ascenders, elegant italics, and slightly flared terminals. It carries every display moment, every numeral, every quote — at scales ranging from headline-small (40px) to jumbo numerals over 700px. Set tight (line-height 0.86, letter-spacing −0.018em), it reads as confident editorial display; set looser in italic (line-height 1.04, letter-spacing −0.005em), it becomes a slow-reading quotation face. **Archivo** is the sans companion — used for body paragraphs and as small, wide-tracked uppercase labels (the "micro-label" treatment). **JetBrains Mono** handles all numerical and metadata callouts: dates, ledger figures, page numbers. The three-face system is rigid and disciplined; the contrast between them is the entire typographic story.
The color world is built on **warm parchment** (`{colors.paper}` — `#E9E5DB`) as the universal ground, marked by a single **ink** color (`{colors.ink}` — `#1B2566`, a deep indigo navy) used for every line of type and every rule. The system's signature color is **sun** (`{colors.sun}` — `#F1EE2E`), a highly saturated solar yellow used as a flooded panel, as a soft blooming radial gradient, or as a geometric tile underprint. A **soft ember peach** (`{colors.ember}` — `#E26B4A`) appears only as a subordinate counter-temperature accent, always at 15-22% opacity in a corner radial bloom. Inverted color treatments are not used; the system commits to navy ink on a warm ground.
Depth is **atmospheric, not structural**. There are no drop shadows anywhere in the system. Depth comes from layered radial gradients of yellow (the sun-bloom and ember-bloom components) and the optional block-tile underprint on cover-class surfaces. Cards have no borders; regions are separated only by 1px hairline rules in ink. The lack of border weight is itself the aesthetic — the design feels printed, not engineered.
**Density philosophy: editorial-restrained.** This system reads as elegant when sparse and broken when crowded. A typical surface holds one large display moment + a handful of supporting elements (a micro-label, a body paragraph, an ordered list, or a single radial bloom). Crowding the canvas with cards, buttons, panels, or stacked components turns the system into a different aesthetic entirely. Even dense surfaces (a calendar or programme) achieve density through tabular repetition, not visual richness — many quiet rows of hairline-separated metadata, not many bordered cells. Generous edge padding (40-76px) and wide footer/header bands let the canvas breathe.
**Key Characteristics:**
- Warm parchment ground (`{colors.paper}`) on every surface; never white, never gray.
- Single ink color (`{colors.ink}`) for all text and all rules — no secondary text colors.
- Solar yellow (`{colors.sun}`) deployed three ways: as a flooded panel, as a soft radial bloom, as a translucent geometric tile underprint.
- Instrument Serif handles every display moment at scales from 40px to 720px+.
- Archivo Bold uppercase + 0.16–0.32em tracking is the universal label voice.
- JetBrains Mono is reserved exclusively for dates, ledger numerals, and page numbers.
- 1px hairline rules in `{colors.ink}` are the only border treatment — used for header bands, ledger rows, footer columns, and strand separators.
- No drop shadows, no rounded corners, no card outlines, no buttons. Decoration is atmospheric (radial blooms) or geometric (translucent tile blocks).
- Persistent `01 / NN` JetBrains Mono pagenumber at bottom-right of every surface at 75% opacity.
- Optional vertical rotated rail-label at the left edge of chapter/divider surfaces.
## Colors
### Palette
- **Paper** (`{colors.paper}` — `#E9E5DB`): The warm parchment canvas. The default and near-universal background. Reads as a softened off-white with strong warmth — never neutral, never cold.
- **Paper-deep** (`{colors.paper-deep}` — `#DCD6C4`): A slightly darker parchment tone, available as a secondary surface or to suggest a shadow band without using actual shadow. Reserved for moments that need surface differentiation while staying within the warm-paper family.
- **Ink** (`{colors.ink}` — `#1B2566`): The single text and line color across the entire system. A deep indigo navy that reads as confident editorial black-with-blue-bias. Used for headlines, body, micro-labels, monos, hairline rules, and ink-bar fills. The `--line` CSS variable resolves to this same color.
- **Sun** (`{colors.sun}` — `#F1EE2E`): The system's signature solar yellow. Highly saturated, slightly green-leaning. Used three ways: as a flooded full-bleed or column-bleed panel, as the core of soft radial blooms, and as 40-70% opacity geometric tile blocks.
- **Sun-soft** (`{colors.sun-soft}` — `#F8F39B`): A paler buttery yellow used in the middle stops of sun-bloom gradients to soften the transition from saturated sun to paper.
- **Haze** (`{colors.haze}` — `#F0DA7C`): A warmer mustard-leaning yellow used in the outermost stops of sun-bloom gradients to extend the bloom into the paper without a hard edge.
- **Ember** (`{colors.ember}` — `#E26B4A`): A warm peach-orange used only as a subordinate counter-temperature accent in 15-22% opacity radial blooms. Never used as a fill color, never as a text color. Its job is to balance a sun-bloom on the opposite side of the canvas.
### Defaults
- **Default surface background**: `{colors.paper}`. Every surface starts here.
- **Default headline color**: `{colors.ink}`. Always. Headlines never appear in yellow, ember, or paper-deep — only ink.
- **Default body text color**: `{colors.ink}`. Body uses the same color as display; the contrast is achieved through size and weight, not color.
- **Default rule color**: `{colors.ink}` (1px solid) for primary separators, ink at 18-20% opacity for secondary row separators.
- **Default accent surface for poster moments**: `{colors.sun}` — a flooded panel of solar yellow with `{colors.ink}` text on top.
- **Default atmospheric layer**: a single `{components.sun-bloom}` placed off-center on the surface, with an optional `{components.ember-bloom}` in the opposite corner.
- **Default chart bar color**: `{colors.ink}`. The featured/current bar uses `{components.bar-lit}` (yellow fill, ink stroke).
- **Default label color**: `{colors.ink}` for the text, no fill. Labels are tracking + uppercase + weight 600, not filled pills.
The system never inverts: ink text on a sun panel is correct (and a key signature treatment), but yellow text on an ink ground does not exist. Text is always ink; the variability lives in what's behind the text, not in the text color itself.
## Typography
### Font Family Stack
The system runs three faces, each with a tightly defined role.
**Instrument Serif** (Google Fonts, italic + roman) is the display and editorial face. Its high contrast, tall ascenders, and slightly flared terminals give it a contemporary literary register — closer to a magazine masthead than a traditional book serif. Roman is used for headlines, numerals, ledger titles, and date rails. Italic is used for manifesto quotes and certain emphasis moments. Set tight (line-height ≤ 1.06, negative letter-spacing −0.005 to −0.04em).
**Archivo** (Google Fonts) is the sans companion. Used at weight 400 for body paragraphs (line-height 1.5) and at weight 600 for the universal micro-label treatment (uppercase, 0.16-0.32em tracking, 10-14px). Never used at intermediate weights, never used for headlines.
**JetBrains Mono** (Google Fonts) is the numerical/metadata face. Used exclusively for dates in ledgers, mono numerical callouts in data slides, page numbers, and the nav-hint. Its slab character gives editorial weight to numerical content without leaning on bold styling.
### Typography Scale
| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | 120–240px | Instrument Serif | 400 | Cover-scale display title |
| `{typography.display-sm}` | 110–200px | Instrument Serif | 400 | Editorial display in a panel context |
| `{typography.display-md}` | 80–200px | Instrument Serif | 400 | Closing-statement display |
| `{typography.display-it}` | 56–120px | Instrument Serif italic | 400 | Manifesto-scale italic quote body |
| `{typography.numeral-jumbo}` | 220–720px | Instrument Serif | 400 | Chapter-divider ordinal numeral |
| `{typography.numeral-lg}` | 120–280px | Instrument Serif | 400 | Decorative quotation mark, oversized punctuation |
| `{typography.numeral-md}` | 72–144px | Instrument Serif | 400 | Hero stat figure |
| `{typography.headline}` | 40–88px | Instrument Serif | 400 | Primary section headline, large quote body |
| `{typography.headline-sm}` | 32–56px | Instrument Serif | 400 | Region headline, ledger/calendar topbar |
| `{typography.date-rail}` | 48–96px | Instrument Serif | 400 | Date or date-range stacked at top of a surface |
| `{typography.ledger-title}` | 20–30px | Instrument Serif | 400 | Title cell inside a calendar/ledger row |
| `{typography.strand-title}` | 22–32px | Instrument Serif | 400 | Title inside a numbered strand/list row |
| `{typography.strand-num}` | 28–38px | Instrument Serif | 400 | Numeral cell inside a strand row |
| `{typography.body-lede}` | 15–18px | Archivo | 400 | Lede paragraph following a chapter headline |
| `{typography.body}` | 14–16px | Archivo | 400 | Standard body paragraph |
| `{typography.body-sm}` | 11–13px | Archivo | 400 | Footer-band body text, dense metadata |
| `{typography.micro-label}` | 11–14px | Archivo | 600 | Universal uppercase eyebrow label |
| `{typography.micro-label-tight}` | 10–12px | Archivo | 600 | Smaller uppercase label inside footer cells |
| `{typography.rail-label}` | 11–13px | Archivo | 600 | Vertical rotated rail label |
| `{typography.mono-data}` | 12–14px | JetBrains Mono | 400 | Chart year/value labels, mono inline data |
| `{typography.mono-date}` | 13–16px | JetBrains Mono | 400 | Date column in calendar ledgers |
| `{typography.pagenum}` | 11–13px | JetBrains Mono | 400 | Persistent page number |
### Defaults
- **Default size for a cover-scale display headline**: `{typography.display}` (120–240px clamp). Anything smaller reads as section-level, not cover-level.
- **Default size for a primary section headline**: `{typography.headline}` (40–88px clamp).
- **Default size for a chapter-divider numeral**: `{typography.numeral-jumbo}` (220–720px clamp). Don't shrink — the jumbo numeral is the point of a divider surface.
- **Default size for a hero statistic**: `{typography.numeral-md}` (72–144px clamp). Stat figures share the same serif as headlines — they are display moments, not data chrome.
- **Default size for a paragraph body**: `{typography.body}` (14–16px). For a lede after a chapter headline, step up to `{typography.body-lede}` (15–18px).
- **Default size for any eyebrow label**: `{typography.micro-label}` (11–14px) at weight 600, uppercase, 0.18em tracking.
- **Default weight for any Archivo body**: 400. Archivo body at any other weight breaks the rhythm.
- **Default weight for any micro-label**: 600. Labels at weight 400 or 700 read as either timid or oversized.
- **Default tracking for any uppercase label**: 0.16em minimum, 0.32em maximum. Labels without wide tracking read as code, not editorial.
When unsure which display token to reach for, default to `{typography.headline}` (40–88px) for the primary moment, and `{typography.numeral-md}` (72–144px) for a single hero statistic. The display, display-sm, and display-md tokens are reserved for cover/colophon/poster-scale moments.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every display, numeral, headline, and ledger-title element is Instrument Serif at weight 400.** Bold serif display does not exist in this system — the face's contrast is its weight signal. Setting Instrument Serif at weight 700 collapses the entire elegance.
- **Every Instrument Serif display element uses tight line-height (0.84–1.06).** Generous line-height on display destroys the editorial poster feel — large serif headlines must feel stacked, not aerated.
- **Every Instrument Serif display element uses negative letter-spacing.** Display, headline, jumbo numerals at −0.018 to −0.04em; italic display at −0.005em. Without negative tracking, the wide-bodied glyphs read as untreated.
- **Every micro-label is uppercase Archivo weight 600 with tracking ≥ 0.16em.** No exceptions. A label without uppercase + tracking is not a label in this system; it's a stray sans element.
- **Every numerical metadata element (date, page number, chart value, calendar date) is JetBrains Mono.** Serif numerals are for display moments; mono numerals are for data chrome. Don't cross the line.
- **Every italic manifesto-scale quote uses `{typography.display-it}`.** Setting an italic quote at headline scale (40–88px) reads as a smaller moment; the italic is meant to dominate.
- **Every body paragraph is Archivo weight 400 with line-height ≥ 1.45.** Body in Instrument Serif does not exist — Instrument is for display only.
### Typography Principles
The voice contrast is **slow elegant serif ↔ wide-tracked uppercase sans ↔ tabular mono**. Italic Instrument is the system's "feeling" voice (reserved for quotes and manifesto moments); roman Instrument is the "statement" voice; Archivo upper-tracked is the "label" voice; mono is the "data" voice. Each has a single job.
Mixing rules are tight: an `<em>` inside an Instrument Serif headline stays in italic Instrument Serif (no face switch). An `<em>` inside an Archivo body paragraph becomes italic Archivo, not a serif. Don't mix faces inline.
Color is locked to ink on every element. There is no "accent color text" treatment in this system — accent is delivered through atmospheric blooms and panel fills, not text color.
## Layout
### Canvas System
The system targets `100vw × 100vh` per slide. Slides are absolutely positioned and crossfade via opacity transition (280ms ease). Only one slide is `.active` at a time. Every measurement uses CSS `clamp()` with both vw and vh terms — typography clamps include `min(...vw, ...vh)` patterns so display type scales by whichever viewport axis is shorter.
### Padding and Margin Scale
| Token | Range | Use |
|---|---|---|
| `{spacing.pad-edge}` | 40–76px | Standard edge padding from any slide edge to content |
| `{spacing.pad-region}` | 40–80px | Internal padding inside a flooded yellow panel or major region |
| `{spacing.pad-foot}` | 56–88px | Bottom padding when the footer band is present |
| `{spacing.gap-region}` | 20–48px | Gap between two major content columns/regions |
| `{spacing.gap-strand}` | 14–22px | Gap between strand rows in a numbered list |
| `{spacing.gap-footer-col}` | 20–44px | Gap between columns of the footer-band metadata strip |
| `{spacing.pagenum-bottom}` | 22–42px | Bottom inset of the persistent pagenum |
| `{spacing.pagenum-right}` | 24–48px | Right inset of the persistent pagenum |
### Persistent Chrome
The **pagenum** is the only persistent on-canvas element. It appears at `bottom-right` of every slide in JetBrains Mono at 11–13px, color ink, opacity 0.75. A **nav-hint** (`← / → · space`) appears once, fixed to the bottom-left of the viewport in JetBrains Mono at 10–12px / opacity 0.4. The nav-hint is not part of the slide composition — it lives outside the `.stage`.
### Edge Discipline
Every meaningful element respects a minimum 40px (mobile) to 76px (desktop) edge inset. The system's elegance depends on negative space at the edges — pushing content to the bleed (other than full-bleed panels, blooms, and tile blocks) breaks the catalogue feel.
### Atmospheric Layer
Every slide may carry one or both atmospheric layers behind content:
- A **sun-bloom** (`{components.sun-bloom}`) — a large soft radial gradient of solar yellow, sized 42-70% of viewport, placed off-center or behind a focal element.
- An **ember-bloom** (`{components.ember-bloom}`) — a small warm peach radial gradient at 15-22% opacity, placed in a corner opposite the sun bloom.
These layers are not optional decoration — they are the system's primary depth mechanism. A surface without a bloom reads as flat parchment.
## Depth and Elevation
### No Drop Shadows
The system has **zero drop shadows**. No `box-shadow`, no `text-shadow`, no `filter: drop-shadow(...)`. Depth is delivered atmospherically.
### Atmospheric Depth (Sun Bloom)
The primary depth mechanism is the **sun-bloom** — a large soft radial gradient of solar yellow blooming from a point on the canvas. Bloom anatomy is a layered radial gradient with three or four color stops:
- 0%: `{colors.sun}` at 70-95% opacity (the hot core)
- ~30-40%: `{colors.sun}` at 40-65% opacity (the bloom)
- ~55-65%: `{colors.haze}` at 18-22% opacity (the soft extension)
- 80-90%: `{colors.paper}` at 0% (smooth fade into ground)
Bloom size and position varies by surface need: cover surfaces use a centered or slightly-off-center bloom 42% × 38% of viewport; chapter surfaces use a corner-anchored 720px-radius bloom; closing surfaces use a bottom-anchored 55% × 50% bloom rising from below.
### Counter-Temperature Accent (Ember Bloom)
An optional **ember-bloom** in a corner opposite the sun-bloom provides warm-cool color tension without raising the saturation of the canvas. Always at 15-22% opacity, always smaller than the sun-bloom, always subordinate.
### Geometric Underprint (Block Tiles)
On cover and colophon surfaces, an additional **block-tile** layer can appear behind content — translucent solar yellow rectangles placed on an 8-row × 4-column grid system at 40-70% opacity. This layer suggests a layered poster underprint without committing to a solid panel. The tiles are decorative geometry, not active content regions.
### Yellow Panel (Structural Color)
For surfaces that need the strongest possible color statement, a **yellow-panel** flood (`{components.yellow-panel}`) covers a column, half, or third of the canvas in saturated `{colors.sun}`. This is the only "hard" color treatment in the system — when a panel is used, ink text sits on top at full opacity. Panels do not have borders or shadows; they meet the paper edge or another panel edge directly.
### Hairline Rules
Internal structural depth is delivered by **1px solid ink hairline rules** separating header bands from content, ledger rows from each other, and footer columns from each other. Rules are never thicker than 1px. Between secondary list rows (e.g., strand separators), the rule drops to `rgba(27, 37, 102, 0.18-0.2)` — same color, lower opacity.
## Shapes and Treatment
### Border Radius
**Zero, on everything.** Every shape is a strict rectangle. The radial blooms are technically circles but they have no visible edge — they fade into paper.
### Border Weights
- **1px solid `{colors.ink}`** — the universal rule. Used for header-band underlines, ledger row separators, footer-column tops, and the bordered chart bar accent on the lit row.
- **1px solid `rgba(27, 37, 102, 0.18-0.2)`** — soft variant of the same rule. Used for secondary row separators inside dense lists where full-weight ink would feel heavy.
The system has **no thicker borders**. There are no 2px, 3px, or 4px outlines anywhere. The visual structure depends on the lightness of the hairline.
### Decorative Element Types
**Sun-bloom** — Large soft radial gradient of solar yellow placed off-center or behind a focal element. The system's primary depth mechanism. Always one per surface, sometimes paired with a counter-bloom.
**Ember-bloom** — Small warm peach radial gradient at 15-22% opacity, placed in a corner opposite the sun-bloom. Subordinate atmospheric balance.
**Block-tile underprint** — Translucent solar yellow rectangles placed on an 8×4 grid system. Decorative geometry suggesting a layered poster, used on cover and colophon-type surfaces.
**Yellow panel** — A full-bleed column, half, or third of the canvas flooded with `{colors.sun}`. The system's strongest color statement. Carries ink text on top.
**Hairline rule** — 1px solid ink. Used for header-band underlines, ledger separators, footer column tops. The system's only border.
**Footer band** — A four-column metadata strip at the bottom of cover/colophon surfaces. Each cell has a `{components.hairline-rule}` top border, an Archivo micro-label, and a short body statement.
**Strand row** — Numbered editorial list row with serif numeral cell + serif title + sans body, separated from the next row by a hairline-soft rule.
**Ledger row** — Four-column tabular calendar/itinerary row: mono date + serif title + sans venue + mono duration (right-aligned), separated by hairline-soft rules.
**Vertical rail label** — Rotated Archivo uppercase text running up the left edge of a chapter-divider surface, with 0.32em tracking.
**Date rail** — Large serif date or date-range stacked at top-right of cover surfaces, often using an en-dash to indicate a span across years or months.
**Jumbo numeral** — A single huge Instrument Serif numeral (220-720px) dominating a divider surface. Always serif, always at weight 400, always with tight line-height.
**Chart bar** — A solid ink rectangle whose width carries the data value. The featured/current bar swaps to yellow fill with a 1px ink stroke (`{components.bar-lit}`). Chart layouts use grid-row patterns: mono year label + bar + mono value, separated by gap.
## Do's and Don'ts
### Do
- Apply `{colors.paper}` as the universal background. Every surface starts on parchment.
- Set every line of text in `{colors.ink}` — display, body, micro-label, mono, everything. The single text color is non-negotiable.
- Use Instrument Serif at weight 400 with tight line-height (0.84-1.06) and negative letter-spacing (-0.018 to -0.04em) for every display moment. The serif's elegance lives in this configuration.
- Add at least one `{components.sun-bloom}` to every surface. Atmospheric depth is the system's depth mechanism; a flat parchment surface reads as broken.
- Pair a sun-bloom with an `{components.ember-bloom}` in the opposite corner when you want warm-cool tension without raising the overall saturation.
- Use `{components.hairline-rule}` (1px solid ink) for every structural separator: header-band underline, ledger row, footer column, strand separator.
- Set every uppercase label in Archivo weight 600 with 0.16-0.32em tracking. Without the wide tracking, labels read as code, not editorial.
- Use `{components.yellow-panel}` (full-bleed sun column or panel) when a surface needs strongest color commitment — keep ink text on top at full opacity.
- Place the persistent `{components.pagenum}` (JetBrains Mono, 75% opacity ink) at bottom-right of every surface.
- Reserve JetBrains Mono exclusively for numerical and metadata callouts: dates, ledger figures, chart values, page numbers, nav-hint. Never use mono for display or body.
### Don't
- Don't add drop shadows. The system has zero box-shadows and zero text-shadows. Adding any blurred or offset shadow breaks the printed-paper feel immediately.
- Don't round any corner. Every shape is strict rectangle. Border-radius is forbidden.
- Don't use borders thicker than 1px. The hairline rule is the only border vocabulary; 2px, 3px, or 4px outlines do not exist.
- Don't set Instrument Serif at weight 700 or any bold weight. The serif's character lives at weight 400; bold serif display flattens the system.
- Don't introduce a second text color. Yellow text on paper, ember text anywhere, or muted-ink secondary text — none exist. Text is always full-opacity ink.
- Don't crowd the canvas with cards or panels. The system reads as elegant when sparse. Bordered cards, button stacks, or multi-region grids of containers break the editorial restraint.
- Don't invert: ink panels with yellow or paper text are not part of the system. Ink ground is reserved for chart bars and small rule elements only.
- Don't substitute Inter, Helvetica, or system-ui for Archivo, or Times for Instrument Serif. The font selection is the visual identity; substitution collapses the aesthetic.
- Don't use mono for body or headlines. JetBrains Mono is exclusively for numerical/metadata chrome.
- Don't omit the bloom layer on a surface. A flat parchment slide reads as a CMS template; the bloom is the atmosphere that signals "biennale".
## Responsive Behavior
This system is built as a **viewport-fluid 100vw × 100vh deck** with no responsive breakpoints. Every font size, padding value, and gap uses CSS `clamp()` with both vw and vh terms — `clamp(40px, min(4.4vw, 7vh), 88px)` is a typical pattern. Display type scales by whichever viewport axis is shorter, so portrait orientations don't blow out the headlines.
### Scaling Behavior
- Cover-scale display scales 120px → 240px.
- Chapter-divider jumbo numeral scales 220px → 720px.
- Headline scales 40px → 88px.
- Body scales 14px → 16px.
- Edge padding scales 40px → 76px.
- Hairline rule (1px) and pagenum sizing (11-13px) are essentially fixed.
### Presenter Behavior
- Slides advance via `ArrowRight`, `PageDown`, or `Space`.
- Slides reverse via `ArrowLeft` or `PageUp`.
- `Home` jumps to first slide, `End` to last.
- Horizontal touch swipe with a 40px threshold advances/reverses.
- Slide crossfades at 280ms ease via `opacity` toggle on the `.active` class. Only the active slide is `pointer-events: auto`.
### Print Behavior
The system has no `@media print` rule. The crossfade transition is screen-only. For static export, capturing each slide individually via screenshot preserves all atmospheric layers (the radial blooms are pure CSS gradients, not assets).
### Mobile Behavior
The `min(vw, vh)` pattern in display clamps means narrow portrait viewports automatically shrink display type to fit. The strand and ledger rows use fixed-px first columns (56px, 92px) that may feel tight on narrow widths — the system is designed for landscape presentation contexts and is functional but not optimized for sub-768px portrait usage.
## CJK & International Content
When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.
### Recommended Chinese Pairing
| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| Display / numerals / headlines / date rail | Instrument Serif 400 | 得意黑 Smiley Sans (oblique) — display moments; 思源宋体 Noto Serif SC 400 as fallback for long-form serif headlines |
| Body / lede / micro-label | Archivo 400–600 | 思源宋体 Noto Serif SC 400 for body; 思源黑体 Noto Sans SC 600 for micro-labels |
| Mono data / dates / page numbers | JetBrains Mono 400 | 思源黑体 Noto Sans SC 500 with tabular-feeling alignment — see Known CJK Gap below |
### Mixed-Content Strategy
**Strategy A** — single CJK family per role, with Latin glyphs handled by the same CJK family. Both 思源宋体 and 思源黑体 ship Latin glyphs that read cleanly alongside Chinese characters, so a mixed sentence renders in a consistent face. 得意黑 is used surgically — only on the biggest display moments where its slight oblique slant matches the Italian-poster register Instrument Serif provides in the Latin original. For everything else (body, micro-label, mono), Noto Serif SC / Noto Sans SC carries both scripts.
### Loading
Add to the template's `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600;700&family=Noto+Serif+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/cn-fontsource-smiley-sans-oblique/font.min.css">
```
After loading, reference 得意黑 as `font-family: 'Smiley Sans Oblique', 'Noto Serif SC', serif` on the display tokens that should carry the strongest poster register.
### Universal CJK Adjustments
- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (up from 1.5–1.55), display 1.05–1.15 (up from the very tight 0.84–0.96 used on Instrument Serif). The Latin display tokens here use line-height as low as 0.84 — at that compression, CJK characters collide vertically. Open display to a minimum of 1.0 for Chinese, and 1.15+ on multi-line headlines.
- **Letter-spacing**: set to 0 on every CJK run. The Latin display tokens use negative tracking from −0.005em down to −0.04em; on square CJK glyphs this overlaps strokes and reads as broken. Micro-labels at 0.16–0.32em wide tracking also drop to 0.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. Every micro-label and rail-label in this system uses `text-transform: uppercase`; remove it for CJK runs.
- **Punctuation**: use full-width Chinese punctuation (,。:;!?「」()). Replace the en-dash separator in date ranges with a Chinese 至 or full-width 「—」 hyphen.
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `2024 春季双年展` not `2024春季双年展`.
- **One font per sentence**: 思源宋体 covers both CJK and Latin glyphs in a unified serif style — let it handle mixed editorial sentences. Don't let the browser font-switch to Archivo mid-paragraph.
### Aesthetic Notes for This System
The system's editorial identity rests on Instrument Serif's high-contrast, tall-ascender personality — a face that signals "art biennale catalogue" and "slow literary quarterly". The closest Chinese equivalent for register is **思源宋体 Noto Serif SC** for body and editorial display, with **得意黑 Smiley Sans Oblique** reserved for the poster-scale display moments where Instrument Serif at 120–240px does the heaviest identity work in the Latin original. 得意黑's slight italic tilt and slab character matches the Italian-exhibition-poster register; pure Noto Serif SC at jumbo numerals reads as restrained academic Chinese rather than biennale-loud.
The "single text color, single accent" discipline of this system transfers cleanly to CJK — ink-on-paper, sun-bloom atmosphere, hairline rules, no shadows. The micro-label treatment (Archivo weight 600, uppercase, 0.16–0.32em tracking) is the system's most fragile element when translated: CJK micro-labels lose both the uppercase signal and the wide tracking. Compensate by setting Chinese micro-labels in 思源黑体 weight 600 at 0 tracking with the **slightly heavier weight contrast** (drop body to weight 400 of 思源宋体, keep labels at 600 of 思源黑体) and by **always pairing the label with a hairline-soft rule beneath** — the rule does the chrome-recognition work the wide-tracked uppercase did in Latin.
### Known CJK Gap
- **No CDN-loadable Chinese monospace face for tabular data.** JetBrains Mono's role here (calendar ledger dates, chart year/value labels, page numbers) depends on monospaced figure rhythm that CJK doesn't provide. 思源黑体 at weight 500 with `font-feature-settings: "tnum"` gives tabular Latin digits but Chinese characters remain proportional. For ledger rows where alignment is structural, keep the date and value columns in Latin digits (Arabic numerals + Latin date abbreviations) and use 思源黑体 only for the title/venue cells.
- **Instrument Serif italic has no direct Chinese counterpart.** The italic display token (manifesto-scale quote body) loses its slow-reading personality entirely in CJK. Use 思源宋体 400 with looser line-height (1.4) and slightly larger size to compensate; consider 「」 quotation framing to signal "this is a quoted passage".
- **得意黑 may not load on restricted networks.** The cn-fontsource CDN is reliable in mainland China but less proven internationally. Always include `'Noto Serif SC', serif` in the stack as fallback so display headlines remain editorial even when 得意黑 fails.
## Iteration Guide
1. Any new surface starts on `{colors.paper}`, places at least one `{components.sun-bloom}` for atmosphere, and pins the persistent `{components.pagenum}` to bottom-right.
2. Any new headline uses Instrument Serif weight 400 with tight line-height and negative tracking. Reach for `{typography.headline}` for primary moments and `{typography.display}` only for cover-scale.
3. Any new body paragraph uses Archivo weight 400 with line-height 1.5. Lede paragraphs following a headline use the slightly larger `{typography.body-lede}` for breathing room.
4. Any new eyebrow or section tag uses the micro-label treatment: Archivo weight 600, uppercase, 0.16-0.32em tracking, ink color, no fill. Don't substitute a pill or chip.
5. Any new structural separator is a 1px `{components.hairline-rule}` in ink, or its soft variant for secondary list rows. Never reach for a thicker border.
6. Any new numerical or metadata content (date, page number, chart value, ledger figure) uses JetBrains Mono. Serif numerals are reserved for display moments only.
7. Any new "poster-scale" color statement uses `{components.yellow-panel}` — a flooded column or fraction of the canvas in `{colors.sun}` with ink text on top.
8. Any new ordered list of program items uses the `{components.strand-row}` pattern: serif numeral cell + serif title + sans body, separated by hairline-soft rule.
9. Any new tabular itinerary uses the `{components.ledger-row}` pattern: mono date + serif title + sans venue + mono duration right-aligned, separated by hairline-soft rule.
10. If a surface feels flat, add an `{components.ember-bloom}` in the opposite corner from the sun-bloom — never add a card border or shadow.
## Known Gaps
- **Instrument Serif, Archivo, and JetBrains Mono are loaded from Google Fonts** via a preconnect + `<link>`. Fallbacks (`Georgia`, `Helvetica Neue`, `ui-monospace`) are defined but render very differently — in environments where Google Fonts fail, the system collapses to generic editorial defaults and loses its identity.
- **The Instrument Serif italic axis is loaded** but used only for the manifesto-scale quote treatment. Other italic moments (an `<em>` inside a body paragraph, for instance) will not stylistically signal the same as the dedicated italic display.
- **The system has no chart engine** — the data slide uses inline `style="width: XX%"` on bar divs. Building dynamic charts requires computing widths in JS or templating the markup server-side.
- **The block-tile underprint uses hardcoded grid positions** (`grid-column: 1 / 3; grid-row: 6 / 9;`) per tile. Tiles are decorative and the placements are tuned per surface; there is no parametric tile placement system.
- **The vertical rail-label uses a rotated transform** that can produce subtle subpixel rendering artifacts on some browsers. The label is decorative; if rendering looks off, it can safely be dropped.
- **The slide navigation has no slide indicator beyond the pagenum.** There are no dot-rails, no progress bar, no thumbnail bar. The pagenum text is the only positional cue.
- **The crossfade transition is screen-only** and doesn't degrade to a sensible print/static state. Capturing slides for PDF export requires manual screenshot per surface.
- **The cover and colophon footer-band columns use fractional widths** (`1.1fr 1fr 1.4fr 2fr` and `1.2fr 1.1fr 1fr 1.4fr`). These ratios are tuned to the demo content and may need adjusting if footer cells carry significantly different text length.
- **The system loads Google Fonts with `ital` axis for Instrument Serif** but only `wght` axes for Archivo and JetBrains Mono. Adding italic body or italic mono moments requires updating the font-loading request.
# Biennale Yellow Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/biennale-yellow/design.md`
- Preview card: `bold-template-pack/templates/biennale-yellow/preview.md`
## Selection Metadata
- Slug: `biennale-yellow`
- Tagline: Solar yellow on warm parchment with deep indigo serif and atmospheric sun-glow gradients.
- Mood: editorial, atmospheric, warm, cultural-institution, poster-like
- Tone: literary, considered, contemplative, warm-modern, Dutch-editorial
- Formality: high
- Density: medium
- Scheme: light
- Best for: Anything that should feel like an art-biennale poster or a museum's annual programme: exhibition decks, arts-institution announcements, design conference brochures, curatorial pitches, literary publications, studio retrospectives. Equally good for any deck wanting Dutch-editorial atmosphere with an unmistakable single-color signature.
- Avoid for: Decks that need visual punch or saturated multi-color energy — the warm-paper canvas and one-yellow palette are intentionally quiet and atmospheric.
## Visual Snapshot
A literary-editorial presentation system in the visual register of an art biennale catalogue or quiet exhibition poster. The aesthetic is built on warm parchment grounds (#E9E5DB) flooded with soft solar yellow (#F1EE2E) radial blooms, set against a single deep indigo navy ink color. Display type is Instrument Serif — a contemporary high-contrast serif with tall ascenders and elegant italics — paired with Archivo for sans-serif chrome and JetBrains Mono for numerical and metadata callouts. No drop shadows, no rounded corners, no bordered cards: the only structural lines are hairline 1px rules in ink. The mood sits between a folded museum brochure, a slow-reading literary quarterly, and a Mediterranean exhibition poster — confident, atmospheric, and deeply restrained.
Biennale Yellow is a literary-editorial presentation system modeled on the visual language of European art biennale catalogues, slow exhibition posters, and quarterly literary publications. There are no cards, no buttons, no shadows, no rounded corners. The structural vocabulary is just three things: paper, ink, and yellow.
## Preview Ingredients
- Palette: paper #E9E5DB; paper-deep #DCD6C4; sun #F1EE2E; sun-soft #F8F39B; haze #F0DA7C; ink #1B2566; ember #E26B4A
- Typography: See full design doc after selection.
- Signature move: Warm parchment ground ({colors.paper}) on every surface; never white, never gray.
- Signature move: Single ink color ({colors.ink}) for all text and all rules — no secondary text colors.
- Signature move: Solar yellow ({colors.sun}) deployed three ways: as a flooded panel, as a soft radial bloom, as a translucent geometric tile underprint.
- Signature move: Instrument Serif handles every display moment at scales from 40px to 720px+.
- Signature move: Archivo Bold uppercase + 0.16–0.32em tracking is the universal label voice.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: BlockFrame
description: A maximalist neobrutalist presentation system built on 4px solid black borders, 8px hard offset shadows, and a high-key candy palette of five saturated pastels plus cream and off-white. Display type runs Inter at weight 800-900 in tight uppercase; secondary chrome uses Space Grotesk as a quasi-monospace label face. Tilted decorative shapes (rotated stars, rectangles, badges) puncture the borders and break the grid intentionally. Pastels are paired loudly: pink + blue + green + yellow + cream cycle through every region with deliberate juxtaposition. The aesthetic borrows from zine layout, 1990s-revival sticker books, and contemporary toy packaging — bold, joyful, slightly chaotic, never timid.
colors:
black: "#000000"
white: "#FFFFFF"
offwhite: "#FFFDF5"
pink: "#FE90E8"
blue: "#C0F7FE"
green: "#99E885"
yellow: "#F7CB46"
cream: "#FFDC8B"
borders:
primary: "4px solid {colors.black}"
thin: "3px solid {colors.black}"
shadows:
default: "8px 8px 0px {colors.black}"
small: "4px 4px 0px {colors.black}"
hover: "6px 6px 0px {colors.black}"
close-yellow: "12px 12px 0px {colors.yellow}"
close-white: "6px 6px 0px {colors.white}"
typography:
heading-xl:
fontFamily: "'Inter', sans-serif"
fontWeight: 900
fontSize: "clamp(48px, 6vw, 96px)"
lineHeight: 0.95
letterSpacing: -0.03em
textTransform: uppercase
heading-lg:
fontFamily: "'Inter', sans-serif"
fontWeight: 800
fontSize: "clamp(32px, 4vw, 64px)"
lineHeight: 1
letterSpacing: -0.02em
textTransform: uppercase
heading-md:
fontFamily: "'Inter', sans-serif"
fontWeight: 700
fontSize: "clamp(24px, 2.5vw, 40px)"
lineHeight: 1.1
letterSpacing: -0.01em
close-title:
fontFamily: "'Inter', sans-serif"
fontWeight: 900
fontSize: "clamp(40px, 5vw, 80px)"
lineHeight: 0.95
letterSpacing: -0.03em
textTransform: uppercase
quote-text:
fontFamily: "'Inter', sans-serif"
fontWeight: 900
fontSize: "clamp(28px, 3.5vw, 52px)"
lineHeight: 1.15
letterSpacing: -0.02em
textTransform: uppercase
stat-number:
fontFamily: "'Inter', sans-serif"
fontWeight: 900
fontSize: "clamp(36px, 4vw, 64px)"
lineHeight: 1
card-title:
fontFamily: "'Inter', sans-serif"
fontWeight: 700
fontSize: 22px
lineHeight: 1.2
textTransform: uppercase
step-num:
fontFamily: "'Inter', sans-serif"
fontWeight: 900
fontSize: 48px
lineHeight: 1
body:
fontFamily: "'Inter', sans-serif"
fontWeight: 500
fontSize: "clamp(16px, 1.2vw, 20px)"
lineHeight: 1.6
body-card:
fontFamily: "'Inter', sans-serif"
fontWeight: 500
fontSize: 15px
lineHeight: 1.6
list-body:
fontFamily: "'Inter', sans-serif"
fontWeight: 500
fontSize: 16px
lineHeight: 1.5
label:
fontFamily: "'Space Grotesk', monospace"
fontWeight: 600
fontSize: 13px
lineHeight: 1
letterSpacing: 0.08em
textTransform: uppercase
mono-tag:
fontFamily: "'Space Grotesk', monospace"
fontWeight: 600
fontSize: 14px
lineHeight: 1
letterSpacing: 0.05em
textTransform: uppercase
mono-meta:
fontFamily: "'Space Grotesk', monospace"
fontWeight: 500
fontSize: 15px
letterSpacing: 0.02em
subtitle-mono:
fontFamily: "'Space Grotesk', monospace"
fontWeight: 500
fontSize: 18px
lineHeight: 1.5
counter:
fontFamily: "'Space Grotesk', monospace"
fontWeight: 700
fontSize: 14px
lineHeight: 1
letterSpacing: 0.1em
textTransform: uppercase
legend-item:
fontFamily: "'Space Grotesk', monospace"
fontWeight: 600
fontSize: 13px
spacing:
slide-pad: 60px
card-pad-lg: 60px
card-pad-md: 36px
card-pad-sm: 28px
card-pad-xs: 22px
gap-lg: 48px
gap-md: 32px
gap-sm: 24px
gap-xs: 16px
pad-bottom-clearance: 110px
canvas:
width: 100vw
height: 100vh
default-background: "{colors.offwhite}"
components:
card-elevated:
border: "4px solid {colors.black}"
background: "{colors.white}"
boxShadow: "{shadows.default}"
description: "Primary elevated card. 4px ink border + 8px ink offset shadow. Background is white by default; on darker surfaces background may shift to offwhite or to a colored fill."
card-flat:
border: "4px solid {colors.black}"
background: "{colors.white}"
description: "Bordered card without elevation shadow. Used for secondary content cells inside multi-card grids where the shadow would compound."
card-small:
border: "3px solid {colors.black}"
background: "{colors.white}"
boxShadow: "{shadows.small}"
description: "Compact card with thinner border + smaller offset shadow. Used for intro-cards, stat-cards, team-cards, and timeline-steps."
label-pill:
border: "3px solid {colors.black}"
padding: "6px 16px"
fontFamily: "'Space Grotesk', monospace"
fontSize: 13px
fontWeight: 600
letterSpacing: 0.08em
textTransform: uppercase
background: "{colors.white}"
boxShadow: "{shadows.small}"
description: "Universal section eyebrow. White base by default; pink, blue, green, yellow, cream variants swap background. Always sits on a 3px black border with a 4px hard offset shadow."
button-primary:
border: "3px solid {colors.black}"
background: "{colors.yellow}"
color: "{colors.black}"
padding: "14px 32px"
fontFamily: "'Inter', sans-serif"
fontWeight: 700
fontSize: 16px
boxShadow: "{shadows.small}"
description: "Primary CTA. Yellow fill with black text, 3px black border, 4px offset shadow. Hover lifts the button -2/-2 and grows shadow to 6px."
corner-bracket:
width: 24px
height: 24px
border: "3px solid {colors.black}"
description: "Two L-shaped brackets at opposite corners of a card or frame (tl + br + tr + bl pattern available). Sits inside the card edge as a decorative frame-within-frame."
icon-square:
width: 64px
height: 64px
border: "3px solid {colors.black}"
description: "Solid pastel square (pink/blue/green) holding a single uppercase letter glyph at weight 700 / 28px. Used as feature-card icons."
feature-deco:
width: 48px
height: 48px
border: "3px solid {colors.black}"
background: "{colors.yellow}"
position: "absolute top -12px right 24px"
description: "Yellow square notch that protrudes from the top edge of a feature card, breaking the card's top border line."
stat-deco-dot:
width: 12px
height: 12px
borderRadius: 50%
border: "2px solid {colors.black}"
description: "Small black-bordered colored circle pinned to the top-right of a stat card. The only round shape used on cards. Fill cycles through the pastel palette."
avatar-square:
width: 72px
height: 72px
border: "3px solid {colors.black}"
background: "{colors.pink}"
fontFamily: "'Inter', sans-serif"
fontWeight: 900
fontSize: 28px
textTransform: uppercase
description: "Square avatar with two-letter initials, used in team grids. Fill cycles through the pastel palette."
list-number:
width: 36px
height: 36px
border: "3px solid {colors.black}"
background: "{colors.yellow}"
fontFamily: "'Space Grotesk', monospace"
fontWeight: 700
fontSize: 14px
description: "Square numerical bullet pinned to the left of each list item. Black border, yellow fill, mono numeral."
star-burst:
clipPath: "polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)"
border: "3px solid"
background: "{colors.pink}"
description: "10-point star clipped via CSS clip-path with a 3px border. Decorative attention-grabber pinned to corners of close-frames and feature cards."
stripe-block:
background: "repeating-linear-gradient(45deg, {colors.black}, {colors.black} 4px, {colors.green} 4px, {colors.green} 12px)"
border: "3px solid {colors.black}"
description: "Black-and-color diagonal stripe panel used as decorative attention block on poster-class surfaces."
bg-dot-grid:
backgroundImage: "radial-gradient(circle, {colors.black} 1.2px, transparent 1.2px)"
backgroundSize: "24px 24px"
description: "Faint dot-grid background pattern used as an overlay on light surfaces or as decoration in corners of cards."
tilt-card:
transform: "rotate(±2deg) or rotate(±8deg)"
description: "Card with intentional tilt. Stat cards alternate -2deg / +2deg; decorative rectangles tilt up to ±12deg. The tilt is the system's playful structural signature."
nav-btn:
width: 48px
height: 48px
border: "3px solid {colors.black}"
background: "{colors.white}"
boxShadow: "{shadows.small}"
description: "Square nav arrow button. Hover translates -2/-2 and grows shadow; active translates 2/2 and shrinks shadow."
slide-counter:
border: "3px solid {colors.black}"
background: "{colors.white}"
padding: "10px 18px"
boxShadow: "{shadows.small}"
description: "Persistent slide counter pill at bottom-left. Space Grotesk uppercase NN / NN format."
---
## Frontend Slides Fixed-Stage Policy
When this design system is used by the `frontend-slides` skill, generate the final deck as a **fixed 1920×1080 stage** that scales uniformly to the browser viewport. The deck should preserve a 16:9 slide canvas on every screen, including phones; it may letterbox or pillarbox, but it should not reflow slide content for mobile.
This policy has higher priority than any source-template responsive behavior described later in this file. If a later section says the original template is viewport-fluid, treat that as source history only, not as the target generation model for `frontend-slides`.
This policy applies even if the source template was originally implemented with viewport-fluid CSS such as `100vw`, `100vh`, `vw`, `vh`, or `clamp()`. Treat those values as design proportions to translate into 1920×1080 stage coordinates, not as live responsive rules in the generated deck.
Use `deck-stage.js` or an equivalent inline stage scaler for final output: render each slide at 1920×1080, scale the whole stage with one transform, and verify rendered screenshots for both text overflow and panel overlap.
## Overview
BlockFrame is a **maximalist neobrutalist presentation system** built on five structural laws: every region has a 4px black border, every elevated element has an 8px hard offset shadow, every corner is square, every accent color is a saturated pastel, and every layout is allowed to be a little bit crooked. The system's joy comes from the deliberate collision of these laws — bordered cards meet bordered cards, shadows stack against shadows, tilted decorations puncture the grid intentionally.
The type system pivots on **Inter** (weights 400-900) for display, body, and stats — set at weight 800-900 in tight uppercase with negative letter-spacing for headlines, weight 500 sentence case for body, and weight 700 uppercase for card titles. **Space Grotesk** (weights 400-700) is the secondary face, used as a quasi-monospace label voice for eyebrows, slide counters, stat labels, mono tags, and any chrome that should read as "system" rather than "editorial". The face combination is deliberately ordinary — both are widely-available open sans-serifs — but the treatment (heavy uppercase Inter + wide-tracked Space Grotesk) gives them a distinct neobrutalist register.
The palette is built around **five saturated pastels** (pink `#FE90E8`, blue `#C0F7FE`, green `#99E885`, yellow `#F7CB46`, cream `#FFDC8B`) plus **pure black** (`#000000`) for borders and text, **white** (`#FFFFFF`) for clean card fills, and **off-white** (`#FFFDF5`) for warm canvas. The pastels are not subtle accents — they are full-bleed surface fills. A typical deck cycles every slide through a different colored ground (offwhite cover → blue intro → offwhite content → green chart → pink quote → yellow split → offwhite timeline → blue stats → cream team → black close). This color cycling is the system's primary rhythm.
Depth is **hard offset shadow at 4px and 8px**, always solid black, always zero blur, always positioned bottom-right. Larger elements get 8px, smaller chrome gets 4px. The close-frame uses a single 12px offset in **yellow** (the only colored shadow in the system) as the system's loudest depth statement, and inverted close-frames pair 6px **white** shadows on black surfaces. Borders are 4px solid black on primary cards, 3px solid black on secondary chrome. Border weight and shadow size are tightly coupled — a 4px border carries an 8px shadow; a 3px border carries a 4px shadow.
**Density philosophy: comfortably dense.** This system reads as authoritative when packed and timid when sparse. A typical surface holds: a label-pill eyebrow + a large headline + a multi-card grid (3-6 cards) + at least one decorative element (tilted rectangle, star burst, stripe block, corner bracket, deco dots). Empty space within a region reads as "broken" — every card should be filled, every grid should be complete. The system's joy depends on the visual chatter of many bordered objects existing in the same frame.
**Key Characteristics:**
- 4px solid black borders on primary cards, 3px on secondary chrome — never thinner.
- 8px hard offset shadows on primary cards, 4px on secondary chrome — solid black, zero blur.
- Five-pastel palette (pink, blue, green, yellow, cream) plus black, white, off-white — cycled across surfaces.
- Inter weight 800-900 uppercase with negative tracking is the display voice; Space Grotesk weight 600 uppercase with 0.08em tracking is the label voice.
- Square corners everywhere except a single circular accent dot on stat cards.
- Tilted decorative elements (rotated rectangles, stars, badges) puncture the grid intentionally.
- Label pills (`{components.label-pill}`) carry a 3px border, 4px offset shadow, and a pastel fill variant — the universal section eyebrow.
- Colored fills are bold and saturated; pastels are used as panel grounds, not as light accents.
- Yellow is the default CTA color; black is the default close-surface color.
- Star bursts, stripe blocks, and dot grids are reusable decorative attention units.
## Colors
### Palette
- **Black** (`{colors.black}` — `#000000`): The structural color. Every border, every primary text moment, every shadow. Pure black, no warm bias. The system's contrast anchor.
- **White** (`{colors.white}` — `#FFFFFF`): The default card fill. Used on every primary card and as the background of label-pills and nav-buttons. Pure white, no warmth.
- **Off-white** (`{colors.offwhite}` — `#FFFDF5`): The warm canvas tone. The default body/slide background when no pastel ground is in play. Subtly warmer than pure white so that white cards sitting on top still feel layered.
- **Pink** (`{colors.pink}` — `#FE90E8`): A high-key candy magenta. Used as a full-surface ground, as label-pill fill, as icon-square fill, as star-burst fill, and as one of the pastel chart series. The most saturated of the five pastels.
- **Blue** (`{colors.blue}` — `#C0F7FE`): A pale cyan-ice blue. Used as a full-surface ground (the "intro" and "stats" feel), as label-pill fill, as icon-square fill, and as a chart series.
- **Green** (`{colors.green}` — `#99E885`): A bright spring green. Used as a full-surface ground, as label-pill fill, as icon-square fill, in the stripe-block diagonal pattern, and as a chart series.
- **Yellow** (`{colors.yellow}` — `#F7CB46`): The CTA color. Used as the default button fill, as the close-frame shadow color, as list-number squares, as the feature-deco notch, and as label-pill fill. The brightest, most attention-pulling pastel.
- **Cream** (`{colors.cream}` — `#FFDC8B`): A warm yellow-cream. Softer than yellow, more saturated than offwhite. Used as a full-surface ground (the "team" or "cover" feel), as label-pill fill, and as a tertiary chart accent.
### Defaults
- **Default surface background**: `{colors.offwhite}` for content-heavy surfaces; cycle through `{colors.cream}`, `{colors.blue}`, `{colors.pink}`, `{colors.green}`, `{colors.yellow}` for surfaces that need a stronger ground. The cycle is the rhythm; staying on one ground for many slides flattens the system.
- **Default headline color**: `{colors.black}` on all light/pastel surfaces; `{colors.white}` on the black close-surface.
- **Default body text color**: `{colors.black}` on all light/pastel surfaces; `{colors.white}` or `{colors.cream}` on dark surfaces.
- **Default border color**: `{colors.black}` — always. There are no colored borders anywhere except the 4px white border on the inverted close-frame.
- **Default card fill**: `{colors.white}`. Use a pastel fill only when the card is part of a multi-card row where each card needs distinct color identity (e.g., the timeline-step row where each step is a different pastel).
- **Default button fill**: `{colors.yellow}`. Other pastels work, but yellow is the system's primary "click here" signal.
- **Default label-pill base**: `{colors.white}`; pastel variants (`{colors.pink}`, `{colors.blue}`, `{colors.green}`, `{colors.yellow}`, `{colors.cream}`) signal section type or decorate the eyebrow.
- **Default decorative accent on stat cards**: a 12px circle (`{components.stat-deco-dot}`) in a pastel fill — cycling pink, blue, green, yellow across cards.
- **Default chart palette order**: pink → blue → green (three-series), with yellow and cream available for additional series.
The pastels are interchangeable in role — none of them carry fixed semantic meaning (green isn't "success", red doesn't exist in the palette at all). Pair them by visual juxtaposition: pink + blue + green is the most common trio; cream + yellow is the warm pair; blue + pink is the cool-warm contrast.
## Typography
### Font Family Stack
The system runs two faces.
**Inter** (weights 400-900) is the display, body, headline, and stat face. Used at weight 900 for hero/close titles and quote text, weight 800 for primary headlines, weight 700 for medium headlines and card titles, weight 500 for body. Display weights are always uppercase with negative letter-spacing (-0.02 to -0.03em); body weights are always sentence case with default tracking. The contrast between heavy uppercase display and weight-500 sentence body is the system's typographic rhythm.
**Space Grotesk** (weights 400-700) is the label and chrome face. Used at weight 600 for label-pills (13px, 0.08em tracking, uppercase) and at weight 500 for monospace meta callouts. The face is technically not monospace, but its slightly geometric character + the wide tracking treatment makes it read as the system's "code" voice.
Don't introduce a third face. The Inter + Space Grotesk pairing is the entire typographic palette.
### Typography Scale
| Token | Size (clamp / px) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.heading-xl}` | 48–96px clamp | Inter | 900 | Hero or cover-scale headline |
| `{typography.heading-lg}` | 32–64px clamp | Inter | 800 | Primary section headline |
| `{typography.heading-md}` | 24–40px clamp | Inter | 700 | Region headline, chart title |
| `{typography.close-title}` | 40–80px clamp | Inter | 900 | Closing-statement title (inverted surface) |
| `{typography.quote-text}` | 28–52px clamp | Inter | 900 | Quote body — always uppercase |
| `{typography.stat-number}` | 36–64px clamp | Inter | 900 | Stat numeral |
| `{typography.card-title}` | 22px | Inter | 700 | Feature card title — uppercase |
| `{typography.step-num}` | 48px | Inter | 900 | Numeral inside a timeline-step (opacity 0.6) |
| `{typography.body}` | 16–20px clamp | Inter | 500 | Standard body paragraph |
| `{typography.body-card}` | 15px | Inter | 500 | Body inside compact cards |
| `{typography.list-body}` | 16px | Inter | 500 | Numbered list body |
| `{typography.label}` | 13px | Space Grotesk | 600 | Text inside label-pill |
| `{typography.mono-tag}` | 14px | Space Grotesk | 600 | Mono tag/badge, slide-counter |
| `{typography.mono-meta}` | 15px | Space Grotesk | 500 | Inline mono metadata |
| `{typography.subtitle-mono}` | 18px | Space Grotesk | 500 | Hero subtitle / close subtitle |
| `{typography.counter}` | 14px | Space Grotesk | 700 | Persistent slide counter (NN / NN) |
| `{typography.legend-item}` | 13px | Space Grotesk | 600 | Chart legend label |
### Defaults
- **Default size for a hero or cover title**: `{typography.heading-xl}` (48–96px). Always uppercase, always weight 900, always with -0.03em tracking.
- **Default size for a primary section headline**: `{typography.heading-lg}` (32–64px). Uppercase, weight 800, -0.02em.
- **Default size for a region or chart title**: `{typography.heading-md}` (24–40px). The only Inter heading not in uppercase by default — though uppercase is permitted.
- **Default size for a stat numeral**: `{typography.stat-number}` (36–64px). Weight 900, line-height 1.
- **Default size for body paragraph**: `{typography.body}` (16–20px clamp). Weight 500, sentence case, line-height 1.6.
- **Default size for an eyebrow label**: `{typography.label}` (13px) inside the `{components.label-pill}`.
- **Default weight for any Inter display**: 800 or 900. Inter display at weight 700 reads as "almost there"; only use 700 for `{typography.heading-md}` or card titles.
- **Default weight for any Inter body**: 500. Body at 400 reads as too light, body at 700 reads as oversized.
- **Default tracking for any Space Grotesk label/chrome**: 0.05-0.10em. Wide tracking is the face's "chrome" signal.
- **Default tracking for any Inter display**: -0.01em (heading-md) to -0.03em (heading-xl). Display without negative tracking reads as untreated.
When unsure which heading token to reach for, default to `{typography.heading-lg}` (32–64px) for the slide's primary text moment. `{typography.heading-md}` is for region or chart titles within a slide.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Inter display element (heading-xl, heading-lg, quote-text, close-title) is uppercase.** Sentence-case Inter display at weights 800+ does not exist in this system. The uppercase + heavy-weight + negative-tracking combination is the visual identity.
- **Every Inter display element uses negative letter-spacing** (-0.01 to -0.03em). Display without negative tracking reads as default Inter, which is a fundamentally different aesthetic.
- **Every label-pill carries the 3px border + 4px shadow + uppercase Space Grotesk text** combination. A label without all three properties is not a label-pill — it's a stray text element.
- **Every card-title is uppercase Inter weight 700.** Card titles in sentence case break the brutalist rhythm.
- **Every Space Grotesk label/chrome/counter is uppercase with 0.05-0.1em tracking.** Sentence-case Space Grotesk does not exist in this system except for body-adjacent metadata (mono-meta, mono inline).
- **Every stat numeral is Inter weight 900 with line-height 1.** Stat numerals are display moments, not data chrome.
- **Every Inter body block is sentence case with line-height 1.6 (or 1.5 for compact card body).** Body in uppercase or with tight line-height reads as broken.
- **Step numbers inside timeline-step cards are 48px weight 900 at opacity 0.6.** The reduced opacity is mandatory — full-opacity step numbers overwhelm the step title.
### Typography Principles
The voice contrast is **bold uppercase display ↔ sentence body ↔ wide-tracked label**. Italic is never used. Underline is never used. The only emphasis mechanism is weight contrast within the Inter ladder and the uppercase/sentence-case switch.
Display elements should be allowed to **dominate the canvas**. The system is built for poster-scale typography; reading a heading-xl at small size collapses its character. Lean into the upper bound of every clamp.
## Layout
### Canvas System
The system targets `100vw × 100vh` per slide. Slides are absolutely positioned and toggled via `display: none` / `display: flex` on the `.active` class. Default slide padding is 60px on all sides. Slides that contain bottom-anchored grids (timeline, team grid, chart with stat column) carry an additional `padding-bottom: 110px` to clear the fixed slide-counter and nav-controls chrome.
The default slide flex direction is column with `justify-content: center`. For two-column splits (intro slide, split image+text), flex direction switches to row.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad}` | 60px | Default slide padding from edge to content |
| `{spacing.card-pad-lg}` | 60px | Hero-frame and quote-frame internal padding |
| `{spacing.card-pad-md}` | 36px | Feature-card internal padding |
| `{spacing.card-pad-sm}` | 28px | Intro-card internal padding |
| `{spacing.card-pad-xs}` | 22px | Team-card and small-cell padding |
| `{spacing.gap-lg}` | 48px | Gap between major sections (header-to-grid) |
| `{spacing.gap-md}` | 32px | Gap between feature cards |
| `{spacing.gap-sm}` | 24px | Gap between intro cards, stat cards |
| `{spacing.gap-xs}` | 16px | Gap inside list items, intra-card content |
| `{spacing.pad-bottom-clearance}` | 110px | Bottom padding reserve to clear fixed nav chrome |
### Persistent Chrome
Three elements appear on every slide:
- **Slide counter** at bottom-left — 3px black border, white fill, 4px shadow, Space Grotesk 14px weight 700 uppercase, NN / NN format.
- **Nav controls** at bottom-right — two 48px square nav buttons with 3px borders, white fills, 4px shadows.
- The slide-counter and nav-controls are not part of the slide composition — they live outside `.slides-container` and overlap the bottom edge.
### Card-on-Card Structure
The system's primary layout pattern is **cards on grounds on grounds**. A typical slide places a colored-ground surface, on which sits a white card with 4px black border + 8px shadow, which may contain smaller cards or icon-squares. Each level of nesting carries its own border weight: 4px for the outer card, 3px for inner chrome. This nested-bordered structure is what gives the system its dense, packed feel.
### Decorative Disruption
Tilted decorative elements (rotated rectangles, stars, badges, dot grids) are placed absolutely on slide and card surfaces to puncture the grid intentionally. These are not "background decoration" — they are part of the composition. A surface without any decorative element reads as too clean.
## Depth and Elevation
### Hard Offset Shadow Stack
The system uses three primary shadow values:
- **`{shadows.default}`** = `8px 8px 0px {colors.black}` — primary card shadow. Used on hero-frame, feature-card, quote-frame, chart-frame, and any elevated card.
- **`{shadows.small}`** = `4px 4px 0px {colors.black}` — secondary chrome shadow. Used on intro-card, stat-card, team-card, timeline-step, label-pill, button-primary, nav-btn, slide-counter.
- **`{shadows.hover}`** = `6px 6px 0px {colors.black}` — hover state for buttons and nav. Triggered with a -2/-2 transform.
All shadows are solid black, zero blur, fixed offset bottom-right. The shadow + transform pairing on hover creates a "lifting off the page" interaction signature — the element translates -2/-2 while the shadow grows to 6/6, simulating a peel-up.
### Inverted Shadows
On the dark close-surface, shadows invert their color but keep the offset logic:
- **`{shadows.close-yellow}`** = `12px 12px 0px {colors.yellow}` — the loudest depth statement in the system. Used on close-frame to make the inverted surface read as still "elevated" despite its dark ground.
- **`{shadows.close-white}`** = `6px 6px 0px {colors.white}` — used on the close-btn to maintain elevation on the black ground.
These colored shadows are the only exceptions to the "shadows are always black" rule, and they appear only on the dark surface.
### Border-Based Depth
Most of the system's apparent layering comes from the 4px or 3px ink borders, not from shadow. A card with a border but no shadow still reads as "an object on a surface" — the shadow is what makes it read as "lifted". Use shadow for elevated cards; use border-only for secondary cards inside a multi-card grid where stacked shadows would compound into noise.
### Tilted Elements as Depth
The system's playful depth signature is **tilt**. Stat cards alternate -2deg / +2deg rotation. Decorative pink rectangles tilt up to ±12deg. The yellow button tab on the hero frame tilts -3deg. These tilts break the grid alignment intentionally and create perceived dimensionality without using actual perspective or shadow.
## Shapes and Treatment
### Border Radius
- **0px** on everything structural — cards, label-pills, buttons, icon-squares, list-numbers, avatars, badges. Square corners are non-negotiable.
- **50% (circle)** used only for the stat-deco dot (12×12 circular accent pinned to stat cards). This is the only round shape in the system.
The square-corner discipline is the system's structural identity. Adding rounded corners to any card or chip immediately reads as a different aesthetic.
### Border Weights
- **4px solid `{colors.black}`** — used on primary cards (hero-frame, feature-card, quote-frame, chart-frame, team-card border, timeline-step border, stat-card border) and the close-frame inverse (4px solid white on black ground).
- **3px solid `{colors.black}`** — used on secondary chrome (label-pill, button, intro-card, icon-square, list-number, avatar, corner-bracket, nav-btn, slide-counter, stripe-block, star-burst). The 3px weight signals "secondary structural" vs. the 4px "primary structural".
- **2px solid `{colors.black}`** — used only on legend swatches (16×16 chart swatches) and stat-deco dots. The thinnest border weight, reserved for atomic chrome.
- **4px solid `{colors.white}`** — used only on the inverted close-frame, the visual-box, and its ::after offset frame on the dark split-visual surface.
The border weight ladder (2 / 3 / 4) is fixed. No 1px borders, no 5px+ borders.
### Decorative Element Types
**Label-pill** — Square bordered pill (3px black border, 4px shadow), pastel or white fill, Space Grotesk 13px weight 600 uppercase text with 0.08em tracking. The universal section eyebrow.
**Corner-bracket** — Two L-shaped brackets (or four for full enclosure) at the corners of a card, 3px black border. Creates a frame-within-frame decorative motif.
**Star-burst** — 10-point star clipped via CSS clip-path with a 3px border, pastel fill. Decorative attention-grabber pinned to corners of close-frames and feature cards.
**Stripe-block** — Diagonal 4px-on, 8px-off stripe pattern in black + a pastel color, framed with a 3px black border. Decorative attention block used on poster-class surfaces.
**Dot-grid** — 1.2px radial-gradient dot pattern at 24×24 spacing. Used as a faint decorative overlay in corners of slides, at 30-40% opacity.
**Feature-deco notch** — 48×48 yellow square with 3px black border, positioned absolutely to protrude from the top edge of a feature card. The notch breaks the card's top border, suggesting it's been "stapled on".
**Icon-square** — 64×64 pastel square with 3px black border holding a single uppercase letter glyph at Inter weight 700 / 28px. Used as feature-card icons.
**Stat-deco dot** — 12×12 circle with 2px black border, pastel fill, pinned to the top-right of a stat card. The system's only round shape.
**List-number** — 36×36 yellow square with 3px black border holding a Space Grotesk 14px weight 700 numeral. Used as bullets on numbered lists.
**Avatar-square** — 72×72 pastel square with 3px black border holding two uppercase initials at Inter weight 900 / 28px. Used in team grids; fills cycle through pastels.
**Step-connector** — A 28×4 horizontal black bar pinned to the right edge of a timeline-step card, mid-height. Visually links adjacent steps in a horizontal flow.
**Tilted decoration** — Any rectangle, badge, or star with a rotate(±2deg to ±12deg) transform. The tilt is intentional disruption of the grid; without it, the system reads as too uniform.
## Do's and Don'ts
### Do
- Apply 4px solid black borders to primary cards (`{components.card-elevated}`, hero-frame, quote-frame) and 3px to secondary chrome. The border weight ladder is the system's structural backbone.
- Pair every 4px border with an 8px offset shadow, and every 3px border with a 4px offset shadow. The border/shadow coupling is non-negotiable.
- Cycle slide backgrounds through the pastel palette — offwhite, cream, blue, pink, green, yellow — to keep the deck visually rhythmic. Staying on one color for many slides flattens the system.
- Set every Inter display element in uppercase with negative letter-spacing (-0.01 to -0.03em) and weight 800+. The combination is the typographic identity.
- Use the `{components.label-pill}` (3px border, 4px shadow, pastel fill, Space Grotesk uppercase 0.08em) as the universal section eyebrow on every region.
- Apply tilt to decorative rectangles, stat cards, stars, and badges (±2deg to ±12deg). The intentional misalignment is the system's playful signature.
- Use `{colors.yellow}` as the default button color. Yellow with a 3px black border and 4px black shadow is the system's "click here" voice.
- Render shadows as solid black with zero blur, always offset bottom-right. The hard-edge shadow is the depth language.
- Add a decorative element (star-burst, stripe-block, dot-grid, corner-bracket, tilted rectangle) to every surface. The visual chatter is part of the system's energy.
- Use pure black `{colors.black}` for the closing surface, with white text and a 12px yellow offset shadow on the close-frame. The inverted dark surface is the system's loudest contrast moment.
### Don't
- Don't round any corner on cards, buttons, label-pills, icon-squares, or avatars. Border-radius is forbidden except on the stat-deco dot (12px circle).
- Don't blur any shadow. Every shadow is hard-edged at zero blur. `box-shadow: 0 4px 12px rgba(0,0,0,0.1)` does not exist in this system.
- Don't use colored borders. Borders are always pure black, except for the inverted 4px white border on the close-frame.
- Don't use Inter display weights in sentence case. Uppercase is mandatory on heading-xl, heading-lg, quote-text, close-title, and card-title.
- Don't set Inter display without negative letter-spacing. Default-tracked Inter at heavy weights reads as a different system.
- Don't introduce a sixth pastel color. The palette is locked at pink, blue, green, yellow, cream. Adding purple, orange, or red breaks the curated candy palette.
- Don't omit the label-pill on a region. Going straight from background to headline without an eyebrow tag breaks the system's editorial rhythm.
- Don't render label-pills as plain text. The 3px border + 4px shadow + pastel fill combination is what defines the pill.
- Don't use blurred or colored body text. Body is solid black on light surfaces, solid white or cream on dark surfaces.
- Don't keep every card perfectly aligned. The tilt on stat cards, decorations, and badges is what gives the system its hand-made energy.
## Responsive Behavior
BlockFrame is designed as a **1920×1080 presentation system** (effective 100vw × 100vh). Sizing uses CSS `clamp()` for type and fixed px for borders, shadows, and structural padding. The system has three component-level breakpoints for narrow viewports.
### Scaling Behavior
- Heading-xl scales 48px → 96px on viewport width.
- Heading-lg scales 32px → 64px.
- Body scales 16px → 20px.
- Borders (3px, 4px), shadows (4px, 8px), and structural padding (60px slide-pad) are fixed and do not scale.
### Component Breakpoints
- `max-width: 1024px` — slide padding shrinks 60px → 40px, two-column splits stack vertically, feature card row stacks vertically, timeline track stacks vertically with step-connectors hidden, stats grid collapses to 2 columns, team grid collapses to 2 columns. Split visual loses left border and gains a top border.
- `max-width: 640px` — stats grid collapses to 1 column, team grid collapses to 1 column, hero-frame padding shrinks to 32px, quote-frame padding shrinks to 32px.
### Presenter Behavior
- Slides advance via `ArrowRight` or `Space`.
- Slides reverse via `ArrowLeft`.
- Horizontal touch swipe with a 50px threshold advances/reverses.
- Slide transitions are instant (`display: none` ↔ `display: flex` on the `.active` class), with no crossfade.
### Print Behavior
The system has no `@media print` rule. Slides are absolute-positioned and only one is visible at a time — printing produces only the active slide. For static export, screenshots of each slide preserve all borders, shadows, and decorations (all are CSS, not image assets).
### Interactive States
- Buttons and nav-buttons translate -2/-2 on hover and shadow grows to 6px (`{shadows.hover}`); on active, translate 2/2 and shadow shrinks to 2px. The hover-press behavior is unusual for a presentation system; it reflects BlockFrame's hybrid identity as both deck and interactive product mockup.
## CJK & International Content
When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.
### Recommended Chinese Pairing
| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| Display / hero / quote / close title / stat numerals | Inter 800–900 (uppercase, negative tracking) | 思源黑体 Noto Sans SC 900 (sentence case, 0 tracking) |
| Card title | Inter 700 (uppercase) | 思源黑体 Noto Sans SC 700 (no transform) |
| Body / list body | Inter 500 | 思源黑体 Noto Sans SC 400 |
| Label / mono tag / counter / legend | Space Grotesk 600–700 (uppercase, 0.05–0.1em tracking) | 思源黑体 Noto Sans SC 600 (no transform, no tracking) |
### Mixed-Content Strategy
**Strategy A** — single CJK family with built-in Latin glyph coverage. Set every text element to `font-family: 'Noto Sans SC', sans-serif`. 思源黑体 ships Latin glyphs that pair cleanly with its Chinese characters, so mixed sentences render in one consistent face. The Inter / Space Grotesk distinction in the Latin original is preserved through weight contrast: weight 900 carries the brutalist display role, weight 600 carries the label role, weight 400–500 carries body. Visual hierarchy survives even though the face contrast is gone.
### Loading
Add to the template's `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600;700;900&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (up from 1.6), display 1.15–1.25 (up from 0.95–1). The Latin display compresses to 0.95 line-height; CJK at that compression collides vertically.
- **Letter-spacing**: set to 0 on every CJK run. The template's negative display tracking (−0.02 to −0.03em on Inter) overlaps CJK strokes and reads as broken; the positive 0.05–0.1em tracking on Space Grotesk labels reads as gappy on square glyphs.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. Every Inter display heading (heading-xl, heading-lg, quote-text, close-title, card-title) uses `text-transform: uppercase` in the Latin original; remove it for CJK runs. Every label-pill, counter, and chrome element also uses uppercase; remove that too.
- **Punctuation**: use full-width Chinese punctuation (,。:;!?「」()).
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `BlockFrame 设计系统` not `BlockFrame设计系统`.
- **One font per sentence**: 思源黑体 covers both CJK and Latin glyphs in a unified style — let it handle mixed sentences. Don't let the browser font-switch to Inter or Space Grotesk mid-word.
### Aesthetic Notes for This System
The Latin original's typographic identity rests entirely on the **heavy uppercase + negative tracking** combination on Inter display. CJK has no case, so this signal disappears. The system survives because its identity is **80% structural, 20% typographic**: the 4px black borders, 8px hard offset shadows, five-pastel palette, tilted decorations, label-pills, star bursts, stripe blocks, and dot grids do the brutalist work. Set 思源黑体 900 in sentence case at the same large sizes; the chunky black-on-pastel + hard-shadow framing reads as brutalist regardless of whether the type is in caps.
The label-pill (Space Grotesk 600 uppercase, 0.08em tracking, 3px border + 4px shadow, pastel fill) loses the uppercase + tracked-mono character. Render Chinese label-pills with 思源黑体 weight 600 at 0 tracking and a slightly tighter fontSize (11–12px instead of 13px) — the bordered pill shape and shadow do the chrome-recognition work. Keep the pastel fill rotation (pink / blue / green / yellow / cream) intact; it's the system's most recognizable signal after the borders themselves.
### Known CJK Gap
- **No CDN Chinese monospace face for the "system readout" voice.** Space Grotesk's quasi-mono role (label-pills, counters, mono-tags, slide counter NN / NN) depends on its slightly geometric character plus the wide-tracked uppercase treatment. Neither survives the CJK translation. The slide counter and chart legend can keep Latin digits + Latin labels intact; for purely Chinese chrome, lean on the pill border + shadow + pastel fill to signal "label" rather than the typographic treatment.
- **The "uppercase brutalist" identity weakens.** The system's most distinctive typographic decision is "heavy uppercase Inter with negative tracking" — and that signal is irreplaceable in CJK. Compensate by leaning harder on the structural elements: more decorative disruption (extra tilted rectangles, star bursts, stripe blocks), more saturated pastel-ground rotation across slides, and slightly tighter shadow offsets to compensate for the calmer typographic baseline.
## Iteration Guide
1. Any new card uses a 4px or 3px solid black border + the matched-weight offset shadow (8px or 4px). Never use a card without both.
2. Any new region begins with a `{components.label-pill}` eyebrow in pastel fill, then the headline in uppercase Inter weight 800+, then content. The label-headline-content sequence is the system's editorial rhythm.
3. Any new headline uses uppercase Inter with negative letter-spacing and weight 800-900. Reach for `{typography.heading-lg}` (32-64px) for primary moments and `{typography.heading-xl}` (48-96px) for cover/hero scale.
4. Any new accent or surface fill picks from the 5-pastel palette (pink, blue, green, yellow, cream) — never introduce a sixth pastel.
5. Any new CTA uses the `{components.button-primary}` pattern: 3px black border, yellow fill, 4px black shadow, Inter weight 700 / 16px. Hover lifts -2/-2 with shadow growing to 6px.
6. Any new chart cycles through pink → blue → green for series order, with yellow/cream available for additional series. Legend swatches use 2px black border.
7. Any new stat or metric uses Inter weight 900 + line-height 1 for the numeral, paired with Space Grotesk uppercase label below. Decorate the card with a `{components.stat-deco-dot}` in a pastel color.
8. Any new slide adds at least one decorative disruption (tilted rectangle, star-burst, stripe-block, dot-grid corner, corner-bracket frame) — empty surfaces feel timid.
9. Any new closing-style surface uses pure `{colors.black}` ground with white text, a 4px white-bordered close-frame, and a 12px yellow offset shadow. This is the only colored shadow allowed.
10. If a surface feels too noisy, drop a decoration — don't drop a border or shadow. The borders and shadows are structural; the decorations are tunable.
## Known Gaps
- **Inter and Space Grotesk are loaded from Google Fonts** via inline `@import`. There are no system fallbacks beyond `sans-serif` and `monospace` — in environments where Google Fonts fail, the system collapses to system defaults and loses its identity.
- **The system uses `@import` inside the `<style>` block** rather than a `<link>` preconnect. This is slower than the standard `<link>` approach and may delay first paint of typography.
- **The chart is rendered as inline SVG with hardcoded coordinates** (`viewBox="0 0 800 360"`, hardcoded `x/y/width/height` per `<rect>`). Adding new chart slides requires manual coordinate math; there is no data-binding layer.
- **The hover/active state on buttons assumes a pointing device.** On touch devices the lift-and-press feedback only triggers on tap and may feel inconsistent.
- **The tilt on stat cards is hardcoded with `:nth-child(odd)` -2deg and `:nth-child(even)` +2deg.** Re-ordering cards changes which tilts which direction — there's no per-card tilt control beyond ordering.
- **The decorative star uses a CSS clip-path polygon with 10 points.** Browsers without clip-path support (very old IE/Edge) will render the star as a colored rectangle.
- **The slide-counter and nav-controls overlap the slide content area at the bottom edge.** The 110px bottom padding on certain slides (slide-4, slide-9) reserves space, but other slides may have content that crowds the bottom-left counter pill.
- **The black close-surface uses pure `#000000` ground with white text** — accessibility-wise this is high-contrast and fine, but the colored decorations on this surface (yellow shadow, white border) don't pass the WCAG color contrast checks at small sizes.
- **The dot-grid background is a CSS radial-gradient.** At very large viewport sizes the dots may look too small to read as a grid; at very small sizes they may visually merge into solid noise.
- **There is no transition between slides** other than the binary display toggle. Adding a fade or slide animation requires modifying the JS and adding transition CSS.
# BlockFrame Preview Card Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below. ## Files - Full design doc: `bold-template-pack/templates/block-frame/design.md` - Preview card: `bold-template-pack/templates/block-frame/preview.md` ## Selection Metadata - Slug: `block-frame` - Tagline: Neobrutalist deck with pastel-neon color blocks and chunky black borders. - Mood: bold, playful, graphic, fresh - Tone: confident, graphic, pop, design-led - Formality: medium-low - Density: high - Scheme: light - Best for: Anything that should feel pop-graphic and design-led: indie SaaS launches, agency credentials, creative reviews, brand redesigns. Also a strong unexpected pick for tech, finance, or research when the speaker wants to land as confident and contemporary rather than buttoned-up. - Avoid for: Contexts that require quiet institutional restraint or traditional weight (regulated disclosures, formal legal briefs). ## Visual Snapshot A maximalist neobrutalist presentation system built on 4px solid black borders, 8px hard offset shadows, and a high-key candy palette of five saturated pastels plus cream and off-white. Display type runs Inter at weight 800-900 in tight uppercase; secondary chrome uses Space Grotesk as a quasi-monospace label face. Tilted decorative shapes (rotated stars, rectangles, badges) puncture the borders and break the grid intentionally. Pastels are paired loudly: pink + blue + green + yellow + cream cycle through every region with deliberate juxtaposition. The aesthetic borrows from zine layout, 1990s-revival sticker books, and contemporary toy packaging — bold, joyful, slightly chaotic, never timid. BlockFrame is a maximalist neobrutalist presentation system built on five structural laws: every region has a 4px black border, every elevated element has an 8px hard offset shadow, every corner is square, every accent color is a saturated pastel, and every layout is allowed to be a little bit crooked. The system's joy comes from the deliberate collision of these laws — bordered cards meet bordered cards, shadows stack against shadows, tilted decorations puncture the grid intentionally. ## Preview Ingredients - Palette: black #000000; white #FFFFFF; offwhite #FFFDF5; pink #FE90E8; blue #C0F7FE; green #99E885; yellow #F7CB46; cream #FFDC8B - Typography: See full design doc after selection. - Signature move: 4px solid black borders on primary cards, 3px on secondary chrome — never thinner. - Signature move: 8px hard offset shadows on primary cards, 4px on secondary chrome — solid black, zero blur. - Signature move: Five-pastel palette (pink, blue, green, yellow, cream) plus black, white, off-white — cycled across surfaces. - Signature move: Inter weight 800-900 uppercase with negative tracking is the display voice; Space Grotesk weight 600 uppercase with 0.08em tracking is the label voice. - Signature move: Square corners everywhere except a single circular accent dot on stat cards. ## International / CJK Preview Note - If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs. - Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments. ## Preview Rules - Build exactly one title slide at 1920x1080 inside the fixed-stage model. - Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above. - Use the user's real title/subtitle/context; do not copy demo slide content. - The rendered preview must look like a real first slide, not a template-selection card. - Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels. - Never place the template name or slug on the slide itself; mention it only in the chat message. - Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck. - Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material. - Do not read `template.html` for preview generation. - Do not read other templates' `design.md` files. - After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Blue Professional
description: A restrained, consulting-grade presentation system on a warm cream canvas (#fdfae7) with a single saturated cobalt blue (#1e2bfa) as the only accent color. Display type runs Space Grotesk for headlines and numerical callouts; Inter handles body and chrome. Cards are soft-tinted cobalt at 4% opacity with 1.5px translucent borders and 10-14px rounded corners — quiet, never bordered in solid color. The aesthetic borrows from investment-research reports, McKinsey-grade quarterly briefings, and contemporary financial dashboards — measured, data-dense without feeling crowded, and unmistakably professional. The system is built for executive readability at distance, with strong typographic hierarchy and a single accent color carrying every emphasis moment.
colors:
bg: "#fdfae7"
primary: "#1e2bfa"
text: "#111111"
text-muted: "#6b6b6b"
text-light: "#9a9a9a"
accent-light: "rgba(30, 43, 250, 0.08)"
accent-medium: "rgba(30, 43, 250, 0.15)"
border: "rgba(30, 43, 250, 0.2)"
card-bg: "rgba(30, 43, 250, 0.04)"
positive: "#059669"
negative: "#dc2626"
typography:
h1:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 700
fontSize: "clamp(44.8px, 5vw, 67.2px)"
lineHeight: 1.1
letterSpacing: -0.02em
h2:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: "clamp(28.8px, 3vw, 41.6px)"
lineHeight: 1.1
letterSpacing: -0.02em
h3:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: "clamp(17.6px, 1.8vw, 24px)"
lineHeight: 1.3
letterSpacing: -0.02em
h4-eyebrow:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: "clamp(13.6px, 1.2vw, 16px)"
lineHeight: 1.1
letterSpacing: 0.08em
textTransform: uppercase
color: "{colors.primary}"
body:
fontFamily: "'Inter', sans-serif"
fontWeight: 400
fontSize: "clamp(13.6px, 1.1vw, 16.8px)"
lineHeight: 1.6
color: "{colors.text-muted}"
metric-value:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 700
fontSize: "clamp(35.2px, 3.4vw, 48px)"
lineHeight: 1
color: "{colors.primary}"
metric-label:
fontFamily: "'Inter', sans-serif"
fontWeight: 600
fontSize: "clamp(15.2px, 1.3vw, 17.6px)"
lineHeight: 1.3
color: "{colors.text}"
metric-desc:
fontFamily: "'Inter', sans-serif"
fontWeight: 400
fontSize: "clamp(12.5px, 0.95vw, 14.4px)"
lineHeight: 1.5
color: "{colors.text-muted}"
metric-support:
fontFamily: "'Inter', sans-serif"
fontWeight: 400
fontSize: "clamp(12px, 0.9vw, 13.6px)"
lineHeight: 1.45
color: "{colors.text-muted}"
stat-num:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 700
fontSize: "clamp(25.6px, 2.4vw, 33.6px)"
lineHeight: 1
color: "{colors.primary}"
stat-name:
fontFamily: "'Inter', sans-serif"
fontWeight: 500
fontSize: "clamp(13.6px, 1vw, 15.2px)"
lineHeight: 1.35
color: "{colors.text}"
stat-context:
fontFamily: "'Inter', sans-serif"
fontWeight: 400
fontSize: 12px
lineHeight: 1.4
color: "{colors.text-light}"
agenda-num:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 700
fontSize: 28.8px
lineHeight: 1
color: "{colors.primary}"
insight-num:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 12.5px
lineHeight: 1.7
letterSpacing: 0.05em
color: "{colors.primary}"
split-highlight:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: "clamp(18.4px, 1.55vw, 24px)"
lineHeight: 1.4
color: "{colors.text}"
blockquote:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: "clamp(25.6px, 2.8vw, 38.4px)"
lineHeight: 1.35
color: "{colors.text}"
quote-mark:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 700
fontSize: "128px"
lineHeight: 0.5
color: "{colors.primary}"
opacity: 0.15
step-circle-text:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 700
fontSize: 20.8px
lineHeight: 1
step-title:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: "clamp(15.2px, 1.4vw, 18.4px)"
lineHeight: 1.2
bar-label:
fontFamily: "'Inter', sans-serif"
fontWeight: 500
fontSize: "clamp(12.8px, 1.1vw, 16px)"
lineHeight: 1.3
color: "{colors.text}"
bar-pct:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 15.2px
color: "{colors.primary}"
tag:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: 12px
lineHeight: 1
color: "{colors.primary}"
counter:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: 12.8px
lineHeight: 1
letterSpacing: 0.05em
color: "{colors.text-muted}"
meta:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 400
fontSize: 12.8px
lineHeight: 1.4
letterSpacing: 0.05em
color: "{colors.text-light}"
cite:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: 12.5px
lineHeight: 1.4
letterSpacing: 0.04em
textTransform: uppercase
color: "{colors.text-muted}"
spacing:
pad-slide-x: "4vw"
pad-slide-y-top: "3.5vw"
pad-slide-y-bottom: "8.5vh"
pad-card-lg: "1.5rem 1.6rem"
pad-card-md: "1.4rem 1.5rem"
pad-card-sm: "1rem 1.2rem"
pad-mini: "0.9rem 1rem"
gap-grid-lg: "3.5rem"
gap-grid-md: "2rem 3rem"
gap-grid-sm: "1.5rem"
gap-cards: "1.2rem"
gap-mini: "1rem"
header-margin: "2.5vh"
accent-line-width: "60px"
accent-line-height: "4px"
canvas:
width: 100vw
height: 100vh
background: "{colors.bg}"
radii:
pill: "100px"
card-lg: "14px"
card-md: "12px"
card-sm: "10px"
bar: "6px"
circle: "50%"
components:
card-tinted:
background: "{colors.card-bg}"
border: "1.5px solid {colors.border}"
borderRadius: 14px
padding: "1.5rem 1.6rem"
description: "Primary content card. Cobalt tinted at 4% with a 20% cobalt 1.5px border. Soft 14px radius. Never solid-colored, never outlined in full primary."
card-tinted-sm:
background: "{colors.card-bg}"
border: "1px solid {colors.border}"
borderRadius: 12px
padding: "1.4rem 1.5rem"
description: "Compact tinted card with 1px border. Used for stat cells and small data blocks."
card-tinted-xs:
background: "{colors.card-bg}"
border: "1px solid {colors.border}"
borderRadius: 10px
padding: "0.9rem 1rem"
description: "Mini tinted card used for inline mini-stats."
detail-block:
background: "{colors.card-bg}"
border: "1px solid {colors.border}"
borderRadius: 10px
padding: "1rem 1.2rem"
description: "Detail block holding a small h3 + a bulleted ul. Used in detail-analysis grids."
tag-pill:
background: "{colors.accent-light}"
color: "{colors.primary}"
padding: "0.35rem 0.9rem"
borderRadius: 100px
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 500
fontSize: 12px
description: "Pill-shaped tag sitting in the top-right of the slide-header. Fully rounded, soft cobalt tint background, cobalt text."
cta-button:
background: "{colors.primary}"
color: "{colors.bg}"
padding: "0.9rem 2.2rem"
borderRadius: 100px
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 15.2px
description: "Primary CTA. Fully rounded solid cobalt pill with cream text. Hover lifts -2 with a soft cobalt drop shadow."
nav-btn:
width: 44px
height: 44px
borderRadius: 50%
border: "1.5px solid {colors.border}"
background: "{colors.bg}"
color: "{colors.primary}"
description: "Circular nav-arrow button. Hover inverts: cobalt fill, cream icon. Disabled state at 30% opacity."
accent-line:
width: 60px
height: 4px
background: "{colors.primary}"
borderRadius: 2px
description: "Short horizontal cobalt rule, 60×4px, slightly rounded. Used above cover titles and as eyebrow separators."
accent-dot:
width: 8px
height: 8px
background: "{colors.primary}"
borderRadius: 50%
description: "Small inline cobalt dot. Decorative inline marker."
bar-track:
height: 28px
background: "{colors.accent-light}"
borderRadius: 6px
description: "Horizontal bar chart track. Soft cobalt tint with 6px rounded corners."
bar-fill:
height: "100%"
background: "{colors.primary}"
borderRadius: 6px
description: "Solid cobalt fill inside bar-track. Width carries the data value. Animates from 0 to value on slide entry."
step-circle:
width: 56px
height: 56px
borderRadius: 50%
background: "{colors.primary}"
color: "{colors.bg}"
description: "Circular numbered step marker in cobalt with cream numeral. Sequential steps reduce opacity (1.0 → 0.85 → 0.7 → 0.55) to suggest fade-into-future."
metric-change-positive:
color: "{colors.positive}"
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 12.5px
description: "Inline positive-change chip with up-arrow glyph and percentage. Green text inline; no border or fill."
metric-change-negative:
color: "{colors.negative}"
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 12.5px
description: "Inline negative-change chip with up/down-arrow glyph and percentage. Red text inline; no border or fill."
insight-list-item:
paddingLeft: "2.6rem"
description: "Numbered insight list with a Space Grotesk 600 counter (decimal-leading-zero) at position absolute left. Numbers in cobalt, body in default text color."
split-highlight-block:
background: "{colors.accent-light}"
borderLeft: "4px solid {colors.primary}"
borderRadius: 12px
padding: "1.3rem 1.5rem"
description: "Highlighted callout block with cobalt left rule and tinted cobalt fill. Used for inline pull-quotes inside split-column layouts."
progress-bar:
position: "fixed bottom 0 left 0"
height: 3px
background: "{colors.primary}"
description: "Thin cobalt progress bar at the bottom edge of the viewport, width grows linearly with slide index."
cover-decoration:
background: "{colors.accent-light}"
clipPath: "polygon(30% 0, 100% 0, 100% 100%, 0% 100%)"
description: "Diagonal accent panel filling the right ~35% of cover surfaces. Soft cobalt tint, clip-path angled cut on the left edge."
cover-dots:
layout: "3x3 grid of 6px cobalt dots at 12px gap, 25% opacity"
description: "Small dotted decoration used on cover and other open-space surfaces."
closing-circles:
border: "1px solid {colors.border}"
borderRadius: "50%"
description: "Two concentric centered circles (500px outer, 360px inner) as atmospheric decoration on closing-class surfaces. Opacity 0.3-0.4."
---
## 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
Blue Professional is a **consulting-grade presentation system** designed for executive briefings, research deliverables, and quarterly reviews. Its foundational visual premise is **restraint with one strong commitment**: a warm cream canvas (`{colors.bg}` — `#fdfae7`) and a single saturated cobalt (`{colors.primary}` — `#1e2bfa`) that carries every accent, every metric, every CTA, every eyebrow, every chart fill. There is no secondary brand color, no palette of pastels, no warm/cool pairing — just cream, cobalt, and a tight ladder of muted grays for body text.
The type system uses two open Google Fonts in tightly defined roles. **Space Grotesk** (weights 300-700) is the display, headline, numerical, and chrome face — used for h1-h3 headings, all metric/stat numerals, eyebrow labels (in uppercase with 0.08em tracking), tag pills, CTAs, slide counters, agenda numbers, and step circles. Its slightly geometric character + soft humanist warmth makes it read as both modern (suitable for AI/tech audiences) and trustworthy (suitable for finance audiences). **Inter** (weights 300-600) is the body face — used for paragraph text, list bodies, metric descriptions, and table-style content. The Space Grotesk / Inter pairing is deliberately ordinary; what makes the system feel distinctive is the discipline of their usage, not the novelty of the faces.
The color philosophy is **one accent, three text grays**. Cobalt does all the emphasis work: headlines stay in `{colors.text}` (a near-black `#111111`), but every metric value, every eyebrow, every CTA, every chart bar, every callout border, every step circle, every progress indicator is cobalt. Body text uses a three-step gray ladder — `{colors.text}` for primary body, `{colors.text-muted}` (`#6b6b6b`) for paragraph body and metric descriptions, `{colors.text-light}` (`#9a9a9a`) for tertiary metadata. Only two non-cobalt accent colors exist: `{colors.positive}` (a subdued green `#059669`) and `{colors.negative}` (a subdued red `#dc2626`), used only on directional change indicators (arrows and percentages on metric cards) — and these are inline text colors, not fills.
Depth is **soft and tinted**, never offset or shadowed. Cards are 4% cobalt tints (`{colors.card-bg}`) with 1.5px translucent cobalt borders (`{colors.border}` — cobalt at 20% opacity) and 10-14px rounded corners. There are no drop shadows except a single subtle cobalt-tinted shadow on the CTA hover state (`0 8px 24px rgba(30, 43, 250, 0.25)`). The lack of harsh shadows is what gives the system its quiet, premium feel — every elevation is implied by border + tint, not by shadow.
**Density philosophy: balanced and data-dense without crowding.** This system is built to carry information — six-stat dashboards, six-detail-block grids, seven-bar rankings, multi-column splits with callouts and mini-stats. The system reads as authoritative when populated with substantive content and timid when sparse. A typical surface holds: a slide-header (h4 eyebrow + tag pill) + a section h2 headline + a grid or list of 3-6 information cells. Cards have moderate internal padding (1.5rem) and moderate inter-card gap (1.2-1.5rem) — neither tight nor airy. The system can support both quote/cover-class surfaces (one bold statement in space) and dashboard-class surfaces (six cards of dense data) without feeling like two different systems.
**Key Characteristics:**
- Warm cream ground (`{colors.bg}`) on every surface — never pure white, never gray.
- Single saturated cobalt (`{colors.primary}`) as the only accent — used for every eyebrow, metric, CTA, chart fill, and progress indicator.
- Space Grotesk (display + chrome) + Inter (body) — never substitute either.
- Cards are 4% cobalt tints with 1.5px cobalt-at-20% borders and 10-14px rounded corners.
- Soft pill-shaped chrome (`{components.tag-pill}`, `{components.cta-button}`) with full `100px` border-radius.
- Headlines use Space Grotesk weight 600-700 with -0.02em tracking on a near-black text color.
- Body uses Inter weight 400 at 13.6-16.8px with 1.6 line-height in the muted gray.
- Every slide carries a slide-header (eyebrow + tag pill), a single h2, and a flexible content region — the structure is rhythmic across the deck.
- Persistent chrome: cobalt progress bar at bottom edge, slide-counter at bottom-left, circular nav-arrows at bottom-right.
- Decorative atmospheric elements (concentric circles, dot grids, diagonal accent panels) appear only on cover and closing-class surfaces.
## Colors
### Palette
- **Bg** (`{colors.bg}` — `#fdfae7`): The warm cream canvas. The default and universal surface. Slightly green-cream-leaning warmth that distinguishes the system from corporate-template white. Every slide rests on this ground.
- **Primary** (`{colors.primary}` — `#1e2bfa`): The signature cobalt. A highly saturated electric blue that carries every emphasis moment. Used for h4 eyebrows, metric values, stat numerals, chart bar fills, CTA fills, step circles, progress bars, accent lines, agenda numbers, and the cite border on highlight blocks. No other accent color exists.
- **Text** (`{colors.text}` — `#111111`): The primary text color. Near-black, slightly warmer than `#000000`. Used for h1-h3 headlines, primary content text, metric labels, and any text that should carry full weight.
- **Text-muted** (`{colors.text-muted}` — `#6b6b6b`): Secondary text — body paragraphs, metric descriptions, captions. Reads as comfortably softer than the primary text without disappearing.
- **Text-light** (`{colors.text-light}` — `#9a9a9a`): Tertiary text — slide meta info, hairline dividers in text, stat context lines. The lightest readable gray; below this, text becomes ambient noise.
- **Accent-light** (`{colors.accent-light}` — `rgba(30, 43, 250, 0.08)`): The default cobalt tint for tag pills, bar tracks, highlight callouts, and cover-decoration panels.
- **Accent-medium** (`{colors.accent-medium}` — `rgba(30, 43, 250, 0.15)`): A slightly darker cobalt tint, available but used sparingly.
- **Border** (`{colors.border}` — `rgba(30, 43, 250, 0.2)`): Cobalt at 20% opacity. The universal soft border color for cards, nav buttons, decorative circles, and structural rules.
- **Card-bg** (`{colors.card-bg}` — `rgba(30, 43, 250, 0.04)`): Cobalt at 4% opacity. The universal card fill — softer than accent-light, reading as a barely-tinted surface that lifts slightly off the cream ground.
- **Positive** (`{colors.positive}` — `#059669`): Subdued green. Used only inline as the text color for positive-change indicators (up-arrow + percentage). Never used as a fill or border.
- **Negative** (`{colors.negative}` — `#dc2626`): Subdued red. Used only inline as the text color for negative-change indicators. Never used as a fill or border.
### Defaults
- **Default surface background**: `{colors.bg}` — every surface starts on cream.
- **Default headline color**: `{colors.text}` (`#111111`) — headlines are near-black, never cobalt. Cobalt is reserved for accent moments (eyebrows, metrics, CTAs).
- **Default body text color**: `{colors.text-muted}` (`#6b6b6b`) — body paragraphs default to muted, not full black.
- **Default eyebrow / h4 color**: `{colors.primary}` — eyebrows are always cobalt, always uppercase, always with 0.08em tracking.
- **Default card fill**: `{colors.card-bg}` (cobalt at 4%) — the universal soft tint.
- **Default card border**: `{colors.border}` (cobalt at 20%) at 1px or 1.5px. Never solid full-cobalt borders.
- **Default card border-radius**: 10-14px depending on card size (`{radii.card-sm}` for stat cells, `{radii.card-md}` for stat cards and detail blocks, `{radii.card-lg}` for metric cards).
- **Default accent for any numerical value (metric, stat, agenda number, bar percentage)**: `{colors.primary}`.
- **Default chart bar color**: `{colors.primary}` solid fill on a `{colors.accent-light}` track.
- **Default CTA**: `{components.cta-button}` — solid cobalt pill with cream text and 100px border-radius.
- **Default tag pill**: `{components.tag-pill}` — soft cobalt tint with cobalt text and 100px border-radius, paired with an h4 eyebrow in the slide-header.
The system has **no secondary accent color**. Don't reach for orange, teal, or purple to differentiate categories — the single-cobalt discipline is the system's identity. Categorical differentiation should be done through positioning, sizing, or labeling, not through additional hues.
## Typography
### Font Family Stack
The system runs two faces, each with a single role.
**Space Grotesk** (Google Fonts, weights 300-700) is the display + numerical + chrome face. Used for every h1, h2, h3, h4 heading; every numerical callout (metric values, stat numbers, agenda numbers, bar percentages, step circles); every chrome element (tag pills, CTAs, slide counters, hint text); and every uppercase eyebrow with 0.08em tracking. Its slightly geometric character + softly rounded humanist forms read as both contemporary and trustworthy — suitable for both AI/tech and finance audiences.
**Inter** (Google Fonts, weights 300-600) is the body face. Used for paragraph text, list bodies, metric descriptions, agenda descriptions, detail-block body, and any longer-form content. Set at weight 400 with line-height 1.6 in the muted gray, Inter reads as comfortable, generous, and editorial.
The face roles are non-overlapping: Space Grotesk handles every numeral and every heading; Inter handles every paragraph and list body. Don't cross the boundary — Inter h1 reads as a different brand; Space Grotesk body reads as a tech startup landing page.
### Typography Scale
| Token | Size (clamp / px) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.h1}` | 44.8–67.2px clamp | Space Grotesk | 700 | Cover or closing title |
| `{typography.h2}` | 28.8–41.6px clamp | Space Grotesk | 600 | Primary section headline on each slide |
| `{typography.h3}` | 17.6–24px clamp | Space Grotesk | 500 | Agenda item / region title |
| `{typography.h4-eyebrow}` | 13.6–16px clamp | Space Grotesk | 600 | Uppercase eyebrow in the slide-header (always cobalt) |
| `{typography.body}` | 13.6–16.8px clamp | Inter | 400 | Standard body paragraph |
| `{typography.metric-value}` | 35.2–48px clamp | Space Grotesk | 700 | Large metric numeral in a callout card |
| `{typography.metric-label}` | 15.2–17.6px clamp | Inter | 600 | Metric label line under the numeral |
| `{typography.metric-desc}` | 12.5–14.4px clamp | Inter | 400 | Metric supporting description paragraph |
| `{typography.metric-support}` | 12–13.6px clamp | Inter | 400 | Metric supporting bullet list |
| `{typography.stat-num}` | 25.6–33.6px clamp | Space Grotesk | 700 | Stat-cell numeral (smaller than metric-value) |
| `{typography.stat-name}` | 13.6–15.2px clamp | Inter | 500 | Stat-cell descriptive name line |
| `{typography.stat-context}` | 12px | Inter | 400 | Stat-cell tertiary context line below a hairline divider |
| `{typography.agenda-num}` | 28.8px | Space Grotesk | 700 | Agenda item numeral |
| `{typography.insight-num}` | 12.5px | Space Grotesk | 600 | Counter-style number prefix on insight list items |
| `{typography.split-highlight}` | 18.4–24px clamp | Space Grotesk | 500 | Inline pull-quote text inside a split-highlight block |
| `{typography.blockquote}` | 25.6–38.4px clamp | Space Grotesk | 500 | Quote-class headline body |
| `{typography.quote-mark}` | 128px | Space Grotesk | 700 | Decorative oversized quote glyph at 15% opacity above a blockquote |
| `{typography.step-circle-text}` | 20.8px | Space Grotesk | 700 | Numeral inside a circular step marker |
| `{typography.step-title}` | 15.2–18.4px clamp | Space Grotesk | 600 | Step title beneath a step circle |
| `{typography.bar-label}` | 12.8–16px clamp | Inter | 500 | Bar chart row label |
| `{typography.bar-pct}` | 15.2px | Space Grotesk | 600 | Bar chart row percentage value |
| `{typography.tag}` | 12px | Space Grotesk | 500 | Tag pill text in slide-header |
| `{typography.counter}` | 12.8px | Space Grotesk | 500 | Persistent slide counter |
| `{typography.meta}` | 12.8px | Space Grotesk | 400 | Cover meta line (e.g., date / confidential marker) |
| `{typography.cite}` | 12.5px | Space Grotesk | 500 | Cite/attribution under a pull-quote, uppercase with 0.04em tracking |
### Defaults
- **Default size for a cover title**: `{typography.h1}` (44.8–67.2px). Always Space Grotesk weight 700 with -0.02em tracking.
- **Default size for the primary section headline on each slide**: `{typography.h2}` (28.8–41.6px). Space Grotesk weight 600. The "section h2" is the system's structural workhorse — every content slide has one.
- **Default size for a region or agenda-item title**: `{typography.h3}` (17.6–24px).
- **Default size for the eyebrow above the h2**: `{typography.h4-eyebrow}` (13.6–16px) in cobalt, uppercase, 0.08em tracking.
- **Default size for paragraph body**: `{typography.body}` (13.6–16.8px clamp). Inter weight 400 with line-height 1.6.
- **Default size for a large metric numeral**: `{typography.metric-value}` (35.2–48px). For dashboard stat cells, step down to `{typography.stat-num}` (25.6–33.6px).
- **Default size for a quote body**: `{typography.blockquote}` (25.6–38.4px). Always Space Grotesk weight 500.
- **Default weight for Space Grotesk headings**: 500 (h3) → 600 (h2 and eyebrow) → 700 (h1 and numerical callouts). Don't reach for weight 400 or 800; the weight ladder is fixed.
- **Default weight for Inter body**: 400. Inter body at 500-600 reads as too assertive; at 300 reads as too thin.
- **Default tracking for h1-h3 headings**: -0.02em. Without negative tracking, Space Grotesk display reads as untreated.
- **Default tracking for the h4 eyebrow**: 0.08em uppercase. Without the wide tracking + uppercase combination, the eyebrow doesn't read as an eyebrow.
When unsure which heading token to reach for, default to `{typography.h2}` (28.8–41.6px) for the slide's primary text moment. `{typography.h3}` is for region or agenda-item titles; `{typography.h1}` is reserved for cover and closing.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every h4 eyebrow is Space Grotesk weight 600 in `{colors.primary}` cobalt, uppercase, with 0.08em letter-spacing.** No exceptions. An eyebrow without uppercase + tracking + cobalt color is not the system's eyebrow — it's a stray sans element.
- **Every headline (h1, h2, h3) uses negative letter-spacing of -0.02em.** Default-tracked Space Grotesk display reads as untreated and breaks the editorial discipline.
- **Every headline uses `{colors.text}` (`#111111`), not cobalt.** Cobalt headlines are forbidden — cobalt is reserved for accent moments (eyebrows, metrics, CTAs, chart bars). Reversing this collapses the visual hierarchy.
- **Every numerical callout (metric value, stat number, agenda number, bar percentage, step circle) is Space Grotesk weight 600-700 in `{colors.primary}` cobalt.** Numerical values are the system's primary accent moment.
- **Every body paragraph is Inter weight 400 in `{colors.text-muted}` (`#6b6b6b`) with line-height 1.6.** Body in pure black reads as too heavy; body in text-light reads as too faint.
- **Every CTA is the `{components.cta-button}` pattern: solid cobalt pill with cream text, 100px border-radius, 0.9rem × 2.2rem padding.** CTAs in any other shape or color don't exist.
- **Every tag pill is the `{components.tag-pill}` pattern: soft cobalt tint with cobalt text, 100px border-radius, 0.35rem × 0.9rem padding.** Tag pills with solid backgrounds or borders break the system.
- **Every slide-header places the h4 eyebrow on the left and the tag pill on the right.** This is the structural rhythm of every content slide.
### Typography Principles
The voice contrast is **near-black display headlines ↔ cobalt eyebrows + numerals ↔ muted gray body**. Italic and underline are not used. The only emphasis mechanisms are: switching weight within the Space Grotesk ladder, switching color from text-muted to text or to cobalt, and uppercase + tracking on labels.
Numerical content is **always Space Grotesk**, even small numerical labels (bar percentages, slide counters, mini-stat values). The mono-flavored character of Space Grotesk at numerical sizes mimics tabular figures without requiring an actual monospace face.
## Layout
### Canvas System
The system targets `100vw × 100vh` per slide. Slides are absolutely positioned and animated in via opacity + translateX (40px → 0px) on 500ms ease. Only the `.active` slide is `opacity: 1`; the previous slide gets a `.prev` class and translates -40px out of view.
Default slide padding is asymmetric: `3.5vw` left, top, and right; `8.5vh` bottom. The extra bottom space reserves room for the fixed slide-counter (left) and nav-controls (right) which sit at `bottom: 2.5vh` overlapping the viewport bottom.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-slide-x}` | 4vw | Slide horizontal padding |
| `{spacing.pad-slide-y-top}` | 3.5vw | Slide top padding |
| `{spacing.pad-slide-y-bottom}` | 8.5vh | Slide bottom padding (extra to clear nav chrome) |
| `{spacing.pad-card-lg}` | 1.5rem 1.6rem | Large card internal padding (metric cards) |
| `{spacing.pad-card-md}` | 1.4rem 1.5rem | Medium card internal padding (stat cells) |
| `{spacing.pad-card-sm}` | 1rem 1.2rem | Small card internal padding (detail blocks) |
| `{spacing.pad-mini}` | 0.9rem 1rem | Mini card internal padding (mini-stat cells) |
| `{spacing.gap-grid-lg}` | 3.5rem | Large gap between split columns |
| `{spacing.gap-grid-md}` | 2rem 3rem | Medium gap in two-column grids (row × col) |
| `{spacing.gap-grid-sm}` | 1.5rem | Standard gap in 3-column metric grids |
| `{spacing.gap-cards}` | 1.2rem | Gap between dashboard stat cells |
| `{spacing.gap-mini}` | 1rem | Gap between mini-stats |
| `{spacing.header-margin}` | 2.5vh | Margin below the slide-header |
### Persistent Chrome
Three elements appear on every slide:
- **Slide counter** at bottom-left — Space Grotesk 12.8px weight 500 in text-muted gray, fixed at `bottom: 2.5vh; left: 3vw`.
- **Nav controls** at bottom-right — two circular 44px nav-buttons with 1.5px cobalt-at-20% borders, fixed at `bottom: 2.5vh; right: 3vw`. Disabled state at 30% opacity (first slide / last slide).
- **Progress bar** at bottom edge — 3px solid cobalt strip with width = `(currentSlide + 1) / total * 100%`. Animates on slide change.
A **keyboard hint** ("Use arrow keys to navigate") appears at bottom center in text-light gray.
### Slide-Header Structure
Every content slide carries a `.slide-header` band at the top: an h4 eyebrow on the left, a tag pill on the right. Below the slide-header sits the section h2, then the content region (a grid, list, chart, or split). Cover, quote, and closing slides skip the slide-header in favor of centered content.
### Content Grids
The system uses repeated grid patterns for content layout: 2×3 agenda grid, 3-column metric row, 3-column stats grid (becomes 2 rows on dashboards), 1.05fr/1fr split-body, 4-step timeline row, 2-column detail grid. These are content-density containers; the grid choice depends on content volume, not on a fixed layout vocabulary.
## Depth and Elevation
### Tinted Cards (Primary Depth Mechanism)
The system uses **soft cobalt-tinted backgrounds + soft cobalt-borders + rounded corners** to create the impression of elevation without using shadows. A card with `background: {colors.card-bg}` (cobalt at 4%) and `border: 1.5px solid {colors.border}` (cobalt at 20%) sits visually above the cream ground without any actual offset. This treatment is the system's depth language.
### No Drop Shadows on Cards
There are no `box-shadow` declarations on cards, stat cells, detail blocks, or any content container. The only shadow in the system is a single soft cobalt-tinted hover state on the CTA button: `0 8px 24px rgba(30, 43, 250, 0.25)`, which appears for 200ms on hover and disappears on mouse-out. This is the only colored, blurred shadow in the system.
### Border-Left Accent (Highlight Block)
The `{components.split-highlight-block}` uses a 4px solid cobalt left border to signal "this is a quoted callout, distinct from surrounding body". This is the system's structural accent mechanism — it's not a shadow, but it carries the same elevation cue (the colored rule pulls the block forward visually).
### Rounded Corners as Softness
The 10-14px border-radius on cards is part of the depth language. Without rounded corners, the cobalt-tinted cards would read as flat panels; the soft radius softens them into "lifted" surfaces.
### Atmospheric Decorations
Decorative elements (cover-decoration diagonal panel, concentric closing-circles, cover-dots grid, quote decoration circles) appear only on cover, quote, and closing-class surfaces. They are atmospheric, not structural — used to soften open-space surfaces without filling them with content.
## Shapes and Treatment
### Border Radius
- **`{radii.pill}` = 100px** — fully rounded. Used on `{components.tag-pill}`, `{components.cta-button}`, and any pill-shaped chrome.
- **`{radii.card-lg}` = 14px** — used on large metric cards.
- **`{radii.card-md}` = 12px** — used on standard stat cells, split-highlight blocks.
- **`{radii.card-sm}` = 10px** — used on detail blocks and mini-stats.
- **`{radii.bar}` = 6px** — used on bar tracks and bar fills.
- **`{radii.circle}` = 50%** — used on step circles, nav-button circles, accent dots, closing decoration circles, cover dots, quote decoration circles.
The radius ladder is graduated: tighter radii on smaller chrome, larger radii on bigger cards, fully rounded on pills, perfect circles on chrome. The system has **no square (0px) corners** anywhere except the progress bar.
### Border Weights
- **1px solid `{colors.border}`** — universal soft border. Used on stat cells, mini-stats, detail blocks, agenda items (bottom border only), stat-context dividers (top border only).
- **1.5px solid `{colors.border}`** — slightly heavier soft border. Used on metric cards, nav-buttons.
- **2px solid `{colors.border}`** — used on the split column divider (border-left on the right column of split layouts).
- **4px solid `{colors.primary}`** — used only as the left rule on `{components.split-highlight-block}` to signal a quoted callout.
The borders are **never opaque cobalt** — they are always at 20% opacity (`{colors.border}`). This is what gives the system its quiet, lifted quality.
### Decorative Element Types
**Tinted card** (`{components.card-tinted}`) — Cobalt-at-4% background with 1.5px cobalt-at-20% border, 14px radius. The primary content card.
**Tag pill** (`{components.tag-pill}`) — Fully rounded cobalt-at-8% pill with cobalt text. Sits in the top-right of the slide-header.
**Eyebrow** (`{typography.h4-eyebrow}`) — Uppercase cobalt label with 0.08em tracking. Sits in the top-left of the slide-header.
**CTA button** (`{components.cta-button}`) — Solid cobalt pill with cream text. The system's only solid-color element. Used once per closing surface.
**Accent line** (`{components.accent-line}`) — A short 60×4 horizontal cobalt rule with 2px radius. Used above cover titles and as eyebrow separators on open-space surfaces.
**Step circle** (`{components.step-circle}`) — A 56×56 solid cobalt circle with cream Space Grotesk numeral inside. Sequential timeline steps reduce opacity (1.0 → 0.85 → 0.7 → 0.55) to suggest fade-into-future.
**Bar track + fill** (`{components.bar-track}` + `{components.bar-fill}`) — 28px-tall track in cobalt-at-8% with a solid cobalt fill whose width carries the data. 6px rounded corners on both.
**Insight list item** (`{components.insight-list-item}`) — A counter-numbered list using CSS counter() to render decimal-leading-zero prefixes ("01", "02") in cobalt Space Grotesk 600 / 12.5px positioned absolute left.
**Split highlight block** (`{components.split-highlight-block}`) — A cobalt-at-8% tinted block with a 4px cobalt left rule and a cite line below. Used for inline pull-quotes inside split-column layouts.
**Cover decoration** (`{components.cover-decoration}`) — A clipped diagonal cobalt-tinted panel filling the right ~35% of cover surfaces. Reads as a printed accent without enclosing the layout.
**Cover dots** (`{components.cover-dots}`) — A 3×3 grid of 6px cobalt dots at 12px gap, 25% opacity. Decorative atmosphere on open-space surfaces.
**Closing circles** (`{components.closing-circles}`) — Two concentric centered circles (500px outer, 360px inner) with 1px cobalt-at-20% borders, opacity 0.3-0.4. Atmospheric decoration on closing-class surfaces.
**Metric change chip** (`{components.metric-change-positive}` / `{components.metric-change-negative}`) — Inline directional indicator: a small arrow glyph + percentage value in `{colors.positive}` or `{colors.negative}`. No fill, no border — pure inline text color.
## Do's and Don'ts
### Do
- Apply `{colors.bg}` (cream) as the universal canvas. Every surface starts on warm cream, never pure white.
- Use `{colors.primary}` cobalt as the only accent color across the entire deck — for eyebrows, metrics, CTAs, chart fills, step circles, and progress indicators.
- Set headlines (h1, h2, h3) in `{colors.text}` (`#111111`) near-black with -0.02em tracking. Cobalt headlines are forbidden; cobalt is for accent moments only.
- Set every h4 eyebrow in cobalt Space Grotesk weight 600 with uppercase + 0.08em tracking. The eyebrow is the universal section opener.
- Use `{components.card-tinted}` (cobalt-at-4% fill + cobalt-at-20% 1.5px border + 14px radius) as the universal content card pattern.
- Pair every slide-header with an h4 eyebrow on the left and a `{components.tag-pill}` on the right. The rhythm is the system's structural identity.
- Set body in Inter weight 400 at 13.6-16.8px in `{colors.text-muted}` (`#6b6b6b`) with line-height 1.6. The muted gray body is what makes the system feel premium.
- Render every numerical callout (metric, stat, bar percentage, agenda number) in Space Grotesk weight 600-700 in cobalt. The cobalt numerical accent is the system's data voice.
- Use full 100px border-radius on all chrome (tag pills, CTAs, nav-buttons). The pill shape is the system's chrome signature.
- Use directional change chips (`{components.metric-change-positive}` / `{components.metric-change-negative}`) inline with no fill — green for positive, red for negative, both subdued.
### Don't
- Don't introduce a second accent color. Cobalt is the only accent — orange, teal, purple, or any additional brand color breaks the single-accent discipline.
- Don't set headlines in cobalt. Headlines are near-black; cobalt is reserved for eyebrows, metrics, CTAs, and chart fills.
- Don't use drop shadows on cards or content. The system has zero box-shadows except a single soft cobalt CTA hover.
- Don't use square corners (0px radius) anywhere. The system is built around soft rounded corners — square corners immediately read as a different aesthetic.
- Don't use opaque cobalt borders on cards. Borders are always cobalt-at-20% (`{colors.border}`). Full-opacity borders break the quiet, lifted feel.
- Don't substitute fonts. Space Grotesk + Inter is the pairing. Substituting Arial, Helvetica, Roboto, or Open Sans collapses the typographic identity.
- Don't crowd the canvas with bordered hard-edged elements. The system depends on soft tints and gentle borders; adding heavy outlines makes it feel like a different system.
- Don't omit the slide-header (h4 eyebrow + tag pill) on a content slide. The header is the editorial rhythm.
- Don't use uppercase body text. Uppercase is reserved for h4 eyebrows and the cite line under highlight blocks.
- Don't use directional chips for non-directional emphasis. The green/red change chips are reserved for actual positive/negative comparisons (e.g., "+11 pts vs. prior quarter"). They are not general accent colors.
## Responsive Behavior
Blue Professional is designed as a **1920×1080 presentation system** (effective 100vw × 100vh). Sizing uses CSS `clamp()` for type and `vw / vh / rem` for spacing. The system has minimal responsive behavior — it's built for landscape presentation contexts.
### Scaling Behavior
- h1 scales 44.8px → 67.2px on viewport width.
- h2 scales 28.8px → 41.6px.
- Body scales 13.6px → 16.8px.
- Metric values scale 35.2px → 48px.
- Card padding (rem-based) scales with the user's font-size setting; default cards stay around 24-26px internal padding.
- Borders (1px, 1.5px, 2px), border-radii (10-14px), and pill radius (100px) are fixed and do not scale.
### Component Adjustments at Low Viewport Heights
A single `@media (max-height: 700px)` block tightens spacing on dense slides:
- Slide padding reduces from 3.5vw / 8.5vh to 2.5vh / 3vw.
- Agenda grid gap reduces.
- Metric and detail card padding reduces to 1rem.
- Bar item padding reduces.
This ensures the system fits on shorter laptop screens without breaking the structural layout.
### Presenter Behavior
- Slides advance via `ArrowRight`, `Space`, or `PageDown`.
- Slides reverse via `ArrowLeft` or `PageUp`.
- `Home` jumps to first, `End` to last.
- Horizontal touch swipe with a 50px threshold advances/reverses.
- Slide transitions are 500ms ease with opacity fade + 40px translateX slide-in/out.
- Nav-buttons disable at first/last slide (opacity 0.3).
- Progress bar at the bottom edge animates to the current slide percentage with a 400ms ease.
### Print Behavior
The system has no `@media print` rule. The slide transition is screen-only; printing produces only the active slide. For static export, screenshots of each slide preserve all atmospheric elements (cover decoration, dots, concentric circles are all CSS).
### Interactive States
- Nav-buttons invert on hover (cobalt fill, cream icon).
- Agenda items get a subtle `{colors.card-bg}` background on hover (200ms transition).
- CTA button lifts -2px on hover with a soft cobalt drop shadow (the only shadow in the system).
- Bar fills animate from 0 to data value with a 0.8s ease transition — most visible on slide entry.
## CJK & International Content
When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.
### Recommended Chinese Pairing
| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| h1 / h2 / h3 / h4-eyebrow / metric numerals / chart percentages | Space Grotesk 500–700 (negative tracking, uppercase on h4) | 思源黑体 Noto Sans SC 700 (0 tracking, no transform) |
| Body / metric description / list body | Inter 400 | 思源宋体 Noto Serif SC 400 |
| Mono / counter / tag pill / cite | Space Grotesk 500–600 (often uppercase) | 思源黑体 Noto Sans SC 500 (no transform) |
### Mixed-Content Strategy
**Strategy A** — single CJK family per role with Latin glyph coverage built in. Use 思源黑体 Noto Sans SC for every Space Grotesk role (display, eyebrow, numerical, chrome) and 思源宋体 Noto Serif SC for the Inter body role. Both faces ship Latin glyphs that read cleanly alongside Chinese characters. The serif body pairing reinforces the consulting-grade editorial register that this template is built for — investor reports and McKinsey-style briefings often pair sans display with serif body in Chinese.
### Loading
Add to the template's `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;600;700&family=Noto+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (up from 1.6), display 1.2–1.3 (up from 1.1). CJK characters are visually full and crowd vertically more than Latin.
- **Letter-spacing**: set to 0 on every CJK run. The template's −0.02em negative tracking on h1–h3 overlaps CJK strokes; the +0.08em positive tracking on h4 eyebrows reads as gappy on square glyphs.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. The h4-eyebrow and cite tokens use `text-transform: uppercase` in the Latin original; remove it for CJK runs.
- **Punctuation**: use full-width Chinese punctuation (,。:;!?「」()).
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `2024 Q3 业绩复盘` not `2024Q3业绩复盘`.
- **One font per sentence**: 思源黑体 / 思源宋体 cover both CJK and Latin glyphs — let one face handle each sentence. Don't let the browser fall back to Space Grotesk or Inter for ASCII characters mid-sentence.
### Aesthetic Notes for This System
The system's identity rests on **restraint with one strong commitment** — cream ground, cobalt accent, soft tinted cards, no shadows. None of that depends on Latin typography; it transfers cleanly to Chinese. The h4-eyebrow loses its "uppercase + 0.08em tracked + cobalt" character in CJK because both uppercase and wide tracking drop. Compensate by **always pairing the eyebrow with the cobalt accent-line component above the headline** — the 60×4 cobalt rule does the chrome-recognition work that the tracked-uppercase did in Latin. Keep the eyebrow's cobalt color and weight-600 contrast against the muted-gray body.
The cobalt color discipline (`#1e2bfa` as the only accent, full-opacity on numerals and CTAs, 20% opacity on borders, 4% opacity on card fills) is the system's actual identity and transfers entirely to a CJK build. Numerical callouts remain Latin Arabic digits in Chinese consulting decks by convention (业绩 $24.3M, 同比 +18%), so the cobalt Space Grotesk → 思源黑体 swap mostly affects labels and headlines, not the headline-grabbing numerical figures. Keep numerals in 思源黑体 weight 700 for the digit rendering.
### Known CJK Gap
- **No CDN Chinese face matches Space Grotesk's "trustworthy consulting" register exactly.** 思源黑体 reads as more institutional and slightly less contemporary than Space Grotesk. The template will feel slightly more "official report" and slightly less "AI startup" than its Latin original. This is generally desirable for executive-briefing contexts in Chinese.
- **The h4-eyebrow signal weakens.** The "uppercase Space Grotesk 600 in cobalt with 0.08em tracking" combination is the system's most recognizable small chrome and loses both the uppercase and tracking signals in CJK. Adding the `{components.accent-line}` above or below the eyebrow is the recommended compensation; without it, eyebrows can blend into body weight contrast.
- **Body in 思源宋体 changes the register.** Inter body reads as neutral-modern; 思源宋体 reads as editorial-serious. The system's "premium consulting" feel becomes slightly more "policy paper" — appropriate for state-owned enterprise or government audiences, slightly heavy for startup-pitch audiences. For startup contexts, swap body to 思源黑体 Noto Sans SC 400 instead.
## Iteration Guide
1. Any new slide starts on `{colors.bg}` cream ground. Don't switch the background per slide; the constant ground is the system's identity.
2. Any new content slide carries a slide-header at the top: h4 eyebrow (cobalt, uppercase, 0.08em) on the left + tag-pill on the right.
3. Any new headline uses Space Grotesk weight 600-700 in `{colors.text}` near-black with -0.02em tracking. Reach for h2 (28.8-41.6px) for primary moments.
4. Any new card uses the tinted pattern: `{colors.card-bg}` (cobalt at 4%) + 1-1.5px `{colors.border}` (cobalt at 20%) + 10-14px radius. Never use solid color fills or opaque borders.
5. Any new numerical callout (metric value, stat number, agenda number, bar percentage, step circle) is Space Grotesk weight 600-700 in `{colors.primary}` cobalt. Numbers are the accent moment.
6. Any new accent line, divider, or directional rule uses cobalt — solid for the primary rule, soft-cobalt (20% opacity) for borders.
7. Any new CTA uses the `{components.cta-button}` pattern: solid cobalt pill with cream text, 100px radius, no other CTA shape exists.
8. Any new chart bar uses `{components.bar-fill}` (solid cobalt) on `{components.bar-track}` (cobalt at 8%) with 6px radius.
9. Any new step or sequential indicator uses the `{components.step-circle}` with diminishing opacity for future steps (1.0 → 0.85 → 0.7 → 0.55).
10. If a surface feels too sparse, add information (more stats, more detail blocks) — don't add a second accent color or a heavier border to fill space. The system reads as elegant when populated with substance, not noise.
## Known Gaps
- **Space Grotesk and Inter are loaded from Google Fonts** via a preconnect + `<link>`. There are no system fallbacks beyond `sans-serif` — in environments where Google Fonts fail, the system collapses to system defaults and loses its character.
- **The directional change colors (`{colors.positive}` and `{colors.negative}`) are inline-only.** There is no token-level support for status fills, success/error badges, or alerts beyond these two inline text colors.
- **The single-accent discipline limits categorical color encoding.** Multi-series charts must distinguish through positioning or labeling — there is no design-system answer for "show 4 categorical series in different colors". This is intentional but limits chart expressiveness.
- **The agenda-item hover state changes background to `{colors.card-bg}`** — interactive on hover. This may not work as expected in static screen-share contexts.
- **Bar fills animate from 0 to value on entry** but only the active slide's bars are visible. Re-entering a slide replays the animation; the system does not preserve animation state.
- **The progress bar reads as decorative on slide 1** (it's at ~10% on a 10-slide deck) and not very informative until later in the deck. Combine with the slide-counter for explicit position cues.
- **The slide transition uses translateX (40px in/out)** with opacity fade. On very wide displays the 40px shift is barely perceptible; on small displays it may feel jarring.
- **The system loads Inter weights 300-600** but uses only weight 400 in practice. Lighter or heavier Inter weights are not part of the visual vocabulary; loading them is technically wasteful.
- **The metric-change indicator uses HTML entities (`↑`, `↓`)** for arrow glyphs. These render correctly in most browsers but may render as small/inconsistent glyphs depending on the system font; replacing with SVG or Unicode characters would standardize rendering.
- **The closing-decoration concentric circles are absolutely positioned with fixed 500px / 360px sizes.** On very small viewports they may exceed the viewport bounds; on very large viewports they may feel undersized.
- **The cover-decoration uses clip-path** which is widely supported but not universal. Browsers without clip-path support will render the panel as a full right column rectangle.
# Blue Professional Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/blue-professional/design.md`
- Preview card: `bold-template-pack/templates/blue-professional/preview.md`
## Selection Metadata
- Slug: `blue-professional`
- Tagline: Cream paper background with electric cobalt blue accents; clean modern professional.
- Mood: professional, modern, calm, trustworthy
- Tone: clean, considered, polished, neutral
- Formality: medium-high
- Density: medium
- Scheme: light
- Best for: Anything that should feel modern-considered and lightly authoritative: B2B SaaS pitches, consulting deliverables, advisory updates, investor reports. Also a clean, tasteful choice whenever you want to read as professional without going stiff — research synthesis, internal reviews, brand work for service businesses.
- Avoid for: Contexts where the deck should feel hot, playful, or intentionally informal — the cool electric-blue restraint will read as overly polished.
## Visual Snapshot
A restrained, consulting-grade presentation system on a warm cream canvas (#fdfae7) with a single saturated cobalt blue (#1e2bfa) as the only accent color. Display type runs Space Grotesk for headlines and numerical callouts; Inter handles body and chrome. Cards are soft-tinted cobalt at 4% opacity with 1.5px translucent borders and 10-14px rounded corners — quiet, never bordered in solid color. The aesthetic borrows from investment-research reports, McKinsey-grade quarterly briefings, and contemporary financial dashboards — measured, data-dense without feeling crowded, and unmistakably professional. The system is built for executive readability at distance, with strong typographic hierarchy and a single accent color carrying every emphasis moment.
Blue Professional is a consulting-grade presentation system designed for executive briefings, research deliverables, and quarterly reviews. Its foundational visual premise is restraint with one strong commitment: a warm cream canvas ({colors.bg} — #fdfae7) and a single saturated cobalt ({colors.primary} — #1e2bfa) that carries every accent, every metric, every CTA, every eyebrow, every chart fill. There is no secondary brand color, no palette of pastels, no warm/cool pairing — just cream, cobalt, and a tight ladder of muted grays for body text.
## Preview Ingredients
- Palette: bg #FDFAE7; primary #1E2BFA; text #111111; text-muted #6B6B6B; text-light #9A9A9A; positive #059669; negative #DC2626
- Typography: See full design doc after selection.
- Signature move: Warm cream ground ({colors.bg}) on every surface — never pure white, never gray.
- Signature move: Single saturated cobalt ({colors.primary}) as the only accent — used for every eyebrow, metric, CTA, chart fill, and progress indicator.
- Signature move: Space Grotesk (display + chrome) + Inter (body) — never substitute either.
- Signature move: Cards are 4% cobalt tints with 1.5px cobalt-at-20% borders and 10-14px rounded corners.
- Signature move: Soft pill-shaped chrome ({components.tag-pill}, {components.cta-button}) with full 100px border-radius.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Bold Poster
description: A populist editorial poster system that mashes vintage Italian sports-magazine display lettering with classical serif body and tight monospace metadata. The display face is Shrikhand — a heavy slab/script hybrid with playful italic personality — rendered at poster scale (often 200-320px) and routinely tilted off-axis. Body runs Libre Baskerville for a literary editorial register; Space Grotesk handles tiny uppercase labels and chrome. The palette is uncompromising: white canvas, deep brown-black ink (#1C1410), single saturated tomato red (#D8000F), and a warm off-white (#F5F2EF) for alternating panels. Borders are bold 1.5-3px ink rules; the only shadow is a single stacked offset behind red display text. The aesthetic is loud, confident, and unmistakably print-poster — closer to a 1970s European brand annual report or a wine merchant's catalogue than a contemporary slide deck.
colors:
bg: "#FFFFFF"
dark: "#1C1410"
red: "#D8000F"
light: "#F5F2EF"
typography:
hero-title:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(72px, 16vw, 220px)"
lineHeight: 0.88
letterSpacing: 1px
color: "{colors.dark}"
hero-title-red:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(84px, 18vw, 260px)"
lineHeight: 0.85
color: "{colors.red}"
transform: "rotate(-4deg)"
hero-title-bottom:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(64px, 14vw, 200px)"
lineHeight: 0.9
color: "{colors.dark}"
transform: "rotate(2deg)"
close-big:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(80px, 18vw, 260px)"
lineHeight: 0.88
color: "{colors.red}"
transform: "rotate(-5deg)"
stat-big:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(120px, 26vw, 320px)"
lineHeight: 0.82
color: "{colors.red}"
transform: "rotate(-6deg)"
red-quote:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(32px, 7vw, 90px)"
lineHeight: 1.15
color: "{colors.bg}"
textShadow: "2px 2px 0 rgba(28,20,16,0.25), 4px 4px 0 rgba(28,20,16,0.2), 6px 6px 0 rgba(28,20,16,0.15)"
section-header:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(32px, 5vw, 64px)"
lineHeight: 1
color: "{colors.dark}"
section-header-lg:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(36px, 6vw, 72px)"
lineHeight: 1
color: "{colors.dark}"
cell-number-lg:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(28px, 3.5vw, 52px)"
lineHeight: 1
color: "{colors.red}"
cell-number-md:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(28px, 3.5vw, 48px)"
lineHeight: 1
color: "{colors.red}"
card-title:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(22px, 3vw, 36px)"
lineHeight: 1.1
color: "{colors.dark}"
card-title-sm:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(20px, 2.5vw, 32px)"
lineHeight: 1.1
color: "{colors.dark}"
pillar-num:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(36px, 5vw, 64px)"
lineHeight: 1
color: "{colors.red}"
pillar-title:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(18px, 2.2vw, 28px)"
lineHeight: 1.15
color: "{colors.dark}"
stat-item-num:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(28px, 4vw, 56px)"
lineHeight: 1
color: "{colors.dark}"
roadmap-title:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(18px, 2.5vw, 32px)"
lineHeight: 1.1
inline-stat:
fontFamily: "'Shrikhand', cursive"
fontWeight: 400
fontSize: "clamp(18px, 2vw, 28px)"
lineHeight: 1
color: "{colors.red}"
body:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(13px, 1.2vw, 16px)"
lineHeight: 1.75
color: "{colors.dark}"
body-card:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(12px, 1.1vw, 14px)"
lineHeight: 1.6
color: "{colors.dark}"
body-cell:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(11px, 1vw, 13px)"
lineHeight: 1.55
color: "{colors.dark}"
body-small:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(11px, 1vw, 13px)"
lineHeight: 1.5
color: "{colors.dark}"
hero-meta:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(11px, 1vw, 14px)"
lineHeight: 1.5
color: "{colors.dark}"
tag-body:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(13px, 1.2vw, 16px)"
lineHeight: 1.6
color: "{colors.dark}"
red-cite:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(13px, 1.3vw, 16px)"
lineHeight: 1.5
color: "{colors.bg}"
close-sub:
fontFamily: "'Libre Baskerville', serif"
fontWeight: 400
fontSize: "clamp(14px, 1.5vw, 18px)"
lineHeight: 1.6
color: "{colors.dark}"
label:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 10px
letterSpacing: 2px
textTransform: uppercase
color: "{colors.dark}"
label-red:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 10px
letterSpacing: 2px
textTransform: uppercase
color: "{colors.red}"
rm-label:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 9px
letterSpacing: 3px
textTransform: uppercase
color: "{colors.red}"
tag-label:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: "clamp(10px, 0.9vw, 12px)"
letterSpacing: 3px
textTransform: uppercase
color: "{colors.red}"
bullet-body:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 400
fontSize: "clamp(10px, 0.9vw, 12px)"
lineHeight: 1.45
color: "{colors.dark}"
counter:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: 11px
lineHeight: 1
letterSpacing: 2px
textTransform: uppercase
color: "{colors.dark}"
link:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 600
fontSize: "clamp(10px, 0.9vw, 12px)"
letterSpacing: 2px
textTransform: uppercase
color: "{colors.dark}"
fc-micro:
fontFamily: "'Space Grotesk', sans-serif"
fontWeight: 400
fontSize: 10px
lineHeight: 1.4
color: "{colors.dark}"
spacing:
pad-slide: "48px 56px"
pad-cell: "22px 20px"
pad-cell-sm: "20px 24px"
pad-pillar: "32px 24px"
pad-card: "24px"
pad-roadmap: "40px 48px"
gap-grid-md: "24px 32px"
gap-grid-roadmap: "28px 36px"
gap-grid-stats: "48px"
gap-stat-row: "20px"
pad-bottom-clearance: "40px"
max-width-content: 1100px
max-width-services: 1000px
canvas:
width: 100vw
height: 100vh
background: "{colors.bg}"
components:
progress-bar:
position: "fixed, bottom 0 left 0"
height: 5px
background: "{colors.red}"
description: "Persistent thick red progress strip at the bottom of the viewport. Width grows linearly with slide index. The system's most prominent piece of chrome."
counter:
position: "fixed, bottom 18px right 24px"
color: "{colors.dark}"
opacity: 0.5
fontFamily: "'Space Grotesk', sans-serif"
fontSize: 11px
letterSpacing: 2px
description: "Persistent slide counter NN / NN at 50% opacity in Space Grotesk uppercase."
hint-pill:
position: "fixed, bottom 18px center"
background: "{colors.light}"
padding: "6px 14px"
borderRadius: 4px
fontSize: 10px
opacity: 0
description: "Bottom-center hint pill that fades to 50% opacity on body hover. Subtle wayfinding only."
section-bordered-grid:
border: "3px solid {colors.dark}"
description: "Heavy 3px ink border enclosing a grid of cells. Each child cell carries a 1.5px ink inner border, producing a hairline-on-heavy double-border tabular grid. Used for financial-figure and summary-highlight grids."
cell-bordered:
border: "1.5px solid {colors.dark}"
padding: "22px 20px"
description: "Tabular cell with 1.5px ink border. Lives inside a 3px-bordered parent grid; the two border weights touch to produce the system's signature grid-with-double-edge."
red-leftbar-card:
borderLeft: "4px solid {colors.red}"
paddingLeft: 18px
description: "Service or content card marked by a 4px solid red left rule and 18px left padding. The system's editorial card pattern — no outline, just the red rule signaling the start of a block."
red-leftbar-card-thin:
borderLeft: "3px solid {colors.red}"
paddingLeft: 16px
description: "Thinner variant of the red-leftbar card used on dark surfaces (roadmap phases). Same pattern, scaled-down rule weight."
bullet-em-dash:
glyph: "—"
color: "{colors.red}"
fontWeight: 700
paddingLeft: 14px
description: "List bullet using a red em-dash (—) glyph in place of a disc. The dash sits at position absolute left and the body text indents to clear it."
bullet-bullet:
glyph: "•"
color: "{colors.red}"
paddingLeft: 12px
description: "List bullet using a red round bullet (•) glyph. Same indent pattern as the em-dash variant."
pillar-panel:
flex: 1
padding: "32px 24px"
borderRight: "3px solid {colors.dark}"
description: "Vertical column panel inside a multi-pillar layout. Each pillar separated by a 3px ink vertical rule. Alternating panels swap background from {colors.bg} to {colors.light} for striping."
pillar-bullet-row:
padding: "5px 0"
borderBottom: "1px solid rgba(28, 20, 16, 0.08)"
description: "Bullet row inside a pillar with a hairline-soft bottom border (ink at 8%) separating items. The last item drops the border."
global-card:
border: "2px solid {colors.dark}"
padding: 24px
description: "Bordered information card with 2px ink outline. Used on the global presence layout. Heavier than the leftbar pattern, more contained."
stacked-text-shadow:
textShadow: "2px 2px 0 rgba(28,20,16,0.25), 4px 4px 0 rgba(28,20,16,0.2), 6px 6px 0 rgba(28,20,16,0.15)"
description: "Three-step decreasing-opacity stacked offset shadow in ink. Applied only to large red display text on red panels. The system's only shadow treatment."
red-panel:
background: "{colors.red}"
color: "{colors.bg}"
description: "Full-bleed saturated red panel surface. Carries white text with the stacked-text-shadow treatment on display."
dark-panel:
background: "{colors.dark}"
color: "{colors.bg}"
description: "Full-bleed deep brown-black panel surface. Carries white text and red accents (left bars, mono labels)."
link-underline:
color: "{colors.dark}"
borderBottom: "2px solid {colors.red}"
paddingBottom: 4px
description: "Footer link style — Space Grotesk uppercase with a 2px red underline. Hover swaps text color to red."
hero-title-stack:
description: "A three-line stacked title where each line is a Shrikhand display element at a slightly different size. Two of the three lines carry rotation transforms (-4deg, +2deg) and one is set in red. The composition is the system's signature opener."
---
## 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
Bold Poster is a **populist editorial poster system** that lifts its visual vocabulary from vintage Italian sports magazines, mid-century European brand annual reports, and wine-merchant catalogues. The premise is that every slide should feel printed — set in heavy display type, locked to one strong red accent, on a white or off-white sheet, with grids ruled in ink and decoration kept to a strict minimum.
The type system is three faces working in tight roles. **Shrikhand** (Google Fonts) is the display face — a heavy slab/script hybrid with chunky italic terminals, narrow apertures, and a distinctly Italian-sports-script personality. Used at poster scale (often 100-320px) and almost always with playful rotation (-6° to +2°), Shrikhand carries every hero title, every section header, every stat figure, every card title. **Libre Baskerville** (Google Fonts) is the body face — a classical literary serif with strong stroke contrast that anchors the system in editorial register. Used at 11-16px with 1.5-1.75 line-height in deep ink, Libre Baskerville is what makes the system feel printed rather than digital. **Space Grotesk** (Google Fonts) is the chrome face — used exclusively for tiny uppercase labels (9-12px, 2-3px tracking), bullet body inside cards, slide counters, and footer links. The Space Grotesk treatment is the system's "metadata" voice.
The color philosophy is **uncompromising restraint**: white canvas, deep brown-black ink (`{colors.dark}` — `#1C1410`), single saturated tomato red (`{colors.red}` — `#D8000F`), and a warm off-white (`{colors.light}` — `#F5F2EF`) for alternating panels. There are no secondary brand colors, no gradients (except the inside of the stacked text-shadow), no tints, no semantic state colors. Every numerical callout, every active rule, every CTA, every emphasis moment is red — and red is reserved for these moments only (it is never used as body text, never as fill on a card without text on top, never as a tint).
Depth is **structural, not atmospheric**. The system has no drop shadows except a single stacked text-shadow applied to red display text on red panels (three steps at 2/2, 4/4, 6/6 in decreasing-opacity ink). All other depth comes from heavy borders: 3px ink outlines on tabular grids, 1.5-2px ink borders on cells, 4px red left rules on editorial cards, 1px hairline rules between bullet items. The double-border treatment (3px outer + 1.5px inner) is the system's signature tabular pattern — it produces a printed-newsprint quality that defines the look.
**Density philosophy: high — populist and packed.** This system reads as authoritative when slides are dense and timid when sparse. Roadmap, pillar, and financial slides routinely carry 3-6 distinct cells with body paragraphs, bullet lists, and tabular data — and they read as energetic, not crowded. Conversely, hero, closing, and statement slides intentionally drop to one or two huge display elements with massive negative space — the very-low and very-high density polarities are both deliberate. A typical content slide carries a section header + a grid of 3-6 cells, each holding a red numerical/title + a Libre Baskerville body paragraph + 3-6 Space Grotesk mono bullets. A typical statement slide carries one rotated red Shrikhand element occupying half the canvas with a single tagline below.
**Key Characteristics:**
- White (`{colors.bg}`) canvas alternating with off-white (`{colors.light}`) panels for striping, plus dark (`{colors.dark}`) and red (`{colors.red}`) full-bleed panel surfaces for statement moments.
- Single tomato red (`{colors.red}`) as the only accent — used for every numerical figure, every section rule, every label, every left-bar marker.
- Three-face stack: Shrikhand (display + numerical), Libre Baskerville (body), Space Grotesk (mono labels + bullets + chrome).
- Display Shrikhand is routinely tilted (-6° to +2°) — the rotation is the system's signature movement.
- Heavy ink borders: 3px on tabular grid containers, 1.5-2px on cells, 4px red on editorial leftbar cards, 1px hairlines between bullet rows.
- Stacked text-shadow (three steps at 2/2, 4/4, 6/6 in decreasing ink opacity) on red display elements — the only shadow in the system.
- Persistent red progress bar (5px thick) at the bottom edge of every slide.
- Em-dash and bullet glyphs in red as list markers — never default disc bullets.
- Hero compositions stack three Shrikhand lines at varying sizes with at least one in red and at least one tilted.
- Footer links use Space Grotesk uppercase with a 2px red underline.
## Colors
### Palette
- **Bg** (`{colors.bg}` — `#FFFFFF`): Pure white canvas. The default ground for most surfaces. Reads as fresh newsprint paper.
- **Dark** (`{colors.dark}` — `#1C1410`): A deep brown-black with warm bias — not pure black. Used for every line of body text, every border, every Space Grotesk label, every Libre Baskerville paragraph, and as a full-bleed panel ground on roadmap-class surfaces. The warmth distinguishes it from generic editorial black.
- **Red** (`{colors.red}` — `#D8000F`): Saturated tomato red. The system's single accent. Used for every numerical figure (Shrikhand red numerals are the most common element), every section eyebrow label, every leftbar rule on editorial cards, every list bullet glyph, every footer link underline, the persistent progress bar, and as a full-bleed panel ground on statement-class surfaces. Never used as body text color, never as a tint, never as a card fill without overlaid text.
- **Light** (`{colors.light}` — `#F5F2EF`): Warm off-white. Used for alternating panel backgrounds inside pillar layouts (every other pillar swaps to off-white for vertical striping) and as the background of the hint-pill chrome. Subtly warmer than the white canvas — creates surface differentiation without disrupting the printed-paper register.
### Defaults
- **Default surface background**: `{colors.bg}` (white). For statement moments, switch to `{colors.red}` (full-bleed red panel). For roadmap-class moments, switch to `{colors.dark}`. For striping inside a pillar layout, alternate `{colors.bg}` and `{colors.light}`.
- **Default headline / display color on white surfaces**: `{colors.dark}` for primary headlines, `{colors.red}` for numerical figures and stat-class display elements.
- **Default headline color on red panels**: `{colors.bg}` (white) with the stacked text-shadow treatment.
- **Default headline color on dark panels**: `{colors.bg}` (white). Numerical accents stay `{colors.red}`.
- **Default body text color**: `{colors.dark}` on white/light surfaces, `{colors.bg}` (white) on dark/red surfaces with opacity 0.5-0.8 for tertiary content.
- **Default eyebrow / label color**: `{colors.red}` on white surfaces (red Space Grotesk uppercase at 2-3px tracking), `{colors.dark}` for the smaller cell labels inside grids.
- **Default leftbar rule color**: `{colors.red}`. The 4px (or 3px on dark surfaces) red left rule is the editorial card signature.
- **Default border color for cells and grids**: `{colors.dark}`. There are no colored cell borders.
- **Default bullet glyph color**: `{colors.red}`. Default disc bullets do not exist in this system; every list uses red em-dash or red round-bullet glyphs.
The system commits **hard** to the four-color palette. Don't introduce a fifth color (green for positive, blue for info, yellow for highlight). All emphasis is achieved by red, all body is dark on light, all inversion is white on red or white on dark. Categorical differentiation comes from positioning, label, and tilt — never from color.
## Typography
### Font Family Stack
The system runs three faces, each tightly bound to its role.
**Shrikhand** (Google Fonts) is the display + numerical face. It's a single-weight (400) heavy slab-script with playful italic-leaning forms and narrow apertures — a face that reads as both old-world (postcard-script) and contemporary (variable-weight digital display). Used at every scale from 18px (inline stats) to 320px (the hero stat). Always weight 400 (the face has no other weights). Rotation is part of the face's voice — multiple Shrikhand elements per slide carry transforms ranging from -6° to +2°.
**Libre Baskerville** (Google Fonts, 400 / 700 + italic) is the body face. A classical literary serif with high stroke contrast — used for every paragraph, every body cell, every metadata line, every cite, every close-sub. Set at 11-16px with 1.5-1.75 line-height, the face reads as comfortably editorial. The face's italic and bold weights are loaded but used sparingly — italic exists for inline emphasis, bold weight 700 is rarely needed since Shrikhand already handles all the heavy display work.
**Space Grotesk** (Google Fonts, weights 400-700) is the metadata + chrome face. Used at 9-12px in uppercase with 2-3px letter-spacing for labels, eyebrows, slide counters, link text, card bullet bodies (when not using Libre Baskerville), and progress chrome. The wide-tracked uppercase treatment is the system's "stamped metadata" voice.
The roles are non-overlapping: Shrikhand handles every display moment and every numerical figure; Libre Baskerville handles every body paragraph and editorial text; Space Grotesk handles every uppercase label, bullet, and chrome element. Don't cross — Shrikhand body would be illegible; Libre Baskerville labels would look like book footnotes; Space Grotesk headlines would feel like a tech startup.
### Typography Scale
| Token | Size (clamp / px) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.stat-big}` | 120–320px clamp | Shrikhand | 400 | Hero-class stat figure (always rotated -6°, always red) |
| `{typography.hero-title-red}` | 84–260px clamp | Shrikhand | 400 | Red word in a multi-line hero stack (always rotated -4°) |
| `{typography.close-big}` | 80–260px clamp | Shrikhand | 400 | Closing-statement title (always rotated -5°, always red) |
| `{typography.hero-title}` | 72–220px clamp | Shrikhand | 400 | Top line of a hero stack (default no rotation) |
| `{typography.hero-title-bottom}` | 64–200px clamp | Shrikhand | 400 | Bottom line of a hero stack (always rotated +2°) |
| `{typography.section-header-lg}` | 36–72px clamp | Shrikhand | 400 | Large section header for financial / dense-data slides |
| `{typography.section-header}` | 32–64px clamp | Shrikhand | 400 | Standard section header (summary, services, global, close) |
| `{typography.pillar-num}` | 36–64px clamp | Shrikhand | 400 | Numeral atop a pillar panel (red) |
| `{typography.cell-number-lg}` / `{typography.cell-number-md}` | 28–52px clamp | Shrikhand | 400 | Tabular cell numerical figure (always red) |
| `{typography.stat-item-num}` | 28–56px clamp | Shrikhand | 400 | Inline supplementary stat numeral (dark color) |
| `{typography.card-title}` | 22–36px clamp | Shrikhand | 400 | Service card title or global card title |
| `{typography.card-title-sm}` | 20–32px clamp | Shrikhand | 400 | Smaller card title (global cards) |
| `{typography.pillar-title}` | 18–28px clamp | Shrikhand | 400 | Pillar panel title |
| `{typography.roadmap-title}` | 18–32px clamp | Shrikhand | 400 | Roadmap phase title (white on dark surface) |
| `{typography.red-quote}` | 32–90px clamp | Shrikhand | 400 | Quote body on a red panel (white text + stacked shadow) |
| `{typography.inline-stat}` | 18–28px clamp | Shrikhand | 400 | Inline mini-stat number (red) inside a body block |
| `{typography.body}` | 13–16px clamp | Libre Baskerville | 400 | Standard body paragraph |
| `{typography.body-card}` | 12–14px clamp | Libre Baskerville | 400 | Card body inside service/global cards |
| `{typography.body-cell}` | 11–13px clamp | Libre Baskerville | 400 | Tabular cell body inside grids |
| `{typography.body-small}` | 11–13px clamp | Libre Baskerville | 400 | Small body for summary highlights |
| `{typography.hero-meta}` | 11–14px clamp | Libre Baskerville | 400 | Hero meta line above the title stack |
| `{typography.red-cite}` | 13–16px clamp | Libre Baskerville | 400 | Citation under a red-panel quote (white text) |
| `{typography.close-sub}` | 14–18px clamp | Libre Baskerville | 400 | Subtitle / contact line under a closing title |
| `{typography.label-red}` / `{typography.tag-label}` | 10–12px | Space Grotesk | 600 | Section label (uppercase, 2-3px tracking, red) |
| `{typography.label}` | 10px | Space Grotesk | 600 | Cell label inside grids (uppercase, 2px tracking, dark) |
| `{typography.rm-label}` | 9px | Space Grotesk | 600 | Roadmap phase label (uppercase, 3px tracking, red) |
| `{typography.bullet-body}` | 10–12px clamp | Space Grotesk | 400 | List bullet body inside cards and pillars |
| `{typography.counter}` | 11px | Space Grotesk | 600 | Persistent slide counter |
| `{typography.link}` | 10–12px clamp | Space Grotesk | 600 | Footer / closing link text (uppercase, 2px tracking) |
| `{typography.fc-micro}` | 10px | Space Grotesk | 400 | Tiny micro-context line at the bottom of a tabular cell |
### Defaults
- **Default size for a hero or cover title**: `{typography.hero-title}` (72–220px) at the top of a stack, paired with `{typography.hero-title-red}` (84–260px, red, rotated -4°) on a second line and `{typography.hero-title-bottom}` (64–200px, rotated +2°) on a third line. The three-line stacked composition is the system's standard hero pattern.
- **Default size for a primary section headline**: `{typography.section-header}` (32–64px). Always Shrikhand.
- **Default size for a hero-class statistic**: `{typography.stat-big}` (120–320px) rotated -6°, always red.
- **Default size for a tabular cell numeral**: `{typography.cell-number-md}` (28–52px) in red.
- **Default size for body**: `{typography.body}` (13–16px) Libre Baskerville at line-height 1.75.
- **Default size for a card body**: `{typography.body-card}` (12–14px) at line-height 1.6.
- **Default size for a section eyebrow label**: `{typography.tag-label}` (10–12px) Space Grotesk weight 600 in red, uppercase, with 2-3px letter-spacing.
- **Default size for a list bullet body**: `{typography.bullet-body}` (10–12px) Space Grotesk weight 400.
- **Default weight for Shrikhand**: 400 — the face has no other weights.
- **Default weight for Libre Baskerville body**: 400. Bold (700) is used only for inline emphasis inside body paragraphs.
- **Default weight for Space Grotesk labels**: 600. Wide tracking is the system's label voice; weight 400 is for bullet bodies only.
When unsure which display token to reach for, default to `{typography.section-header}` (32–64px) for a primary slide section opener. Reserve `{typography.stat-big}` for hero-stat moments and `{typography.hero-title}` triples for cover-class surfaces.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every hero-class Shrikhand element is part of a multi-line stacked composition with at least one rotated line and at least one red line.** A single-line Shrikhand hero title without rotation or color contrast collapses into a generic display moment.
- **Every tabular numerical cell figure is Shrikhand at the cell-number scale (28–52px) in `{colors.red}`.** Numerical cells in dark text break the system's hierarchy — red is the data signal.
- **Every section eyebrow is Space Grotesk weight 600 in `{colors.red}`, uppercase, with 2-3px letter-spacing.** No exceptions. Eyebrows at any other tracking, weight, color, or case are not the system's eyebrow.
- **Every statement-class Shrikhand element (stat-big, close-big) is rotated -5° to -6° in `{colors.red}`.** Untilted red Shrikhand at hero scale looks like a misplaced word — the tilt is the system's "movement" signal.
- **Every red-panel display element carries the stacked text-shadow** (`2px 2px 0 rgba(28,20,16,0.25), 4px 4px 0 rgba(28,20,16,0.2), 6px 6px 0 rgba(28,20,16,0.15)`). Without the shadow, white Shrikhand on red reads as floating; with it, the text feels printed-and-pressed into the panel.
- **Every list bullet uses a `{colors.red}` em-dash (—) or round-bullet (•) glyph** at position absolute left with a 12-14px padding-left on the body. Default disc bullets do not exist; the red marker is the system's list signal.
- **Every Libre Baskerville body is at line-height ≥ 1.5 (preferably 1.6-1.75).** Tighter line-height collapses the editorial register.
- **Every body strong (`<strong>`) inside a Libre Baskerville paragraph switches face to Space Grotesk weight 600.** The inline face-switch is the system's primary inline emphasis mechanism — a serif strong tag does not produce the same effect.
### Typography Principles
The voice contrast is **chunky tilted display Shrikhand ↔ literary serif body ↔ wide-tracked mono labels**. Italic is rare (Libre Baskerville italic exists but is used only for inline emphasis inside body); underline is reserved for the red-underline footer link treatment. Bold within Libre Baskerville body is replaced by an inline face-switch to Space Grotesk weight 600 — the change-of-face is the emphasis signal.
Numerical content (stat figures, financial values, percentage callouts, mini-stats) is always Shrikhand in red. Even small inline stats inside body cells become red Shrikhand. The numerical-as-display pattern is what gives the system its sports-magazine register.
## Layout
### Canvas System
The system targets `100vw × 100vh` per slide. Slides are absolutely positioned and animate in via opacity + translateY (30px) + scale (0.98 → 1) on 550ms ease. Only one slide is `.active` at a time. Default slide padding is `48px 56px` with major variations:
- Hero slides: `5vh 7vw` top-padding, alignment shifted to top-left.
- Roadmap slides: `40px 48px` to accommodate the dense two-column grid.
- Pillars slides: `0` (the pillar columns provide their own internal padding).
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-slide}` | 48px 56px | Default slide padding |
| `{spacing.pad-cell}` | 22px 20px | Tabular cell internal padding (financial grid) |
| `{spacing.pad-cell-sm}` | 20px 24px | Summary highlight cell padding |
| `{spacing.pad-pillar}` | 32px 24px | Pillar column padding |
| `{spacing.pad-card}` | 24px | Global card padding |
| `{spacing.pad-roadmap}` | 40px 48px | Roadmap surface padding |
| `{spacing.gap-grid-md}` | 24px 32px | Standard service/global grid gap (row × col) |
| `{spacing.gap-grid-roadmap}` | 28px 36px | Roadmap two-column grid gap |
| `{spacing.gap-grid-stats}` | 48px | Big stat row gap |
| `{spacing.gap-stat-row}` | 20px | Vertical gap within a stat-item stack |
### Persistent Chrome
Three elements appear on every slide:
- **Progress bar** at the bottom edge — a 5px thick `{colors.red}` strip that grows in width with slide index. The thickest, most visible piece of chrome; it functions as both progress indicator and bottom-edge poster trim.
- **Slide counter** at bottom-right (`bottom: 18px right: 24px`) — Space Grotesk weight 600 uppercase NN / NN at 50% opacity.
- **Hint pill** at bottom-center — Space Grotesk uppercase text in an off-white pill, opacity 0 by default, fading to 50% on `body:hover`.
### Surface Variations
The deck cycles through five surface treatments:
- **White content surfaces** — default, most slides.
- **Off-white striped panels** — inside pillar layouts, alternating columns get `{colors.light}` background for vertical striping.
- **Full-bleed red panel** — statement / quote slides flood the canvas in `{colors.red}` with white display text and the stacked text-shadow.
- **Full-bleed dark panel** — roadmap-class surfaces use `{colors.dark}` ground with white text and red accents.
- **Bordered tabular grids** — financial-figure and summary-highlight grids carry a 3px ink outer border + 1.5px ink inner cell borders, producing the system's signature double-border tabular composition.
### Hero Stack Composition
The standard cover/hero pattern is a **three-line Shrikhand stack** where each line carries a different size and at least one carries rotation and at least one is in red. The stack reads top-left → bottom-right, with the smallest line at the bottom and the boldest red rotation in the middle. The composition is the system's most distinctive opener.
## Depth and Elevation
### No Cards, No Shadows (Mostly)
The system uses **almost no box-shadows**. Cards do not float off the surface via shadow. Depth comes from:
- **Heavy borders** (3px outer + 1.5px inner double-border on tabular grids; 2px solid borders on global cards; 4px red left rules on editorial leftbar cards).
- **Surface inversion** (full-bleed red or dark panels switch the entire surface).
- **Tilted display elements** that break the grid alignment.
### The Single Shadow Pattern (Stacked Text Shadow)
The only shadow in the entire system is the **stacked text-shadow on red display text on red panels**: three steps at 2/2, 4/4, 6/6 with decreasing-opacity ink fill (0.25, 0.20, 0.15). The shadow is applied via `text-shadow:` not `box-shadow:`. The effect is a printed-press feel — the text reads as having been stamped slightly off-register, three times. This treatment appears only on the red-quote and certain rotated Shrikhand display moments on red panels.
### Border-as-Depth (Tabular Grid Signature)
The financial-grid and summary-highlight-grid patterns use a **3px solid ink outer border** with **1.5px solid ink inner cell borders** — the two border weights touch at every cell intersection, producing a printed-newsprint quality. This is the system's primary structural depth mechanism on data-heavy surfaces.
### Leftbar Rules
Editorial cards (service cards, roadmap phases, global cards) are marked by a **4px (or 3px on dark surfaces) red solid left border** with 16-18px padding-left. The leftbar rule signals "this is a card" without enclosing it — the card reads as cantilevered off the red rule. This is the system's most common card pattern.
### Tilt as Depth
Rotated Shrikhand display elements break the horizontal baseline and create perceived dimensionality without using perspective. The standard rotations are -6° (stat-big), -5° (close-big), -4° (hero-title-red), +2° (hero-title-bottom). These tilts are part of the system's spatial language.
## Shapes and Treatment
### Border Radius
- **0px** on everything except the hint-pill (4px) and the bar-track elements (none in this template, but if used should be 0px). Every card, every cell, every panel, every callout is a strict rectangle.
- **4px** on the hint-pill only — a minor concession for the floating chrome.
The square-corner discipline is essential. Rounded cards immediately collapse the printed-poster feel into generic web aesthetic.
### Border Weights
- **5px solid `{colors.red}`** — used only on the persistent progress bar.
- **4px solid `{colors.red}`** — used on the editorial leftbar card (service cards on white surfaces).
- **3px solid `{colors.dark}`** — used on the outer border of tabular grids (financial-grid, summary-highlights) and as the vertical pillar separator.
- **3px solid `{colors.red}`** — used on the leftbar of roadmap phase cards (on dark surfaces).
- **2px solid `{colors.red}`** — used as the underline rule on footer links.
- **2px solid `{colors.dark}`** — used as the outline border on global cards.
- **1.5px solid `{colors.dark}`** — used on inner cells of tabular grids.
- **1px solid `rgba(28, 20, 16, 0.08)`** — hairline-soft separator between bullet rows inside pillar panels.
The border ladder (1px-soft / 1.5px / 2px / 3px / 4px / 5px) is fixed. Every border is solid; dashed and dotted borders do not exist.
### Decorative Element Types
**Hero title stack** — A three-line Shrikhand composition at varying sizes with rotation and color contrast. The system's signature opener.
**Red panel** — Full-bleed `{colors.red}` ground with white display text carrying the stacked text-shadow. Used for statement / quote moments.
**Dark panel** — Full-bleed `{colors.dark}` ground with white text and red accents. Used for roadmap-class dense-data surfaces.
**Tabular bordered grid** — 3px ink outer border + 1.5px ink inner cell borders producing a double-border tabular composition. Each cell holds a Shrikhand red numeral + Space Grotesk uppercase label + Libre Baskerville body paragraph + optional Space Grotesk micro line at bottom.
**Red leftbar card** — A 4px solid red left rule with 18px left padding holding a Shrikhand card title + Libre Baskerville body + Space Grotesk red-bullet list. The system's primary editorial card pattern.
**Pillar panel** — A vertical column inside a multi-pillar layout, separated by 3px ink vertical rules and alternating between white and off-white backgrounds. Each pillar holds a Shrikhand red numeral, Shrikhand title, Libre Baskerville lead, and Space Grotesk bullets separated by 1px hairline-soft rules.
**Global card** — A 2px solid ink-bordered card with 24px padding holding a Space Grotesk red label + Shrikhand title + Libre Baskerville body + inline gc-stats row. Used on the global-presence surface.
**Em-dash bullet** — A red em-dash glyph at position absolute left with 14px padding-left on the body. The system's primary list marker.
**Round bullet** — A red round-bullet glyph at position absolute left with 12px padding-left on the body. Secondary list marker, used in card and pillar bullets.
**Footer link** — Space Grotesk uppercase text with a 2px red underline and 4px padding-bottom. Hover swaps text color to red.
**Stacked text shadow** — Three-step decreasing-opacity ink shadow applied to red display text on red panels. The system's only shadow treatment.
**Tilted display** — Shrikhand elements rotated -6° to +2°. Used on hero-title-red, stat-big, close-big, and hero-title-bottom.
## Do's and Don'ts
### Do
- Apply `{colors.bg}` (white) as the default canvas on most surfaces. Switch to `{colors.red}` for statement slides, `{colors.dark}` for dense-data slides, and alternate `{colors.bg}` / `{colors.light}` for vertical pillar striping.
- Set every hero-class title as a multi-line Shrikhand stack with at least one rotated line and at least one red line. The composed-stack is the system's opener signature.
- Use Shrikhand at every numerical-callout moment in `{colors.red}` — tabular cells, summary highlights, pillar numbers, inline mini-stats. Red Shrikhand numerals are the system's data voice.
- Set every section eyebrow in Space Grotesk weight 600 uppercase with 2-3px letter-spacing in `{colors.red}`. The wide-tracked red label is the universal section opener.
- Apply the stacked text-shadow to red display text on red panels. The three-step decreasing-opacity ink shadow is the system's only shadow and creates the printed-press feel.
- Use the 4px red leftbar pattern (`{components.red-leftbar-card}`) for editorial cards. The cantilevered-off-the-rule treatment is the system's primary card pattern.
- Build tabular grids with the double-border treatment: 3px ink outer border + 1.5px ink inner cell borders touching at intersections.
- Render every list bullet with a red em-dash (`{components.bullet-em-dash}`) or red round-bullet (`{components.bullet-bullet}`) at position absolute left. Default disc bullets are forbidden.
- Tilt Shrikhand statement elements (-5° to -6°) to create the system's signature movement. Untilted red statement display reads as misplaced.
- Use Libre Baskerville at line-height 1.5-1.75 in `{colors.dark}` for every body paragraph. The literary editorial body is what makes the system feel printed.
### Don't
- Don't introduce a second accent color. Red is the only accent — green for positive, blue for info, yellow for highlight all break the single-accent discipline.
- Don't round any corner on cards, panels, cells, or callouts. Square corners are non-negotiable; the only exception is the 4px hint-pill chrome.
- Don't add drop shadows or blurred shadows. The system has zero box-shadows; the only shadow is the stacked text-shadow on red display text.
- Don't substitute fonts. Shrikhand + Libre Baskerville + Space Grotesk is the trio. Replacing Shrikhand with any other display face collapses the entire identity.
- Don't use Shrikhand for body or Libre Baskerville for labels. The three-face role discipline is non-negotiable.
- Don't use default bullet points or disc list markers. Lists always use red em-dash or red round-bullet glyphs at position absolute left.
- Don't omit the tilt on hero-class red Shrikhand elements. The rotation is the system's signature movement; untilted red display reads as flat.
- Don't render headlines in red on white surfaces (except for stat-big, close-big, hero-title-red — the rotated statement elements). Most section headers are `{colors.dark}` Shrikhand, not red.
- Don't tighten Libre Baskerville body line-height below 1.5. Tight body line-height collapses the literary register into something cramped.
- Don't crowd a statement slide with cards or structural content. Statement surfaces (red panel, stat slide, close slide) deliberately reserve massive negative space around a single rotated red display element.
## Responsive Behavior
Bold Poster is designed as a **1920×1080 presentation system**. Sizing uses CSS `clamp()` with `vw`-based mid values for display type, fixed `px` for borders and chrome, and `rem`-adjacent fixed values for cell padding. The system has a single responsive breakpoint at 768px for narrow viewports.
### Scaling Behavior
- Hero stat scales 120px → 320px on viewport width.
- Hero titles scale 64px → 260px.
- Section headers scale 32px → 72px.
- Body scales 11px → 16px.
- Borders (1px-soft / 1.5px / 2px / 3px / 4px / 5px) and rotation transforms are fixed and do not scale.
### Mobile Breakpoint (max-width: 768px)
A single `@media (max-width: 768px)` block restructures dense layouts for narrow viewports:
- Slide padding shrinks from 48px × 56px to 32px × 24px.
- Summary columns collapse from 2 → 1.
- Summary highlights grid collapses from 3 → 1.
- Financial grid collapses from 3 → 2.
- Service grid collapses from 2 → 1.
- Roadmap grid collapses from 2 → 1.
- Pillars switch from horizontal flex-row to vertical flex-column; vertical separators become horizontal bottom borders.
- Global grid collapses from 2 → 1.
- Stat row stacks vertically.
- Hero tagline shifts from absolute-positioned bottom-right to relative-positioned below the hero title stack.
The system is functional but not optimized for sub-768px portrait usage — it's designed for landscape presentation contexts.
### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, `Space`, `Enter`, or `PageDown`.
- Slides reverse via `ArrowLeft`, `ArrowUp`, or `PageUp`.
- Click on the right half of the viewport advances; click on the left half reverses.
- Horizontal touch swipe with a 50px threshold advances/reverses.
- Slide transitions are 550ms cubic-bezier `(0.22, 1, 0.36, 1)` with combined opacity, translateY (30px), and scale (0.98 → 1).
- Progress bar at bottom edge animates to current slide percentage with a 500ms cubic-bezier ease.
### Print Behavior
The system has no `@media print` rule. The transition is screen-only. For static export, screenshots of each slide preserve all rotation transforms and the stacked text-shadow (both are pure CSS).
### Interactive States
- Footer links swap text color from `{colors.dark}` to `{colors.red}` on hover.
- The hint-pill fades from opacity 0 to 0.5 on `body:hover` via a 400ms ease.
## CJK & International Content
When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.
### Recommended Chinese Pairing
| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| Display / hero / stat / section header / numerical figures / card titles | Shrikhand 400 (heavy slab-script, rotated) | 思源宋体 Noto Serif SC 900 |
| Body / body-card / body-cell / hero-meta / cite / close-sub | Libre Baskerville 400 (literary serif) | 思源宋体 Noto Serif SC 400 |
| Label / bullet body / counter / link / micro chrome | Space Grotesk 400–600 (uppercase, 2–3px tracking) | 思源黑体 Noto Sans SC 500 (no transform, no tracking) |
### Mixed-Content Strategy
**Strategy A** — single CJK family per role with Latin glyph coverage built in. Use **思源宋体 Noto Serif SC** for both display and body (weight 900 for display, weight 400 for body — visual hierarchy comes from weight, size, color, and rotation, not face contrast). Use **思源黑体 Noto Sans SC** weight 500 for the small uppercase chrome (labels, bullet bodies, counter, links). 思源宋体 ships Latin glyphs that pair cleanly with Chinese characters; for mixed display moments, 思源宋体 weight 900 will render both 中文 and Latin in the same heavy serif voice.
### Loading
Add to the template's `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;700;900&family=Noto+Sans+SC:wght@400;500;600&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (already close to Libre Baskerville 1.75; keep at 1.8 for CJK), display 1.1–1.25 (up from the very tight 0.82–0.9 used on Shrikhand). Display at 0.82 collides vertically in CJK; open to 1.0 minimum.
- **Letter-spacing**: set to 0 on every CJK run. The template's 1px positive tracking on hero-title and the 2–3px tracking on Space Grotesk labels both read as gappy on square CJK glyphs.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. Every Space Grotesk label, tag-label, rm-label, counter, and link uses `text-transform: uppercase` in the Latin original; remove for CJK runs.
- **Punctuation**: use full-width Chinese punctuation (,。:;!?「」()).
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `1970 米兰式海报` not `1970米兰式海报`.
- **One font per sentence**: 思源宋体 covers both CJK and Latin glyphs in a unified serif style — let it handle mixed sentences in display and body. Don't let the browser fall back to Shrikhand or Libre Baskerville mid-word for ASCII characters.
### Aesthetic Notes for This System
The system's identity rests on **Shrikhand's chunky slab-script personality + rotation + saturated red**. Shrikhand is the most distinctive single decision in this template — and it has no Chinese equivalent. 思源宋体 weight 900 carries weight and editorial register but loses the playful italic-leaning slab character entirely. Compensate by **leaning harder on the non-typographic signatures**: keep all rotations intact (-6° on stat-big, -5° on close-big, -4° on hero-title-red, +2° on hero-title-bottom), keep the stacked text-shadow on red-panel display, keep the saturated tomato red as the only accent, keep the 3px + 1.5px double-border tabular grids, keep the red leftbar cards, keep the red em-dash bullet markers. The rotation, red, and printed-newsprint structural language survive the face swap.
The system's three-face role discipline (Shrikhand display / Libre Baskerville body / Space Grotesk chrome) collapses to a two-face system in CJK: 思源宋体 for everything Latin-serif, 思源黑体 for everything Latin-mono. The body-vs-display contrast becomes pure weight (400 vs 900) plus color (dark vs red). For inline `<strong>` emphasis inside body, switch from 思源宋体 400 to 思源黑体 600 — the change-of-face is what signals emphasis in the Latin original, and the serif-to-sans swap preserves the same logic in CJK.
### Known CJK Gap
- **No exact online CJK match for Shrikhand's slab-script personality.** The face is Italian-sports-magazine display script with chunky terminals and playful italic forms — there is no Chinese equivalent on Google Fonts, Adobe Fonts, or cn-fontsource. 思源宋体 weight 900 gives heft and editorial register but reads as serious rather than playful. The rotation transforms and saturated red carry the playful-sports-magazine voice on their own; don't drop the tilts when translating to CJK.
- **No CDN Chinese monospace face for the chrome voice.** Space Grotesk's role (uppercase tracked labels, slide counter, footer links with red underline) depends on the uppercase + 2–3px tracking treatment. 思源黑体 weight 500–600 at 0 tracking is the closest match but loses the "stamped metadata" signal. The red color and 1–2px border treatments on tags/links do most of the chrome-recognition work in a CJK build.
- **Libre Baskerville's classical literary register has no exact Chinese counterpart.** 思源宋体 reads as institutional-modern rather than 19th-century-literary. For projects that need the literary-quarterly voice specifically (long body paragraphs in essays or manifestos), consider 霞鹜文楷 LXGW WenKai instead of 思源宋体 — it carries a hand-written/calligraphic warmth closer to Baskerville's editorial personality.
## Iteration Guide
1. Any new content slide starts with a Shrikhand section header at `{typography.section-header}` (32–64px) in `{colors.dark}`, optionally preceded by a Space Grotesk red eyebrow label.
2. Any new numerical callout (cell figure, pillar number, inline stat, summary highlight) is Shrikhand in `{colors.red}` at the appropriate cell-number scale.
3. Any new body paragraph is Libre Baskerville weight 400 in `{colors.dark}` at line-height 1.5-1.75.
4. Any new editorial card uses the `{components.red-leftbar-card}` pattern (4px red left rule + 18px padding-left), holding a Shrikhand title + Libre Baskerville body + Space Grotesk red-bullet list.
5. Any new data-grid is wrapped in a 3px ink outer border with 1.5px ink inner cell borders. Each cell holds: Shrikhand red numeral + Space Grotesk uppercase label + Libre Baskerville body + optional Space Grotesk micro-context line at bottom.
6. Any new statement slide uses a full-bleed `{colors.red}` panel with white Shrikhand display text carrying the stacked text-shadow, and white Libre Baskerville cite below.
7. Any new dense-data slide uses a full-bleed `{colors.dark}` panel with white text, red Space Grotesk labels, red 3px leftbar rules on phase cards, and red round-bullet glyphs on lists.
8. Any new list uses red em-dash or red round-bullet glyphs at position absolute left — never default disc bullets.
9. Any new hero composition is a multi-line Shrikhand stack: at least three lines, at least one rotated, at least one in red. Don't collapse to a single horizontal title.
10. If a surface feels too monotone, switch the surface ground (white → red / dark / off-white panel) — don't add a second accent color or a third typeface.
## Known Gaps
- **Shrikhand is a single-weight (400) display face** — there are no bolder or lighter weights available. Every Shrikhand element is the same weight; visual hierarchy comes from size, color, and rotation only.
- **Shrikhand, Libre Baskerville, and Space Grotesk are loaded from Google Fonts** via a single `<link>` request. There are no system fallbacks beyond `cursive` / `serif` / `sans-serif` — in environments where Google Fonts fail, the system collapses to generic system fonts and loses its identity entirely.
- **The stacked text-shadow is hardcoded for ink-on-red contexts.** Applying it to different color combinations (e.g., red text on a light ground) does not produce the same effect; the three-step shadow is specifically tuned for the red-panel surface.
- **Rotation transforms are fixed per element type** (-6° on stat-big, -5° on close-big, -4° on hero-title-red, +2° on hero-title-bottom). Adjusting individual rotations requires per-instance style overrides.
- **The financial-grid and summary-highlights grid use overlapping borders** (3px outer + 1.5px inner that physically overlap by half-pixel due to box-sizing). Browser rendering of this overlap is generally clean but can produce subtle 1-pixel artifacts at certain zoom levels.
- **The pillars layout uses `overflow-y: auto`** on each pillar column. On surfaces with long content, this introduces visible scrollbars on certain operating systems — the system is designed for content that fits the viewport.
- **The hero tagline on slide-hero is absolutely positioned at `bottom: 8vh; right: 7vw`** with a 300px max-width. On very wide aspect ratios or very narrow ones it may misalign with the hero title stack.
- **The progress bar is a 5px height strip** that may visually overlap content on slides with bottom-edge text — the slide-close surface in particular places close-links at `bottom: 5vh` which clears the progress bar but only by a small margin.
- **The click-to-advance interaction divides the viewport at 50% width** for next/prev. This may conflict with click-to-interact behaviors on links inside slides (the close-slide footer links). The system relies on link click events to stopPropagation, which they do not by default.
- **The bullet-list class is defined globally** with em-dash glyphs but is not used in the demo template — the pillar bullets, service bullets, and roadmap bullets all redefine their own bullet styles inline. There's some inconsistency between the defined utility and the actual usage patterns.
# Bold Poster Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/bold-poster/design.md`
- Preview card: `bold-template-pack/templates/bold-poster/preview.md`
## Selection Metadata
- Slug: `bold-poster`
- Tagline: Editorial poster aesthetic with massive Shrikhand display and a single fire-engine red accent.
- Mood: bold, editorial, loud, confident
- Tone: dramatic, graphic, sharp, intentional
- Formality: medium
- Density: low
- Scheme: light
- Best for: Anything that should land like a magazine cover: brand manifestos, founder vision decks, editorial / cultural pitches, creative reviews. Excellent any time you want a few words to feel like a poster — including unexpected fits like a tech keynote or a finance manifesto that wants to be quotable.
- Avoid for: Decks that need to communicate dense information per slide — the layout is built around a few large statements, not paragraphs of detail.
## Visual Snapshot
A populist editorial poster system that mashes vintage Italian sports-magazine display lettering with classical serif body and tight monospace metadata. The display face is Shrikhand — a heavy slab/script hybrid with playful italic personality — rendered at poster scale (often 200-320px) and routinely tilted off-axis. Body runs Libre Baskerville for a literary editorial register; Space Grotesk handles tiny uppercase labels and chrome. The palette is uncompromising: white canvas, deep brown-black ink (#1C1410), single saturated tomato red (#D8000F), and a warm off-white (#F5F2EF) for alternating panels. Borders are bold 1.5-3px ink rules; the only shadow is a single stacked offset behind red display text. The aesthetic is loud, confident, and unmistakably print-poster — closer to a 1970s European brand annual report or a wine merchant's catalogue than a contemporary slide deck.
Bold Poster is a populist editorial poster system that lifts its visual vocabulary from vintage Italian sports magazines, mid-century European brand annual reports, and wine-merchant catalogues. The premise is that every slide should feel printed — set in heavy display type, locked to one strong red accent, on a white or off-white sheet, with grids ruled in ink and decoration kept to a strict minimum.
## Preview Ingredients
- Palette: bg #FFFFFF; dark #1C1410; red #D8000F; light #F5F2EF
- Typography: See full design doc after selection.
- Signature move: White ({colors.bg}) canvas alternating with off-white ({colors.light}) panels for striping, plus dark ({colors.dark}) and red ({colors.red}) full-bleed panel surfaces for statement moments.
- Signature move: Single tomato red ({colors.red}) as the only accent — used for every numerical figure, every section rule, every label, every left-bar marker.
- Signature move: Three-face stack: Shrikhand (display + numerical), Libre Baskerville (body), Space Grotesk (mono labels + bullets + chrome).
- Signature move: Display Shrikhand is routinely tilted (-6° to +2°) — the rotation is the system's signature movement.
- Signature move: Heavy ink borders: 3px on tabular grid containers, 1.5-2px on cells, 4px red on editorial leftbar cards, 1px hairlines between bullet rows.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Broadside
description: A protest-poster editorial system built on massive Barlow type and a single fire-orange environment color. The aesthetic is "ink on fire" — dark slides for documentation, orange slides for declaration. Display type is enormous (13vw, roughly 187px at 1440 width) in weight 900 lowercase, treating words as graphic elements rather than reading copy. The cultural reference is broadside printing, SPACE10 reports, and Wim Crouwel grids reinterpreted with one loud color and zero decoration.
colors:
ink-black: "#111111"
ink-black-alt: "#1A1A18"
fire-orange: "#E85D26"
cream: "#F0ECE5"
cream-muted: "#888880"
cream-hint: "#505048"
border-dark: "#282826"
ink-on-orange-muted: "rgba(17, 17, 17, 0.75)"
ink-on-orange-hint: "rgba(17, 17, 17, 0.55)"
ink-on-orange-faint: "rgba(17, 17, 17, 0.40)"
ink-on-orange-border: "rgba(17, 17, 17, 0.20)"
color-aliases:
c-bg: ink-black
c-bg-alt: ink-black-alt
c-bg-light: ink-black # Broadside collapses "light" → dark; there are no cream slides
c-bg-orange: fire-orange
c-fg: cream
c-fg-2: cream-muted
c-fg-3: cream-hint
c-accent: fire-orange
c-border: border-dark
typography:
display:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "13vw"
fontWeight: 900
lineHeight: 0.88
letterSpacing: -0.04em
h1:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "7.5vw"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.03em
h2:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "4.5vw"
fontWeight: 700
lineHeight: 1.1
letterSpacing: -0.02em
h3:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "2.8vw"
fontWeight: 600
lineHeight: 1.2
lead:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "1.6vw"
fontWeight: 400
lineHeight: 1.5
body:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "1.2vw"
fontWeight: 400
lineHeight: 1.6
caption:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "0.9vw"
fontWeight: 400
lineHeight: 1.5
label:
fontFamily: "IBM Plex Mono, monospace"
fontSize: "0.72vw"
fontWeight: 500
lineHeight: 1
letterSpacing: 0.14em
textTransform: uppercase
stat-value:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "5.5vw"
fontWeight: 900
lineHeight: 1
letterSpacing: -0.04em
quote-mark:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "10vw"
fontWeight: 900
lineHeight: 0.6
quote-text:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "3.8vw"
fontWeight: 700
lineHeight: 1.15
letterSpacing: -0.02em
fadelist-item:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "7.5vw"
fontWeight: 900
lineHeight: 1
letterSpacing: -0.03em
fadelist-title:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: "10.5vw"
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.04em
spacing:
pad-x: "5.5vw"
pad-y: "5.5vh"
gap-lg: "3.5vh"
gap-md: "2vh"
gap-sm: "1vh"
canvas:
width: 100vw
height: 100vh
motion:
ease-slide: "cubic-bezier(0.77, 0, 0.175, 1)"
dur-slide: "0.8s"
ease-enter: "cubic-bezier(0.16, 1, 0.3, 1)"
dur-enter: "0.5s"
components:
slide-chrome:
layout: "flex row, justify space-between"
paddingBottom: "{spacing.gap-sm}"
borderBottom: "1px solid {colors.border-dark}"
marginBottom: "{spacing.gap-md}"
description: "Top chrome bar carrying section label on left, slide number/meta on right. Suppressed on cover, chapter, quote, and end slides."
slide-foot:
layout: "flex row, justify space-between"
paddingTop: "{spacing.gap-sm}"
borderTop: "1px solid {colors.border-dark}"
marginTop: "{spacing.gap-md}"
description: "Bottom chrome bar, mirrors top chrome. Same suppression rules."
rule:
width: 36px
height: 2px
background: "{colors.fire-orange}"
description: "Stub accent rule. On orange slides this flips to {colors.ink-black}."
rule-full:
width: "100%"
height: 2px
background: "{colors.border-dark}"
kicker:
fontFamily: "{typography.label.fontFamily}"
fontSize: "{typography.label.fontSize}"
letterSpacing: 0.14em
textTransform: uppercase
color: "{colors.fire-orange}"
description: "Eyebrow above headlines. Orange on dark; dark-ink-at-55%-opacity on orange."
tag:
fontFamily: "{typography.label.fontFamily}"
fontSize: "{typography.label.fontSize}"
letterSpacing: 0.14em
textTransform: uppercase
color: "{colors.fire-orange}"
border: "1px solid {colors.fire-orange}"
padding: "0.3em 0.8em"
description: "Bordered mono tag. On orange slides flips to dark ink with 40%-opacity dark border."
broadside-num:
fontFamily: "IBM Plex Mono, monospace"
fontSize: "1.1vw"
fontWeight: 500
letterSpacing: 0.1em
color: "rgba(17, 17, 17, 0.45)"
description: "Catalogue-style slide number, typically anchored top-left on orange slides. On dark slides, color shifts to {colors.cream-hint}."
stat-card:
borderTop: "1px solid {colors.border-dark}"
padding: "{spacing.gap-md} {spacing.gap-md} {spacing.gap-md} 0"
description: "Top-border-only data card. Big orange numeral above body label above mono note."
bullet-marker:
content: "/"
color: "{colors.fire-orange}"
fontFamily: "IBM Plex Mono, monospace"
fontWeight: 700
description: "Slash glyph rendered via ::before on every bullet item. Orange on dark, dark-at-45%-opacity on orange."
compare-panel-left:
paddingRight: "calc({spacing.pad-x} * 0.55)"
borderRight: "1px solid {colors.border-dark}"
compare-panel-right:
paddingLeft: "calc({spacing.pad-x} * 0.55)"
compare-panel-orange:
background: "{colors.fire-orange}"
description: "Right-half panel filled with fire orange — the 'after' or payoff side in compare layouts."
bar-track:
height: "30vh"
borderLeft: "1px solid {colors.border-dark}"
description: "Vertical bar chart container. Bars are cream-hint by default; one bar per chart gets the .accent class for fire orange."
bar-fill:
background: "{colors.cream-hint}"
bar-fill-accent:
background: "{colors.fire-orange}"
img-placeholder:
height: "55vh"
background: "rgba(255, 255, 255, 0.04)"
border: "1px dashed {colors.border-dark}"
textTransform: uppercase
letterSpacing: 0.12em
description: "Dashed-border placeholder shown when no image is wired. Same 55vh footprint as a real img."
fadelist-stack:
description: "Vertical stack of three display-weight words, opacities 1.0 / 0.5 / 0.22 top-to-bottom. The SPACE10 'before/during/after' treatment."
---
## 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
Broadside is a **protest-poster editorial system**. The defining premise: type is so large it stops behaving as text and starts behaving as graphic primitive. Display sizes at `13vw` (`{typography.display}`) put a single word at roughly 187px on a 1440-wide screen — wide enough that the eye scans letterforms before reading. This is the system's primary expressive instrument.
The typeface stack is monolithic. **Barlow** carries every text role from `{typography.display}` down to `{typography.body}` — there is no serif companion, no script accent, no secondary display face. The expressive range is achieved entirely through weight (400 to 900) and size, not face contrast. **IBM Plex Mono** is the only secondary face and it appears only in chrome: slide numbers, kickers, labels, tags, captions, and the bullet-list slash markers. **Noto Sans SC** sits in every font-family stack as the CJK fallback at matching weights. The voice is uniform, heavy, and lowercase — *Broadside does not use uppercase headlines.* That is a meaningful inversion of the brutalist norm.
The palette functions in two distinct registers. The **dark register** uses near-black canvas `{colors.ink-black}` with cream text `{colors.cream}` and `{colors.fire-orange}` as the singular accent — the orange is used only for emphasis (kickers, accent stats, bullet markers, the leading bar). The **orange register** flips the relationship entirely: `{colors.fire-orange}` becomes the full slide background, and the same dark `#111111` ink is used for headlines and body. There is no light/cream slide variant — the `.light` class is intentionally aliased to dark in the source. Cover and chapter slides default to the orange register; content slides default to dark.
Depth is **flat**. There are no drop shadows, no elevation tokens, no soft surfaces. Hierarchy is constructed entirely from type weight, type size, and 1px hairline dividers. The `slide-chrome` and `slide-foot` borders, the `stat-card` top borders, and the `compare-panel` divider are the system's only depth signals. Everything sits on a single plane.
**Density philosophy: low to medium.** Broadside is built for negative space. A correctly composed slide pairs one massive display moment with a 1–2 line caption and nothing else. Bullet lists are explicitly capped at three items — the system prizes density of impact over density of information. A slide that feels broken in this system is one where four columns of body copy compete for attention; the correct density is one statement, one rule, breathing room. Cover, chapter, and quote slides take this furthest, suppressing chrome entirely and leaving the type alone in the field.
**Key Characteristics:**
- Massive Barlow display type at weight 900 in **lowercase** — never uppercase on display elements.
- Two-register color system: dark slides with cream text, or orange slides with dark ink. No cream/white slides exist.
- `{colors.fire-orange}` is both accent (on dark) and environment (on orange) — never a secondary color, always *the* color.
- Single-typeface system on Barlow + IBM Plex Mono for chrome only. No serif, no script, no third face.
- 1px hairline dividers (`{colors.border-dark}` on dark; `rgba(17,17,17,0.2)` on orange) provide all hierarchy structure.
- Mono kickers, mono tags, mono catalogue numbers — the chrome voice is always IBM Plex Mono uppercase.
- Bullet lists use `/` glyph in mono as the marker, capped at three items per list.
- Flat plane — no shadows, no rounded surfaces, no gradient backgrounds.
- `{spacing.pad-x}` of 5.5vw + `{spacing.pad-y}` of 5.5vh creates a generous frame; type fills the remaining space.
## Colors
### The Two Registers
Broadside operates on a binary surface system. Every slide is either **dark** (near-black background, cream text, orange as singular accent) or **orange** (fire-orange background, dark-ink text, dark-ink as the muted-emphasis tone). There is no cream/paper register — the `.light` class is aliased to dark in the source. Choose one register per slide and commit to it.
### Palette
- **Ink Black** (`{colors.ink-black}` — #111111): The dark register's primary canvas, and the primary text color on orange slides. Slightly softer than pure black but reads as black. This is the universal "ink" of the system.
- **Ink Black Alt** (`{colors.ink-black-alt}` — #1A1A18): A secondary surface for the dark register, used when a region needs to feel slightly raised from the base canvas without breaking the flat plane.
- **Fire Orange** (`{colors.fire-orange}` — #E85D26): The signature. On dark slides it is the accent — kickers, accent stat values, bullet markers, the leading bar in a chart, the orange opening quote mark. On orange slides it is the entire environment. Saturation is high but the hue is warm rather than electric; it reads as protest poster, not safety vest.
- **Cream** (`{colors.cream}` — #F0ECE5): Primary text color on dark slides. Warm off-white, never pure white — the warmth softens the dark canvas and signals an editorial register.
- **Cream Muted** (`{colors.cream-muted}` — #888880): Secondary text on dark slides — supporting body, sub-headings, the muted half of a comparison.
- **Cream Hint** (`{colors.cream-hint}` — #505048): Tertiary text on dark — chart axis labels, source notes, slide numbers when not in mono context.
- **Border Dark** (`{colors.border-dark}` — #282826): The 1px divider color on dark slides. Barely visible against the canvas; provides structure without drawing attention.
- **Ink-on-orange overlays**: Dark ink at four opacities (75% / 55% / 40% / 20%) for body, hint, label, and border treatments on orange slides. These are the orange register's "muted" equivalents.
### Defaults
- **Default surface for content slides**: `{colors.ink-black}` (dark register).
- **Default surface for cover, chapter, statement-payoff, and section-divider slides**: `{colors.fire-orange}` (orange register).
- **Default headline color on dark surfaces**: `{colors.cream}`.
- **Default headline color on orange surfaces**: `{colors.ink-black}`.
- **Default body text color on dark surfaces**: `{colors.cream}`.
- **Default body text color on orange surfaces**: `rgba(17, 17, 17, 0.75)`.
- **Default accent color on dark surfaces**: `{colors.fire-orange}` — used for kickers, accent stat values, bullet markers, the lead bar in a chart, and the opening quote mark.
- **Default accent color on orange surfaces**: `{colors.ink-black}` — the dark ink itself becomes the contrast pop.
- **Default chrome border color**: `{colors.border-dark}` on dark; `rgba(17, 17, 17, 0.2)` on orange.
The orange register has no third color. When emphasis is needed on an orange slide, use weight or opacity contrast on the existing ink, not a new hue. Introducing a second accent color breaks the system.
## Typography
### Font Family
The system is monolingual on **Barlow** (with Noto Sans SC as the CJK fallback for identical role coverage). Every display, heading, lead, body, and caption token uses Barlow. The only secondary face is **IBM Plex Mono**, which is reserved entirely for chrome: slide numbers, kickers, tags, labels, captions in chart axes, bullet-list markers, image captions, and source notes. The contrast between Barlow's tight grotesque density and IBM Plex Mono's even monospace is the system's secondary typographic rhythm; the primary rhythm is Barlow's own weight and size axis.
Italic is not used. Underline is not used. The only emphasis mechanisms are weight, size, and color (orange accent on dark, or weight-only on orange).
### Display, Heading, and Body Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | 13vw | Barlow | 900 | Cover-scale display — the single dominant element on a slide where type *is* the composition |
| `{typography.fadelist-title}` | 10.5vw | Barlow | 900 | Oversized side-of-stage display in a fadelist composition |
| `{typography.quote-mark}` | 10vw | Barlow | 900 | The opening quotation glyph on a pull-quote slide |
| `{typography.h1}` | 7.5vw | Barlow | 800 | Chapter or section-opener title |
| `{typography.fadelist-item}` | 7.5vw | Barlow | 900 | Each stacked word in a three-stage fadelist treatment |
| `{typography.stat-value}` | 5.5vw | Barlow | 900 | Large data figure inside a stat card |
| `{typography.h2}` | 4.5vw | Barlow | 700 | Primary slide headline |
| `{typography.quote-text}` | 3.8vw | Barlow | 700 | Pull-quote body |
| `{typography.h3}` | 2.8vw | Barlow | 600 | Sub-headline or panel title inside a comparison |
| `{typography.lead}` | 1.6vw | Barlow | 400 | Lead paragraph, list items, prominent supporting copy |
| `{typography.body}` | 1.2vw | Barlow | 400 | Standard body paragraph |
| `{typography.caption}` | 0.9vw | Barlow | 400 | Image caption, footnote, source line |
| `{typography.label}` | 0.72vw | IBM Plex Mono | 500 | Chrome labels, kickers, tags, mono notes |
### Defaults
- **Default size for a primary content slide headline**: `{typography.h2}` (4.5vw).
- **Default size for a cover or chapter title**: `{typography.h1}` (7.5vw).
- **Default size for the single declarative display moment on a statement slide**: `{typography.display}` (13vw).
- **Default size for paragraph body**: `{typography.body}` (1.2vw); for the lead paragraph immediately following a headline, `{typography.lead}` (1.6vw).
- **Default size for any inline chrome element (label, kicker, tag, slide number, axis label)**: `{typography.label}` (0.72vw).
- **Default size for a hero numerical figure inside a stat card**: `{typography.stat-value}` (5.5vw).
- **Default weight for any Barlow display moment (h2 and above)**: 700+; for the largest display, 900.
- **Default weight for body**: 400.
When unsure, reach for `{typography.h2}` for the slide's primary text moment. `{typography.h1}` is reserved for chapter/section openers; `{typography.display}` for the rare moment where type is the entire composition.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **All Barlow display, heading, lead, and body text is set in sentence case (or true title case for proper nouns).** Uppercase Barlow at display weights does not exist in this system — it reads as a different design language entirely. The lowercase-display choice is the most distinctive single decision in Broadside.
- **All IBM Plex Mono chrome text is uppercase with at least 0.1em letter-spacing.** Mono labels, kickers, tags, slide numbers, axis labels, source notes, and bullet markers are always uppercase. The uppercase/lowercase split between Barlow body and mono chrome is the system's primary case rhythm.
- **All display tokens carry negative letter-spacing.** `{typography.display}` and `{typography.stat-value}` at -0.04em; `{typography.h1}` and `{typography.fadelist-title}` at -0.03em or -0.04em; `{typography.h2}` and `{typography.quote-text}` at -0.02em. Barlow at display weight without negative tracking reads as untreated.
- **All Barlow display elements run at weight 700, 800, or 900 — never lighter.** Lighter Barlow at display sizes loses the broadside density.
- **On orange slides, every Barlow display/h1/h2/h3 element is forced to `{colors.ink-black}`.** This is the "ink on fire" rule — cream-colored headlines on orange do not exist.
- **Every bulleted list item carries the orange `/` mono marker via `::before`.** Bullet discs, dashes, or numerals do not exist in this system.
- **Every kicker is uppercase IBM Plex Mono at `{typography.label}` size in `{colors.fire-orange}`** (or dark-ink-at-55%-opacity on orange).
### Typography Principles
The weight-900 + lowercase + negative-tracking + Barlow combination is the system's voice. Substituting uppercase, switching to weight 600, or removing the negative tracking each reads as a different system. The chrome's IBM Plex Mono uppercase + 0.14em-tracking is similarly inseparable.
Line-height collapses at scale: `{typography.display}` runs at 0.88, `{typography.h1}` at 0.9, `{typography.h2}` at 1.1, and only by `{typography.lead}` does it open to 1.5+. The compression at the top of the scale is what makes the display feel monolithic.
## Layout
### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Slides sit side-by-side in a horizontal `#deck` flexbox; navigation translates the deck container horizontally rather than swapping `display`. All sizes are viewport-relative (`vw` / `vh`) — there is no fixed 1920×1080 grid.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 5.5vw | Outer horizontal padding on every slide |
| `{spacing.pad-y}` | 5.5vh | Outer vertical padding on every slide |
| `{spacing.gap-lg}` | 3.5vh | Large vertical spacing between major blocks |
| `{spacing.gap-md}` | 2vh | Standard spacing between sibling elements |
| `{spacing.gap-sm}` | 1vh | Tight spacing — kicker to headline, chrome bar inner gap |
The padding is deliberately tighter than a generic editorial system. Broadside's massive type needs the slide's edge to feel close, not distant — the type is supposed to crowd the frame.
### Chrome Frame
The system has an optional chrome frame consisting of two horizontal hairline bars: a top `slide-chrome` bar (label left, slide number right) and a bottom `slide-foot` bar (mirror). Both are 1px solid borders in `{colors.border-dark}` on dark slides, or `rgba(17, 17, 17, 0.2)` on orange. Internal padding/margin uses `{spacing.gap-sm}` and `{spacing.gap-md}`.
The chrome is **suppressed entirely** on the system's "declarative" slide types — cover, chapter, statement, quote, and end. Those slides remove all chrome and let the type occupy the whole field. Content slides (split, stats, list, compare, chart, diagram) keep the chrome.
A separate `broadside-num` element (mono, ~1.1vw, low-opacity) may also be placed independently of the chrome bar as a catalogue-style slide number anchored at the top-left of orange cover/chapter slides.
## Depth and Elevation
### Flat Plane (Only Technique)
Broadside is entirely flat. There are no drop shadows, no inner shadows, no blurred elevations, no rounded surface gradients. Every element sits on a single plane.
Hierarchy is constructed from:
- **Type weight + size contrast** — the dominant signal.
- **1px hairline dividers** — `slide-chrome`/`slide-foot` borders, `stat-card` top borders, `compare-panel` dividers, `bar-track` left border, `chart-baseline` baseline.
- **Color shift** — orange against ink, ink against cream, cream-muted against cream.
- **Negative space** — generous padding and intentional empty regions.
Introducing a `box-shadow`, a card with elevation, or a soft gradient breaks the system. The flatness is the editorial signal.
## Shapes and Treatment
### Border Radius
Border radius is **0px everywhere** except `nav-dot` (50% — the tiny navigation circles at the bottom). Cards, panels, tags, image placeholders, stat cards, chart bars — all rectangles with sharp corners.
### Border Weights
- **1px solid** — the only structural weight. Used on `slide-chrome`, `slide-foot`, `stat-card` top, `compare-panel` divider, `bar-track` left edge, `chart-baseline`, image captions, the `rule.full` divider.
- **1px dashed** — used only on `img-placeholder` to signal "no image wired".
- **2px solid** — used only on the small `rule` accent stub (36px wide) and the `chapter-rule` mark.
All borders are either `{colors.border-dark}` (dark slides), `rgba(17, 17, 17, 0.2)` (orange slides), or `{colors.fire-orange}` (the tag border on dark slides).
### Decorative Element Types
**Stub accent rule** — A 36×2px solid bar in `{colors.fire-orange}` (on dark) or `{colors.ink-black}` (on orange). Used as a visual "section break" mark above a chapter title, above a stat, or beside a kicker. Functions as Broadside's only ornament.
**Mono catalogue number** — A small IBM Plex Mono numeral anchored top-left on cover/chapter slides at low opacity (`rgba(17, 17, 17, 0.45)` on orange, `{colors.cream-hint}` on dark). Reads as a publication catalogue mark.
**Stat card** — A top-border-only data block: 1px solid border on top, no other borders, padded body containing `{typography.stat-value}` (large orange numeral on dark; dark ink on orange) above `{typography.body}` (label) above `{typography.caption}` (mono note in `{colors.cream-hint}` or dark-faint).
**Compare panel pair** — Two equal-width panels divided by a 1px vertical border. The right panel may optionally be filled with `{colors.fire-orange}` (`compare-panel-orange`) as the "after" / payoff side; the left panel remains transparent over the dark canvas.
**Vertical bar chart** — A `bar-track` container with `border-left` only (no other axes), bars dropping from the top with `cream-hint` fill, one bar per chart carrying the `.accent` class for fire orange. Axis labels in mono uppercase below the baseline.
**Fadelist** — A SPACE10-style composition: three stacked Barlow-900 words at descending opacity (1.0 / 0.5 / 0.22) paired with one oversized display title on the opposite side of the slide. Used for "before / during / after" or "past / present / future" narratives.
**Pull quote** — An oversized fire-orange `{typography.quote-mark}` glyph (with line-height 0.6 so it sits on the baseline rather than below), followed by `{typography.quote-text}` capped at ~78% of the column width, followed by a two-line `quote-attr` with name above mono role/affiliation.
**Bordered mono tag** — A small inline pill in IBM Plex Mono uppercase with a 1px solid border, padded 0.3em vertical × 0.8em horizontal. The border and text are both `{colors.fire-orange}` on dark; dark ink at 40% opacity on orange.
## Do's and Don'ts
### Do
- Set every Barlow display, heading, lead, and body element in sentence case. Lowercase display is Broadside's most distinctive single choice.
- Use IBM Plex Mono uppercase at 0.1em+ tracking for every chrome element: slide numbers, kickers, labels, tags, axis labels, source notes, bullet markers.
- Make `{colors.fire-orange}` the singular accent on dark slides — kickers, accent stat values, bullet `/` markers, the leading chart bar, the opening quote mark, the `rule` stub.
- Make orange the *full background* on cover, chapter, and declarative-payoff slides. Use it as environment, not just accent, on those slide types.
- Cap bullet lists at three items. Broadside prizes density of impact over density of information.
- Apply negative letter-spacing on every Barlow display moment — -0.04em on the largest, -0.02em on h2.
- Use 1px hairline borders (`{colors.border-dark}` on dark, `rgba(17,17,17,0.2)` on orange) for all structural division. They are the system's only hierarchy chrome.
- Suppress slide-chrome and slide-foot on cover, chapter, statement, quote, and end slides — let the type breathe edge-to-edge.
- Place the `broadside-num` catalogue number top-left on orange cover/chapter slides as a publication-style mark.
- Use the `/` mono glyph in fire orange as the bullet marker on every list item.
### Don't
- Don't uppercase Barlow at display or heading weights. Uppercase Barlow at 13vw reads as a different design system entirely.
- Don't introduce a second accent color. Orange is *the* color — adding a blue, yellow, or green accent breaks the protest-poster identity.
- Don't add drop shadows, blurred elevations, or rounded surfaces. Broadside is strictly flat — depth comes from type and 1px lines.
- Don't use cream-colored text on orange slides. The "ink on fire" rule is absolute: orange slides use `{colors.ink-black}` for headlines and body.
- Don't pair Barlow with a serif companion. The single-typeface monolith is part of the identity.
- Don't use border-radius on cards, tags, panels, or stat blocks. The only round shapes in the system are the small nav dots.
- Don't pack more than one display moment into a slide. Broadside is for one statement, one rule, breathing room — not magazine-style layered composition.
- Don't render chrome elements in Barlow. Chrome is exclusively IBM Plex Mono uppercase.
- Don't introduce a third surface register. There are two: dark and orange. A cream/paper slide does not exist.
- Don't use italic or underline. Emphasis is achieved through weight, size, or orange color only.
## Responsive Behavior
This is a viewport-fluid 1920×1080 presentation system that uses `vw`/`vh` units throughout. There are no fixed pixel breakpoints. Every typography token, padding value, and component dimension scales linearly with the viewport.
### Scaling Behavior
- Display headline (`{typography.display}`) scales from ~138px at 1066-wide viewports to ~250px at 1920-wide.
- Body text (`{typography.body}`) scales from ~13px to ~23px across the same range.
- Outer padding (`{spacing.pad-x}` 5.5vw) scales from ~59px to ~106px.
- All borders are fixed at 1px or 2px and do not scale.
### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, `Space`, or `PageDown`.
- Slides reverse via `ArrowLeft`, `ArrowUp`, or `PageUp`.
- Navigation translates the deck container horizontally with a `cubic-bezier(0.77, 0, 0.175, 1)` ease at 0.8s.
- Per-element entry animations (`data-anim="fade-up"`, `fade-in`, `reveal-right`, `reveal-left`, `scale-in`) replay every time a slide becomes `.is-active`, staggered by `data-delay` (0 through 6).
- Nav dots at bottom-center, mono slide counter at bottom-right.
### Print / Export
Not explicitly handled by the source. Each slide is a `100vw × 100vh` block; export workflows should target 1920×1080 PNG/PDF per slide.
## CJK & International Content
When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.
### Recommended Chinese Pairing
| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| Display / h1 / h2 / h3 / stat-value / quote / fadelist | Barlow 700–900 (lowercase, negative tracking) | 思源宋体 Noto Serif SC 900 |
| Lead / body / caption | Barlow 400 | 霞鹜文楷 LXGW WenKai 400 |
| Label / kicker / tag / slide number / bullet marker | IBM Plex Mono 500 (uppercase, 0.14em tracking) | 思源黑体 Noto Sans SC 500 (no transform, no tracking) |
### Mixed-Content Strategy
**Strategy A** — single CJK family per role with Latin glyph coverage built in. Use **思源宋体 Noto Serif SC** weight 900 for every display and heading role; use **霞鹜文楷 LXGW WenKai** weight 400 for body and lead text; use **思源黑体 Noto Sans SC** weight 500 for chrome (kickers, labels, slide numbers, bullet markers). All three faces ship Latin glyphs that pair cleanly with Chinese characters. The serif/handwritten/sans contrast loosely echoes Broadside's display/body/mono distinction even though the source uses Barlow throughout.
### Loading
Add to the template's `<head>`:
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;700;900&family=Noto+Sans+SC:wght@400;500&family=LXGW+WenKai+TC&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (up from 1.6), display 1.15–1.25 (up from the very tight 0.88–0.9 used on Barlow display). The Latin template compresses display to 0.6 on the quote-mark token; at that compression CJK characters overlap entirely. Open display to 1.0 minimum.
- **Letter-spacing**: set to 0 on every CJK run. The template's −0.02 to −0.04em negative tracking on Barlow display overlaps CJK strokes; the +0.14em positive tracking on IBM Plex Mono chrome reads as gappy on square glyphs.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. Every IBM Plex Mono label, kicker, tag, slide number, and bullet marker uses `text-transform: uppercase` in the Latin original; remove for CJK runs.
- **Punctuation**: use full-width Chinese punctuation (,。:;!?「」()).
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines. Especially important for Broadside's massive display moments — a trailing 。 at 13vw is visually disruptive.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `2024 大字海报` not `2024大字海报`.
- **One font per sentence**: 思源宋体 covers both CJK and Latin glyphs in a unified serif style for display; 霞鹜文楷 covers both for body. Don't let the browser fall back to Barlow mid-word for ASCII characters in a Chinese sentence.
### Aesthetic Notes for This System
Broadside's most distinctive single decision is **lowercase Barlow at weight 900 at 13vw display sizes**. The lowercase-display choice is what separates this system from generic brutalist decks. In CJK that signal disappears entirely — Chinese has no case. The system compensates because its identity is **80% structural + color**: the two-register surface system (dark / orange), the singular fire-orange accent, the flat plane, the 1px hairline dividers, the `/` mono bullet markers, the suppressed chrome on declarative slides, and the negative-space-as-composition philosophy all transfer cleanly.
The closest Chinese face to Barlow's "monolithic heavy grotesque" register is **思源宋体 weight 900** — but a serif heavy display rather than a sans heavy display. This is a deliberate register shift: heavy Chinese serif at protest-poster scale reads as "broadside printed-poster" (the system's actual cultural reference) more credibly than heavy Chinese sans, which reads more "corporate signage." For the body face, **霞鹜文楷 LXGW WenKai** brings a handwritten/calligraphic warmth that pairs with the editorial-protest register; if a more institutional body is needed, swap to 思源宋体 400.
Keep the chrome's "stamped metadata" voice by maintaining the small font size (0.72vw equivalent) and the orange color on kickers/labels. The IBM Plex Mono uppercase + tracked treatment loses both signals in CJK, but the orange color carries enough chrome-recognition on its own. The `/` bullet marker can stay as a Latin slash character even in Chinese contexts — it's a graphic mark, not a language element.
### Known CJK Gap
- **No CDN Chinese face matches Barlow's monolithic grotesque + lowercase identity.** Barlow's distinctive choice in this system is lowercase-display at heavy weights — and CJK has no equivalent expressive lever. The system's "protest-poster lowercase-shouting" character softens to "heavy-serif declarative." The two-register color system (dark / orange) and the singular fire-orange accent carry the protest-poster identity on their own.
- **No CDN Chinese monospace face for the chrome voice.** IBM Plex Mono's role (kickers, labels, slide numbers, `/` bullet markers) depends on monospaced rhythm + uppercase + 0.14em tracking. 思源黑体 weight 500 at 0 tracking is the closest match but loses the "catalogue mark" signal. Keep the orange color and the small font size; the color and scale do the chrome-recognition work.
- **霞鹜文楷 may not load on restricted networks.** The Google Fonts CDN serves the Traditional Chinese variant (LXGW WenKai TC) reliably; the Simplified variant is also available via cn-fontsource. Always include `'Noto Serif SC', serif` in the body stack as fallback.
- **The quote-mark glyph at 10vw with line-height 0.6 is a Latin-quote convention.** Chinese typography uses 「」 or 『』 framing rather than oversized opening-quote glyphs. For Chinese pull-quotes, consider replacing the oversized fire-orange quote-mark with a full-width 「 character at 8vw, or dropping the decorative quote glyph entirely and relying on the orange color + larger size to signal "this is a quoted passage."
## Iteration Guide
1. Every new content slide opens with a `kicker` in mono uppercase fire orange, followed by `{typography.h2}` headline in Barlow lowercase. Don't skip the kicker — it is the system's content-slide chrome signal.
2. Every cover, chapter, statement-payoff, or end slide uses the orange register. Don't use orange for content/data slides — orange is for declaration moments.
3. New stat cards use the `stat-card` top-border-only pattern with `{typography.stat-value}` in orange (on dark) or ink (on orange). Don't bottom-border or fully-border stat cards.
4. New bullet lists use the `/` mono marker in fire orange. Cap at three items.
5. New charts use the `bar-track` vertical-bar pattern with one accent bar per chart in fire orange; remaining bars in `{colors.cream-hint}`.
6. New quotes use the oversized fire-orange `{typography.quote-mark}` opening glyph, followed by `{typography.quote-text}` at max 78% width.
7. Headlines on orange slides are always `{colors.ink-black}`. There are no cream headlines on orange.
8. New tags use `tag` styling: 1px fire-orange border + fire-orange mono uppercase text on dark; dark-ink at 40% opacity on orange.
9. The system has nine canonical layout patterns — cover, chapter, statement, split, stats, quote, list, compare, end — plus fadelist, chart, and diagram extensions. New layouts should respect the chrome/no-chrome rule based on whether the slide is declarative or content-bearing.
## Known Gaps
- Broadside's `.light` slide class is intentionally overridden to dark — the source comments confirm "there are no cream/white slides." Any attempt to use `.light` will fall back to the dark register.
- Noto Sans SC is in every font stack as the CJK fallback but the system was not designed with mixed Latin/CJK headlines in mind; line-height behavior on CJK display sizes may need per-slide adjustment.
- The bullet marker glyph (`/`) is set in IBM Plex Mono via `::before` — replacing it with a different glyph requires editing CSS, not markup.
- The bar chart `bar-fill` heights are inline-styled via `style="height: NN%"` in the source; there is no data-binding layer.
- The fadelist and bar-chart layouts are not in the canonical "9 layout patterns" comment block; they are extensions added beyond the documented system.
- Image placeholders use a dashed `{colors.border-dark}` border and a mono uppercase label — replace with a real `<img src>` at the same 55vh height to maintain layout.
- The `c-fg-light` token exists in the palette (`#111111`) for "light theme primary text" but since the light theme is suppressed, this token is effectively unused in the rendered output.
- The system loads three Google Fonts families (Barlow, IBM Plex Mono, Noto Sans SC) with multiple weights — initial render requires successful font load to avoid Times New Roman fallback.
# Broadside Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/broadside/design.md`
- Preview card: `bold-template-pack/templates/broadside/preview.md`
## Selection Metadata
- Slug: `broadside`
- Tagline: Dark editorial canvas with a single fire orange accent and bilingual Latin/Chinese type stack.
- Mood: editorial, dramatic, loud, newspaper
- Tone: graphic, punchy, literary, considered
- Formality: medium-high
- Density: medium
- Scheme: dark
- Best for: Anything that should land like a broadside newspaper headline: brand manifestos, magazine and cultural pitches, design talks, bilingual EN/CN decks, founder vision statements. Also a striking pick for tech, research, or business decks that want a dramatic single-accent editorial feel.
- Avoid for: Decks that need to feel quiet, warm, or institutionally traditional — the dark canvas with fire-orange accent commits to drama.
## Visual Snapshot
A protest-poster editorial system built on massive Barlow type and a single fire-orange environment color. The aesthetic is "ink on fire" — dark slides for documentation, orange slides for declaration. Display type is enormous (13vw, roughly 187px at 1440 width) in weight 900 lowercase, treating words as graphic elements rather than reading copy. The cultural reference is broadside printing, SPACE10 reports, and Wim Crouwel grids reinterpreted with one loud color and zero decoration.
Broadside is a protest-poster editorial system. The defining premise: type is so large it stops behaving as text and starts behaving as graphic primitive. Display sizes at 13vw ({typography.display}) put a single word at roughly 187px on a 1440-wide screen — wide enough that the eye scans letterforms before reading. This is the system's primary expressive instrument.
## Preview Ingredients
- Palette: ink-black #111111; ink-black-alt #1A1A18; fire-orange #E85D26; cream #F0ECE5; cream-muted #888880; cream-hint #505048; border-dark #282826
- Typography: Barlow; IBM Plex Mono; {typography.label.fontFamily}
- Signature move: Massive Barlow display type at weight 900 in lowercase — never uppercase on display elements.
- Signature move: Two-register color system: dark slides with cream text, or orange slides with dark ink. No cream/white slides exist.
- Signature move: {colors.fire-orange} is both accent (on dark) and environment (on orange) — never a secondary color, always *the* color.
- Signature move: Single-typeface system on Barlow + IBM Plex Mono for chrome only. No serif, no script, no third face.
- Signature move: 1px hairline dividers ({colors.border-dark} on dark; rgba(17,17,17,0.2) on orange) provide all hierarchy structure.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Capsule
description: A playful editorial system built on pill-shaped containers, a sun-bleached cream canvas, and a nine-color candy palette. Bodoni Moda serif headlines pair with Space Grotesk body to suggest a literary magazine that took a holiday at a 1970s ice-cream parlor. Every container that holds text is a pill (border-radius 9999px) outlined with a 2px ink stroke, casting a soft 6–12px offset shadow. The aesthetic is "Memphis-meets-editorial" — confident typography, generous bordered shapes, and decorative floating pills as atmospheric wallpaper.
colors:
cream: "#F5F5F0"
ink: "#1A1A1A"
outline: "#1E1E1E"
white: "#FFFFFF"
coral: "#E85D4E"
lime: "#C4D94E"
lavender: "#C5B5E0"
sky: "#8BB4F7"
violet: "#A06CE8"
yellow: "#F2D160"
peach: "#F5B895"
mint: "#A8E6CF"
shadow: "rgba(26, 26, 26, 0.08)"
color-aliases:
bg: cream
fg: ink
outline: outline # same hue family as ink; reserved for stroke role
typography:
display:
fontFamily: "Bodoni Moda, serif"
fontSize: "clamp(3rem, 8vw, 7rem)"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.02em
closing-display:
fontFamily: "Bodoni Moda, serif"
fontSize: "clamp(2.5rem, 6vw, 5rem)"
fontWeight: 800
lineHeight: 0.95
letterSpacing: -0.03em
headline:
fontFamily: "Bodoni Moda, serif"
fontSize: "clamp(2rem, 4vw, 3.5rem)"
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.02em
section-headline:
fontFamily: "Bodoni Moda, serif"
fontSize: "clamp(1.8rem, 3.5vw, 3rem)"
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.01em
quote-display:
fontFamily: "Bodoni Moda, serif"
fontSize: "clamp(1.6rem, 3.5vw, 3rem)"
fontWeight: 600
lineHeight: 1.35
letterSpacing: -0.01em
card-headline:
fontFamily: "Bodoni Moda, serif"
fontSize: "1.5rem"
fontWeight: 700
lineHeight: 1.1
stat-number:
fontFamily: "Bodoni Moda, serif"
fontSize: "clamp(2rem, 3.5vw, 3rem)"
fontWeight: 800
lineHeight: 1
letterSpacing: -0.03em
orbit-numeral:
fontFamily: "Bodoni Moda, serif"
fontSize: "2.5rem"
fontWeight: 700
lineHeight: 1
body:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "clamp(0.95rem, 1.2vw, 1.15rem)"
fontWeight: 400
lineHeight: 1.6
body-sm:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.9rem"
fontWeight: 400
lineHeight: 1.55
subtitle:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "clamp(0.8rem, 1.5vw, 1.1rem)"
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0.15em
textTransform: uppercase
pill-text-md:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.85rem"
fontWeight: 600
lineHeight: 1
letterSpacing: 0.12em
textTransform: uppercase
pill-text-sm:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.7rem"
fontWeight: 600
lineHeight: 1
letterSpacing: 0.1em
textTransform: uppercase
label:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.75rem"
fontWeight: 500
lineHeight: 1
letterSpacing: 0.1em
textTransform: uppercase
mini-label:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.65rem"
fontWeight: 500
lineHeight: 1
letterSpacing: 0.08em
textTransform: uppercase
spacing:
pad-lg: "3rem 4rem"
pad-md: "2rem"
gap-xl: "4rem"
gap-lg: "3rem"
gap-md: "2rem"
gap-sm: "1.5rem"
gap-xs: "0.75rem"
card-pad: "2.5rem 2rem"
pill-pad-lg: "1.5rem 3.5rem"
pill-pad-md: "1rem 2.5rem"
pill-pad-sm: "0.4rem 1.2rem"
pill-pad-xs: "0.35rem 1rem"
canvas:
width: 100vw
height: 100vh
components:
pill:
borderRadius: 9999px
border: "2px solid {colors.outline}"
fontFamily: "Space Grotesk, sans-serif"
fontWeight: 500
letterSpacing: 0.02em
whiteSpace: nowrap
description: "The universal container shape. Any text container — chip, button, label, statement-highlight, stat tile, card, bar — is a pill with 2px outline. Background can be any palette accent or white."
pill-card:
background: "{colors.white}"
border: "2px solid {colors.outline}"
borderRadius: "2rem"
padding: "{spacing.card-pad}"
boxShadow: "8px 8px 0 {colors.shadow}"
description: "Larger pill-shaped card (slightly squared corners at 2rem rather than full pill) for content blocks. Always white background, always shadowed."
stat-pill:
background: "{colors.white}"
border: "2px solid {colors.outline}"
borderRadius: "2rem"
padding: "2rem 1.5rem"
boxShadow: "6px 6px 0 {colors.shadow}"
description: "Stat tile — pill-shaped white card containing a colored stat number, label, and a tiny accent bar."
bar-track:
height: 36px
background: "{colors.cream}"
border: "2px solid {colors.outline}"
borderRadius: 9999px
overflow: hidden
description: "Horizontal bar chart track shaped as a pill. Fills use the candy palette."
bar-fill:
height: "100%"
borderRadius: 9999px
borderRight: "2px solid {colors.outline}"
description: "Inner bar pill with the value label printed at right edge inside the fill."
accent-line:
width: 60px
height: 4px
background: "{colors.coral}"
borderRadius: 9999px
description: "Pill-shaped 60×4 accent rule. Default color coral; closing-context variant uses 80×4."
card-icon:
width: 60px
height: 60px
borderRadius: "50%"
border: "2px solid {colors.outline}"
fontFamily: "Bodoni Moda, serif"
fontSize: "1.5rem"
fontWeight: 700
description: "Circular pill icon (60px) used as a card mark. Background is an accent color; contains a 1–3 character Roman numeral or letter."
step-node:
width: 56px
height: 56px
borderRadius: "50%"
border: "2px solid {colors.outline}"
background: "{colors.white}"
fontFamily: "Bodoni Moda, serif"
fontSize: "1.3rem"
fontWeight: 700
boxShadow: "4px 4px 0 {colors.shadow}"
description: "Circular pill node (56px) used as a timeline step or sequence marker. Step accent color appears as filled-pill class on the node."
orbit-center:
width: 160px
height: 160px
borderRadius: "50%"
background: "{colors.lime}"
border: "2px solid {colors.outline}"
fontFamily: "Bodoni Moda, serif"
fontSize: "2.5rem"
fontWeight: 700
description: "Large circular pill (160px) used as the gravitational anchor of an orbit composition. Default fill lime; small satellite pills orbit around it."
diagram-node:
borderRadius: 9999px
border: "2px solid {colors.outline}"
padding: "1rem 2rem"
boxShadow: "6px 6px 0 {colors.shadow}"
background: "{colors.white}"
description: "Flow-diagram node — pill-shaped container with shadow. Connected by 50×4 ink connectors with triangular arrowheads."
diagram-connector:
width: 50px
height: 4px
background: "{colors.outline}"
description: "Solid 50×4 ink bar with a triangular arrowhead at the right end, connecting two diagram nodes inline."
visual-frame:
borderRadius: "2rem"
border: "2px solid {colors.outline}"
boxShadow: "12px 12px 0 {colors.shadow}"
description: "Large image/illustration frame — slightly squared pill (2rem radius) with thicker 12px offset shadow. Often filled with a tri-stop linear gradient and a dot-pattern overlay."
grain-overlay:
position: fixed
inset: 0
pointerEvents: none
zIndex: 9999
opacity: 0.04
mixBlendMode: multiply
backgroundImage: "fractalNoise SVG"
description: "Subtle film-grain noise overlay applied to the entire viewport at 4% opacity in multiply blend mode. Always present, never absent."
radial-glow:
description: "Soft radial gradient wash anchored to a corner or center of a slide background. Uses one of the candy palette colors at 6–15% opacity, blended into the cream canvas. Provides atmospheric warmth without changing the surface color."
---
## Frontend Slides Fixed-Stage Policy
When this design system is used by the `frontend-slides` skill, generate the final deck as a **fixed 1920×1080 stage** that scales uniformly to the browser viewport. The deck should preserve a 16:9 slide canvas on every screen, including phones; it may letterbox or pillarbox, but it should not reflow slide content for mobile.
This policy has higher priority than any source-template responsive behavior described later in this file. If a later section says the original template is viewport-fluid, treat that as source history only, not as the target generation model for `frontend-slides`.
This policy applies even if the source template was originally implemented with viewport-fluid CSS such as `100vw`, `100vh`, `vw`, `vh`, or `clamp()`. Treat those values as design proportions to translate into 1920×1080 stage coordinates, not as live responsive rules in the generated deck.
Use `deck-stage.js` or an equivalent inline stage scaler for final output: render each slide at 1920×1080, scale the whole stage with one transform, and verify rendered screenshots for both text overflow and panel overlap.
## Overview
Capsule is a **playful editorial system** whose defining structural premise is the **pill**: every text container is a pill, every icon is a pill, every bar is a pill, every node in a diagram is a pill. The `border-radius: 9999px` rule applies to virtually all UI elements, with larger panels softening to a 2rem radius. Combined with the 2px ink outline that wraps every shape, the result is a system where containers feel inflated, friendly, and graphically distinct — a nod to Memphis design and late-70s ice-cream-parlor signage without abandoning editorial discipline.
The typeface stack is a deliberate two-face conversation. **Bodoni Moda** — a high-contrast didone serif — carries every display moment, every section headline, every stat numeral, every card title, every quote. Bodoni's tall capitals and thin-thick stroke contrast give the headlines their editorial weight and a touch of fashion-magazine glamour. **Space Grotesk** — a contemporary geometric sans — carries every body paragraph, every label, every pill text, every subtitle. The serif/grotesk pairing creates the system's primary typographic rhythm: glamorous serif statements + clean grotesk supporting structure.
The palette runs nine colors plus three neutrals. The canvas is `{colors.cream}` — a warm sun-bleached off-white that signals "magazine paper" rather than "screen white." The ink is `{colors.ink}`, used for body text, headlines, and the universal outline. The seven candy accents — `{colors.coral}`, `{colors.lime}`, `{colors.lavender}`, `{colors.sky}`, `{colors.violet}`, `{colors.yellow}`, `{colors.peach}`, plus `{colors.mint}` — are interchangeable. They fill pills, color stat numbers, fill bar charts, and float as decorative atmosphere. There is no semantic mapping: no color means "warning," none means "success." Each accent is chosen for compositional balance, not meaning.
Depth comes from **soft hard-offset shadows** at 4px, 6px, 8px, and 12px in a low-opacity ink color (`{colors.shadow}` = `rgba(26, 26, 26, 0.08)`). Unlike a true brutalist shadow, these are slightly transparent — they read as "lifted" rather than "stamped." Combined with the 2px outline, every pill feels like it's floating just above the cream canvas. There is no use of blurred drop shadows; the offset is always solid, always to the bottom-right.
**Density philosophy: medium-high atmospheric.** Capsule slides feel populated. The system is built around the idea that decorative floating pills should orbit the actual content as wallpaper — small colored pills tilted at 5–25° rotations across the slide background, each containing a single uppercase word. These atmospheric pills are non-functional; they are typographic confetti. A correctly composed slide pairs one or two substantive content blocks (a pill-card, a stat grid, a diagram) with 5–8 floating decorative pills around the edges. A slide that feels broken in Capsule is one with empty corners or unrelieved cream space — the candy palette wants to participate even where the content doesn't strictly require it.
**Key Characteristics:**
- Universal pill geometry — `border-radius: 9999px` for small containers, 2rem for larger cards/frames.
- 2px solid `{colors.outline}` stroke wraps every pill, icon, and card.
- Bodoni Moda serif for every display/headline/stat; Space Grotesk sans for every body/label/pill text.
- Sun-bleached cream canvas `{colors.cream}` with soft radial glows in candy accent colors at 6–15% opacity for background atmosphere.
- Hard-offset shadows in low-opacity ink (`{colors.shadow}`) at 4/6/8/12px offsets, always solid, always bottom-right.
- Nine-color candy accent palette used interchangeably — no semantic mapping.
- Decorative floating pills tilted at 5–25° rotations populate slide backgrounds as atmospheric wallpaper.
- A persistent fractal-noise grain overlay (4% opacity, multiply blend) sits over the entire viewport at all times.
- Full-screen vertical nav-dot column at right, mono slide counter at bottom-right.
## Colors
### Canvas & Ink
- **Cream** (`{colors.cream}` — #F5F5F0): The canvas. Warm sun-bleached off-white. Used as default slide background, default bar-track interior, and any neutral region that wants paper warmth without being pure white.
- **Ink** (`{colors.ink}` — #1A1A1A): The primary text color. Used for headlines, body, and (under the alias `outline`) the universal stroke.
- **Outline** (`{colors.outline}` — #1E1E1E): Functionally identical to ink; reserved as the stroke color on every pill, card, icon, and frame for semantic clarity.
- **White** (`{colors.white}` — #FFFFFF): True white. Used as the default fill for pill-cards, stat-pills, diagram nodes, and any pill that needs the highest contrast against the cream canvas. White pills always carry the 2px ink outline.
### Candy Accents
- **Coral** (`{colors.coral}` — #E85D4E): Warm orange-red. The most "voice-y" of the accents; used as a default accent-line color, default pill-card icon fill on the first card in a sequence, and the most frequent stat-number color.
- **Lime** (`{colors.lime}` — #C4D94E): Vivid chartreuse-green. Pairs well with coral; default fill for orbit-center anchors and frequent stat-number color.
- **Lavender** (`{colors.lavender}` — #C5B5E0): Soft lilac-purple. Used as a calming pill fill in headers and as a frequent quote-highlight color.
- **Sky** (`{colors.sky}` — #8BB4F7): Mid-saturation cornflower blue. The default "third accent" — sits comfortably next to coral and lime in a 3-card grid.
- **Violet** (`{colors.violet}` — #A06CE8): Deeper purple. Used when a slide already has lavender as one accent and needs a second purple-family pop.
- **Yellow** (`{colors.yellow}` — #F2D160): Warm marigold. The default fill for title pills, closing pills, and any pill that should read as "important / featured."
- **Peach** (`{colors.peach}` — #F5B895): Pale apricot. The softest accent; used in floating decorative pills and circular decorative spots.
- **Mint** (`{colors.mint}` — #A8E6CF): Pale aqua-green. Used most often inside the linear-gradient visual frame and in lower-emphasis decorative pills.
- **Shadow** (`{colors.shadow}` — `rgba(26, 26, 26, 0.08)`): The universal soft hard-offset shadow color. Never use a different shadow color.
### Defaults
- **Default slide surface**: `{colors.cream}`.
- **Default headline color**: `{colors.ink}` — Bodoni serif headlines are always ink, never colored. Color appears only on stat numerals and inside accent pills.
- **Default body text color**: `{colors.ink}` rendered at opacity 0.6–0.7 to soften it against the cream canvas.
- **Default outline color**: `{colors.outline}` (≈ ink) — 2px on every pill/card/icon, no exceptions.
- **Default card fill**: `{colors.white}`.
- **Default accent-line color**: `{colors.coral}`.
- **Default title-pill fill**: `{colors.yellow}`.
- **Default closing-pill fill**: `{colors.yellow}`.
- **Default orbit-center fill**: `{colors.lime}`.
- **Default first accent in a 3- or 4-accent sequence**: coral → lime → sky → violet (rotated when more colors are needed). The sequence is the system's "Roy G. Biv"; it gives the agent a deterministic order to reach for so the candy palette doesn't feel random.
- **Default decorative pill background opacity**: full saturation (no fading). The floating pills are loud on purpose.
Accent colors have no semantic role. Choose accents based on warm/cool balance and adjacency, not meaning. When three accents appear together, pair a warm (coral/yellow/peach) with a cool (sky/lavender/violet/mint) with a neutral-bright (lime). Avoid placing two same-family accents adjacent (two purples, two greens, two warms).
## Typography
### Font Family
The system runs on a **two-face conversation**: `Bodoni Moda` (serif, weights 400–900, opsz axis) carries every display and headline; `Space Grotesk` (sans, weights 300–700) carries every body, label, and pill text. There is no third face. Both families are loaded from Google Fonts at variable-axis weights.
Bodoni Moda's high contrast and didone modulation give the system its editorial-glamour register; the thin-thick stroke contrast is most pronounced at large sizes, so display weights should always be 700+ to maintain stroke presence. Space Grotesk's geometric grotesque carries clean, modern body — it never tries to compete with the Bodoni headlines.
An inline `<em>` inside a Bodoni headline keeps Bodoni and shifts to italic. A `quote-highlight` inside a Bodoni quote body switches the wrapped word to a pill (Space Grotesk uppercase pill text on a candy fill) for visual emphasis.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | clamp(3rem, 8vw, 7rem) | Bodoni Moda | 800 | Largest cover/title display |
| `{typography.closing-display}` | clamp(2.5rem, 6vw, 5rem) | Bodoni Moda | 800 | Conclusive declarative headline |
| `{typography.headline}` | clamp(2rem, 4vw, 3.5rem) | Bodoni Moda | 700 | Primary slide headline on split or two-column layouts |
| `{typography.section-headline}` | clamp(1.8rem, 3.5vw, 3rem) | Bodoni Moda | 700 | Section-opening or centered headline above cards/charts |
| `{typography.quote-display}` | clamp(1.6rem, 3.5vw, 3rem) | Bodoni Moda | 600 | Pull-quote body |
| `{typography.card-headline}` | 1.5rem | Bodoni Moda | 700 | Card or pillar-block title |
| `{typography.stat-number}` | clamp(2rem, 3.5vw, 3rem) | Bodoni Moda | 800 | Large numerical stat figure |
| `{typography.orbit-numeral}` | 2.5rem | Bodoni Moda | 700 | Centered ordinal inside the orbit-center circle |
| `{typography.body}` | clamp(0.95rem, 1.2vw, 1.15rem) | Space Grotesk | 400 | Paragraph body |
| `{typography.body-sm}` | 0.9rem | Space Grotesk | 400 | Compact body inside a card |
| `{typography.subtitle}` | clamp(0.8rem, 1.5vw, 1.1rem) | Space Grotesk | 400 | Uppercase tracked subtitle below a display headline |
| `{typography.pill-text-md}` | 0.85rem | Space Grotesk | 600 | Text inside title/closing pills |
| `{typography.pill-text-sm}` | 0.7rem | Space Grotesk | 600 | Text inside small floating decorative pills |
| `{typography.label}` | 0.75rem | Space Grotesk | 500 | Header tag pills, attribution lines |
| `{typography.mini-label}` | 0.65rem | Space Grotesk | 500 | Mini-pill chips in a tag cluster |
### Defaults
- **Default size for the primary section headline**: `{typography.section-headline}` (clamp 1.8–3rem). For two-column or split layouts, `{typography.headline}` (clamp 2–3.5rem).
- **Default size for a cover or opening display moment**: `{typography.display}` (clamp 3–7rem).
- **Default size for paragraph body**: `{typography.body}` (clamp 0.95–1.15rem).
- **Default size for any inline label or chip**: `{typography.label}` (0.75rem).
- **Default weight for any Bodoni display element**: 700 minimum; 800 for the largest display.
- **Default weight for any Space Grotesk body element**: 400.
- **Default size for a hero stat figure**: `{typography.stat-number}` (clamp 2–3rem).
When unsure, reach for `{typography.section-headline}` for the slide's primary text moment, not `{typography.card-headline}` (which is for block-level titles within a card).
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every display, headline, stat-number, card-headline, and quote-display element is set in Bodoni Moda.** Space Grotesk does not appear in any display role.
- **Every body, subtitle, pill-text, label, and chip element is set in Space Grotesk.** Bodoni does not appear in body or chip roles.
- **Every Bodoni display element uses negative letter-spacing** (-0.01em to -0.03em). Bodoni at large sizes with default tracking reads loose.
- **Every Space Grotesk subtitle, label, pill-text, and chip element is uppercase with 0.08em+ tracking.** The uppercase + tracking is the small-text identity signal.
- **Bodoni headlines are always rendered in `{colors.ink}`, never in a candy color.** Color appears on stat numerals (e.g., `color: {colors.coral}`) but not on serif headlines. The exception is the orbit-center numeral, which sits inside a colored circular pill but the numeral itself remains ink.
- **Every pill element carries the 2px solid outline.** A pill without its 2px ink stroke breaks the system.
- **Every container with `border-radius: 9999px` or `2rem` carries either the 2px outline or sits inside an already-outlined parent.** Unoutlined rounded containers do not exist.
- **Every card or elevated pill carries a hard-offset shadow** at 4/6/8/12px in `{colors.shadow}`. Smaller pills get 4–6px; cards get 8px; visual frames get 12px.
### Typography Principles
The Bodoni-headline + Space-Grotesk-body pairing is the primary rhythm; switching either face breaks the system. Italic appears only inside pull-quote bodies via the `<em>` tag (Bodoni italic). Underline is not used. Pill-encapsulation is the system's primary emphasis mechanism: wrapping a phrase in a candy-filled pill is the equivalent of bold-italicizing it in a traditional editorial system.
Line-height tightens at scale: `{typography.display}` at 0.9, `{typography.headline}` at 1.05, body at 1.6. The tight display + open body contrast is what gives the system its editorial breathing rhythm.
## Layout
### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Each `.slide` is absolutely positioned to fill the viewport, with one slide carrying `.active` (opacity 1) at a time. Transitions are 0.6s opacity fades via `cubic-bezier(0.4, 0, 0.2, 1)`. All sizes use rem units inside CSS `clamp()` so the layout scales fluidly.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-lg}` | 3rem 4rem | Default slide outer padding |
| `{spacing.gap-xl}` | 4rem | Major two-column gutter |
| `{spacing.gap-lg}` | 3rem | Section-block spacing |
| `{spacing.gap-md}` | 2rem | Standard inter-element spacing |
| `{spacing.gap-sm}` | 1.5rem | Tight card-internal spacing |
| `{spacing.gap-xs}` | 0.75rem | Inline gap between mini-pills |
| `{spacing.card-pad}` | 2.5rem 2rem | Default pillar-card padding |
| `{spacing.pill-pad-lg}` | 1.5rem 3.5rem | Title-pill / closing-pill padding |
| `{spacing.pill-pad-md}` | 1rem 2.5rem | Featured pill padding |
| `{spacing.pill-pad-sm}` | 0.4rem 1.2rem | Header-tag pill padding |
| `{spacing.pill-pad-xs}` | 0.35rem 1rem | Mini-pill chip padding |
### Atmospheric Background Layer
Every slide layers two atmospheric treatments on top of the cream canvas:
1. **Radial glows** — one to three soft `radial-gradient(ellipse at X% Y%, rgba(accent, 0.06–0.15), transparent)` washes anchored to corners or center. These tint the canvas warmly without changing its surface color.
2. **Grain overlay** — a fractal-noise SVG fixed at `inset: 0`, opacity 0.04, mix-blend-mode multiply, z-index 9999. Always present, always identical, never removed.
These are not decorative options; they are baseline canvas treatments that should appear on every slide.
### Decorative Pill Wallpaper
A signature: small decorative pills (60–160px wide, 35–90px tall) tilted at -20° to +25° rotations are placed absolutely on slide backgrounds as atmospheric typographic confetti. Each contains a single uppercase Space-Grotesk word and a candy fill. Some are circular (border-radius 50%) instead of capsule-shaped. They have no informational role — they are visual atmosphere. Typical count: 5–8 per slide on cover/closing/quote layouts; 0 on dense data layouts.
## Depth and Elevation
### Soft Hard-Offset Shadow
The system's only depth technique is a **solid hard-offset shadow** in low-opacity ink:
- **4px 4px 0** — small elevated nodes (step nodes, small pills).
- **6px 6px 0** — orbit pills, stat-pills, diagram nodes.
- **8px 8px 0** — pillar-cards, chart container.
- **12px 12px 0** — large visual frame (the most lifted element in the system).
All shadows use `{colors.shadow}` (`rgba(26, 26, 26, 0.08)`). The opacity is the key distinction from a brutalist hard shadow: at 8% the shadow reads as a soft lift rather than a stamped offset. The offset direction is always bottom-right.
### Outline-Based Depth
Most apparent depth comes from the 2px ink outline that wraps every pill against the cream canvas. The outline does much of the elevation work; the shadow adds the lift on cards and elevated pills.
### Flat Decorative Layer
Decorative floating pills and radial glows are flat — they cast no shadow. The shadow is reserved for content-bearing containers (cards, stat tiles, diagram nodes, visual frames). This visual rule separates "content" from "atmosphere" at a glance.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 9999px (full pill) | All small pills: title pill, closing pill, decorative pills, header tags, mini chips, bar tracks, bar fills, accent lines, orbit pills, floating pills, quote highlights, diagram nodes |
| 2rem (32px) | Larger cards: pillar-cards, stat-pills, chart container, visual frame |
| 1.5rem (24px) | Inner dashed frame inside the visual frame |
| 50% (circle) | Circular pills: card-icon (60px), step-node (56px), orbit-center (160px), nav dots (10px) |
| 0 | The grain overlay; the slide itself; the candy-color gradient regions inside a visual frame |
The system has **no sharp-cornered text containers**. Every container that holds text or icon content is rounded.
### Border Weights
- **2px solid `{colors.outline}`** — the universal stroke. Used on every pill, card, icon, frame, bar track, nav dot.
- **2px dashed `{colors.outline}`** — used only on the inner frame inside the visual-frame component (a decorative interior border indicating "image placeholder").
- **4px solid ink** — used only on the timeline-line that connects sequential step nodes horizontally.
All borders are `{colors.outline}`. Colored borders do not exist in the system.
### Decorative Element Types
**Decorative floating pill** — A small (60–160px wide × 35–90px tall) pill or circle in a candy fill, tilted at -20° to +25° rotation, positioned absolutely on the slide background. Contains a single uppercase Space-Grotesk word at 0.55–0.85rem. Functions as typographic confetti / atmospheric wallpaper. Five to eight per declarative slide.
**Header tag pill** — A small (≈0.7rem text) pill in a candy fill (typically lavender) with `pill-pad-sm` padding, centered above a section headline. The system's section-tag chip.
**Title pill / closing pill** — A medium pill (`pill-pad-lg`) in `{colors.yellow}` carrying uppercase Space-Grotesk text. Placed above the largest display headline on cover and closing slides.
**Pillar-card** — A 2rem-radius white card with 2px outline and 8px offset shadow, containing a circular `card-icon` at the top, a Bodoni `card-headline`, and a Space-Grotesk body paragraph. Used in 3-card and 4-card grids.
**Stat-pill** — A 2rem-radius white card containing a colored Bodoni stat number, a small uppercase label, and a tiny 40×4 accent bar at the bottom. Sits in 3- or 4-column stat grids.
**Bar-track** — A 36px-tall horizontal pill (9999px radius) with 2px outline and cream interior. The fill is a child pill in a candy color with the value label printed at the right edge inside the fill.
**Orbit composition** — A central 160px circular pill in `{colors.lime}` carrying a Bodoni ordinal, surrounded by 4–6 small `orbit-pill` satellites in candy fills, each tilted, positioned at 8–45% / 8–45% offsets, with 6px shadows.
**Diagram-node + connector** — Pill-shaped flow node (`diagram-node`) with 6px shadow, connected to the next node by a 50×4 ink bar with a triangular arrowhead. Nodes may carry candy fills; arrows are always ink.
**Visual-frame** — A 2rem-radius large frame with 12px offset shadow, filled with a tri-stop linear gradient (typically lavender → sky → mint), overlaid with a dot-grid pattern at 0.15 opacity, with an inner dashed border indicating "image placeholder." Used for hero visual moments.
**Quote-highlight** — An inline pill in lime or sky with 2px outline, wrapped around a single phrase inside a Bodoni quote body. The system's primary inline emphasis mechanism.
**Accent line** — A 60×4 (or 80×4 on closing slides) horizontal pill in `{colors.coral}` used as a sub-headline accent rule.
## Do's and Don'ts
### Do
- Make every text container a pill — 9999px radius for small pills, 2rem radius for larger cards. The pill geometry is the system's most distinctive single trait.
- Apply the 2px `{colors.outline}` stroke to every pill, card, icon, and frame. The outline is what makes the candy palette read as graphic rather than candy.
- Set every Bodoni display element in `{colors.ink}`, never in a candy color. Color belongs on stat numerals and pill fills, not on serif headlines.
- Use Bodoni Moda for every headline/stat/card title; use Space Grotesk for every body/label/pill. The two-face split is non-negotiable.
- Render shadows as solid hard offsets at 4/6/8/12px in `{colors.shadow}` (`rgba(26,26,26,0.08)`). Never blur; never re-color.
- Populate slide backgrounds with 5–8 floating decorative pills tilted at -20° to +25° rotations on cover, closing, quote, and other declarative layouts. The wallpaper-pill treatment is a system signature.
- Layer radial-gradient accent glows (6–15% opacity) into the cream canvas on every slide for atmospheric warmth.
- Keep the grain overlay (4% opacity, multiply blend) active on every slide — it is a baseline layer, not optional decoration.
- Wrap inline emphasis phrases in `quote-highlight` pills (lime, sky, or another candy) inside Bodoni quote bodies, rather than bolding or italicizing.
- Pair warm + cool accents adjacently: coral with sky, yellow with lavender, peach with mint. Avoid two same-family accents next to each other.
### Don't
- Don't render any text container with sharp corners. Square text containers do not exist in Capsule.
- Don't render a pill, card, or icon without the 2px ink outline. The stroke is the system's identity.
- Don't render Bodoni headlines in a candy color. Headlines are always `{colors.ink}`; color lives on stat numerals and pill fills.
- Don't use blurred drop shadows. The shadow is always solid offset at 4/6/8/12px in `{colors.shadow}`.
- Don't pair Bodoni with a different sans companion. The Bodoni Moda + Space Grotesk pairing is fixed.
- Don't use uppercase on Bodoni headlines. Bodoni in this system is sentence case (or true title case for proper nouns).
- Don't use sentence case on Space Grotesk subtitles, labels, or pill text. Small Space Grotesk text is always uppercase + 0.08em tracking.
- Don't introduce a tenth accent color. The nine candy accents are the closed palette.
- Don't apply shadows to decorative floating pills. Shadows are reserved for content-bearing containers.
- Don't leave a slide's corners empty on declarative layouts. The cream canvas wants atmospheric pills or radial glows; bare corners read as broken.
## Responsive Behavior
Capsule is a viewport-fluid 1920×1080 presentation system using `clamp()` and viewport-relative units throughout. There is a single `@media (max-width: 900px)` breakpoint that collapses grid columns to single-column stacks and hides the nav-dot column; below 600px the stats grid further collapses from 2-col to 1-col. The system is otherwise responsive without breakpoints.
### Scaling Behavior
- Display headline scales from 3rem at minimum viewport to 7rem at maximum.
- Body text scales from 0.95rem to 1.15rem.
- Padding scales via `clamp` inside individual layout selectors.
- Borders, pill outlines, shadow offsets, and grain overlay are fixed and do not scale.
### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, or `Space`.
- Slides reverse via `ArrowLeft` or `ArrowUp`.
- `Home` jumps to the first slide; `End` to the last.
- Touch swipe (horizontal): swipe distance >50px advances or reverses.
- The active slide carries `.active` (opacity 1); non-active slides are opacity 0 + pointer-events none.
- Nav dots are a vertical column at the right edge; the slide counter is at bottom-right; a keyboard hint is at bottom-left.
### Print / Export
Not explicitly handled; opacity-toggling means a naïve print captures only the active slide. Export workflows should snapshot each slide individually at 1920×1080.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Bodoni Moda 700–800) | Bodoni Moda | 站酷小薇体 ZCOOL XiaoWei | Google Fonts |
| Body / Pill text (Space Grotesk 400–600) | Space Grotesk | 悠哉字体 Yozai | cn-fontsource CDN |
### Mixed-Content Strategy
Use **Strategy A — single-font-stack with fallback**: declare the CJK font *after* the Latin font in the same `font-family` stack so Latin glyphs render in Bodoni Moda / Space Grotesk and CJK glyphs fall through to the Chinese face automatically. One CSS rule per role, no manual class switching.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bodoni+Moda:ital,opsz,wght@0,6..96,400..900;1,6..96,400..900&family=Space+Grotesk:[email protected]&family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-yozai-regular/font.css" rel="stylesheet">
```
```css
:root {
--font-display: "Bodoni Moda", "ZCOOL XiaoWei", serif;
--font-body: "Space Grotesk", "Yozai", sans-serif;
}
```
### Universal CJK Adjustments
- **Line-height**: bump CJK body line-height to ~1.7 (from 1.6) — Hanzi need more vertical breathing than Latin lowercase.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (negative tracking that flatters Bodoni capitals jams Hanzi strokes together). Keep tight tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any pill/label/subtitle when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (,。:;「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick ZCOOL XiaoWei *or* Yozai for a given text run based on its role, never both inside one phrase.
### Aesthetic Notes
ZCOOL XiaoWei is a high-contrast literary serif-leaning Hanzi face whose thin-thick stroke modulation echoes Bodoni Moda's didone register — it gives display headlines the same editorial-glamour weight as the Latin original. Yozai is a friendly rounded Hanzi sans whose open counters and modest stroke contrast mirror Space Grotesk's geometric grotesque, so pill text, labels, and body paragraphs retain the "clean modern sans" feel rather than reverting to a stiff system Hanzi. Both pair cleanly with the candy palette: ZCOOL XiaoWei in `{colors.ink}` keeps the rule "Bodoni headlines are never colored" intact, and Yozai sits inside coral / lime / yellow pills without losing legibility against the 2px ink outline. The decorative floating pill wallpaper still works in Chinese — substitute single-character or two-character atmospheric words (愿景, 未来, 下一步) for the English uppercase confetti.
### Known CJK Gap
ZCOOL XiaoWei is a display face with limited weight axis (single weight) and a smaller glyph set than Noto family — exotic or technical Hanzi (rare surnames, classical characters, simplified-only variants outside GB2312) may fall back to system font. For Traditional Chinese decks, swap Yozai for `LXGW WenKai TC` (Google Fonts) which has fuller TC coverage and a similar friendly humanist register. The ZCOOL XiaoWei italic / heavy moments that Bodoni achieves via the opsz axis have no equivalent in the Chinese face — use scale and color to compensate when Latin would have leaned on italic Bodoni.
## Iteration Guide
1. Any new container that holds text uses the pill geometry — 9999px radius for small, 2rem radius for cards. Don't introduce a sharp-cornered text container.
2. Any new pill carries the 2px solid `{colors.outline}` stroke. Don't render an unstroked pill.
3. Any new headline uses Bodoni Moda in `{colors.ink}`. Don't color a serif headline; don't switch to Space Grotesk for display.
4. Any new card carries a `8px 8px 0 {colors.shadow}` offset shadow (4px for small nodes, 12px for the visual frame). Don't blur; don't re-color.
5. Any new accent uses the nine-color candy palette in the coral → lime → sky → violet → yellow → lavender → peach → mint default sequence. Don't introduce a tenth color.
6. Any new declarative slide (cover, closing, quote, statement) gets 5–8 floating decorative pills as atmospheric wallpaper.
7. Any new data slide gets one or two radial accent glows in the canvas background. Don't leave the cream surface flat.
8. Any inline emphasis inside a Bodoni quote body uses a `quote-highlight` pill. Don't bold; don't italicize except via the Bodoni italic axis inside `<em>`.
9. New components inherit the pill geometry + 2px outline + 4–12px shadow pattern. If a new component breaks any of these three rules, redesign it before adding it.
## Known Gaps
- Two Bodoni font axes (italic and opsz 6..96) are loaded but the template only exercises the upright axis at fixed sizes; the optical-size variation across display sizes is not explicitly opted into.
- Bar-chart values are inline-styled via `style="width: NN%"` — there is no data-binding layer.
- The decorative floating pill positions and rotations are all hand-tuned via inline style on each instance; there is no generative placement system.
- The visual-frame's tri-stop gradient (lavender → sky → mint) is a hardcoded "default" — alternate gradient combinations are valid but need to be authored per instance.
- The grain overlay uses an inline SVG data URL; replacing or removing it requires editing the markup, not a CSS variable.
- The chart-bar-fill border-right at 2px solid outline is what gives bars their pill-end-cap definition; removing it loses the pill aesthetic on bars.
- The system inherits all 9 candy accent CSS variables but only ~6 are actively used across the source — peach and mint are present in the palette but used sparingly. They are available for new compositions.
- Decorative floating pills include their text content as part of the visual identity (single uppercase Space-Grotesk words). The words are not informational; new compositions should pick neutral single-word atmospheres ("VISION", "FUTURE", "NEXT", etc.) rather than content-specific text.
# Capsule Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/capsule/design.md`
- Preview card: `bold-template-pack/templates/capsule/preview.md`
## Selection Metadata
- Slug: `capsule`
- Tagline: Modular pill-shaped cards on warm bone with a full pastel-pop palette.
- Mood: playful, modern, warm, fresh, fun
- Tone: upbeat, graphic, approachable, cool
- Formality: medium-low
- Density: medium
- Scheme: light
- Best for: Anything that should feel modular, modern, and a little Y2K: lifestyle brands, creator portfolios, DTC launches, beauty / wellness, agency credentials. Also fun for a playful tech demo or a research deck that wants pop-art clarity instead of gravitas.
- Avoid for: Contexts that require traditional institutional weight — the capsule shapes and pastel pops actively soften authority.
## Visual Snapshot
A playful editorial system built on pill-shaped containers, a sun-bleached cream canvas, and a nine-color candy palette. Bodoni Moda serif headlines pair with Space Grotesk body to suggest a literary magazine that took a holiday at a 1970s ice-cream parlor. Every container that holds text is a pill (border-radius 9999px) outlined with a 2px ink stroke, casting a soft 6–12px offset shadow. The aesthetic is "Memphis-meets-editorial" — confident typography, generous bordered shapes, and decorative floating pills as atmospheric wallpaper.
Capsule is a playful editorial system whose defining structural premise is the pill: every text container is a pill, every icon is a pill, every bar is a pill, every node in a diagram is a pill. The border-radius: 9999px rule applies to virtually all UI elements, with larger panels softening to a 2rem radius. Combined with the 2px ink outline that wraps every shape, the result is a system where containers feel inflated, friendly, and graphically distinct — a nod to Memphis design and late-70s ice-cream-parlor signage without abandoning editorial discipline.
## Preview Ingredients
- Palette: cream #F5F5F0; ink #1A1A1A; outline #1E1E1E; white #FFFFFF; coral #E85D4E; lime #C4D94E; lavender #C5B5E0; sky #8BB4F7
- Typography: Bodoni Moda; Space Grotesk
- Signature move: Universal pill geometry — border-radius: 9999px for small containers, 2rem for larger cards/frames.
- Signature move: 2px solid {colors.outline} stroke wraps every pill, icon, and card.
- Signature move: Bodoni Moda serif for every display/headline/stat; Space Grotesk sans for every body/label/pill text.
- Signature move: Sun-bleached cream canvas {colors.cream} with soft radial glows in candy accent colors at 6–15% opacity for background atmosphere.
- Signature move: Hard-offset shadows in low-opacity ink ({colors.shadow}) at 4/6/8/12px offsets, always solid, always bottom-right.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Cartesian
description: A quiet, museum-catalog editorial system built on Playfair Display serif headlines, Inter sans body, and a five-tone warm-stone palette. The aesthetic is "consulting deck meets architectural monograph" — minimal geometric line decorations (thin circles, dashed arcs, vertical and horizontal hairlines) drift behind content, suggesting drafting paper and compass work. Every divider is a single 1px line in a muted taupe; nothing is bold, nothing is loud. The cultural reference is Massimo Vignelli's editorial work, the Cooper Hewitt catalog, and pencil-and-tracing-paper urban planning documents.
colors:
bg-primary: "#EDE8E0"
bg-secondary: "#E2DBD1"
text-primary: "#1A1A1A"
text-secondary: "#5A5A5A"
accent: "#8A8178"
line: "#B8B0A4"
white-overlay: "rgba(255, 255, 255, 0.3)"
typography:
display:
fontFamily: "Playfair Display, serif"
fontSize: "clamp(3rem, 6vw, 5.5rem)"
fontWeight: 400
lineHeight: 1.1
h1:
fontFamily: "Playfair Display, serif"
fontSize: "clamp(2.5rem, 5vw, 4.5rem)"
fontWeight: 400
lineHeight: 1.1
h2:
fontFamily: "Playfair Display, serif"
fontSize: "clamp(1.8rem, 3.5vw, 3rem)"
fontWeight: 400
lineHeight: 1.1
h3:
fontFamily: "Playfair Display, serif"
fontSize: "clamp(1.2rem, 2vw, 1.6rem)"
fontWeight: 400
lineHeight: 1.1
stat-figure:
fontFamily: "Playfair Display, serif"
fontSize: "2rem"
fontWeight: 400
lineHeight: 1
agenda-numeral:
fontFamily: "Playfair Display, serif"
fontSize: "1.5rem"
fontWeight: 400
lineHeight: 1
team-initial:
fontFamily: "Playfair Display, serif"
fontSize: "2rem"
fontWeight: 400
lineHeight: 1
quote-mark:
fontFamily: "Playfair Display, serif"
fontSize: "5rem"
fontWeight: 400
lineHeight: 1
card-headline:
fontFamily: "Playfair Display, serif"
fontSize: "1.3rem"
fontWeight: 400
lineHeight: 1.1
timeline-headline:
fontFamily: "Playfair Display, serif"
fontSize: "1.2rem"
fontWeight: 400
lineHeight: 1.1
body:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(0.9rem, 1.2vw, 1.1rem)"
fontWeight: 400
lineHeight: 1.6
body-sm:
fontFamily: "Inter, sans-serif"
fontSize: "0.9rem"
fontWeight: 400
lineHeight: 1.6
subtitle:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(1rem, 1.5vw, 1.3rem)"
fontWeight: 400
lineHeight: 1.5
attribution:
fontFamily: "Inter, sans-serif"
fontSize: "0.85rem"
fontWeight: 400
lineHeight: 1.4
letterSpacing: 2px
textTransform: uppercase
label:
fontFamily: "Inter, sans-serif"
fontSize: "0.75rem"
fontWeight: 500
lineHeight: 1
letterSpacing: 3px
textTransform: uppercase
micro:
fontFamily: "Inter, sans-serif"
fontSize: "0.7rem"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
textTransform: uppercase
spacing:
pad-y: "4vh"
pad-x: "4vw"
gap-xl: "6vw"
gap-lg: "5vw"
gap-md: "3vw"
gap-sm: "2vh"
card-pad: "4vh 2vw"
canvas:
width: 100vw
height: 100vh
components:
card:
border: "1px solid {colors.line}"
padding: "{spacing.card-pad}"
background: "{colors.white-overlay}"
description: "Tracing-paper card — 1px taupe outline with semi-transparent white fill that lets the canvas tone bleed through. No radius, no shadow."
card-icon:
width: 40px
height: 40px
border: "1px solid {colors.line}"
borderRadius: "50%"
color: "{colors.accent}"
fontSize: "1rem"
description: "Small ringed circle (40px) containing a 1–3 character Roman numeral or letter in accent taupe."
agenda-row:
padding: "2vh 0"
borderBottom: "1px solid {colors.line}"
description: "List row separated only by a 1px taupe hairline. Numeral at left, label at right."
timeline-rule:
height: "1px"
background: "{colors.line}"
description: "Single horizontal 1px taupe line connecting timeline items. No nodes, no markers — just the line."
vertical-line:
width: "1px"
height: "100%"
background: "{colors.line}"
opacity: 0.3
description: "Optional decorative vertical hairline anchored at left edge (default 8vw from edge) at low opacity. Provides drafting-paper grid feel."
horizontal-accent:
width: "20vw"
height: "1px"
background: "{colors.text-primary}"
description: "Single short ink-black 1px horizontal line used as a strong accent rule. Black, not taupe."
geo-circle:
border: "1px solid {colors.line}"
borderRadius: "50%"
opacity: 0.5
description: "Thin solid taupe ring at low opacity, used as decorative geometry behind content."
geo-arc:
border: "1px dashed {colors.line}"
borderRadius: "50%"
opacity: 0.3
description: "Thin dashed taupe ring at very low opacity, paired with geo-circle to suggest compass construction."
geo-decoration:
border: "1px solid {colors.line}"
borderRadius: "50%"
description: "Large decorative ring (30–50vw diameter) anchored to a corner or center. Always pairs with a ::before pseudo-element rendering a smaller dashed ring inside it, suggesting concentric drafting."
geo-ring:
width: "50vw"
height: "50vw"
border: "1px solid {colors.line}"
borderRadius: "50%"
opacity: 0.3
description: "The largest geometric decoration variant — a 50vw centered ring with an inner ::before dashed ring at 70% diameter."
image-placeholder:
background: "{colors.bg-secondary}"
border: "1px solid {colors.line}"
description: "Solid taupe-tinted block with two crossed 1px diagonal hairlines via ::before/::after at +30° and -30°, suggesting an X over a blank frame. Holds a small uppercase label centered."
team-photo:
width: "12vw"
height: "12vw"
borderRadius: "50%"
border: "1px solid {colors.line}"
background: "{colors.bg-secondary}"
description: "Circular portrait frame (12vw) in slightly darker stone, ringed in taupe, holding a single Playfair initial in accent taupe at center."
nav-arrow:
width: 40px
height: 40px
border: "1px solid {colors.line}"
background: "transparent"
description: "Square 40px button with 1px taupe border holding an arrow glyph. Hover state inverts to ink fill with cream text."
nav-dot:
width: 8px
height: 8px
borderRadius: "50%"
background: "{colors.line}"
description: "Small taupe dot at right edge as navigation indicator. Active state shifts to ink and scales 1.3."
chart-stroke-primary: "{colors.text-primary}"
chart-stroke-comparison: "{colors.line}"
chart-comparison-dash: "5, 5"
chart-grid-color: "{colors.bg-secondary}"
chart-axis-tick-color: "{colors.accent}"
---
## 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
Cartesian is a **quiet museum-catalog editorial system**. Its defining premise is **restraint through 1px lines**. Every structural element — list separators, agenda rules, timeline connectors, card borders, table dividers — is a single 1px line in a muted taupe `{colors.line}`. There are no thick borders, no fills, no shadows, no rounded surfaces. Hierarchy is built through type contrast and negative space; depth does not exist in the conventional sense.
The typeface stack is a literary-monograph pairing. **Playfair Display** — a high-contrast didone-influenced serif — carries every headline, every stat numeral, every card title, every team initial, every quote mark. Playfair runs at weight 400 (regular) almost exclusively — there is no use of bold or 700-weight Playfair in the system. The thin-stroke didone aesthetic depends on letting the letterforms breathe at modest weights. **Inter** — a clean modern grotesque — carries every body paragraph, every subtitle, every label, every attribution. Inter runs at 400 for body and 500 for labels. The pairing creates the system's editorial voice: serif statements + clean sans supporting structure.
The palette is **five warm stones plus ink**. The canvas is `{colors.bg-primary}` — a warm sandstone off-cream. A slightly deeper stone `{colors.bg-secondary}` provides subtle region differentiation (image placeholders, team photo frames). Ink `{colors.text-primary}` is the headline color; medium gray `{colors.text-secondary}` is body. A warmer taupe `{colors.accent}` carries labels, attribution, and small numerals. The lightest taupe `{colors.line}` is the universal 1px line color. There are no accent colors in the populist sense — no red, no orange, no blue. The palette is stone, stone, stone, ink, ink. The only "color" in the system is type contrast.
Depth is **entirely absent in the conventional sense**. There are no shadows, no elevated cards, no rounded surfaces, no gradients. Atmosphere is created by **geometric line decorations**: thin solid and dashed circles in `{colors.line}` at 20–50% opacity drift behind content as if drawn on tracing paper with a compass. These do not create hierarchy — they create mood. The decorative geometry signals "drafted, considered, precise."
**Density philosophy: sparse and breathing.** Cartesian reads as elegant when sparse and broken when crowded. A correctly composed slide pairs one Playfair headline with one body paragraph, or one chart with one short caption, framed by generous negative space. Most slide composition uses centered or asymmetric two-column layouts with `5–6vw` gutters and significant vertical breathing room. The decorative compass arcs reinforce the sparseness — they are most effective when there is room around them. A slide that feels broken in this system is one packed edge-to-edge with content; the correct density is "one clear idea, well-framed, on stone paper."
**Key Characteristics:**
- Warm sandstone canvas `{colors.bg-primary}` with single 1px taupe `{colors.line}` dividers as the universal structural element.
- Playfair Display serif at weight 400 for every headline/numeral/quote-mark; Inter sans for every body/label/attribution.
- Five-tone monochrome palette: two stones, two grays, one ink. No vivid accent colors anywhere.
- Decorative geometric rings (thin solid + dashed circles, 20–50% opacity) drift behind content as compass-drafted atmosphere.
- Every label, attribution, and micro-text is uppercase Inter with 2–3px letter-spacing.
- All borders are 1px hairlines; no element has a thicker border, a shadow, or a rounded fill.
- Right-edge vertical nav-dot column, bottom-left square nav-arrow buttons, bottom-right mono slide counter.
- Image placeholders carry a signature pair of crossed 1px diagonals (an X) over a stone-tinted block.
## Colors
### Stone & Ink Palette
- **Background Primary** (`{colors.bg-primary}` — #EDE8E0): The canvas. Warm sandstone off-cream — closer to "manila folder" than "white paper." This is the default slide background.
- **Background Secondary** (`{colors.bg-secondary}` — #E2DBD1): A slightly deeper stone, used for image placeholders, team-photo frames, and any region that needs subtle separation from the canvas without a colored fill or a border.
- **Text Primary** (`{colors.text-primary}` — #1A1A1A): Near-black ink. Used for headlines, stat numerals, and the special `{components.horizontal-accent}` rule. The strongest contrast color in the system.
- **Text Secondary** (`{colors.text-secondary}` — #5A5A5A): Medium warm gray. Used for all body paragraph text. Softer than ink — readable but recedes.
- **Accent** (`{colors.accent}` — #8A8178): Warm taupe. Used for labels, attributions, agenda numerals, slide counter, card-icon text, team-member role text. The system's "small text" color.
- **Line** (`{colors.line}` — #B8B0A4): Pale taupe. The universal 1px line color: card borders, agenda rules, timeline connectors, team-photo rings, nav-arrow borders, geo-decoration rings.
### Defaults
- **Default surface background**: `{colors.bg-primary}`.
- **Default headline color**: `{colors.text-primary}` — always ink, never colored, never accent-taupe. Playfair headlines are uniformly ink.
- **Default body text color**: `{colors.text-secondary}` (medium warm gray).
- **Default label / attribution / micro-text color**: `{colors.accent}` (warm taupe).
- **Default border color**: `{colors.line}` — every 1px structural border. Never use ink-black for borders except the rare `horizontal-accent` rule.
- **Default secondary surface fill**: `{colors.bg-secondary}`.
- **Default chart primary series color**: `{colors.text-primary}` (ink).
- **Default chart comparison/secondary series color**: `{colors.line}` with 5px dashed stroke.
- **Default chart grid color**: `{colors.bg-secondary}`.
- **Default chart axis tick color**: `{colors.accent}`.
Cartesian has **no accent color in the populist sense.** A red callout, a blue bar, a green stat — none of these exist. When emphasis is needed, increase type size, switch from sans to serif, or add a single 1px `horizontal-accent` rule in ink. Color is not the emphasis mechanism in this system; restraint is.
## Typography
### Font Family
The system runs on a **two-face conversation**: `Playfair Display` (serif, weights 400/600/700, italic available) carries every headline, stat numeral, quote mark, card title, and team initial; `Inter` (sans, weights 300/400/500/600) carries every body, subtitle, label, attribution, and micro-text. There is no third face.
Playfair Display is used almost exclusively at **weight 400 (regular)**. The system deliberately avoids bold Playfair — the didone aesthetic relies on thin-stroke modulation that disappears at heavier weights. Italic Playfair is available (loaded) but not exercised in the default template; reserve it for inline emphasis inside body copy.
Inter runs at weight 400 for body, weight 500 for labels and micro-text, weight 600 for the rare emphasized inline element. The contrast between Playfair's high-modulation serif and Inter's even sans is the system's primary typographic rhythm.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | clamp(3rem, 6vw, 5.5rem) | Playfair Display | 400 | Cover or large opening title |
| `{typography.h1}` | clamp(2.5rem, 5vw, 4.5rem) | Playfair Display | 400 | Section-opening or large closing headline |
| `{typography.h2}` | clamp(1.8rem, 3.5vw, 3rem) | Playfair Display | 400 | Primary slide headline |
| `{typography.h3}` | clamp(1.2rem, 2vw, 1.6rem) | Playfair Display | 400 | Sub-headline within a region |
| `{typography.card-headline}` | 1.3rem | Playfair Display | 400 | Card or pillar-block title |
| `{typography.timeline-headline}` | 1.2rem | Playfair Display | 400 | Timeline-step or phase headline |
| `{typography.stat-figure}` | 2rem | Playfair Display | 400 | Numerical stat figure (typically inline in a stats cluster) |
| `{typography.team-initial}` | 2rem | Playfair Display | 400 | Initial letter centered inside a team-photo circle |
| `{typography.agenda-numeral}` | 1.5rem | Playfair Display | 400 | Ordinal numeral preceding an agenda row |
| `{typography.quote-mark}` | 5rem | Playfair Display | 400 | Opening quotation glyph for a pull-quote |
| `{typography.subtitle}` | clamp(1rem, 1.5vw, 1.3rem) | Inter | 400 | Subtitle paragraph below a display headline |
| `{typography.body}` | clamp(0.9rem, 1.2vw, 1.1rem) | Inter | 400 | Standard paragraph body |
| `{typography.body-sm}` | 0.9rem | Inter | 400 | Compact body inside cards or timeline items |
| `{typography.attribution}` | 0.85rem | Inter | 400 | Attribution line below a quote, with 2px tracking + uppercase |
| `{typography.label}` | 0.75rem | Inter | 500 | Section label / eyebrow above a headline, with 3px tracking + uppercase |
| `{typography.micro}` | 0.7rem | Inter | 400 | Image label, slide counter, smallest chrome text |
### Defaults
- **Default size for the primary slide headline**: `{typography.h2}` (clamp 1.8–3rem).
- **Default size for a cover or large opening headline**: `{typography.h1}` (clamp 2.5–4.5rem); for the most expansive cover, `{typography.display}` (clamp 3–5.5rem).
- **Default size for paragraph body**: `{typography.body}` (clamp 0.9–1.1rem).
- **Default size for any inline label or eyebrow**: `{typography.label}` (0.75rem) — always 3px tracking + uppercase.
- **Default weight for any Playfair headline**: 400. Don't reach for 600 or 700.
- **Default weight for body**: 400.
- **Default weight for labels/micro**: 500.
- **Default size for a stat numeral inside a stats cluster**: `{typography.stat-figure}` (2rem). Cartesian does not have a hero-stat-numeral pattern (no 5–7rem display stat); stats are presented as inline ranks at modest scale.
When unsure, reach for `{typography.h2}` for the slide's primary text moment, not `{typography.h3}` (which is a sub-headline within a region).
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Playfair headline, stat, quote, card title, and initial is set at weight 400.** Bold Playfair does not exist in this system. The thin-stroke didone aesthetic is the identity.
- **Every Playfair element is set in sentence case (or true title case for proper nouns).** Uppercase Playfair is not used.
- **Every Inter label, attribution, and micro-text element is uppercase with 2–3px letter-spacing.** Labels at 3px tracking; attributions and micro at 2px. Without the tracking, Inter caps read as untreated.
- **Every Playfair element is rendered in `{colors.text-primary}` (ink).** Headlines are never accent-taupe and never gray. The exception is decorative initial letters inside a circular `card-icon` or `team-photo`, where the letterform is rendered in `{colors.accent}`.
- **Every 1px structural border uses `{colors.line}`.** Other border colors do not exist except for the rare `horizontal-accent` rule in ink.
- **Every card, image-placeholder, team-photo, and nav-arrow border is 1px solid.** Thicker borders do not exist in this system.
- **Charts use ink-black for the primary series and dashed taupe (5px, 5px) for the comparison series.** This pair is the only chart-color rule.
### Typography Principles
The Playfair-400 + Inter-400 combination is the system's voice. Switching either family or jumping Playfair to weight 700 reads as a different design system. Italic emphasis is permitted via inline `<em>` inside body copy (Inter italic) — italic Playfair is loaded but reserved for rare uses. Underline is not used.
Line-height stays open: headlines at 1.1, body at 1.6. The wide body line-height is part of the breathing-room aesthetic.
## Layout
### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Each `.slide` is absolutely positioned to fill the viewport; one slide carries `.active` (opacity 1, visibility visible) at a time. Transitions are 0.6s opacity + visibility fades.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-y}` | 4vh | Default vertical slide padding |
| `{spacing.pad-x}` | 4vw | Default horizontal slide padding |
| `{spacing.gap-xl}` | 6vw | Major two-column gutter (most spacious) |
| `{spacing.gap-lg}` | 5vw | Standard two-column or grid gutter |
| `{spacing.gap-md}` | 3vw | Card-grid gutter |
| `{spacing.gap-sm}` | 2vh | Agenda row vertical padding, attribution spacing |
| `{spacing.card-pad}` | 4vh 2vw | Internal padding for content cards |
Headlines typically carry a 2–3vh margin-bottom from labels above and a 2vh margin-bottom from body below. Section headers above 3-card or 4-team grids carry a 6vh margin-bottom from the grid (significant breathing room).
### Decorative Geometry Layer
Cartesian's signature is its **drafting-paper geometric decoration**. Every slide may layer one or more of:
- A large ringed `geo-decoration` anchored to a corner (typically 30–50vw diameter) with an inner dashed ring at ~80% diameter (the `::before` pseudo).
- A `vertical-line` at ~8vw from the left edge running floor-to-ceiling at 30% opacity.
- A `horizontal-accent` (a single short black 1px line) anchored at 15vh from the bottom-left.
- A centered `geo-ring` (50vw circle) on closing or contemplative slides.
These elements have **no informational role** — they create atmosphere. Slides without any geometric decoration are valid; over-decoration (more than two geo elements per slide) breaks the restraint.
### Chrome
The system's chrome is minimal:
- Right-edge vertical column of small `nav-dot` indicators (8px circles in taupe).
- Bottom-left pair of square `nav-arrow` buttons (40×40, 1px taupe border, transparent fill).
- Bottom-right `slide-counter` text in Inter at 0.75rem with 2px tracking in `{colors.accent}`.
There is no top chrome bar, no persistent header, no footer rule.
## Depth and Elevation
### Flat Plane (Only Technique)
Cartesian has no shadows, no elevated cards, no rounded surfaces, no gradients. Every element sits on a single plane.
Hierarchy is constructed from:
- **Type contrast** — Playfair serif vs Inter sans; size scale from 5rem down to 0.7rem.
- **1px hairline dividers** — agenda rows, timeline rule, card outlines, image-placeholder outlines, stats top-border, team-photo rings, nav-arrow borders.
- **Color tone** — ink vs gray vs taupe.
- **Negative space** — generous padding around every element.
- **Geometric atmosphere** — compass-drafted rings behind content suggest depth without creating it.
Introducing a `box-shadow`, an elevated card, or a soft gradient breaks the restraint that defines the system.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 50% (circle) | Every circular element: `card-icon` (40px), `team-photo` (12vw), `nav-dot` (8px), `geo-circle`, `geo-arc`, `geo-decoration`, `geo-ring` |
| 0 | Everything else: cards, image-placeholders, nav-arrows, agenda rows, timeline, stat-blocks, chart container |
The system uses **only two radius values**: 50% (true circle) or 0 (sharp rectangle). Soft-rounded corners do not exist.
### Border Weights
- **1px solid `{colors.line}`** — the universal structural border. Used on every card, image-placeholder, team-photo ring, nav-arrow, agenda row bottom, timeline rule, stats top, geo-circle, geo-decoration.
- **1px dashed `{colors.line}`** — used on `geo-arc` and the inner `::before` ring inside `geo-decoration` / `geo-ring`. Dashed signals "construction line / arc."
- **1px solid `{colors.text-primary}`** — used only on the rare `horizontal-accent` decorative rule. The system's only ink-black line.
- **Chart bar/line stroke widths** — Chart.js series at 1px (bar borders), 2px (line series). Comparison series at 2px dashed (5px dash, 5px gap).
All structural borders are `{colors.line}`. Thicker borders, colored borders, and dashed structural borders (other than geo-arcs) do not exist.
### Decorative Element Types
**Geometric ring (geo-circle / geo-decoration / geo-ring)** — Thin 1px taupe circles in various sizes (10vw, 30vw, 50vw) at 20–50% opacity. Typically paired with an inner dashed `::before` ring at 70–80% of the outer diameter, suggesting compass construction with both a primary and an offset arc. Anchored to corners or centers; sits behind content with `z-index: 0` and `pointer-events: none`.
**Vertical line** — A single 1px taupe column anchored at ~8vw from the left slide edge, running floor-to-ceiling at 30% opacity. Suggests a drafting-paper alignment guide. Optional per slide.
**Horizontal accent** — A single 20vw × 1px black line anchored 15vh from the bottom-left of a slide. The system's only ink-black line — used as a strong terminal accent rule on cover or closing layouts. Use sparingly.
**Image placeholder** — A solid `{colors.bg-secondary}` block with two 150% diagonal 1px taupe lines crossed at +30° and -30° via `::before` / `::after`, forming an X. Centers a small uppercase Inter label ("Visual Reference" or similar). The X pattern is the signature image-not-yet-wired treatment.
**Team-photo frame** — A 12vw circular block in `{colors.bg-secondary}` with a 1px taupe ring, holding a single Playfair-400 initial at 2rem in `{colors.accent}` centered. Used as portrait placeholder.
**Card** — A 1px taupe-bordered block with a semi-transparent white interior fill (`{colors.white-overlay}`) that lets the canvas tone bleed through subtly. The faint white fill is what differentiates a card from a bare region; remove the fill and the card disappears.
**Agenda row** — A flex row containing a Playfair `{typography.agenda-numeral}` in `{colors.accent}` at left, then a label at right, with 2vh padding and a 1px taupe bottom border. Stacked rows form an agenda list.
**Timeline** — A 1px taupe top-border across a flex row of evenly-distributed timeline items; each item carries a small Inter `year` label in taupe, a Playfair `{typography.timeline-headline}`, and an Inter body paragraph. The hairline is the only timeline structure — there are no nodes, no markers, no dots.
**Stats cluster** — A flex row of stat items separated by `gap-md`, framed by a 1px taupe top border, holding inline `{typography.stat-figure}` Playfair numerals with small uppercase Inter labels in taupe below.
**Quote mark** — A 5rem Playfair quote glyph at 50% opacity in taupe, positioned above a Playfair `{typography.h2}` headline + a small uppercase taupe attribution below.
**Chart** — Chart.js bar or line chart with ink-black primary series and dashed taupe comparison series. Grid lines in `{colors.bg-secondary}`. Axis ticks in `{colors.accent}`. Always rendered without fill on the primary series (or with a 5% ink-tinted fill on line charts).
## Do's and Don'ts
### Do
- Use a single 1px line in `{colors.line}` for every structural separator — agenda rule, timeline connector, card border, stats top, team-photo ring. The 1px hairline is Cartesian's identity.
- Set every Playfair headline, stat, quote mark, and card title at weight 400. Don't reach for bold; the thin-stroke didone aesthetic depends on it.
- Render every headline in `{colors.text-primary}` (ink). Playfair never appears in taupe or color.
- Render every label, attribution, agenda numeral, and micro-text in `{colors.accent}` (taupe) with uppercase + 2–3px letter-spacing.
- Layer decorative geometric rings (solid + dashed) at 20–50% opacity behind content for atmosphere. One or two geo elements per slide; never more.
- Pair Playfair Display (serif headlines) with Inter (sans body). The two-face pairing is fixed.
- Use the crossed-diagonal X pattern inside image placeholders. It is the system's signature placeholder treatment.
- Let slides breathe — sparse layouts with generous negative space are the correct density.
- Use `{colors.bg-secondary}` as the fill for image placeholders and team-photo frames — a subtle stone, not white, not gray.
- Use a single `horizontal-accent` (20vw × 1px ink line) sparingly as a strong terminal rule on cover or closing compositions.
### Don't
- Don't introduce a populist accent color. No red, no orange, no blue, no green. The palette is stone-on-stone with ink for headlines.
- Don't render Playfair headlines in `{colors.accent}` (taupe). Headlines are ink; taupe is reserved for small text.
- Don't bold any Playfair element. Weight 400 is the standing rule; bold breaks the didone aesthetic.
- Don't add shadows, elevated cards, or gradient fills. Cartesian is flat; depth comes from geometry and type, not z-axis.
- Don't use rounded corners on cards or rectangles. The only round shapes are true circles (radius 50%).
- Don't use thick borders (2px+). Every structural border is 1px.
- Don't crowd the slide. Sparse breathing layouts read as elegant; packed layouts read as broken.
- Don't pair Playfair with a different sans companion. The Inter pairing is fixed.
- Don't render labels or micro-text in sentence case. Small Inter text is always uppercase + 2–3px tracking.
- Don't add more than two geo decorations per slide — restraint is the rule; over-decoration reads as cluttered.
## Responsive Behavior
Cartesian is a viewport-fluid 1920×1080 presentation system using `vw` / `vh` units and `clamp()` throughout. There is a single `@media (max-aspect-ratio: 4/3)` breakpoint that collapses two-column grids to single-column, hides the timeline rule (which would lose meaning when stacked), and stacks team and card grids vertically. The system is otherwise responsive without breakpoints.
### Scaling Behavior
- Display headlines scale from 2.5rem at minimum viewport to 5.5rem at maximum via `clamp()`.
- Body text scales from 0.9rem to 1.1rem.
- Padding uses `vh` / `vw` units that scale linearly with viewport.
- The 1px borders, 8px nav dots, and 40px nav arrows are fixed and do not scale.
### Presenter Behavior
- Slides advance via `ArrowRight` or `Space`.
- Slides reverse via `ArrowLeft`.
- Nav dots at right edge can be clicked to jump to specific slides.
- Nav arrows at bottom-left are clickable; hover state inverts background to ink and text to cream.
- Slide counter at bottom-right shows current / total with 2-digit zero-padding.
### Charts
Charts are rendered with Chart.js (loaded via CDN). The two chart types in the source are bar and line; both follow the ink-primary / dashed-taupe-comparison convention. Custom font settings inject Inter into Chart.js label rendering.
### Print / Export
Not explicitly handled. Each slide is a 100vw × 100vh block; export workflows should snapshot each slide at 1920×1080.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Playfair Display 400) | Playfair Display | 思源宋体 Noto Serif SC 700 | Google Fonts |
| Body / Label (Inter 400–500) | Inter | 思源宋体 Noto Serif SC 400 | Google Fonts |
### Mixed-Content Strategy
Use **Strategy A — single-font-stack with fallback**: declare Noto Serif SC *after* the Latin font in the same `font-family` stack so Latin glyphs render in Playfair / Inter and CJK glyphs fall through to Noto Serif SC automatically. One CSS rule per role, no manual class switching.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..700;1,400..700&family=Inter:[email protected]&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
```
```css
:root {
--font-display: "Playfair Display", "Noto Serif SC", serif;
--font-body: "Inter", "Noto Serif SC", sans-serif;
}
/* Headlines use Noto Serif SC 700; body uses Noto Serif SC 400. */
```
### Universal CJK Adjustments
- **Line-height**: bump CJK body line-height to ~1.75 (from 1.6) — Hanzi need more vertical breathing than Latin lowercase, and Cartesian already favors generous leading.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs. Keep the 2–3px tracking only on uppercase Latin labels.
- **Text-transform**: drop `text-transform: uppercase` on any label/attribution/micro when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (,。:;「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick a single weight of Noto Serif SC for a given text run, never two inside one phrase.
### Aesthetic Notes
Noto Serif SC (思源宋体) is the only mainstream Hanzi serif with the same restrained editorial register Cartesian needs — its modulated horizontal-thin / vertical-thick strokes echo Playfair's didone aesthetic, and its uniformly even cadence matches Cartesian's "museum-catalog" voice. Using NSC at weight 700 for headlines preserves the visual mass of the Latin display while NSC 400 carries body with the same quiet warmth Inter provides. The five-stone palette absorbs Hanzi cleanly because every glyph stays in ink or taupe — no candy fills to negotiate. The decorative compass-arc geometry layer is content-agnostic and works identically in any language. Avoid bolding Hanzi (the Chinese-typography equivalent of Cartesian's "no bold Playfair" rule); rely on size and the 1px line dividers for hierarchy.
### Known CJK Gap
Noto Serif SC is the only Hanzi serif loaded — there is no italic axis (Chinese type historically has no italic), so the rare italic Playfair `<em>` moment loses its emphasis when the body falls through to NSC. Substitute a single-character span colored in `{colors.accent}` (taupe), or wrap the emphasized phrase in faint brackets 「」, to recover emphasis. NSC's 700 weight is the heaviest available — the system's restraint-through-400-weight rule naturally extends to Chinese, so this is rarely a gap in practice.
## Iteration Guide
1. Every new structural separator uses a 1px solid `{colors.line}` border. No exceptions.
2. Every new headline uses Playfair Display at weight 400 in `{colors.text-primary}`. Don't bold; don't color.
3. Every new small text element (label, attribution, micro) uses Inter uppercase with 2–3px letter-spacing in `{colors.accent}`.
4. Every new body paragraph uses Inter weight 400 in `{colors.text-secondary}`, with line-height 1.6.
5. Every new card uses 1px taupe border + semi-transparent white overlay fill. No shadow, no radius.
6. New circular elements (icons, photos, decorative rings) use border-radius 50% with 1px taupe ring.
7. New geometric decorations stay subtle: 1 or 2 per slide, at 20–50% opacity, behind content (z-index 0, pointer-events none).
8. New chart series follow the ink-primary / dashed-taupe-comparison convention. Don't introduce colored chart series.
9. New layouts respect the breathing-room density rule — sparse beats dense in Cartesian.
10. The `horizontal-accent` 20vw ink line is the system's only "ink rule" — use it sparingly as a terminal accent, never as a routine divider.
## Known Gaps
- The Chart.js library is loaded via CDN; new chart types beyond bar and line require manual configuration matching the ink-primary / dashed-taupe-comparison aesthetic.
- The decorative `geo-decoration` and `geo-ring` `::before` inner-ring pattern is hardcoded in CSS; size variants beyond what the source exercises require new style rules.
- The team-photo placeholder shows a single Playfair initial in taupe; real portrait insertion requires replacing the initial with an `<img>` and adjusting the circular crop.
- The chart axis label colors and grid colors are hardcoded inline in the Chart.js options blocks (rather than reading from CSS variables) — restyling requires editing JS, not CSS.
- The image-placeholder X pattern (crossed +30°/-30° diagonals) is rendered via `::before` / `::after` with fixed 150% widths; resizing the placeholder beyond the source dimensions may require recomputing the rotation angle to maintain edge-touch.
- Italic Playfair is loaded but not exercised in any default rule; it is available for inline `<em>` emphasis in body copy but the system itself does not author any italic text.
- The `vertical-line` and `horizontal-accent` decorative elements have hardcoded position values (8vw from left, 15vh from bottom); using them off-default-position requires per-instance style overrides.
- The slide-counter `currentSlide` / `totalSlides` IDs are referenced in the JS but the system has no internal slide-name registry; new slides simply increment by their DOM order.
# Cartesian Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/cartesian/design.md`
- Preview card: `bold-template-pack/templates/cartesian/preview.md`
## Selection Metadata
- Slug: `cartesian`
- Tagline: Quiet warm-neutral palette with classical Playfair serifs; tasteful and unhurried.
- Mood: quiet, considered, elegant, warm-minimal
- Tone: classical, literary, restrained, confident-quiet
- Formality: high
- Density: low
- Scheme: light
- Best for: Anything that should feel quiet, considered, and grown-up: investment theses, white papers, advisory work, longform research, gallery / cultural decks. Also a strong choice for editorial features, founder reflections, or any deck where restraint is the message — including across tech and finance.
- Avoid for: Decks that need visual heat, multiple accents, or a sense of urgency — the warm-neutral palette is intentionally low-energy.
## Visual Snapshot
A quiet, museum-catalog editorial system built on Playfair Display serif headlines, Inter sans body, and a five-tone warm-stone palette. The aesthetic is "consulting deck meets architectural monograph" — minimal geometric line decorations (thin circles, dashed arcs, vertical and horizontal hairlines) drift behind content, suggesting drafting paper and compass work. Every divider is a single 1px line in a muted taupe; nothing is bold, nothing is loud. The cultural reference is Massimo Vignelli's editorial work, the Cooper Hewitt catalog, and pencil-and-tracing-paper urban planning documents.
Cartesian is a quiet museum-catalog editorial system. Its defining premise is restraint through 1px lines. Every structural element — list separators, agenda rules, timeline connectors, card borders, table dividers — is a single 1px line in a muted taupe {colors.line}. There are no thick borders, no fills, no shadows, no rounded surfaces. Hierarchy is built through type contrast and negative space; depth does not exist in the conventional sense.
## Preview Ingredients
- Palette: bg-primary #EDE8E0; bg-secondary #E2DBD1; text-primary #1A1A1A; text-secondary #5A5A5A; accent #8A8178; line #B8B0A4
- Typography: Playfair Display; Inter
- Signature move: Warm sandstone canvas {colors.bg-primary} with single 1px taupe {colors.line} dividers as the universal structural element.
- Signature move: Playfair Display serif at weight 400 for every headline/numeral/quote-mark; Inter sans for every body/label/attribution.
- Signature move: Five-tone monochrome palette: two stones, two grays, one ink. No vivid accent colors anywhere.
- Signature move: Decorative geometric rings (thin solid + dashed circles, 20–50% opacity) drift behind content as compass-drafted atmosphere.
- Signature move: Every label, attribution, and micro-text is uppercase Inter with 2–3px letter-spacing.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Cobalt Grid
description: A Japanese-magazine trend-report system built on warm cream paper, electric cobalt ink, and a graph-paper grid that lives permanently behind every slide. Newsreader serif headlines tower at 18vh while DM Mono carries chrome and ticker text. The signature decoration is a pixel-glitch column — vertical scanlines stair-stepped down the right edge of declarative slides — paired with QR-style 8×8 grid patches. The cultural reference is WIRED Japan, Shift magazine, and architectural trend reports printed in two-color risograph: cream + one cobalt.
colors:
paper: "#F0EBDE"
paper-2: "#E6E0CE"
ink: "#1F2BE0"
ink-soft: "#5560E5"
grid: "rgba(31, 43, 224, 0.10)"
ink-faint: "rgba(31, 43, 224, 0.18)"
color-aliases:
rule: ink
bg: paper
typography:
display-hero:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(100px, min(11vw, 18vh), 200px)"
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.008em
display-closing:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(72px, min(8.4vw, 14vh), 180px)"
fontWeight: 400
lineHeight: 0.96
letterSpacing: -0.005em
display-chapter:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(56px, min(6vw, 10vh), 130px)"
fontWeight: 400
lineHeight: 1
letterSpacing: -0.005em
display-quote:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(50px, min(5.6vw, 9vh), 110px)"
fontWeight: 400
lineHeight: 1.05
letterSpacing: -0.005em
display-manifesto:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(56px, min(6.4vw, 11vh), 120px)"
fontWeight: 400
lineHeight: 1.05
letterSpacing: -0.005em
headline:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(46px, min(4.8vw, 8.2vh), 92px)"
fontWeight: 400
lineHeight: 0.95
headline-index:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(48px, min(5vw, 8.5vh), 100px)"
fontWeight: 400
lineHeight: 0.95
vbig-numeral:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(110px, min(11vw, 18vh), 240px)"
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.015em
ed-callout:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(28px, min(2.8vw, 4.6vh), 50px)"
fontWeight: 400
lineHeight: 1.1
row-headline:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(26px, 2vw, 40px)"
fontWeight: 400
lineHeight: 1.05
table-name:
fontFamily: "Newsreader, Georgia, serif"
fontSize: "clamp(20px, 1.6vw, 28px)"
fontWeight: 400
lineHeight: 1.15
micro:
fontFamily: "Hanken Grotesk, sans-serif"
fontSize: "clamp(12px, 0.9vw, 14px)"
fontWeight: 600
lineHeight: 1
letterSpacing: 0.16em
textTransform: uppercase
micro-strong:
fontFamily: "Hanken Grotesk, sans-serif"
fontSize: "clamp(13px, 1vw, 16px)"
fontWeight: 600
lineHeight: 1
letterSpacing: 0.18em
textTransform: uppercase
micro-sm:
fontFamily: "Hanken Grotesk, sans-serif"
fontSize: "clamp(11px, 0.75vw, 12px)"
fontWeight: 600
lineHeight: 1
letterSpacing: 0.18em
textTransform: uppercase
body:
fontFamily: "Hanken Grotesk, sans-serif"
fontSize: "clamp(14px, 0.95vw, 15px)"
fontWeight: 400
lineHeight: 1.5
body-lede:
fontFamily: "Hanken Grotesk, sans-serif"
fontSize: "clamp(15px, 1vw, 18px)"
fontWeight: 400
lineHeight: 1.5
body-stat:
fontFamily: "Hanken Grotesk, sans-serif"
fontSize: "clamp(15px, 1vw, 17px)"
fontWeight: 400
lineHeight: 1.5
mono-tag:
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: "clamp(13px, 0.9vw, 15px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 0.04em
mono-chrome:
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: "clamp(11px, 0.82vw, 13px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 0.06em
mono-tick:
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: "clamp(12px, 0.85vw, 14px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 0.04em
spacing:
edge: "clamp(36px, 3.6vw, 80px)"
edge-inner: "clamp(60px, 8vw, 160px)"
pad-top: "clamp(76px, 8vh, 130px)"
pad-bottom: "clamp(100px, 10vh, 150px)"
gap-lg: "clamp(28px, 3vw, 56px)"
gap-md: "clamp(20px, 2.2vh, 36px)"
gap-sm: "clamp(14px, 1.6vh, 24px)"
gap-xs: "clamp(10px, 1.2vh, 18px)"
canvas:
width: 100vw
height: 100vh
components:
graph-paper-grid:
backgroundImage: "linear-gradient(to right, {colors.grid} 1px, transparent 1px), linear-gradient(to bottom, {colors.grid} 1px, transparent 1px)"
backgroundSize: "clamp(28px, 2.2vw, 44px) clamp(28px, 2.2vw, 44px)"
description: "Permanent ::before pseudo on every stage. 28–44px squared graph paper grid in 10%-opacity cobalt that sits behind every slide at z-index 1. Cannot be turned off — it is the canvas tone."
hairlines:
height: "1.5px"
background: "{colors.ink}"
description: "Two persistent slim cobalt rules — one at the top of every slide (≈2.6vh from top) and one near the bottom (≈2vh from bottom) — both inset from edges by {spacing.edge}. They frame the slide composition."
pagenum:
position: absolute
right: "{spacing.edge}"
bottom: "clamp(48px, 4.8vh, 76px)"
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: "clamp(11px, 0.82vw, 13px)"
color: "{colors.ink}"
letterSpacing: 0.06em
description: "Mono cobalt page number anchored bottom-right above the bottom hairline. One per slide."
nav-hint:
position: fixed
left: "{spacing.edge}"
bottom: "clamp(48px, 4.8vh, 76px)"
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: "clamp(10px, 0.75vw, 12px)"
color: "{colors.ink}"
letterSpacing: 0.08em
opacity: 0.4
description: "Mono cobalt navigation hint anchored bottom-left, mirrors pagenum."
pixel-glitch:
description: "Stair-stepped column of vertical scanlines, rendered as inline SVG. Each stepped rectangle contains evenly-spaced cobalt vertical lines on cream. Sits absolutely positioned (typically right edge) at z-index 3, decorative only. Size ranges from 16vw × full-height (compact decoration) to 32vw × full-height (signature cover decoration)."
qr-block:
display: grid
gridTemplateColumns: "repeat(8, 1fr)"
gridTemplateRows: "repeat(8, 1fr)"
gap: 1.5px
background: "{colors.paper}"
padding: 4px
boxShadow: "0 0 0 1.5px {colors.paper}"
description: "8×8 QR-style mosaic of cobalt cells on cream background. Paper-fill ensures it reads as a discrete patch when overlapping the pixel-glitch column. Typical size 58–100px square."
topbar-rule:
borderBottom: "1.5px solid {colors.ink}"
paddingBottom: "clamp(12px, 1.4vh, 22px)"
description: "1.5px cobalt rule under the topbar of an index, data, or table layout. Below the rule sits a Newsreader headline (left) and a mono lab-tag (right)."
row-divider:
borderBottom: "1px solid {colors.ink-faint}"
description: "Faint 18%-opacity cobalt rule between rows of an index list, table, or ledger."
attribution-rule:
borderTop: "1px solid {colors.ink}"
paddingTop: "clamp(10px, 1.2vh, 18px)"
description: "Solid cobalt rule above a quote attribution or manifesto byline."
pixel-stack-bars:
description: "Vertical bar chart rendered as a column of stacked 'cells' — flex column-reverse with 3px gaps, each cell a small horizontal block. Cells default to 10%-opacity cobalt (the grid color); .on cells fill solid cobalt to represent the value. Reads as a pixelated bar made of grid units."
ledger-row:
display: grid
gridTemplateColumns: "76px 0.6fr 1.4fr 0.7fr 0.5fr"
gap: "clamp(14px, 1.4vw, 28px)"
borderBottom: "1px solid {colors.ink-faint}"
description: "Dense table row carrying a num-tag, name (Newsreader), description (Hanken Grotesk), mood-tag, and delta-tag (mono with up/down arrow prefix). Header row uses 1.5px solid cobalt bottom border."
vstack-label:
fontFamily: "DM Mono, ui-monospace, monospace"
writingMode: "vertical-rl"
textOrientation: "mixed"
letterSpacing: 0.04em
description: "Vertical-orientation mono label column anchored to the right edge of a slide. Replaces the Korean vertical column of the reference with mono catalogue text rotated 90°."
delta-up:
content: "↑ "
description: "Up arrow prefix via ::before on a mono delta tag in the ledger table."
delta-down:
content: "↓ "
opacity: 0.6
description: "Down arrow prefix via ::before, dimmed 40% to read as decline."
delta-flat:
content: "— "
opacity: 0.6
description: "Em-dash prefix via ::before, dimmed 40% to read as neutral."
---
## 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
Cobalt Grid is a **two-color trend-report editorial system** built on three immovable foundations: a warm cream paper canvas (`{colors.paper}`), an electric cobalt ink (`{colors.ink}`), and a **permanent graph-paper grid** that sits behind every slide. The grid is not optional decoration — it is rendered via a `::before` pseudo on every `.stage` and cannot be turned off. The aesthetic is "two-color risograph monograph": cream + cobalt only, with the grid lending the entire deck the feel of architectural tracing paper or a Japanese trend report.
The typeface stack is a deliberate three-face conversation. **Newsreader** — a contemporary literary serif with low-modulation roman letterforms — carries every display moment, every section headline, every stat numeral. Newsreader is used at weight 400 only; the type relies on size to assert hierarchy, not weight. **Hanken Grotesk** — a humanist sans — carries every body paragraph, every uppercase label, every micro-text. Hanken runs at 400 for body and 600 for labels. **DM Mono** — a monospace — carries every chrome element: page numbers, mono tags, axis ticks, vertical-stack labels, delta arrows in tables. The three-face system creates the system's identity: serif statements + sans bodies + mono chrome.
The palette is **strictly two-color**: cream and cobalt, with a softer cobalt `{colors.ink-soft}` and two opacity tones (`{colors.grid}` at 10%, `{colors.ink-faint}` at 18%) for atmospheric and structural use. There are no accent colors. Cobalt is the *only* ink color — for headlines, body, borders, page numbers, the graph paper, the pixel-glitch decoration, and the QR patches. The cream paper is the *only* surface. Even the pixel-stack bar chart uses cobalt at two opacities (10% off, 100% on) to render data.
Depth is **flat with structural rules**. There are no drop shadows, no elevated cards, no rounded surfaces. Hierarchy comes from:
- The 1.5px cobalt **hairline frame** (top and bottom of every slide).
- 1.5px cobalt **topbar rule** under section headers.
- 1px faint-cobalt **row dividers** between table or index entries.
- The 10%-opacity **graph paper grid** behind everything.
- The pixel-glitch and QR-block **decorative SVG patches** as compositional accents.
**Density philosophy: medium to dense, structured by the grid.** Cobalt Grid is built for editorial density — magazine spreads, trend indices, data ledgers. A correctly composed slide pairs one large Newsreader headline with multiple structured information rows (an index of six trends, a ledger of eight entries, a chart with eight pixel-stack bars). The graph paper underneath actively wants to be filled; sparse slides leave too much grid showing and read as wireframe. The exception is the manifesto, quote, and colophon layouts, which deliberately leave space open and let the graph paper breathe. Choose density by slide type: chapter / manifesto / quote / colophon are sparse; index / data / table are dense.
**Key Characteristics:**
- Cream paper canvas `{colors.paper}` with electric cobalt `{colors.ink}` as the only ink — strictly two-color.
- Permanent 28–44px graph-paper grid in 10%-opacity cobalt behind every slide.
- Top and bottom 1.5px cobalt hairlines frame every slide with `{spacing.edge}` insets.
- Newsreader serif at weight 400 for every display/headline; Hanken Grotesk sans for body/labels; DM Mono for all chrome.
- Pixel-glitch vertical scanline columns and QR-style 8×8 mosaics as the system's signature decorative patches.
- Display type can be enormous — `{typography.display-hero}` up to 18vh (≈194px on a 1080-tall display) and `{typography.vbig-numeral}` to 240px.
- Hanken labels are uppercase at 0.16–0.18em letter-spacing; mono tags carry 0.04–0.06em tracking.
- Pixel-stack bar charts render data as stacks of grid-unit cells (cobalt on / cobalt-10% off).
- Page number bottom-right, mono navigation hint bottom-left, both anchored above the bottom hairline.
## Colors
### Two-Color System
- **Paper** (`{colors.paper}` — #F0EBDE): The canvas. Warm cream off-white with a clear yellow-warm bias — closer to "newsprint paper" than "blank white." Used as the universal slide background and as the fill behind QR-blocks so they read as discrete patches against the pixel-glitch column.
- **Paper-2** (`{colors.paper-2}` — #E6E0CE): A slightly deeper cream. Defined in the palette but used sparingly — available for subtle region differentiation when needed.
- **Ink** (`{colors.ink}` — #1F2BE0): Electric cobalt / royal blue. The *only* ink color in the system. Used for all headlines, all body text, all borders, all chrome, the graph paper grid, the pixel-glitch decoration, and the QR patches. The high saturation is intentional — at full strength it reads as risograph-printed cobalt, not navy blue.
- **Ink Soft** (`{colors.ink-soft}` — #5560E5): A lighter cobalt for secondary marks. Defined in the palette but used sparingly — most softened cobalt in the system comes from opacity-on-ink rather than this dedicated tone.
- **Grid** (`{colors.grid}` — rgba(31, 43, 224, 0.10)): 10%-opacity cobalt. Used exclusively for the permanent graph-paper grid behind every slide, and for the "off" cells in pixel-stack bar charts.
- **Ink Faint** (`{colors.ink-faint}` — rgba(31, 43, 224, 0.18)): 18%-opacity cobalt. Used exclusively for the faint row dividers in index lists, tables, and ledgers — between rows that share the same dense information layer.
### Defaults
- **Default slide surface**: `{colors.paper}`.
- **Default headline color**: `{colors.ink}` — every Newsreader serif headline is cobalt. There is no other headline color.
- **Default body text color**: `{colors.ink}` — body is also cobalt, just smaller. Cobalt-on-cream is the system's only text relationship.
- **Default label / mono / micro color**: `{colors.ink}`.
- **Default border color (structural rules)**: `{colors.ink}` at 1.5px solid.
- **Default border color (row dividers within dense lists)**: `{colors.ink-faint}` at 1px solid.
- **Default grid color**: `{colors.grid}` — never visible at full strength; never disabled.
- **Default chart data color (on)**: `{colors.ink}`.
- **Default chart data color (off)**: `{colors.grid}`.
The system has **no accent color** in the populist sense. A second color does not exist — adding a red callout, a green stat, or a yellow highlight breaks the risograph two-color identity. When emphasis is needed, increase type size, switch from Hanken to Newsreader, add a mono delta arrow, or use opacity to dim rather than coloring to highlight.
## Typography
### Font Family
The system runs on a **three-face conversation**: `Newsreader` (serif, weight 400 / 500 italic) carries every display and headline; `Hanken Grotesk` (sans, weights 400–700) carries every body, label, and micro-text; `DM Mono` (monospace, 400–500) carries every chrome element. There is no fourth face.
Newsreader's roman letterforms run at weight 400 almost exclusively — the type relies on size to assert hierarchy, not weight. Italic Newsreader is loaded (300/400/500 italic axis) and is used inside the manifesto's `.roman` modifier (which is *non-italic* — the modifier flips the italic body back to roman for an inline pull moment) and is available for inline `<em>` emphasis. Hanken Grotesk carries body at 400 and labels at 600. DM Mono provides chrome at 400.
The serif/grotesk/mono three-way pairing is the system's primary typographic rhythm. Each face has a strict role: serif = statement, grotesk = supporting copy, mono = catalogue chrome.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.vbig-numeral}` | clamp(110px, min(11vw, 18vh), 240px) | Newsreader | 400 | Largest numerical display — hero stat figure |
| `{typography.display-hero}` | clamp(100px, min(11vw, 18vh), 200px) | Newsreader | 400 | Largest title — cover or hero display |
| `{typography.display-closing}` | clamp(72px, min(8.4vw, 14vh), 180px) | Newsreader | 400 | Conclusive headline on a colophon/closing layout |
| `{typography.display-chapter}` | clamp(56px, min(6vw, 10vh), 130px) | Newsreader | 400 | Section-opening or chapter title |
| `{typography.display-manifesto}` | clamp(56px, min(6.4vw, 11vh), 120px) | Newsreader | 400 | Manifesto statement display |
| `{typography.display-quote}` | clamp(50px, min(5.6vw, 9vh), 110px) | Newsreader | 400 | Pull-quote body |
| `{typography.headline-index}` | clamp(48px, min(5vw, 8.5vh), 100px) | Newsreader | 400 | Index or trend-list section header |
| `{typography.headline}` | clamp(46px, min(4.8vw, 8.2vh), 92px) | Newsreader | 400 | Data, table, or chart section header |
| `{typography.ed-callout}` | clamp(28px, min(2.8vw, 4.6vh), 50px) | Newsreader | 400 | Editorial subtitle below a hero title |
| `{typography.row-headline}` | clamp(26px, 2vw, 40px) | Newsreader | 400 | Per-row headline inside an index list |
| `{typography.table-name}` | clamp(20px, 1.6vw, 28px) | Newsreader | 400 | Per-row name cell inside a ledger table |
| `{typography.body-lede}` | clamp(15px, 1vw, 18px) | Hanken Grotesk | 400 | Lead paragraph below a chapter title |
| `{typography.body-stat}` | clamp(15px, 1vw, 17px) | Hanken Grotesk | 400 | Descriptive paragraph next to a stat figure |
| `{typography.body}` | clamp(14px, 0.95vw, 15px) | Hanken Grotesk | 400 | Standard paragraph body |
| `{typography.micro-strong}` | clamp(13px, 1vw, 16px) | Hanken Grotesk | 600 | Largest uppercase label / kicker |
| `{typography.micro}` | clamp(12px, 0.9vw, 14px) | Hanken Grotesk | 600 | Standard uppercase label / lab-tag |
| `{typography.micro-sm}` | clamp(11px, 0.75vw, 12px) | Hanken Grotesk | 600 | Smallest uppercase label / table header |
| `{typography.mono-tag}` | clamp(13px, 0.9vw, 15px) | DM Mono | 400 | Mono catalogue tag, num-tag in an index row |
| `{typography.mono-tick}` | clamp(12px, 0.85vw, 14px) | DM Mono | 400 | Mono chart tick label, vertical-stack-label entry |
| `{typography.mono-chrome}` | clamp(11px, 0.82vw, 13px) | DM Mono | 400 | Mono page number, navigation hint, secondary meta |
### Defaults
- **Default size for the primary section headline (index, data, table)**: `{typography.headline}` (clamp 46–92px) or `{typography.headline-index}` for index layouts.
- **Default size for a cover or hero display**: `{typography.display-hero}` (clamp 100–200px).
- **Default size for a chapter or section-opener title**: `{typography.display-chapter}` (clamp 56–130px).
- **Default size for paragraph body**: `{typography.body}` (clamp 14–15px).
- **Default size for any inline uppercase label**: `{typography.micro}` (clamp 12–14px) at weight 600 with 0.16em tracking.
- **Default size for any mono chrome (page number, tag, tick)**: `{typography.mono-tag}` (clamp 13–15px).
- **Default weight for Newsreader**: 400. Newsreader bold is not used.
- **Default weight for Hanken body**: 400.
- **Default weight for Hanken label**: 600.
When unsure, reach for `{typography.headline}` (clamp 46–92px) for the slide's primary section header, not `{typography.display-chapter}` (which is for chapter-opening moments only).
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Newsreader element is set at weight 400.** Newsreader at 600/700 is not used in this system. The literary-serif aesthetic depends on the open roman letterforms at modest weight.
- **Every Newsreader element is rendered in `{colors.ink}` (cobalt).** A cream serif headline does not exist.
- **Every Hanken label, kicker, lab-tag, and micro-text is uppercase with at least 0.16em letter-spacing** at weight 600. Hanken caps without tracking read as untreated.
- **Every DM Mono element is rendered in `{colors.ink}` with 0.04–0.08em letter-spacing.** Mono with tighter tracking reads as code, not editorial.
- **Every display element carries negative letter-spacing.** Display-hero at -0.008em, vbig-numeral at -0.015em, chapter / closing / manifesto / quote at -0.005em.
- **The graph-paper grid is permanent on every slide.** The `.stage::before` rule is not overridable per-slide — every composition sits on top of it.
- **The top and bottom hairlines frame every slide.** The `.hairlines::before` and `.hairlines::after` rules apply by default; they should not be suppressed.
- **Page number sits above the bottom hairline with clear vertical space.** The bottom hairline anchors at `bottom: clamp(20px, 2vh, 32px)`; the page number anchors at `bottom: clamp(48px, 4.8vh, 76px)` — they must not collide.
### Typography Principles
The Newsreader-400 + Hanken-600-uppercase-tracked + DM-Mono-tracked combination is the system's voice. Switching any of those three face/weight/case rules reads as a different design system. Italic is permitted via Newsreader italic (loaded) for inline `<em>` and for the manifesto's editorial italic-with-`.roman`-flip treatment. Underline is not used.
Line-height collapses at the top: display-hero / vbig-numeral at 0.92, display-chapter at 1.0, body at 1.5. The tight display + open body contrast is what gives the system its trend-report rhythm.
## Layout
### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Each `.slide` is absolutely positioned to fill the viewport; one slide carries `.active` (opacity 1, pointer-events auto) at a time. Transitions are 280ms opacity fades.
A `.stage` wrapper sits inside `.deck` (`position: fixed; inset: 0`) and provides the cream background plus the permanent `::before` graph-paper grid.
### Edge and Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.edge}` | clamp(36px, 3.6vw, 80px) | Standard slide edge inset for content, page number, hairlines |
| `{spacing.edge-inner}` | clamp(60px, 8vw, 160px) | Tighter inset used for manifesto-style centered statements |
| `{spacing.pad-top}` | clamp(76px, 8vh, 130px) | Top padding inside index/data/table frame, below the top hairline |
| `{spacing.pad-bottom}` | clamp(100px, 10vh, 150px) | Bottom padding inside index/data/table frame, above the bottom hairline |
| `{spacing.gap-lg}` | clamp(28px, 3vw, 56px) | Large gap between major regions inside a slide |
| `{spacing.gap-md}` | clamp(20px, 2.2vh, 36px) | Standard inter-element spacing |
| `{spacing.gap-sm}` | clamp(14px, 1.6vh, 24px) | Tight spacing — chrome bar inner gap, attribution-to-quote gap |
| `{spacing.gap-xs}` | clamp(10px, 1.2vh, 18px) | Vertical-stack row gap, smallest inter-element gap |
### Universal Chrome Frame
Every slide carries a four-piece chrome frame:
1. **Top hairline** — 1.5px solid cobalt at ≈2.6vh from top, inset by `{spacing.edge}` left/right.
2. **Bottom hairline** — 1.5px solid cobalt at ≈2vh from bottom, inset by `{spacing.edge}` left/right.
3. **Page number** — DM Mono cobalt anchored bottom-right, ≈4.8vh from bottom (above the bottom hairline).
4. **Nav hint** — DM Mono cobalt at 40% opacity anchored bottom-left, same vertical level as page number.
This frame is rendered automatically by the `.hairlines` and `.pagenum` / `.nav-hint` rules — every new slide inherits it.
A nested **`.frame` content rectangle** sits inside the chrome on index, data, table, and chapter layouts. It is absolutely positioned with `inset: {spacing.pad-top} {spacing.edge} {spacing.pad-bottom}` and serves as the actual content container.
### Composition Patterns
Within the chrome frame, content typically follows one of these compositional moves (not enumerated as available layouts — these are descriptive, not prescriptive):
- A `topbar` block (Newsreader headline left, mono lab-tag right, 1.5px cobalt rule beneath) above a main content region.
- A pixel-glitch column anchored to the right edge of the content region (or occasionally the left, as on the colophon).
- A QR-block patch as a small punctuation mark (typically top-right corner).
- A vertical-stack mono label column anchored to one edge.
- A dense ledger or index of equal-flex rows separated by faint cobalt dividers.
## Depth and Elevation
### Flat With Structural Rules
Cobalt Grid has no drop shadows, no elevated cards, no rounded surfaces, no gradients. Every element sits on a single plane.
Depth signals are entirely structural:
- **1.5px cobalt rules** — top/bottom slide hairlines, topbar rule, attribution rule.
- **1px faint cobalt dividers** — row separators inside index lists, tables, and ledgers.
- **Graph-paper grid** — the 10%-opacity cobalt background creates a sense of measured plane.
- **Pixel-glitch decoration** — vertical scanline columns add visual texture without z-axis elevation.
- **QR-block patches** — read as discrete graphic objects against the grid+glitch background due to their paper-fill and 1.5px paper-color outset shadow (which is functionally an "anti-shadow" — it pushes the grid away so the QR mosaic stays readable).
The QR-block's 1.5px paper-color outset is the *only* shadow-like effect in the system, and it exists to preserve readability against the pixel-glitch column, not to create elevation. There is no z-axis depth.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0 | Every structural element — frames, cards, ledger rows, QR cells, pixel-glitch rectangles, charts, tables |
| 50% (circle) | None — Cobalt Grid has no circular elements |
The system uses **zero rounded corners**. Every shape is a strict rectangle. This is unusual for editorial systems and is part of the trend-report identity.
### Border Weights
- **1.5px solid `{colors.ink}`** — primary structural rules: top/bottom slide hairlines, topbar bottom rule, table head row bottom border, chart baseline rule.
- **1px solid `{colors.ink}`** — attribution rules above quote bylines, manifesto attribution top border.
- **1px solid `{colors.ink-faint}`** (18% opacity) — faint row dividers between dense list / table / ledger entries.
- **1px solid `{colors.grid}`** (10% opacity) — the permanent graph-paper grid behind every slide.
- **1.5px box-shadow in `{colors.paper}`** — QR-block readability outset (functional, not decorative).
All structural borders are cobalt. Colored borders do not exist (there is no "colored" — only cobalt at different opacities).
### Decorative Element Types
**Pixel-glitch column** — A stair-stepped vertical column rendered as inline SVG. Each step is a rectangle filled with evenly-spaced cobalt vertical scanlines on cream. Steps decrease in width as the column descends (or vice versa), creating a "glitch" pixelation effect. Anchored to one edge of a slide (typically right), absolutely positioned, z-index 3, pointer-events disabled. Decorative only — sizes range from compact 16vw × full-height secondary use to 32vw × full-height signature cover decoration. Opacity 0.6–1.0 depending on context (lower opacity when used as background, full opacity when used as primary decoration).
**QR-block patch** — An 8×8 grid of cells (some `.on` = solid cobalt, some default = paper) forming a QR-code-like mosaic. Sits over a paper-fill background with 4px internal padding and 1.5px paper-color outset (which preserves readability when overlapping the pixel-glitch column). Typical size 58–100px square. Used as compositional punctuation — typically top-right corner.
**Vertical-stack label column** — A column of DM Mono labels written with `writing-mode: vertical-rl` and `text-orientation: mixed`, rotating Latin text 90° clockwise. Anchored to right edge, vertically centered, evenly spaced. Reads as catalogue-style metadata stacked along the slide edge.
**Topbar (with rule)** — A flex row containing a Newsreader headline left and a small mono lab-tag right, separated from the content below by a 1.5px solid cobalt bottom border. The universal section-header pattern.
**Frame** — An absolutely-positioned content container with `inset: {spacing.pad-top} {spacing.edge} {spacing.pad-bottom}`. Holds the slide's actual content while keeping it clear of the hairline frame, page number, and nav hint.
**Index list** — A 2×3 grid of equal-flex rows, each row a 56px num-tag column + a content column with a Newsreader row-headline and a Hanken body paragraph, separated by 1px faint-cobalt bottom borders.
**Pixel-stack bar chart** — A row of 8 vertical "stacks," each a flex column-reverse of small horizontal cells (default 10%-cobalt off, .on solid cobalt). Cell counts represent values. A 1.5px cobalt top border with mono tick labels sits beneath the bars as the axis. Renders data as pixelated bars made of grid units — directly echoes the pixel-glitch decoration.
**Ledger table** — A flex column of dense rows, each row a 5-column grid (76px num-tag / 0.6fr name / 1.4fr description / 0.7fr mood-tag / 0.5fr delta-tag), separated by 1px faint-cobalt bottom borders. Header row uses 1.5px solid cobalt. Delta tags use `↑` / `↓` / `—` prefixes via `::before`.
**Manifesto** — A centered statement in `{typography.display-manifesto}` Newsreader with an italic `<em>` body containing inline `.roman` (non-italic) emphasis moments. Below: a 1px cobalt top border with a Hanken who-tag and a mono meta-tag side-by-side.
**Quote** — A Hanken kicker above a `{typography.display-quote}` Newsreader pull, with a 1px cobalt top-border attribution row beneath. Paired with a compact pixel-glitch column at the right edge.
**Colophon** — Right-aligned closing layout. A large `{typography.display-closing}` Newsreader title aligned right with a kicker above. Pixel-glitch column anchored to left edge (mirroring the cover). Page footer with 3–4 column grid of paragraph credits.
## Do's and Don'ts
### Do
- Set every Newsreader element at weight 400 in `{colors.ink}`. The thin roman serif at modest weight is the literary register's identity.
- Render every label, kicker, and micro-text in Hanken Grotesk weight 600 uppercase with 0.16em+ letter-spacing in `{colors.ink}`.
- Render every chrome element (page number, mono tag, tick label, vertical-stack) in DM Mono with 0.04–0.08em tracking in `{colors.ink}`.
- Keep the permanent graph-paper grid behind every slide. The grid is the system — disabling it breaks the identity.
- Maintain the top and bottom 1.5px cobalt hairlines on every slide, with the page number and nav hint sitting above the bottom hairline.
- Use the pixel-glitch column as the system's primary decorative move on declarative slides (cover, chapter, quote, colophon).
- Pair pixel-glitch with a QR-block patch when the composition needs a discrete graphic anchor — the QR's paper-fill keeps it readable against the glitch lines.
- Use the `topbar + 1.5px cobalt rule` pattern as the standard section-header treatment on index, data, and table layouts.
- Use 1px faint-cobalt dividers between rows of dense lists, tables, and ledgers.
- Render charts as pixel-stack columns of grid cells (cobalt on / cobalt-10% off). The pixel-stack bar treatment echoes the decorative glitch and unifies the visual language.
### Don't
- Don't introduce a second ink color. The system is strictly two-color: cream paper + cobalt ink. A second hue breaks the risograph identity.
- Don't render a Newsreader headline at weight 600 or 700. The 400-only rule is a signature.
- Don't disable or hide the graph-paper grid. It is the canvas tone, not optional decoration.
- Don't suppress the top/bottom hairlines on a slide. They are the frame — every slide carries them.
- Don't round any corner. Every shape is a strict rectangle; the system has zero circular elements.
- Don't add drop shadows, elevated cards, or gradient fills. Depth is structural (rules + grid + glitch), not z-axis.
- Don't use Hanken caps without 0.16em+ tracking. Untracked Hanken caps read as untreated.
- Don't put the page number directly on the bottom hairline. It sits at `bottom: clamp(48px, 4.8vh, 76px)` with clear space above the hairline.
- Don't render the QR-block without its paper-fill and 1.5px paper outset. The fill is what preserves QR readability against the pixel-glitch column.
- Don't crowd the manifesto, quote, or colophon layouts. Those layouts deliberately leave grid showing — over-stuffing them breaks the contemplative register.
## Responsive Behavior
Cobalt Grid is a viewport-fluid 1920×1080 presentation system using `clamp()` and viewport-relative units throughout. There are no explicit responsive breakpoints in the source — every dimension scales between a min and max.
### Scaling Behavior
- Display-hero scales from ~100px at minimum viewport to ~200px at maximum.
- Body text scales from 14px to 15px (deliberately narrow range — body stays compact).
- Graph-paper grid scales from 28px cells (smaller viewports) to 44px cells (larger viewports), maintaining roughly 50–80 cells across the slide width.
- Edge insets scale from 36px to 80px.
- The 1.5px hairlines and 1px row dividers are fixed and do not scale.
### Presenter Behavior
- Slides cross-fade via 280ms opacity transitions.
- Navigation is JS-driven (the source includes a `.deck` / `.slide.active` pattern); typical keyboard arrow / spacebar conventions apply.
- The nav hint at bottom-left displays interaction guidance in mono cobalt at 40% opacity.
### Print / Export
Not explicitly handled. Each slide is a 100vw × 100vh block; export workflows should snapshot each slide at 1920×1080. The grid and hairline overlays should render correctly in PDF capture (no blend modes or filters).
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Newsreader 400) | Newsreader | 思源宋体 Noto Serif SC 700 | Google Fonts |
| Body / Label (Hanken Grotesk 400–600) | Hanken Grotesk | 思源宋体 Noto Serif SC 400 | Google Fonts |
| Chrome / Mono (DM Mono) | DM Mono | DM Mono (Latin/digit only — keep mono chrome in Latin) | Google Fonts |
### Mixed-Content Strategy
Use **Strategy A — single-font-stack with fallback**: declare Noto Serif SC *after* the Latin font in the same `font-family` stack so Latin glyphs render in Newsreader / Hanken Grotesk and CJK glyphs fall through to NSC automatically. Mono chrome stays Latin/digit-only — page numbers, ticks, and vertical-stack tags do not need a CJK fallback (and DM Mono has no CJK glyphs by design).
### 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=Newsreader:ital,opsz,wght@0,6..72,400..500;1,6..72,400..500&family=Hanken+Grotesk:[email protected]&family=DM+Mono:[email protected]&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
```
```css
:root {
--font-display: "Newsreader", "Noto Serif SC", Georgia, serif;
--font-body: "Hanken Grotesk", "Noto Serif SC", sans-serif;
--font-mono: "DM Mono", ui-monospace, monospace;
}
/* Headlines use Noto Serif SC 700; body uses Noto Serif SC 400. */
```
### Universal CJK Adjustments
- **Line-height**: bump CJK body line-height to ~1.7 (from 1.5) — Hanzi need more vertical breathing than Latin lowercase.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (the 0.16em+ Hanken caps tracking shatters Hanzi cadence). Keep tight tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any micro/label/kicker when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (,。:;「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick a single weight of Noto Serif SC for a given text run, never two inside one phrase.
### Aesthetic Notes
Noto Serif SC (思源宋体) is the natural Hanzi partner for Newsreader — both are quiet literary serifs with thin-thick modulation that holds at very large display sizes (up to 18vh / 240px on the vbig-numeral). The cobalt-on-cream two-color rule absorbs Chinese without negotiation because there's only one ink color to assign. NSC 700 carries display moments where Newsreader 400 would have at 100–200px; NSC 400 carries body and labels. The DM Mono chrome layer (page numbers, vertical-stack tags, ticks) intentionally stays Latin/digit-only — `编号 001` is rendered as Latin "001" in DM Mono with the Hanzi prefix in Hanken/NSC, preserving the mono catalogue chrome's "technical spec" voice. The graph-paper grid, pixel-glitch column, and QR-block decoration are content-agnostic and read identically in any language. Vertical-stack labels written with `writing-mode: vertical-rl` work for Hanzi too — Chinese is the original vertical script — but mixing Latin and Hanzi in the same vertical run will rotate the Hanzi to upright while keeping Latin rotated 90°; isolate runs by language.
### Known CJK Gap
Noto Serif SC has no italic axis (Chinese type historically has no italic), so the manifesto layout's italic-Newsreader-with-`.roman`-flip emphasis pattern collapses when content is Hanzi. Substitute a weight contrast (NSC 700 vs NSC 400) or a faint-cobalt tone (`{colors.ink-faint}`) to recover the emphasis register. Newsreader's optical-size axis (6..72) has no NSC equivalent — the literary "this is a small caption" optical refinement is unavailable for Hanzi, but at NSC's quality this is rarely noticeable.
## Iteration Guide
1. Every new slide inherits the permanent graph-paper grid, the top and bottom 1.5px cobalt hairlines, the page number bottom-right, and the nav hint bottom-left. Don't author these per-slide — they live on `.stage` and `.hairlines`.
2. Every new headline uses Newsreader at weight 400 in `{colors.ink}`. Don't bold; don't color.
3. Every new label uses Hanken Grotesk weight 600 uppercase with 0.16em+ letter-spacing in `{colors.ink}`.
4. Every new chrome element uses DM Mono in `{colors.ink}` with 0.04–0.08em tracking.
5. New content slides on index / data / table layouts use a topbar (Newsreader headline left + Hanken lab-tag right) with a 1.5px cobalt bottom rule.
6. New chart slides use the pixel-stack treatment — cobalt on / cobalt-10% off cells in column-reverse stacks. Don't introduce filled bar charts in a single solid block.
7. New declarative slides (cover, chapter, quote, colophon) use a pixel-glitch column as the primary decoration. Pair with a QR-block when the composition needs a discrete graphic anchor.
8. New row dividers in dense lists use 1px solid `{colors.ink-faint}` (18% opacity), not full-strength cobalt. Full-strength cobalt is reserved for major structural rules.
9. New components inherit the zero-radius, no-shadow, no-gradient flatness. If a component breaks any of these, redesign it before adding.
10. The system has one ink color (`{colors.ink}`) and one surface (`{colors.paper}`). New compositions should never introduce a third color or a third surface tone (paper-2 is available but rarely needed).
## Known Gaps
- The pixel-glitch column is rendered as inline SVG hand-authored per usage; there is no generative component — adjusting the stair-step pattern requires editing the SVG markup directly.
- The QR-block 8×8 cell pattern is hand-authored per usage; each instance places `.on` cells manually. There is no QR-code generation logic.
- The pixel-stack bar chart cell counts are hardcoded in markup; there is no data-binding layer translating numeric values to cell-on counts.
- The vertical-stack label column uses `writing-mode: vertical-rl`; this works in modern browsers but rendering of mixed Latin/CJK in this orientation may vary across rendering engines.
- The manifesto layout's italic-with-`.roman`-flip pattern (italic Newsreader body containing inline non-italic `.roman` spans for emphasis) is the inverse of typical italic emphasis — the rule lives in the manifesto-specific CSS and is not generalized.
- The 1.5px paper-color outset on the QR-block is a `box-shadow` used as an anti-shadow (it extends the paper fill outward to clear the grid behind the QR cells). This is the only `box-shadow` in the system and it should not be repurposed for elevation.
- The colophon's pixel-glitch column anchors to the left edge (mirroring the cover); other slides anchor to the right edge — the directionality is per-slide and should be considered when authoring new declarative layouts.
- The graph-paper grid cell size scales between 28–44px via `clamp` — at extreme aspect ratios, the grid count across the slide width may feel uneven.
- The system loads three Google Fonts families (Newsreader, Hanken Grotesk, DM Mono) with multiple weights — initial render requires successful font load to avoid Georgia/Helvetica fallback shifting the visual rhythm.
# Cobalt Grid Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/cobalt-grid/design.md`
- Preview card: `bold-template-pack/templates/cobalt-grid/preview.md`
## Selection Metadata
- Slug: `cobalt-grid`
- Tagline: Electric cobalt serifs on a graph-paper canvas, anchored by stair-stepped pixel-glitch decorations and slim hairline rules.
- Mood: editorial, design-research, studious, modernist, tech-print, monochrome
- Tone: considered, literary, studious, quietly-modern, editorial
- Formality: high
- Density: medium
- Scheme: light
- Best for: Anything that should feel like a quietly serious design / research bulletin, art publication, or curated trend report. Strong for studio annuals, agency capabilities decks, design-research publications, architecture / art / academic decks, and any deck wanting one strict accent colour and a printed-ledger calmness rather than corporate polish.
- Avoid for: Decks that need warmth, multi-colour energy, or a casual / playful voice — the strict cobalt + cream + grid palette is intentionally austere.
## Visual Snapshot
A Japanese-magazine trend-report system built on warm cream paper, electric cobalt ink, and a graph-paper grid that lives permanently behind every slide. Newsreader serif headlines tower at 18vh while DM Mono carries chrome and ticker text. The signature decoration is a pixel-glitch column — vertical scanlines stair-stepped down the right edge of declarative slides — paired with QR-style 8×8 grid patches. The cultural reference is WIRED Japan, Shift magazine, and architectural trend reports printed in two-color risograph: cream + one cobalt.
Cobalt Grid is a two-color trend-report editorial system built on three immovable foundations: a warm cream paper canvas ({colors.paper}), an electric cobalt ink ({colors.ink}), and a permanent graph-paper grid that sits behind every slide. The grid is not optional decoration — it is rendered via a ::before pseudo on every .stage and cannot be turned off. The aesthetic is "two-color risograph monograph": cream + cobalt only, with the grid lending the entire deck the feel of architectural tracing paper or a Japanese trend report.
## Preview Ingredients
- Palette: paper #F0EBDE; paper-2 #E6E0CE; ink #1F2BE0; ink-soft #5560E5
- Typography: Newsreader; Hanken Grotesk; DM Mono
- Signature move: The 1.5px cobalt hairline frame (top and bottom of every slide).
- Signature move: 1.5px cobalt topbar rule under section headers.
- Signature move: 1px faint-cobalt row dividers between table or index entries.
- Signature move: The 10%-opacity graph paper grid behind everything.
- Signature move: The pixel-glitch and QR-block decorative SVG patches as compositional accents.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Coral
description: A bold magazine-poster system that runs on three surface registers — coral fire, ink black, and warm cream — animated by Bebas Neue display caps and a constant 45° diagonal hatch pattern. Inter handles body copy; Bebas Neue handles every headline, stat, title, and meta-figure at heavy letter-spacing. The cultural reference is mid-century travel posters, Saul Bass film titles, and modern editorial sport magazines: solid color planes meeting at hard edges, oversized condensed caps as architectural elements, and a single coral hue used both as accent and as full-slide environment.
colors:
coral: "#E85D5D"
coral-dark: "#D44A4A"
cream: "#F5F0E8"
cream-dark: "#E8E0D4"
black: "#1A1A1A"
gray: "#6B6B6B"
light-gray: "#B0B0B0"
white: "#FFFFFF"
color-aliases:
bg: cream
ink: black
typography:
hero-title:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "min(120px, 9vw, 13vh)"
fontWeight: 400
lineHeight: 0.9
letterSpacing: 4px
jumbo-feature:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(80px, 15vw, 200px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 12px
display-statement:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(42px, 7vw, 100px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
section-headline:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(40px, 6vw, 80px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
column-title:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(36px, 5vw, 72px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
stat-numeral:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(48px, 7vw, 96px)"
fontWeight: 400
lineHeight: 1
card-stat:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(36px, 4vw, 56px)"
fontWeight: 400
lineHeight: 1
sidebar-value:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(28px, 3vw, 48px)"
fontWeight: 400
lineHeight: 1
card-title:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(24px, 2.5vw, 36px)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 1px
bar-title:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(28px, 4vw, 56px)"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
meta-figure:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "min(44px, 3.5vw, 5.5vh)"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
meta-date:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "min(38px, 3vw, 4.8vh)"
fontWeight: 400
lineHeight: 1
letterSpacing: 2px
background-numeral:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(100px, 15vw, 200px)"
fontWeight: 400
lineHeight: 1
description: "Decorative oversized numeral placed inside a coral region at rgba(0,0,0,0.12) — wallpaper opacity. Sits behind the actual column title at full opacity."
giant-mark:
fontFamily: "Bebas Neue, sans-serif"
fontSize: "clamp(140px, 20vw, 280px)"
fontWeight: 400
lineHeight: 1
description: "Oversized quote mark or single character placed inside a coral region at opacity 0.35 — half-decorative, half-content."
body:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(15px, 1.4vw, 20px)"
fontWeight: 400
lineHeight: 1.7
body-sm:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(13px, 1.1vw, 16px)"
fontWeight: 400
lineHeight: 1.6
body-light:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(20px, 2.5vw, 36px)"
fontWeight: 300
lineHeight: 1.5
description: "Lighter-weight Inter for pull quotes — weight 300 to contrast against the Bebas Neue dominant voice."
item-text:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(14px, 1.2vw, 18px)"
fontWeight: 400
lineHeight: 1.6
card-text:
fontFamily: "Inter, sans-serif"
fontSize: "clamp(13px, 1.1vw, 16px)"
fontWeight: 400
lineHeight: 1.6
bar-meta:
fontFamily: "Inter, sans-serif"
fontSize: "12px"
fontWeight: 400
lineHeight: 1.4
letterSpacing: 2px
textTransform: uppercase
section-label:
fontFamily: "Inter, sans-serif"
fontSize: "12px"
fontWeight: 700
lineHeight: 1
letterSpacing: 4px
textTransform: uppercase
item-label:
fontFamily: "Inter, sans-serif"
fontSize: "11px"
fontWeight: 700
lineHeight: 1
letterSpacing: 3px
textTransform: uppercase
meta-label:
fontFamily: "Inter, sans-serif"
fontSize: "11px"
fontWeight: 600
lineHeight: 1
letterSpacing: 3px
textTransform: uppercase
sidebar-label:
fontFamily: "Inter, sans-serif"
fontSize: "12px"
fontWeight: 400
lineHeight: 1.4
letterSpacing: 1px
quote-attribution:
fontFamily: "Inter, sans-serif"
fontSize: "14px"
fontWeight: 600
lineHeight: 1
letterSpacing: 3px
textTransform: uppercase
quote-role:
fontFamily: "Inter, sans-serif"
fontSize: "12px"
fontWeight: 400
lineHeight: 1.4
letterSpacing: 1px
spacing:
pad-y: "clamp(40px, 6vh, 80px)"
pad-x: "clamp(40px, 8vw, 100px)"
pad-y-tight: "clamp(28px, 4.5vh, 60px)"
pad-col: "clamp(32px, 4vw, 60px)"
gap-grid: "32px"
gap-md: "40px"
card-pad: "clamp(24px, 3vh, 40px)"
bar-pad: "clamp(24px, 4vh, 40px)"
canvas:
width: 100vw
height: 100vh
components:
diagonal-hatch:
background: "repeating-linear-gradient(45deg, transparent, transparent 20px, rgba(0,0,0,0.06) 20px, rgba(0,0,0,0.06) 40px)"
description: "Signature 45° diagonal hatch pattern in 6%-opacity black. Applied as a pseudo-element overlay on coral regions to provide texture without changing the surface color. Variant: -45° hatch on coral quote-left, with 30/60px stride. Variant: 90° vertical hatch in 10%-opacity black on coral gradient regions, with 60/62px stride. The hatch is a per-region atmospheric treatment, not a slide-level overlay."
accent-line:
width: "80px"
height: "4px"
background: "{colors.coral}"
description: "Solid 80×4 coral rectangle used as a sub-headline accent rule. Closing or section-divider variant uses 60×4."
quote-accent:
width: "60px"
height: "4px"
background: "{colors.coral}"
description: "60×4 coral rectangle placed above a quote attribution as a terminal accent."
title-rule:
width: "100%"
height: "3px"
background: "{colors.black}"
opacity: 0.15
description: "Full-width 3px ink rule at 15% opacity used as a subtle horizontal divider beneath the hero title on the cover composition."
card:
background: "{colors.white}"
padding: "{spacing.card-pad}"
borderTop: "5px solid {colors.coral}"
description: "Column card — white surface with a 5px solid coral top border as the only border on the element. No shadow, no radius."
sidebar-item:
background: "{colors.white}"
padding: "20px 24px"
borderLeft: "4px solid {colors.coral}"
description: "Compact data tile — white surface with a 4px solid coral left border. Holds a Bebas value and an Inter label."
card-icon:
width: "48px"
height: "48px"
background: "{colors.coral}"
fontFamily: "Bebas Neue, sans-serif"
fontSize: "24px"
color: "{colors.white}"
description: "48px solid coral square (no radius) containing a 1-character Bebas Neue glyph in white. Used as a card mark."
timeline-line:
height: "4px"
background: "{colors.black}"
description: "Horizontal 4px solid ink line spanning the timeline width. A ::after pseudo overlays a repeating linear-gradient (20px ink + 10px transparent) to create a dashed effect. The dashed pattern is rendered through the gradient, not the border-style."
t-point-dot:
width: "20px"
height: "20px"
borderRadius: "50%"
background: "{colors.coral}"
border: "4px solid {colors.cream}"
description: "Timeline node — 20px coral circle with a 4px cream halo, sitting on the timeline-line."
nav-dot:
width: "10px"
height: "10px"
borderRadius: "50%"
background: "rgba(255, 255, 255, 0.3)"
border: "2px solid rgba(255, 255, 255, 0.5)"
description: "Small 10px nav indicator. White-translucent default on dark/coral surfaces; ink-translucent .dark variant on cream surfaces. Active state fills with coral."
nav-arrow:
width: "44px"
height: "44px"
borderRadius: "50%"
background: "rgba(255, 255, 255, 0.1)"
border: "2px solid rgba(255, 255, 255, 0.3)"
description: "44px circular nav button with translucent fill and 2px translucent border. .dark variant for cream surfaces. Hover state fills with coral."
zigzag-layer:
description: "SVG zigzag pattern overlay used decoratively on the cover's coral top-section. Renders as a thin black zigzag line at low opacity behind the title."
pattern-overlay:
description: "Decorative repeating-pattern overlay applied to feature regions — typically 90° vertical hatch in ink at 10% opacity on coral gradient backgrounds. Separate from the 45° diagonal-hatch which is the system's primary texture."
bar-fill:
description: "Chart.js horizontal bar fills use solid coral (#E85D5D) as the primary series color, with a darker coral (#D44A4A) for comparison or secondary series."
---
## 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
Coral is a **bold magazine-poster system** built on three surface registers — coral fire, ink black, and warm cream — that meet at hard edges. The defining structural premise is **solid color planes**: a single slide will split into a coral half + a cream half + an ink top-section, with each region a flat solid color holding its own self-contained composition. There are no gradient transitions between regions; the meeting point of two colors is the layout. This is the populist counterpart to a more refined editorial system — closer to a sports magazine cover than a literary catalogue.
The typeface stack is a **two-face hierarchy**. **Bebas Neue** — a tall narrow condensed sans display face — carries every headline, every stat, every column title, every meta figure, every section name. Bebas runs at its single available weight (400) and is treated as architectural — heavy letter-spacing (2–12px), oversized scale (up to 200px on jumbo features), and always set in its native uppercase. **Inter** — a contemporary humanist sans — carries every body paragraph, every label, every micro-text, every attribution. Inter spans weights 300 to 700: 300 for pull-quote bodies, 400 for paragraph body, 600 for meta labels, 700 for section eyebrows. The Bebas/Inter pair creates the system's voice: Bebas declares, Inter explains.
The palette is **three surfaces + ink + neutrals**. The coral `{colors.coral}` is both *the* accent (a 4px left border on a sidebar tile, a 5px top border on a card, a 48px solid icon square) and an entire slide environment (a full coral panel, the cover's top-section, a coral gradient feature region). The cream `{colors.cream}` is the warm canvas — the magazine paper. Ink `{colors.black}` is the strongest surface, used as full-slide background on quote and statement layouts. White appears only as card fills against coral or cream regions. Two grays (`{colors.gray}`, `{colors.light-gray}`) carry body and meta text.
Depth is **flat with hard color edges**. There are no drop shadows, no rounded surfaces, no soft elevations. Hierarchy comes from:
- **Solid color region splits** — coral / ink / cream regions meeting at hard edges.
- **Accent borders** — 4px coral left, 5px coral top, 3px ink top, 4px ink horizontal.
- **45° diagonal hatch** — a signature 6%-opacity black diagonal repeating pattern overlaid on coral regions, providing texture.
- **Oversized decorative typography** — background numerals at 12% opacity, giant quote marks at 35% opacity, sitting behind or beside primary content.
**Density philosophy: medium-high, structured by region.** Coral slides are structured rather than dense — each color region holds a self-contained composition (a single column title with one body block, a single stat tile with one label, a single timeline line with five dots). The aesthetic relies on regions feeling fully populated within their boundary, not on the slide overall being crowded. A correctly composed slide pairs 2–3 substantive regions, each fully expressed. A slide that feels broken is one where a coral region holds only a sparse fragment, or where a cream region attempts to carry too many competing elements. Decorative oversized numerals at 12% opacity behind a region's primary title are the standard "fill the region" move when content alone doesn't fully occupy the plane.
**Key Characteristics:**
- Three-surface system: `{colors.coral}` (fire), `{colors.black}` (ink), `{colors.cream}` (paper) — used as solid regions meeting at hard edges.
- Bebas Neue uppercase condensed display for every headline/stat/title; Inter sans for every body/label/attribution.
- 45° diagonal hatch in 6%-opacity black on coral regions as the signature atmospheric texture.
- Coral as both accent (4–5px borders, 48px icon squares, 4-point timeline dots) and environment (full-region surfaces).
- Decorative oversized numerals at 12% opacity behind column titles inside coral regions.
- Oversized quote marks at 35% opacity inside coral regions as half-decorative content.
- No rounded corners on rectangles; circular shapes only for nav dots, nav arrows, and timeline nodes.
- Heavy letter-spacing on every Bebas element: 1–4px on most, 12px on the largest feature treatment.
- Hard-edge color splits (vertical, horizontal, or 40/60 ratios) define slide composition.
## Colors
### Three-Surface System
- **Coral** (`{colors.coral}` — #E85D5D): The signature color — a warm orange-red, vivid but not neon. Used both as accent (4px sidebar-item left border, 5px card top border, 48px card-icon fill, 80×4 accent line, 60×4 quote accent, timeline-point dot, chart primary series, hover-state fills, section eyebrows, stat-numerals on cream surfaces) and as a full-region surface (cover top-section, two-column left panel, full-width feature region, quote left panel). Defines the system.
- **Coral Dark** (`{colors.coral-dark}` — #D44A4A): A darker coral variant. Used as the start stop in linear-gradient feature regions (135° from coral-dark to coral), and as the chart secondary/comparison series color.
- **Cream** (`{colors.cream}` — #F5F0E8): The warm canvas. Used as default slide background, as the cover's bottom-section, as info-bar surfaces, as body text color on ink-black surfaces, and as the timeline-point dot halo.
- **Cream Dark** (`{colors.cream-dark}` — #E8E0D4): A slightly deeper cream. Available in the palette for subtle region differentiation but sparingly used.
- **Black** (`{colors.black}` — #1A1A1A): Near-black ink. Used as headline color on cream surfaces, as the full-background ink register for quote and certain feature slides, as timeline-line color, as title-rule color, as decorative background-numeral color (at 12% opacity inside coral regions), and as giant-mark color (at 35% opacity inside coral regions).
- **Gray** (`{colors.gray}` — #6B6B6B): Mid neutral. Used for body paragraph text on cream surfaces, for meta labels, for sidebar labels, for card body copy, for quote roles.
- **Light Gray** (`{colors.light-gray}` — #B0B0B0): Pale neutral. Defined in the palette but used sparingly — available for tertiary text where gray is too strong.
- **White** (`{colors.white}` — #FFFFFF): True white. Used as card fills (sidebar-item, card, column-card), as item-text color on ink surfaces, as nav-dot/nav-arrow translucent fills.
### Defaults
- **Default slide surface**: `{colors.cream}`. (Cover and feature slides use mixed-surface compositions; statement, quote, and three-column slides default to cream or ink.)
- **Default headline color on cream surfaces**: `{colors.black}` — Bebas Neue headlines are ink, not coral.
- **Default headline color on coral surfaces**: `{colors.black}` — ink-on-fire. Bebas on coral is always ink, never white.
- **Default headline color on ink surfaces**: `{colors.cream}`.
- **Default body text color on cream surfaces**: `{colors.gray}`.
- **Default body text color on ink surfaces**: `{colors.cream}`.
- **Default body text color on coral surfaces**: `{colors.black}` — ink, not white.
- **Default eyebrow / section-label color**: `{colors.coral}` on cream and ink surfaces; `{colors.black}` on coral surfaces.
- **Default accent border color**: `{colors.coral}` — 4px left (sidebar tiles), 5px top (cards), 48px solid (icon squares).
- **Default decorative numeral color inside a coral region**: `rgba(0, 0, 0, 0.12)` (ink at 12% opacity).
- **Default giant-mark color inside a coral region**: `rgba(0, 0, 0, 0.35)` (ink at 35% opacity).
- **Default chart primary series color**: `{colors.coral}`.
- **Default chart comparison series color**: `{colors.coral-dark}`.
The three surfaces are intermixed by composition: a slide may be split coral/cream, coral/ink, ink/cream, or held to a single surface. There is no semantic mapping between surfaces; each is chosen for compositional balance and contrast.
## Typography
### Font Family
The system runs on a **two-face hierarchy**: `Bebas Neue` (display, single weight 400) carries every headline, stat numeral, column title, meta figure, bar title, card stat, sidebar value, and decorative numeral; `Inter` (sans, weights 300 / 400 / 600 / 700) carries every body paragraph, label, eyebrow, meta-label, attribution, role, and chart legend. There is no third face.
Bebas Neue is a tall narrow condensed sans display face — its narrow letterforms allow large sizes without overwhelming the slide width, and its single available weight (400) is treated as the system's only weight. Bebas is always set in its native uppercase. The display character of the system comes from heavy letter-spacing (1–4px on standard headlines, 12px on the largest jumbo feature treatment) and oversized scale (up to 200–280px on jumbo / giant-mark moments).
Inter carries the supporting voice with weight contrast: 300 for pull-quote bodies (a lighter register against Bebas's dominance), 400 for body paragraphs, 600 for meta labels, 700 for section eyebrows. Italic and underline are not used.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.giant-mark}` | clamp(140px, 20vw, 280px) | Bebas Neue | 400 | Oversized decorative quote mark or feature character inside a coral region |
| `{typography.jumbo-feature}` | clamp(80px, 15vw, 200px) | Bebas Neue | 400 | Single dominant word filling a feature region |
| `{typography.background-numeral}` | clamp(100px, 15vw, 200px) | Bebas Neue | 400 | Decorative wallpaper numeral inside a coral region at 12% opacity |
| `{typography.hero-title}` | min(120px, 9vw, 13vh) | Bebas Neue | 400 | Largest cover title — 3-line title cap-and-line-broken |
| `{typography.display-statement}` | clamp(42px, 7vw, 100px) | Bebas Neue | 400 | Big declarative statement on a cream surface |
| `{typography.stat-numeral}` | clamp(48px, 7vw, 96px) | Bebas Neue | 400 | Hero stat figure |
| `{typography.section-headline}` | clamp(40px, 6vw, 80px) | Bebas Neue | 400 | Primary section headline |
| `{typography.column-title}` | clamp(36px, 5vw, 72px) | Bebas Neue | 400 | Column or panel title inside a region |
| `{typography.card-stat}` | clamp(36px, 4vw, 56px) | Bebas Neue | 400 | Per-card stat figure |
| `{typography.bar-title}` | clamp(28px, 4vw, 56px) | Bebas Neue | 400 | Info-bar title |
| `{typography.sidebar-value}` | clamp(28px, 3vw, 48px) | Bebas Neue | 400 | Sidebar tile value |
| `{typography.card-title}` | clamp(24px, 2.5vw, 36px) | Bebas Neue | 400 | Card or column-card title |
| `{typography.meta-figure}` | min(44px, 3.5vw, 5.5vh) | Bebas Neue | 400 | Cover meta value (location, date, brand) |
| `{typography.meta-date}` | min(38px, 3vw, 4.8vh) | Bebas Neue | 400 | Cover date variant |
| `{typography.body-light}` | clamp(20px, 2.5vw, 36px) | Inter | 300 | Pull-quote body (lighter weight against Bebas dominance) |
| `{typography.body}` | clamp(15px, 1.4vw, 20px) | Inter | 400 | Standard paragraph body |
| `{typography.item-text}` | clamp(14px, 1.2vw, 18px) | Inter | 400 | Item body on ink surfaces |
| `{typography.card-text}` | clamp(13px, 1.1vw, 16px) | Inter | 400 | Card body copy |
| `{typography.body-sm}` | clamp(13px, 1.1vw, 16px) | Inter | 400 | Compact body |
| `{typography.section-label}` | 12px | Inter | 700 | Section eyebrow above a headline, 4px letter-spacing |
| `{typography.item-label}` | 11px | Inter | 700 | Item eyebrow in a list, 3px letter-spacing |
| `{typography.meta-label}` | 11px | Inter | 600 | Cover meta label, 3px letter-spacing |
| `{typography.quote-attribution}` | 14px | Inter | 600 | Author name below a pull quote, 3px letter-spacing |
| `{typography.bar-meta}` | 12px | Inter | 400 | Info-bar meta-text, 2px letter-spacing |
| `{typography.sidebar-label}` | 12px | Inter | 400 | Sidebar tile label, 1px letter-spacing |
| `{typography.quote-role}` | 12px | Inter | 400 | Author role below quote attribution, 1px letter-spacing |
### Defaults
- **Default size for the primary section headline**: `{typography.section-headline}` (clamp 40–80px).
- **Default size for a cover/hero title**: `{typography.hero-title}` (min(120px, 9vw, 13vh)).
- **Default size for a feature dominant word**: `{typography.jumbo-feature}` (clamp 80–200px) with 12px letter-spacing.
- **Default size for paragraph body**: `{typography.body}` (clamp 15–20px).
- **Default size for any uppercase eyebrow / label**: `{typography.section-label}` (12px) at weight 700 with 4px letter-spacing; or `{typography.item-label}` (11px) at weight 700 with 3px letter-spacing for in-list contexts.
- **Default weight for any Bebas Neue element**: 400 (the only available weight).
- **Default weight for body**: 400; for pull quotes, 300.
- **Default weight for labels**: 600 or 700.
- **Default size for a hero stat figure**: `{typography.stat-numeral}` (clamp 48–96px).
- **Default size for an in-card stat figure**: `{typography.card-stat}` (clamp 36–56px).
When unsure, reach for `{typography.section-headline}` for the slide's primary text moment.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Bebas Neue element is set in its native uppercase.** Bebas Neue in sentence case does not exist — the typeface itself doesn't support it. This is the system's most foundational typographic rule.
- **Every Bebas Neue element carries letter-spacing of at least 1px.** Standard headlines at 2px, hero-title at 4px, jumbo-feature at 12px. Untracked Bebas reads as untreated.
- **Every Inter label, eyebrow, and meta-text is uppercase with 1–4px letter-spacing.** Section labels at 4px, item labels at 3px, bar-meta at 2px, sidebar-labels at 1px. Inter caps without tracking break the editorial register.
- **Every Bebas headline is rendered in `{colors.black}`, `{colors.cream}`, or `{colors.coral}`** based on surface contrast — never gray. Color choice: ink on cream/coral, cream on ink, coral on cream when emphasis is needed.
- **Every section eyebrow is rendered in `{colors.coral}`** when sitting on cream or ink, or in `{colors.black}` when sitting on coral. Coral-on-coral does not exist.
- **Every decorative oversized numeral inside a coral region is rendered at `rgba(0, 0, 0, 0.12)`** — the wallpaper-numeral signature. Sits behind primary content at full opacity.
- **Every giant decorative mark (quote, single character) inside a coral region is rendered at `rgba(0, 0, 0, 0.35)`** — half-decorative, half-content.
- **Pull-quote bodies use Inter weight 300, not Bebas.** This is the system's primary "voice break" — when content needs to feel personal rather than declarative, Inter Light takes over.
### Typography Principles
The Bebas-uppercase-tracked + Inter-mixed-weight combination is the system's voice. Switching either face — using a different display sans for headlines, or using Bebas for body — breaks the system entirely. Italic does not appear. Underline does not appear. The only emphasis mechanism is weight (Bebas dominance), case (uppercase always on Bebas + labels), color (coral on cream surfaces), and surface inversion (placing the element in a different region).
Line-height is uniformly tight at the top of the scale: Bebas elements at 0.9–1.0; Inter body at 1.6–1.7. The display compression + open body is what gives the system its magazine-poster rhythm.
## Layout
### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Each `.slide` is absolutely positioned to fill the viewport; one slide carries `.active` (opacity 1, visibility visible) at a time. Transitions are 0.6s opacity + visibility fades.
The system has **no universal chrome bar**. Each slide is its own self-contained composition with its own padding, region structure, and color treatment. Navigation is per-page (nav arrows + nav dots + slide counter) and floats over the active surface with `.dark` variants for cream surfaces.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-y}` | clamp(40px, 6vh, 80px) | Standard vertical slide padding |
| `{spacing.pad-x}` | clamp(40px, 8vw, 100px) | Standard horizontal slide padding |
| `{spacing.pad-y-tight}` | clamp(28px, 4.5vh, 60px) | Compact vertical padding (cover bottom-section) |
| `{spacing.pad-col}` | clamp(32px, 4vw, 60px) | Column padding inside a region |
| `{spacing.gap-grid}` | 32px | Column-grid gap |
| `{spacing.gap-md}` | 40px | Chart container internal gap |
| `{spacing.card-pad}` | clamp(24px, 3vh, 40px) | Card internal padding |
| `{spacing.bar-pad}` | clamp(24px, 4vh, 40px) | Info-bar internal padding |
### Region Composition
Coral's primary layout move is **multi-surface composition**. Slides split into regions of solid color, with the boundary between regions defining the layout. Standard splits include:
- `grid-template-rows: 32% 68%` — top accent strip + main body (cover composition).
- `grid-template-rows: 1fr auto` — large feature region + bottom info-bar.
- `grid-template-columns: 1fr 1fr` — equal vertical split (often coral left + ink right).
- `grid-template-columns: 40% 60%` — narrow accent column + wider content column (quote layout).
- Single-surface slides — cream or ink as the whole canvas (statement, three-column, timeline layouts).
The boundary between regions is always a **hard color edge** — no soft transitions, no gradients across the boundary, no rounded corners at the junction. The meeting of two solid colors is the layout structure.
## Depth and Elevation
### Flat With Hard Color Edges
Coral has no drop shadows, no soft elevations, no rounded surfaces. Every element sits on a single plane.
Depth signals are entirely structural:
- **Hard color region boundaries** — the primary structural signal.
- **Accent borders** — 5px coral top on cards, 4px coral left on sidebar tiles, 4px ink horizontal timeline-line, 3px ink at 15% opacity title-rule.
- **45° diagonal hatch** — 6%-opacity black diagonal repeating-linear-gradient overlay on coral regions creates texture without depth.
- **Decorative wallpaper typography** — oversized numerals at 12% opacity and giant marks at 35% opacity sit behind primary content as wallpaper, creating a layered effect without z-index trickery.
Introducing a box-shadow, an elevated card, or a soft gradient breaks the populist-poster aesthetic that defines the system.
### Atmospheric Hatch Variants
The 45° diagonal hatch is the system's primary atmospheric treatment, but several stride/angle variants appear:
- **45° at 20/40px stride** in 6%-opacity black — the standard coral region overlay.
- **-45° at 30/60px stride** in 6%-opacity black — coral quote-left panel variant.
- **90° vertical at 60/62px stride** in 10%-opacity black — coral gradient feature-region overlay.
All hatches are subtle (6–10% opacity black). They provide texture without competing with content.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 50% (circle) | Circular elements only: `nav-dot` (10px), `nav-arrow` (44px), `t-point-dot` (20px timeline node) |
| 0 | Everything else: every region, every card, every sidebar tile, every icon square, every chart, every accent line, every accent border |
The system uses **only two radius values**: 50% (true circle) or 0 (sharp rectangle). Soft-rounded corners do not exist. Cards, icon squares, info-bars, and feature regions are all strict rectangles.
### Border Weights
- **5px solid `{colors.coral}` (top)** — used on card top borders (column-card pattern).
- **4px solid `{colors.coral}` (left)** — used on sidebar-item left borders.
- **4px solid `{colors.black}` (horizontal)** — used on timeline-line.
- **4px solid `{colors.cream}` (ring)** — used as the halo around 20px coral timeline-point dots.
- **3px solid `{colors.black}` at 15% opacity** — used on title-rule beneath the cover hero title.
- **2px solid translucent** — used on nav-dot and nav-arrow borders (rgba(255,255,255,0.3–0.5) on dark surfaces; rgba(26,26,26,0.2–0.4) on cream surfaces).
All borders are either coral, black, cream, or translucent. There is no border-radius on bordered rectangles.
### Decorative Element Types
**45° diagonal hatch** — A `repeating-linear-gradient(45deg, transparent, transparent 20px, rgba(0,0,0,0.06) 20px, rgba(0,0,0,0.06) 40px)` applied as a `::before` pseudo-element overlay on coral regions. The signature atmospheric texture. Variants: -45°, 90° vertical, different stride widths.
**Background numeral** — An oversized Bebas Neue numeral (clamp 100–200px) at `rgba(0, 0, 0, 0.12)` placed inside a coral region. Sits behind the region's primary column-title at full opacity, creating a layered "ordinal wallpaper" effect.
**Giant mark** — An oversized Bebas Neue character (clamp 140–280px) at `rgba(0, 0, 0, 0.35)` placed inside a coral region. Used as a half-decorative half-content element, typically a quotation mark on the coral left panel of a quote layout.
**Card (column-card)** — A white-fill rectangle with a 5px coral top border as its only border. Contains a 48px solid coral icon square at top, a Bebas card-title, an Inter card-text body, and a coral card-stat figure at the bottom. The 5px top border is the only chrome — no other border, no shadow, no radius.
**Sidebar item** — A white-fill rectangle with a 4px coral left border as its only border. Contains a Bebas sidebar-value and an Inter sidebar-label. The 4px left border is the only chrome.
**Icon square** — A 48px solid coral rectangle (no radius) containing a 1-character Bebas glyph in white. Used as a card mark.
**Info bar** — A flex row spanning a region's full width, holding a Bebas bar-title left and an uppercase Inter bar-meta right. Cream background; used as a footer band beneath a feature region.
**Timeline** — A 4px solid ink horizontal line spanning the timeline width, with a `::after` repeating-linear-gradient overlay (20px ink + 10px transparent) creating a dashed effect. Timeline points are 20px coral circles with 4px cream halos, distributed evenly along the line.
**Accent line** — An 80×4 solid coral rectangle used as a sub-headline accent rule, or 60×4 for closing/quote contexts. Always coral, always solid, no radius.
**Title rule** — A full-width 3px solid ink line at 15% opacity, used as a subtle horizontal divider beneath the cover hero title.
**Zigzag layer** — An SVG zigzag pattern rendered as a thin ink line at low opacity, overlaid decoratively on the cover's coral top-section.
**Pattern overlay** — A separate repeating-pattern overlay (typically 90° vertical hatch in 10%-opacity ink) applied to coral gradient feature regions. Distinct from the standard 45° diagonal hatch.
## Do's and Don'ts
### Do
- Compose slides as multi-surface region splits — coral, ink, and cream meeting at hard color edges. The region boundary is the layout structure.
- Set every Bebas Neue element in its native uppercase with at least 1px letter-spacing — 2px for standard headlines, 4px for hero titles, 12px for jumbo feature treatments.
- Render every section eyebrow in `{colors.coral}` uppercase Inter weight 700 with 3–4px letter-spacing on cream and ink surfaces.
- Apply the 45° diagonal hatch (6% opacity black, 20/40px stride) as a `::before` overlay on coral regions for atmospheric texture.
- Use the 5px coral top border on cards and the 4px coral left border on sidebar tiles as the only chrome on those elements — no other border, no shadow, no radius.
- Place oversized decorative Bebas numerals at 12% opacity behind column titles inside coral regions when a region needs more visual weight than the title alone provides.
- Use Inter weight 300 (light) for pull-quote bodies on ink-surface quote layouts — the lighter weight contrasts against Bebas dominance.
- Render Bebas headlines on coral surfaces in `{colors.black}` (ink-on-fire). White headlines on coral do not exist in this system.
- Use the coral chart series + coral-dark comparison series convention for any chart data.
- Use the 48px solid coral icon square (no radius, single white Bebas glyph) as the standard card mark.
### Don't
- Don't render Bebas Neue in sentence case. The typeface is uppercase only — that is the entire identity.
- Don't render Bebas without letter-spacing. Untracked Bebas reads as untreated, even at large sizes.
- Don't introduce a fourth surface color. The three surfaces (coral / ink / cream) are the system — adding a yellow or blue region breaks the magazine-poster identity.
- Don't render headlines in `{colors.gray}`. Headlines are ink, cream, or coral; gray is reserved for body and meta text only.
- Don't add drop shadows, elevated cards, or rounded surfaces. The system is flat — depth comes from color region splits and accent borders.
- Don't round any rectangular element. Cards, sidebar tiles, info bars, icon squares, accent lines — all sharp rectangles.
- Don't pair Bebas with a different sans body face. The Bebas + Inter pairing is fixed.
- Don't render Inter labels in sentence case. Small Inter text is always uppercase with 1–4px tracking.
- Don't soften region boundaries with gradients (except in the rare 135° coral-dark → coral feature gradient). Region edges are hard color meetings.
- Don't fill a coral region with sparse content. Coral wants weight — either fully populate the region's composition or use a decorative oversized numeral / giant mark as wallpaper.
## Responsive Behavior
Coral is a viewport-fluid 1920×1080 presentation system using `clamp()`, `min()`, and viewport-relative units throughout. There are no explicit responsive breakpoints in the source — every dimension scales between minimum and maximum bounds.
### Scaling Behavior
- Hero title scales via `min(120px, 9vw, 13vh)` — capped by both width and height so the 3-line title cannot overflow a short laptop screen.
- Jumbo feature scales from 80px at minimum viewport to 200px at maximum.
- Body text scales from 15px to 20px.
- Padding scales via `clamp` per-region.
- Borders, icon squares (48px), nav dots (10px), nav arrows (44px), and timeline dots (20px) are fixed and do not scale.
### Presenter Behavior
- Slides advance via `ArrowRight` or `Space`.
- Slides reverse via `ArrowLeft`.
- Nav-dots float at right edge; nav-arrows at bottom-left; slide counter at bottom-right. All three carry `.dark` variants for cream surfaces (ink-translucent fills) and standard variants for coral/ink surfaces (white-translucent fills).
- Active nav-dot fills with `{colors.coral}` regardless of surface.
### Charts
Charts are rendered with Chart.js (loaded via CDN). Primary series uses `{colors.coral}`; comparison series uses `{colors.coral-dark}`. Chart styling is configured inline in the JS; restyling requires editing JS, not CSS.
### Print / Export
Not explicitly handled. Each slide is a 100vw × 100vh block; export workflows should snapshot each slide at 1920×1080. The 45° hatch overlays should render correctly in PDF capture.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Bebas Neue uppercase 400) | Bebas Neue | 站酷小薇体 ZCOOL XiaoWei | Google Fonts |
| Body / Label (Inter 300–700) | Inter | 悠哉字体 Yozai | cn-fontsource CDN |
### Mixed-Content Strategy
Use **Strategy A — single-font-stack with fallback**: declare ZCOOL XiaoWei *after* Bebas Neue and Yozai *after* Inter in the same `font-family` stack so Latin glyphs render in Bebas / Inter and CJK glyphs fall through to the Chinese face automatically. One CSS rule per role, no manual class switching.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Inter:[email protected]&family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-yozai-regular/font.css" rel="stylesheet">
```
```css
:root {
--font-display: "Bebas Neue", "ZCOOL XiaoWei", sans-serif;
--font-body: "Inter", "Yozai", sans-serif;
}
```
### Universal CJK Adjustments
- **Line-height**: bump CJK body line-height to ~1.8 (from 1.7) — Hanzi need more vertical breathing than Latin lowercase, and Coral's body already favors generous leading.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (the 1–12px Bebas tracking and 1–4px Inter tracking shatter Hanzi cadence). Keep heavy tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any label/eyebrow/meta when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (,。:;「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick ZCOOL XiaoWei *or* Yozai for a given text run based on its role, never both inside one phrase.
### Aesthetic Notes
ZCOOL XiaoWei carries the magazine-poster voice that Bebas Neue provides for Latin — its tall narrow Hanzi forms have a similar architectural-display register, and at the 80–200px sizes Coral uses for jumbo features, ZCOOL XiaoWei holds shape without crumbling the way a system Hanzi face would. Critically, Bebas Neue's "uppercase only with heavy tracking" rule is meaningless for Hanzi (no case, no tracking), so the system's most foundational typographic rule simply doesn't apply to CJK — drop the tracking, drop the uppercase, and let ZCOOL XiaoWei stand on size alone. Yozai pairs with Inter for body and labels: its rounded humanist forms match Inter's warmth and stay legible inside coral / cream / ink surfaces. The three-surface region splits, 45° diagonal hatch, decorative oversized numerals (which can stay Latin — 01, 02, 03 work perfectly as wallpaper behind a Chinese column title), and 5px coral top borders are all content-agnostic and work identically in any language.
### Known CJK Gap
ZCOOL XiaoWei is a single-weight display face with limited glyph coverage compared to Noto family — exotic or technical Hanzi (rare surnames, classical characters, simplified-only variants outside GB2312) may fall back to system font. For Traditional Chinese decks, swap Yozai for `LXGW WenKai TC` (Google Fonts) which has fuller TC coverage. Bebas Neue's narrow condensed proportion has no exact Chinese equivalent — ZCOOL XiaoWei is medium-condensed at best, so Chinese hero titles will occupy ~20% more horizontal space than Latin equivalents. Adjust line-breaks (typically a 2-line Chinese title fills the same area as a 3-line English hero-title) and consider increasing the hero-title `min()` cap when a Chinese title runs long.
## Iteration Guide
1. Every new slide is a composition of one to three surface regions (coral, ink, cream) meeting at hard edges. Choose the surface split based on content emphasis.
2. Every new headline uses Bebas Neue uppercase with at least 1–2px letter-spacing. Don't sentence-case; don't untracked.
3. Every new section eyebrow uses Inter weight 700 uppercase 4px-tracked in `{colors.coral}` on cream/ink, or `{colors.black}` on coral.
4. Every new card uses the 5px coral top border + white fill + no shadow + no radius pattern.
5. Every new sidebar tile uses the 4px coral left border + white fill + no radius pattern.
6. Every new coral region carries a 45° diagonal hatch overlay at 6% opacity for texture.
7. New coral regions that feel underweight get a decorative oversized Bebas numeral at 12% opacity as wallpaper behind the primary title.
8. New chart series use coral + coral-dark; don't introduce additional series colors.
9. New quote layouts pair a coral left panel (with a giant mark at 35% opacity) with an ink or cream right panel (carrying the quote body in Inter weight 300).
10. The system has three surfaces and one accent (coral). Don't introduce a fourth surface color or a second accent.
## Known Gaps
- The Chart.js library is loaded via CDN; chart styling is configured inline in JS rather than reading from CSS variables — restyling requires editing JS.
- The 45° diagonal hatch stride values (20px/40px standard; 30px/60px variant; 60px/62px vertical) are hardcoded per usage; there is no parameterized hatch component.
- Decorative oversized numerals are placed as inline content with hardcoded values; there is no generative ordinal system.
- The cover composition's SVG zigzag-layer is an inline SVG embedded in the source — adjusting the zigzag pattern requires editing SVG markup.
- The timeline-line's dashed effect is rendered via a `::after` repeating-linear-gradient overlay rather than `border-style: dashed` — this gives precise control over dash dimensions but is unusual.
- The cover composition uses `min(120px, 9vw, 13vh)` triple-cap sizing to prevent the 3-line title from overflowing on short laptops; new cover variants should follow the same multi-axis cap pattern.
- The pull-quote layout uses Inter weight 300; Inter weight 300 is loaded explicitly but not used elsewhere — this is the system's only Inter Light deployment.
- The `cream-dark` and `light-gray` palette tokens are defined but used sparingly across the source; they are available for new compositions that need additional neutral shades.
- The nav-dot and nav-arrow `.dark` variant must be manually applied on cream-surface slides to maintain visibility — there is no automatic surface detection.
- Linear-gradient feature regions (135° coral-dark → coral) are the system's only intentional gradient; all other surfaces are flat colors. Using gradients elsewhere breaks the flat-surface aesthetic.
# Coral Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/coral/design.md`
- Preview card: `bold-template-pack/templates/coral/preview.md`
## Selection Metadata
- Slug: `coral`
- Tagline: Cream and coral on near-black, set in oversized Bebas Neue.
- Mood: bold, warm, modern, confident
- Tone: graphic, punchy, magazine
- Formality: medium
- Density: medium
- Scheme: mixed
- Best for: Anything that should feel warm-graphic and editorial: fashion, beauty, fitness, F&B, lifestyle brands, agency credentials. Just as strong for a creator portfolio, a manifesto, or a tech / research deck that wants warmth and a single bold accent instead of corporate cool.
- Avoid for: Contexts that should feel quiet or institutional — the coral accent and oversized Bebas Neue commit hard to a confident magazine voice.
## Visual Snapshot
A bold magazine-poster system that runs on three surface registers — coral fire, ink black, and warm cream — animated by Bebas Neue display caps and a constant 45° diagonal hatch pattern. Inter handles body copy; Bebas Neue handles every headline, stat, title, and meta-figure at heavy letter-spacing. The cultural reference is mid-century travel posters, Saul Bass film titles, and modern editorial sport magazines: solid color planes meeting at hard edges, oversized condensed caps as architectural elements, and a single coral hue used both as accent and as full-slide environment.
Coral is a bold magazine-poster system built on three surface registers — coral fire, ink black, and warm cream — that meet at hard edges. The defining structural premise is solid color planes: a single slide will split into a coral half + a cream half + an ink top-section, with each region a flat solid color holding its own self-contained composition. There are no gradient transitions between regions; the meeting point of two colors is the layout. This is the populist counterpart to a more refined editorial system — closer to a sports magazine cover than a literary catalogue.
## Preview Ingredients
- Palette: coral #E85D5D; coral-dark #D44A4A; cream #F5F0E8; cream-dark #E8E0D4; black #1A1A1A; gray #6B6B6B; light-gray #B0B0B0; white #FFFFFF
- Typography: Bebas Neue; Inter
- Signature move: Solid color region splits — coral / ink / cream regions meeting at hard edges.
- Signature move: Accent borders — 4px coral left, 5px coral top, 3px ink top, 4px ink horizontal.
- Signature move: 45° diagonal hatch — a signature 6%-opacity black diagonal repeating pattern overlaid on coral regions, providing texture.
- Signature move: Oversized decorative typography — background numerals at 12% opacity, giant quote marks at 35% opacity, sitting behind or beside primary content.
- Signature move: Three-surface system: {colors.coral} (fire), {colors.black} (ink), {colors.cream} (paper) — used as solid regions meeting at hard edges.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Creative Mode
description: A neo-brutalist editorial presentation system built for 1920x1080 slides. The deck anchors on a warm cream canvas with heavy 4px ink borders, hard offset drop-shadows, and a bold four-color accent palette (forest green, hot pink, burnt orange, sunshine yellow). Display headlines run Archivo Black in pure uppercase — aggressive, loud, zero letter-spacing softness. Monospace labels in JetBrains Mono echo a typesetting rule-sheet. Body copy sits in Space Grotesk. Every slide uses flat color-blocking with no gradients, no rounded cards, and no subtlety. The aesthetic is part Bauhaus grid, part punk zine, part Swiss editorial.
colors:
cream: "#EFE9D9"
cream-2: "#E4DCC4"
ink: "#0F0F0F"
ink-2: "#2A2A2A"
green: "#1F8A4C"
green-dark: "#136636"
pink: "#F06CA8"
pink-dark: "#D14E8B"
orange: "#E85A1F"
yellow: "#F5C518"
typography:
display-jumbo:
fontFamily: "Archivo Black, sans-serif"
fontSize: 220px
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
display-hero:
fontFamily: "Archivo Black, sans-serif"
fontSize: 160px
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
display-xl:
fontFamily: "Archivo Black, sans-serif"
fontSize: 140px
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
display-lg:
fontFamily: "Archivo Black, sans-serif"
fontSize: 100px
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
display-md:
fontFamily: "Archivo Black, sans-serif"
fontSize: 96px
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
display-sm:
fontFamily: "Archivo Black, sans-serif"
fontSize: 84px
fontWeight: 400
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
display-xs:
fontFamily: "Archivo Black, sans-serif"
fontSize: 72px
fontWeight: 400
lineHeight: 0.95
letterSpacing: -0.01em
textTransform: uppercase
stat-num:
fontFamily: "Archivo Black, sans-serif"
fontSize: 96px
fontWeight: 400
lineHeight: 0.9
letterSpacing: 0
step-num:
fontFamily: "Archivo Black, sans-serif"
fontSize: 140px
fontWeight: 400
lineHeight: 0.85
letterSpacing: 0
step-title:
fontFamily: "Archivo Black, sans-serif"
fontSize: 34px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
textTransform: uppercase
stamp-num:
fontFamily: "Archivo Black, sans-serif"
fontSize: 64px
fontWeight: 400
lineHeight: 0.9
letterSpacing: 0
marker-label:
fontFamily: "Archivo Black, sans-serif"
fontSize: 46px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
textTransform: uppercase
badge-label:
fontFamily: "Archivo Black, sans-serif"
fontSize: 28px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
textTransform: uppercase
table-head:
fontFamily: "Archivo Black, sans-serif"
fontSize: 28px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
textTransform: uppercase
table-label:
fontFamily: "Archivo Black, sans-serif"
fontSize: 28px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
textTransform: uppercase
body-lg:
fontFamily: "Space Grotesk, sans-serif"
fontSize: 28px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0
body-md:
fontFamily: "Space Grotesk, sans-serif"
fontSize: 24px
fontWeight: 400
lineHeight: 1.3
letterSpacing: 0
mono-label:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.06em
textTransform: uppercase
mono-kicker:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.14em
textTransform: uppercase
mono-tag:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.1em
textTransform: uppercase
mono-chart:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.08em
textTransform: uppercase
spacing:
slide-gutter: 96px
chrome-gutter: 64px
grid-gap: 28px
cell-pad: 32px
step-pad: 28px
topbar-top: 48px
meta-bottom: 40px
table-cell-pad: 18px 26px
canvas:
width: 1920px
height: 1080px
components:
slide-chrome:
topbar:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.08em
textTransform: uppercase
position: absolute
left: 64px
right: 64px
top: 48px
topbar-pill:
border: "2px solid {colors.ink}"
padding: 6px 14px
borderRadius: 999px
slide-meta:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.06em
textTransform: uppercase
position: absolute
left: 64px
right: 64px
bottom: 40px
slide-meta-dot:
width: 10px
height: 10px
background: "{colors.ink}"
borderRadius: 50%
stat-cell:
border: "4px solid {colors.ink}"
padding: 28px 32px
stat-cell-green:
background: "{colors.green}"
color: "{colors.cream}"
stat-cell-pink:
background: "{colors.pink}"
color: "{colors.ink}"
stat-cell-cream:
background: "{colors.cream}"
color: "{colors.ink}"
stat-cell-orange:
background: "{colors.orange}"
color: "{colors.cream}"
step-card:
border: "4px solid {colors.ink}"
padding: 28px
height: 420px
step-card-cream:
background: "{colors.cream}"
color: "{colors.ink}"
step-card-pink:
background: "{colors.pink}"
color: "{colors.ink}"
step-card-yellow:
background: "{colors.yellow}"
color: "{colors.ink}"
step-card-green:
background: "{colors.green}"
color: "{colors.cream}"
step-arrow:
borderTop: "18px solid transparent"
borderBottom: "18px solid transparent"
borderLeft: "24px solid {colors.ink}"
table:
border: "4px solid {colors.ink}"
background: "{colors.cream-2}"
rowBorder: "3px solid {colors.ink}"
colBorder: "3px solid {colors.ink}"
table-head-row:
background: "{colors.ink}"
color: "{colors.cream}"
fontFamily: "Archivo Black, sans-serif"
fontSize: 28px
borderColor: "{colors.cream}"
table-col-pink:
background: "{colors.pink}"
color: "{colors.ink}"
table-col-green:
background: "{colors.green}"
color: "{colors.cream}"
table-col-orange:
background: "{colors.orange}"
color: "{colors.cream}"
marker-block:
background: "{colors.pink}"
border: "4px solid {colors.ink}"
fontFamily: "Archivo Black, sans-serif"
fontSize: 46px
hardShadow: "24px 24px 0 {colors.orange}, 24px 24px 0 4px {colors.ink}"
iso-panel:
background: "{colors.green}"
border: "4px solid {colors.ink}"
stacked-block:
border: "4px solid {colors.ink}"
hardShadow: "18px 18px 0 {colors.ink}"
badge-rotated:
background: "{colors.yellow}"
border: "4px solid {colors.ink}"
fontFamily: "Archivo Black, sans-serif"
fontSize: 28px
textTransform: uppercase
transform: rotate(-4deg)
stamp:
background: "{colors.pink}"
border: "4px solid {colors.cream}"
width: 340px
height: 340px
transform: rotate(-6deg)
stamp-inner:
border: "4px solid {colors.cream}"
borderRadius: 50%
kicker-block:
background: "{colors.ink}"
color: "{colors.cream}"
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.14em
textTransform: uppercase
padding: 8px 16px
bar-chart-bar:
border: "3px solid {colors.ink}"
bar-chart-axis:
borderRight: "3px solid {colors.ink}"
borderBottom: "3px solid {colors.ink}"
decorative-circle:
background: "{colors.yellow}"
border: "4px solid {colors.ink}"
borderRadius: 50%
closing-slide:
background: "{colors.green}"
color: "{colors.cream}"
---
## 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
Creative Mode is a **neo-brutalist editorial slide system** for 1920x1080 presentations. The foundational aesthetic choice is restraint of technique paired with aggression of expression: no rounded cards, no gradients, no shadows that suggest light sources — only flat color-blocking and hard offset drop-shadows (the "Risograph" or "screen-print" kind where the shadow is a sold same-color offset).
The canvas is warm cream (`{colors.cream}` — #EFE9D9) with near-black ink (`{colors.ink}` — #0F0F0F) for borders, text, and rules. Four accent colors fire at full saturation: forest green, hot pink, burnt orange, and sunshine yellow. These never blend — they collide on the slide and the collision is the design.
Headlines run **Archivo Black** (weight 400 due to the display face being intrinsically heavy) in strict uppercase with tight line-height (0.92). Font sizes are extreme: 220px for closing slides, 160px for titles. **JetBrains Mono** carries all metadata, labels, topbar text, and axis labels — reinforcing a "designed artifact" or "technical manual" register. **Space Grotesk** handles all body paragraphs.
Every slide follows an identical chrome frame: a JetBrains Mono topbar at 48px from top (left text + right pill), and a JetBrains Mono meta footer at 40px from bottom (label left, slide number right with ink dot divider). Content lives inside this frame with 96px side gutters.
**Key Characteristics:**
- Cream canvas (`{colors.cream}` — #EFE9D9) as the universal background; green (`{colors.green}` — #1F8A4C) used for the closing slide only.
- 4px solid ink borders on every structural element — cards, panels, table cells, chart axes.
- Hard offset box-shadows in place of blurred drops: `24px 24px 0 color, 24px 24px 0 4px ink` on featured blocks.
- Archivo Black display type in uppercase with 0.92 line-height for extreme tightness.
- Four accent colors used as flat fills; each slide uses two or three of the four, never all simultaneously.
- Topbar pill badge (JetBrains Mono, 2px ink border, 999px radius) as the only rounded element per slide.
## Colors
### Canvas and Ink
- **Cream** (`{colors.cream}` — #EFE9D9): The universal slide background. Warm, not white. Distinguishes the deck from sterile white-background slides.
- **Cream 2** (`{colors.cream-2}` — #E4DCC4): One step darker cream. Used exclusively as the comparison table's background fill, creating a subtle recessed surface inside the ink border.
- **Ink** (`{colors.ink}` — #0F0F0F): Near-black used for all borders, body text, rules, topbar chrome, and the closing stamp border. Not pure #000000 — slightly softened.
- **Ink 2** (`{colors.ink-2}` — #2A2A2A): Softer near-black for secondary body text, descriptions inside stat cells, chart footnotes.
### Accent Colors
- **Green** (`{colors.green}` — #1F8A4C): Forest green. The dominant accent. Works on stat cells, diagram panels, process steps, and as a full-slide background for maximum visual impact.
- **Green Dark** (`{colors.green-dark}` — #136636): Darker green variant — available for lever/depth decorative effects. Not used as a primary surface fill.
- **Pink** (`{colors.pink}` — #F06CA8): Hot pink. High energy. Works on toggle switch illustrations, section markers, stat cells, process steps, and stamp elements.
- **Pink Dark** (`{colors.pink-dark}` — #D14E8B): Darker pink for depth on decorative lever elements. Available for shadow-side accents.
- **Orange** (`{colors.orange}` — #E85A1F): Burnt orange. The hard drop-shadow color on featured blocks; also works as a stat cell fill, bar chart color, and table column background.
- **Yellow** (`{colors.yellow}` — #F5C518): Sunshine yellow. Works on decorative circles, process steps, rotated badges, and bar chart bars. A warm punctuation color.
## Typography
### Font Families
The system uses three typefaces, each in a strict register:
- **Archivo Black** — display headlines, step numbers, stat numbers, table labels, all uppercase presentation text. Intrinsically heavy, no additional font-weight needed.
- **JetBrains Mono** — all metadata: topbar labels, meta footer, kicker labels, chart axes, legend rows, layer tags, figure notes. Carries the "technical spec" voice.
- **Space Grotesk** — body copy only: body column text (slide 2), stat cell descriptors, diagram subtext, step descriptions, closing strap.
### Display Scale
The slide canvas is 1920x1080px, so font sizes are far larger than web norms.
| Token | Size | Use |
|---|---|---|
| `{typography.display-jumbo}` | 220px | Jumbo title or closing headline |
| `{typography.display-hero}` | 160px | Primary deck title or hero name |
| `{typography.display-xl}` | 140px | Section-opening display headline |
| `{typography.display-lg}` | 100px | Section headline alongside a panel |
| `{typography.display-md}` | 96px | Mid-weight section headline |
| `{typography.display-sm}` | 84px | Section headline for data-heavy layouts |
| `{typography.display-xs}` | 72px | Section headline for grid layouts |
| `{typography.step-num}` | 140px | Large ordinal numerals in stepped layouts |
| `{typography.stat-num}` | 96px | Large numerals in stat or data cells |
| `{typography.stamp-num}` | 64px | Stamp or seal numeral |
| `{typography.marker-label}` | 46px | Featured marker or callout block label |
| `{typography.step-title}` | 34px | Card or step title |
| `{typography.table-head}` | 28px | Table header or label row text |
| `{typography.badge-label}` | 28px | Rotated badge or annotation label |
### Monospace Scale
All JetBrains Mono text sits at 24px. Letter-spacing varies by use:
- Topbar labels: 0.08em
- Meta footer: 0.06em
- Kicker labels (inverted): 0.14em
- Chart axes: 0.08em (via `{typography.mono-chart}`)
- Legend rows: 0.06em
- Layer tags: 0.1em
### Body Scale
- `{typography.body-lg}` (28px): Body copy for wide column layouts or lede paragraphs.
- `{typography.body-md}` (24px): Body text in stat cells, diagram annotations, step descriptions, footnotes, and strap lines.
### Principles
Archivo Black has a line-height of 0.92 — headlines overlap their own cap-height, which is intentional. Uppercase lock is non-negotiable for the display face; lowercase Archivo Black breaks the editorial register. The monospace face uses generous letter-spacing (0.06–0.16em) to feel like a typewritten label. Never use letter-spacing on Archivo Black or Space Grotesk.
## Layout
### Canvas System
Every slide is exactly 1920×1080px in a fixed, non-scrolling viewport. The `deck-stage` custom element handles centering and scaling.
### Gutter System
- **Chrome gutter** (64px left/right): Used by topbar and slide-meta only.
- **Content gutter** (96px left/right): Used by all content — headlines, body, grids.
- Headlines occasionally push right to within 96px of the right edge, or are constrained by `right: 1000px` / `right: 900px` to coexist with a right-panel diagram.
### Chrome Frame (All Slides)
```
┌─ topbar @ top:48px, left:64px, right:64px ──────────────────────────────────┐
│ SECTION LABEL [pill badge] │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ CONTENT (96px left gutter, 96px right gutter) │
│ │
├─ slide-meta @ bottom:40px, left:64px, right:64px ───────────────────────────┤
│ DESCRIPTOR LABEL 01 • 08 │
└─────────────────────────────────────────────────────────────────────────────┘
```
## Depth and Elevation
The system uses **zero blurred shadows**. Depth is expressed through two techniques:
### Hard Offset Shadow
The signature treatment: a second solid shape offset by a fixed amount in both X and Y. Two values are used:
- **Large offset** (24px 24px): Featured blocks like the marker and poster switch — `box-shadow: 24px 24px 0 {colors.orange}, 24px 24px 0 4px {colors.ink}`. The first shadow is the colored offset; the second is the ink border around it.
- **Medium offset** (18px 18px): Stacked blocks in the diagram — `box-shadow: 18px 18px 0 {colors.ink}`. Pure ink shadow only.
### Color-Block Contrast
Depth perception comes from juxtaposing surfaces: cream on cream-2 (table), ink on cream (kicker block), green on cream (diagram panel). No shadow needed when contrast does the work.
### Flat Elements
Topbar, meta footer, chart axis lines, legend swatches: flat, no shadow, no border-radius.
## Shapes and Treatment
### Border Radius
- **0px (square)**: All structural elements — stat cells, step cards, table cells, chart bars, diagram panels, stacked blocks. No rounding.
- **50% (circle)**: Decorative circles within diagram (yellow circ), the topbar pill dot (slide meta separator dot).
- **999px (pill)**: Topbar badge pill only. The one exception to the system's overall squareness, and it reads as a label chip rather than a card.
- **Rotated elements**: The comparison badge rotates -4deg; the closing stamp rotates -6deg. These are the system's only non-orthogonal placements.
### Borders
- **4px solid `{colors.ink}`**: All structural borders — stat cells, step cards, diagram panels, table (outer), poster block, marker block, switch block, stamp.
- **3px solid `{colors.ink}`**: All internal structural lines — table rows, table columns, chart axis, bar chart bars.
- **2px solid `{colors.ink}`**: Topbar pill badge.
- **3px dashed `{colors.ink}`**: Dashed horizontal rule separating the process slide's topbar from its flow cards.
### Decorative Elements
- **Toggle switch**: Pink square with a lever shape (skewed div) and thick/dark underside, offset shadow in orange with ink border.
- **Stacked blocks**: Four overlapping absolute-positioned rectangles in pink, yellow, orange, cream-2 with 18px ink hard shadows.
- **Circle overlay**: Yellow circle centered in a green square — shape contrast acting as decorative figure.
- **Stamp**: Pink rotated square with a cream circular inner border — acts as a seal or approval mark.
## Do's and Don'ts
### Do
- Use 4px ink borders on every structural element. Thinner looks soft; thicker looks like a web component.
- Use hard offset shadows in exactly two sizes: 24px for featured hero blocks, 18px for diagram stacked blocks. Don't mix sizes.
- Stay uppercase on all Archivo Black usage. The font in sentence case reads as a different brand.
- Use the four accents in groups of two or three per slide. Every accent on one slide is noise.
- Reserve the green background for a single dominant slide. Its rarity is what gives it impact.
- Use JetBrains Mono for all labels, metadata, indices, figure notes, and axis text. Never use it for body or headlines.
- Keep line-height at 0.92 for all display text. Looser leading breaks the tight editorial register.
- Maintain 96px content gutter and 64px chrome gutter consistently across all slides.
### Don't
- Don't round card corners (except the topbar pill). Rounding signals "friendly SaaS"; sharp corners signal "editorial precision."
- Don't use gradients, drop shadows with blur, or glow effects. All depth must come from hard offset or color contrast.
- Don't use Archivo Black in sentence case. Never lowercase the display face.
- Don't apply letter-spacing to Archivo Black (except at -0.01em which is already encoded). Extra tracking breaks its density.
- Don't introduce a fifth accent color. The four-color palette is the brand constraint.
- Don't use pure white (#ffffff) as a background. Cream is the canvas; white reads as blank.
- Don't use Space Grotesk for labels or metadata. That role belongs to JetBrains Mono.
- Don't add multiple typefaces. The three-family stack is complete.
- Don't center-align body text. All body copy is left-aligned; centered text breaks the grid discipline.
- Don't soften the stamp or badge rotation. The -4deg and -6deg angles are deliberate imperfection signals.
## Responsive Behavior
This template is designed **exclusively for 1920x1080 presentation display**. It is not a web page and has no mobile breakpoints. The `deck-stage` web component handles viewport scaling via CSS transforms, so the 1920x1080 canvas scales proportionally on any screen size without layout changes.
### Touch / Presenter Behavior
- Slides advance via keyboard arrow keys or presentation clicker (handled by `deck-stage.js`).
- No hover states are defined or needed.
- No interactive form elements exist.
### Print / Export Behavior
- At 96dpi, the 1920x1080 canvas maps to a standard 20x11.25 inch frame.
- For PDF export, a 1920x1080 viewport capture or browser print-to-PDF at 100% scale is recommended.
- At 1pt = 1.333px, the effective print sizes of headlines range from 54pt (72px) to 165pt (220px) — correct for poster/title cards.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Archivo Black uppercase 400) | Archivo Black | 思源宋体 Noto Serif SC 900 | Google Fonts |
| Body (Space Grotesk 400) | Space Grotesk | 思源宋体 Noto Serif SC 400 | Google Fonts |
| Mono / Label (JetBrains Mono uppercase) | JetBrains Mono | JetBrains Mono (Latin/digit only — keep mono chrome in Latin) | Google Fonts |
### Mixed-Content Strategy
Use **Strategy A — single-font-stack with fallback**: declare Noto Serif SC *after* the Latin face in the same `font-family` stack so Latin glyphs render in Archivo Black / Space Grotesk and CJK glyphs fall through to NSC automatically. JetBrains Mono chrome stays Latin/digit-only — topbar labels, slide-meta, axis ticks, and figure notes do not need a CJK fallback (and JetBrains Mono has no CJK glyphs by design).
### 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=Archivo+Black&family=Space+Grotesk:[email protected]&family=JetBrains+Mono:[email protected]&family=Noto+Serif+SC:wght@400;900&display=swap" rel="stylesheet">
```
```css
:root {
--font-display: "Archivo Black", "Noto Serif SC", sans-serif;
--font-body: "Space Grotesk", "Noto Serif SC", sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
}
/* Display headlines use Noto Serif SC 900; body uses NSC 400. */
```
### Universal CJK Adjustments
- **Line-height**: bump CJK body line-height to ~1.55 (from 1.4) — Hanzi need more vertical breathing than Latin lowercase. For display NSC 900 at 100–220px, keep line-height tight at ~1.0 (NSC heavy weight at display size needs less leading than Archivo Black).
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (negative tracking that flatters Archivo Black caps jams Hanzi strokes together). Keep tight tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any display/label/mono when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (,。:;「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick a single weight of Noto Serif SC for a given text run, never two inside one phrase.
### Aesthetic Notes
Creative Mode's neo-brutalist register depends on Archivo Black's extreme density at 100–220px — there is no Hanzi face that matches this exact mass, so Noto Serif SC at weight 900 is the closest available substitute. NSC 900's modulated serif strokes will read as more literary than the punk-zine Archivo Black voice, but the four-color block palette, 4px ink borders, and hard 24px offset shadows do most of the brutalist work — the typography becomes one component of a louder system rather than the system itself. The "uppercase always" rule for Archivo Black is meaningless for Hanzi (no case), so drop both `text-transform: uppercase` and the -0.01em tracking when content switches to Chinese — NSC 900 stands on size and color alone. JetBrains Mono chrome (topbar pill, slide-meta, axis ticks, kicker block) intentionally stays Latin/digit-only: render `04 / 08` slide counters in mono, but render any Chinese descriptor label in NSC 400 inside the meta footer. The four accents (green / pink / orange / yellow), stat-cell color blocks, table treatment, and decorative geometry (stamp, badge, stacked blocks) are all content-agnostic.
### Known CJK Gap
**Heavy Latin display has no exact CJK equivalent.** Archivo Black's brutalist density at 220px is the system's signature — Noto Serif SC 900 is the heaviest commonly available Hanzi weight, but it reads as a literary serif rather than a poster-grotesk. Chinese decks built with Creative Mode will feel ~30% less "punk-zine" than the Latin original; compensate by leaning harder on the accent color blocks, the hard offset shadows, and the rotated badge / stamp elements. Avoid the alternative of `Smiley Sans Oblique` for display — its oblique cut conflicts with the system's strict orthogonal rectangle geometry. NSC has no italic axis, but the system doesn't use italic anywhere — no loss. The mono chrome's "technical spec" voice is best preserved by keeping all JetBrains Mono content in Latin/digit and reserving NSC for headline and body roles only.
## Iteration Guide
1. New slide layouts must respect the chrome frame: topbar at top:48px left:64px, slide-meta at bottom:40px left:64px.
2. Content begins at 96px from each side edge.
3. When adding a data section (chart, table, grid), pair a display headline above with JetBrains Mono labels inside.
4. Pick two or three accent fills per slide. Never mix all four on a single slide.
5. Hard shadows go on featured single elements only (marker, featured block). Grid cells do not get individual shadows.
6. New step/stat cards follow the existing color-sequence pattern: alternate cream with accents, end the sequence on green.
7. All borders are 4px solid ink. Internal sub-borders within a table or axis are 3px solid ink.
8. Rotated elements (badge, stamp) use single fixed angles (-4deg, -6deg). Do not introduce other angles.
9. Icons and illustrations are CSS-only geometric shapes (divs, borders, pseudo-elements). No external images or SVGs needed.
## Known Gaps
- The `deck-stage.js` script (slide advancement, keyboard nav) is an external dependency not documented here.
- Animation and transition between slides is not in scope for this template; all slides are static.
- The title slide poster contains a decorative toggle switch illustration built from nested divs; it has no functional state.
- Chart data (bar heights, values, labels) is hardcoded as inline styles and placeholder content — there is no data-binding layer.
- Table data is all placeholder; no dynamic population is supported.
- The `--rule` CSS variable (#0F0F0F, identical to `--ink`) is defined but not used explicitly — it is reserved for horizontal rule elements and can be considered an alias for ink.
- Font fallback for Archivo Black is `sans-serif` — the font must be loaded from Google Fonts for the design to render correctly.
# Creative Mode Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/creative-mode/design.md`
- Preview card: `bold-template-pack/templates/creative-mode/preview.md`
## Selection Metadata
- Slug: `creative-mode`
- Tagline: Cream paper canvas with confident multi-color (green, pink, orange, yellow) accents and Archivo Black display.
- Mood: creative, confident, playful, design-led
- Tone: graphic, expressive, modern
- Formality: medium
- Density: medium-high
- Scheme: light
- Best for: Anything that should feel design-led and confident: creative agency pitches, design studio decks, ad shop credentials, brand creative reviews, art-direction reviews. Also a great unexpected pick for a tech talk, research findings, or finance review when the speaker wants to lead with taste rather than convention.
- Avoid for: Contexts that demand institutional restraint and a quiet authority — the saturated multi-accent palette will read as expressive, not formal.
## Visual Snapshot
A neo-brutalist editorial presentation system built for 1920x1080 slides. The deck anchors on a warm cream canvas with heavy 4px ink borders, hard offset drop-shadows, and a bold four-color accent palette (forest green, hot pink, burnt orange, sunshine yellow). Display headlines run Archivo Black in pure uppercase — aggressive, loud, zero letter-spacing softness. Monospace labels in JetBrains Mono echo a typesetting rule-sheet. Body copy sits in Space Grotesk. Every slide uses flat color-blocking with no gradients, no rounded cards, and no subtlety. The aesthetic is part Bauhaus grid, part punk zine, part Swiss editorial.
Creative Mode is a neo-brutalist editorial slide system for 1920x1080 presentations. The foundational aesthetic choice is restraint of technique paired with aggression of expression: no rounded cards, no gradients, no shadows that suggest light sources — only flat color-blocking and hard offset drop-shadows (the "Risograph" or "screen-print" kind where the shadow is a sold same-color offset).
## Preview Ingredients
- Palette: cream #EFE9D9; cream-2 #E4DCC4; ink #0F0F0F; ink-2 #2A2A2A; green #1F8A4C; green-dark #136636; pink #F06CA8; pink-dark #D14E8B
- Typography: Archivo Black; Space Grotesk; JetBrains Mono
- Signature move: Cream canvas ({colors.cream} — #EFE9D9) as the universal background; green ({colors.green} — #1F8A4C) used for the closing slide only.
- Signature move: 4px solid ink borders on every structural element — cards, panels, table cells, chart axes.
- Signature move: Hard offset box-shadows in place of blurred drops: 24px 24px 0 color, 24px 24px 0 4px ink on featured blocks.
- Signature move: Archivo Black display type in uppercase with 0.92 line-height for extreme tightness.
- Signature move: Four accent colors used as flat fills; each slide uses two or three of the four, never all simultaneously.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Daisy Days
description: A cheerful, childlike presentation system built around the chunky display face Fredoka One and the rounded humanist sans Quicksand. The palette is a sunny garden — cream canvas, turquoise, soft pink, butter yellow, mint, lavender, peach, sky blue, and a single coral accent — with charcoal-brown 2D outlines wrapping every shape. Hard offset shadows in dark charcoal, generous border-radius, and hand-drawn SVG decorations (daisies, stars, suns, clouds, rainbows) anchor the aesthetic somewhere between a children's storybook spread and a sticker-sheet kawaii zine.
colors:
cream: "#F5F0E6"
turquoise: "#7ECDC0"
soft-pink: "#F7C8D4"
butter: "#FDE68A"
mint: "#A8E6CF"
lavender: "#D4A5E8"
peach: "#FFCBA4"
sky: "#A8D8F0"
coral: "#F8635F"
text-dark: "#2D2D2D"
text-muted: "#6B6B6B"
white: "#FFFFFF"
borders:
primary: "3px solid {colors.text-dark}"
thin: "2px solid {colors.text-dark}"
shadows:
default: "6px 6px 0 {colors.text-dark}"
small: "4px 4px 0 {colors.text-dark}"
text-headline: "3px 3px 0 {colors.text-dark}"
text-headline-soft: "3px 3px 0 rgba(0,0,0,0.2)"
typography:
display:
fontFamily: "'Fredoka One', cursive"
fontSize: "clamp(3.2rem, 7vw, 6.5rem)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
headline:
fontFamily: "'Fredoka One', cursive"
fontSize: "clamp(2.5rem, 5vw, 4.5rem)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
title:
fontFamily: "'Fredoka One', cursive"
fontSize: "clamp(1.8rem, 3.5vw, 3rem)"
fontWeight: 400
lineHeight: 1.15
letterSpacing: 0.02em
subtitle:
fontFamily: "'Fredoka One', cursive"
fontSize: "clamp(1.3rem, 2vw, 1.8rem)"
fontWeight: 400
lineHeight: 1.2
letterSpacing: 0.02em
label-display:
fontFamily: "'Fredoka One', cursive"
fontSize: "clamp(1rem, 1.5vw, 1.3rem)"
fontWeight: 400
lineHeight: 1.3
letterSpacing: 0.02em
quote:
fontFamily: "'Fredoka One', cursive"
fontSize: "clamp(1.3rem, 2.5vw, 2rem)"
fontWeight: 400
lineHeight: 1.35
body:
fontFamily: "'Quicksand', sans-serif"
fontSize: "clamp(0.95rem, 1.3vw, 1.15rem)"
fontWeight: 500
lineHeight: 1.6
body-strong:
fontFamily: "'Quicksand', sans-serif"
fontSize: "clamp(0.95rem, 1.4vw, 1.15rem)"
fontWeight: 600
lineHeight: 1.5
meta:
fontFamily: "'Quicksand', sans-serif"
fontSize: "clamp(0.8rem, 1.1vw, 0.95rem)"
fontWeight: 600
lineHeight: 1.45
badge:
fontFamily: "'Fredoka One', cursive"
fontSize: "0.85rem"
fontWeight: 400
letterSpacing: 0.02em
spacing:
pad-slide: "40px 60px"
pad-card-lg: "48px 56px"
pad-card-md: "32px 40px"
pad-card-sm: "16px 24px"
gap-grid-lg: "28px"
gap-grid-md: "24px"
gap-grid-sm: "14px"
radius: "20px"
radius-lg: "28px"
radius-pill: "50px"
radius-round: "50%"
canvas:
width: 100vw
height: 100vh
components:
card:
background: "{colors.white}"
border: "3px solid {colors.text-dark}"
borderRadius: "{spacing.radius}"
boxShadow: "{shadows.default}"
card-lg:
background: "{colors.white}"
border: "3px solid {colors.text-dark}"
borderRadius: "{spacing.radius-lg}"
boxShadow: "{shadows.default}"
badge-pill:
display: "inline-block"
padding: "8px 20px"
borderRadius: "{spacing.radius-pill}"
border: "3px solid {colors.text-dark}"
fontFamily: "'Fredoka One', cursive"
fontSize: "0.85rem"
background: "{colors.butter}"
framed-header:
description: "A two-part stacked card: a colored header strip (any accent surface) with rounded top corners and no bottom border, sitting flush above a white body with rounded bottom corners. The pair reads as a single unit with a tonal cap."
headerBackground: "any accent surface"
headerBorderRadius: "{spacing.radius-lg} {spacing.radius-lg} 0 0"
bodyBackground: "{colors.white}"
bodyBorderRadius: "0 0 {spacing.radius-lg} {spacing.radius-lg}"
border: "3px solid {colors.text-dark}"
boxShadow: "{shadows.default}"
circle-dot:
width: "48px"
height: "48px"
borderRadius: "{spacing.radius-round}"
border: "3px solid {colors.text-dark}"
fontFamily: "'Fredoka One', cursive"
color: "{colors.white}"
description: "Outlined colored disc holding a numeral or single letter. Used as timeline node, step marker, or list bullet anchor."
circle-icon:
width: "44px"
height: "44px"
borderRadius: "{spacing.radius-round}"
border: "3px solid {colors.text-dark}"
fontFamily: "'Fredoka One', cursive"
background: "any accent surface"
description: "Smaller cousin of circle-dot used as a card icon at the top of an info card."
step-circle-lg:
width: "90px"
height: "90px"
borderRadius: "{spacing.radius-round}"
border: "3px solid {colors.text-dark}"
fontFamily: "'Fredoka One', cursive"
color: "{colors.white}"
boxShadow: "{shadows.small}"
description: "Oversized outlined disc used as a process step marker. Carries a hard offset shadow."
avatar-circle:
width: "100px"
height: "100px"
borderRadius: "{spacing.radius-round}"
border: "3px solid {colors.text-dark}"
background: "{colors.white}"
boxShadow: "{shadows.small}"
overflow: "hidden"
bullet-dot:
width: "20px"
height: "20px"
borderRadius: "{spacing.radius-round}"
border: "2px solid {colors.text-dark}"
background: "{colors.butter}"
description: "Small outlined disc used as a ::before bullet for body list items, anchored 4px from the top of the line."
list-dash:
description: "A simple muted-text dash character used as a ::before bullet for compact in-card lists (day-card body)."
legend-swatch:
width: "18px"
height: "18px"
border: "2px solid {colors.text-dark}"
borderRadius: "4px"
decoration:
position: "absolute"
pointerEvents: "none"
zIndex: 1
description: "Hand-drawn SVG sticker (daisy, star, sun, cloud, rainbow) placed at slide corners and edges as atmospheric ornament. Often crops past the slide edge."
nav-dots:
position: "fixed"
placement: "right edge, vertically centered"
dotSize: "12px"
dotBorder: "2px solid {colors.text-dark}"
activeBackground: "{colors.butter}"
activeTransform: "scale(1.2)"
slide-counter:
position: "fixed"
placement: "bottom center"
background: "{colors.white}"
border: "3px solid {colors.text-dark}"
borderRadius: "{spacing.radius-pill}"
padding: "6px 20px"
fontFamily: "'Fredoka One', cursive"
boxShadow: "{shadows.small}"
chart-container:
background: "{colors.white}"
border: "3px solid {colors.text-dark}"
borderRadius: "{spacing.radius-lg}"
boxShadow: "{shadows.default}"
padding: "{spacing.pad-card-md}"
---
## 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
Daisy Days is a **cheerful childlike presentation system** rooted in a single typographic pairing: the chubby rounded display face **Fredoka One** for every headline, and the friendly humanist sans **Quicksand** for every line of body and meta text. The visual language descends from picture-book illustration and sticker-sheet kawaii: every shape carries a charcoal 2D outline, every elevated element casts a solid offset shadow, and every surface is a pastel from a sunny garden palette.
The color philosophy is **multi-pastel with a single warm pop**. The background canvas alternates between a soft cream (`{colors.cream}`) and the saturated pastels (`{colors.turquoise}`, `{colors.soft-pink}`, `{colors.butter}`, `{colors.mint}`, `{colors.lavender}`, `{colors.peach}`, `{colors.sky}`). The lone high-saturation accent is `{colors.coral}` — used sparingly on small marker dots and headline strokes, never as a full surface. Headlines on top of a colored surface get a 3px charcoal text-shadow, which gives display text the same outlined appearance as the shapes around it; headlines on cream stay flat. Body text never leaves `{colors.text-dark}` or `{colors.text-muted}`.
Depth is **2D and graphic**, not photographic. Every elevated element gets a `{shadows.default}` or `{shadows.small}` — a solid charcoal block offset to the bottom-right, with zero blur. The combination of thick charcoal outline plus hard offset shadow gives the system its sticker-on-paper feel. There are no gradients, no glow, no glass effects.
The signature treatment is the **hand-drawn SVG decoration layer**. Every region carries 3–7 absolutely-positioned ornaments — yellow-centered daisies, multi-color stars, smiling suns, fluffy clouds, arched rainbows — that cluster at the corners and edges, often cropping past the slide boundary at `top:-30px / right:-20px`. These decorations sit on a `z-index:1` layer behind the content (`z-index:2`) and carry the same 2px-ish charcoal stroke as the rest of the system, unifying ornament with structure.
**Density philosophy: full but not crowded.** This system reads as authoritative when every slide carries one focused content region (a card, a frame, a grid) at the center plus a generous wreath of corner ornaments at the edges. An empty corner with no decoration reads as broken — the ornaments are part of the structural composition, not optional garnish. Conversely, dense overlapping content panels read as anxious; the system wants one main subject, framed and surrounded, not three competing ones. Aim for one bordered/shadowed container per slide, with the corner decorations doing the work of filling the rest of the canvas.
**Key Characteristics:**
- Cream (`{colors.cream}`) default canvas with rotating pastel surfaces — every slide may pick a different surface color.
- Fredoka One for all headline / display / quote text; Quicksand 500/600 for all body and meta text.
- Every shape and card carries a 3px solid charcoal outline (`{colors.text-dark}`) plus a hard offset shadow (`{shadows.default}` or `{shadows.small}`).
- Generous border-radius: 20px on standard cards, 28px on featured cards, pill (`{spacing.radius-pill}`) on badges, full circle on dots and avatars.
- Hand-drawn SVG ornaments (daisies, stars, suns, clouds, rainbows) cluster at corners and crop past slide edges as atmospheric layer.
- Headlines on colored surfaces always carry a 3px solid charcoal text-shadow; headlines on cream sit flat.
- Bullets are colored outlined dots (`{components.bullet-dot}`), not glyphs. Lists feel hand-set.
- One main content container per slide, surrounded by 3–7 ornaments. Empty corners are wrong.
## Colors
### Palette
- **Cream** (`{colors.cream}` — #F5F0E6): The default canvas. A warm off-white that reads as paper-stock rather than digital white. Used as the deck's neutral surface — title openings, info-card slides, anything that wants to feel like a storybook page.
- **Turquoise** (`{colors.turquoise}` — #7ECDC0): A medium-saturation teal-green. The boldest of the surface pastels; loud enough that headlines on top need the charcoal text-shadow to stay legible.
- **Soft Pink** (`{colors.soft-pink}` — #F7C8D4): A bubblegum blush. Used as a full surface, a header-strip color, a day-marker fill, and the quote-mark accent inside a quote card.
- **Butter** (`{colors.butter}` — #FDE68A): A buttery pastel yellow. The active-state color for nav dots, the default badge fill, and the default bullet-dot fill. It is the system's "highlight" color when something needs to feel marked.
- **Mint** (`{colors.mint}` — #A8E6CF): A cool celadon green. A surface color, a header-strip color, a circle-icon fill, and a timeline-dot color.
- **Lavender** (`{colors.lavender}` — #D4A5E8): A muted purple. Surface, header-strip, marker-dot, day-marker — same role flexibility as mint and soft-pink.
- **Peach** (`{colors.peach}` — #FFCBA4): A warm pastel orange. Used as a surface (typically on process or sequence slides) and an accent.
- **Sky** (`{colors.sky}` — #A8D8F0): A pastel blue. Surface and accent color, often paired with cloud decorations.
- **Coral** (`{colors.coral}` — #F8635F): The single saturated accent. Used only as a marker fill (a numbered dot, a timeline node, a step circle) and a day-header — never as a full slide surface. Coral is the system's "look here" color and loses its punch if overused.
- **Text Dark** (`{colors.text-dark}` — #2D2D2D): The structural color. Every border, every body text run on light surfaces, every shadow, every SVG stroke. Slightly warmer than pure black — reads charcoal, not jet.
- **Text Muted** (`{colors.text-muted}` — #6B6B6B): The de-emphasized text color. Subtitles, descriptions under headlines, list-dash bullets, role labels.
- **White** (`{colors.white}` — #FFFFFF): The default card fill — every card, every avatar, every chart-container interior. Cards on a cream canvas still get white interiors so the card edge reads cleanly.
### Defaults
- **Default slide background**: `{colors.cream}`. Use a saturated pastel surface (turquoise, soft-pink, mint, butter, lavender, peach, sky) when the slide wants a tonal personality; default to cream when it doesn't.
- **Default card background**: `{colors.white}` — on any surface, including pastel surfaces. White-on-pastel is the standard card treatment.
- **Default headline color**: `{colors.text-dark}` — always.
- **Default body color**: `{colors.text-dark}` for primary body, `{colors.text-muted}` for descriptions, role labels, captions, and sublines.
- **Default border color**: `{colors.text-dark}` — always. There are no colored borders anywhere.
- **Default shadow color**: `{colors.text-dark}` — always. Shadows are never pastel.
- **Default badge fill**: `{colors.butter}`.
- **Default marker / accent fill** when an element needs a single "attention" color: `{colors.coral}`. When a sequence of markers is needed, rotate through the full pastel set (coral → mint → sky → lavender → butter) for sequence steps and dots.
- **Default header-strip color** on a framed-header component: any pastel surface — pick whichever harmonizes with the slide's surface color.
The pastels are interchangeable at the surface level — they do not carry fixed semantic meaning (mint is not "success", coral is not "warning"). Pick the surface that best serves the slide's emotional register. The one rule: coral is reserved for small high-contrast accents, not surfaces.
## Typography
### Font Family
The system loads exactly two web fonts from Google Fonts: **Fredoka One** (a single-weight rounded display face) and **Quicksand** (a humanist sans available at 400/500/600/700). The pairing is the entire typographic identity.
Fredoka One is a chunky single-weight display face — it has no italic, no lighter variants, no condensed cuts. The display weight reads as 400 by spec but visually behaves as a heavy weight because the letterforms are so rounded and full. Every headline, every title, every step number, every quote in the system runs in Fredoka One. There is no exception — using Quicksand for a heading or Fredoka One for a body paragraph breaks the system instantly.
Quicksand carries everything else: paragraphs, list items, role labels, captions, day-card body lists, legend text. Quicksand 500 is the body default; 600 is the "slightly stronger" variant used for emphasized body (welcome-list items, info-card descriptions, legend labels); 700 is used sparingly for quote-author attribution.
### Display, Body, and Marker Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | clamp(3.2rem, 7vw, 6.5rem) | Fredoka One | 400 | Cover / opening hero headline |
| `{typography.headline}` | clamp(2.5rem, 5vw, 4.5rem) | Fredoka One | 400 | Primary slide headline |
| `{typography.title}` | clamp(1.8rem, 3.5vw, 3rem) | Fredoka One | 400 | Section title or framed-header title |
| `{typography.quote}` | clamp(1.3rem, 2.5vw, 2rem) | Fredoka One | 400 | Pull-quote body text |
| `{typography.subtitle}` | clamp(1.3rem, 2vw, 1.8rem) | Fredoka One | 400 | Sub-headline, in-card title |
| `{typography.label-display}` | clamp(1rem, 1.5vw, 1.3rem) | Fredoka One | 400 | Small Fredoka labels — day-card header, step title |
| `{typography.body-strong}` | clamp(0.95rem, 1.4vw, 1.15rem) | Quicksand | 600 | Emphasized body — welcome lists, info-card descriptions |
| `{typography.body}` | clamp(0.95rem, 1.3vw, 1.15rem) | Quicksand | 500 | Standard paragraph body |
| `{typography.meta}` | clamp(0.8rem, 1.1vw, 0.95rem) | Quicksand | 600 | Compact secondary text — day-card lists, step descriptions, legend rows |
| `{typography.badge}` | 0.85rem | Fredoka One | 400 | Text inside a pill badge |
### Defaults
- **Default size for a primary slide headline**: `{typography.headline}` (clamp 2.5–4.5rem).
- **Default size for a cover-level title moment**: `{typography.display}` (clamp 3.2–6.5rem).
- **Default size for a paragraph**: `{typography.body}` (clamp 0.95–1.15rem) in Quicksand 500.
- **Default size for emphasized list items**: `{typography.body-strong}` (Quicksand 600).
- **Default size for a description under a card title or a meta caption**: `{typography.meta}` in `{colors.text-muted}`.
- **Default size for a section / framed-header title**: `{typography.title}`.
- **Default family for any text larger than ~1.3rem**: Fredoka One. Default family for any text smaller than that: Quicksand. The size threshold roughly tracks the Fredoka / Quicksand role boundary.
When unsure, reach for `{typography.headline}` for the slide's main text moment, not `{typography.subtitle}` or `{typography.title}` (which are intra-content titles, not the primary slide voice).
### Signature Treatments
These are **non-optional whenever the corresponding element type is used**:
- **Every Fredoka One headline placed on a saturated pastel surface carries a 3px charcoal text-shadow** (`{shadows.text-headline}` on bold surfaces like turquoise / mint, `{shadows.text-headline-soft}` on softer surfaces like pink / lavender). Headlines on cream sit flat without the shadow. The text-shadow is what makes the headline read as "outlined" in the same vocabulary as the rest of the system. Skipping it on a colored surface reads as broken.
- **Headlines placed on saturated surfaces switch text color to `{colors.white}`**; headlines on cream and on light pastel cards stay `{colors.text-dark}`. The pairing is white-on-saturated, dark-on-cream-or-card.
- **Every body list item uses an outlined colored disc as its bullet, not a glyph.** Default fill is `{colors.butter}`. The bullet is rendered as a `::before` 20px circle with 2px charcoal border, positioned 4px from the top of the first line.
- **Every quote uses the Fredoka quote-mark treatment**: an oversized `"` glyph in `{colors.soft-pink}` sits above the quoted text. Quotes never appear without a quote-mark anchor.
- **Quicksand body text never goes uppercase.** No display-style ALL-CAPS treatments on body. Fredoka has its own personality and doesn't need shouting.
### Typography Principles
The size ladder is the rhythm. Fredoka One does not get italicized, underlined, or rendered in alternate weights — Fredoka has one weight, full stop. Quicksand stays inside the 500 / 600 / 700 ladder; do not introduce 400 or 800 even if available. Letter-spacing on Fredoka stays at the spec default of `0.02em`. Letter-spacing on Quicksand stays at 0.
Mixing Quicksand into a headline (e.g. for an italicized phrase) is not supported in this system — the headline runs in one face. If a headline needs a different emotional register, the size and color do the work, not the font swap.
## Layout
### Canvas System
The system targets full viewport — every `.slide` is `100vw × 100vh` with `padding: 40px 60px` (default slide padding). Slides are stacked vertically inside a `.slides-container` that uses CSS scroll-snap (`scroll-snap-type: y mandatory`) to lock each slide to the viewport. Navigation is handled via fixed right-edge nav dots, a fixed bottom-center counter pill, keyboard arrows / spacebar, and intersection-observer-driven dot state.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-slide}` | 40px 60px | Outer slide padding |
| `{spacing.pad-card-lg}` | 48px 56px | Large featured cards (quote box, welcome body) |
| `{spacing.pad-card-md}` | 32px 40px | Standard cards (chart container, framed-header body) |
| `{spacing.pad-card-sm}` | 16px 24px | Compact cards (timeline card, day-card body) |
| `{spacing.gap-grid-lg}` | 28px | Major grid gaps (team grid, info-card grid) |
| `{spacing.gap-grid-md}` | 24px | Standard grid gaps |
| `{spacing.gap-grid-sm}` | 14px | Tight grid gaps (weekly day-card grid) |
### Border-Radius Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.radius}` | 20px | Standard cards, day-cards, timeline cards |
| `{spacing.radius-lg}` | 28px | Featured cards (chart container, welcome frame, quote box) |
| `{spacing.radius-pill}` | 50px | Badges, slide counter |
| `{spacing.radius-round}` | 50% | All circles (avatars, bullet dots, marker dots, step circles, icons) |
Every visible region carries some radius. There are zero square corners in this system besides the SVG decorations themselves.
### Content Centering
Slide content is flex-centered both vertically and horizontally inside the slide padding. The main content container has a max-width that varies by composition (typically 700–1100px) and never spans the full slide width — there is always margin between content and slide edge for the decorations to occupy.
## Depth and Elevation
### Hard Offset Shadow (Only Technique)
Every elevated element uses one of two shadow values:
- **`{shadows.default}`** = `6px 6px 0 {colors.text-dark}` — standard offset for cards, frames, chart containers, badges, the slide counter.
- **`{shadows.small}`** = `4px 4px 0 {colors.text-dark}` — lighter offset for smaller elevated elements (day-cards, timeline-cards, info-cards, step circles, avatars).
The shadow is **solid charcoal, zero blur, fixed bottom-right offset**. There is no rgba shadow, no blur, no soft elevation. An element either casts a hard offset shadow in `{colors.text-dark}` or it casts no shadow.
### Text Shadow for Display Type
A separate text-shadow treatment lives only on display headlines placed over saturated pastel surfaces:
- **`{shadows.text-headline}`** = `3px 3px 0 {colors.text-dark}` for bold pastel surfaces (turquoise, butter, peach).
- **`{shadows.text-headline-soft}`** = `3px 3px 0 rgba(0,0,0,0.2)` for softer pastel surfaces (soft-pink, mint) where the full charcoal would feel too heavy.
Headlines on cream get no text-shadow.
### Decorative Z-Index Layer
The atmospheric SVG decorations live on `z-index: 1` with `pointer-events: none`. Content sits on `z-index: 2`. This means decorations may visually overlap content rectangles, but never block interaction. Decorations frequently crop past the slide edge with negative offsets like `top:-30px / left:-30px`, which gives the layout a "stickers reaching off the page" feel.
## Shapes and Treatment
### Border Weight and Style
- **3px solid `{colors.text-dark}`** — the universal structural border. Cards, framed headers, badges, marker circles, step circles, avatars, chart containers, the slide counter.
- **2px solid `{colors.text-dark}`** — the lighter border used only on small elements at the bullet / nav-dot / legend-swatch / day-header divider scale.
- **~2.1px solid `#232323` or `#000`** — the SVG stroke weight used inside the daisy / star / cloud / sun decorations. This matches the perceived weight of the 3px structural border at the SVG's natural scale.
Borders are never colored. Borders are never dashed. The only line style in the system is solid charcoal.
### Decorative Element Types
**Daisy** — A six-petal white-petal / yellow-center daisy in two paired stem positions. The system's signature ornament. Place at corners (typically `top-left`, `top-right`, `bottom-left`, `bottom-right`), often cropped past the edge at `top:-30px` or `right:-20px`. Two daisies plus 2–3 stars is the most common decoration cluster.
**Star** — A puffy five-pointed sticker star in a solid pastel fill (pink, yellow, mint, lavender, white) with charcoal outline. Used as scattered accents between the larger daisy / sun / cloud ornaments. Vary fill color across instances on the same slide; do not use all-white or all-yellow stars.
**Sun** — A smiling round sun in butter yellow with rays. Used as a single feature ornament, typically at top-left or bottom-right.
**Cloud** — A puffy white-and-blue cloud with optional smaller cloud variant. Used in sequences (two clouds at opposing corners) or as a single ornament on slides that want a sky atmosphere.
**Rainbow** — An arched four-band rainbow (coral / yellow / mint / sky) with the standard charcoal outline. Used as a single feature ornament, typically at top-right or bottom-right.
**Framed Header** (`{components.framed-header}`) — A two-part stacked card: a colored header strip (any pastel) sits flush above a white body. The pair shares one rounded outer corner radius and one continuous 3px border, and the whole unit casts a single offset shadow. Used as a featured info container.
**Badge Pill** (`{components.badge-pill}`) — A short rounded-pill chip with 3px border and butter (default) fill. Used as a section tag or small label. Pill text is Fredoka One at 0.85rem.
**Marker Circle Set** — Three sizes (`{components.bullet-dot}` 20px, `{components.circle-dot}` 48px, `{components.circle-icon}` 44px, `{components.step-circle-lg}` 90px). All are outlined circles in a pastel fill, all carry charcoal border. Numerals or single letters inside larger marker circles are always Fredoka One in white text (except on butter-yellow, where text returns to dark).
**Avatar Circle** — A 100px outlined white circle holding a small character SVG portrait or initial. Carries `{shadows.small}`.
**Quote Mark** — An oversized `"` glyph in Fredoka One at ~4rem in `{colors.soft-pink}`, placed above the quote body inside a quote card.
**Process Arrow** — A simple `→` glyph in Fredoka One at ~2rem in `{colors.text-dark}`, sat between process steps.
**Legend Swatch** — A 18px square with 4px rounded corners and a 2px border. Holds a fill color matched to a corresponding data series.
## Do's and Don'ts
### Do
- Pair Fredoka One with Quicksand strictly by role — Fredoka for every headline and display moment, Quicksand for every paragraph and meta line. The two-face contrast is the system's voice.
- Set the default canvas to `{colors.cream}`. Reach for a saturated pastel surface (turquoise, soft-pink, mint, etc.) when the slide wants a tonal mood, but cream is the safe default for content-heavy moments.
- Apply a 3px solid charcoal outline plus a `{shadows.default}` or `{shadows.small}` hard offset shadow to every elevated container. The outline + offset shadow combo is the system's signature elevation.
- Apply the `{shadows.text-headline}` text-shadow to every Fredoka One headline placed over a saturated pastel surface. Skip it only on cream.
- Cluster 3–7 hand-drawn SVG decorations (daisies, stars, suns, clouds, rainbows) around every slide's edges, often cropping past the boundary. Empty corners look broken in this system.
- Use outlined colored discs as list bullets — never bare hyphens or asterisks. The `{components.bullet-dot}` with `{colors.butter}` fill is the default.
- Reserve `{colors.coral}` for small high-attention markers (step numbers, timeline dots, day-headers). Coral as a full slide surface breaks the warmth-balance and reads aggressive.
- Center the main content container with a max-width well inside the slide padding. The decorations need room at the edges; full-bleed content blocks the ornament layer.
- Rotate marker / dot colors through the pastel set (coral → mint → sky → lavender → butter) when a sequence needs distinct steps. Do not use a single color for all steps.
### Don't
- Don't use any font other than Fredoka One and Quicksand. The system loads only those two faces from Google Fonts. Adding a third face breaks the storybook voice.
- Don't put Quicksand into a headline or Fredoka One into a paragraph. The role / face mapping is strict.
- Don't use square corners. Every card, every badge, every marker has some radius — the smallest radius in the system is 4px (legend swatch), and most are 20px or larger.
- Don't use blurred or rgba shadows. The system uses solid charcoal offsets only. `0 4px 12px rgba(0,0,0,0.1)` does not exist here.
- Don't use colored borders. All borders are charcoal `{colors.text-dark}`.
- Don't use coral as a full slide surface. Coral is the system's high-attention spot color; it loses power if it covers a region.
- Don't render Fredoka One in italic, underline, or stretched weights. Fredoka has one weight — that's the design.
- Don't omit the text-shadow on Fredoka headlines that sit on a saturated pastel surface. The shadow is what unifies headline weight with the outlined-shape vocabulary.
- Don't leave a slide's corners empty of decorations. The ornament layer is part of the composition, not optional dressing.
- Don't pile two cards on top of each other without separation. The system reads as one main content region per slide, surrounded by ornament — not as a stack of competing panels.
## Responsive Behavior
The system targets a viewport-fluid layout (everything sized in `clamp()` or `vw`), but is tuned for desktop / projector at roughly 1280–1920 width. Two responsive breakpoints adapt the grids:
- **`@media (max-width: 768px)`**: Slide padding tightens to `24px 20px`. Multi-column grids collapse: the 5-column weekly grid drops to 3, the 4-column team grid drops to 2, the 2-column info-card grid drops to 1, the horizontal process flow stacks vertically with rotated arrows, and the horizontal donut layout stacks. The right-edge nav dots hide. Decoration opacity drops to 0.6 so they don't overwhelm the cramped layout.
- **`@media (max-width: 480px)`**: The 3-column weekly grid drops further to 2. Decoration opacity drops to 0.4.
### Presenter Behavior
- Scroll-snap-y mandatory locks each slide to the viewport on vertical scroll.
- Keyboard: ArrowDown / ArrowRight / Space / PageDown advance; ArrowUp / ArrowLeft / PageUp reverse; Home jumps to first; End jumps to last.
- Right-edge nav dots show current slide and accept click-to-jump.
- A bottom-center counter pill displays `N / total` and updates via IntersectionObserver.
### Print / Export
There is no `@media print` rule defined. Print export will inherit the scroll-container layout, which may not paginate cleanly. Treat this as a screen-first system; a separate print stylesheet would be needed for PDF export.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Fredoka One 400) | Fredoka One | 站酷小薇体 ZCOOL XiaoWei | Google Fonts |
| Body (Quicksand 500–600) | Quicksand | 悠哉字体 Yozai | cn-fontsource CDN |
### Mixed-Content Strategy
Use **Strategy A — single-font-stack with fallback**: declare ZCOOL XiaoWei *after* Fredoka One and Yozai *after* Quicksand in the same `font-family` stack so Latin glyphs render in the Latin face and CJK glyphs fall through to the Chinese face automatically. One CSS rule per role, no manual class switching.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka+One&family=Quicksand:[email protected]&family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-yozai-regular/font.css" rel="stylesheet">
```
```css
:root {
--font-display: "Fredoka One", "ZCOOL XiaoWei", cursive;
--font-body: "Quicksand", "Yozai", sans-serif;
}
```
### Universal CJK Adjustments
- **Line-height**: bump CJK body line-height to ~1.75 (from 1.6) — Hanzi need more vertical breathing than Latin lowercase.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (the 0.02em Fredoka tracking jams Hanzi strokes together). Keep Latin tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any badge/label when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (,。:;「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick ZCOOL XiaoWei *or* Yozai for a given text run based on its role, never both inside one phrase.
### Aesthetic Notes
ZCOOL XiaoWei's rounded soft display register is the closest Hanzi analogue to Fredoka One's chubby storybook voice — it carries the same "friendly children's-book" mood at headline scale without becoming saccharine. Yozai's open counters and modest stroke contrast match Quicksand's humanist warmth, so body paragraphs and meta lines feel continuous with the pastel-garden aesthetic. The 3px charcoal text-shadow on headlines that sit on saturated pastel surfaces works identically on ZCOOL XiaoWei — apply `{shadows.text-headline}` to Chinese headlines on turquoise / butter / peach surfaces, and `{shadows.text-headline-soft}` on soft-pink / mint, exactly as the Latin rule prescribes. The colored bullet-dots, hand-drawn SVG decorations (daisies, stars, suns, clouds, rainbows), framed-header cap-and-body pattern, and pastel marker rotation are all content-agnostic. The single-weight constraint of Fredoka One maps cleanly to ZCOOL XiaoWei's single-weight constraint — neither face supports italic, underline, or weight axis variation, which preserves the system's "one weight, one face per role" discipline.
### Known CJK Gap
ZCOOL XiaoWei is a single-weight display face with limited glyph coverage compared to Noto family — exotic or technical Hanzi (rare surnames, classical characters, simplified-only variants outside GB2312) may fall back to system font. For Traditional Chinese decks, swap Yozai for `LXGW WenKai TC` (Google Fonts) which has fuller TC coverage and a similar friendly humanist register. ZCOOL XiaoWei reads slightly more literary-formal than Fredoka One's chubby chunky personality — Chinese decks built with Daisy Days will feel ~20% more "calm pastel" and ~20% less "sticker-sheet kawaii" than the Latin original. The hand-drawn SVG ornaments (daisy, star, sun, cloud, rainbow) carry the storybook mood that the typography slightly loses, so on Chinese decks consider clustering 5–7 ornaments per slide (the upper end of the 3–7 range) to recover the playful weight.
## Iteration Guide
1. Any new container is rounded (20px / 28px / pill / circle), bordered in 3px charcoal, and shadowed with `{shadows.default}` or `{shadows.small}`. Never ship a flat rectangle with square corners.
2. Any new headline is Fredoka One. If it sits on a saturated pastel surface, it gets a 3px charcoal text-shadow and switches color to `{colors.white}`. If it sits on cream or on a white card, it stays `{colors.text-dark}` and skips the shadow.
3. Any new paragraph is Quicksand 500 by default; Quicksand 600 when the paragraph needs emphasis.
4. Any new bullet is an outlined colored disc (`{components.bullet-dot}`), not a glyph. The default fill is butter, but circle bullets can rotate through the pastel set.
5. Any new sequence of markers (steps, timeline nodes, day labels) rotates through the pastel set (`coral → mint → sky → lavender → butter`) rather than reusing one color.
6. Any new slide needs 3–7 SVG decorations clustered at corners and edges. Draw from the established ornament types (daisy, star, sun, cloud, rainbow) — do not introduce a new ornament style (e.g. line-art arrows, photo cutouts).
7. Any new accent surface picks one of the eight pastels. Do not introduce a ninth color.
8. Coral stays a small-marker color only. Do not make a coral surface, a coral card, or a coral headline.
9. Any list bullet sits 4px from the top of the first text line, vertically aligned with x-height, not the line baseline.
10. When a new component needs a "two-part frame" feel, reach for the `{components.framed-header}` pattern (colored cap + white body) rather than nesting two separate cards.
## Known Gaps
- The two Google Fonts (Fredoka One, Quicksand) are loaded via `<link>` from Google Fonts CDN. Offline rendering will fall back to `cursive` and `sans-serif` system defaults, which collapses the entire typographic identity. Self-hosting the fonts is required for offline / print reliability.
- The hand-drawn SVG decorations (daisy, star, sun, cloud, rainbow) are inline SVG with their stroke colors hardcoded to `#232323` or `#2D2D2D`. There is no programmatic way to recolor them to match a new palette — extending the decoration library requires authoring new SVG sources.
- The system uses scroll-snap navigation (not absolute-positioned slides). It does not have a dedicated print stylesheet; PDF export of the deck will not paginate one-slide-per-page out of the box.
- The nav-dots / slide-counter / keyboard / observer JavaScript is embedded inline and hardcodes the slide count via the `<div class="nav-dot">` array. Adding a new slide requires manually adding a corresponding nav-dot div.
- The pastel surfaces (turquoise, mint, peach) have varying perceived brightness; the text-shadow treatment for headlines must be tuned per-surface (the system already does this — full charcoal for bold surfaces, 20%-opacity charcoal for soft surfaces). New surface colors will require a similar tuning decision.
- The `--text-muted` color (#6B6B6B) is used for subtitles and captions but has limited contrast against pastel surfaces. Reserve muted text for use on cream or on white cards, not on pastel surfaces directly.
- The decoration SVGs include a placeholder comment string `SVG created with Arrow, by QuiverAI (https://quiver.ai)` — this is the original authoring tool credit and can be stripped without affecting rendering.
# Daisy Days Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/daisy-days/design.md`
- Preview card: `bold-template-pack/templates/daisy-days/preview.md`
## Selection Metadata
- Slug: `daisy-days`
- Tagline: Cheerful pastel deck with hand-drawn daisies, stars, and rainbows. Friendly, soft, and warm.
- Mood: cheerful, playful, warm, sunny, wholesome
- Tone: friendly, soft, encouraging, approachable, lighthearted
- Formality: low
- Density: medium
- Scheme: light
- Best for: Anything that should feel friendly, soft, and joyful: educational content, kids and family, wellness programs, community workshops, creator portfolios for craft / illustration. Also lovely for an unexpected playful internal kickoff, a wedding planning deck, or any moment where warmth is the message — including across tech or business contexts.
- Avoid for: Contexts where the audience explicitly expects authority and precision — the hand-drawn pastel SVG decorations are the opposite of buttoned-up.
## Visual Snapshot
A cheerful, childlike presentation system built around the chunky display face Fredoka One and the rounded humanist sans Quicksand. The palette is a sunny garden — cream canvas, turquoise, soft pink, butter yellow, mint, lavender, peach, sky blue, and a single coral accent — with charcoal-brown 2D outlines wrapping every shape. Hard offset shadows in dark charcoal, generous border-radius, and hand-drawn SVG decorations (daisies, stars, suns, clouds, rainbows) anchor the aesthetic somewhere between a children's storybook spread and a sticker-sheet kawaii zine.
Daisy Days is a cheerful childlike presentation system rooted in a single typographic pairing: the chubby rounded display face Fredoka One for every headline, and the friendly humanist sans Quicksand for every line of body and meta text. The visual language descends from picture-book illustration and sticker-sheet kawaii: every shape carries a charcoal 2D outline, every elevated element casts a solid offset shadow, and every surface is a pastel from a sunny garden palette.
## Preview Ingredients
- Palette: cream #F5F0E6; turquoise #7ECDC0; soft-pink #F7C8D4; butter #FDE68A; mint #A8E6CF; lavender #D4A5E8; peach #FFCBA4; sky #A8D8F0
- Typography: See full design doc after selection.
- Signature move: Cream ({colors.cream}) default canvas with rotating pastel surfaces — every slide may pick a different surface color.
- Signature move: Fredoka One for all headline / display / quote text; Quicksand 500/600 for all body and meta text.
- Signature move: Every shape and card carries a 3px solid charcoal outline ({colors.text-dark}) plus a hard offset shadow ({shadows.default} or {shadows.small}).
- Signature move: Generous border-radius: 20px on standard cards, 28px on featured cards, pill ({spacing.radius-pill}) on badges, full circle on dots and avatars.
- Signature move: Hand-drawn SVG ornaments (daisies, stars, suns, clouds, rainbows) cluster at corners and crop past slide edges as atmospheric layer.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Editorial Forest
description: A serif-led editorial presentation system in the register of a literary quarterly or art-book monograph. Display type runs in Source Serif 4 at weight 500 with optical-size axis engaged, scaling up to 220px for cover and stat moments. The palette pairs a deep forest green (#2e4a2a) with a dusty rose pink (#e89cb1) over an oat-cream paper ground (#efe7d4), with JetBrains Mono as the editorial chrome (labels, captions, axis ticks). The aesthetic is closer to a Penguin classic, Apartamento spread, or quiet annual report than a tech keynote — confident, paper-feeling, and committed to a small color vocabulary.
colors:
green: "#2e4a2a"
green-deep: "#243a21"
green-lite: "#3a5a36"
pink: "#e89cb1"
pink-deep: "#d27e96"
cream: "#efe7d4"
cream-2: "#e6dcc4"
ink: "#1a1a17"
typography:
display-hero:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 220
fontWeight: 500
lineHeight: 0.92
letterSpacing: -0.02em
display:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 140
fontWeight: 500
lineHeight: 1.02
letterSpacing: -0.02em
headline-xl:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 96
fontWeight: 500
lineHeight: 0.96
letterSpacing: -0.02em
headline:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 84
fontWeight: 500
lineHeight: 1.0
letterSpacing: -0.02em
headline-sm:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 80
fontWeight: 500
lineHeight: 0.98
letterSpacing: -0.02em
title-card-lg:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 84
fontWeight: 500
lineHeight: 0.98
letterSpacing: -0.01em
title-card:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 68
fontWeight: 500
lineHeight: 0.96
letterSpacing: -0.01em
title-card-sm:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 56
fontWeight: 500
lineHeight: 0.98
letterSpacing: -0.01em
figure-caption-serif:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 56
fontWeight: 500
lineHeight: 1.05
name:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 44
fontWeight: 600
lineHeight: 1.0
meta-value:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 32
fontWeight: 500
body-lg:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 32
fontWeight: 400
lineHeight: 1.32
body:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 30
fontWeight: 400
lineHeight: 1.38
body-card:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 26
fontWeight: 400
lineHeight: 1.34
label:
fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
fontSize: 26
fontWeight: 500
letterSpacing: 0.18em
textTransform: uppercase
label-tight:
fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
fontSize: 26
fontWeight: 500
letterSpacing: 0.14em
textTransform: uppercase
caption-mono:
fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
fontSize: 24
fontWeight: 500
letterSpacing: 0.14em
textTransform: uppercase
axis-mono:
fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
fontSize: 26
fontWeight: 500
letterSpacing: 0.08em
stat-figure:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 220
fontWeight: 500
lineHeight: 0.92
letterSpacing: -0.03em
stat-figure-unit:
fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
fontSize: 110
fontWeight: 500
lineHeight: 0.92
spacing:
slide-pad-default: "96px 120px"
slide-pad-narrow: "100px 120px"
slide-pad-wide: "100px 140px"
slide-pad-statement: "130px 160px"
grid-gap-cards: 28
grid-gap-topics: 24
grid-gap-kpi: 60
rule-weight: "2px"
rule-weight-card: "2.5px"
radius-card: "6px"
radius-card-step: "8px"
radius-bar-top: "3px 3px 0 0"
radius-mark-circle: "50%"
canvas:
width: 1920px
height: 1080px
components:
topic-tile:
description: "Bordered or filled rectangular region holding a mono ordinal, a serif title, optional body, and a mono foot. Background may be green / green-lite / pink / cream-2-with-green-border. Corner radius 6px."
borderRadius: "{spacing.radius-card}"
padding: "40px 40px 36px"
step-tile:
description: "Vertical card carrying a mono ordinal, a serif title, body paragraph, and a mono marker row separated by a top rule. Background fills: cream-with-green-border, solid green, or solid pink."
borderRadius: "{spacing.radius-card-step}"
padding: "40px 32px 32px"
minHeight: "470px"
border: "2.5px solid currentColor-region"
monogram-circle:
width: "130px"
height: "130px"
borderRadius: "{spacing.radius-mark-circle}"
border: "2px solid {colors.pink}"
fontFamily: "JetBrains Mono"
fontSize: 28
letterSpacing: 0.1em
fontWeight: 500
description: "Outlined round mark holding a short mono monogram. The system's signature identity stamp."
topbar:
placement: "top edge of slide"
layout: "flex space-between, baseline-aligned"
content: "{components.label} on the left, monogram-circle or counter on the right"
footline:
position: "absolute"
placement: "bottom edge of slide, full-width between slide padding"
layout: "flex space-between"
typography: "{typography.caption-mono}"
meta-dl:
description: "Three-column definition list separated by a top rule (2px {colors.green}). Each entry has a mono dt label and a serif dd value."
columns: 3
gap: "36px"
topBorder: "2px solid {colors.green}"
bar:
width: "56px"
borderRadius: "{spacing.radius-bar-top}"
description: "Vertical chart bar in pink, cream, or green. Value label printed above bar in mono."
chart-axis:
border: "2px solid currentColor"
description: "Y-axis and x-axis use a single 2px rule on the inner edges of the plot region; no full axis box."
rule-thin:
description: "Hairline 2px rule, used as section separator above kpi rows, summary grids, meta dls. Color follows region (green on cream, pink on green)."
legend-swatch:
display: "inline-block"
width: "26px"
height: "26px"
borderRadius: "2px"
description: "Small filled square preceding a mono legend label. 2px corner radius is the smallest radius in the system."
---
## 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
Editorial Forest is a **serif-led editorial presentation system** in the tonal register of a Penguin classic, a quiet annual report, or an art-book spread. The system's foundational premise is a single, confident typographic voice — Source Serif 4 — used at extreme scale (up to 220px) for headlines and stat figures, with JetBrains Mono playing the supporting role of editorial chrome (labels, captions, axis ticks, page footlines).
The serif is run at **weight 500** for nearly every display moment — never the more familiar 400 or 700. The 500 weight is the system's most distinctive typographic choice: heavy enough to feel authored, light enough to keep the page calm. Optical-size axis is engaged (`opsz` 8..60), which means the same Source Serif 4 face renders with subtly different letterforms at 26px caption sizes versus 220px display sizes — the small sizes pick up extra contrast and finer details automatically. JetBrains Mono runs at 500 in uppercase with 0.14em–0.18em letter-spacing, used for every label, tag, caption, axis tick, and footer line. The system never mixes a third typeface.
The palette is a tight five-color editorial set built around three primary surfaces: a **deep forest green** (`{colors.green}` — #2e4a2a), a **dusty rose pink** (`{colors.pink}` — #e89cb1), and an **oat cream paper** (`{colors.cream}` — #efe7d4). Two near-duplicates round out the set: `{colors.green-deep}` for green-on-pink text contrast, `{colors.green-lite}` for tile fills that need a second green shade, `{colors.pink-deep}` for pink-on-pink borders, and `{colors.cream-2}` for tiles that sit on the main cream surface. Body text everywhere is `{colors.ink}` (#1a1a17) — a warm near-black — except when sat on a green or pink surface, where it switches to the surface's complementary color (cream or pink on green; green-deep or cream on pink).
Depth is **flat and paper-based**. There are no drop shadows, no glows, no gradients, no overlays. Elevation is communicated entirely through color-block contrast, 2px hairline rules, and the difference between a filled region and a bordered region. The 6px and 8px card radii are the only roundness in the system besides the monogram circle. The page feels printed, not glassy.
**Density philosophy: spacious and committed.** Each slide carries one strong subject — a headline, a quote, a chart, a stat row, a card grid — surrounded by deep negative space. The slide padding of 96–140px is generous; the top of the slide carries a mono topbar (label + monogram or counter), the bottom carries a mono footline, and the middle holds the main subject at scale. A slide that crams two competing content blocks reads as broken; a slide with one display headline + supporting cards + breathing room reads as authoritative. Reach for fewer elements at larger sizes rather than more elements at smaller sizes.
**Key Characteristics:**
- Three-color editorial palette: deep forest green, dusty rose pink, oat cream paper. Two surface tones per slide is typical; three is loud.
- Source Serif 4 at weight 500 for every headline, body, and display moment. Optical-size axis engaged for size-aware letterforms.
- JetBrains Mono at weight 500 uppercase with wide tracking (0.14em–0.18em) for every label, caption, axis tick, and footline.
- Display type scales to 220px for cover and stat-figure moments; 96px for primary headlines; 56–84px for card titles.
- 2px hairline rules separate stacked sections — never thicker, never colored beyond region context.
- Card radius is 6px for topic tiles and 8px for step tiles. The monogram circle is the only fully round shape.
- Every slide carries a topbar (label + monogram or counter) and most carry a footline (mono caption row). The chrome anchors the editorial feel.
- No shadows, no gradients, no glows. Elevation is color-block + rule.
## Colors
### Palette
- **Green** (`{colors.green}` — #2e4a2a): The deep forest primary. Used as a slide surface, a tile fill, a card border, a meta-dl rule color, and a primary text color on cream surfaces. The most distinctive surface in the system.
- **Green Deep** (`{colors.green-deep}` — #243a21): A darker green used almost exclusively as text color on pink surfaces, where pure green would lack contrast. Also used as text color on pink tiles.
- **Green Lite** (`{colors.green-lite}` — #3a5a36): A lighter green used as a tile fill when two greens need to sit beside each other (e.g., a primary green tile next to a secondary green-lite tile in the same grid). Carries pink text.
- **Pink** (`{colors.pink}` — #e89cb1): A dusty rose. Used as a slide surface, a tile fill, the on-green text color, a bar-chart series color, and the monogram circle border color. The system's primary accent.
- **Pink Deep** (`{colors.pink-deep}` — #d27e96): A slightly darker rose used only as a border color on pink-filled tiles where the same-color border needs to differentiate from the fill.
- **Cream** (`{colors.cream}` — #efe7d4): The oat paper surface. The default slide background on non-cover slides, the on-green body text color, and the cream bar-chart series color.
- **Cream 2** (`{colors.cream-2}` — #e6dcc4): A subtly darker cream used as a tile fill on the cream slide surface. Pairs with a 2px green border so the tile reads as distinct from the slide ground.
- **Ink** (`{colors.ink}` — #1a1a17): The body text color on cream surfaces. A warm near-black; never pure #000.
### Defaults
- **Default slide background**: `{colors.cream}` for content-heavy slides; `{colors.green}` for cover, statement-data, summary, and any moment that needs gravity.
- **Default headline color on `{colors.cream}` surface**: `{colors.green}`.
- **Default headline color on `{colors.green}` surface**: `{colors.cream}` for primary headlines, `{colors.pink}` for hero / cover-scale headlines.
- **Default headline color on `{colors.pink}` surface**: `{colors.green-deep}`.
- **Default body color on `{colors.cream}` surface**: `{colors.ink}`.
- **Default body color on `{colors.green}` surface**: `{colors.cream}`.
- **Default body color on `{colors.pink}` surface**: `{colors.green-deep}`.
- **Default label / caption color**: matches the region's accent (label is pink on green, green on cream, green-deep on pink).
- **Default tile fill on a cream slide**: choose from the rotation — solid green (with pink text), solid pink (with green-deep text), green-lite (with pink text), or cream-2 with a 2px green border (with green text). A single grid typically mixes 3 of these 4.
- **Default rule color**: green on cream, pink on green, green-deep on pink. The 2px hairline always picks up the region's accent.
The palette is intentionally tight. Introducing a fourth chromatic family (a yellow, a blue, an additional rose) breaks the editorial discipline. Stick to the green / pink / cream triad and let the contrast between filled and bordered tiles do the variation work.
## Typography
### Font Family
The system loads exactly two web fonts: **Source Serif 4** (with the full optical-size axis 8..60 and weights 300–800) and **JetBrains Mono** (weights 400, 500, 700). Source Serif 4 carries every editorial moment — headlines, body, captions in serif, names, figures. JetBrains Mono carries every piece of chrome — labels, taglines, axis ticks, footlines, ordinals on tiles.
The mono / serif pairing is the system's typographic identity. Mono never tries to be the headline; serif never tries to be the caption. The roles are inverted from a typical "sans for chrome, serif for body" stack — here it's "mono for chrome, serif for body and display."
Source Serif 4 is run at **weight 500** for nearly every moment. Weight 400 appears only for body paragraphs (where the lighter weight reads better at small scale). Weight 600 appears once, for the attribution name on the statement slide — its slightly heavier set distinguishes a proper name from surrounding mono labels. Weight 700 is not used.
### Display, Body, and Chrome Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-hero}` | 220px | Source Serif 4 | 500 | Cover-scale or closing-scale headline |
| `{typography.display}` | 140px | Source Serif 4 | 500 | Pull-quote / big-idea statement |
| `{typography.headline-xl}` | 96px | Source Serif 4 | 500 | Primary section headline on cream |
| `{typography.headline}` | 84px | Source Serif 4 | 500 | Primary section headline on green |
| `{typography.headline-sm}` | 80px | Source Serif 4 | 500 | Stat-row introductory headline |
| `{typography.title-card-lg}` | 84px | Source Serif 4 | 500 | Title inside a hero topic tile (largest tile in a grid) |
| `{typography.title-card}` | 68px | Source Serif 4 | 500 | Title inside a step tile |
| `{typography.title-card-sm}` | 56px | Source Serif 4 | 500 | Title inside a standard topic tile |
| `{typography.figure-caption-serif}` | 56px | Source Serif 4 | 500 | Centered figure / image-placeholder caption |
| `{typography.stat-figure}` | 220px | Source Serif 4 | 500 | KPI numeral |
| `{typography.stat-figure-unit}` | 110px | Source Serif 4 | 500 | Unit suffix on a KPI numeral (e.g. "%") |
| `{typography.name}` | 44px | Source Serif 4 | 600 | Personal name in an attribution row |
| `{typography.meta-value}` | 32px | Source Serif 4 | 500 | Definition-list value in a meta row |
| `{typography.body-lg}` | 32px | Source Serif 4 | 400 | Primary body paragraph in a summary or stat description |
| `{typography.body}` | 30px | Source Serif 4 | 400 | Standard body paragraph |
| `{typography.body-card}` | 26px | Source Serif 4 | 400 | Body inside a card or tile |
| `{typography.label}` | 26px | JetBrains Mono | 500 / 0.18em | Eyebrow or section label in topbar |
| `{typography.label-tight}` | 26px | JetBrains Mono | 500 / 0.14em | Caption row, foot line, attribution row, tile ordinal |
| `{typography.caption-mono}` | 24px | JetBrains Mono | 500 / 0.12–0.16em | Tile foot, tile marker, kpi tag, meta-dl term |
| `{typography.axis-mono}` | 26px | JetBrains Mono | 500 / 0.08em | Chart axis ticks and labels |
### Defaults
- **Default size for a primary section headline**: `{typography.headline-xl}` (96px) on cream surfaces, `{typography.headline}` (84px) on green surfaces.
- **Default size for a cover-scale or closing-scale moment**: `{typography.display-hero}` (220px).
- **Default size for a quote / big-idea statement**: `{typography.display}` (140px).
- **Default size for a body paragraph**: `{typography.body}` (30px) in serif weight 400.
- **Default size for a body paragraph inside a card / tile**: `{typography.body-card}` (26px).
- **Default size for a meta dt label or tile ordinal**: `{typography.caption-mono}` (24px) in JetBrains Mono uppercase.
- **Default size for a topbar label / eyebrow**: `{typography.label}` (26px) in JetBrains Mono uppercase with 0.18em tracking.
- **Default weight for any serif moment**: 500. (400 is reserved for body paragraphs; 600 only for a proper name in attribution.)
- **Default weight for any mono moment**: 500.
When unsure, reach for `{typography.headline-xl}` (96px) for the slide's primary headline on cream, not the larger display sizes. The 140–220px tier is reserved for statement, stat-figure, and hero/closing moments — using it for routine headlines flattens the system's hierarchy.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every JetBrains Mono element is UPPERCASE with letter-spacing of at least 0.08em.** Mono in sentence case or without tracking reads as code, not editorial chrome. The wide tracking is what makes mono feel like a caption row in a magazine, not a terminal.
- **Every Source Serif 4 display element uses negative letter-spacing (-0.01em to -0.03em).** Tighter tracking pulls the large serif glyphs into a single mass and is essential for the 96–220px sizes. Display serif at default tracking reads loose and untreated.
- **Display headlines use line-height between 0.92 and 1.02.** Tight line-height is part of the system's display voice. Larger headlines run tighter (0.92 at 220px); smaller headlines (84–96px) run at 0.96–1.0.
- **Body paragraphs use serif weight 400, not 500.** The weight drop from headline to body is the system's reading rhythm. Body at 500 reads heavy.
- **Every slide carries a topbar (mono label + monogram or counter on the opposite edge).** The topbar is the system's universal chrome anchor.
- **Hairline rules between sections are always 2px solid.** Never 1px (reads as web app), never 3px+ (reads as poster).
### Typography Principles
The weight 500 + optical-size + tight tracking combination is the system's display voice — switching any of those three properties (e.g., serif weight 700, or default tracking, or no opsz) reads as a different design system. The serif/mono role split is strict: mono never appears at headline scale, serif never appears at axis-tick scale.
Italics are not used anywhere in the system. Underline is not used. Emphasis is communicated through size and color contrast, not type variants.
## Layout
### Canvas System
The system targets a fixed **1920×1080** canvas. Slides are `<section>` elements at exact width/height; rendering relies on `deck-stage.js` to scale the canvas to fit the viewport. The canvas is paper, not a viewport — designed for projector, printer, or PDF export.
### Slide Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad-default}` | 96px 120px | Standard slide padding |
| `{spacing.slide-pad-narrow}` | 100px 120px | Data, framework, stats slides — slightly taller top padding |
| `{spacing.slide-pad-wide}` | 100px 140px | Cover, summary slides — extra side padding for hero headlines |
| `{spacing.slide-pad-statement}` | 130px 160px | Statement slide — most generous padding for the display-quote moment |
Pick the padding that matches the content gravity. Statement-class moments get the widest padding; everyday content slides use the default 96×120.
### Chrome Anatomy
Every slide carries (at minimum) a **topbar** at the top edge — a flex-row with a JetBrains Mono `{typography.label}` on one side and either a `{components.monogram-circle}` or a mono counter / location string on the other. Heavier slides (cover, data, summary) also carry a **footline** absolutely positioned at `bottom: 60–80px` with a mono caption row spanning the slide width between the padding.
The topbar is the system's spine. Without it, a slide reads as untreated.
### Card Radii
| Value | Use |
|---|---|
| 2px | Legend swatch only (smallest radius in the system) |
| 3px 3px 0 0 | Top corners of bar-chart bars |
| 6px | Topic tile (agenda-style grid) |
| 8px | Step tile (framework-style grid) |
| 50% | Monogram circle |
Cards are subtly rounded — never sharp-cornered, never heavily-rounded. The 6–8px radius gives the system its paper-not-plastic feel.
## Depth and Elevation
### Flat, No Shadows
There are **no shadows in this system**. Not on cards, not on tiles, not on text, not on the monogram circle. Elevation is communicated entirely through:
1. **Color-block contrast** — a green tile on a cream slide reads as elevated because the dark green block separates from the paper ground.
2. **2px hairline rules** — section separators (above kpi rows, summary grids, meta dls) sit on a 2px line in the region's accent color.
3. **Border vs fill** — a cream-2 tile with a 2px green border reads as a different elevation than a solid-fill tile beside it.
The absence of shadow is itself the elevation language. Adding `box-shadow: 0 4px 12px rgba(0,0,0,0.1)` would shatter the editorial feel.
### Paper-Surface Rule
Every surface in the system reads as paper, not as a digital pane. The cream tones (`{colors.cream}`, `{colors.cream-2}`) carry that quality literally. The green and pink surfaces inherit it by association — used at full saturation, surrounded by cream chrome, never with shadow or glow, they read as printed ink on stock.
## Shapes and Treatment
### Border Weight and Style
- **2px solid** — the universal hairline. Section separator rules above kpi rows / summary grids / meta dls / chart axes; the border on cream-2 tiles; the border on the monogram circle.
- **2.5px solid** — step-tile borders. Slightly heavier so the tile reads as a separate object from a hairline rule.
Borders take the region's accent color (`{colors.green}` on cream, `{colors.pink}` on green, `{colors.green-deep}` or `{colors.pink-deep}` on pink).
### Decorative Element Types
**Monogram Circle** (`{components.monogram-circle}`) — A 130px outlined circle with a 2px pink border, holding a 2–3-character JetBrains Mono monogram at 28px. Lives in the top-right of cover and summary slides. The system's identity stamp.
**Topbar** (`{components.topbar}`) — A flex row spanning the top of every slide. A JetBrains Mono label on one side, a monogram or counter or location string on the other. The topbar establishes which surface family the slide belongs to (label color tells you).
**Footline** (`{components.footline}`) — An absolutely positioned flex row at `bottom: 60–80px` spanning the slide between padding. Two mono caption strings (e.g., a section name on the left, a page number on the right). Used on cover, data, summary, and any slide that wants to feel like a printed page.
**Topic Tile** (`{components.topic-tile}`) — A 6px-radius rectangular region holding a mono ordinal, a serif title, optional body, and a mono foot string. Background fills rotate through green, green-lite, pink, or cream-2-with-green-border. A grid of these tiles is the agenda / table-of-contents pattern.
**Step Tile** (`{components.step-tile}`) — An 8px-radius vertical card with 2.5px border, holding a mono ordinal, a serif title (68px), a body paragraph, and a mono marker row separated by a top rule. Background fills: cream-with-green-border, solid green, or solid pink. A row of 3–4 step tiles is the framework / process pattern.
**KPI Block** — A vertical stack: mono tag (24px) on top, oversized serif figure (220px) with optional 110px unit, then a serif description paragraph (30px). Sits inside a row separated above by a 2px pink rule on green surfaces.
**Bar (chart)** — A 56px-wide rectangle with top corners rounded at 3px, filled in pink, cream, or green. The value label is mono 24px, absolutely positioned 38px above the bar.
**Meta Definition List** (`{components.meta-dl}`) — A three-column dt/dd grid with a 2px top border. The dt is mono 24px uppercase tracked, the dd is serif 32px weight 500. Used as a credits / specs / details row at the bottom of a two-column slide.
**Legend Row** — A horizontal flex of mono uppercase items, each preceded by a 26×26px filled swatch with 2px corner radius. Used in chart and data contexts.
## Do's and Don'ts
### Do
- Run every display headline in Source Serif 4 at weight 500 with negative letter-spacing (-0.01em to -0.03em) and tight line-height (0.92–1.0). The combination is the system's voice.
- Run every label, caption, tag, axis tick, and footline in JetBrains Mono at weight 500 uppercase with 0.08em–0.18em letter-spacing.
- Place a topbar (mono label + monogram or counter) on every slide. The topbar is the system's spine.
- Pick a single dominant surface per slide (green, pink, or cream) and let it carry the whole canvas. Two surface colors per slide is the maximum.
- Pair tile fills in a grid: rotate through green + pink + green-lite + cream-2-with-green-border rather than reusing one fill across all tiles.
- Use 2px solid hairline rules to separate stacked sections (kpi rows, summary grids, meta dls). The hairline is the system's separator language.
- Scale display type aggressively when content allows — 140–220px for statement, hero, and closing moments. The system rewards bigness when there's room.
- Use generous slide padding (96–160px). Negative space is part of the editorial register; cramped padding reads as broken.
- Reserve the monogram circle for cover and summary moments. Using it on every slide dilutes its function as an identity stamp.
### Don't
- Don't add box-shadow to any element. The system is shadow-free; adding shadow shatters the paper feel.
- Don't introduce a third typeface. Only Source Serif 4 and JetBrains Mono. No Inter, no system stack.
- Don't run serif text in italic or underline. Emphasis is size and color, not type variant.
- Don't render JetBrains Mono in sentence case or without letter-spacing. Mono without uppercase + tracking reads as code, not chrome.
- Don't introduce a fourth chromatic family (yellow, blue, lavender). The green / pink / cream triad is the entire palette.
- Don't use heavy borders (4px+) or thin hairlines (1px). The system has 2px and 2.5px — pick one.
- Don't pile two competing content blocks on one slide. One subject per slide; expand or split.
- Don't use rgba transparency for surface colors. Each surface is solid ink-on-paper.
- Don't run serif body text at weight 500 — it reads heavy. Body is weight 400; display is weight 500.
- Don't omit the topbar. A slide without the mono label at the top loses its editorial spine.
## Responsive Behavior
This is a **fixed 1920×1080 presentation system** rendered through `deck-stage.js`. The canvas is not responsive in the web sense — there are no media queries, no breakpoints, no fluid sizing. Every measurement is in fixed pixels at 1920×1080.
### Scaling Behavior
The `deck-stage.js` script wraps each `<section>` and scales the 1920×1080 canvas uniformly to fit the browser viewport, letterboxing as needed. Type, padding, gaps, and rule weights are all in pixels and scale proportionally with the canvas. Borders that read as 2px at 1920px will read as 1px at 960px viewport width — this is acceptable inside the system's tolerance.
### Presenter Behavior
Navigation is delegated to whatever wrapper `deck-stage.js` provides — there is no inline keyboard handler. Treat each `<section>` as a slide; the runtime handles transitions.
### Print / Export
Because every measurement is fixed-pixel inside a 1920×1080 canvas, the system exports cleanly to PDF at the same aspect ratio (16:9). Source Serif 4 with the optical-size axis renders well at print resolution because the small-sized variants pick up the print-appropriate letterform detail automatically.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display headline (220 / 140 / 96 / 84px) | 霞鹜文楷 LXGW WenKai (Noto Serif SC fallback) | 400 | Literary, handwritten-ish brushwork; matches the Penguin-classic register of Source Serif 4 |
| Body paragraph (26 / 30 / 32px) | 思源宋体 Noto Serif SC | 400 | Reads as the printed body voice of a literary quarterly |
| Stat figure (220px) | 思源宋体 Noto Serif SC | 700 | Mincho weight 700 gives the numeric mass that Source Serif 4 weight 500 provides in Latin |
| Mono label / caption / footline (24–26px) | 思源等宽 Noto Sans Mono CJK SC | 500 | JetBrains Mono has no CJK glyphs; Noto Sans Mono CJK SC preserves the typewriter-chrome quality |
### Mixed-Content Strategy
Use **Strategy C** — keep Source Serif 4 as the Latin face and fall back to LXGW WenKai (for headlines / display) or Noto Serif SC (for body / stats) for CJK glyphs. This is the right call for Editorial Forest because the Source Serif 4 optical-size axis is a signature of the system; replacing it wholesale with a Mincho would flatten the Penguin-classic register that defines the deck. The font-family stack puts the Latin face first, then the CJK fallback, then the generic serif:
```css
font-family: 'Source Serif 4', 'Source Serif Pro', 'LXGW WenKai TC', 'Noto Serif SC', Georgia, serif;
```
Browsers per-glyph fall back: Latin characters render in Source Serif 4 at weight 500 with opsz engaged, Chinese characters render in LXGW WenKai (display) or Noto Serif SC (body). The baseline mismatch at display sizes (96–220px) is the main thing to watch — LXGW WenKai sits slightly higher than Source Serif 4 in optical baseline, so a mixed-script line like "Designed in 北京" may show a 1–2px vertical wobble. Acceptable for slide content; for printed export, prefer all-CJK or all-Latin lines.
### Loading
Add to the existing Google Fonts `<link>` (or as a second link tag):
```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=LXGW+WenKai+TC&family=Noto+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
LXGW WenKai TC is the version served on Google Fonts (the Simplified-Chinese build `LXGW+WenKai+SC` is not yet on the Google CDN — TC ships both traditional and simplified glyphs and works for both).
### Universal CJK Adjustments
These adjustments apply to **every CJK block** in this system, regardless of size or role:
- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (0.92–1.0 on display, 1.32–1.38 on body) read as cramped in Chinese. Bump display to 1.0–1.1 and body to 1.5–1.6.
- **Remove negative letter-spacing on CJK headlines.** Source Serif 4 display uses -0.01em to -0.03em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the Latin portion was meant to be capitalized.
- **Use Chinese full-width punctuation** (`,。:;!?「」『』()`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between LXGW WenKai and Noto Serif SC inside the same sentence — pick the face that matches the size tier (display = LXGW WenKai, body = Noto Serif SC) and commit to it for the whole run.
### Aesthetic Notes for This System
Editorial Forest's whole voice is "Penguin classic / quiet annual report" — a serif at weight 500 with the optical-size axis doing the size-aware letterform work. The Chinese equivalent of that register is **LXGW WenKai for display moments** (it has the same hand-set, slightly informal warmth as Source Serif 4 at 500) and **Noto Serif SC at 400 for body** (the calm Mincho voice that reads like a literary journal). Avoid Noto Sans SC for body — the sans face flips the system into "tech report" rather than "monograph spread."
The system's mono / serif role split (JetBrains Mono for chrome, Source Serif 4 for everything else) maps cleanly onto Chinese. Use Noto Sans Mono CJK SC for the topbar label, footline strings, tile ordinals, and axis ticks — keep them uppercase-equivalent (i.e., 0.14em–0.18em letter-spacing on Latin labels, and for Chinese, the Mono CJK face at 500 weight provides the same chrome quality). Do not run Chinese labels in LXGW WenKai or Noto Serif SC; the editorial chrome would lose its typewriter feel.
### Known CJK Gap
LXGW WenKai's brushwork warmth is its strength at large display sizes, but at body scale (26–32px) the same brushwork reads slightly noisy. The system bumps body to Noto Serif SC (a cleaner Mincho) to avoid this, but the visual handoff between a 96px LXGW WenKai headline and a 30px Noto Serif SC paragraph below it is the system's biggest CJK seam — the two faces have different stroke contrast profiles. If the seam reads loud, use Noto Serif SC for both display and body (sacrifices warmth for consistency), or use LXGW WenKai for both (sacrifices body legibility for consistency). The default split is the right trade-off for most decks, but worth a manual check on cover and statement slides.
## Iteration Guide
1. Any new headline is Source Serif 4 weight 500 with negative letter-spacing. Pick the size from the display ladder (220 / 140 / 96 / 84 / 80 / 68 / 56) — do not invent a new size.
2. Any new label, caption, or tag is JetBrains Mono weight 500 uppercase with 0.08em–0.18em letter-spacing. Pick the size from the mono ladder (26 / 24).
3. Any new slide carries a topbar at the top. The mono label color follows the surface (pink-on-green, green-on-cream, green-deep-on-pink).
4. Any new card uses 6px (topic tile) or 8px (step tile) radius. The monogram circle is the only fully round shape; do not introduce a fourth radius.
5. Any new section separator is a 2px hairline rule in the region's accent color. No 1px rules, no 3px rules.
6. Any new fill color must come from the existing palette (`{colors.green}`, `{colors.green-lite}`, `{colors.pink}`, `{colors.cream}`, `{colors.cream-2}`). Do not introduce a yellow, blue, or third pink.
7. Any new body paragraph is serif weight 400 at 26–32px. Do not run body at weight 500.
8. Any new KPI figure is `{typography.stat-figure}` (220px). Smaller KPI sizes are not in the system — if the layout can't accommodate 220px, restructure the slide.
9. Any new chart uses the bar treatment (pink / cream / green fills, mono axes, 2px axis rules) on a green surface. The data composition is part of the system identity.
10. When in doubt, reach for fewer elements at larger sizes. The system's editorial register collapses when crowded.
## Known Gaps
- The system depends on `deck-stage.js` for canvas scaling and slide navigation. The script is not described in this design.md — treat it as a runtime dependency.
- Source Serif 4 and JetBrains Mono are loaded from Google Fonts via `<link>`. Offline rendering will fall back to Georgia serif and Menlo mono respectively, which will preserve the rough character but lose the optical-size axis and the JetBrains Mono identity. Self-hosting recommended for offline / print reliability.
- The Source Serif 4 optical-size axis (`opsz` 8..60) is critical to the system's quality — using a non-opsz fallback face flattens the size-aware letterform contrast.
- The bar chart uses hand-set bar heights (`%` of a fixed 520px plot region). There is no data-binding — extending the chart requires manually computing heights.
- The monogram circle, footline strings, and tile counters carry hardcoded text in the source. Replacing them with a deck's actual identity is required per-deck.
- The system has no `@media print` rule and no responsive breakpoints — it is fixed 1920×1080 and relies on `deck-stage.js` for any viewport adaptation.
- The green-on-pink and pink-on-green text contrast ratios are sufficient at the display sizes used (84px+) but would fail WCAG AA at body-text sizes. Do not put 26px body text in pink-on-green or green-on-pink — keep small text in cream-on-green or ink-on-cream.
# Editorial Forest Preview Card Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below. ## Files - Full design doc: `bold-template-pack/templates/editorial-forest/design.md` - Preview card: `bold-template-pack/templates/editorial-forest/preview.md` ## Selection Metadata - Slug: `editorial-forest` - Tagline: Forest green, dusty pink, and warm cream meet Source Serif 4 in a quiet, intentional quarterly-review deck. - Mood: editorial, quiet, considered, warm, intentional - Tone: literary, thoughtful, warm, low-pressure - Formality: medium - Density: medium - Scheme: mixed - Best for: Anything that should feel like a considered editorial — quarterly reviews, internal readouts, studio updates, creative-agency presentations. Equally good for any deck that wants to feel warm and unhurried rather than corporate, including research recaps, book or program announcements, and team retrospectives. - Avoid for: Contexts that need to feel urgent, punchy, or sales-driven — the palette and rhythm are intentionally quiet. ## Visual Snapshot A serif-led editorial presentation system in the register of a literary quarterly or art-book monograph. Display type runs in Source Serif 4 at weight 500 with optical-size axis engaged, scaling up to 220px for cover and stat moments. The palette pairs a deep forest green (#2e4a2a) with a dusty rose pink (#e89cb1) over an oat-cream paper ground (#efe7d4), with JetBrains Mono as the editorial chrome (labels, captions, axis ticks). The aesthetic is closer to a Penguin classic, Apartamento spread, or quiet annual report than a tech keynote — confident, paper-feeling, and committed to a small color vocabulary. Editorial Forest is a serif-led editorial presentation system in the tonal register of a Penguin classic, a quiet annual report, or an art-book spread. The system's foundational premise is a single, confident typographic voice — Source Serif 4 — used at extreme scale (up to 220px) for headlines and stat figures, with JetBrains Mono playing the supporting role of editorial chrome (labels, captions, axis ticks, page footlines). ## Preview Ingredients - Palette: green #2E4A2A; green-deep #243A21; green-lite #3A5A36; pink #E89CB1; pink-deep #D27E96; cream #EFE7D4; cream-2 #E6DCC4; ink #1A1A17 - Typography: JetBrains Mono - Signature move: Three-color editorial palette: deep forest green, dusty rose pink, oat cream paper. Two surface tones per slide is typical; three is loud. - Signature move: Source Serif 4 at weight 500 for every headline, body, and display moment. Optical-size axis engaged for size-aware letterforms. - Signature move: JetBrains Mono at weight 500 uppercase with wide tracking (0.14em–0.18em) for every label, caption, axis tick, and footline. - Signature move: Display type scales to 220px for cover and stat-figure moments; 96px for primary headlines; 56–84px for card titles. - Signature move: 2px hairline rules separate stacked sections — never thicker, never colored beyond region context. ## International / CJK Preview Note - If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs. - Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments. ## Preview Rules - Build exactly one title slide at 1920x1080 inside the fixed-stage model. - Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above. - Use the user's real title/subtitle/context; do not copy demo slide content. - The rendered preview must look like a real first slide, not a template-selection card. - Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels. - Never place the template name or slug on the slide itself; mention it only in the chat message. - Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck. - Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material. - Do not read `template.html` for preview generation. - Do not read other templates' `design.md` files. - After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Editorial Tri-Tone
description: A literary magazine-meets-annual-report presentation system built on a strict three-color palette — blush pink, golden butter, and deep burgundy wine. Despite having eleven CSS variable names, only three hex values exist in the entire system; every alias is a semantic rename of one of those three. Headlines run Bricolage Grotesque (a variable grotesque with an optical-size axis) at extreme weights and negative letter-spacing. Instrument Serif (italic-cut only) appears as the expressive accent face for chapter numerals, pull-quotes, years, and signatures. JetBrains Mono carries all metadata, labels, and section markers at tight uppercase tracking. The aesthetic is "independent arts publication" — the kind with a colophon, hand-numbered editions, and an editorial desk.
colors:
pink: "#F2B6C6"
butter: "#F2D86A"
burgundy: "#7A1F35"
color-aliases:
pink-deep: pink
sky: pink
cream: butter
lime: butter
terracotta: butter
navy: burgundy
forest: burgundy
ink: burgundy
typography:
display-wordmark:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 300px
fontWeight: 800
lineHeight: 0.82
letterSpacing: -0.04em
display-closer:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 320px
fontWeight: 700
lineHeight: 0.82
letterSpacing: -0.05em
display-stat:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 540px
fontWeight: 700
lineHeight: 0.78
letterSpacing: -0.06em
display-stat-unit:
fontFamily: "Instrument Serif, serif"
fontSize: 220px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
chapter-num:
fontFamily: "Instrument Serif, serif"
fontSize: 240px
fontWeight: 400
lineHeight: 0.9
letterSpacing: 0
quote-mark:
fontFamily: "Instrument Serif, serif"
fontSize: 200px
fontWeight: 400
lineHeight: 0.6
letterSpacing: 0
display-xl:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 84px
fontWeight: 700
lineHeight: 0.95
letterSpacing: -0.02em
display-lg:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 76px
fontWeight: 700
lineHeight: 0.95
letterSpacing: -0.02em
signature:
fontFamily: "Instrument Serif, serif"
fontSize: 64px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
endorsement-num:
fontFamily: "Instrument Serif, serif"
fontSize: 56px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
color: pink
timeline-year:
fontFamily: "Instrument Serif, serif"
fontSize: 56px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
subhead-serif:
fontFamily: "Instrument Serif, serif"
fontSize: 48px
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0
lede:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 56px
fontWeight: 500
lineHeight: 1.05
letterSpacing: -0.02em
cover-pill:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 44px
fontWeight: 500
lineHeight: 1.0
letterSpacing: 0
chart-title:
fontFamily: "Instrument Serif, serif"
fontSize: 40px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
card-title:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 40px
fontWeight: 600
lineHeight: 1.0
letterSpacing: -0.02em
quote-heading:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 56px
fontWeight: 600
lineHeight: 1.0
letterSpacing: -0.02em
body-lg:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 28px
fontWeight: 400
lineHeight: 1.45
letterSpacing: 0
body-md:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 26px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0
body-sm:
fontFamily: "Bricolage Grotesque, sans-serif"
fontSize: 24px
fontWeight: 400
lineHeight: 1.45
letterSpacing: 0
label:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.15em
textTransform: uppercase
label-wide:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.18em
textTransform: uppercase
label-mid:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.12em
textTransform: uppercase
label-tight:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.10em
textTransform: uppercase
footer:
fontFamily: "JetBrains Mono, monospace"
fontSize: 16px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.12em
textTransform: uppercase
opacity: 0.75
spacing:
slide-pad: 96px
chrome-gutter: 64px
section-gap: 48px
card-pad: 28px 28px 30px
chart-pad: 48px 48px 56px
footer-bottom: 36px
grid-gap: 24px
endorsement-pad: 20px 0
canvas:
width: 1920px
height: 1080px
components:
pill:
borderRadius: 999px
padding: 0.35em 0.9em
fontFamily: "Bricolage Grotesque, sans-serif"
fontWeight: 500
lineHeight: 1.0
cover-pill:
borderRadius: 999px
padding: 16px 38px
fontSize: 44px
fontWeight: 500
closer-pill:
borderRadius: 999px
padding: 12px 28px
fontSize: 22px
value-card:
borderRadius: 28px
padding: 28px 28px 30px
height: 340px
value-card-dark:
background: "{colors.burgundy}"
color: "{colors.butter}"
value-card-light:
background: "{colors.butter}"
color: "{colors.burgundy}"
chart-card:
background: "{colors.butter}"
color: "{colors.burgundy}"
borderRadius: 32px
padding: 48px 48px 56px
timeline-ribbon:
background: "{colors.burgundy}"
color: "{colors.butter}"
borderRadius: 999px
padding: 24px 44px
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.15em
textTransform: uppercase
timeline-ribbon-accent:
fontFamily: "Instrument Serif, serif"
fontSize: 30px
fontWeight: 400
letterSpacing: 0
textTransform: none
color: "{colors.pink}"
footer-chrome:
position: absolute
left: 64px
right: 64px
bottom: 36px
fontFamily: "JetBrains Mono, monospace"
fontSize: 16px
letterSpacing: 0.12em
textTransform: uppercase
opacity: 0.75
footer-dot:
width: 8px
height: 8px
borderRadius: 999px
background: currentColor
opacity-inactive: 0.3
opacity-active: 1.0
swatch-circle:
width: 36px
height: 36px
borderRadius: 999px
stat-breakdown-bar:
height: 10px
borderRadius: 999px
background: "rgba(246,237,220,0.15)"
stat-breakdown-divider:
borderTop: "1px solid rgba(246,237,220,0.25)"
endorsement-divider:
borderTop: "1px solid rgba(246,237,220,0.30)"
avatar:
width: 72px
height: 72px
borderRadius: 999px
background: "{colors.burgundy}"
border: "3px solid {colors.burgundy}"
timeline-axis:
height: 4px
background: "{colors.burgundy}"
opacity: 0.15
timeline-dot:
width: 28px
height: 28px
borderRadius: 999px
border: "4px solid {colors.butter}"
background: "{colors.burgundy}"
---
## 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
Editorial Tri-Tone is a **literary magazine presentation system** built on the strictest possible palette: three hex values, eleven CSS variable names. The naming system reveals editorial intent — `--pink` and `--sky` point at the same blush; `--cream`, `--butter`, `--lime`, and `--terracotta` all resolve to the same golden yellow; `--burgundy`, `--navy`, `--forest`, and `--ink` all collapse to the same deep wine. The aliases exist to communicate the role of the color in context, not to introduce variation.
The typeface stack is a deliberate three-way conversation:
1. **Bricolage Grotesque** — a variable grotesque with an optical-size axis. Used at weights 500, 600, 700, and 800 for all display and body sans text.
2. **Instrument Serif** — used exclusively in weight 400, often in its italic guise. Reserved for chapter numerals, pull-quote marks, timeline years, signatures, endorsement ordinals, and stat percentage symbols.
3. **JetBrains Mono** — all metadata, labels, section markers, footnotes, footer chrome.
The editorial voice is that of an independent magazine with a colophon — the deck's last slide is literally called "Colophon." Section markers use the section sign (§) followed by a number and a title. The tone is measured, literary, and warm rather than corporate or high-energy.
**Key Characteristics:**
- Three-color palette with semantic aliases: blush pink (#F2B6C6), golden butter (#F2D86A), deep burgundy (#7A1F35).
- Mixed typography: Bricolage Grotesque grotesque for display and body; Instrument Serif for expressive accent numerals, quotes, and years; JetBrains Mono for all labels.
- The `em` tag within Bricolage Grotesque headlines always triggers a switch to Instrument Serif italic — the system's primary typographic mix.
- Pills (border-radius 999px) are the universal tag component; used at three different sizes across cover, chart legend, and closer.
- Value cards have a generous 28px border-radius — soft, rounded, not brutalist.
- Dividers on dark surfaces use low-opacity rgba (0.25–0.30) rather than solid colors — whispered separators.
- Footer dot row: a progress indicator using 8px circles at 30% opacity (inactive) and 100% opacity (active).
- The sole SVG chart combines four series types on a single canvas: filled area, vertical bars, connected circles, dotted line.
## Colors
### The Three Actual Colors
Despite many CSS variable names, the palette is:
| Name | Hex | Role |
|---|---|---|
| Blush Pink | #F2B6C6 | Accent / highlight on dark surfaces; stat figure color; quote mark glow |
| Golden Butter | #F2D86A | Warm mid-tone; background for light slides; accent text on dark surfaces |
| Deep Burgundy | #7A1F35 | Primary dark surface; ink color; structural tone |
### Alias Map
All aliases resolve to one of the three values above. The alias name signals context:
| Alias | Points to | Context of use |
|---|---|---|
| `--pink` | #F2B6C6 | Default accent label |
| `--pink-deep` | #F2B6C6 | (unused distinct value — same as pink) |
| `--sky` | #F2B6C6 | Segment D bar in breakdown |
| `--cream` | #F2D86A | Light surface background |
| `--butter` | #F2D86A | Accent text on dark; card backgrounds |
| `--lime` | #F2D86A | Ribbon accent text; kicker label on dark surfaces |
| `--terracotta` | #F2D86A | Italic em highlights in lede or body |
| `--navy` | #7A1F35 | Alternate label for dark surface contexts |
| `--forest` | #7A1F35 | Dark panel or column background |
| `--burgundy` | #7A1F35 | Structural background color |
| `--ink` | #7A1F35 | All text color |
## Typography
### Font Families
- **Bricolage Grotesque**: The primary typeface. Variable with optical-size axis (opsz 12..96) and weights from 400 to 800. The weight range is the expressive tool — 400 for body, 500 for lede, 600 for card titles and quote headers, 700 for section headlines, 800 for the wordmark.
- **Instrument Serif**: Weight 400 only, italic variant loaded. Functions as the expressive counterpoint to Bricolage Grotesque. Never used for body copy; always for large numerals, quotation marks, signatures, years, endorsement ordinals, and the stat percentage symbol. The key insight is that the system never uses Instrument Serif for "normal" running text — only for moments of human expressiveness.
- **JetBrains Mono**: Weights 400 and 500. All labels are uppercase with 0.10–0.18em letter-spacing. Always secondary information: section markers, metadata, footnotes, legend categories, kickers, footer chrome.
### The `em` Rule
Within any Bricolage Grotesque headline, an `<em>` tag triggers a switch to Instrument Serif at weight 400. This is the system's primary in-line typographic mix — a grotesque headline interrupted by a serif aside. Example: "A short trajectory, told in *five stops*." The em portion reads as a quieter, more reflective counterpoint.
### The `b` Rule (Quote Slide Only)
Within Instrument Serif blockquotes, a `<b>` tag triggers a switch back to Bricolage Grotesque weight 600 in burgundy. The reverse of the em rule — a serif quote punctuated by a grotesk emphasis.
### Display Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-stat}` | 540px | Bricolage Grotesque | 700 | Full-bleed oversized stat or number figure |
| `{typography.display-closer}` | 320px | Bricolage Grotesque | 700 | Jumbo title or closing wordmark |
| `{typography.display-wordmark}` | 300px | Bricolage Grotesque | 800 | Primary wordmark or deck title |
| `{typography.display-stat-unit}` | 220px | Instrument Serif | 400 | Accent symbol alongside a stat figure |
| `{typography.chapter-num}` | 240px | Instrument Serif | 400 | Large chapter or section numeral |
| `{typography.quote-mark}` | 200px | Instrument Serif | 400 | Decorative large quotation mark |
| `{typography.display-xl}` | 84px | Bricolage Grotesque | 700 | Section headline for data or chart layouts |
| `{typography.display-lg}` | 76px | Bricolage Grotesque | 700 | Section headlines |
| `{typography.signature}` | 64px | Instrument Serif | 400 | Signature or sign-off element |
| `{typography.lede}` | 56px | Bricolage Grotesque | 500 | Lede or opening statement |
| `{typography.quote-heading}` | 56px | Bricolage Grotesque | 600 | Panel heading or editorial subhead |
| `{typography.endorsement-num}` | 56px | Instrument Serif | 400 | Endorsement or list ordinals |
| `{typography.timeline-year}` | 56px | Instrument Serif | 400 | Year stamps or large ordinal accents |
| `{typography.subhead-serif}` | 48px | Instrument Serif | 400 | Secondary subheads on dark surfaces |
| `{typography.cover-pill}` | 44px | Bricolage Grotesque | 500 | Large tag cloud or keyword pills |
| `{typography.chart-title}` | 40px | Instrument Serif | 400 | Card or panel title |
| `{typography.card-title}` | 40px | Bricolage Grotesque | 600 | Card or value title |
### Body and Label Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.body-lg}` | 28px | Bricolage Grotesque | 400 | Manifesto right-column body |
| `{typography.body-md}` | 26px | Bricolage Grotesque | 600/400 | Attribution name, endorsement body |
| `{typography.body-sm}` | 24px | Bricolage Grotesque | 400 | Card descriptions, stat annotation, closer index |
| `{typography.label}` | 24px | JetBrains Mono | 400 | Standard section labels (0.15em tracking) |
| `{typography.label-wide}` | 24px | JetBrains Mono | 400 | Kickers on dark slides (0.18em tracking) |
| `{typography.label-mid}` | 24px | JetBrains Mono | 400 | Manifesto bottom meta (0.12em) |
| `{typography.label-tight}` | 24px | JetBrains Mono | 400 | Legend categories, breakdown labels (0.10em) |
| `{typography.footer}` | 16px | JetBrains Mono | 400 | Page footer chrome (0.12em, opacity 0.75) |
### Principles
Bricolage Grotesque's optical-size axis makes the face significantly more expressive at large sizes and more legible at small sizes without changing weight. At 540px and 300px (stat and wordmark), the display renders with wide, open letterforms; at 24px (body), it compresses. Both are weight 700 or 800 at display; both are weight 400 at body. The face is never used in intermediate sizes (48–72px) — that zone belongs to Instrument Serif.
Letter-spacing on Bricolage Grotesque is always negative at display: -0.04em at 300px, -0.05em at 320px, -0.06em at 540px. At body sizes (24–28px), no letter-spacing is applied.
JetBrains Mono label tracking is always positive and varies by use: 0.10em for dense data contexts, 0.12em for secondary meta, 0.15em for standard section labels, 0.18em for headline kickers on dark slides.
## Layout
### Canvas System
Every slide is exactly 1920×1080px. The `deck-stage` custom element handles centering and scaling.
### Gutter System
- **Chrome gutter** (64px left/right): Used by footer chrome and most content edges.
- **Generous slide padding** (96px): Most slides use `padding: 96px 64px` — the top/bottom pad is larger than the sides, giving a portrait-publication feel even on landscape slides.
- **Wide slide padding** (88px top on chart slide): Slight reduction to accommodate the two-column layout.
### Slide Internal Spacing Pattern
Each slide follows a top-to-bottom reading order:
1. Section marker (`§ XX — Title`, JetBrains Mono, 24px, label tracking)
2. Headline or major content
3. Body / grid content
4. Footer meta (absolute, bottom 36px)
## Elevation and Depth
The system uses **no box shadows at all**. Depth comes entirely from:
### Color Surface Contrast
The burgundy/butter/pink trio creates its own depth hierarchy:
- Butter surfaces feel "forward" (warm, light)
- Pink feels "accented" (warm, mid)
- Burgundy feels "recessed" (dark, anchoring)
Alternating surface colors within split slides (cream left / burgundy right on manifesto; lime left / burgundy right on quote) creates depth through edge contrast rather than shadow.
### Opacity Dividers
On dark (burgundy) surfaces, all dividers and structural lines use rgba rather than solid colors:
- Row separators in stat breakdown: `rgba(246,237,220,0.25)`
- Endorsement rows in quote slide: `rgba(246,237,220,0.30)`
- Timeline axis: `opacity: 0.15` on solid burgundy
The cream values (246,237,220) in those rgba strings approximate the butter color at full opacity — dividers feel like recessed etchings rather than drawn lines.
### Chart Card Lift
The chart card (slide 6) achieves its "lifted" feeling through border-radius 32px on a butter card placed over a burgundy background. No shadow — the rounded corner on a contrasting surface signals elevation.
## Shapes and Treatment
### Border Radius Scale
| Value | Use |
|---|---|
| 999px | All pills, timeline ribbon, swatch circles, avatar, breakdown bars, timeline dots, footer dots, chart data circles |
| 32px | Chart card (slide 6) |
| 28px | Value cards (slide 3) |
| 4px | SVG chart bars (rx="4") |
| 0px | Section headlines, grid cells (no rounding) |
The system has a strong binary: either fully rounded (pills, circles) or square (content blocks). The exception is the chart card (32px) and value cards (28px) — large enough radius to feel "soft" but geometric rather than circular.
### Pill System
Pills are the universal label/tag component. Three size variants:
- **Cover pills**: 44px font, 16px 38px padding — large enough to read as headline elements in the tag cloud
- **Standard pills** (section labels, legend items): 22–24px font, 10–12px 24–28px padding
- **Color assignments** alternate: burgundy-bg/pink-text and butter-bg/burgundy-text on cover; burgundy/cream or lime/ink on closer
### SVG Chart (Slide 6)
The inline SVG chart at 720×380 viewBox combines four series types deliberately to demonstrate the range of a single chart surface:
- **Area series** (Series A): Filled path with pink fill at 0.85 opacity, burgundy stroke at weight 3
- **Bar series** (Series C): Burgundy rectangles with rx="4"
- **Connected circle series** (Series B): Butter circles (r=8) with burgundy stroke/fill on a burgundy line at weight 3
- **Dotted line** (Series D): Burgundy dashed stroke (stroke-dasharray="2 10", stroke-linecap="round") at 60% opacity
Y-axis labels are JetBrains Mono 24px at 60% opacity, left-aligned to x=0.
## Do's and Don'ts
### Do
- Treat the three hex values as a closed system. Every element uses pink, butter, or burgundy — no neutrals, no grays, no white.
- Use Instrument Serif only for moments of human expressiveness: numerals, years, signatures, quotation marks, endorsement ordinals. Never for running body text.
- Use the `em` tag in Bricolage Grotesque headlines to trigger the serif switch. This is the system's primary inline mix and its clearest editorial voice.
- Give all label text (JetBrains Mono) positive letter-spacing between 0.10em and 0.18em. Monospace without tracking reads as code, not editorial.
- Alternate surface colors across the two-column split slides. One side is always butter, the other always burgundy.
- Keep body text in Bricolage Grotesque at weights 400 (text) and 500–600 (emphasized labels). The weight axis is the tonal dial.
- Use pills at multiple sizes — the pill is the universal tag and its size signals context: 44px for headline-level categorization, 22–24px for utility labels.
- Section markers follow the pattern `§ NN — Title` in JetBrains Mono — every slide opens with this convention.
### Don't
- Don't introduce a fourth color. The tri-tone constraint is the design premise.
- Don't use Instrument Serif at small sizes or in body paragraphs. It is purely an accent face.
- Don't break the em rule — using Bricolage Grotesque italic instead of Instrument Serif for inline emphasis loses the typographic mix.
- Don't use letter-spacing on Bricolage Grotesque at display sizes — only negative tracking via `letter-spacing: -0.02em` to `-0.06em` depending on size.
- Don't add solid-color dividers on dark (burgundy) surfaces. All structural lines on dark backgrounds must use low-opacity rgba.
- Don't apply box shadows. The system has none. Depth comes from surface contrast and border-radius on contrasting backgrounds.
- Don't round large content containers (section panels, grid backgrounds). Rounding applies only to pill-scale and card-scale elements (value cards, chart card).
- Don't use Bricolage Grotesque weight 800 except in the wordmark. The weight 800 is reserved for the single largest typographic moment.
## Responsive Behavior
This template is designed **exclusively for 1920x1080 presentation display**. The `deck-stage` web component handles viewport scaling via CSS transforms; the 1920x1080 canvas scales proportionally to any screen without layout changes.
### Presenter Behavior
- Slide advancement via keyboard or presentation clicker (handled by `deck-stage.js`).
- No hover states are defined.
- No interactive elements.
### Print / Export
- At 96dpi, 1920x1080 maps to a 20x11.25 inch frame.
- The stat figure at 540px renders at ~405pt — suitable for large-format print.
- The three-color palette is print-safe; burgundy is a deep PMS-range wine tone, butter is a warm yellow, pink is a muted blush — all reproduce well in CMYK offset.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display wordmark / closer / stat (300–540px) | 站酷小薇体 ZCOOL XiaoWei | 400 | A literary decorative serif with the same expressive personality as Bricolage Grotesque + Instrument Serif italic at extreme scale |
| Section headlines (76–84px) | 思源黑体 Noto Sans SC | 700 | The grotesque equivalent in CJK — carries the Bricolage Grotesque structural weight |
| Chapter numerals / quote marks / years (200–240px) | 霞鹜文楷 LXGW WenKai | 400 | Hand-set warmth that matches Instrument Serif's expressive accent role |
| Body paragraph (24–28px) | 思源宋体 Noto Serif SC | 400 | Mincho body voice; literary register |
| Lede / quote-heading (56px) | 思源黑体 Noto Sans SC | 500–600 | Matches Bricolage Grotesque weight 500/600 |
| Mono label / section marker / footer | 思源等宽 Noto Sans Mono CJK SC | 400–500 | Preserves the JetBrains Mono chrome quality for `§ NN — Title` markers |
### Mixed-Content Strategy
Use **Strategy C** — keep Bricolage Grotesque (display, body) and Instrument Serif (italic accents) as the Latin faces and fall back to the Chinese stack only for CJK glyphs. The literary-magazine identity of Editorial Tri-Tone depends on Bricolage Grotesque's optical-size axis and Instrument Serif's italic cut as part of the brand voice; replacing them wholesale with a CJK family would flatten the system into "generic Chinese editorial." Stack:
```css
/* Bricolage Grotesque roles (display, body) */
font-family: 'Bricolage Grotesque', 'Noto Sans SC', sans-serif;
/* Instrument Serif roles (chapter-num, quote-mark, year, signature) */
font-family: 'Instrument Serif', 'LXGW WenKai TC', serif;
/* JetBrains Mono roles (labels, section markers) */
font-family: 'JetBrains Mono', 'Noto Sans Mono CJK SC', monospace;
```
The system's signature `<em>` rule (Bricolage Grotesque → Instrument Serif italic inline) is what carries the editorial tone in Latin. The CJK equivalent: an `<em>` inside a 思源黑体 (Noto Sans SC) headline should switch to **站酷小薇体 (ZCOOL XiaoWei)** — a decorative literary serif with the same softness contrast as Instrument Serif italic. Add a CSS rule:
```css
h1 em, h2 em, .lede em, .quote-heading em {
font-family: 'Instrument Serif', 'ZCOOL XiaoWei', 'LXGW WenKai TC', serif;
font-style: italic; /* Latin only — CJK ignores font-style */
}
```
Watch for baseline mismatch at display sizes (300–540px): Bricolage Grotesque at -0.04em to -0.06em tracking sits visually tighter than Noto Sans SC, so a mixed-script wordmark like `INTO 中国` may feel uneven. For hero / wordmark moments, prefer single-script lines and let the second script live on its own line below.
### Loading
Add to the existing Google Fonts `<link>` (or as a second link tag):
```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&family=Noto+Serif+SC:wght@400;500;700&family=LXGW+WenKai+TC&family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
```
ZCOOL XiaoWei is the decorative-terminal serif used for the em-switch role; it's hosted on Google Fonts at weight 400 only.
### Universal CJK Adjustments
These adjustments apply to **every CJK block** in this system, regardless of size or role:
- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (0.78–0.92 on display, 1.4–1.45 on body) read as cramped in Chinese. Bump display to 0.95–1.05 and body to 1.5–1.6.
- **Remove negative letter-spacing on CJK headlines.** Bricolage Grotesque display uses -0.04em to -0.06em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the Latin portion was meant to be capitalized.
- **Use Chinese full-width punctuation** (`,。:;!?「」『』()`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between Noto Sans SC, Noto Serif SC, and ZCOOL XiaoWei inside the same sentence — pick the face that matches the role (headline = Noto Sans SC, body = Noto Serif SC, em-accent = ZCOOL XiaoWei) and commit to it for the whole run.
### Aesthetic Notes for This System
Editorial Tri-Tone's literary-magazine voice depends on the typographic contrast between Bricolage Grotesque (structural) and Instrument Serif italic (expressive). In Chinese, that same contrast lives in the **思源黑体 ↔ 站酷小薇体** pairing — a clean grotesque set against a literary decorative serif. The em-rule inside headlines should switch from 思源黑体 to **站酷小薇体** specifically (not 霞鹜文楷, which is warmer but less "literary-decorative"); this preserves the typographic mix that defines the system.
For the system's signature display moments — the 300px wordmark, the 540px stat figure, the 240px chapter numeral — Chinese is at its loudest. Reach for **站酷小薇体** when the moment is decorative (a chapter ordinal "第一章" rendered in literary serif) and **思源黑体 weight 700** when the moment is structural (a section headline like "我们的方法"). The 200px quote-mark glyph is harder in Chinese — Chinese quotation marks (「」) don't carry the same decorative weight as Latin 'curly quotes', so consider rendering the entire quote moment in the Latin glyph (using the `Instrument Serif` face on the punctuation character itself) and let the body text below switch to 思源宋体.
The section marker convention `§ NN — Title` works in Chinese: `§ 02 — 我们的承诺`. Keep the section sign and the numeral in JetBrains Mono / Noto Sans Mono CJK SC; the title text can switch to 思源黑体 weight 400 with 0.05em tracking to preserve the chrome quality.
### Known CJK Gap
ZCOOL XiaoWei is the right aesthetic match for the em-switch role, but it ships as **weight 400 only with no italic cut**. Chinese has no italic concept (slanted Han glyphs read as broken, not emphasized), so the lack of italic is fine — but the visual softness contrast that Instrument Serif italic provides in Latin (a slanted, more flowing letterform) cannot be exactly replicated in Chinese. The decorative-terminal serif quality of ZCOOL XiaoWei provides the closest equivalent, but the contrast against 思源黑体 is **face-based, not slant-based**. Decks with heavy reliance on the em-rule should test the visual rhythm in Chinese before committing — if the contrast feels muted, increase the em-portion font-size by 4–8px to compensate.
## Iteration Guide
1. Section labels always use the `§ NN — Title` convention in JetBrains Mono with `{typography.label}` tracking.
2. Every headline with an em/italic moment uses `<em>` to trigger Instrument Serif. Never use `font-style: italic` on Bricolage Grotesque directly.
3. Value card alternation: odd-numbered cards (c1, c3, c5, c7) are dark (burgundy/butter); even-numbered (c2, c4, c6, c8) are light (butter/burgundy).
4. New dark-surface sections use `rgba(246,237,220,0.25)` for dividers — not `{colors.butter}` at full opacity.
5. New pills follow the existing alternation: burgundy-bg/pink-text and butter-bg/burgundy-text for variety in clusters.
6. Adding a chart series: use the four established visual encodings (area, bars, circles, dotted line) before inventing a new one.
7. All section backgrounds must be one of the three palette colors — never mix (no half-pink half-butter).
8. Footer chrome is shared across all slides: `position:absolute; left:64px; right:64px; bottom:36px; font-family:JetBrains Mono; font-size:16px; opacity:0.75`.
## Known Gaps
- The `deck-stage.js` script is an external dependency not documented here.
- The footer dot-row progress indicator (`.footer .dotrow`) is rendered in the HTML but the dots are all styled with class "on" or left as inactive — a presenter would need to update slide state dynamically.
- The SVG chart uses hardcoded paths, coordinates, and placeholder values — no data-binding layer exists.
- The breakdown bars in slide 4 use inline `width: XX%` as a style — percentages must be set manually.
- The timeline stop dots (`.stop .dot`) have `display: none` — they are styled but not visible. A presenter populating this slide would enable them via CSS.
- Instrument Serif italic is loaded as a font variant but is not explicitly called with `font-style: italic` in every context — in some cases the browser selects it from the variable font's italic axis automatically based on surrounding context.
- Color swatch circles on slide 4 reference `--terracotta` and `--sky`, which resolve identically to `--butter` and `--pink` — the visual distinction exists only semantically in the source, not visually.
# Editorial Tri-Tone Preview Card Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below. ## Files - Full design doc: `bold-template-pack/templates/editorial-tri-tone/design.md` - Preview card: `bold-template-pack/templates/editorial-tri-tone/preview.md` ## Selection Metadata - Slug: `editorial-tri-tone` - Tagline: Three-color editorial system: dusty pink, mustard cream, and deep burgundy, set in Bricolage + Instrument Serif. - Mood: editorial, warm, intentional, moody - Tone: literary, warm, considered, stylish - Formality: medium-high - Density: medium - Scheme: mixed - Best for: Anything that should feel like a fashion-magazine spread: editorial pitches, fashion brand decks, lifestyle media, art direction reviews. Equally good for any deck — including tech, research, or business — that wants tri-tone discipline and serif/sans contrast instead of the usual neutrals. - Avoid for: Decks that need to read as soft or comforting — the burgundy/pink/cream tri-tone is intentionally high-contrast and styled. ## Visual Snapshot A literary magazine-meets-annual-report presentation system built on a strict three-color palette — blush pink, golden butter, and deep burgundy wine. Despite having eleven CSS variable names, only three hex values exist in the entire system; every alias is a semantic rename of one of those three. Headlines run Bricolage Grotesque (a variable grotesque with an optical-size axis) at extreme weights and negative letter-spacing. Instrument Serif (italic-cut only) appears as the expressive accent face for chapter numerals, pull-quotes, years, and signatures. JetBrains Mono carries all metadata, labels, and section markers at tight uppercase tracking. The aesthetic is "independent arts publication" — the kind with a colophon, hand-numbered editions, and an editorial desk. Editorial Tri-Tone is a literary magazine presentation system built on the strictest possible palette: three hex values, eleven CSS variable names. The naming system reveals editorial intent — --pink and --sky point at the same blush; --cream, --butter, --lime, and --terracotta all resolve to the same golden yellow; --burgundy, --navy, --forest, and --ink all collapse to the same deep wine. The aliases exist to communicate the role of the color in context, not to introduce variation. ## Preview Ingredients - Palette: pink #F2B6C6; butter #F2D86A; burgundy #7A1F35 - Typography: Bricolage Grotesque; Instrument Serif; JetBrains Mono - Signature move: Three-color palette with semantic aliases: blush pink (#F2B6C6), golden butter (#F2D86A), deep burgundy (#7A1F35). - Signature move: Mixed typography: Bricolage Grotesque grotesque for display and body; Instrument Serif for expressive accent numerals, quotes, and years; JetBrains Mono for all labels. - Signature move: The em tag within Bricolage Grotesque headlines always triggers a switch to Instrument Serif italic — the system's primary typographic mix. - Signature move: Pills (border-radius 999px) are the universal tag component; used at three different sizes across cover, chart legend, and closer. - Signature move: Value cards have a generous 28px border-radius — soft, rounded, not brutalist. ## International / CJK Preview Note - If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs. - Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments. ## Preview Rules - Build exactly one title slide at 1920x1080 inside the fixed-stage model. - Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above. - Use the user's real title/subtitle/context; do not copy demo slide content. - The rendered preview must look like a real first slide, not a template-selection card. - Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels. - Never place the template name or slug on the slide itself; mention it only in the chat message. - Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck. - Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material. - Do not read `template.html` for preview generation. - Do not read other templates' `design.md` files. - After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Emerald Editorial
description: A bold display-serif editorial system in the register of a fashion masthead or vintage magazine cover. Bodoni Moda runs at weight 900 across a wide scale (44–460px), set against a saturated emerald-green canvas with deep navy ink and oat-paper accents. The signature treatment is a stacked double-rule ornament that brackets centered display words like a 19th-century theatrical playbill. The aesthetic borrows from Harper's Bazaar / Vogue / Wallpaper covers: confident, theatrical, paper-and-ink committed, with a tight three-color palette and zero gradients or shadows.
colors:
bg: "#3CD896"
bg-2: "#2DC684"
bg-3: "#25B377"
ink: "#0F1A5C"
ink-2: "#1B2774"
ink-3: "#3A4593"
paper: "#F1E9D6"
rule: "rgba(15, 26, 92, 0.22)"
rule-strong: "rgba(15, 26, 92, 0.85)"
typography:
numeral-jumbo:
fontFamily: "'Bodoni Moda', serif"
fontSize: 460
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.04em
display-section:
fontFamily: "'Bodoni Moda', serif"
fontSize: 200
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.015em
display-cover:
fontFamily: "'Bodoni Moda', serif"
fontSize: 184
fontWeight: 900
lineHeight: 0.92
letterSpacing: -0.01em
display:
fontFamily: "'Bodoni Moda', serif"
fontSize: 130
fontWeight: 900
lineHeight: 0.96
letterSpacing: -0.015em
display-md:
fontFamily: "'Bodoni Moda', serif"
fontSize: 128
fontWeight: 900
lineHeight: 0.95
letterSpacing: -0.015em
display-sm:
fontFamily: "'Bodoni Moda', serif"
fontSize: 120
fontWeight: 900
lineHeight: 0.95
letterSpacing: -0.015em
headline-xl:
fontFamily: "'Bodoni Moda', serif"
fontSize: 104
fontWeight: 900
lineHeight: 0.95
letterSpacing: -0.015em
headline:
fontFamily: "'Bodoni Moda', serif"
fontSize: 92
fontWeight: 900
lineHeight: 1
letterSpacing: -0.02em
ornament-word-lg:
fontFamily: "'Bodoni Moda', serif"
fontSize: 84
fontWeight: 800
lineHeight: 1
ornament-word:
fontFamily: "'Bodoni Moda', serif"
fontSize: 76
fontWeight: 800
lineHeight: 1
ornament-word-sm:
fontFamily: "'Bodoni Moda', serif"
fontSize: 68
fontWeight: 800
lineHeight: 1
title-card-lg:
fontFamily: "'Bodoni Moda', serif"
fontSize: 64
fontWeight: 800
lineHeight: 1
letterSpacing: -0.005em
title-card:
fontFamily: "'Bodoni Moda', serif"
fontSize: 48
fontWeight: 800
lineHeight: 1
letterSpacing: -0.005em
title-card-sm:
fontFamily: "'Bodoni Moda', serif"
fontSize: 44
fontWeight: 800
lineHeight: 1.05
letterSpacing: -0.005em
step-numeral:
fontFamily: "'Bodoni Moda', serif"
fontSize: 80
fontWeight: 900
lineHeight: 1
step-title:
fontFamily: "'Bodoni Moda', serif"
fontSize: 40
fontWeight: 800
lineHeight: 1
letterSpacing: -0.005em
kpi-figure:
fontFamily: "'Bodoni Moda', serif"
fontSize: 144
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.03em
kpi-figure-unit:
fontFamily: "'Bodoni Moda', serif"
fontSize: 60
fontWeight: 800
stat-figure:
fontFamily: "'Bodoni Moda', serif"
fontSize: 92
fontWeight: 900
lineHeight: 1
letterSpacing: -0.02em
stat-figure-unit:
fontFamily: "'Bodoni Moda', serif"
fontSize: 48
fontWeight: 900
eyebrow:
fontFamily: "'Manrope', sans-serif"
fontSize: 28
fontWeight: 800
letterSpacing: 0.18em
textTransform: uppercase
label:
fontFamily: "'Manrope', sans-serif"
fontSize: 26
fontWeight: 700
letterSpacing: 0.08em
textTransform: uppercase
label-tight:
fontFamily: "'Manrope', sans-serif"
fontSize: 26
fontWeight: 700
letterSpacing: 0.05em
textTransform: uppercase
tag:
fontFamily: "'Manrope', sans-serif"
fontSize: 24
fontWeight: 800
letterSpacing: 0.12em
textTransform: uppercase
caption:
fontFamily: "'Manrope', sans-serif"
fontSize: 24
fontWeight: 700
letterSpacing: 0.1em
textTransform: uppercase
body-lg:
fontFamily: "'Manrope', sans-serif"
fontSize: 28
fontWeight: 500
lineHeight: 1.5
body:
fontFamily: "'Manrope', sans-serif"
fontSize: 26
fontWeight: 500
lineHeight: 1.5
body-sm:
fontFamily: "'Manrope', sans-serif"
fontSize: 24
fontWeight: 500
lineHeight: 1.45
credit:
fontFamily: "'Manrope', sans-serif"
fontSize: 28
fontWeight: 700
letterSpacing: 0.18em
textTransform: uppercase
spacing:
pad-default: "110px 110px 70px"
pad-cover: "56px 110px"
pad-closing: "80px 110px"
pad-statement: "110px 110px 70px"
masthead-inset: "56px 80px"
rule-thick: "4px"
rule-thicker: "5px"
rule-thin: "2px"
canvas:
width: 1920px
height: 1080px
components:
ornament-double-rule:
description: "The system's signature treatment. A centered serif word framed by two stacked 4px horizontal rules on each side. The rules sit 3px apart on top and 3px apart on bottom, giving a 19th-century playbill / theatrical-poster bracket effect. Configurable via :root[data-ornament] to switch between double (default), single, or none."
ruleHeight: "4px"
ruleGap: "3px"
wordWeight: 800
wordFamily: "'Bodoni Moda', serif"
ornament-vertical:
description: "An inline horizontal pair of stacked rules (each 4px tall, 8px apart) on either side of a small serif word. Used as a side bracket around connector words like prepositions."
ruleHeight: "4px"
ruleGap: "8px"
barWidth: "64px"
masthead:
position: "absolute"
placement: "top: 56px, full-width between 80px side padding"
layout: "flex space-between"
typography: "{typography.label-tight}"
color: "{colors.ink}"
footline:
position: "absolute"
placement: "bottom: 56px, full-width between 80px side padding"
layout: "flex space-between"
typography: "{typography.label-tight}"
color: "{colors.ink}"
rule-h-thick:
height: "4px"
background: "{colors.ink}"
description: "Universal 4px horizontal rule used as section separator and tile/row border. The system's standard rule weight."
agenda-row:
description: "A three-column grid row (130px / 1fr / 320px) with 4px ink top borders. Holds a serif ordinal, serif name, and sans-serif kind label. The last row in a list also carries a 4px bottom border, sealing the list."
rowPad: "26px 0"
topBorder: "4px solid {colors.ink}"
inverse-tile:
description: "A solid {colors.ink} rectangle holding {colors.bg} text. Used for chart-card containers, kpi tiles, process steps, section-opener panels. Carries no corner radius and no shadow."
background: "{colors.ink}"
color: "{colors.bg}"
padding: "32px to 36px"
paper-tile:
description: "A solid {colors.paper} rectangle holding {colors.ink} text. The alt variant of inverse-tile — used in rotation across a row of process steps or kpi tiles to break the monotony of ink fills."
background: "{colors.paper}"
color: "{colors.ink}"
mark-pill:
background: "{colors.ink}"
color: "{colors.bg}"
padding: "10px 22px"
fontWeight: 700
letterSpacing: 0.1em
fontSize: 24
textTransform: uppercase
description: "A small ink-on-bg pill used as a category mark or section tag. No border-radius — strict rectangle."
tag-pill:
background: "{colors.ink}"
color: "{colors.bg}"
padding: "8px 20px"
fontWeight: 700
letterSpacing: 0.12em
fontSize: 24
textTransform: uppercase
delta-pill:
background: "{colors.bg}"
color: "{colors.ink}"
padding: "6px 16px"
fontWeight: 800
letterSpacing: 0.08em
fontSize: 24
textTransform: uppercase
description: "A small bg-on-ink delta indicator placed inside an inverse kpi tile to show change direction. Inverted to ink-on-bg when inside a paper-tile."
bar:
description: "A vertical rectangular chart bar in bg (primary), paper (alt). Value label printed above bar in Bodoni 30px. No corner radius."
background: "{colors.bg} or {colors.paper}"
chart-card:
background: "{colors.ink}"
color: "{colors.bg}"
padding: "36px 50px 30px"
gridLineColor: "rgba(60, 216, 150, 0.22)"
description: "An ink container framing a bar chart on bg. Y-axis labels are Bodoni 26px on the left; x-axis labels are Manrope 24px. Grid lines are 2px at 22% bg-on-ink."
ornament-numeral-panel:
description: "A full-bleed inverse panel (ink background) holding a single oversized Bodoni numeral (~460px weight 900) centered. Used as a section-opener device. Topbar / footline strings sit absolutely positioned in the panel corners."
---
## 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
Emerald Editorial is a **bold display-serif editorial system** rooted in the visual language of fashion magazines and 19th-century theatrical playbills. The foundational premise is a single typographic face — **Bodoni Moda at weight 900** — used at unapologetic scale: 92px for routine headlines, 130–200px for statements and section openers, and 460px for hero numerals. The serif is loud, theatrical, and confident. Every slide leads with type, not with image.
The palette is a tight three-color editorial set: a **saturated emerald green** (`{colors.bg}` — #3CD896) as the dominant surface, a **deep navy ink** (`{colors.ink}` — #0F1A5C) as both the primary text color and the inverse-panel surface, and an **oat paper** (`{colors.paper}` — #F1E9D6) as the secondary surface for alternate tiles. The navy / emerald contrast is the system's chromatic identity; every body of text is navy-on-emerald or emerald-on-navy. Two near-duplicates of the emerald (`{colors.bg-2}`, `{colors.bg-3}`) and two of the navy (`{colors.ink-2}`, `{colors.ink-3}`) exist in the token system but are reserved — the published slides commit almost entirely to the three primaries.
The supporting typeface is **Manrope**, a humanist geometric sans, run at weight 500 for body paragraphs and weight 700–800 in uppercase with wide letter-spacing for every label, tag, eyebrow, caption, and footline. Manrope never crosses into display territory — it stops at 28px and stays in the chrome layer.
The signature treatment is the **double-rule ornament** — a centered serif word framed by two stacked 4px horizontal rules on each side, with 3px between the rules. This treatment appears as the cover's centerpiece and as a recurring statement bracket. It reads as a 19th-century playbill or vintage program — a "The [word] of [word]" framing device. The double-rule ornament is configurable to a single-rule or no-rule variant via a `:root[data-ornament]` attribute, but the double variant is the system's identity.
Depth is **flat and ink-based**. There are no drop shadows, no gradients, no blur, no glow. Every surface is solid emerald, solid navy, or solid paper. Elevation happens through color-block inversion (a navy tile on the emerald canvas is the "elevated" element) and 4px ink rules separating sections. The whole system reads as printed ink on paper, not as a digital interface.
**Density philosophy: medium-full and centered.** Most slides carry one display headline at scale (92–200px) plus 3–4 supporting elements (a stat row, a kpi grid, a process flow, a chart card). The slide padding of 110px gives breathing room, and the masthead/footline chrome at top and bottom anchors the page. A slide that crams six small elements reads as broken; a slide with one giant headline plus three supporting tiles reads as authoritative. Reach for fewer, larger elements. The exception: the agenda-list pattern (a vertical list of large-numbered rows separated by 4px ink rules) is naturally dense and fills the canvas vertically — and it should, when used.
**Key Characteristics:**
- Bodoni Moda at weight 900 for every display moment; Manrope at weight 500/700/800 for every body and label moment.
- Saturated emerald canvas (`{colors.bg}`) with deep navy ink (`{colors.ink}`) text and inverse panels.
- Double-rule ornament with centered serif word is the signature decorative device.
- 4px ink horizontal rules separate every stacked section, every list row, every chart border. The 4px weight is the system's default rule.
- No corner radius anywhere. Every shape is a strict rectangle, except for the round logo/typographic glyphs themselves.
- No shadows, no gradients, no blur. Depth is color-block inversion + 4px rules.
- Display type scales aggressively — 184–460px for hero / section-opener / closing moments.
- Manrope chrome (labels, tags, captions) is always uppercase with 0.05em–0.18em letter-spacing.
## Colors
### Palette
- **BG / Emerald** (`{colors.bg}` — #3CD896): The dominant slide canvas. A saturated, slightly cool emerald — saturated enough to feel like printed ink, not like a CSS preset. The default slide background.
- **BG-2** (`{colors.bg-2}` — #2DC684): A slightly darker emerald reserved for tonal variation; available in the token system but used sparingly. Reach for it only when two emerald surfaces sit adjacent and need separation.
- **BG-3** (`{colors.bg-3}` — #25B377): The darkest emerald variant; similarly reserved.
- **Ink / Navy** (`{colors.ink}` — #0F1A5C): The deep navy primary. The text color on emerald and paper surfaces; the inverse-panel background color; the rule color; the border color. The system's structural color.
- **Ink-2** (`{colors.ink-2}` — #1B2774): A slightly lighter navy variant — available for tonal contrast inside ink-on-ink situations, but rarely used.
- **Ink-3** (`{colors.ink-3}` — #3A4593): The lightest navy variant; reserved.
- **Paper** (`{colors.paper}` — #F1E9D6): The oat-cream secondary surface. Used as the alt-tile fill in process / kpi rows, as the alt bar-chart series, and anywhere a third "warm" surface is needed to break a row of all-navy inverse tiles. Carries `{colors.ink}` text.
- **Rule** (`{colors.rule}` — `rgba(15, 26, 92, 0.22)`): A semi-transparent navy used only for subtle internal grid lines (e.g., chart grid lines on a dark ground). Not a structural rule color.
- **Rule Strong** (`{colors.rule-strong}` — `rgba(15, 26, 92, 0.85)`): An 85%-opacity navy, available as a near-solid rule alternative.
### Defaults
- **Default slide background**: `{colors.bg}` (emerald). Reach for `{colors.ink}` (navy) as a full slide surface when the moment wants gravity (section opener, closing).
- **Default headline color on emerald**: `{colors.ink}`.
- **Default headline color on navy**: `{colors.bg}` — emerald-on-navy is the only color flip the system uses for display type.
- **Default body color on emerald**: `{colors.ink}`.
- **Default body color on navy**: `{colors.bg}`.
- **Default body color on paper**: `{colors.ink}`.
- **Default label / eyebrow / tag color**: `{colors.ink}` on emerald and paper surfaces, `{colors.bg}` on navy surfaces.
- **Default rule color**: `{colors.ink}` at 4px solid. Always.
- **Default inverse tile fill**: `{colors.ink}` with `{colors.bg}` text. The alt tile in a row uses `{colors.paper}` with `{colors.ink}` text.
- **Default delta / pill fill** inside an ink tile: `{colors.bg}` background with `{colors.ink}` text. Inside a paper tile, invert to `{colors.ink}` background with `{colors.bg}` text.
The palette is intentionally tight. Introducing a fourth chromatic family (red, yellow, orange, lavender) shatters the editorial commitment. Stay inside emerald / navy / paper. The bg-2/3 and ink-2/3 variants exist for tonal nuance but should rarely be needed.
## Typography
### Font Family
The system loads several display serif families from Google Fonts (Bodoni Moda, Playfair Display, DM Serif Display, Rozha One, Yeseva One) plus Manrope as the supporting sans. **In practice, only Bodoni Moda is used for display** — the other serif families are loaded but dormant, reserved as future variants. Bodoni Moda is the canonical display face; the others are not part of the system's voice.
Bodoni Moda is run almost exclusively at **weight 900** — the heaviest cut. Weight 800 appears for small ornament words and tile titles (slightly less heavy so they don't compete with the primary headline). Weight 700 appears once or twice for the smallest ornament prepositions. There is no weight-500 Bodoni in the published system. The 900-weight commitment is what gives the system its theatrical-playbill voice.
Manrope handles everything else: body paragraphs at weight 500, labels / eyebrows / tags / captions at weight 700 or 800 in uppercase with 0.05em–0.18em letter-spacing. Manrope never appears at display scale; Bodoni never appears at chrome scale.
### Display, Body, and Chrome Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.numeral-jumbo}` | 460px | Bodoni Moda | 900 | Hero numeral on an inverse section-opener panel |
| `{typography.display-section}` | 200px | Bodoni Moda | 900 | Agenda / section-title hero |
| `{typography.display-cover}` | 184px | Bodoni Moda | 900 | Cover masthead title |
| `{typography.display}` | 130px | Bodoni Moda | 900 | Statement / pull-quote scale |
| `{typography.display-md}` | 128px | Bodoni Moda | 900 | KPI-row introductory headline |
| `{typography.display-sm}` | 120px | Bodoni Moda | 900 | Process-flow introductory headline |
| `{typography.headline-xl}` | 104px | Bodoni Moda | 900 | Chart / data introductory headline |
| `{typography.headline}` | 92px | Bodoni Moda | 900 | Routine slide headline |
| `{typography.ornament-word-lg}` | 84px | Bodoni Moda | 800 | Large ornament-bracketed word (statement variant) |
| `{typography.ornament-word}` | 76px | Bodoni Moda | 800 | Standard ornament-bracketed word (cover variant) |
| `{typography.ornament-word-sm}` | 68px | Bodoni Moda | 800 | Cover preposition between the double-rule brackets |
| `{typography.kpi-figure}` | 144px | Bodoni Moda | 900 | KPI-tile numeral |
| `{typography.kpi-figure-unit}` | 60px | Bodoni Moda | 800 | Unit suffix on a KPI numeral |
| `{typography.stat-figure}` | 92px | Bodoni Moda | 900 | Secondary stat numeral (in a side panel) |
| `{typography.stat-figure-unit}` | 48px | Bodoni Moda | 900 | Unit suffix on a secondary stat |
| `{typography.title-card-lg}` | 64px | Bodoni Moda | 800 | Title inside a large card / agenda-row name |
| `{typography.title-card}` | 48px | Bodoni Moda | 800 | Chart-card take-away title |
| `{typography.title-card-sm}` | 44px | Bodoni Moda | 800 | Statement-supporting cell title |
| `{typography.step-numeral}` | 80px | Bodoni Moda | 900 | Process-step ordinal |
| `{typography.step-title}` | 40px | Bodoni Moda | 800 | Process-step title (sits below a top rule) |
| `{typography.body-lg}` | 28px | Manrope | 500 | Lede / subtitle paragraph |
| `{typography.body}` | 26px | Manrope | 500 | Standard body paragraph |
| `{typography.body-sm}` | 24px | Manrope | 500 | Compact body in a tile / chart side panel |
| `{typography.eyebrow}` | 28px | Manrope | 800 / 0.18em | Section eyebrow above a headline |
| `{typography.label}` | 26px | Manrope | 700 / 0.08em | Masthead / footline label |
| `{typography.label-tight}` | 26px | Manrope | 700 / 0.05em | Cover top/bottom strings |
| `{typography.tag}` | 24px | Manrope | 800 / 0.12em | Inverse pill / tag (mark, delta, side-tag) |
| `{typography.caption}` | 24px | Manrope | 700 / 0.1em | Agenda-row kind label, chart x-axis, kpi label |
| `{typography.credit}` | 28px | Manrope | 700 / 0.18em | Author / org credit row |
### Defaults
- **Default size for a routine slide headline**: `{typography.headline}` (92px).
- **Default size for a hero / cover-scale moment**: `{typography.display-cover}` (184px) or `{typography.display-section}` (200px).
- **Default size for a body paragraph**: `{typography.body}` (26px) in Manrope weight 500.
- **Default size for a body paragraph inside a tile**: `{typography.body-sm}` (24px).
- **Default size for an eyebrow above a headline**: `{typography.eyebrow}` (28px) in Manrope 800 uppercase 0.18em.
- **Default size for a tag / pill / chip**: `{typography.tag}` (24px) in Manrope 800 uppercase 0.12em.
- **Default size for a KPI figure**: `{typography.kpi-figure}` (144px) with an optional 60px unit.
- **Default weight for any Bodoni display moment**: 900. The 800 variant is reserved for ornament words and tile titles, never for primary headlines.
- **Default weight for any Manrope body line**: 500.
When unsure, reach for `{typography.headline}` (92px) for the slide's primary headline. The 120–200px tier is reserved for section openers, statements, and KPI-row headlines — using it for routine headlines flattens the hierarchy.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every primary Bodoni headline runs at weight 900 with negative letter-spacing (-0.01em to -0.03em) and tight line-height (0.9–0.95).** A weight-700 or weight-800 Bodoni headline reads as a sub-headline, not a primary moment.
- **Every Manrope label, eyebrow, tag, caption, footline, and credit element is UPPERCASE with letter-spacing of at least 0.05em.** Manrope in sentence case or with default tracking reads as web app body, not editorial chrome.
- **The double-rule ornament, when used, is bilateral — rules on both sides of the centered word.** A one-sided ornament breaks the bracket symmetry. The ornament can be downgraded to a single-rule or no-rule variant via `:root[data-ornament]`, but the default and recommended form is double.
- **Every section separator and tile divider is a 4px solid `{colors.ink}` rule.** Never 1px, never 2px, never colored beyond ink. The 4px weight is the system's structural rhythm.
- **Inverse tiles always carry `{colors.ink}` background with `{colors.bg}` text.** The alt paper tile carries `{colors.paper}` background with `{colors.ink}` text. Color combinations outside these pairings break the system's printed-ink discipline.
- **Bodoni numerals at jumbo scale (200px+) live on inverse navy panels.** Putting a 460px numeral on the emerald canvas is technically possible but visually breaks the panel-anchored playbill voice; the jumbo numerals belong inside ink panels.
### Typography Principles
The weight 900 + negative tracking + tight leading combination is the system's display voice. Switching any of those three properties (e.g., weight 700, or default tracking, or 1.2 leading) reads as a different design system. The serif/sans role split is strict: Bodoni never appears at body / label scale, Manrope never appears at display scale.
Italics are loaded in the Bodoni font request but not used in the published system — keep them out unless intentionally introducing a new pattern. Underline is not used. Emphasis is communicated through size, color inversion, and ornamentation.
## Layout
### Canvas System
The system targets a fixed **1920×1080** canvas. Slides are `<section class="slide">` elements at exact width/height. Rendering relies on `deck-stage.js` to scale the canvas to fit the viewport. The canvas is paper-stock, not a viewport — designed for projector, printer, or PDF export at 16:9.
### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-default}` | 110px 110px 70px | Standard content slide (asymmetric — slightly less bottom for footline) |
| `{spacing.pad-cover}` | 56px 110px | Cover slide (less top padding to give masthead room) |
| `{spacing.pad-closing}` | 80px 110px | Closing slide |
| `{spacing.masthead-inset}` | 56px top, 80px sides | Absolute masthead / footline inset on cover and closing |
### Chrome Anatomy
The cover and closing carry a **masthead** at top (a Manrope flex row with two label strings on opposite sides) and a **footline** at bottom (a matching row). Content slides typically skip the masthead and footline, leaning on the 110px-top padding to give the headline space. When the masthead is used, it lives at `top: 56px, left/right: 80px`.
### Card and Tile Treatment
The system has **no border-radius anywhere**. Cards, tiles, kpi panels, ornament rules, mark pills, tag pills — all strict rectangles. The only round shapes are the natural curves of the Bodoni glyphs themselves. The visual rhythm comes entirely from rectangle composition and 4px ink rules.
### Rule Weights
| Weight | Use |
|---|---|
| 2px | Chart grid lines (subtle, semi-transparent) |
| 4px | Universal structural rule — section separators, list-row borders, tile top rules |
| 5px | Cover ornament rules (slightly heavier so they hold weight next to the 184px display headline) |
| 18px height (with 4px rule top + 4px rule bottom) | Double-rule ornament span |
The 4px weight is the system's default; reach for it unless the moment specifically needs the cover's heavier 5px rules.
## Depth and Elevation
### Flat, No Shadows
The system uses **zero shadows**. No box-shadow, no text-shadow, no filter blur, no gradient. Elevation is communicated entirely through:
1. **Color-block inversion** — a navy tile on the emerald canvas is the system's "elevated" element. Inversion is the depth language.
2. **4px ink rules** — sections are separated by 4px solid navy lines that read as paper-fold creases between regions.
3. **Solid panels with no border-radius** — the strict-rectangle treatment combined with full inverse fill gives tiles the weight of printed ink blocks.
There is no soft-glow, no glass, no neumorphism. Adding box-shadow shatters the printed-ink discipline.
### Section-Opener Panel
A signature elevation device: a slide can be split into a full-bleed two-column grid where the left side is a solid `{colors.ink}` panel holding a jumbo Bodoni numeral (`{typography.numeral-jumbo}` at 460px) and the right side is the standard emerald canvas with headline + lede + category marks. The panel reads as a magazine title-page opening — heavy, anchored, ceremonial. Treat this as an opener pattern, not a routine slide layout.
## Shapes and Treatment
### Border Radius
**Zero.** Every shape is a strict rectangle. Pills, tags, tiles, panels, bars, mastheads, footlines, ornament words — all square corners.
### Border / Rule Style
- **4px solid `{colors.ink}`** — universal structural rule. Section separators, list-row borders, tile internal rules.
- **5px solid `{colors.ink}`** — the cover ornament's slightly heavier rule.
- **4px solid `currentColor`** — used inside tiles where the rule should match the tile's text color (e.g., a paper tile's internal rule is `{colors.ink}`; an ink tile's internal rule is `{colors.bg}`).
Rules are never dashed, never dotted, never colored beyond the ink / currentColor pattern.
### Decorative Element Types
**Double-Rule Ornament** (`{components.ornament-double-rule}`) — The system's signature. A centered serif word framed by two stacked 4px horizontal rules on each side (3px between them). Used on the cover ("The [word] of [word]" framing), on statement slides (around a small connector word), and anywhere a typographic moment needs theatrical bracketing. Configurable to single-rule or no-rule via `:root[data-ornament]`.
**Vertical Side-Bracket** (`{components.ornament-vertical}`) — A smaller inline variant: a pair of stacked 4px rules on the left and a matching pair on the right of a small serif preposition. Used inline within a sentence rather than as a centered span.
**Masthead / Footline** (`{components.masthead}`, `{components.footline}`) — Absolutely positioned flex rows at top/bottom of cover and closing slides. Two Manrope uppercase strings on opposite sides (e.g., publication name + date; section + page number). Establishes the magazine-page identity.
**Inverse Tile** (`{components.inverse-tile}`) — A solid `{colors.ink}` rectangle holding `{colors.bg}` text. Used as a chart-card container, a kpi tile, a process step, a side panel. No border-radius, no shadow.
**Paper Tile** (`{components.paper-tile}`) — The alt variant: solid `{colors.paper}` with `{colors.ink}` text. Used in rotation across a row of inverse tiles to break monotony (e.g., a four-step process flow alternates ink → paper → ink → paper).
**Mark Pill** (`{components.mark-pill}`) — A small ink-on-bg pill used as a category mark or section tag in the bottom margin of a section opener. Strict rectangle.
**Tag Pill** (`{components.tag-pill}`) — Slightly smaller pill variant used inside chart sides and kpi tiles to mark a takeaway or stat type.
**Delta Pill** (`{components.delta-pill}`) — A bg-on-ink (or inverted ink-on-bg when inside a paper tile) chip showing a directional change indicator (e.g., "↑ 12% YoY"). Lives at the corner of a kpi tile.
**Agenda Row** (`{components.agenda-row}`) — A three-column grid row separated above and below by 4px ink rules. Holds a serif ordinal in the left column, a serif name in the middle, and a Manrope kind label in the right. Stacked agenda rows form the system's table-of-contents pattern.
**Chart Card** (`{components.chart-card}`) — A navy inverse panel holding a bar chart on emerald + paper bars. Y-axis labels in Bodoni; x-axis labels in Manrope. Grid lines are 2px at 22% opacity emerald-on-navy. The panel reads as a magazine data-spread.
**Ornament Numeral Panel** (`{components.ornament-numeral-panel}`) — A full-bleed inverse half-slide holding a single Bodoni numeral at 460px. Topbar / footline strings sit in the corners. Used as a section-opener device only.
## Do's and Don'ts
### Do
- Run every Bodoni display headline at weight 900 with negative letter-spacing (-0.01em to -0.03em) and tight line-height (0.9–0.95). The combination is the system's voice.
- Run every Manrope label / eyebrow / tag / caption / footline in uppercase with at least 0.05em letter-spacing. Manrope in sentence case loses the editorial register.
- Default slide background to `{colors.bg}` (emerald). Reach for `{colors.ink}` as a full slide surface only for section openers and closing moments.
- Use 4px solid `{colors.ink}` rules for every section separator, list border, tile divider. The 4px weight is the system's structural rhythm.
- Reach for the double-rule ornament when a typographic moment needs theatrical framing — especially around small connector words ("of", "in", "for") between two display headlines.
- Use inverse tiles (`{colors.ink}` bg with `{colors.bg}` text) as the default elevated element. Rotate in paper tiles to break a row of all-inverse fills.
- Scale display type aggressively — 130–460px for hero, section-opener, and statement moments. The system rewards scale.
- Pair ink-on-bg with bg-on-ink for color flips. Do not introduce a third color flip (paper-on-ink, ink-on-paper) without a clear semantic reason.
- Keep every shape a strict rectangle. The no-radius commitment is the system's signature alongside the double-rule ornament.
### Don't
- Don't add box-shadow, text-shadow, gradient, or blur to any element. The system is flat printed-ink only.
- Don't introduce a third typeface beyond Bodoni Moda and Manrope. The other serif families in the Google Fonts request (Playfair, DM Serif, Rozha, Yeseva) are loaded but not part of the published voice — adding them shatters the Bodoni commitment.
- Don't run Bodoni at weight 500 or lighter. The system commits to 900 (default), 800 (ornament words, tile titles), and 700 (small prepositions only).
- Don't render Manrope in sentence case or without letter-spacing. Manrope is always uppercase chrome.
- Don't introduce a fourth chromatic family. The emerald / navy / paper triad is the entire palette.
- Don't use border-radius on any element. Zero radius is the system's signature.
- Don't use 1px or 2px structural rules. The 4px weight is the structural default; 2px is reserved for subtle chart grid lines.
- Don't place a 460px numeral on the emerald canvas without an ink panel anchor. Jumbo numerals live on inverse navy panels.
- Don't crowd a slide with six small elements. One display headline + 3–4 supporting tiles is the rhythm; more elements need a smaller scale and break the editorial register.
- Don't omit the masthead / footline on cover and closing slides. The chrome is what makes them read as magazine title pages.
## Responsive Behavior
This is a **fixed 1920×1080 presentation system** rendered through `deck-stage.js`. The canvas is not responsive in the CSS sense — there are no media queries, no breakpoints, no fluid sizing. Every measurement is in fixed pixels at 1920×1080.
### Scaling Behavior
`deck-stage.js` wraps each `<section class="slide">` and scales the 1920×1080 canvas uniformly to fit the browser viewport, letterboxing as needed. Type, padding, gaps, and rule weights are all fixed pixels and scale proportionally with the canvas.
### Presenter Behavior
Navigation is delegated to `deck-stage.js`. Each `<section class="slide">` is one frame; the runtime handles transitions.
### Print / Export
Fixed-pixel measurements inside a 1920×1080 canvas export cleanly to PDF at 16:9. Bodoni Moda renders well at print resolution because the heavy display weight carries the page even at large physical sizes.
### Ornament Variant Switch
The `:root[data-ornament]` attribute controls a global ornament style: `"double"` (default, two stacked rules), `"single"` (one rule centered), or `"none"` (no rule, word floats alone). This is a presentation-level decision per deck, not per slide.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display headline (92–460px) | 霞鹜文楷 LXGW WenKai (with Noto Serif SC fallback at 900) | 400 / 900 | LXGW WenKai's hand-lettered warmth is the closest Chinese analog to Bodoni Moda's theatrical-playbill voice; Noto Serif SC at weight 900 carries the structural mass at jumbo sizes |
| Stat / KPI figure (144px+) | 思源宋体 Noto Serif SC | 900 | Mincho weight 900 provides the printed-ink mass Bodoni Moda achieves at 900 |
| Body paragraph (24–28px) | 思源宋体 Noto Serif SC | 400 | Mincho body voice for warm magazine-spread reading |
| Eyebrow / label / tag (24–28px) | 思源黑体 Noto Sans SC | 700–800 | Replaces Manrope for chrome-layer Chinese; geometric humanist quality |
| Tile mark / pill / caption | 思源黑体 Noto Sans SC | 700 | Maintains the uppercase-tracked chrome feel for inverse pills and tags |
### Mixed-Content Strategy
Use **Strategy C** — keep Bodoni Moda as the Latin display face and let CJK glyphs fall through to LXGW WenKai (display) or Noto Serif SC (body). The Bodoni Moda commitment at weight 900 is the entire brand identity of Emerald Editorial; replacing it with a CJK family would break the fashion-magazine / 19th-century playbill register that defines the deck. Stack:
```css
/* Bodoni Moda roles (every display moment) */
font-family: 'Bodoni Moda', 'LXGW WenKai TC', 'Noto Serif SC', Georgia, serif;
/* Manrope roles (every chrome / body moment) */
font-family: 'Manrope', 'Noto Sans SC', system-ui, sans-serif;
```
The per-glyph fallback strategy lets Latin words render in Bodoni 900 (with the theatrical compression that gives the system its voice) and Chinese characters render in LXGW WenKai or Noto Serif SC. Baseline mismatch at jumbo sizes (200–460px) is the biggest watchpoint — Bodoni Moda at -0.03em tracking sits visually denser than LXGW WenKai, so a mixed-script numeral panel like `第 3 期` may show wobble. For section-opener panels with jumbo numerals, prefer all-numeric (Bodoni) or all-Chinese (LXGW WenKai) lines.
### Loading
Add to the existing Google Fonts `<link>` (or as a second link tag):
```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=LXGW+WenKai+TC&family=Noto+Serif+SC:wght@400;700;900&family=Noto+Sans+SC:wght@500;700;800&display=swap" rel="stylesheet">
```
LXGW WenKai TC is the version on Google Fonts (ships both traditional and simplified glyphs).
### Universal CJK Adjustments
These adjustments apply to **every CJK block** in this system, regardless of size or role:
- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (0.9–0.95 on display, 1.45–1.5 on body) read as cramped in Chinese. Bump display to 1.0–1.1 and body to 1.55–1.65.
- **Remove negative letter-spacing on CJK headlines.** Bodoni Moda display uses -0.01em to -0.03em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the Manrope portion was meant to be capitalized. (This matters here — every Manrope label, eyebrow, tag, caption uses `text-transform: uppercase`.)
- **Use Chinese full-width punctuation** (`,。:;!?「」『』()`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between LXGW WenKai and Noto Serif SC inside the same sentence — pick the face that matches the size tier (display = LXGW WenKai, body = Noto Serif SC) and commit to it for the whole run.
### Aesthetic Notes for This System
Emerald Editorial's whole voice is "fashion masthead / 19th-century theatrical playbill" — Bodoni Moda weight 900 at extreme scale with the double-rule ornament bracketing centered words. The Chinese equivalent of that theatrical heaviness is **LXGW WenKai at large display sizes** (its brush-warmth replicates Bodoni's hand-set character) with **Noto Serif SC at weight 900 for jumbo numerals** (where pure mass matters more than warmth). Avoid Noto Sans SC for display — the geometric grotesque flattens the playbill voice into "modern corporate."
The double-rule ornament works in Chinese — bracket a single Chinese word (e.g., 「春」) between the 4px stacked rules and let LXGW WenKai's warmth carry the theatrical bracket. For the "The X of Y" cover convention, Chinese reads naturally as `「X」之「Y」` or `X 与 Y`, with the connector preposition (之 / 与 / 的) replacing the Latin "of" inside the small-prep slot. The connector word should use LXGW WenKai at weight 400 (matching the ornament-word-sm role in Latin).
Manrope's role as the chrome layer (uppercase + 0.08em–0.18em tracking) translates to **思源黑体 Noto Sans SC weight 700–800 with 0.05em positive tracking** for Chinese. Don't try to fake uppercase — drop the `text-transform: uppercase` rule on CJK runs and let the geometric humanist quality of Noto Sans SC carry the chrome feel through weight and tracking alone.
### Known CJK Gap
The system's commitment to Bodoni Moda weight 900 at 460px (jumbo numerals on inverse navy panels) is the hardest to translate — there is no Chinese face on the Google Fonts CDN that delivers Bodoni 900's optical heaviness at that scale. Noto Serif SC at weight 900 is the closest, but the contrast profile of Han glyphs at 460px reads visually heavier than Bodoni numerals, which can overwhelm the navy panel. For jumbo-numeral section openers in Chinese, consider: (1) using a Chinese numeral character (一二三四五六七八九十) which sits visually lighter than Western digits, or (2) keeping the numeral in Bodoni (Latin) and letting the panel label below it carry the Chinese context. The pure-Chinese jumbo numeral on this system is the riskiest moment and benefits from per-slide manual review.
## Iteration Guide
1. Any new display headline is Bodoni Moda at weight 900 with negative letter-spacing and tight leading. Pick the size from the display ladder (92 / 104 / 120 / 128 / 130 / 184 / 200) — do not invent a new size.
2. Any new chrome line (label, eyebrow, tag, caption) is Manrope at weight 700 or 800 uppercase with 0.05em–0.18em letter-spacing. Pick the size from the chrome ladder (24 / 26 / 28).
3. Any new section separator or list-row border is a 4px solid `{colors.ink}` rule. No 1px / 2px / 3px structural rules.
4. Any new tile uses the inverse-fill pattern (`{colors.ink}` bg with `{colors.bg}` text) or the paper-fill pattern (`{colors.paper}` bg with `{colors.ink}` text). Mix the two in rotation across a row of tiles.
5. Any new pill / tag / chip is a strict rectangle (no border-radius) in the inverse-fill or bg-fill color combination from `{components.tag-pill}` / `{components.delta-pill}`.
6. Any new KPI figure is `{typography.kpi-figure}` (144px) with an optional `{typography.kpi-figure-unit}` (60px) suffix. Smaller KPI sizes are not in the system.
7. Any new ornament moment uses the double-rule treatment by default. Switch to single or none only via the `:root[data-ornament]` global, not per-element.
8. Any new section-opener uses the half-bleed inverse panel + jumbo numeral pattern. The numeral lives on the navy panel; the right half holds the eyebrow + headline + lede + marks.
9. Any new color must come from `{colors.bg}` / `{colors.ink}` / `{colors.paper}` (or the reserved bg-2/3 / ink-2/3 variants if tonal nuance is needed). Do not introduce a yellow, red, or third accent.
10. When the layout feels crowded, increase the display headline size rather than adding more elements. The system rewards bigger type, not more pieces.
## Known Gaps
- The Google Fonts request loads Bodoni Moda, Playfair Display, DM Serif Display, Rozha One, Yeseva One, and Manrope. **In practice only Bodoni Moda and Manrope are used.** The other four serif families are dormant — loaded but not referenced in the CSS. They are available as alternate display voices but must be wired in explicitly.
- The system depends on `deck-stage.js` for canvas scaling and slide navigation. The script is not described in this design.md — treat it as a runtime dependency.
- The `:root[data-ornament]` switch (`double` / `single` / `none`) is a global presentation setting. It cannot be applied per-slide or per-ornament — switching variants applies deck-wide.
- The ink-2 / ink-3 and bg-2 / bg-3 color tokens are defined but not actively used in the published CSS. They are reserved for tonal variation but currently dormant.
- The bar chart uses hand-set bar heights (CSS `%`). There is no data-binding layer — extending the chart requires manually computing percentages.
- Offline rendering will fall back to system serif (likely Georgia) for Bodoni and system sans (likely SF/Segoe) for Manrope. The Bodoni fallback dramatically flattens the display voice; self-hosting recommended for offline / print reliability.
- The 92px Bodoni headlines maintain WCAG AA contrast at navy-on-emerald and emerald-on-navy, but smaller text (24–28px Manrope) on the same color pairings approaches the contrast floor. Keep small text in navy-on-emerald (the more contrastful direction) when possible.
- The masthead and footline strings are hardcoded placeholders in the source (publication name, date, page numbers). They must be edited per-deck.
- The system has no `@media print` rule and no responsive breakpoints. It is fixed 1920×1080 and relies on `deck-stage.js` for any viewport adaptation.
# Emerald Editorial Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/emerald-editorial/design.md`
- Preview card: `bold-template-pack/templates/emerald-editorial/preview.md`
## Selection Metadata
- Slug: `emerald-editorial`
- Tagline: A magazine-cover business deck: emerald + navy + paper, double-rule masthead ornaments, and a bold Bodoni-style display serif.
- Mood: editorial, considered, confident, magazine-cover
- Tone: literary, authoritative, warm, designed
- Formality: medium-high
- Density: medium
- Scheme: mixed
- Best for: Anything that should feel like the front of a serious magazine, including but not limited to leadership readouts, planning-office reviews, and strategy briefings. The double-rule masthead ornament gives it editorial gravitas without making it stiff — also a great unexpected pick for product launches or research recaps that want to feel considered rather than corporate.
- Avoid for: Contexts that need to read as quiet, neutral, or institutionally restrained — the emerald field is too saturated to disappear into the background.
## Visual Snapshot
A bold display-serif editorial system in the register of a fashion masthead or vintage magazine cover. Bodoni Moda runs at weight 900 across a wide scale (44–460px), set against a saturated emerald-green canvas with deep navy ink and oat-paper accents. The signature treatment is a stacked double-rule ornament that brackets centered display words like a 19th-century theatrical playbill. The aesthetic borrows from Harper's Bazaar / Vogue / Wallpaper covers: confident, theatrical, paper-and-ink committed, with a tight three-color palette and zero gradients or shadows.
Emerald Editorial is a bold display-serif editorial system rooted in the visual language of fashion magazines and 19th-century theatrical playbills. The foundational premise is a single typographic face — Bodoni Moda at weight 900 — used at unapologetic scale: 92px for routine headlines, 130–200px for statements and section openers, and 460px for hero numerals. The serif is loud, theatrical, and confident. Every slide leads with type, not with image.
## Preview Ingredients
- Palette: bg #3CD896; bg-2 #2DC684; bg-3 #25B377; ink #0F1A5C; ink-2 #1B2774; ink-3 #3A4593; paper #F1E9D6
- Typography: See full design doc after selection.
- Signature move: Bodoni Moda at weight 900 for every display moment; Manrope at weight 500/700/800 for every body and label moment.
- Signature move: Saturated emerald canvas ({colors.bg}) with deep navy ink ({colors.ink}) text and inverse panels.
- Signature move: Double-rule ornament with centered serif word is the signature decorative device.
- Signature move: 4px ink horizontal rules separate every stacked section, every list row, every chart border. The 4px weight is the system's default rule.
- Signature move: No corner radius anywhere. Every shape is a strict rectangle, except for the round logo/typographic glyphs themselves.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Grove
description: A quiet, editorial-serif presentation system in the register of a well-bound monograph or boutique brand book. Playfair Display at weight 400 (never bold) carries every headline, italicized in terracotta coral for accent emphasis as the signature move. Jost weight 300 carries every paragraph as the "good paper" body face. JetBrains Mono at weight 300 holds labels, kickers, and the thin chrome bars. The palette pairs a deep forest green canvas (#192b1b) with warm cream text (#d4cfbf) and a single terracotta coral accent (#c8524a). Generous negative space, hairline 1px borders, and a near-invisible serif watermark numeral give it the calm authority of a literary journal.
colors:
bg: "#192b1b"
bg-alt: "#1e3221"
bg-light: "#e8e4d6"
bg-light-alt: "#dedad0"
fg: "#d4cfbf"
fg-2: "rgba(212, 207, 191, 0.6)"
fg-3: "rgba(212, 207, 191, 0.32)"
fg-light: "#192b1b"
fg-light-2: "rgba(25, 43, 27, 0.58)"
fg-light-3: "rgba(25, 43, 27, 0.33)"
accent: "#c8524a"
border: "rgba(212, 207, 191, 0.12)"
border-light: "rgba(25, 43, 27, 0.14)"
watermark-dark: "rgba(212, 207, 191, 0.06)"
watermark-light: "rgba(25, 43, 27, 0.06)"
color-aliases:
fg-light: bg
fg-light-canonical: "fg-light shares hex #192b1b with bg — the green is reused as both surface and primary text-on-light"
typography:
display:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "10vw"
fontWeight: 400
lineHeight: 1
letterSpacing: -0.01em
h1:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "5.5vw"
fontWeight: 400
lineHeight: 1.1
h1-statement:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "min(4.5vw, 7.5vh, 88px)"
fontWeight: 400
lineHeight: 1.15
h2:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "3.2vw"
fontWeight: 400
lineHeight: 1.2
h3:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "2vw"
fontWeight: 400
lineHeight: 1.3
quote-text:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "3.2vw"
fontWeight: 400
lineHeight: 1.35
letterSpacing: -0.01em
fontStyle: italic
quote-mark:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "8vw"
fontWeight: 400
lineHeight: 0.6
stat-value:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "4.5vw"
fontWeight: 400
lineHeight: 1
letterSpacing: -0.02em
grove-num:
fontFamily: "'Playfair Display', 'Noto Serif SC', Georgia, serif"
fontSize: "18vw"
fontWeight: 400
lineHeight: 1
letterSpacing: -0.03em
lead:
fontFamily: "'Jost', 'Noto Sans SC', system-ui, sans-serif"
fontSize: "1.45vw"
fontWeight: 300
lineHeight: 1.65
body:
fontFamily: "'Jost', 'Noto Sans SC', system-ui, sans-serif"
fontSize: "1.05vw"
fontWeight: 300
lineHeight: 1.75
body-list-emph:
fontFamily: "'Jost', 'Noto Sans SC', system-ui, sans-serif"
fontSize: "max(1.4vw, 17px)"
fontWeight: 300
lineHeight: 1.6
caption:
fontFamily: "'Jost', 'Noto Sans SC', system-ui, sans-serif"
fontSize: "0.82vw"
fontWeight: 300
lineHeight: 1.55
label:
fontFamily: "'JetBrains Mono', monospace"
fontSize: "0.7vw"
fontWeight: 300
letterSpacing: 0.12em
kicker:
fontFamily: "'JetBrains Mono', monospace"
fontSize: "0.7vw"
fontWeight: 300
letterSpacing: 0.14em
textTransform: uppercase
chapter-num:
fontFamily: "'JetBrains Mono', monospace"
fontSize: "0.7vw"
fontWeight: 300
letterSpacing: 0.2em
textTransform: uppercase
stat-label:
fontFamily: "'JetBrains Mono', monospace"
fontSize: "0.7vw"
fontWeight: 300
letterSpacing: 0.12em
textTransform: uppercase
spacing:
pad-x: "8vw"
pad-y: "6.5vh"
pad-quote-x: "calc(8vw * 1.1)"
pad-quote-y: "calc(6.5vh * 1.2)"
gap-lg: "4.5vh"
gap-md: "2.8vh"
gap-sm: "1.4vh"
rule-short: "36px"
motion:
ease-slide: "cubic-bezier(0.77, 0, 0.175, 1)"
dur-slide: "0.9s"
ease-enter: "cubic-bezier(0.16, 1, 0.3, 1)"
dur-enter: "0.7s"
stagger-delays: "0 / 0.08s / 0.18s / 0.3s / 0.44s / 0.6s / 0.78s"
canvas:
width: 100vw
height: 100vh
components:
slide-chrome:
description: "Thin top bar separating slide content from the page edge. A flex space-between row holding mono label text on each side, separated below by a 1px hairline in {colors.border} (or {colors.border-light} on light slides). Pads with {spacing.gap-sm} above the rule, then {spacing.gap-md} below before content starts."
border: "1px solid {colors.border}"
typography: "{typography.label}"
slide-foot:
description: "Matching bottom bar. Flex space-between row holding section name and 'NN / TT' counter, with 1px hairline border-top. The chrome and foot together frame every content slide; cover, chapter, quote, and end slides hide both."
border: "1px solid {colors.border}"
typography: "{typography.label}"
grove-num:
description: "Massive serif digit placed in the background at very low opacity (6%) as compositional texture. Sits absolutely at right: {spacing.pad-x}, bottom: -0.15em, with pointer-events disabled. The system's signature wallpaper element on chapter and section moments."
fontSize: "18vw"
color: "{colors.watermark-dark} on dark / {colors.watermark-light} on light"
grove-stat:
description: "Stat card: large Playfair value in {colors.accent}, mono uppercase label beneath, 1px border-bottom hairline. No background fill — the card is defined by the rule and the type ratio alone."
valueColor: "{colors.accent}"
valueSize: "4.5vw"
labelTypography: "{typography.stat-label}"
borderBottom: "1px solid {colors.border}"
bullet-list:
description: "Two-column grid list (2em / 1fr) where the bullet is a coral em-dash glyph rendered in JetBrains Mono, not a CSS bullet. The em-dash is the system's bullet language."
bulletGlyph: "—"
bulletColor: "{colors.accent}"
bulletFont: "'JetBrains Mono', monospace"
rule-coral:
width: "{spacing.rule-short}"
height: "1px"
background: "{colors.accent}"
description: "A 36px-wide 1px-tall terracotta coral rule. The compositional beat between a kicker and the headline that follows."
rule-full:
width: "100%"
height: "1px"
background: "{colors.border} on dark / {colors.border-light} on light"
description: "Full-width hairline divider. Used between stacked sections inside a slide."
kicker:
typography: "{typography.kicker}"
color: "{colors.accent}"
description: "Mono uppercase eyebrow in coral, placed above an h1/h2 headline."
chapter-num:
typography: "{typography.chapter-num}"
color: "{colors.accent}"
marginBottom: "{spacing.gap-md}"
quote-mark:
typography: "{typography.quote-mark}"
color: "{colors.accent}"
description: "Massive Playfair opening-quote glyph in coral, placed above the italic quote body."
img-placeholder:
background: "{colors.bg-alt} on dark / {colors.border-light} on light"
color: "{colors.fg-3} on dark / {colors.fg-light-3} on light"
typography: "{typography.label}"
minHeight: "30vh"
description: "Image-region marker — solid darker-than-background fill with a mono caption stating the placeholder text. Use this in place of <img> until a real image is available."
nav-dots:
position: "fixed"
placement: "bottom: 24px, horizontally centered"
dotSize: "5px"
dotBackground: "rgba(255, 255, 255, 0.22)"
activeBackground: "rgba(255, 255, 255, 0.8)"
activeTransform: "scale(1.4)"
description: "Small white dots at the bottom of the viewport indicating slide position. The fixed counter (#slide-counter) is intentionally disabled — the slide-foot already shows NN / TT."
---
## 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
Grove is a **quiet, editorial-serif presentation system** in the register of a literary monograph or boutique brand book. The foundational premise is restraint: every slide carries one focused content moment surrounded by deep negative space, anchored by thin 1px chrome bars at top and bottom and supported by a small library of compositional beats (coral kicker, 36px coral rule, italic-coral accent, em-dash bullet, near-invisible watermark numeral).
The typographic stack runs four faces, each in a single specific weight:
- **Playfair Display at weight 400** carries every headline, every quote, every stat figure, and every watermark numeral. **Bold serif is not permitted** — the no-bold rule is the system's most important typographic commitment. Italicized Playfair in `{colors.accent}` coral is the signature accent move: `<em>` inside any headline switches to italic coral.
- **Jost at weight 300** carries every paragraph and bullet body. The light weight is the "good paper" feel — it sits back and lets the serif lead.
- **JetBrains Mono at weight 300** carries every label, kicker, footline, slide counter, and stat caption. Always uppercase, always with at least 0.12em letter-spacing.
- **Noto Serif SC / Noto Sans SC at weight 300–500** are loaded as Chinese fallbacks for every role. The deck is built bilingually-aware — Chinese characters render through the Noto cuts when present in the content.
The palette is a tight two-surface system with one accent. Dark slides use `{colors.bg}` (a deep forest green) with `{colors.fg}` (warm cream — never pure white) for body text. Light slides flip to `{colors.bg-light}` (warm parchment) with `{colors.fg-light}` (the same forest green now used as text). The single accent is **terracotta coral** (`{colors.accent}` — #c8524a), used only in small, deliberate places: the italic emphasis inside headlines, the 36px rule under a kicker, the em-dash bullet, the stat figure, the chapter ordinal, and the opening quote mark. Coral is the system's accent voice; using it as a surface fill or for body paragraphs shatters the editorial discipline.
Depth is **flat and air-based**. There are no drop shadows, no gradients, no blur, no glow. The only "depth" devices are 1px hairline borders (the chrome bars, the stat-card divider, the compare-panel separator) and the watermark numeral at 6% opacity. The whole system reads as printed ink on linen paper, not as a digital surface.
The system carries a built-in **motion vocabulary**: slide-to-slide transitions use a sharp `cubic-bezier(0.77, 0, 0.175, 1)` pan at 0.9s; element entrances stagger via `[data-anim]` and `[data-delay]` attributes (fade-up / fade-in / reveal-right / reveal-left / scale-in) with a spring-y `cubic-bezier(0.16, 1, 0.3, 1)` curve at 0.7s and delays of 0 / 0.08 / 0.18 / 0.3 / 0.44 / 0.6 / 0.78s. Animation is part of the system identity; new slides should use the animation attribute stack rather than authoring custom transitions.
**Density philosophy: sparse and breathing.** Grove reads as elegant when slides are quiet — one headline, one supporting paragraph, three stats in a row, two columns of text-and-image. The 8vw horizontal and 6.5vh vertical padding is generous by design. A slide that crowds 6 elements into the canvas breaks the system; a slide with one headline, one lede, and one accent rule reads as authoritative. Reach for fewer, larger elements. The system rewards silence around the type, not density of content.
**Key Characteristics:**
- Playfair Display at weight 400 — never bold — for every serif moment. Italic in `{colors.accent}` is the headline accent.
- Jost weight 300 for every body paragraph. Lighter weight is the system's "good paper" voice.
- JetBrains Mono weight 300 uppercase with 0.12em–0.2em letter-spacing for every label, kicker, footline, counter, and caption.
- Dark slides on `{colors.bg}` deep forest green with `{colors.fg}` warm cream text. Light slides on `{colors.bg-light}` parchment with `{colors.fg-light}` green text.
- One accent color: `{colors.accent}` terracotta coral. Used only for italic headline emphasis, the 36px coral rule, em-dash bullets, stat figures, chapter ordinals, and the quote mark.
- 1px hairline borders only (`{colors.border}` on dark, `{colors.border-light}` on light). No thick borders, no shadows, no gradients.
- Em-dash glyph rendered in JetBrains Mono coral is the system's universal bullet.
- A massive serif watermark numeral (`{components.grove-num}` at 18vw, 6% opacity) sits in the bottom-right corner of chapter and section slides as compositional texture.
- A staggered fade / reveal animation system (`[data-anim]` + `[data-delay]`) is built-in; new content should use it rather than appearing without entrance.
## Colors
### Palette
- **BG / Deep Forest** (`{colors.bg}` — #192b1b): The dominant dark canvas. A deep, considered forest green — grounded, editorial, the Grove base. The default slide background.
- **BG Alt** (`{colors.bg-alt}` — #1e3221): A slightly lighter forest green for secondary dark surfaces. Used as the `{components.img-placeholder}` fill on dark slides, where it reads as a tonal step up from the canvas without leaving the green family.
- **BG Light / Parchment** (`{colors.bg-light}` — #e8e4d6): The warm parchment surface used on light slides. Reads as good-quality paper stock, not as digital white.
- **BG Light Alt** (`{colors.bg-light-alt}` — #dedad0): A slightly cooler parchment for secondary light surfaces. Available for tonal separation between adjacent light regions.
- **FG / Warm Cream** (`{colors.fg}` — #d4cfbf): Primary text color on dark surfaces. Warm cream — never pure white. The off-white temperature is essential to the printed-ink feel.
- **FG-2** (`{colors.fg-2}` — rgba(212,207,191,0.6)): Secondary / muted text on dark. Used for ledes, captions, and supporting copy that needs to recede from primary.
- **FG-3** (`{colors.fg-3}` — rgba(212,207,191,0.32)): Tertiary / hint text on dark. Near-invisible — used for image-placeholder captions and the faintest metadata.
- **FG Light** (`{colors.fg-light}` — #192b1b): Primary text on light surfaces. **Shares its hex with `{colors.bg}`** — the deep forest green is used both as the dark canvas and as the dark text-on-light color. This is the system's primary surface-text inversion device.
- **FG Light 2** (`{colors.fg-light-2}` — rgba(25,43,27,0.58)): Secondary muted text on light.
- **FG Light 3** (`{colors.fg-light-3}` — rgba(25,43,27,0.33)): Tertiary text on light.
- **Accent / Terracotta Coral** (`{colors.accent}` — #c8524a): The single warm note. Used sparingly: italic emphasis inside headlines, the 36px coral rule under a kicker, the em-dash bullet, the stat figure, the chapter ordinal, the opening quote mark, and nav-dot active state. Never used as a surface fill, never used for body paragraphs.
- **Border** (`{colors.border}` — rgba(212,207,191,0.12)): Hairline divider on dark slides. 12% cream — visible as a structural line but never loud.
- **Border Light** (`{colors.border-light}` — rgba(25,43,27,0.14)): Hairline divider on light slides. 14% forest green.
### Defaults
- **Default slide background**: `{colors.bg}` (deep forest green) for the deck's dominant tonal register. Reach for `{colors.bg-light}` (parchment) when the content wants a literal "page" feel — typically for quote slides, lighter chapters, or contrast.
- **Default primary text color on dark surface**: `{colors.fg}` (warm cream).
- **Default primary text color on light surface**: `{colors.fg-light}` (deep forest green — same hex as the dark surface).
- **Default secondary / muted text**: `{colors.fg-2}` on dark, `{colors.fg-light-2}` on light. Use the `.muted` utility class.
- **Default headline color**: matches the surface's primary text color. Headlines never appear in coral except for the italic `<em>` accent inside them.
- **Default body color**: matches the surface's primary text color.
- **Default border color**: `{colors.border}` on dark, `{colors.border-light}` on light — both at 1px solid hairline weight.
- **Default kicker / chapter-num color**: `{colors.accent}` (terracotta coral). The mono uppercase kicker is the only chrome element that takes the accent color.
- **Default rule color** for the short 36px compositional rule under a kicker: `{colors.accent}`. The full-width section divider rule uses `{colors.border}` instead.
The palette is intentionally minimal. The dark forest / light parchment / terracotta coral triad is the entire color vocabulary. Introducing a fourth color (a navy, a yellow, a second accent) breaks the system's editorial restraint.
## Typography
### Font Family
The system loads four families from Google Fonts:
- **Playfair Display** at weights 400 and 500 (italic and roman). **Only weight 400 is used in published slides.** Weight 500 is loaded but reserved; bold serif (weight 700) is explicitly not permitted by the system rules.
- **Jost** at weights 200, 300, 400, 500. **Only weight 300 is used.** The light weight is the system's body voice.
- **JetBrains Mono** at weights 300 and 400. **Only weight 300 is used.** The light mono is the chrome voice.
- **Noto Serif SC / Noto Sans SC** at weights 300–500, loaded as the Chinese fallback chain for every role.
The four-family stack is strict by role: Playfair for every serif moment (display, headlines, quotes, stat figures, watermark), Jost for every body paragraph and bullet, JetBrains Mono for every label / kicker / footline / counter / caption.
### Display, Body, and Chrome Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.grove-num}` | 18vw | Playfair | 400 | Watermark ordinal numeral, 6% opacity, absolute bottom-right |
| `{typography.display}` | 10vw | Playfair | 400 | Cover hero title |
| `{typography.quote-mark}` | 8vw | Playfair | 400 | Opening quotation glyph |
| `{typography.h1}` | 5.5vw | Playfair | 400 | Chapter title, statement headline |
| `{typography.stat-value}` | 4.5vw | Playfair | 400 / coral | Stat-card numeric value |
| `{typography.h2}` | 3.2vw | Playfair | 400 | Routine slide headline |
| `{typography.quote-text}` | 3.2vw | Playfair | 400 italic | Quote body |
| `{typography.h3}` | 2vw | Playfair | 400 | Sub-headline, compare-panel title |
| `{typography.lead}` | 1.45vw | Jost | 300 | Lead paragraph |
| `{typography.body-list-emph}` | max(1.4vw, 17px) | Jost | 300 | List-slide body / bullets — emphasized for legibility |
| `{typography.body}` | 1.05vw | Jost | 300 | Standard body paragraph |
| `{typography.caption}` | 0.82vw | Jost | 300 | Captions, footnotes, chart sources |
| `{typography.label}` | 0.7vw | JetBrains Mono | 300 / 0.12em | Chrome label, mono metadata |
| `{typography.kicker}` | 0.7vw | JetBrains Mono | 300 / 0.14em / UPPER | Eyebrow above a headline |
| `{typography.chapter-num}` | 0.7vw | JetBrains Mono | 300 / 0.2em / UPPER | Chapter ordinal label |
| `{typography.stat-label}` | 0.7vw | JetBrains Mono | 300 / 0.12em / UPPER | Mono label beneath a stat figure |
### Defaults
- **Default size for a routine slide headline**: `{typography.h2}` (3.2vw).
- **Default size for a chapter or statement headline**: `{typography.h1}` (5.5vw). For statement-class moments specifically, use `{typography.h1-statement}` which caps at `min(4.5vw, 7.5vh, 88px)` to prevent overflow on short viewports.
- **Default size for a cover hero title**: `{typography.display}` (10vw).
- **Default size for a body paragraph**: `{typography.body}` (1.05vw) in Jost weight 300.
- **Default size for a lede / introductory paragraph**: `{typography.lead}` (1.45vw).
- **Default size for a kicker / eyebrow**: `{typography.kicker}` (0.7vw) in JetBrains Mono uppercase 0.14em with `{colors.accent}` color.
- **Default size for a stat-card figure**: `{typography.stat-value}` (4.5vw) in Playfair coral.
- **Default weight for every serif element**: 400.
- **Default weight for every body / Jost element**: 300.
- **Default weight for every mono / JetBrains element**: 300.
When the body text on a list-style slide reads too small at 1.05vw on typical laptop viewports, the system bumps it to `{typography.body-list-emph}` (max of 1.4vw or 17px). Reach for the emphasized size whenever a slide's primary content moment is a body paragraph or bulleted list — the default 1.05vw is calibrated for projector viewing, not laptop reading.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Playfair element runs at weight 400.** Bold serif (weight 700) is not used anywhere in the system. This is the system's most important typographic rule.
- **An `<em>` tag inside any Playfair headline (h1, h2, h3, or quote) renders as italic in `{colors.accent}` coral.** This is the signature Grove accent — the way you add emphasis to a headline is to italicize a word in coral. The em-style switch is automatic via CSS.
- **The opening quote mark on a quote slide is rendered as a massive Playfair glyph at 8vw in `{colors.accent}` coral.** A quote without the oversized coral quote-mark is broken.
- **The quote body is always italic.** Roman-style quote text is not in the system.
- **Every kicker / chapter-num / footline / label / caption is JetBrains Mono uppercase with at least 0.12em letter-spacing.** Mono in sentence case or without tracking reads as code, not chrome.
- **Bullet glyphs are em-dashes (`—`) rendered in JetBrains Mono `{colors.accent}` coral.** Never bullets (`•`), never hyphens (`-`), never asterisks. The em-dash is the system's bullet language.
- **Every chrome bar (top and bottom) carries a 1px solid `{colors.border}` rule (or `{colors.border-light}` on light slides).** The hairline rule is what makes the chrome read as a "frame around the page" rather than a banner.
### Typography Principles
The Playfair-400 / Jost-300 / JetBrains-Mono-300 weight commitment is the system's voice. Switching any of those weights breaks the editorial register. There is no weight ladder — each face has exactly one weight.
Italics are reserved for two specific roles: the coral accent inside headlines (via `<em>`) and the quote body. Italic body paragraphs are not used. Underline is not used. Emphasis in body text is communicated by the `.accent` color utility (changes color to coral), not by italic or bold.
## Layout
### Canvas System
The system targets a fluid viewport — each `.slide` is `100vw × 100vh` with `padding: {spacing.pad-y} {spacing.pad-x}` (6.5vh / 8vw). Slides sit side-by-side in a horizontal `#deck` flex strip and translate via `transform: translateX(...)` with the `{motion.dur-slide}` / `{motion.ease-slide}` transition. Only one slide is `is-active` at a time; non-active slides hold their content invisible (`[data-anim]` is `opacity: 0`) until the active class triggers the entrance animations.
### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 8vw | Horizontal slide padding |
| `{spacing.pad-y}` | 6.5vh | Vertical slide padding |
| `{spacing.pad-quote-x}` | 8.8vw | Slightly wider horizontal padding on quote slides |
| `{spacing.pad-quote-y}` | 7.8vh | Slightly taller vertical padding on quote slides |
| `{spacing.gap-lg}` | 4.5vh | Between major content sections |
| `{spacing.gap-md}` | 2.8vh | Between related elements |
| `{spacing.gap-sm}` | 1.4vh | Between tightly coupled elements |
### Chrome Anatomy
Every content slide carries a **slide-chrome** at the top — a thin flex space-between row holding two mono labels separated below by a 1px hairline border — and a **slide-foot** at the bottom — a matching row with section name + "NN / TT" counter, separated above by a matching hairline.
The chrome and foot are hidden on cover, chapter, quote, and end slides — those are the deck's chromeless emotional moments. Every other slide carries the frame.
### Border-Radius
**Zero structural radius.** No rounded cards, no rounded buttons, no rounded image placeholders. The only round shapes in the system are the 5px nav-dots (50% radius — fully circular) at the bottom of the viewport.
## Depth and Elevation
### Flat, No Shadows
The system uses **zero box-shadow, zero text-shadow, zero blur, zero gradient**. Depth is communicated entirely through:
1. **1px hairline borders** — the chrome bars at top and bottom, the stat-card divider, the compare-panel separator, the section-divider rule.
2. **Opacity layers in text color** — primary (`{colors.fg}`), muted (`{colors.fg-2}`), hint (`{colors.fg-3}`). The three-step opacity ladder is the system's text-elevation device.
3. **The watermark numeral** at 6% opacity — a massive Playfair digit sitting in the bottom-right corner of chapter and section slides as compositional texture, not as UI.
The absence of shadow is itself the elevation language. Adding `box-shadow: 0 4px 12px rgba(0,0,0,0.1)` shatters the printed-ink feel.
### Watermark Numeral
The `{components.grove-num}` element is a Playfair digit at 18vw / 6% opacity, positioned absolutely at `right: {spacing.pad-x}, bottom: -0.15em`. It reads as a faint background texture, never as content. Use it on chapter / section / statement slides where the empty bottom-right would otherwise feel un-anchored. It is part of the depth language even though it appears as a decorative element.
## Shapes and Treatment
### Border Weight and Style
- **1px solid `{colors.border}`** — the universal hairline on dark slides. Chrome bar borders, stat-card bottoms, compare-panel separators, full-width section dividers.
- **1px solid `{colors.border-light}`** — the matching hairline on light slides.
- **1px solid `{colors.accent}`** — the 36px-wide coral rule (`{components.rule-coral}`) used as the compositional beat between a kicker and the headline that follows.
Borders are never thicker than 1px. Never dashed, never dotted. The 1px hairline is the system's structural rhythm.
### Decorative Element Types
**Slide Chrome Bar** (`{components.slide-chrome}`) — Thin top bar with mono labels on each side, separated below by a 1px hairline. The system's universal "you are reading a page" frame.
**Slide Foot Bar** (`{components.slide-foot}`) — Matching bottom bar with section name + counter, separated above by 1px hairline.
**Coral Rule** (`{components.rule-coral}`) — A 36px-wide 1px terracotta coral horizontal rule. The compositional beat that sits between a kicker (above) and a headline (below). Use it once per slide where a kicker leads into a primary headline — do not stack multiple coral rules.
**Full Rule** (`{components.rule-full}`) — Full-width 1px hairline divider in `{colors.border}` / `{colors.border-light}`. Used as a section break inside a slide body.
**Kicker** (`{components.kicker}`) — Mono uppercase eyebrow in coral, placed above an h1 or h2 headline. Often paired with a coral rule below it.
**Chapter Number** — A mono uppercase ordinal in coral (`{typography.chapter-num}`) above the chapter title. Sets the chapter's identity at chapter-opener slides.
**Em-Dash Bullet** (`{components.bullet-list}`) — A two-column grid list (2em / 1fr) where the bullet is a coral em-dash glyph rendered in JetBrains Mono. Never use a true bullet (`•`); always the em-dash.
**Grove Stat** (`{components.grove-stat}`) — A vertical stack: large Playfair coral value (4.5vw) on top, mono uppercase label beneath, 1px border-bottom hairline. No background fill — the card is defined by the rule + the type, not by a containing box.
**Quote Mark** (`{components.quote-mark}`) — Massive Playfair opening-quote glyph at 8vw in coral, placed above the italic quote body. Always present on a quote slide.
**Watermark Numeral** (`{components.grove-num}`) — Playfair digit at 18vw / 6% opacity in the bottom-right corner. Compositional texture only, never UI.
**Image Placeholder** (`{components.img-placeholder}`) — A solid `{colors.bg-alt}` (on dark) or `{colors.border-light}` (on light) fill marking where a real `<img>` will go. Holds a mono caption like "[ image ]" in `{colors.fg-3}`.
**Nav Dots** (`{components.nav-dots}`) — Fixed 5px circular dots at the bottom of the viewport indicating slide position. Inactive: 22% white. Active: 80% white at 1.4× scale.
## Do's and Don'ts
### Do
- Run every serif moment in Playfair Display weight 400. Never bold.
- Use `<em>` inside any Playfair headline to switch a word to italic terracotta coral — this is the system's signature accent move.
- Run every paragraph in Jost weight 300. The lighter weight is the system's body voice.
- Run every label, kicker, chapter-num, footline, counter, and stat-caption in JetBrains Mono weight 300, uppercase, with at least 0.12em letter-spacing.
- Default slide background to `{colors.bg}` (deep forest green). Use `{colors.bg-light}` (parchment) on quote slides and any moment that wants a literal "page" feel.
- Pair the kicker with the 36px coral rule as a single compositional unit above the slide's primary headline.
- Use the em-dash glyph (`—`) in coral as the universal bullet. Never use round bullets or hyphens.
- Apply the `{components.grove-num}` watermark numeral to chapter and section-opener slides — the bottom-right corner needs that anchor.
- Use the built-in `[data-anim]` + `[data-delay]` animation stack (fade-up / fade-in / reveal-right / reveal-left / scale-in, with delays 0–6) for every new content element. Animation is part of the system identity, not optional polish.
- Keep slides spacious — one headline + one supporting paragraph + one accent rule is the rhythm. Reach for fewer elements at larger sizes.
### Don't
- Don't use bold serif. Playfair at weight 700 is not in this system. Bold serif breaks the editorial voice.
- Don't introduce a fourth typeface beyond Playfair, Jost, JetBrains Mono, and Noto SC. The four-family stack is the entire typographic identity.
- Don't use coral as a surface fill or for body paragraphs. Coral is the accent voice: italic emphasis, kicker, rule, em-dash bullet, stat figure, quote mark, chapter ordinal. That's the entire coral vocabulary.
- Don't use box-shadow, gradient, blur, or any rgba shadow. The system is flat.
- Don't use thick borders (2px+). The 1px hairline is the system's structural rhythm.
- Don't round any corners. The only round shape is the 5px nav-dot.
- Don't use round bullets, hyphens, or asterisks for list items. The em-dash in coral is the only bullet glyph.
- Don't put a kicker without a coral rule below it. The kicker → rule → headline triad is one unit.
- Don't render mono text in sentence case or without letter-spacing. Mono is always uppercase chrome with 0.12em+ tracking.
- Don't omit the slide-chrome and slide-foot on content slides. The thin frame at top and bottom is what makes the slide read as a page.
- Don't crowd the canvas. Grove rewards silence around the type. If a slide feels full, remove a supporting element rather than shrinking type.
## Responsive Behavior
The system uses **vw / vh units throughout** — every size, padding, gap, and rule is proportional to the viewport. The same composition renders correctly on a 1280×720 laptop, a 1920×1080 monitor, and a 2560×1440 display without breakpoints.
### Scaling Behavior
- Display headline scales linearly with viewport width (10vw → 192px at 1920, 128px at 1280).
- Body text scales similarly (1.05vw → 20.16px at 1920, 13.44px at 1280) — except on list-slide body, where the `max(1.4vw, 17px)` floor prevents the text from going unreadable on smaller viewports.
- Padding, gaps, and grove-num all scale proportionally with vw/vh.
- The 1px hairline borders are fixed-pixel and do not scale, which means at larger viewports they appear proportionally finer. This is by design.
### Presenter Behavior
- Slides advance via right/down arrow / space / page-down (handled by the deck JavaScript).
- Slides reverse via left/up arrow / page-up.
- The horizontal `#deck` strip translates via `transform: translateX(-N * 100vw)` between slides, with the `{motion.dur-slide}` sharp deceleration curve at 0.9s.
- Each slide carries an `is-active` class that triggers the staggered entrance animations on its `[data-anim]` elements.
- Bottom nav-dots reflect current slide position; clicking a dot jumps to that slide.
### Animation
The `[data-anim]` + `[data-delay]` system is built-in:
- `fade-up`: opacity 0 → 1, translateY 28px → 0
- `fade-in`: opacity 0 → 1
- `reveal-right`: clip-path inset(0 100% 0 0) → inset(0 0 0 0)
- `reveal-left`: clip-path inset(0 0 0 100%) → inset(0 0 0 0)
- `scale-in`: opacity 0 → 1, scale 0.94 → 1
All entrance animations use `{motion.ease-enter}` at `{motion.dur-enter}` (0.7s). Stagger delays: 0 / 0.08s / 0.18s / 0.3s / 0.44s / 0.6s / 0.78s.
### Print / Export
The system has no `@media print` rule. Print export will inherit the horizontal-strip layout and is unlikely to paginate cleanly. Treat Grove as a screen-first system; PDF export requires a dedicated print stylesheet.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display / h1 / h2 / h3 (Playfair roles, 2–10vw) | 霞鹜文楷 LXGW WenKai | 400 | Literary, hand-set warmth that mirrors Playfair Display at weight 400 — never bold, exactly the Grove rule |
| Quote text / mark (8vw mark, 3.2vw text) | 霞鹜文楷 LXGW WenKai | 400 | The same literary warmth carries the italic-quote moment; Chinese has no italic so the face does the expressive work |
| Stat figure (4.5vw, coral) | 霞鹜文楷 LXGW WenKai | 400 | Keeps stat figures in the Playfair register; the coral color carries the accent |
| Watermark numeral (18vw) | 霞鹜文楷 LXGW WenKai | 400 | The 6%-opacity watermark works at this scale with LXGW WenKai's open letterforms |
| Body / lede (Jost roles, 1.05–1.45vw) | 思源宋体 Noto Serif SC | 300–400 | Mincho body voice — calm, literary, sits back like Jost weight 300 |
| Label / kicker / chapter-num (JetBrains Mono roles) | 思源等宽 Noto Sans Mono CJK SC | 300–400 | Preserves the typewriter-chrome quality for kickers and footlines |
### Mixed-Content Strategy
Use **Strategy C** — keep Playfair Display as the Latin serif and let CJK glyphs fall through to LXGW WenKai. Playfair Display weight 400 (never bold) is the system's most important typographic commitment; replacing it with a CJK serif wholesale would break the monograph / boutique-brand-book register that defines Grove. The system already loads Noto Serif SC / Noto Sans SC as fallbacks per its existing font stack — the change is to add LXGW WenKai as the preferred CJK display face ahead of Noto Serif SC:
```css
/* Playfair roles (display, h1, h2, h3, quote, stat, watermark) */
font-family: 'Playfair Display', 'LXGW WenKai TC', 'Noto Serif SC', Georgia, serif;
/* Jost roles (lead, body, caption) */
font-family: 'Jost', 'Noto Serif SC', system-ui, sans-serif;
/* JetBrains Mono roles (label, kicker, chapter-num, stat-label) */
font-family: 'JetBrains Mono', 'Noto Sans Mono CJK SC', monospace;
```
(Note: the system currently lists `'Noto Sans SC'` in the Jost stack — for Grove's literary register, swap to `'Noto Serif SC'` instead. The Mincho body voice is closer to Jost weight 300's "good paper" feel than the Hei sans face.)
Baseline mismatch at display sizes (5.5–10vw) is mild — LXGW WenKai and Playfair Display both sit at similar optical baselines, so mixed-script headlines like `A Quiet 山林` read cleanly. The `<em>` italic-coral accent rule is the more delicate piece (see Known CJK Gap below).
### Loading
Replace the existing Noto-only fallback with an LXGW WenKai + Noto Serif SC + Noto Sans Mono CJK pair:
```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=LXGW+WenKai+TC&family=Noto+Serif+SC:wght@300;400;500&family=Noto+Sans+Mono+CJK+SC:wght@300;400&display=swap" rel="stylesheet">
```
LXGW WenKai TC is the version hosted on Google Fonts (covers both traditional and simplified glyphs).
### Universal CJK Adjustments
These adjustments apply to **every CJK block** in this system, regardless of size or role:
- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (1.0–1.1 on display, 1.65–1.75 on body) read as cramped in Chinese. Bump display to 1.15–1.25 and body to 1.7–1.85.
- **Remove negative letter-spacing on CJK headlines.** Playfair Display uses -0.01em to -0.03em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the JetBrains Mono portion was meant to be capitalized.
- **Use Chinese full-width punctuation** (`,。:;!?「」『』()`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between LXGW WenKai and Noto Serif SC inside the same sentence — pick the face that matches the role (display = LXGW WenKai, body = Noto Serif SC) and commit to it for the whole run.
### Aesthetic Notes for This System
Grove's whole voice is "literary monograph / boutique brand book" with a single accent of terracotta coral. The Chinese equivalent of that quiet authority is **LXGW WenKai for every serif moment** (its hand-set warmth is the closest Chinese analog to Playfair Display at weight 400) and **Noto Serif SC at weight 300–400 for body** (the Mincho calm that matches Jost weight 300's reticence). Avoid running Chinese body in Noto Sans SC — the geometric sans tips the system from "good paper" to "modern app."
The em-dash bullet glyph in DM Mono coral works in Chinese without modification — the em-dash character itself is the same Unicode glyph (—) and reads as a deliberate mark in front of a Chinese list item. Keep the bullet column in Noto Sans Mono CJK SC at weight 300 coral, exactly mirroring the Latin pattern.
The watermark numeral (18vw, 6% opacity) is particularly effective in Chinese — render a Chinese ordinal character (e.g., 「三」or 「五」) instead of a Western digit. At 6% opacity it reads as faint compositional texture, and the Han glyph's denser visual weight at that scale balances the slide better than a thin Western numeral would.
### Known CJK Gap
The system's signature `<em>` italic-coral treatment is the hardest piece to translate: **Chinese has no italic concept** — slanted Han glyphs read as broken, not as emphasis. The current Grove CSS depends on the browser's default `<em>` styling (italic) plus a CSS color rule for the coral. In Chinese, the italic does nothing visually, so the emphasis collapses to "just coral text inside a headline." That's not bad — coral inside an LXGW WenKai headline still reads as a deliberate accent — but the system loses one of its two emphasis dimensions (color + slant) and is left with only color.
To compensate, two options: (1) accept color-only emphasis on Chinese headlines and let the coral carry the weight, or (2) switch the `<em>` portion to a different face inside Chinese headlines — e.g., **站酷小薇体 (ZCOOL XiaoWei)** — to provide a face-based contrast that approximates the slant contrast of Latin italic. Add to the CSS:
```css
.h1 em, .h2 em, .h3 em, .quote-text em {
color: var(--c-accent);
font-family: 'Playfair Display', 'ZCOOL XiaoWei', 'LXGW WenKai TC', serif;
font-style: italic; /* Latin renders italic; CJK ignores */
}
```
This gives the Latin portion italic-coral and the CJK portion face-shift-coral. Test on a per-deck basis — for many Grove decks, color-only emphasis is sufficient.
## Iteration Guide
1. Any new headline is Playfair Display weight 400. Pick the size from the headline ladder (10vw display / 5.5vw h1 / 3.2vw h2 / 2vw h3) — do not invent a new size.
2. Any new emphasis inside a headline uses `<em>` and renders as italic coral automatically. Do not author a manual color/italic style.
3. Any new body paragraph is Jost weight 300 at 1.05vw (or 1.45vw for lede, or `max(1.4vw, 17px)` on list-style slides).
4. Any new label / kicker / footline / counter / caption is JetBrains Mono weight 300 uppercase with at least 0.12em letter-spacing.
5. Any new chrome line (top bar, bottom bar, section divider, stat-card border) is a 1px solid hairline in `{colors.border}` (dark) or `{colors.border-light}` (light). No thicker borders.
6. Any new bullet list uses the `{components.bullet-list}` pattern (two-column grid, em-dash in coral mono). Do not author a different bullet style.
7. Any new accent moment uses `{colors.accent}` terracotta coral. The accent is for italic headline emphasis, the 36px rule, em-dashes, stat figures, quote marks, chapter ordinals, and the kicker text. Nothing else.
8. Any new chapter or section-opener slide carries a `{components.grove-num}` watermark numeral in the bottom-right corner.
9. Any new content element gets a `[data-anim]` attribute (fade-up, fade-in, reveal-right, reveal-left, or scale-in) plus a `[data-delay]` (0–6) for staggered entrance. Do not author custom transitions.
10. When in doubt, add space rather than content. Grove's editorial register is silence, not density.
## Known Gaps
- The four Google Fonts (Playfair Display, Jost, JetBrains Mono, Noto Serif SC / Noto Sans SC) are loaded via `<link>`. Offline rendering will fall back to Georgia, system-ui, monospace, and system serif/sans for the Noto roles — which preserves the rough character but loses the typographic identity. Self-hosting recommended for offline / print reliability.
- The system loads Playfair weight 500 and Jost weights 200/400/500 — these are not used in the published CSS but are available. Using them would break the system's single-weight commitment.
- The `<em>` italic-coral treatment relies on the CSS rule `.h1 em, .h2 em, .h3 em { color: var(--c-accent); }` — note that the actual italic property is NOT set in the rule (the comment block is empty). The italic comes from the browser's default `<em>` styling. If a stylesheet override removes the default italic, the coral accent will lose its italic character.
- The grove-num watermark uses 18vw font-size — on extremely wide viewports (3000px+) this becomes very large and may push the slide-foot area. The CSS positions it at `bottom: -0.15em` to absorb some overflow, but very tall numerals at very wide viewports may need adjustment.
- The vertical sidebar component (`.grove-sidebar`) is loaded in the CSS but explicitly disabled (`display: none !important`). It was a chapter-tab decoration that read as clutter; the slide-chrome bar provides the section name already.
- The fixed slide-counter (`#slide-counter`) is also disabled — the slide-foot bar already shows "NN / TT" so the fixed counter was a duplicate.
- The CSS has a few empty rule blocks (`.h1 em { }`, `.grove-stat-val em { }`, `.quote-text { ... }`) which appear to be leftover stubs from earlier iterations. They are inert and can be removed without effect.
- The deck is built bilingually-aware (Chinese fallbacks via Noto Serif SC / Noto Sans SC) but no actual Chinese content is in the published source — the bilingual support is structural, not active.
- The image-placeholder component is a layout reservation, not a real image. Replacing the placeholder div with an `<img>` requires manually matching the parent's flex behavior and background.
# Grove Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/grove/design.md`
- Preview card: `bold-template-pack/templates/grove/preview.md`
## Selection Metadata
- Slug: `grove`
- Tagline: Forest-green canvas with cream type, classical Playfair serifs, and a single rust accent.
- Mood: organic, considered, warm, literary, natural
- Tone: classical, warm, considered, patient
- Formality: medium-high
- Density: medium
- Scheme: mixed
- Best for: Anything that should feel organic, considered, and grown-up: sustainability and wellness brands, outdoor / nature products, wineries and restaurants, literary or arts decks, advisory deliverables, bilingual EN/CN reports. Also a calm, distinctive choice for tech, research, or business decks that want patience over urgency.
- Avoid for: Decks that need neon energy or rapid-fire pop — the forest-green canvas and Playfair serif commit to a slow, classical voice.
## Visual Snapshot
A quiet, editorial-serif presentation system in the register of a well-bound monograph or boutique brand book. Playfair Display at weight 400 (never bold) carries every headline, italicized in terracotta coral for accent emphasis as the signature move. Jost weight 300 carries every paragraph as the "good paper" body face. JetBrains Mono at weight 300 holds labels, kickers, and the thin chrome bars. The palette pairs a deep forest green canvas (#192b1b) with warm cream text (#d4cfbf) and a single terracotta coral accent (#c8524a). Generous negative space, hairline 1px borders, and a near-invisible serif watermark numeral give it the calm authority of a literary journal.
Grove is a quiet, editorial-serif presentation system in the register of a literary monograph or boutique brand book. The foundational premise is restraint: every slide carries one focused content moment surrounded by deep negative space, anchored by thin 1px chrome bars at top and bottom and supported by a small library of compositional beats (coral kicker, 36px coral rule, italic-coral accent, em-dash bullet, near-invisible watermark numeral).
## Preview Ingredients
- Palette: bg #192B1B; bg-alt #1E3221; bg-light #E8E4D6; bg-light-alt #DEDAD0; fg #D4CFBF; fg-light #192B1B; accent #C8524A
- Typography: See full design doc after selection.
- Signature move: Playfair Display at weight 400 carries every headline, every quote, every stat figure, and every watermark numeral. Bold serif is not permitted — the no-bold rule is the system's most important typographic commitment. Italicized Playfair in {colors.accent} co...
- Signature move: Jost at weight 300 carries every paragraph and bullet body. The light weight is the "good paper" feel — it sits back and lets the serif lead.
- Signature move: JetBrains Mono at weight 300 carries every label, kicker, footline, slide counter, and stat caption. Always uppercase, always with at least 0.12em letter-spacing.
- Signature move: Noto Serif SC / Noto Sans SC at weight 300–500 are loaded as Chinese fallbacks for every role. The deck is built bilingually-aware — Chinese characters render through the Noto cuts when present in the content.
- Signature move: Playfair Display at weight 400 — never bold — for every serif moment. Italic in {colors.accent} is the headline accent.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Long Table
description: A warm, single-ink editorial system in the register of a supper-club poster, a small-batch zine, or a Risograph-printed program. The entire system runs in one ink color — a warm rust terracotta (#B53D2A) — on a buttery cream paper ground (#FAF1E2), with a subtle 4px radial-dot texture overlay giving the surface its "printed paper" quality. Display type runs in Bricolage Grotesque at weight 700–800 in uppercase; body and metadata run in Fraunces serif at weight 400–600 with optical-size axis engaged. Pill buttons, outlined edition badges, italic-edition numerals, and dashed/solid 1.5px borders complete the printed-program vocabulary.
colors:
paper: "#FAF1E2"
paper-d: "#F2E5CF"
paper-vd: "#E8D7B6"
ink: "#B53D2A"
ink-dp: "#8E2D1F"
rule: "#B53D2A"
ink-32: "rgba(181, 61, 42, 0.32)"
ink-78: "rgba(181, 61, 42, 0.78)"
ink-50: "rgba(181, 61, 42, 0.5)"
color-aliases:
rule: ink
ink-32-canonical: "Same ink #B53D2A at 32% opacity, used for dashed dividers and subtle internal rules"
ink-78-canonical: "Same ink #B53D2A at 78% opacity, used for de-emphasized metadata"
typography:
display-jumbo-numeral:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(180px, min(22vw, 38vh), 480px)"
fontWeight: 400
lineHeight: 0.86
letterSpacing: -0.02em
fontStyle: italic
display-cover:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(82px, min(8.8vw, 15vh), 180px)"
fontWeight: 800
lineHeight: 0.92
letterSpacing: -0.012em
textTransform: uppercase
display:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(72px, min(7.6vw, 13vh), 160px)"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.012em
textTransform: uppercase
headline-xl:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(60px, min(6.4vw, 10.5vh), 140px)"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.012em
textTransform: uppercase
headline:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(56px, min(6vw, 10vh), 120px)"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.012em
textTransform: uppercase
headline-md:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(48px, min(5vw, 8.4vh), 100px)"
fontWeight: 800
lineHeight: 0.92
letterSpacing: -0.012em
textTransform: uppercase
quote:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(40px, min(4.4vw, 7.4vh), 96px)"
fontWeight: 700
lineHeight: 0.95
letterSpacing: -0.012em
textTransform: uppercase
card-title:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(28px, 2.4vw, 44px)"
fontWeight: 800
lineHeight: 0.95
letterSpacing: -0.008em
textTransform: uppercase
course-name:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(20px, 1.5vw, 28px)"
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.005em
textTransform: uppercase
info-value:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(20px, 1.6vw, 28px)"
fontWeight: 700
lineHeight: 1.1
letterSpacing: -0.005em
textTransform: uppercase
edition-label-tracked:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(15px, 1.1vw, 18px)"
fontWeight: 700
letterSpacing: 0.18em
textTransform: uppercase
who-tag:
fontFamily: "'Bricolage Grotesque', sans-serif"
fontSize: "clamp(15px, 1.05vw, 18px)"
fontWeight: 700
letterSpacing: -0.005em
textTransform: uppercase
body-serif-italic-lg:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(20px, 1.5vw, 28px)"
fontWeight: 400
lineHeight: 1.45
fontStyle: italic
body-serif-italic:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(17px, 1.2vw, 22px)"
fontWeight: 400
lineHeight: 1.5
fontStyle: italic
body-roman:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(15px, 1vw, 17px)"
fontWeight: 400
lineHeight: 1.45
edition-label:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(20px, 1.6vw, 30px)"
fontWeight: 400
lineHeight: 1
fontStyle: italic
tagline:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(18px, 1.4vw, 26px)"
fontWeight: 400
lineHeight: 1.35
fontStyle: italic
stats:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(17px, 1.2vw, 22px)"
fontWeight: 400
lineHeight: 1.4
fontStyle: italic
pill-text:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(15px, 1.1vw, 20px)"
fontWeight: 400
lineHeight: 1
fontStyle: italic
meta-tag:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(14px, 0.95vw, 16px)"
fontWeight: 400
lineHeight: 1.4
fontStyle: italic
info-key:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(14px, 0.95vw, 16px)"
fontWeight: 400
letterSpacing: 0.16em
textTransform: uppercase
fontStyle: italic
pagenum:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(14px, 0.95vw, 16px)"
fontWeight: 400
letterSpacing: 0.02em
fontStyle: italic
nav-hint:
fontFamily: "'Fraunces', Georgia, serif"
fontSize: "clamp(11px, 0.78vw, 13px)"
fontWeight: 400
letterSpacing: 0.02em
fontStyle: italic
spacing:
slide-pad-h-default: "clamp(60px, 5vw, 110px)"
slide-pad-h-wide: "clamp(80px, 7vw, 160px)"
slide-pad-h-narrow: "clamp(120px, 12vw, 280px)"
slide-pad-top-default: "clamp(96px, 10vh, 160px)"
slide-pad-top-cover: "clamp(60px, 6vh, 100px)"
slide-pad-bottom-default: "clamp(110px, 11vh, 170px)"
slide-pad-bottom-wide: "clamp(150px, 14vh, 220px)"
gap-section: "clamp(28px, 3vh, 50px)"
gap-content: "clamp(18px, 2vh, 32px)"
gap-row: "clamp(14px, 1.6vh, 24px)"
gap-tight: "clamp(10px, 1.2vh, 18px)"
border-weight: "1.5px"
rule-dashed-color: "{colors.ink-32}"
canvas:
width: 100vw
height: 100vh
components:
pill:
description: "Outlined rounded-rectangle (border-radius 999px → fully pill) holding short italic Fraunces text. The system's CTA / action button. Border is 1.5px solid {colors.ink}; padding is generous (~12px / 28px); text-color is {colors.ink}."
border: "1.5px solid {colors.ink}"
borderRadius: "999px"
padding: "clamp(8px, 1vh, 14px) clamp(20px, 2vw, 32px)"
typography: "{typography.pill-text}"
pill-divider:
typography: "{typography.pill-text}"
opacity: 0.7
description: "A small italic Fraunces divider character (typically · or /) used inline between adjacent pills."
ed-badge:
description: "A small circular outlined badge (~38px) holding a single italic Fraunces digit. The edition / chapter ordinal marker. Border is 1.5px solid {colors.ink}; background is transparent."
width: "clamp(34px, 2.6vw, 44px)"
height: "clamp(34px, 2.6vw, 44px)"
border: "1.5px solid {colors.ink}"
borderRadius: "50%"
rect-tag:
description: "Outlined rectangular tag — like the pill but with sharp corners. Holds short italic Fraunces text. Used as a category / status / metadata chip when the pill's roundness isn't appropriate."
border: "1.5px solid {colors.ink}"
padding: "clamp(7px, 0.9vh, 12px) clamp(14px, 1.4vw, 22px)"
typography: "{typography.pill-text}"
card-outlined:
description: "A 1.5px ink-outlined rectangular content card. Holds a card-top metadata row (separated below by a 1px @ 32%-opacity rule), a Bricolage card-name, a Fraunces body description, and a meta-row at the bottom (separated above by a 1px dashed @ 32%-opacity rule). The system's primary content card pattern."
border: "1.5px solid {colors.ink}"
padding: "clamp(20px, 2vh, 32px) clamp(20px, 1.8vw, 30px)"
internalDivider-solid: "1px solid {colors.ink-32}"
internalDivider-dashed: "1px dashed {colors.ink-32}"
paper-texture:
description: "Subtle radial-dot texture overlay on the stage. A 4px-tile background-image of 0.5px radial-gradient dots in {colors.ink-50} at 10% opacity. Sits absolutely on the stage with pointer-events disabled, giving the paper its Risograph / printed-stock quality. This is on every slide."
backgroundImage: "radial-gradient(circle at 1px 1px, {colors.ink-50} 0.5px, transparent 1px)"
backgroundSize: "4px 4px"
opacity: 0.1
topbar-divider:
description: "A 1.5px ink solid border-bottom under a slide topbar (where a Bricolage headline sits beside a small Fraunces label). The horizontal rule beneath the topbar is the system's universal page-divider device."
borderBottom: "1.5px solid {colors.ink}"
pagenum:
position: "absolute"
placement: "right: clamp(36px, 3.6vw, 80px); bottom: clamp(40px, 4vh, 64px)"
typography: "{typography.pagenum}"
color: "{colors.ink}"
description: "Italic Fraunces page number at the bottom-right of every slide."
nav-hint:
position: "fixed"
placement: "left: clamp(36px, 3.6vw, 80px); bottom: clamp(40px, 4vh, 64px)"
typography: "{typography.nav-hint}"
color: "{colors.ink}"
opacity: 0.45
description: "A faint italic Fraunces hint string at the bottom-left of the viewport (e.g. '← → to navigate'). Bonus interactivity affordance."
ledger-row:
description: "A horizontal ledger-style row in a calendar/schedule context. Multi-column grid (typical: 80px / 130px / 1.6fr / 0.9fr / auto) with a 1px @ 32%-opacity ink border-bottom. Each cell is a tag, label, or pill. Reads as a guestbook / restaurant-reservation log."
rowPad: "clamp(11px, 1.3vh, 18px) 0"
borderBottom: "1px solid {colors.ink-32}"
---
## 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
Long Table is a **single-ink editorial system** in the register of a supper-club poster, a Risograph zine, or a small-press dinner program. The foundational premise is monochromatic: every visible mark in the system — every headline, every paragraph, every border, every rule, every pill, every page number — is rendered in a single warm rust terracotta ink (`{colors.ink}` — #B53D2A) on a buttery cream paper ground (`{colors.paper}` — #FAF1E2). The only chromatic variation is opacity: the same ink at 100% for primary marks, at 78% for de-emphasized metadata, at 32% for dashed internal dividers, at 10% for the paper-texture dots.
The single-ink constraint is the system's identity. The aesthetic borrows from one-color screen printing, letterpress posters, and Risograph stationery — formats where each additional color is a separate printing pass and therefore a deliberate decision. By committing to one ink, the system achieves the calm authority of a printed object rather than the polish of a digital surface.
A signature **paper-texture overlay** sits on every slide: a 4px-tile radial-dot pattern in 50%-opacity ink at 10% opacity, applied via the `.stage::before` pseudo-element. The dots are invisible at conversational viewing distance but visible up close — they give the cream surface its "printed paper" feel and are an essential part of the design system, not optional decoration.
The typographic stack is a two-face pairing:
- **Bricolage Grotesque** at weights 700 and 800 in **strict uppercase** carries every display moment — covers, headlines, card titles, course names, quote bodies, info values, who-tags. Bricolage is a wide, slightly-condensed grotesque with strong personality; its uppercase set has the impact of a hand-lettered poster. The optical-size axis (`opsz` 12..96) is engaged.
- **Fraunces** at weight 400–600 carries every body paragraph, every metadata field, every pill, every page number, every edition label. **Italic Fraunces is the default body style** — the slanted serif is the system's body voice, lending warmth and editorial personality. Roman Fraunces appears only for specific tight cases (info keys, the description body inside index cards). The optical-size axis (`opsz` 9..144) is engaged for both styles.
A massive **italic Fraunces edition numeral** at up to 480px is the system's signature display anchor — it replaces the hand-drawn illustration that would traditionally fill the cover/featured slide right-half, giving the slide a typographic centerpiece in the same ink as the rest of the page.
Depth is **flat and printed**. There are no shadows, no gradients, no blur, no glow. Elevation is communicated entirely through 1.5px solid ink borders on cards, badges, pills, and tags; 1px solid or 1px-dashed internal dividers at 32% opacity; and the texture overlay's atmospheric quality. The whole system reads as ink soaked into paper.
**Density philosophy: rich-but-curated.** Long Table reads as authoritative when slides carry substantive content — a cover with a hero title plus a tagline plus action pills plus stats plus a big edition numeral; an index slide with a topbar headline plus three rich cards; a menu slide with five course rows with name + description + pairing. The slides are full but never crowded — each region carries one focused element with breathing room around it. A slide that holds only a headline reads as missing-its-program; a slide that holds 8 competing content blocks reads as broken. Reach for one major typographic moment (Bricolage display) anchored by 2–4 supporting groups (cards, pills, ledger rows, info-value pairs) per slide.
**Key Characteristics:**
- One ink color (`{colors.ink}` — warm rust terracotta) on cream paper (`{colors.paper}`). Opacity variants are the only color variation.
- Bricolage Grotesque weight 700–800 uppercase for every display moment; Fraunces 400–600 italic-default for every body and metadata moment.
- Subtle 4px radial-dot paper texture on every slide via `.stage::before` — invisible at distance, present up close.
- Pill buttons (border-radius 999px), edition badges (circular), rect-tags (sharp-cornered), and outlined cards (1.5px solid) — all single-weight ink outlines, no fills.
- A massive italic Fraunces edition numeral (up to 480px) is the system's hero typographic anchor on cover-class slides.
- 1.5px structural borders, 1px @ 32%-opacity solid or dashed internal dividers. No thicker borders, no shadows.
- Page number (italic Fraunces) at every slide's bottom-right; nav-hint (italic Fraunces at 45% opacity) at the bottom-left.
- The system is single-ink by design — adding any second color (a navy, a green, a yellow) shatters the printed-program register.
## Colors
### Palette
- **Paper / Cream** (`{colors.paper}` — #FAF1E2): The dominant warm buttery cream surface. Reads as good-quality paper stock — not white, not beige, somewhere between. The default slide background, and the only background fill the system uses.
- **Paper Dark** (`{colors.paper-d}` — #F2E5CF): A slightly darker cream for secondary surfaces or tonal separation. Available in the token system but used sparingly.
- **Paper Very Dark** (`{colors.paper-vd}` — #E8D7B6): A deeper cream for accent surfaces. Reserved.
- **Ink / Warm Rust Terracotta** (`{colors.ink}` — #B53D2A): The single ink color. Every text run, every border, every rule, every pill outline, every page number — all in this one color. The system's structural and expressive color.
- **Ink Deep** (`{colors.ink-dp}` — #8E2D1F): A deeper rust reserved for emphasis. Available in the token system but used sparingly in the published slides.
- **Rule** (`{colors.rule}` — #B53D2A): An alias for `{colors.ink}` — same hex, used semantically when referring to a rule line.
- **Ink @ 78%** (`{colors.ink-78}` — rgba(181,61,42,0.78)): The ink at 78% opacity. Used for de-emphasized metadata text where slightly lower contrast is desired (e.g., pairing notes in menu rows, meta-tags under quotes).
- **Ink @ 50%** (`{colors.ink-50}` — rgba(181,61,42,0.5)): The ink at 50% opacity. Used inside the paper-texture radial-dot gradient.
- **Ink @ 32%** (`{colors.ink-32}` — rgba(181,61,42,0.32)): The ink at 32% opacity. Used for internal dividers — solid 1px lines and 1px dashed lines inside cards, between ledger rows, between course rows.
### Defaults
- **Default slide background**: `{colors.paper}`. Every slide. There is no alternate surface in this system.
- **Default text color**: `{colors.ink}`. Every text run.
- **Default border color**: `{colors.ink}` at 1.5px solid for structural borders; `{colors.ink-32}` at 1px solid or dashed for internal dividers.
- **Default headline color**: `{colors.ink}`.
- **Default body color**: `{colors.ink}`.
- **Default page-number / nav-hint color**: `{colors.ink}` (full opacity for pagenum; 45% opacity for nav-hint).
- **Default de-emphasized metadata color**: `{colors.ink-78}` — when a small piece of supporting text needs to recede from a primary line.
The palette is intentionally single-ink. There is no "accent color" to reach for — the design language depends on the one-ink constraint. If a moment needs to stand out, scale up the type (Bricolage 800 at 180px) or reach for the italic Fraunces edition numeral; do not introduce a second color.
## Typography
### Font Family
The system loads exactly two web fonts from Google Fonts, both with optical-size axes:
- **Bricolage Grotesque** with `opsz` 12..96 and weights 400, 600, 700, 800. **In the published slides, only 700 and 800 are used.**
- **Fraunces** with `opsz` 9..144, both roman and italic styles, weights 400, 500, 600. **In the published slides, all three weights of italic and weight 400/600 of roman are used.**
The two-face role split is strict: **Bricolage uppercase carries every display moment** (covers, headlines, card titles, course names, quote bodies, info values, who-tags, edition labels with tracking). **Fraunces italic carries every body moment** (paragraphs, leads, metadata, taglines, pills, page numbers, info keys, edition labels without tracking). **Fraunces roman** is reserved for specific tight roles (info keys in info-rows where italic tracking would feel out of place, and the description body inside index cards where roman is more readable).
The optical-size axis is critical: the same Fraunces face renders with subtly different letterforms at 14px metadata sizes versus 480px hero-numeral sizes — small sizes pick up sturdier strokes; large sizes pick up finer detail. Self-hosted fallbacks without `opsz` will lose this quality.
### Display, Body, and Chrome Scale
| Token | Size | Family | Weight / Style | Use |
|---|---|---|---|---|
| `{typography.display-jumbo-numeral}` | up to 480px | Fraunces | 400 italic | Hero edition numeral (cover-class typographic anchor) |
| `{typography.display-cover}` | up to 180px | Bricolage | 800 uppercase | Cover-scale Bricolage title |
| `{typography.display}` | up to 160px | Bricolage | 800 uppercase | Section-opener / manifesto headline |
| `{typography.headline-xl}` | up to 140px | Bricolage | 800 uppercase | Featured-edition title |
| `{typography.headline}` | up to 120px | Bricolage | 800 uppercase | Topbar headline on index / calendar slides |
| `{typography.headline-md}` | up to 100px | Bricolage | 800 uppercase | Menu / programme title |
| `{typography.quote}` | up to 96px | Bricolage | 700 uppercase | Pull-quote / testimonial body |
| `{typography.card-title}` | up to 44px | Bricolage | 800 uppercase | Title inside an outlined card |
| `{typography.course-name}` | up to 28px | Bricolage | 700 uppercase | Course / item name in a ledger row |
| `{typography.info-value}` | up to 28px | Bricolage | 700 uppercase | Value in a key/value info row |
| `{typography.edition-label-tracked}` | up to 18px | Bricolage | 700 uppercase / 0.18em | Big-edition label beneath a hero numeral |
| `{typography.who-tag}` | up to 18px | Bricolage | 700 uppercase | Attribution name in a quote row |
| `{typography.body-serif-italic-lg}` | up to 28px | Fraunces | 400 italic | Lead paragraph in a manifesto / letter |
| `{typography.body-serif-italic}` | up to 22px | Fraunces | 400 italic | Standard body paragraph / lede |
| `{typography.body-roman}` | up to 17px | Fraunces | 400 roman | Card description body (tighter setting for legibility at small size) |
| `{typography.edition-label}` | up to 30px | Fraunces | 400 italic | "EDITION N." italic label beside an edition badge |
| `{typography.tagline}` | up to 26px | Fraunces | 400 italic | Tagline / subtitle beneath a cover title |
| `{typography.stats}` | up to 22px | Fraunces | 400 italic | Stats line ("N seats · M cities · L hours") |
| `{typography.pill-text}` | up to 20px | Fraunces | 400 italic | Text inside a pill button or rect-tag |
| `{typography.meta-tag}` | up to 16px | Fraunces | 400 italic | Card metadata (city tag, num tag, seats tag, date tag) |
| `{typography.info-key}` | up to 16px | Fraunces | 400 italic / 0.16em / UPPER | Key in a key/value info row |
| `{typography.pagenum}` | up to 16px | Fraunces | 400 italic | Page number at the bottom-right of every slide |
| `{typography.nav-hint}` | up to 13px | Fraunces | 400 italic / 45% opacity | Navigation hint at the bottom-left of the viewport |
### Defaults
- **Default size for a primary slide headline**: `{typography.headline}` (up to 120px) in Bricolage 800 uppercase.
- **Default size for a cover-scale title**: `{typography.display-cover}` (up to 180px).
- **Default size for the hero typographic anchor on cover-class slides**: `{typography.display-jumbo-numeral}` (italic Fraunces up to 480px) — the system's signature hero element.
- **Default size for a body paragraph**: `{typography.body-serif-italic}` (up to 22px) in italic Fraunces.
- **Default size for a lede paragraph**: `{typography.body-serif-italic-lg}` (up to 28px).
- **Default size for body text inside a card**: `{typography.body-roman}` (up to 17px) in **roman** Fraunces — the roman is more readable at small sizes than italic.
- **Default size for an "EDITION N." label**: `{typography.edition-label}` (up to 30px) in italic Fraunces, paired with an `{components.ed-badge}` circular ordinal.
- **Default weight for any Bricolage display moment**: 800. (Weight 700 is reserved for the quote body and course/who-tag elements; weight 800 is the primary display weight.)
- **Default weight for any Fraunces body moment**: 400.
When unsure, reach for `{typography.headline}` (up to 120px) for a routine slide headline. The 140–180px tier is for featured-edition titles and covers; the 160px tier is for section openers. Use the jumbo edition numeral when the slide is a cover-class moment and needs a hero anchor.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Bricolage display element is UPPERCASE with negative letter-spacing (-0.005em to -0.012em).** A sentence-case Bricolage headline does not exist in this system. The uppercase + negative-tracking + weight 800 combination is the system's display voice.
- **Every Fraunces body element is italic by default.** Roman Fraunces appears only for specific tight cases (info-key in info-rows, body inside index cards). When in doubt, italic.
- **The edition badge (`{components.ed-badge}`) is always paired with an italic edition label** — the circle ordinal and the "EDITION N." text are one unit. Using one without the other reads as broken.
- **Every card / pill / rect-tag / badge carries a 1.5px solid ink border with no fill.** The single-weight outlined-shape vocabulary is the system's structural language. Filled shapes do not exist.
- **The paper-texture overlay (`{components.paper-texture}`) is on every slide.** Removing it (or running the system on a pure flat cream without texture) loses the printed-paper quality.
- **Every slide carries the page-number marker** at bottom-right in italic Fraunces. The page-number is the system's spine — without it, slides feel unanchored.
- **Internal dividers inside cards alternate between 1px solid @ 32% opacity (above content) and 1px dashed @ 32% opacity (below content).** The solid/dashed pairing is the system's card-rhythm device.
### Typography Principles
The weight 800 + uppercase + negative letter-spacing combination is the system's Bricolage voice. Switching any of those three properties (e.g., weight 700 uppercase, or weight 800 sentence case, or default tracking) reads as a different design system. The Fraunces italic-default + opsz-axis combination is the system's body voice — using a non-opsz fallback face flattens the quality at small sizes.
Underline is not used. Bold within body paragraphs uses Fraunces weight 600 (not 700/800). Color emphasis does not exist because there is only one color. The system's only emphasis mechanisms are: scale (bigger Bricolage), weight shift inside body (Fraunces 400 → 600), italic ↔ roman switch, and opacity (full → 78%).
## Layout
### Canvas System
The system targets a fluid viewport — each `.slide` is `100vw × 100vh` with absolute positioning. Slides stack inside a `.stage` container with the paper-texture overlay sitting absolutely on the stage. Only one `.slide.active` is visible at a time; opacity transitions between slides take 280ms.
### Padding Scale (uses `clamp()` ranges)
| Token | Range | Use |
|---|---|---|
| `{spacing.slide-pad-h-default}` | clamp(60px, 5vw, 110px) | Default horizontal slide padding |
| `{spacing.slide-pad-h-wide}` | clamp(80px, 7vw, 160px) | Wider horizontal padding for featured / calendar slides |
| `{spacing.slide-pad-h-narrow}` | clamp(120px, 12vw, 280px) | Narrow horizontal padding for menu / quote slides (forces content into a column) |
| `{spacing.slide-pad-top-default}` | clamp(96px, 10vh, 160px) | Default top padding |
| `{spacing.slide-pad-top-cover}` | clamp(60px, 6vh, 100px) | Cover top padding (less, to give the title room) |
| `{spacing.slide-pad-bottom-default}` | clamp(110px, 11vh, 170px) | Default bottom padding (leaves room for page-num chrome) |
| `{spacing.slide-pad-bottom-wide}` | clamp(150px, 14vh, 220px) | Wider bottom padding for featured / quote slides |
| `{spacing.gap-section}` | clamp(28px, 3vh, 50px) | Between major content sections |
| `{spacing.gap-content}` | clamp(18px, 2vh, 32px) | Between related content blocks |
| `{spacing.gap-row}` | clamp(14px, 1.6vh, 24px) | Between row-level elements (course rows, ledger rows) |
| `{spacing.gap-tight}` | clamp(10px, 1.2vh, 18px) | Between tightly coupled elements |
### Chrome Anatomy
Every slide carries a **page-number marker** at the bottom-right (italic Fraunces, ~16px max). The viewport also carries a **nav-hint** at the bottom-left (italic Fraunces, 45% opacity), suggesting keyboard navigation. These two chrome elements are the system's universal slide anchors.
Slides with a topbar (index, calendar) carry a Bricolage headline on the left + a small italic Fraunces label-tag on the right, separated below by a 1.5px solid ink horizontal rule. The topbar-divider is the system's universal page-divider device.
### Border-Radius
- **999px** — pill buttons (fully pill-shaped)
- **50%** — circular edition badges
- **0** — every other shape (cards, rect-tags, info-cards, ledger rows, internal dividers)
The system uses sharp corners for content containers and pill/circle for action and ordinal markers. No medium border-radius values (4px, 8px, 12px) exist.
## Depth and Elevation
### Flat, No Shadows
The system uses **zero shadows**. No box-shadow, no text-shadow, no filter, no gradient. Elevation is communicated entirely through:
1. **1.5px solid ink borders** on cards, pills, badges, rect-tags — the outlined-shape vocabulary is the system's structural depth.
2. **1px solid or dashed internal dividers at 32% opacity** inside cards and between rows — the subtle horizontal lines give cards their internal rhythm.
3. **The paper-texture overlay** at 10% opacity on every slide — the dotted texture sits atmospherically beneath all content, giving the page its print-stock quality.
4. **Opacity layering on text** — primary at 100%, de-emphasized metadata at 78%, near-invisible dividers at 32%.
The absence of shadow is itself the depth language. Adding `box-shadow: 0 4px 12px rgba(0,0,0,0.1)` shatters the printed-paper feel.
### Paper Texture as Atmospheric Depth
The radial-dot texture on `.stage::before` is part of the depth system — it is not optional decoration. The texture gives the cream surface a quality that flat #FAF1E2 lacks: a sense that the surface is paper stock with grain, not a CSS background fill. The 4px tile size with 0.5px radial dots in 50%-opacity ink at 10% overall opacity is calibrated to be invisible at conversational viewing distance and just-visible at close inspection.
## Shapes and Treatment
### Border Weight and Style
- **1.5px solid `{colors.ink}`** — the universal structural border. Cards, pills, edition badges, rect-tags, topbar dividers, who-row top borders, info-card outlines.
- **1px solid `{colors.ink-32}`** — internal solid dividers inside cards (between card-top metadata and the card title), between ledger rows, between course rows.
- **1px dashed `{colors.ink-32}`** — internal dashed dividers inside cards (between the card body and the meta-row at the bottom), between info-rows in info-cards.
Borders are never thicker than 1.5px. Never colored beyond ink (full or 32%). Never dotted (dotted is reserved for the paper-texture pattern). The solid/dashed pairing inside cards is the system's signature rhythm device.
### Decorative Element Types
**Paper Texture Overlay** (`{components.paper-texture}`) — A 4px-tile radial-dot pattern in 50%-opacity ink at 10% overall opacity on `.stage::before`. The system's atmospheric base; on every slide.
**Pill Button** (`{components.pill}`) — An outlined fully-rounded-rectangle (border-radius 999px) holding short italic Fraunces text. The system's CTA / action button. Pills cluster in action rows (e.g., cover action row).
**Pill Divider** (`{components.pill-divider}`) — A small italic Fraunces character (typically `·` or `/`) at 70% opacity placed between pills in a row.
**Edition Badge** (`{components.ed-badge}`) — A ~38px circular outlined badge holding a single italic Fraunces digit. The system's edition / chapter ordinal marker; always paired with an italic "EDITION N." label.
**Rect Tag** (`{components.rect-tag}`) — An outlined sharp-cornered rectangular tag holding short italic Fraunces text. The sharp-cornered cousin of the pill; used where roundness isn't appropriate.
**Outlined Card** (`{components.card-outlined}`) — A 1.5px ink-outlined rectangular card. Holds a card-top metadata row (separated below by a 1px @ 32% solid divider), a Bricolage card title, a Fraunces body description, and a meta-row at the bottom (separated above by a 1px @ 32% dashed divider). The system's primary content card.
**Topbar with Divider** — A Bricolage headline on the left + a small italic Fraunces label-tag on the right, separated below by a 1.5px solid ink horizontal rule. The system's universal section opener.
**Info-Card** — A wider outlined card with internal info-rows (key / value pairs separated by 1px @ 32% dashed dividers). Used as a featured-edition supporting panel.
**Ledger Row** (`{components.ledger-row}`) — A multi-column grid row with a 1px @ 32% solid border-bottom. Holds tags, labels, and pills aligned in columns. The system's calendar / schedule / index pattern.
**Course Row** — A 64px / 1fr / auto grid row with a 1px @ 32% solid border-bottom. Holds a Fraunces num-tag, an item (Bricolage name + Fraunces description), and a Fraunces pairing tag. The menu / programme pattern.
**Italic Jumbo Edition Numeral** — A massive italic Fraunces digit at up to 480px. The system's signature hero typographic anchor on cover-class slides, paired with a small tracked Bricolage label beneath and an italic Fraunces meta line.
**Page Number** (`{components.pagenum}`) — Italic Fraunces at the bottom-right of every slide.
**Nav Hint** (`{components.nav-hint}`) — Italic Fraunces at 45% opacity at the bottom-left of the viewport, suggesting keyboard navigation.
## Do's and Don'ts
### Do
- Commit to single-ink rendering. Every text, border, rule, badge, and pill is `{colors.ink}` — the warm rust terracotta. Use opacity (78%, 32%, 10%) for variation, never a different hue.
- Apply the paper-texture overlay to every slide. The 4px radial-dot pattern at 10% opacity is part of the design system, not optional polish.
- Run every Bricolage display element at weight 800 (or 700 for quote / course-name / who-tag) in strict uppercase with negative letter-spacing.
- Run every Fraunces body element in italic by default. Use roman only for info-keys (where italic tracking would feel out of place) and card body descriptions (where italic at small size is less readable).
- Reach for the italic Fraunces jumbo numeral (up to 480px) as the hero typographic anchor on cover-class slides. It's the system's signature.
- Pair every edition badge with an italic "EDITION N." Fraunces label — the circle ordinal and the text label are one unit.
- Use the outlined-card pattern (1.5px ink border + internal 1px @ 32% solid divider above content + 1px @ 32% dashed divider below content) for primary content cards. The solid/dashed pairing is the system's rhythm.
- Use the pill (border-radius 999px) and the rect-tag (sharp corners) intentionally — pill for actions, rect for metadata / status. Don't conflate them.
- Place the page-number marker (italic Fraunces, bottom-right) on every slide. The marker is the system's spine.
- Keep slides rich-but-curated: one major Bricolage display moment + 2–4 supporting groups (cards, pills, ledger rows, info pairs). Single-element slides feel underweight; 8-element slides feel broken.
### Don't
- Don't introduce a second ink color. The system is single-ink — adding a navy, green, yellow, or any second hue shatters the printed-program register.
- Don't fill any shape. Cards, pills, badges, rect-tags are outline-only. Filled rectangles in the ink color do not exist.
- Don't use box-shadow, gradient, blur, or filter on any element. The system is flat printed paper.
- Don't omit the paper-texture overlay. A flat #FAF1E2 background without the dot pattern reads as digital, not paper.
- Don't run Bricolage in sentence case. Bricolage is always uppercase with negative tracking and weight 700 or 800.
- Don't render Fraunces in roman by default. Italic is the body voice; roman is the exception for specific tight cases.
- Don't use thicker borders (2px+). The 1.5px structural border weight is the system's commitment.
- Don't use a medium border-radius (4px, 8px, 12px). The system uses 999px (pill), 50% (badge), or 0 (everything else).
- Don't pair the edition badge with a non-Fraunces label or skip the label entirely. The badge-and-label unit is the system's edition marker.
- Don't crowd a slide with 8 small elements. Reach for fewer, larger groups with breathing room.
## Responsive Behavior
The system uses **`clamp()` units throughout** — every size, padding, gap, and rule scales fluidly between minimum and maximum based on viewport width and height. The same composition renders correctly on a 1280×720 laptop, a 1920×1080 monitor, and a 2560×1440 display without media queries.
### Scaling Behavior
- Bricolage display sizes clamp between a min (e.g. 60px), a vw/vh-based middle value, and a max (e.g. 140px). The `min()` inner function combines width-based and height-based caps so headlines never overflow on short viewports.
- Fraunces body sizes follow the same pattern but with smaller ranges.
- Padding and gaps scale linearly with vw/vh.
- The 1.5px structural border and 1px @ 32% internal dividers are fixed-pixel and do not scale, which means at larger viewports the borders appear proportionally finer. This is by design.
### Presenter Behavior
- Slides advance via keyboard navigation (handled by deck JavaScript).
- Only one `.slide.active` is visible at a time; non-active slides are `opacity: 0; pointer-events: none`.
- Slide-to-slide transition is a 280ms opacity fade.
- The nav-hint at the bottom-left ("← → to navigate") tells the viewer how to advance.
### Print / Export
There is no `@media print` rule in the system. Print export will render only the active slide; multi-slide print requires per-slide rendering or a dedicated print stylesheet.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display / cover / headline (Bricolage roles, 96–180px) | 思源宋体 Noto Serif SC | 700 | Mincho heavy weight carries the printed-program mass that Bricolage 800 provides in Latin |
| Card title / course-name / info-value (28–44px) | 思源宋体 Noto Serif SC | 700 | Same Mincho voice at smaller sizes for consistency |
| Hero edition numeral (480px italic Fraunces) | 思源宋体 Noto Serif SC | 400 | Use a Chinese ordinal character (一二三 / 春夏秋) for the hero anchor instead of a Western digit |
| Body / lede / tagline (Fraunces italic roles) | 思源宋体 Noto Serif SC | 400 | Mincho body voice — warmth without italic, since Chinese has no italic |
| Pill text / meta-tag / pagenum | 思源宋体 Noto Serif SC | 400 | Keep all chrome in Mincho 400; the system's single-ink discipline carries through |
| Info-key / edition-label-tracked (uppercase tracked roles) | 思源宋体 Noto Serif SC | 400 with 0.16em letter-spacing | Maintains the tracked-chrome feel |
### Mixed-Content Strategy
Use **Strategy A** — switch the entire face stack to Noto Serif SC across all roles, replacing both Bricolage Grotesque (display) and Fraunces (body). Long Table is a minimal single-ink data / program system where the typographic personality is carried more by the **single-ink rust terracotta**, the **outlined-shape vocabulary**, and the **paper-texture overlay** than by the specific Latin faces. Going all-Mincho in Chinese preserves the printed-program register cleanly without the per-glyph baseline wobble that Strategy C would introduce on a system this typographically dense. Stack:
```css
/* Bricolage roles (display, headline, card-title, course-name, info-value) */
font-family: 'Bricolage Grotesque', 'Noto Serif SC', sans-serif;
/* Fraunces roles (body, lede, tagline, pill, pagenum, edition-label) */
font-family: 'Fraunces', 'Noto Serif SC', Georgia, serif;
```
When the deck content is pure Chinese, override both font stacks to lead with Noto Serif SC. Bricolage roles get weight 700 (matches 800 mass in Mincho), Fraunces roles get weight 400.
### Loading
Add to the existing Google Fonts `<link>`:
```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+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
These adjustments apply to **every CJK block** in this system, regardless of size or role:
- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (0.86–0.95 on display, 1.45–1.5 on body) read as cramped in Chinese. Bump display to 1.0–1.1 and body to 1.55–1.65.
- **Remove negative letter-spacing on CJK headlines.** Bricolage display uses -0.005em to -0.012em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the Bricolage portion was meant to be capitalized. (This matters here — every Bricolage display element in the source is `text-transform: uppercase`.)
- **Use Chinese full-width punctuation** (`,。:;!?「」『』()`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between Noto Serif SC weight 400 and 700 inside the same sentence — pick the weight that matches the role (headline = 700, body = 400) and commit to it for the whole run.
### Aesthetic Notes for This System
Long Table's whole voice is "supper-club poster / Risograph zine / small-press dinner program" — single-ink rust terracotta on cream, outlined shapes, paper-texture overlay. In Chinese, the system's identity does not depend on the specific Latin faces (Bricolage and Fraunces); it depends on the **single-ink commitment**, the **1.5px outlined-shape vocabulary**, the **4px radial-dot paper texture**, and the **rich-but-curated density**. Going all-Noto-Serif-SC preserves every one of those identity markers cleanly.
The default-italic body rule does not translate to Chinese (Chinese has no italic concept; slanted Han glyphs read as broken, not as a body voice). In Chinese, every Fraunces-italic role simply becomes **Noto Serif SC weight 400 upright** — the warmth comes from the Mincho character itself, not from the slant. This is the right trade-off for this system.
The hero italic Fraunces jumbo numeral (up to 480px) is the system's signature anchor in Latin — a single italic digit acting as a typographic centerpiece. In Chinese, **use a Chinese ordinal or season character instead of a Western digit**: 「三」、「五」、「春」、「秋」, rendered in Noto Serif SC at weight 400. The Han glyph's denser visual weight at 480px balances the cover slide better than a Western digit would; the cream paper background and warm rust ink carry the printed-program feel through unchanged.
The system's outlined-shape vocabulary (pills, edition badges, rect-tags, outlined cards) works identically in Chinese — no adjustments needed. The "EDITION N." label paired with the circular badge becomes 「第三期」or 「第 03 期」inside the circle, with the meta-label below in Noto Serif SC 400. The 32%-opacity solid / dashed internal divider rhythm is purely structural and unaffected by language.
### Known CJK Gap
The Fraunces italic-default body voice is one of Long Table's most distinctive typographic moves in Latin — italic Mincho-style serif body that gives the system its lyrical, hand-written warmth. Chinese has no equivalent: there is no commonly-available "italic Mincho" face on the Google Fonts CDN, and slanted Han glyphs read as broken regardless. The Chinese rendering loses the italic-default character — every body line becomes upright Noto Serif SC weight 400. This is a real loss of personality, partially compensated by Noto Serif SC's own warmth at body sizes, but Chinese-content Long Table decks read measurably more "neutral magazine" than "supper-club poster." For decks where this matters, lean harder on the **single-ink color** and the **paper-texture overlay** to carry the warmth that the italic body would have carried in Latin.
## Iteration Guide
1. Any new mark on a slide is in `{colors.ink}` — full opacity for primary, 78% for de-emphasized metadata, 32% for internal dividers. No second color.
2. Any new headline is Bricolage Grotesque weight 800 uppercase with negative letter-spacing. Pick the size from the headline ladder (96 / 100 / 120 / 140 / 160 / 180px max) — do not invent a new size.
3. Any new body paragraph is Fraunces italic at weight 400. Use roman only for info-keys (tracked uppercase) and card-body descriptions.
4. Any new edition / ordinal marker uses the `{components.ed-badge}` (circular outline) paired with an italic "EDITION N." Fraunces label.
5. Any new action button is the `{components.pill}` (border-radius 999px); any new metadata tag is the `{components.rect-tag}` (sharp corners). Don't conflate the two.
6. Any new card is the `{components.card-outlined}` pattern: 1.5px ink border, internal 1px @ 32% solid divider above content, internal 1px @ 32% dashed divider below content.
7. Any new ledger / schedule / calendar row uses the multi-column grid + 1px @ 32% solid border-bottom pattern (`{components.ledger-row}`).
8. Any new section opener uses the topbar pattern: Bricolage headline + small italic Fraunces label on the right + 1.5px solid ink horizontal rule beneath.
9. Any new cover-class moment reaches for the italic Fraunces jumbo edition numeral as the hero typographic anchor — paired with a small tracked Bricolage label beneath and a italic Fraunces meta line.
10. Every slide carries the page-number marker. If you skip it, the slide will feel unanchored.
## Known Gaps
- The two Google Fonts (Bricolage Grotesque with `opsz` 12..96, Fraunces with `opsz` 9..144) are loaded via `<link>`. Offline rendering will fall back to system sans (for Bricolage) and Georgia (for Fraunces) — which loses the optical-size axis and the personality of both faces. Self-hosting recommended for offline / print reliability.
- The `opsz` optical-size axis is critical to quality at large display sizes (480px jumbo numeral) and small metadata sizes (14px page-number). Fallback faces without `opsz` will look noticeably flat at the extremes.
- The system is single-ink by design. If a deck needs a second emphasis color (a "callout" or "warning" hue), the system cannot accommodate it without breaking the printed-program register. Use Bricolage scale + opacity + italic/roman switch as the only emphasis mechanisms.
- The paper-texture overlay uses a `background-image` radial-gradient that may render with subtle compression artifacts on some browsers at high zoom. The texture is essential to the system identity; do not remove it as a "performance optimization."
- Body paragraphs are italic by default. For deck content where italic at body scale is hard to read (long technical paragraphs, code samples), the system has no clean fallback — italic is the body voice. Keep paragraphs short and lyrical.
- The CSS has several empty rule blocks (`.body-it { ... }`, `.s-cover .stats .num { font-weight: 600; }` etc.) where the original commented-out italic / weight properties have been stripped. The intended treatment in many places is "italic Fraunces at weight 400" — the default style — but the empty blocks make this implicit rather than explicit. Treat italic as the default everywhere the comments hint at it.
- The system loads Bricolage weights 400 and 600 and Fraunces weights 500 — these are not actively used in the published CSS. Using them would introduce intermediate weights that break the single-weight commitment per face.
- The fallback `.body-it` and `.body-ro` utility classes are defined but use the explicit class names sparingly in the markup. Most slides set typography per-element rather than via the utility classes — copy the per-element styles when authoring new slides, not the utilities.
- The hero italic Fraunces jumbo numeral at 480px is a literal numeral character — there is no glyph alternation or kerning fix for specific characters. The "0" and "8" glyphs may need optical adjustment at extreme sizes; check rendering at the target viewport.
- The system has no `@media print` rule. Print export will not paginate; treat Long Table as screen-first.
# Long Table Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/long-table/design.md`
- Preview card: `bold-template-pack/templates/long-table/preview.md`
## Selection Metadata
- Slug: `long-table`
- Tagline: Warm cream and rust-red supper-club aesthetic with bold uppercase grotesk headlines, Fraunces serifs, and pill-shaped outlined buttons.
- Mood: warm, intimate, modern, friendly, small-batch, social, hospitality
- Tone: warm, playful, considered, social, magazine-friendly, modern-editorial
- Formality: medium
- Density: medium
- Scheme: light
- Best for: Anything that should feel like a warm, intimate, modern hospitality / community brand: supper clubs, dinner series, small restaurants, creative-studio events, membership pitches, lifestyle and wine brands. Equally good for any deck wanting a single warm accent colour, mixed-weight typography, and a social-media-aware modern-editorial voice.
- Avoid for: Decks that need corporate polish, technical density, or a cold / minimalist register — the rust-red palette and bold serif mix are intentionally warm and people-facing.
## Visual Snapshot
A warm, single-ink editorial system in the register of a supper-club poster, a small-batch zine, or a Risograph-printed program. The entire system runs in one ink color — a warm rust terracotta (#B53D2A) — on a buttery cream paper ground (#FAF1E2), with a subtle 4px radial-dot texture overlay giving the surface its "printed paper" quality. Display type runs in Bricolage Grotesque at weight 700–800 in uppercase; body and metadata run in Fraunces serif at weight 400–600 with optical-size axis engaged. Pill buttons, outlined edition badges, italic-edition numerals, and dashed/solid 1.5px borders complete the printed-program vocabulary.
Long Table is a single-ink editorial system in the register of a supper-club poster, a Risograph zine, or a small-press dinner program. The foundational premise is monochromatic: every visible mark in the system — every headline, every paragraph, every border, every rule, every pill, every page number — is rendered in a single warm rust terracotta ink ({colors.ink} — #B53D2A) on a buttery cream paper ground ({colors.paper} — #FAF1E2). The only chromatic variation is opacity: the same ink at 100% for primary marks, at 78% for de-emphasized metadata, at 32% for dashed internal dividers, at 10% for the paper-texture dots.
## Preview Ingredients
- Palette: paper #FAF1E2; paper-d #F2E5CF; paper-vd #E8D7B6; ink #B53D2A; ink-dp #8E2D1F; rule #B53D2A
- Typography: See full design doc after selection.
- Signature move: Bricolage Grotesque at weights 700 and 800 in strict uppercase carries every display moment — covers, headlines, card titles, course names, quote bodies, info values, who-tags. Bricolage is a wide, slightly-condensed grotesque with strong personality; its upp...
- Signature move: Fraunces at weight 400–600 carries every body paragraph, every metadata field, every pill, every page number, every edition label. Italic Fraunces is the default body style — the slanted serif is the system's body voice, lending warmth and editorial personali...
- Signature move: One ink color ({colors.ink} — warm rust terracotta) on cream paper ({colors.paper}). Opacity variants are the only color variation.
- Signature move: Bricolage Grotesque weight 700–800 uppercase for every display moment; Fraunces 400–600 italic-default for every body and metadata moment.
- Signature move: Subtle 4px radial-dot paper texture on every slide via .stage::before — invisible at distance, present up close.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Mat
description: A warm, material-tactile presentation system inspired by a high-end product landing page. Dark forest green is the dominant environment, warmed by a low atmospheric wood-brown glow from the bottom-right corner of every dark slide. Cream type floats directly on the field; warm orange acts as the single accent. The typeface stack pairs Bricolage Grotesque (a heavy, rounded grotesque) for display with DM Sans for body and DM Mono for labels — the result reads as industrial-design portfolio meets boutique product launch, never tech demo.
colors:
bg-dark: "#232E26"
bg-dark-alt: "#2E3D30"
bg-cream: "#EDE6D0"
bg-cream-alt: "#E4DAC4"
ink-cream: "#F0E8D2"
ink-cream-2: "rgba(240, 232, 210, 0.58)"
ink-cream-3: "rgba(240, 232, 210, 0.3)"
ink-dark: "#1E2820"
ink-dark-2: "rgba(30, 40, 32, 0.6)"
ink-dark-3: "rgba(30, 40, 32, 0.3)"
accent-orange: "#C07030"
border-on-dark: "rgba(240, 232, 210, 0.12)"
border-on-cream: "rgba(30, 40, 32, 0.14)"
wood-glow: "#7A4E24"
color-aliases:
c-fg: ink-cream
c-fg-light: ink-dark
c-bg: bg-dark
c-bg-light: bg-cream
c-accent: accent-orange
typography:
display:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 12vw
fontWeight: 800
lineHeight: 0.88
letterSpacing: -0.03em
h1:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 7vw
fontWeight: 800
lineHeight: 0.92
letterSpacing: -0.025em
h2:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 4vw
fontWeight: 700
lineHeight: 1.0
letterSpacing: -0.02em
h3:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 2.4vw
fontWeight: 600
lineHeight: 1.1
letterSpacing: -0.01em
lead:
fontFamily: "DM Sans, Noto Sans SC, sans-serif"
fontSize: 1.5vw
fontWeight: 400
lineHeight: 1.55
body:
fontFamily: "DM Sans, Noto Sans SC, sans-serif"
fontSize: 1.05vw
fontWeight: 400
lineHeight: 1.65
caption:
fontFamily: "DM Sans, Noto Sans SC, sans-serif"
fontSize: 0.82vw
fontWeight: 400
lineHeight: 1.5
label:
fontFamily: "DM Mono, monospace"
fontSize: 0.7vw
fontWeight: 400
letterSpacing: 0.12em
textTransform: uppercase
stat-value:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 5.5vw
fontWeight: 800
lineHeight: 1.0
letterSpacing: -0.025em
quote-text:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 3.4vw
fontWeight: 600
lineHeight: 1.2
letterSpacing: -0.02em
quote-mark:
fontFamily: "Bricolage Grotesque, Noto Sans SC, sans-serif"
fontSize: 8vw
fontWeight: 800
lineHeight: 0.6
spacing:
pad-x: 5.5vw
pad-y: 5.5vh
gap-lg: 4.5vh
gap-md: 2.8vh
gap-sm: 1.4vh
canvas:
width: 100vw
height: 100vh
components:
kicker:
fontFamily: "{typography.label.fontFamily}"
fontSize: "{typography.label.fontSize}"
letterSpacing: 0.12em
textTransform: uppercase
color: "{colors.accent-orange}"
rule:
width: 32px
height: 1px
background: "{colors.accent-orange}"
bullet-marker:
content: "—"
color: "{colors.accent-orange}"
fontFamily: "{typography.label.fontFamily}"
description: "Em-dash prefix in warm orange; emerges in mono face. The system's standard list mark; never a bullet, never a checkmark."
info-card:
background: "{colors.bg-cream}"
color: "{colors.ink-dark}"
padding: "{spacing.gap-md} calc({spacing.pad-x} * 0.8)"
maxWidth: 28vw
description: "Cream inset box embedded on a dark green field. The signature material-contrast component; carries a heading and a body block, no border, no shadow."
chrome-band:
borderBottom: "1px solid {colors.border-on-dark}"
paddingBottom: "{spacing.gap-sm}"
description: "Label-pair on top of a 1px rule; suppressed on cover/quote/end slide types."
foot-band:
borderTop: "1px solid {colors.border-on-dark}"
paddingTop: "{spacing.gap-sm}"
description: "Label-pair under a 1px rule; mirrors the chrome band."
stat-cell:
borderRight: "1px solid {colors.border-on-dark}"
padding: "{spacing.gap-md} {spacing.pad-x} {spacing.gap-md} 0"
description: "A vertically-divided cell containing a large numerical value (with optional inline orange-emphasis em-span) and a one-line label. Last cell has no right border."
bar-fill:
width: "100%"
background: "{colors.ink-cream-3}"
description: "Vertical bar in muted cream; gets the orange accent (.accent variant) when it's the highlighted data point."
compare-divider:
width: 1px
background: "{colors.border-on-dark}"
description: "A 1px-wide vertical column (not a border) used to split a before/after comparison; subtle, not loud."
image-placeholder:
background: "rgba(240, 232, 210, 0.06)"
border: "1px solid {colors.border-on-dark}"
color: "{colors.ink-cream-3}"
description: "Hairline-bordered void with centered mono label until photography is available."
atmospheric-glow:
selector: ".slide.dark::before"
position: "bottom-right ellipse, 55% wide × 70% tall"
gradient: "radial-gradient(ellipse at 70% 80%, rgba(122, 78, 36, 0.28) 0%, rgba(80, 50, 20, 0.14) 40%, transparent 70%)"
description: "The wood-brown atmospheric glow that lives on every dark slide via ::before. Non-optional on dark surfaces; defines the warmth of the system."
---
## 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
Mat is a **material-tactile presentation system** built around a single environmental premise: a deep forest-green surface warmed from the bottom-right corner by a low wood-brown glow. The atmosphere does the heavy lifting — before any content lands, the slide already feels like a workbench in afternoon light. Cream type floats directly on the green field; there are no cards, no panels, no frames. Where the system needs to break the green, it does so with a single cream inset box (the info-card) that reads as a piece of warm paper laid on the dark surface.
The typeface stack is a deliberate three-voice pairing. **Bricolage Grotesque** at weights 700 and 800 is the display workhorse — heavy, rounded, with a slightly mechanical character that suits product writing without feeling tech-startup. **DM Sans** at weight 400 is the body voice, neutral enough to let the display type breathe. **DM Mono** at weight 400 handles all labels, kickers, metadata, and chrome — anything structural that needs to read as a tag rather than a sentence. Display type is **always mixed case** in this system, never uppercase; the uppercase work is reserved for mono labels.
The palette is intentionally narrow. **Dark forest green** is the dominant surface (`{colors.bg-dark}`), with a slightly lighter alternate available for layered regions. **Warm cream** is the primary text color on dark and the secondary surface color when a slide flips light. **Warm orange** (`{colors.accent-orange}`) is the single accent — it appears only as small inline marks: kicker text, bullet em-dashes, the `<em>` inside a stat numeral, the opening quote glyph, the single highlighted bar in a chart. Orange is never a background and never a large headline color; it's the structural emphasis dot of the system.
Depth is minimal and atmospheric, not stacked. There are no drop shadows. There are no rounded corners on any structural element. The only depth signal is the wood-brown radial glow that sits behind every dark slide via a `::before` pseudo-element. Region separation comes from **thin 1px hairline rules** in low-opacity cream — for chrome bands, foot bands, stat cell dividers, compare panel splits, and chart baselines. Nothing about this system is loud.
**Density philosophy: medium-sparse.** Mat reads as elegant when the slide breathes — generous left and right padding (`{spacing.pad-x}` at 5.5vw), one main typographic moment, and one secondary block of supporting copy. Cramming three columns of bullets onto a slide breaks the system; the warm green field needs negative space to do its atmospheric work. The exception is the stats and compare slide types, where a clean three-up or two-up arrangement of restrained cells is correct. A slide with a single headline and one paragraph of lead copy is right in this system's lane. A slide that fills 80% of its area with type is fighting the design.
**Key Characteristics:**
- Dark forest green canvas (`{colors.bg-dark}`) with a warm wood-brown radial glow (`{components.atmospheric-glow}`) anchored to the bottom-right corner of every dark slide.
- Cream text (`{colors.ink-cream}`) floats directly on the green field with no card, panel, or frame around it.
- Bricolage Grotesque display type is **always mixed case** — never uppercase. Uppercase is reserved for DM Mono labels.
- A single accent color, warm orange (`{colors.accent-orange}`), used only as small inline emphasis (kicker, bullet marker, inline `<em>`, quote glyph, one chart bar).
- The cream **info-card** (`{components.info-card}`) is the signature material-contrast component — a warm paper rectangle inset on the dark field.
- Bullet lists use an em-dash prefix in warm orange via DM Mono — never a dot, never a check.
- Thin 1px hairline rules in low-opacity cream are the only divider language. No heavy borders, no shadows.
- The system has one light slide variant (cream background with dark green text) used as a tonal inversion within a deck, never as the default.
## Colors
### Palette
- **Dark Forest Green** (`{colors.bg-dark}` — #232E26): The dominant environment. Default background for every slide unless a deliberate light-slide variant is chosen. The green is muted enough that cream type sits on it without vibration.
- **Slightly Lighter Green** (`{colors.bg-dark-alt}` — #2E3D30): A tonal step-up reserved for layered or recessed surfaces within a dark slide. Available but used sparingly.
- **Warm Cream** (`{colors.bg-cream}` — #EDE6D0): The light-slide background and the fill color of the info-card inset. Reads as warm paper, not white — the warmth is essential to the system's material identity.
- **Deeper Cream** (`{colors.bg-cream-alt}` — #E4DAC4): A secondary cream tone for image placeholders on light slides.
- **Cream Ink** (`{colors.ink-cream}` — #F0E8D2): Primary text color on every dark surface. Slightly warmer than the background cream — chosen so headlines feel like they're carved into the green rather than printed on it.
- **Cream Ink at 58% / 30%** (`{colors.ink-cream-2}`, `{colors.ink-cream-3}`): Secondary and tertiary text on dark. Used for muted lead copy and barely-there metadata respectively.
- **Dark Ink** (`{colors.ink-dark}` — #1E2820): Primary text color on cream surfaces (info-card body, light slide). A very dark forest green, never pure black.
- **Dark Ink at 60% / 30%** (`{colors.ink-dark-2}`, `{colors.ink-dark-3}`): Muted and tertiary text on cream.
- **Warm Orange** (`{colors.accent-orange}` — #C07030): The single accent. A burnt copper-orange that nods to wood, leather, and oxidized metal. Never a background, never a large headline color.
- **Wood Glow** (`{colors.wood-glow}` — #7A4E24): The radial atmospheric glow color, applied only at 0.28 and 0.14 alpha inside the bottom-right corner gradient. Never used as a flat fill.
### Defaults
- **Default surface background**: `{colors.bg-dark}` (forest green). The system is dark-default; cream slides are an intentional tonal break, not a routine choice.
- **Default headline color on dark**: `{colors.ink-cream}`. Headlines never appear in orange.
- **Default headline color on cream**: `{colors.ink-dark}`.
- **Default body text color on dark**: `{colors.ink-cream-2}` (the 58% cream — the `.muted` helper).
- **Default body text color on cream**: `{colors.ink-dark-2}`.
- **Default border / divider color**: `{colors.border-on-dark}` on dark; `{colors.border-on-cream}` on cream. Always 1px, never thicker.
- **Default kicker color**: `{colors.accent-orange}`. The kicker is the system's eyebrow label and is the most consistent place orange shows up.
- **Default inline emphasis color**: `{colors.accent-orange}`. An `<em>` inside a stat value, a quote attribution, or a chart label resolves to orange.
- **Default atmospheric treatment for dark slides**: the wood-brown radial glow (`{components.atmospheric-glow}`) is always on. It is part of the dark surface itself.
Orange functions as a punctuation color: it tells the eye where the structural emphasis lives without ever competing for surface area. If two orange elements end up adjacent on the same slide, one of them is wrong.
## Typography
### Font Family
The system runs on three Google Fonts plus CJK fallback. **Bricolage Grotesque** carries every display, h1, h2, h3, stat numeral, and quote text — its rounded, heavy character at weights 700–800 is the defining voice. **DM Sans** at weight 400 carries every paragraph, lead, caption, and bullet item — neutral, readable, lets the display type lead. **DM Mono** at weight 400 carries every label, kicker, chrome tag, footer text, bullet em-dash, and chart label — anything that needs to read as a structural marker rather than prose. **Noto Sans SC** is the CJK fallback for all sans roles; **Noto Serif SC** is not used.
A subtle but load-bearing rule: **the bullet em-dash before each list item renders in DM Mono in warm orange**, not in the body face. The mono shape is what makes the dash feel like a deliberate mark and not a stray punctuation glyph.
Italics are not used for typographic decoration in this system. The `<em>` tag is repurposed as an **orange inline emphasis** — `<em>` inside a stat value or a quote attribution switches to `{colors.accent-orange}` and stays upright (font-style: normal). There is no italicized face anywhere.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | 12vw | Bricolage Grotesque | 800 | Cover or opening hero display — massive, line-broken into 1–2 words per line |
| `{typography.h1}` | 7vw | Bricolage Grotesque | 800 | Chapter-opening or closing headline |
| `{typography.h2}` | 4vw | Bricolage Grotesque | 700 | Primary content-slide headline |
| `{typography.stat-value}` | 5.5vw | Bricolage Grotesque | 800 | Large numerical figure inside a stat cell |
| `{typography.quote-mark}` | 8vw | Bricolage Grotesque | 800 | Decorative opening quotation glyph in warm orange |
| `{typography.quote-text}` | 3.4vw | Bricolage Grotesque | 600 | Pull-quote body text |
| `{typography.h3}` | 2.4vw | Bricolage Grotesque | 600 | Sub-headline or region heading |
| `{typography.lead}` | 1.5vw | DM Sans | 400 | Lead paragraph or large bullet item |
| `{typography.body}` | 1.05vw | DM Sans | 400 | Body paragraph and info-card body |
| `{typography.caption}` | 0.82vw | DM Sans | 400 | Image caption, tagline, fine print |
| `{typography.label}` | 0.7vw | DM Mono | 400 | Kicker, chrome tag, footer label, metadata, chart label |
### Defaults
- **Default primary section headline**: `{typography.h2}` (4vw).
- **Default opening or cover display**: `{typography.display}` (12vw) on a cover; `{typography.h1}` (7vw) on a chapter or closing moment.
- **Default body paragraph size**: `{typography.body}` (1.05vw). Reach for `{typography.lead}` (1.5vw) when the paragraph is the single supporting block under a large headline.
- **Default label / kicker size**: `{typography.label}` (0.7vw).
- **Default weight for any display element**: 700 (h2) or 800 (display, h1, stat-value).
- **Default weight for body**: 400.
- **Default headline letter-spacing**: negative — display at -0.03em, h1 at -0.025em, h2 at -0.02em. The negative tracking is essential.
When unsure, default to `{typography.h2}` for the primary text moment paired with one `{typography.lead}` paragraph as supporting copy — that pairing is the system's most reliable rhythm.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **All display, h1, h2, h3 text is mixed case** — never uppercase. Uppercase display type does not exist in this system. If text is in Bricolage Grotesque, it is sentence case.
- **All labels, kickers, chrome text, footers, and metadata are DM Mono uppercase with 0.12em positive tracking.** Mono in sentence case does not exist here.
- **The kicker is always warm orange.** When a slide carries a kicker (eyebrow label above a headline), its color is `{colors.accent-orange}` regardless of surface.
- **Bullet lists use an em-dash prefix in DM Mono colored warm orange.** Never a dot, never a check, never a numeral.
- **The `<em>` tag inside a stat numeral renders in warm orange and stays upright.** It is the mechanism for highlighting a unit suffix or a key digit inside a number.
- **Headlines on dark surfaces are cream; headlines on cream surfaces are dark ink.** Headlines are never orange.
- **All Bricolage display type uses negative letter-spacing.** Default tracking on display reads as untreated; the negative is what gives the type its compressed, premium-product character.
### Typography Principles
The rhythm of the system is **heavy mixed-case display + light mixed-case body + small uppercase mono label**. Switching any of those three modes (e.g., uppercasing the display, or making the body the same weight as the display) breaks the editorial register. Bricolage at 700–800 sits next to DM Sans at 400 — the weight gap is deliberate and wide. Do not use intermediate Bricolage weights (400, 500) for display moments; they read as undecided.
Italics are not used. Underline is not used. The only emphasis mechanism inside body copy is the orange `<em>` inline. The only structural emphasis is the kicker and the bullet em-dash.
## Layout
### Canvas System
Mat is **viewport-fluid by design**. All sizes use `vw` and `vh` units so the layout scales linearly with the viewport. The slide container is `100vw × 100vh` and the deck is a horizontal flex strip that translates left/right by full viewport widths. There is no fixed canvas dimension; the same composition renders correctly on any 16:9-ish viewport.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 5.5vw | Slide horizontal padding; the breathing room on left and right edges |
| `{spacing.pad-y}` | 5.5vh | Slide vertical padding |
| `{spacing.gap-lg}` | 4.5vh | Between major content sections |
| `{spacing.gap-md}` | 2.8vh | Between related elements (headline → lead, stat → label) |
| `{spacing.gap-sm}` | 1.4vh | Between tightly related elements (label pair in chrome band) |
The horizontal padding is generous — content occupies roughly the middle 89% of the viewport. Pushing content closer to the edges breaks the system's editorial spaciousness.
### Chrome Frame
Most slide types carry a **chrome band** (`{components.chrome-band}`) at the top and a **foot band** (`{components.foot-band}`) at the bottom. Each is a `flex space-between` row of two DM Mono labels (typically a section name on the left and a slide-position or section number on the right) separated from the body by a 1px hairline rule. Cover, quote, and end-style slides suppress both bands entirely — those moments are chromeless by convention.
### Navigation Chrome
A row of nav-dots is fixed center-bottom (5px circles in low-opacity white) and a slide counter sits bottom-right (10px DM Mono in `rgba(255,255,255,0.25)`, format `01 / 09`). These are presentation chrome, not part of the design language proper — they're consistent across all template families in this library.
## Depth and Elevation
### Atmospheric Glow (Primary Depth Mechanism)
The system's only depth treatment is the **bottom-right wood-brown radial glow** that lives on every dark slide via `::before`. The pseudo-element occupies 55% width × 70% height anchored to the bottom-right corner, with a radial gradient from `rgba(122,78,36,0.28)` to `rgba(80,50,20,0.14)` to transparent. The glow sits at `z-index: 0`; all slide content sits at `z-index: 1`. This is the depth — there are no drop shadows, no elevation cards, no glow effects on text.
### Hairline Rules (Structural Separation)
Where the system needs to separate regions, it uses **1px hairline rules in low-opacity cream** (`{colors.border-on-dark}` at 12% opacity) on dark surfaces, or low-opacity dark ink (`{colors.border-on-cream}` at 14% opacity) on cream. These rules appear under chrome bands, above foot bands, between stat cells, between compare panels, and as the chart baseline. Hairlines never go thicker than 1px, never colored.
### No Shadows
There are no `box-shadow` declarations on any structural element. The info-card sits on the dark field with no shadow — its material contrast is the cream-on-green tonal jump, not elevation. Adding a shadow to any component breaks the system's flat material-photography aesthetic.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | Every structural element — info-card, image placeholders, stat cells, compare panels, bars |
| 50% | Nav-dot circles only |
The system has **no rounded corners** on any composed content. Cards, panels, and image frames are all strict rectangles. The only round shapes are the navigation UI dots.
### Border Weights
- **1px solid hairline** — the universal structural border. Used for chrome bands, foot bands, stat cell dividers, compare panel splits, chart baselines, and image placeholder outlines. Color is `{colors.border-on-dark}` on dark surfaces and `{colors.border-on-cream}` on cream.
- No other border weights exist. A 2px border breaks the system; a 3px border belongs to a different design family.
### Decorative Element Types
**Kicker** — A small DM Mono uppercase tag in warm orange with 0.12em positive tracking, placed above a headline as an eyebrow label. The most consistent appearance of orange in the system. Typically 0.7vw size.
**Rule** — A 32px-wide × 1px-tall horizontal accent line in warm orange. Used as a small underline-style separator between a kicker and a headline, or beneath a chapter number. Decorative, not structural.
**Bullet em-dash** — The list marker for every bullet list. Renders as `—` in DM Mono colored warm orange, prepended to the list item via the marker column of a CSS grid (`grid-template-columns: 1.4em 1fr`). The bullet voice of the system.
**Info-card** — A cream inset rectangle (`{components.info-card}`) placed on a dark slide. Carries a heading (h3-scale, dark ink) and a body block (body-scale, muted dark ink). The single most distinctive component in the system — used to puncture the green field with a piece of warm paper. Has no border, no shadow, no rounded corners; the tonal jump alone defines the edge.
**Stat cell** — A vertically-divided cell containing a large numerical value (`{typography.stat-value}`) above a one-line label (`{typography.body}` in muted cream). Cells line up in groups of three with a 1px right border separating each (last cell has no right border). The numerical value supports an inline `<em>` in orange for unit suffixes (e.g., the suffix in `4.7k`).
**Quote mark** — An oversized opening quotation glyph at `{typography.quote-mark}` size in warm orange. Sits above the quote text as a typographic ornament. Used only inside the quote slide type.
**Compare divider** — A 1px-wide vertical CSS column (not a border) between two side-by-side panels. Subtle by design — the contrast between the two panels does the visual work, not the divider.
**Image placeholder** — A void rectangle with a 1px hairline border, 6% cream background, and centered DM Mono label reading the placeholder name. Used until real photography is dropped in. The placeholder color is intentionally close to the background — image regions should not announce themselves.
## Do's and Don'ts
### Do
- Use the dark forest green (`{colors.bg-dark}`) as your default slide background. The system is dark-first; cream slides are a tonal break, not the default.
- Apply the wood-brown atmospheric glow to every dark slide. It is part of the surface, not an optional flourish.
- Pair Bricolage Grotesque display in mixed case with DM Mono labels in uppercase. The case contrast between the two faces is the system's typographic rhythm.
- Set headlines in cream (`{colors.ink-cream}`) on dark and dark ink (`{colors.ink-dark}`) on cream. Headlines never carry the orange accent.
- Use warm orange (`{colors.accent-orange}`) as the kicker color, the bullet em-dash color, and the inline `<em>` color. Orange is the punctuation, never the surface.
- Use the cream info-card (`{components.info-card}`) when a slide needs a piece of warm paper inset on the green field — the system's signature material-contrast move.
- Keep slides medium-sparse. One primary headline, one supporting paragraph, optionally one list of 3–5 short bullets is the right density.
- Use 1px hairline rules in low-opacity cream or dark ink for every structural divider. Borders never go thicker.
- Use the em-dash prefix in DM Mono for every bullet list. Never substitute a dot, check, or numeral.
- Render the `<em>` inside a numerical value in warm orange, font-style normal — that's how unit suffixes and emphasis digits read in this system.
### Don't
- Don't uppercase any Bricolage display, h1, h2, or h3 text. Display type is always mixed case. Uppercase is exclusively for DM Mono labels.
- Don't introduce a second accent color. The system has one accent (warm orange) and it cannot share that role.
- Don't add drop shadows, blur shadows, or elevation effects on any component. Depth is the atmospheric glow only.
- Don't round any corner on a structural element. Cards, panels, image frames, bars — all strict rectangles. Only the nav-dot circles are round.
- Don't fill a slide with three columns of bullets or stack five regions vertically. Mat reads as broken when crowded.
- Don't use orange as a background fill. Orange is inline-only.
- Don't use a serif face anywhere. There is no serif in this system; the rounded grotesque carries every editorial moment.
- Don't add a border around the info-card. The tonal jump between cream and forest green defines the edge — a border breaks the flat material reading.
- Don't use italic letterforms. The `<em>` tag is repurposed as an orange inline color switch and stays upright.
- Don't increase border weights above 1px. A 2px border breaks the hairline language of the system.
## Responsive Behavior
Mat targets a fluid `100vw × 100vh` viewport and uses `vw`/`vh` units for every typographic size, padding, and gap. The same composition renders correctly across 1280×720, 1920×1080, and 2560×1440 displays without breakpoints. Because all sizes are viewport-relative, content scales linearly — at wider viewports, both text and padding grow proportionally, so the visual density stays constant.
### Presenter Behavior
- Arrow Right / Arrow Down / Space advance to the next slide.
- Arrow Left / Arrow Up move back.
- Home jumps to the first slide; End jumps to the last.
- Touch swipe (horizontal) advances or reverses on mobile.
- Mouse wheel advances with a 1000ms debounce to prevent accidental multi-skip.
- Slides translate horizontally as a single flex strip with a 0s transition (the deck is configured for instant navigation, not animated transitions — the `--dur-slide` token is set to `0s`).
### Print Behavior
The template does not declare a `@media print` rule. To produce a PDF, use the browser's screenshot or printing tool; multi-slide PDF export requires manually triggering each slide.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display / h1 / h2 / h3 / stat-value (Bricolage roles, 2.4–12vw) | 思源宋体 Noto Serif SC | 700 | Mincho heavy weight provides the structural mass that Bricolage 700–800 provides in Latin, while preserving the warm material register |
| Quote text / quote mark (3.4vw / 8vw) | 思源宋体 Noto Serif SC | 600–700 | Same Mincho voice for editorial moments |
| Lead / body / caption (DM Sans roles, 0.82–1.5vw) | 思源宋体 Noto Serif SC | 400 | Mincho body voice — calm and material; pairs with the wood-glow warmth |
| Info-card body / heading | 思源宋体 Noto Serif SC | 400 / 600 | Maintains the warm-paper-on-green contrast in Chinese |
| Label / kicker / chrome / footer (DM Mono roles, 0.7vw) | 思源宋体 Noto Serif SC | 500 with 0.05em letter-spacing | Replaces DM Mono — Chinese has no monospace tradition that reads as editorial chrome |
### Mixed-Content Strategy
Use **Strategy A** — switch the entire face stack to Noto Serif SC across all roles, replacing Bricolage Grotesque (display), DM Sans (body), and DM Mono (labels). Mat's identity does not depend on the specific Latin faces; it depends on the **dark forest green canvas with wood-brown atmospheric glow**, the **single warm orange accent**, the **cream info-card inset**, and the **1px hairline divider language**. Going all-Mincho in Chinese preserves every one of those identity markers cleanly without the baseline wobble that Strategy C would introduce on a viewport-fluid system. Stack:
```css
/* Bricolage roles (display, h1, h2, h3, stat-value, quote) */
font-family: 'Bricolage Grotesque', 'Noto Serif SC', sans-serif;
/* DM Sans roles (lead, body, caption) */
font-family: 'DM Sans', 'Noto Serif SC', sans-serif;
/* DM Mono roles (label, kicker, chrome, footer) */
font-family: 'DM Mono', 'Noto Serif SC', monospace;
```
The system's source currently lists `'Noto Sans SC'` as the CJK fallback — for Mat's material-tactile register, **swap to `'Noto Serif SC'`**. The Mincho face's warm letterforms match the wood-glow / forest-green atmosphere better than the geometric Noto Sans SC, which reads as too modern-clinical for this system.
### Loading
Replace the existing Noto Sans SC link with Noto Serif SC:
```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+Serif+SC:wght@400;500;600;700&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
These adjustments apply to **every CJK block** in this system, regardless of size or role:
- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (0.88–1.1 on display, 1.5–1.65 on body) read as cramped in Chinese. Bump display to 1.0–1.2 and body to 1.7–1.85.
- **Remove negative letter-spacing on CJK headlines.** Bricolage display uses -0.025em to -0.03em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the DM Mono label portion was meant to be capitalized. (This matters here — every DM Mono label, kicker, chrome-band, and footer is `text-transform: uppercase`.)
- **Use Chinese full-width punctuation** (`,。:;!?「」『』()`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between Noto Serif SC weight 400, 500, and 700 inside the same sentence — pick the weight that matches the role (headline = 700, body = 400, label = 500) and commit to it for the whole run.
### Aesthetic Notes for This System
Mat's whole voice is "industrial-design portfolio meets boutique product launch" — dark forest green with a wood-brown glow, cream type floating on the field, warm orange as the single accent. In Chinese, the system's identity does not depend on the Bricolage / DM Sans / DM Mono trio; it depends on the **environmental atmosphere** (the radial wood-glow on every dark slide), the **single-accent discipline** (orange only as kicker, em-dash bullet, inline emphasis), and the **cream info-card** as the signature material-contrast move. All of these translate without modification.
The bullet em-dash in orange works in Chinese identically — the em-dash character (—) is the same glyph in any script, and the orange Noto Serif SC at weight 500 prepended to a Chinese list item reads as a deliberate mark exactly as it does in Latin. Keep the bullet column in Noto Serif SC at weight 500 (replacing DM Mono); the warmth of the Mincho face matches the system's material-tactile register better than a sans-serif chrome face would.
The Bricolage rule "always mixed case, never uppercase" is interesting in Chinese — since Chinese has no case, the rule is automatically satisfied. But the system's uppercase rule for labels (DM Mono at 0.12em tracking) doesn't translate; in Chinese, labels should be **Noto Serif SC weight 500 with 0.05em positive tracking**, no `text-transform`. The positive tracking carries the chrome quality through weight and spacing alone.
The `<em>` inline-orange rule (for unit suffixes inside stat numerals) works in Chinese — a Chinese unit character like 「万」or 「亿」 inside `<em>` renders in warm orange and stays upright, exactly mirroring the Latin pattern. Use it the same way: `4.7<em>万</em>` for `4.7 万 (47k)`.
### Known CJK Gap
The Bricolage Grotesque "heavy, rounded grotesque with mechanical character" is one of Mat's most distinctive typographic moves in Latin — it's what gives the system its industrial-product-page voice. Chinese has no exact equivalent: Noto Serif SC at weight 700 provides structural mass but reads as more traditional / literary than Bricolage's rounded modernity. The Chinese rendering loses some of the industrial-design quality, partially compensated by the wood-glow atmosphere and the warm orange accent doing more of the personality work. For decks where the industrial register is critical (e.g., a product launch deck specifically about hardware or material design), consider supplementing Noto Serif SC with **思源黑体 Noto Sans SC at weight 800** for the largest display moments only (cover, hero) — the geometric heaviness of Noto Sans SC at 800 reads closer to Bricolage Grotesque 800 than Noto Serif SC does. Use sparingly to preserve the literary-material register elsewhere.
## Iteration Guide
1. Any new component sits on the dark surface as cream text; no card, panel, or frame wraps it unless it's the info-card move (cream-on-green tonal contrast).
2. Any new headline uses Bricolage Grotesque in mixed case, weight 700 (h2) or 800 (display/h1). Never reach for weight 500 on display.
3. Any new structural divider is a 1px hairline rule in low-opacity cream or dark ink. Never use a thicker or colored border.
4. Any new label, eyebrow, tag, or metadata text uses DM Mono uppercase with 0.12em tracking. Mono in mixed case does not exist here.
5. Any new bullet list uses the em-dash prefix in DM Mono colored warm orange. The marker face and color are non-negotiable.
6. Any new accent moment (a highlighted number, an emphasis word, a kicker) uses warm orange. Don't introduce a second accent.
7. Any new dark slide carries the atmospheric glow on `::before`. If you make a custom slide layout, replicate the pseudo-element or the slide will read flat.
8. If a slide needs a piece of warm paper to anchor it (a CTA, a summary, an attribution block), use the info-card. Don't invent a parallel card pattern.
9. Tonal break slides (cream backgrounds) are used once per deck for emphasis, not as a routine alternative to dark. The system reads as dark-default.
## Known Gaps
- The `--c-bg-dark-alt` (#2E3D30) variable is defined for a slightly lighter green surface but is not actively used in any selector. It's reserved for future layered-region work.
- The atmospheric glow is hardcoded to the bottom-right corner via the `::before` pseudo-element. Repositioning it requires editing the CSS rule directly; there's no token for glow position or intensity.
- The system loads four Google Fonts (Bricolage Grotesque, DM Sans, DM Mono, Noto Sans SC) — render parity depends on those fonts loading. The CJK fallback stack covers Chinese, but Japanese and Korean glyphs fall back to system serif/sans.
- The slide-transition duration is set to `0s` (instant). The `--ease-slide` and `--dur-slide` tokens exist for animation but are inert; if a deck needs animated transitions, the duration value must be raised.
- The vertical bar chart uses inline `style="height: XX%"` declarations on each bar fill. There is no data-binding layer; bar heights must be computed manually.
- The `.split-center` image region is fixed at 52vh height. Tall portrait imagery may need a layout-level override.
- Nav dots and slide counter use hardcoded `rgba(255,255,255,...)` values that don't adapt to the cream-slide variant — on cream slides, the white dots read as washed-out.
# Mat Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/mat/design.md`
- Preview card: `bold-template-pack/templates/mat/preview.md`
## Selection Metadata
- Slug: `mat`
- Tagline: Dark sage canvas with bone paper and burnt-orange accent; mid-century modern with wood undertones.
- Mood: warm-modern, considered, tactile, mid-century
- Tone: warm, design-led, intentional, considered
- Formality: medium
- Density: medium
- Scheme: mixed
- Best for: Anything that should feel mid-century, tactile, and intentional: design studio credentials, architecture / interior brands, ceramics / craft / furniture, advisory decks. Also a warm, distinctive choice for tech, research, or business decks that want a considered analog feel instead of digital-cool.
- Avoid for: Contexts that need fast tech energy or institutional restraint — the muted sage and burnt-orange palette is intentionally warm and slow.
## Visual Snapshot
A warm, material-tactile presentation system inspired by a high-end product landing page. Dark forest green is the dominant environment, warmed by a low atmospheric wood-brown glow from the bottom-right corner of every dark slide. Cream type floats directly on the field; warm orange acts as the single accent. The typeface stack pairs Bricolage Grotesque (a heavy, rounded grotesque) for display with DM Sans for body and DM Mono for labels — the result reads as industrial-design portfolio meets boutique product launch, never tech demo.
Mat is a material-tactile presentation system built around a single environmental premise: a deep forest-green surface warmed from the bottom-right corner by a low wood-brown glow. The atmosphere does the heavy lifting — before any content lands, the slide already feels like a workbench in afternoon light. Cream type floats directly on the green field; there are no cards, no panels, no frames. Where the system needs to break the green, it does so with a single cream inset box (the info-card) that reads as a piece of warm paper laid on the dark surface.
## Preview Ingredients
- Palette: bg-dark #232E26; bg-dark-alt #2E3D30; bg-cream #EDE6D0; bg-cream-alt #E4DAC4; ink-cream #F0E8D2; ink-dark #1E2820; accent-orange #C07030; wood-glow #7A4E24
- Typography: Bricolage Grotesque; DM Sans; DM Mono; {typography.label.fontFamily}
- Signature move: Dark forest green canvas ({colors.bg-dark}) with a warm wood-brown radial glow ({components.atmospheric-glow}) anchored to the bottom-right corner of every dark slide.
- Signature move: Cream text ({colors.ink-cream}) floats directly on the green field with no card, panel, or frame around it.
- Signature move: Bricolage Grotesque display type is always mixed case — never uppercase. Uppercase is reserved for DM Mono labels.
- Signature move: A single accent color, warm orange ({colors.accent-orange}), used only as small inline emphasis (kicker, bullet marker, inline <em>, quote glyph, one chart bar).
- Signature move: The cream info-card ({components.info-card}) is the signature material-contrast component — a warm paper rectangle inset on the dark field.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Monochrome (Ivory Ledger)
description: A literary editorial system rendered in black ink on cream paper. Ultra-light geometric sans (Jost at weight 200–300) carries every headline; Lora italic serif handles quote text and insight-card titles; JetBrains Mono provides the structural chrome. There are no chromatic accents — every color in the palette is a graphite or cream tone, and "accent" simply means "darker ink." The aesthetic borrows from independent research reports, scholarly monographs, and the quietest end of contemporary editorial design — closer to a printed journal than a tech presentation.
colors:
cream-paper: "#FAFADF"
cream-paper-2: "#F2F2D2"
cream-paper-3: "#F0F0D4"
cream-warm: "#F5F0E4"
ink-black: "#1A1A16"
ink-graphite: "#5E5E54"
ink-graphite-light: "#8A8A80"
color-aliases:
c-bg: cream-paper
c-bg-light: cream-paper
c-bg-cream: cream-warm
c-fg: ink-black
c-fg-light: ink-black
c-fg-2: ink-graphite
c-fg-3: ink-graphite-light
c-accent: ink-black
c-border: ink-black
c-border-light: ink-black
typography:
display:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 8.5vw
fontWeight: 200
lineHeight: 0.96
letterSpacing: -0.02em
h1:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 5vw
fontWeight: 200
lineHeight: 1.1
letterSpacing: -0.01em
h2:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 3.2vw
fontWeight: 300
lineHeight: 1.2
h3:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 2vw
fontWeight: 400
lineHeight: 1.3
lead:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.5vw
fontWeight: 300
lineHeight: 1.65
body:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.1vw
fontWeight: 300
lineHeight: 1.7
caption:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 0.85vw
fontWeight: 300
lineHeight: 1.55
label:
fontFamily: "JetBrains Mono, monospace"
fontSize: 0.72vw
fontWeight: 400
letterSpacing: 0.12em
textTransform: uppercase
quote-serif:
fontFamily: "Lora, Noto Serif SC, Georgia, serif"
fontSize: 3.2vw
fontWeight: 400
lineHeight: 1.35
insight-serif:
fontFamily: "Lora, Noto Serif SC, Georgia, serif"
fontSize: 2.8vw
fontWeight: 400
lineHeight: 1.15
stat-value:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 5.5vw
fontWeight: 200
lineHeight: 1.0
letterSpacing: -0.03em
flow-num:
fontFamily: "Jost, Noto Sans SC, system-ui, sans-serif"
fontSize: 3.5vw
fontWeight: 200
lineHeight: 1.0
letterSpacing: -0.02em
spacing:
pad-x: 8vw
pad-y: 6vh
gap-lg: 5vh
gap-md: 3vh
gap-sm: 1.5vh
canvas:
width: 100vw
height: 100vh
components:
rule:
width: 36px
height: 1px
background: "{colors.ink-black}"
description: "A 36-pixel hairline accent rule. The system's signature small punctuation mark — appears under chapter labels, beside kickers, above stat values."
rule-full:
width: "100%"
height: 1px
background: "{colors.ink-black}"
description: "Full-width 1px hairline rule for chrome bands, foot bands, and section dividers."
kicker:
fontFamily: "{typography.label.fontFamily}"
fontSize: "{typography.label.fontSize}"
letterSpacing: 0.14em
textTransform: uppercase
color: "{colors.ink-graphite-light}"
description: "Muted mono uppercase eyebrow label above a headline."
tag:
border: "1px solid {colors.ink-black}"
padding: "0.3em 0.8em"
fontFamily: "{typography.label.fontFamily}"
fontSize: "{typography.label.fontSize}"
letterSpacing: 0.12em
textTransform: uppercase
description: "Bordered inline tag for version numbers, status labels."
bullet-marker:
content: "—"
color: "{colors.ink-graphite-light}"
fontFamily: "{typography.label.fontFamily}"
description: "Em-dash in muted graphite via JetBrains Mono. The standard list mark; never a dot, never a check."
insight-card:
background: "{colors.cream-warm}"
borderRadius: 16px
padding: "3vh 2.5vw"
description: "Tall rounded-rectangle card in cream tone (one of three near-identical creams). Holds a large Lora serif title and a Jost body block at the bottom."
stat-cell:
borderTop: "1px solid {colors.ink-black}"
padding: "{spacing.gap-md} {spacing.gap-md} {spacing.gap-md} 0"
description: "Rule-topped vertical cell with a 5.5vw weight-200 numeral, a Jost label, and a mono source note."
timeline-dot:
width: 8px
height: 8px
borderRadius: 50%
background: "{colors.ink-black}"
border: "2px solid {colors.cream-warm}"
description: "Solid black dot with a cream border ring that punches through a horizontal connector rule."
vtimeline-spine:
width: 1px
background: "{colors.ink-black}"
description: "1px vertical rule that anchors a vertical timeline. Carries a 9px solid black dot at the top of each entry."
pie-donut:
width: "min(26vw, 42vh)"
height: "min(26vw, 42vh)"
borderRadius: 50%
description: "Donut ring rendered by overlaying a same-color circular ::after pseudo on a conic-gradient or similar. Center cutout is the slide background."
pyramid-bar:
borderLeft: "2px solid {colors.ink-black}"
background: "color-mix(in srgb, {colors.ink-black} N%, {colors.cream-paper})"
description: "Horizontal pyramid level. Width grows down each level (36% → 100%); fill darkens up the pyramid via color-mix at increasing percentages."
bar-fill:
width: "100%"
background: "{colors.ink-graphite-light}"
opacity: 0.5
description: "Vertical bar in muted graphite at half opacity. Accented variant uses solid ink-black at full opacity."
img-placeholder:
border: "1px solid {colors.ink-black}"
background: "{colors.cream-paper-3}"
color: "{colors.ink-graphite}"
description: "Hairline-bordered cream void with a centered mono label. Used until photography is dropped in."
---
## 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
Monochrome (Ivory Ledger) is a **literary editorial system** built on a single material constraint: black ink on cream paper, and nothing else. The palette has eight tokens, but seven of them are tonal variations of cream or graphite. There is no chromatic accent — the "accent" color is just darker ink. The result is a system that reads as a carefully typeset research report or a quiet contemporary monograph, not a presentation.
The typeface stack is a three-voice editorial pairing. **Jost** at weights 200, 300, and 400 carries every display, headline, body, and label — its geometric sans construction stays calm at ultra-light weights and the contrast between weight 200 (display) and weight 300 (body) is the system's primary typographic rhythm. **Lora** italic serif is reserved for two specific moments: the body text of a pull-quote and the title of an insight card. The serif italic provides the only typographic warmth in the system — wherever it appears, it signals "this is the human voice." **JetBrains Mono** at weight 400 carries every structural marker: chrome labels, sidebar tags, version numbers, footer text, bullet dashes, axis labels, dates. Mono is uppercase and tracked at 0.12em or wider.
The palette functions in three roles. **Cream paper** (`{colors.cream-paper}` and its three near-identical sibling tones) is the canvas — slides are never white, always a warm off-yellow cream. **Black ink** (`{colors.ink-black}` — actually #1A1A16, a very dark olive-black) is every text moment, every border, every divider, every shape fill that isn't decorative cream. **Graphite** in two tones (`{colors.ink-graphite}` for secondary text, `{colors.ink-graphite-light}` for tertiary) handles muted copy. That's the whole color system.
Depth is achieved entirely through **1px hairline rules** and **generous whitespace**. There are no drop shadows, no gradients, no elevation, no atmospheric effects. When two regions need separation, a 1px black line divides them. When a region needs visual weight, it gets more padding, not a fill change. The insight-card surfaces are nearly indistinguishable from the page itself — the cards are defined by their corner radius and padding, not by a contrast jump.
**Density philosophy: sparse.** Ivory Ledger reads as elegant when generous whitespace dominates and a single typographic moment anchors the slide. The horizontal padding is set to 8vw (the most generous in the library), and content typically uses only the middle 60–70% of the canvas. A slide that fills 80% of its area with type reads as cramped and breaks the editorial reading. The system is asking the agent to leave space — to let a single Jost-200 headline carry an otherwise nearly-empty slide. When density is required (a research timeline, a two-column dense-text spread, a 12-row table), the system holds together only because the type is so light and the rules so thin that even dense content reads as airy.
**Key Characteristics:**
- Cream paper background (`{colors.cream-paper}`) on every slide — never white, never dark by default. The cream is the surface, not a stylistic choice.
- Ultra-light Jost (weight 200 for display, weight 300 for body) is the dominant typographic voice.
- Lora italic serif appears in two specific moments: pull-quote bodies and insight-card titles. Nowhere else.
- JetBrains Mono uppercase with 0.12em+ tracking handles every structural label, chrome tag, axis, and bullet marker.
- The system has no chromatic accent. The accent color is `{colors.ink-black}` — slightly darker ink.
- All structural separation is 1px hairline rules in black, plus the signature 36px short rule (`{components.rule}`) used as a small punctuation mark.
- The bullet list marker is an em-dash in muted graphite via JetBrains Mono.
- Generous 8vw horizontal padding — the most spacious in the template library.
## Colors
### Palette
- **Cream Paper** (`{colors.cream-paper}` — #FAFADF): The default surface. Warm off-yellow, never pure white. Every slide background is this color or a near-identical variant.
- **Cream Paper Alt** (`{colors.cream-paper-2}` — #F2F2D2): A slightly deeper cream for inset surfaces. Used sparingly — the difference from the default cream is barely perceptible.
- **Cream Paper Deep** (`{colors.cream-paper-3}` — #F0F0D4): The image-placeholder fill. Slightly more saturated cream that distinguishes a void rectangle from the slide surface.
- **Cream Warm** (`{colors.cream-warm}` — #F5F0E4): The insight / timeline slide background, a warmer tone that signals these slides as related sub-aesthetic moments within the deck.
- **Ink Black** (`{colors.ink-black}` — #1A1A16): Every text moment, every rule, every divider, every border. A very dark olive-black, not pure black — chosen for warmth against the cream paper.
- **Ink Graphite** (`{colors.ink-graphite}` — #5E5E54): Secondary text color. Used for muted lead copy, body paragraphs in dense slides, and labels that need to step back from headline weight.
- **Ink Graphite Light** (`{colors.ink-graphite-light}` — #8A8A80): Tertiary text. Used for kickers, axis labels, source notes, bullet markers, footer chrome — anything that should read as barely-present structural metadata.
### Defaults
- **Default surface background**: `{colors.cream-paper}`. The system is single-surface by default.
- **Default primary headline color**: `{colors.ink-black}`. Headlines never appear in graphite or any other tone.
- **Default body text color**: `{colors.ink-black}` for primary copy on light slides; `{colors.ink-graphite}` for muted lead paragraphs.
- **Default kicker / label color**: `{colors.ink-graphite-light}` — the most muted graphite. Labels should sit back, not lead.
- **Default border / divider color**: `{colors.ink-black}` — every divider is solid black. There is no muted border tone.
- **Default rule weight**: 1px. The system never uses thicker rules.
- **Default "accent" color**: `{colors.ink-black}` — the same as the primary text color. Accent in this system means darker emphasis ink, not a chromatic switch.
- **Default warmer-surface treatment for insight or timeline groups**: `{colors.cream-warm}` — used to tonally identify a group of slides without breaking the monochrome palette.
The system has no warm/cool pairing, no semantic color (no red for warning, no green for success), no chromatic emphasis. Every emphasis comes from typography (size, weight, italic switch) or from a rule, never from color.
## Colors (continued)
The three "insight card surfaces" (`--c-card-a`, `--c-card-b`, `--c-card-c`) are all near-identical cream tones (#FAFADF, #F5F0E4, #FAFADF). They are intentionally collapsed — the card distinction is meant to come from padding and serif title, not surface color. Treat the three card-surface tokens as effectively one surface.
## Typography
### Font Family
The system loads five faces: **Jost** (weights 200, 300, 400, 500, 600) carries all sans display and body; **Lora** (italic and roman, weights 400, 500, 600) carries only the pull-quote text and the insight-card title; **JetBrains Mono** (weights 300, 400, 500) carries every structural label; **Noto Serif SC** is the CJK fallback for Lora; **Noto Sans SC** is the CJK fallback for Jost.
The emotional register is deliberate:
- Jost reads as **quiet, geometric, almost mathematical** at weight 200. It is the system's editorial voice.
- Lora italic reads as **literary, personal, hand-set**. It signals "this is the voice of a human or a quote" — wherever it appears, the tone shifts from analytical to lyrical.
- JetBrains Mono reads as **archival, indexical, structural**. It is the system's catalog-card voice — version numbers, dates, axis labels, anything that's metadata rather than message.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | 8.5vw | Jost | 200 | Cover or opening hero display — generous and airy |
| `{typography.h1}` | 5vw | Jost | 200 | Chapter-opening or section-break headline |
| `{typography.h2}` | 3.2vw | Jost | 300 | Primary content-slide headline |
| `{typography.stat-value}` | 5.5vw | Jost | 200 | Large numerical figure inside a stat cell |
| `{typography.quote-serif}` | 3.2vw | Lora italic | 400 | Pull-quote body text |
| `{typography.insight-serif}` | 2.8vw | Lora | 400 | Insight-card title |
| `{typography.h3}` | 2vw | Jost | 400 | Sub-headline, region heading, flow-step title |
| `{typography.lead}` | 1.5vw | Jost | 300 | Lead paragraph or large bullet item |
| `{typography.body}` | 1.1vw | Jost | 300 | Body paragraph |
| `{typography.caption}` | 0.85vw | Jost | 300 | Image caption, source note, fine print |
| `{typography.label}` | 0.72vw | JetBrains Mono | 400 | Kicker, chrome label, axis label, version tag |
| `{typography.flow-num}` | 3.5vw | Jost | 200 | Large step numeral in a process diagram |
### Defaults
- **Default primary section headline**: `{typography.h2}` (3.2vw at weight 300). Don't reach for `{typography.h1}` for a standard content slide — that size is for chapter breaks.
- **Default opening or cover display**: `{typography.display}` (8.5vw at weight 200).
- **Default body paragraph size**: `{typography.body}` (1.1vw at weight 300).
- **Default lead paragraph size**: `{typography.lead}` (1.5vw at weight 300) when a paragraph is the single supporting block under a headline.
- **Default label / kicker size**: `{typography.label}` (0.72vw).
- **Default weight for any display element**: 200. Jost at 200 is the system's display voice.
- **Default weight for body**: 300.
When unsure, the canonical pairing is `{typography.h2}` (weight 300) for the headline + one paragraph at `{typography.lead}` (weight 300) for the supporting block. The narrow weight gap (300 vs. 300, distinguished only by size) is correct — Ivory Ledger does not lean on heavy weight contrast.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Jost display, h1, h2, h3 element is mixed case** — never uppercase. Uppercase is reserved exclusively for JetBrains Mono labels.
- **Every label, kicker, chrome tag, footer, axis label, and source note uses JetBrains Mono uppercase with at least 0.12em positive tracking** (most are 0.14–0.18em). Mono in sentence case does not exist here.
- **The pull-quote body is always Lora italic.** A pull-quote in Jost reads as a different design system.
- **The insight-card title is always Lora roman (not italic).** The serif face is the card's defining visual signal.
- **The bullet-list marker is always an em-dash in JetBrains Mono colored `{colors.ink-graphite-light}`.** Never a dot, never a check, never a numeral.
- **Stat values, display headlines, and flow numerals all use Jost weight 200 with negative letter-spacing.** The combination of ultra-light weight and tight tracking is the system's display signature.
- **Headlines and body text are colored `{colors.ink-black}`; muted lead is `{colors.ink-graphite}`; labels are `{colors.ink-graphite-light}`.** Headlines never carry the graphite tones.
### Typography Principles
The rhythm of Ivory Ledger is **ultra-light Jost + Lora italic in two specific moments + tracked mono labels**. Switching Jost to a heavier weight (500+) for a headline reads as a different system. Setting body text in Lora reads as a different system. Setting a label in Jost rather than JetBrains Mono reads as a different system. The role of each face is narrow and unmoving.
Italic is used exclusively in Lora (pull-quote body) and not in Jost. Underline is not used anywhere. Bold is not used to emphasize body text — emphasis inside a paragraph is achieved either by Lora italic switch (rare) or by isolation through whitespace.
## Layout
### Canvas System
The system targets a fluid `100vw × 100vh` viewport with all sizes in `vw`/`vh`. The deck is a horizontal flex strip with slide-to-slide transitions at 0.9s with a smooth easing curve. Animation tokens (`fade-up`, `fade-in`, `reveal-right`, `reveal-left`, `scale-in`) are available with stagger delays via `data-delay` attributes — these run on each slide entrance.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 8vw | Slide horizontal padding (the most generous in the library) |
| `{spacing.pad-y}` | 6vh | Slide vertical padding |
| `{spacing.gap-lg}` | 5vh | Between major content sections |
| `{spacing.gap-md}` | 3vh | Between related elements |
| `{spacing.gap-sm}` | 1.5vh | Between tightly related elements |
The slide container reserves an additional 3.5vw on the left for a vertical sidebar element (currently disabled in the source — see Known Gaps), so total left padding is ~11.5vw. Content sits inside this generous gutter system.
### Chrome Frame
Most content slides carry a **chrome header** and **chrome foot**: each is a `flex space-between` row of two JetBrains Mono labels, separated from the slide body by a 1px solid black rule. Cover-style, chapter-break, quote, and closing slide types suppress chrome and foot entirely.
### Disabled Sidebar
The CSS defines a `.slide-sidebar` element — a thin vertical 1px black line in the left gutter with rotated mono labels reading bottom-to-top. The source explicitly disables this with `display: none !important`, with a comment noting it reads as "visual noise." The styling remains in the CSS as a dormant artifact; do not re-enable without intentional design rationale.
## Depth and Elevation
### No Shadows, Hairline Rules Only
The system uses **zero box-shadow declarations** on any structural element. Depth is created through three mechanisms:
1. **1px hairline rules in solid `{colors.ink-black}`** — under chrome bands, above foot bands, between compare panels, above stat cells, across timeline tracks, across chart baselines. The rule is the divider, the separator, the structural mark.
2. **The 36px short rule** (`{components.rule}`) — a small punctuation mark used under chapter labels, beside kickers, or as a delicate accent break.
3. **Generous whitespace** — the primary depth signal is the 8vw horizontal gutter and the space around each typographic moment.
### No Atmospheric Effects
There are no gradients, no glows, no textures, no grain overlays. Even the donut chart center cutout is just a same-color circle laid over the conic ring — there is no contrast jump.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | Every structural element — image placeholders, stat cells, compare panels, tables, chart areas |
| 16px | Insight cards only |
| 50% (circle) | Pie/donut chart shape, timeline-dot small circles, vt-spine dot |
| 999px (pill) | None — pills are not used |
The system is dominantly square-cornered. The 16px rounded radius on insight cards is the only structural soft edge and is the visual signal that distinguishes a card from a region.
### Border Weights
- **1px solid `{colors.ink-black}`** — the universal structural rule weight. Used for every divider, every chrome rule, every chart axis, every cell border.
- **2px solid `{colors.ink-black}`** — used only on the pyramid-bar left edge (`{components.pyramid-bar}`) as a slightly stronger left-anchor for that specific chart type.
There is no thicker border weight, no dashed border (except a `1px dashed` graphite hint inside dense charts), no colored border.
### Decorative Element Types
**36px short rule** — A small 36px-wide × 1px-tall solid black horizontal accent rule. The system's signature punctuation mark. Used under a chapter number, beside a kicker, or as a delicate section break.
**Kicker / mono eyebrow** — A muted JetBrains Mono uppercase label in `{colors.ink-graphite-light}` placed above a headline. The eyebrow is barely-there by design.
**Bordered tag** — A small inline element with a 1px black border and 0.3em × 0.8em padding, containing a mono uppercase string. Used for version tags or status labels.
**Bullet em-dash** — A `—` glyph in JetBrains Mono colored `{colors.ink-graphite-light}`, prepended to each list item via a CSS grid marker column (`grid-template-columns: 1.2em 1fr`).
**Insight card** — A 16px-rounded rectangle (`{components.insight-card}`) on a slightly warmer cream surface. Carries a Lora roman title (2.8vw weight 400) and a Jost body block (weight 300) pushed to the bottom of the card. The card is identified by its rounded corners and its serif title, not by a color contrast.
**Stat cell** — A vertical region with a 1px solid black top rule (`{components.stat-cell}`), containing a 5.5vw Jost-200 numeral, a Jost label, and a small mono source note. Three stat cells side by side is the canonical arrangement.
**Timeline dot** — An 8px solid black circle with a 2px cream-warm border ring (`{components.timeline-dot}`) that punches through the horizontal connector rule. The ring color matches the warm-cream slide surface so the dot reads as floating on the rule, not crossing it.
**Vertical timeline spine** — A 1px-wide vertical solid black line (`{components.vtimeline-spine}`) with 9px solid black dots at the top of each entry. Used in long chronological lists.
**Pie / donut chart** — A circle (`{components.pie-donut}`) at min(26vw, 42vh) size, with a same-color circular cutout via `::after` to create the donut ring. The chart sits beside a legend column.
**Pyramid bar** — A horizontal bar (`{components.pyramid-bar}`) with a 2px solid black left edge and a tonal cream-to-graphite fill computed via `color-mix(in srgb, ink-black N%, cream-paper)` where N ranges from 4% to 55% across the five levels. Widths step from 36% (top, darkest) to 100% (bottom, lightest).
**Vertical bar chart** — A muted graphite (`{colors.ink-graphite-light}`) bar at 50% opacity for default bars; a solid black bar at full opacity for the highlighted bar. The chart has a 1px black left axis and a 1px black baseline.
**Image placeholder** — A 1px-bordered cream-paper-3 rectangle with centered mono label. Used until photography arrives.
**Process flow with no arrows** — Flow diagrams in this system are explicit about not using arrows between steps. Whitespace between steps implies sequence; the system declares this with a comment in the CSS.
## Do's and Don'ts
### Do
- Use the cream paper background (`{colors.cream-paper}`) on every slide. The single-surface canvas is the system's foundation.
- Set every headline in `{colors.ink-black}` and let the weight (Jost 200) and size do the work. Headlines never need a chromatic shift.
- Use Jost at weight 200 for any display moment. The ultra-light weight is the system's defining typographic voice.
- Reach for Lora italic only when the text is a pull-quote body; reach for Lora roman only when it's an insight-card title. The serif's two roles are non-overlapping.
- Use JetBrains Mono uppercase with at least 0.12em tracking for every structural label, axis tag, footer, and bullet marker. Mono is the catalog-card voice.
- Render every structural divider as a 1px solid black rule. There is no thicker, no muted, no dashed border in the system.
- Apply the em-dash marker in muted graphite via JetBrains Mono for every bullet list.
- Leave generous whitespace. Content should sit comfortably in the middle 60–70% of the canvas; cramming content to the edges breaks the editorial reading.
### Don't
- Don't introduce a chromatic color. Red, blue, green, yellow do not exist in this system. The accent is darker ink.
- Don't use heavy weights (Jost 500, 600, 700) for headlines. The system reads as broken if display type weighs more than 300.
- Don't put a pull-quote in Jost. The Lora italic body is the quote's identity — switching to sans collapses the typographic distinction.
- Don't use box-shadow on any element. The system has no elevation.
- Don't use a card surface with chromatic contrast. Insight cards are identified by corner radius and serif title; a colored fill breaks the monochrome reading.
- Don't crowd a slide. The horizontal padding is 8vw for a reason — content needs to breathe.
- Don't use bold to emphasize body text. Inline emphasis is rare; when used, switch to Lora italic, not weight increase.
- Don't substitute the em-dash bullet marker with a dot, check, arrow, or numeral. The em-dash is the system's only list mark.
- Don't enable the disabled sidebar (`.slide-sidebar`). It's hidden intentionally — re-enabling it adds visual noise that the system was tuned to remove.
- Don't round any element other than insight cards (16px) or true circles (dots, donut). Square corners are the structural default.
## Responsive Behavior
The system is viewport-fluid by design. All sizes use `vw`/`vh` so the same composition renders correctly across any 16:9 viewport without breakpoints. At smaller viewports, both typography and padding scale linearly so the visual density and the negative-space ratio stay constant.
### Presenter Behavior
- Standard keyboard navigation: arrows, space, Home, End.
- Touch swipe for mobile.
- Mouse wheel with debounce to prevent multi-skip.
- Slide-to-slide transitions animate over 0.9s with a smooth easing curve.
- Each slide can declare entrance animations on individual elements via `data-anim` (fade-up, fade-in, reveal-right, reveal-left, scale-in) with stagger delays via `data-delay="N"` where N maps to a discrete delay step (0s, 0.08s, 0.18s, 0.3s, 0.44s, 0.6s, 0.78s, 0.96s).
- Elements with `[data-anim]` start invisible (opacity:0) and animate on `.is-active` — re-visiting a slide replays the entrance.
### Print Behavior
The template does not declare a `@media print` rule. Browser-driven PDF export will capture only the active slide; multi-slide export requires manual navigation per slide.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face | Chinese face | Weight |
|---|---|---|---|
| Display / headline (Jost 200) | Jost | Noto Sans SC (思源黑体) | 700 (heaviest available; CJK at 200 reads as broken — see Aesthetic Notes) |
| Body / lead (Jost 300) | Jost | Noto Sans SC (思源黑体) | 400 |
| Pull quote / insight title (Lora italic / roman) | Lora | Noto Serif SC (思源宋体) | 400 |
| Label / mono chrome (JetBrains Mono) | JetBrains Mono | Noto Sans SC | 400 (do not force monospace on CJK; see Aesthetic Notes) |
### Mixed-Content Strategy
Strategy A — same `font-family` stack, Latin-first fallback. Each typographic token already lists `"Jost, Noto Sans SC, system-ui, sans-serif"` (or the Lora equivalent). Latin glyphs render in Jost / Lora; CJK glyphs automatically fall through to Noto Sans SC / Noto Serif SC. No per-language class needed. Mixed sentences like `使用 Claude 思考` render in one logical run with the correct face per script.
### 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=Jost:wght@200;300;400;500;600&family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,500&family=JetBrains+Mono:wght@300;400;500&family=Noto+Sans+SC:wght@300;400;500;700;900&family=Noto+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation (,。:;!?「」())
- No period on display headlines (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence
### Aesthetic Notes for This System
Ivory Ledger's defining trait is Jost at weight 200 — paper-thin geometric strokes against cream. **Noto Sans SC does not have a usable weight 200.** Its lightest weight (300) still reads heavier than Jost 200 because Chinese glyphs carry far more strokes per character. Set Chinese display in **Noto Sans SC 700** to match the *visual presence* of Jost 200 on the cream paper (counterintuitive, but Chinese readers perceive lighter weights as anemic at large sizes). For body, Noto Sans SC 400 against Jost 300 is the correct match — the cream-paper-and-graphite ink moment carries across scripts.
Lora italic is the system's "human voice" in pull-quote bodies. **Noto Serif SC has no italic.** Drop italic entirely for Chinese pull quotes; the serif face itself carries the editorial warmth. Don't try to fake italic with `font-style: italic` — Noto Serif SC will render an auto-slanted glyph that looks broken.
JetBrains Mono's uppercase tracked labels (0.12–0.18em) do not transfer to CJK. **Set Chinese labels in Noto Sans SC 400, mixed case, with letter-spacing reset to 0.** The "catalog-card" voice in Chinese is achieved through the small size and the cream-paper-light color, not through monospace + tracking. If a label is pure Latin (a version number, a date), keep it in JetBrains Mono uppercase as originally designed.
The em-dash bullet marker (`—`) works perfectly in Chinese — the Chinese em-dash is also `—` and renders the same width. Keep the marker as-is.
### Known CJK Gap
The 8vw horizontal padding (the most generous in the library) was tuned for Latin's narrower glyph widths. Chinese characters are roughly square and consume more horizontal space at the same point size. Long Chinese headlines that would fit on one line in English may wrap to two. Reduce display headline sizes by ~15% (Jost 8.5vw → Noto Sans SC 7.2vw) when the headline is pure Chinese, or accept the wrap as part of the editorial rhythm.
## Iteration Guide
1. Any new slide background is `{colors.cream-paper}` (or `{colors.cream-warm}` for the insight/timeline sub-aesthetic). Never introduce a dark or chromatic background.
2. Any new headline uses Jost in mixed case at weight 200 (display, h1) or 300 (h2). Never reach for heavier weights.
3. Any new label, eyebrow, tag, or metadata text uses JetBrains Mono uppercase with at least 0.12em tracking colored `{colors.ink-graphite-light}`.
4. Any new structural divider is a 1px solid black rule. Use `{components.rule}` (36px short) for decorative accents and `{components.rule-full}` for region separation.
5. Any new pull-quote uses Lora italic at `{typography.quote-serif}` size. Quotes never appear in sans.
6. Any new card moment uses 16px rounded corners and a Lora roman title. Don't introduce square cards or sans-titled cards.
7. Any new bullet list uses the em-dash in muted graphite via JetBrains Mono.
8. Generous whitespace is a feature, not a missing layout. Don't fill space because it's available.
9. If you need to emphasize a moment, increase size or wrap a span in Lora italic. Do not introduce color.
10. Color tokens that look chromatic (e.g. `--c-accent`) are aliased to `{colors.ink-black}` — they exist for token compatibility but resolve to black. Don't add a chromatic value to them.
## Known Gaps
- The CSS defines a `.slide-sidebar` element (rotated mono labels in the left gutter) that is intentionally hidden via `display: none !important`. The dormant styles remain in the source; re-enabling without design review will add visual noise the system was tuned to remove.
- The three insight-card surface tokens (`--c-card-a`, `--c-card-b`, `--c-card-c`) resolve to two near-identical values (#FAFADF, #F5F0E4). The card "color variation" is effectively cosmetic — cards are distinguished by serif title and padding, not surface tone.
- The pie/donut chart uses a `::after` pseudo cutout that requires the chart background to match the slide surface. Slides with a different background (e.g., the cream-warm variant) need the `--c-bg-light` token adjusted for the cutout to disappear correctly.
- The pyramid chart uses `color-mix(in srgb, ...)` which requires a modern browser. Older browsers will render the bars as solid `{colors.cream-paper}`.
- The animation system requires the `.is-active` class to be applied to a slide for entrance animations to play. Without proper navigation engine wiring, `[data-anim]` elements will remain at opacity 0.
- Lora italic at large sizes (3.2vw quote body) has noticeably wider stroke contrast than the surrounding Jost — this is intentional but creates a perceived weight jump. Don't compensate by making the surrounding text heavier.
- The bar-chart `bar-fill` uses inline `style="height: XX%"` declarations — there's no data-binding layer. Heights are computed manually.
- The system was originally named "Ivory Ledger" in the source comments. The template is exposed in the library as "Monochrome"; both names refer to the same design system.
# Monochrome Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/monochrome/design.md`
- Preview card: `bold-template-pack/templates/monochrome/preview.md`
## Selection Metadata
- Slug: `monochrome`
- Tagline: Ivory ledger paper with all-black type; Lora serif headlines, Jost body, no color at all.
- Mood: restrained, literary, archival, ledger
- Tone: literary, considered, neutral, honest
- Formality: high
- Density: high
- Scheme: light
- Best for: Anything that should feel like a hand-typeset ledger: user research synthesis, white papers, longform reports, academic and policy briefs, advisory deliverables, bilingual EN/CN reports. Equally good for tech, design, or brand decks that want their words to be the only thing on the page.
- Avoid for: Decks that need visual personality or color-led storytelling — the all-ink palette is intentionally austere.
## Visual Snapshot
A literary editorial system rendered in black ink on cream paper. Ultra-light geometric sans (Jost at weight 200–300) carries every headline; Lora italic serif handles quote text and insight-card titles; JetBrains Mono provides the structural chrome. There are no chromatic accents — every color in the palette is a graphite or cream tone, and "accent" simply means "darker ink." The aesthetic borrows from independent research reports, scholarly monographs, and the quietest end of contemporary editorial design — closer to a printed journal than a tech presentation.
Monochrome (Ivory Ledger) is a literary editorial system built on a single material constraint: black ink on cream paper, and nothing else. The palette has eight tokens, but seven of them are tonal variations of cream or graphite. There is no chromatic accent — the "accent" color is just darker ink. The result is a system that reads as a carefully typeset research report or a quiet contemporary monograph, not a presentation.
## Preview Ingredients
- Palette: cream-paper #FAFADF; cream-paper-2 #F2F2D2; cream-paper-3 #F0F0D4; cream-warm #F5F0E4; ink-black #1A1A16; ink-graphite #5E5E54; ink-graphite-light #8A8A80
- Typography: Jost; JetBrains Mono; Lora; {typography.label.fontFamily}
- Signature move: Cream paper background ({colors.cream-paper}) on every slide — never white, never dark by default. The cream is the surface, not a stylistic choice.
- Signature move: Ultra-light Jost (weight 200 for display, weight 300 for body) is the dominant typographic voice.
- Signature move: Lora italic serif appears in two specific moments: pull-quote bodies and insight-card titles. Nowhere else.
- Signature move: JetBrains Mono uppercase with 0.12em+ tracking handles every structural label, chrome tag, axis, and bullet marker.
- Signature move: The system has no chromatic accent. The accent color is {colors.ink-black} — slightly darker ink.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Neo-Grid Bold
description: A heavy editorial poster system built on a strict 12-column × 8-row block grid with neon-yellow accents on putty-ecru. Space Grotesk at weight 700 in strict uppercase carries every display moment; JetBrains Mono carries every label and metadata tag. Each slide reads as a magazine spread divided into colored panels — paper-ecru, ink-black, and electric lemon-yellow trading roles across cells. The aesthetic borrows from contemporary editorial print, brutalist annual reports, and the populist-poster end of design week showcases.
colors:
paper: "#F5F4EF"
bg: "#ECECE8"
ink: "#0A0A0A"
accent-lemon: "#E6FF3D"
muted: "#8A8A85"
stage-bg: "#1A1A1A"
color-aliases:
line: ink
primary-bg: bg
card-bg: paper
typography:
display:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 132px
fontWeight: 700
lineHeight: 0.92
letterSpacing: -0.02em
textTransform: uppercase
title:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 88px
fontWeight: 700
lineHeight: 0.95
letterSpacing: -0.015em
textTransform: uppercase
subtitle:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 56px
fontWeight: 700
lineHeight: 1.0
letterSpacing: -0.01em
textTransform: uppercase
section-num:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 320px
fontWeight: 700
lineHeight: 0.85
letterSpacing: -0.05em
stat-num:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 156px
fontWeight: 700
lineHeight: 0.9
letterSpacing: -0.03em
stat-num-lg:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 240px
fontWeight: 700
lineHeight: 0.85
letterSpacing: -0.04em
stat-num-sm:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 96px
fontWeight: 700
lineHeight: 0.9
letterSpacing: -0.03em
card-headline:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 44px
fontWeight: 700
lineHeight: 1.0
letterSpacing: -0.01em
textTransform: uppercase
card-h3:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 30px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.005em
textTransform: uppercase
body:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 28px
fontWeight: 400
lineHeight: 1.35
body-sm:
fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
fontSize: 22px
fontWeight: 400
lineHeight: 1.45
label:
fontFamily: "JetBrains Mono, ui-monospace, monospace"
fontSize: 24px
fontWeight: 400
letterSpacing: 0.08em
textTransform: uppercase
label-sm:
fontFamily: "JetBrains Mono, ui-monospace, monospace"
fontSize: 16px
fontWeight: 400
letterSpacing: 0.08em
textTransform: uppercase
label-xs:
fontFamily: "JetBrains Mono, ui-monospace, monospace"
fontSize: 14px
fontWeight: 400
letterSpacing: 0.12em
textTransform: uppercase
pagenum:
fontFamily: "JetBrains Mono, ui-monospace, monospace"
fontSize: 24px
fontWeight: 400
letterSpacing: 0.04em
spacing:
frame-inset: 40px
grid-gap: 12px
grid-gap-lg: 18px
card-pad-sm: "24px 28px"
card-pad-md: "28px 32px"
card-pad-lg: "36px 32px"
card-pad-xl: "40px 44px"
canvas:
width: 1920px
height: 1080px
components:
frame:
position: "absolute; inset: 40px"
display: grid
gridTemplateColumns: "repeat(12, 1fr)"
gridTemplateRows: "repeat(8, 1fr)"
gap: "{spacing.grid-gap}"
description: "The universal slide frame — a 12-column × 8-row CSS grid inset 40px from each slide edge with 12px gaps between cells. Every slide composes its layout by spanning cells inside this frame."
card:
background: "{colors.paper}"
position: relative
overflow: hidden
description: "Generic colored panel. Paper is the default fill; .ink switches to black with paper text; .lemon switches to yellow with ink text; .photo switches to deep-black with white text for image regions."
card-ink:
background: "{colors.ink}"
color: "{colors.paper}"
description: "Inverted card — black background, paper text. Used as a contrast block in any composition."
card-lemon:
background: "{colors.accent-lemon}"
color: "{colors.ink}"
description: "Yellow accent card — full neon-yellow fill with ink text. The system's loudest signal."
pagenum:
position: "absolute; left: 0; bottom: 0"
background: "{colors.paper}"
color: "{colors.ink}"
padding: "14px 22px"
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.04em
description: "Bottom-left page-number tag in the format '01 / 12'. Three variants: default (paper bg), .invert (ink bg), .lemon (yellow bg)."
corner-mark:
position: "absolute; top: 22px; right: 22px"
width: 36px
height: 36px
display: "grid 2x2"
gap: 4px
description: "Top-right 2x2 block mark — three solid currentColor squares plus one transparent. A small structural identity stamp."
blockmark:
width: 56px
height: 56px
display: "grid 2x2"
gap: 4px
description: "Larger 2x2 block stamp with diagonal squares filled — used as a brand mark on covers and dividers. May be sized 56px, 96px, or larger."
qr-tile:
width: 90px
height: 90px
display: "grid 5x5"
description: "Decorative QR-pattern tile composed of a 5x5 grid of black squares with some accent-lemon squares interspersed. Decorative, not a real scannable code."
table-cell:
padding: "18px 22px"
borderBottom: "1.5px solid {colors.ink}"
borderRight: "1.5px solid {colors.ink}"
fontSize: 24px
lineHeight: 1.35
description: "Comparison-matrix cell. Solid hairline ink dividers on bottom and right; last column has no right border."
table-head-row:
background: "{colors.ink}"
color: "{colors.paper}"
fontFamily: "JetBrains Mono, monospace"
fontSize: 14px
letterSpacing: 0.12em
textTransform: uppercase
description: "Inverted table header — black row with paper mono uppercase text."
pill-yes:
background: "{colors.accent-lemon}"
color: "{colors.ink}"
padding: "6px 14px"
description: "Affirmative pill in a comparison cell — yellow fill, ink text, mono uppercase."
pill-part:
background: "{colors.paper}"
color: "{colors.ink}"
border: "1.5px solid {colors.ink}"
description: "Partial-state pill — paper fill, ink border, ink text."
pill-no:
background: "{colors.ink}"
color: "{colors.paper}"
description: "Negative pill — black fill, paper text."
arrow:
width: 64px
height: 64px
description: "Inline SVG arrow glyph (right-pointing) at 64px square. Used as a flow indicator between process steps and as an out-of-cell pointer on stat cards."
highlight-mark:
background: "{colors.accent-lemon}"
color: "{colors.ink}"
padding: "0 6px"
description: "Inline <mark> element — yellow background swatch wrapping one or more words inside a headline for emphasis."
bar-fill-ink:
background: "{colors.ink}"
description: "Solid black vertical bar for chart series A."
bar-fill-lemon:
background: "{colors.accent-lemon}"
border: "1.5px solid {colors.ink}"
description: "Yellow vertical bar with ink border for chart series B."
copyright:
position: "absolute; left: 22px; bottom: 22px"
fontFamily: "JetBrains Mono, ui-monospace, monospace"
fontSize: 16px
lineHeight: 1.4
color: "{colors.ink}"
opacity: 0.85
---
## Frontend Slides Fixed-Stage Policy
When this design system is used by the `frontend-slides` skill, generate the final deck as a **fixed 1920×1080 stage** that scales uniformly to the browser viewport. The deck should preserve a 16:9 slide canvas on every screen, including phones; it may letterbox or pillarbox, but it should not reflow slide content for mobile.
This policy has higher priority than any source-template responsive behavior described later in this file. If a later section says the original template is viewport-fluid, treat that as source history only, not as the target generation model for `frontend-slides`.
This policy applies even if the source template was originally implemented with viewport-fluid CSS such as `100vw`, `100vh`, `vw`, `vh`, or `clamp()`. Treat those values as design proportions to translate into 1920×1080 stage coordinates, not as live responsive rules in the generated deck.
Use `deck-stage.js` or an equivalent inline stage scaler for final output: render each slide at 1920×1080, scale the whole stage with one transform, and verify rendered screenshots for both text overflow and panel overlap.
## Overview
Neo-Grid Bold is a **heavy editorial poster system** built on a single structural premise: every slide is a 12-column × 8-row CSS grid inset 40px from the slide edges, with 12px gaps between cells. Composition happens by assigning colored panels to grid spans — `grid-column: 4 / span 5` and `grid-row: 1 / span 5` is how layout is described. The grid is rigid; the visual variety comes from how panels of `{colors.paper}`, `{colors.ink}`, and `{colors.accent-lemon}` are arranged across cells.
The typeface stack is intentionally narrow. **Space Grotesk** at weight 700 carries every display moment in strict uppercase with negative letter-spacing. Body copy runs at weight 400 in mixed case. **JetBrains Mono** at weight 400 carries every label, page number, axis tag, and metadata string — always uppercase with 0.08–0.12em positive tracking. There is no third face. The contrast between heavy Space Grotesk uppercase and JetBrains Mono uppercase is the system's primary typographic rhythm.
The palette has three working colors plus a putty surface. **Paper** (`{colors.paper}` — a warm ecru off-white) is the default panel fill. **Ink** (`{colors.ink}` — a near-black) is the structural color: text on paper, fills for inverted panels, all dividers, all rules. **Accent Lemon** (`{colors.accent-lemon}` — an electric neon-yellow #E6FF3D) is the loud signal — used as panel fill, as a highlight `<mark>` swatch inside headlines, and as the second series in charts. **Putty BG** (`{colors.bg}`) is the slightly cooler ecru that sits behind the 40px slide inset, framing the composition like a passe-partout. **Muted graphite** is present in the token list but rarely used in practice.
Depth is created entirely through **panel adjacency and color contrast**, not shadows. Cards do not carry box-shadows; cards do not have rounded corners; cards do not have borders (except for table cells and pill outlines, which use 1.5px solid ink). The visual weight of a slide is determined by how many cells are filled with `{colors.ink}` vs. `{colors.accent-lemon}` vs. `{colors.paper}`. A composition with three yellow panels reads as much more aggressive than one with a single yellow panel.
**Density philosophy: dense.** Neo-Grid Bold reads as authoritative when the 12×8 grid is fully populated with panels of varying span and color. A slide with only one or two panels and large empty grid areas reads as broken; the system was designed as an editorial poster, and posters are dense. The expected pattern is 4–8 panels per slide, each occupying a non-trivial cell span, with the grid fully used corner-to-corner. The exception is a section-divider slide where a single 320px section number occupies an entire pane of the grid — but even there, the rest of the canvas is filled with a second panel of contrasting color.
**Key Characteristics:**
- Universal 12-column × 8-row CSS grid (`{components.frame}`) inset 40px from each slide edge, with 12px gaps between cells.
- Three-color panel system: paper ecru (`{colors.paper}`) as default, ink black (`{colors.ink}`) for inverted blocks, accent lemon (`{colors.accent-lemon}`) for signal blocks.
- Space Grotesk weight 700 uppercase with negative letter-spacing for every display element.
- JetBrains Mono uppercase with 0.08–0.12em tracking for every label, page number, axis tag.
- A signature corner-mark and blockmark — small 2×2 block stamps that act as decorative identity tags.
- Inline `<mark>` element that wraps words inside a headline in a neon-yellow swatch — the system's headline emphasis mechanism.
- A persistent page-number tag (`{components.pagenum}`) anchored bottom-left of every slide.
- No rounded corners, no drop shadows, no gradients (apart from photo-region stylized noise textures).
- Stat numerals scale up to 240px and even 320px — type is allowed to dominate entire panels.
## Colors
### Palette
- **Paper** (`{colors.paper}` — #F5F4EF): Warm ecru off-white. The default panel fill, the default text color when inverted, and the canvas of any "neutral" card. Slightly creamier than pure white — chosen so the neon-yellow accent doesn't vibrate against it.
- **BG (Putty)** (`{colors.bg}` — #ECECE8): A cooler ecru that sits behind the 40px slide inset, framing the grid composition like a passe-partout. The 40px border of putty around every slide is the system's universal frame.
- **Ink** (`{colors.ink}` — #0A0A0A): The structural near-black. Used for all text on paper, all inverted panel fills, all dividers, all table cell borders, all pill outlines. Not pure #000 — slightly softer.
- **Accent Lemon** (`{colors.accent-lemon}` — #E6FF3D): Electric neon-yellow. The signal color. Used as a panel fill, as the inline `<mark>` highlight swatch inside headlines, as the second chart series, as the affirmative pill fill, and as page-number variant background. Never as a text color (the yellow is too light to read as type against any surface).
- **Muted** (`{colors.muted}` — #8A8A85): A reserved graphite tone present in the token list but used only at low opacity on photo-region tags. Available for de-emphasized text but rarely deployed.
- **Stage BG** (`{colors.stage-bg}` — #1A1A1A): The viewport background outside the 1920×1080 slide canvas. This is the deck-stage container color, not part of slide design.
### Defaults
- **Default slide canvas background**: `{colors.bg}` — visible as the 40px putty frame around every grid composition.
- **Default panel fill**: `{colors.paper}`. When in doubt, a panel is paper.
- **Default primary headline color**: `{colors.ink}` on paper or lemon panels; `{colors.paper}` on ink panels.
- **Default body text color**: `{colors.ink}` on paper/lemon; `{colors.paper}` on ink.
- **Default label / metadata color**: `{colors.ink}` on paper, at opacity 0.7–0.85 to mute; `{colors.paper}` on ink, at opacity 0.7–0.85.
- **Default chart series color**: `{colors.ink}` for series A; `{colors.accent-lemon}` for series B (with 1.5px ink border).
- **Default emphasis mechanism inside a headline**: wrap in `<mark>` for a neon-yellow swatch on ink text. This is the system's primary headline-level emphasis.
- **Default affirmative state**: `{colors.accent-lemon}` fill. Default negative state: `{colors.ink}` fill. Default neutral state: `{colors.paper}` fill with `{colors.ink}` border.
Neon yellow is the system's only chromatic accent — never substitute red, blue, or any third color. Yellow's role is to draw the eye, not to communicate meaning (it is not "warning" or "highlight" in the semantic sense; it is simply the signal).
## Typography
### Font Family
The system uses two web fonts: **Space Grotesk** (weights 400, 500, 700) for all display and body, and **JetBrains Mono** (weights 400, 500) for all labels and metadata. There is no third face — no serif, no italic, no display script. The system's character lives in the weight contrast between Space Grotesk 700 uppercase and Space Grotesk 400 mixed case, plus the structural mono labels in JetBrains Mono.
A specific inline mixing rule: **the `<em>` tag inside a Space Grotesk headline switches color to `{colors.accent-lemon}` and stays upright** (font-style is normalized to non-italic). Em is repurposed as a yellow inline color switch, like the `<mark>` swatch but without the background fill.
A second inline mixing rule: **the `<mark>` element wraps words inside a Space Grotesk headline in a neon-yellow swatch with 0 6px padding**, creating the highlighter-pen emphasis that is a recurring signature of the system.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.section-num}` | 320px | Space Grotesk | 700 | Hero section ordinal in a section-divider panel |
| `{typography.stat-num-lg}` | 240px | Space Grotesk | 700 | Featured large numerical stat |
| `{typography.stat-num}` | 156px | Space Grotesk | 700 | Standard stat numeral |
| `{typography.display}` | 132px | Space Grotesk | 700 | Cover, section, or hero display headline |
| `{typography.stat-num-sm}` | 96px | Space Grotesk | 700 | Compact stat numeral inside a small card |
| `{typography.title}` | 88px | Space Grotesk | 700 | Primary content-slide headline |
| `{typography.subtitle}` | 56px | Space Grotesk | 700 | Secondary headline, region heading |
| `{typography.card-headline}` | 44px | Space Grotesk | 700 | Card title at panel-fill scale |
| `{typography.card-h3}` | 30px | Space Grotesk | 700 | Sub-headline inside a smaller card |
| `{typography.body}` | 28px | Space Grotesk | 400 | Body paragraph inside a feature card |
| `{typography.label}` | 24px | JetBrains Mono | 400 | Standard mono label or kicker |
| `{typography.body-sm}` | 22px | Space Grotesk | 400 | Compact body inside dense cards |
| `{typography.pagenum}` | 24px | JetBrains Mono | 400 | Page-number tag (e.g. "01 / 12") |
| `{typography.label-sm}` | 16px | JetBrains Mono | 400 | Secondary metadata label, copyright text |
| `{typography.label-xs}` | 14px | JetBrains Mono | 400 | Axis labels, table header text, fine print |
### Defaults
- **Default primary section headline**: `{typography.title}` (88px) — the workhorse content-slide headline.
- **Default cover or section-opening display**: `{typography.display}` (132px) for a cover; `{typography.section-num}` (320px) for a section-divider ordinal.
- **Default body paragraph size**: `{typography.body}` (28px). For dense multi-card slides, drop to `{typography.body-sm}` (22px).
- **Default label / metadata size**: `{typography.label}` (24px) for standalone mono tags; `{typography.label-sm}` (16px) for inline metadata.
- **Default stat numeral**: `{typography.stat-num}` (156px). Reach for `{typography.stat-num-lg}` (240px) only when the stat occupies an entire featured panel.
- **Default weight for any display element**: 700. Display in any other weight does not exist in this system.
- **Default weight for body**: 400.
When unsure, reach for `{typography.title}` for the slide's primary text moment and pair it with `{typography.body}` for supporting copy.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Space Grotesk display, title, subtitle, card-headline, and stat numeral is uppercase** with negative letter-spacing (-0.005 to -0.05em depending on scale). Mixed-case display does not exist in this system.
- **Body copy is mixed case at weight 400.** Never uppercase body.
- **Every JetBrains Mono element is uppercase** with at least 0.08em positive tracking.
- **The `<mark>` element inside a headline always uses `{colors.accent-lemon}` background with `{colors.ink}` text and 0 6px padding.** The yellow highlighter swatch is the system's headline emphasis signal.
- **The `<em>` element inside a headline switches to `{colors.accent-lemon}` color and stays upright (font-style: normal).** Italic letterforms are not used.
- **Negative letter-spacing scales with size**: smaller headlines use -0.005em to -0.015em; larger displays use -0.02 to -0.05em. The tighter the tracking, the more compressed and brutalist the headline reads — at 320px size, -0.05em is correct.
- **Page numbers are always JetBrains Mono at 24px with 0.04em tracking** in the format `01 / 12` with a single padded zero and slash separator.
### Typography Principles
The rhythm is **heavy uppercase display + light mixed-case body + small uppercase mono label**. Switching any of those three modes breaks the editorial register. Body in uppercase reads as a shouting paragraph. Display in mixed case reads as a different design system. Mono in mixed case reads as code, not editorial metadata.
Italic letterforms are not used. The `<em>` and `<mark>` tags are repurposed as color/highlight switches, not italic emphasis. Underline is not used. Bold inside body text is not used — emphasis is achieved by isolating the headline in its own cell.
## Layout
### Canvas System
The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component that handles scaling to fit the viewport. All sizes are in `px` (not vw/vh) — typography sizes, padding values, grid gaps, and inset values are all pixel-fixed. The composition is designed at 1920×1080 and the stage scales the entire deck proportionally.
The viewport background outside the deck stage is `{colors.stage-bg}` (#1A1A1A) — a dark gray frame that visually anchors the bright slide against the browser chrome.
### The Universal Frame
Every slide carries a `.frame` div positioned `absolute; inset: 40px` with `display: grid; grid-template-columns: repeat(12, 1fr); grid-template-rows: repeat(8, 1fr); gap: 12px`. This is the structural constant of the system: a 12-column × 8-row grid with 12px gaps, inset 40px from the slide edges. Some slide variants increase the grid gap to 16–18px for breathing room, but the column/row counts and the 40px inset never change.
Composition happens entirely by spanning cells inside this grid. A panel occupying `grid-column: 1 / span 4; grid-row: 1 / span 3` is a 4-cell-wide × 3-row-tall card in the upper-left. The grid is the only layout language — flexbox is used only for internal alignment inside a single cell.
### Padding Inside Cells
Internal padding inside a cell varies with cell size and purpose:
- Compact cards (small stat tiles): 24px × 28px
- Standard cards (feature panels): 28px × 32px
- Large cards (chapter panels): 36px × 32px
- Hero cards (section dividers): 40px × 44px
These are not rigid tokens — they're a practical scale. Choose the padding that gives the card's internal type room to breathe without losing the panel's identity.
### Persistent Chrome
Every slide carries a `{components.pagenum}` tag bottom-left in the format `01 / 12`. Three variants:
- Default: paper background, ink text.
- `.invert`: ink background, paper text.
- `.lemon`: yellow background, ink text.
Some slides also carry a `{components.corner-mark}` (small 2×2 block) top-right, a `{components.copyright}` bottom-left, or a `{components.blockmark}` (larger 2×2 stamp) as a brand identifier.
## Depth and Elevation
### No Shadows, Color-Block Adjacency Only
The system uses **zero box-shadow declarations** on any structural panel. Depth is entirely a function of color adjacency: a paper panel next to an ink panel reads as elevated (paper toward viewer); a yellow panel next to an ink panel reads as the loudest signal in the composition. The 12px grid gap between panels reveals the putty `{colors.bg}` between cells, which acts as a unifying frame color.
### No Gradients (Except Photo Regions)
The only gradients in the system are inside photo-region placeholder textures, where a `radial-gradient` plus a `repeating-linear-gradient` creates a stylized B&W-grain texture as a stand-in for photography. These textures live inside cells classed `.photo` or `.ph`, never on a structural panel.
### Borders on Tables and Pills
- Table cells (`{components.table-cell}`) use 1.5px solid ink dividers on bottom and right edges to create a wireframe grid.
- Comparison pills (`{components.pill-part}`) use a 1.5px solid ink border as the partial-state outline.
- Chart axes use 2px solid ink as the bottom-left wireframe.
- The yellow bar in a bar chart (`{components.bar-fill-lemon}`) carries a 1.5px solid ink border to prevent the bright fill from vibrating against the paper background.
No other elements carry borders. Cards are borderless and rely on fill contrast.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | Every element — cards, pills, tags, page numbers, table cells, chart bars, blockmarks |
The system has **zero border-radius** on any element. Every shape is a strict rectangle or square. The block-stamp and corner-mark glyphs are composed of right-angle squares.
### Border Weights
- **1.5px solid `{colors.ink}`** — used on table cell dividers, pill outlines, and the yellow bar's border. The most common border weight.
- **2px solid `{colors.ink}`** — used on chart axes (left and bottom of the plot area) for slightly stronger wireframe.
No other border weights exist. There are no muted-color borders, no dashed borders (except a very specific `1px dashed rgba(0,0,0,.18)` chart grid line used internally).
### Decorative Element Types
**Block stamp (`{components.blockmark}`)** — A 2×2 grid of small squares with the top-left and bottom-right cells filled (and the other two transparent). A diagonal-fill stamp that acts as a brand identity mark. Sized from 36px (corner-mark) up to 96px (block stamp on quote slides). May render in ink or accent-lemon.
**Corner mark (`{components.corner-mark}`)** — A 36px × 36px version of the block stamp anchored top-right of a panel. Acts as a small structural identity tag.
**QR tile (`{components.qr-tile}`)** — A 5×5 grid of small squares with a checkerboard-like pattern of ink and accent-lemon fills. Decorative QR-pattern visual, not a real scannable code. Used as a cover-slide flourish.
**Arrow (`{components.arrow}`)** — An inline SVG right-pointing arrow at 64px × 64px (or 24px × 24px for small flow indicators). Used as a flow signal between process steps and as an out-pointing indicator on stat panels.
**Highlight mark (`{components.highlight-mark}`)** — A neon-yellow swatch wrapping one or more words inside a headline via the `<mark>` element. The system's headline emphasis mechanism. Padding is `0 6px` (or `0 8px` at larger sizes).
**Page number (`{components.pagenum}`)** — Bottom-left position-tag in the format `01 / 12` with a colored background. The three background variants (paper, ink, lemon) let the page number adapt to whichever color is most visible against the active slide's dominant panels.
**Photo region** — A cell classed `.photo` with a deep-black background (#111) containing a `.ph` child that renders a stylized B&W noise texture (radial + diagonal stripes). A small mono tag inside the cell labels the region (e.g., "PORTRAIT / B&W"). Used as a placeholder until real photography arrives.
**Pills (`{components.pill-yes}`, `{components.pill-part}`, `{components.pill-no}`)** — Inline mono uppercase labels in a comparison cell with three color states: yellow fill (affirmative), paper with ink border (partial), ink fill with paper text (negative). All three are 0-radius rectangles, not rounded pills despite the name.
**Section ordinal panel** — A panel containing a 320px Space Grotesk weight-700 numeral as the entire content. Used as the visual identity of a section-divider slide; the rest of the slide carries a complementary headline panel in ink.
**Chart bar pair** — Vertical bars in groups of two (series A in solid ink, series B in yellow with ink border). The bars share equal width inside their column and the column gap is set by the parent grid.
## Do's and Don'ts
### Do
- Compose every slide on the 12-column × 8-row grid (`{components.frame}`) with 40px inset and 12px (or 18px for breathing room) gaps. The grid is the system's identity.
- Fill the grid corner to corner. The system reads as authoritative when the grid is densely populated with panels of varying span.
- Use `{colors.paper}` as your default panel fill, `{colors.ink}` for contrast blocks, and `{colors.accent-lemon}` for one to three signal panels per slide.
- Set every display, title, subtitle, and stat numeral in Space Grotesk 700 uppercase with negative letter-spacing. The combination is the system's typographic voice.
- Use `<mark>` inside a headline to wrap one or more words in a yellow highlighter swatch — the system's primary headline emphasis.
- Use `<em>` inside a headline to switch one word to accent-lemon color (stays upright, no italic).
- Place a `{components.pagenum}` tag bottom-left of every slide. Choose the background variant (paper / ink / lemon) that contrasts with the lower-left panel.
- Use JetBrains Mono uppercase with at least 0.08em tracking for every label, page number, axis tag, and metadata string.
- Render pills (yes / part / no) in their canonical three-color treatment inside comparison tables.
- Allow stat numerals to scale to 156–320px when they occupy a featured panel. Large numbers are part of the editorial poster identity.
### Don't
- Don't add box-shadow to any panel. Depth comes from color adjacency only.
- Don't round any corner on any element. The system is strictly rectangular.
- Don't put display headlines in mixed case. Space Grotesk display is always uppercase.
- Don't put body copy in uppercase. Mixed case at weight 400 is the body voice.
- Don't introduce a second accent color. Neon yellow is the only chromatic accent — adding red, blue, or green breaks the system.
- Don't use the yellow as a text color. The accent is too light to read as type; it's a fill color only.
- Don't compose layouts outside the 12×8 grid. Absolutely-positioned elements that break the grid (page number, corner mark, copyright) are explicitly the only exceptions.
- Don't use italic letterforms. The `<em>` tag is repurposed as a color switch — italic visual style does not exist here.
- Don't use rounded "pill" shapes despite the pill component naming. Pills are 0-radius rectangles.
- Don't sparsely populate the grid. A slide with one panel and seven empty cells reads as broken — the system needs density to function as an editorial poster.
## Responsive Behavior
The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component (loaded via `deck-stage.js`). The stage scales the entire 1920×1080 composition proportionally to fit the browser viewport — type sizes, panel positions, grid gaps, and inset values are all pixel-fixed inside the canvas, and the stage handles the responsive transform.
This means: every typographic and layout decision in the system is made at 1920×1080 resolution. Sizes do not scale per breakpoint; the entire canvas scales as a single unit. There are no media queries inside slide styles.
### Presenter Behavior
- The `<deck-stage>` web component manages slide-to-slide navigation, viewport scaling, and presenter chrome.
- Keyboard navigation, touch swipe, and mouse wheel are handled by the stage component, not by inline scripts.
- The slide canvas is constant 1920×1080 regardless of browser viewport; the stage proportionally scales it.
### Frontend Slides Integration Note
When using this design system inside the `frontend-slides` skill, preserve the
fixed 1920×1080 canvas model. Do not translate the 12-column × 8-row grid,
fixed typography, and fixed spacing into independent viewport-responsive
`clamp()` values. That breaks the relationship between panel size and type
scale, especially with CJK text, and can create clipping even when the original
template would have scaled cleanly.
The safe single-file implementation is:
1. Render each slide as a 1920×1080 `.stage`.
2. Scale that stage proportionally to fit the current viewport.
3. Keep the internal `.frame` grid at `inset: 40px`, `12` columns, `8` rows,
and `12px` gaps.
4. Fit content at the 1920×1080 design size first, then scale the whole stage.
5. Verify both text overflow and panel overlap in the rendered browser. A
`scrollHeight` check can pass while one grid panel visually covers another.
### Print Behavior
The template uses the deck-stage component for rendering. Print export depends on the component's print handling, which may render slide-per-page or capture the active slide only.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face | Chinese face | Weight |
|---|---|---|---|
| Display / title / stat (Space Grotesk 700 UPPERCASE) | Space Grotesk | Noto Sans SC (思源黑体) | 900 |
| Body (Space Grotesk 400) | Space Grotesk | Noto Sans SC | 400 |
| Label / page number (JetBrains Mono UPPERCASE) | JetBrains Mono | Noto Sans SC | 400 (do not force monospace on CJK) |
### Mixed-Content Strategy
Strategy A — single `font-family` stack with Latin-first fallback. Update each token's `fontFamily` from `"Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"` to `"Space Grotesk, Noto Sans SC, Helvetica Neue, Helvetica, Arial, sans-serif"`. Latin glyphs render in Space Grotesk 700; CJK characters fall through to Noto Sans SC 900 automatically. Mixed strings like `THE CLAUDE 模型` render correctly inline.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=JetBrains+Mono:wght@400;500&family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation (,。:;!?「」())
- No period on display headlines (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence
### Aesthetic Notes for This System
Neo-Grid Bold is heavy uppercase Space Grotesk 700 with negative letter-spacing at sizes up to 320px. **Chinese has no concept of uppercase**, so the system's primary typographic signature (uppercase brutalist headlines) must transfer through *weight and density* instead. Set every Chinese display moment in **Noto Sans SC 900** — the heaviest available weight — to match the visual weight of Space Grotesk 700 ALL CAPS at large sizes. Chinese headlines should also drop the negative letter-spacing entirely; CJK glyphs are designed on a square em-box and tightening them causes glyph collision.
The `<mark>` neon-yellow swatch highlighting one word inside a headline is a perfect transfer to Chinese — wrap one CJK character or one phrase in `<mark>` and the lemon swatch reads the same. **Keep the highlighter mechanism as the system's primary headline emphasis in CJK.** The `<em>` color switch (yellow inline) also transfers cleanly.
JetBrains Mono uppercase labels (page numbers in `01 / 12` format) are pure Latin / numeric — keep them in JetBrains Mono. Don't try to render Chinese in monospace; CJK glyphs are already monospaced by design and forcing JetBrains Mono produces missing glyphs. For mixed mono labels containing CJK, fall through to Noto Sans SC 400 at the same size.
Section numerals (320px Space Grotesk 700) and stat numerals (156–240px) are pure digits — they transfer unchanged. The neon-yellow accent panel system is script-agnostic; the brutalist poster aesthetic survives the script switch as long as the weight stays at 900.
### Known CJK Gap
The negative letter-spacing (-0.005 to -0.05em) scales with display size in this system and is part of the "brutalist compressed" signature. **Removing it for Chinese characters breaks visual parity with Latin slides in a mixed deck.** Accept this: pure-CJK slides will read as slightly less compressed than pure-Latin slides. Don't try to compensate by tightening Chinese — glyph collision is a worse failure than tonal mismatch.
## Iteration Guide
1. Every new slide composes its layout on the 12×8 grid via `grid-column` and `grid-row` span declarations. Never break the grid with absolute positioning except for the page-number tag, corner-mark, and copyright stamp.
2. Every new panel uses one of three fill colors: paper (default), ink (inverted), or accent-lemon (signal). Don't introduce a fourth panel color.
3. Every new display headline is Space Grotesk weight 700 uppercase with negative letter-spacing scaled to the headline size (-0.005em at 30px, up to -0.05em at 320px).
4. Every new body element is Space Grotesk weight 400 mixed case at one of the three body sizes (28px, 24px, 22px).
5. Every new label or metadata tag is JetBrains Mono uppercase with at least 0.08em tracking.
6. Every new chart-series color is either `{colors.ink}` (series A) or `{colors.accent-lemon}` with an ink border (series B). Don't add a third series color.
7. Every new card uses 0 border-radius. Square corners are non-negotiable.
8. To emphasize a word inside a headline, wrap it in `<mark>` for a yellow swatch or `<em>` for a yellow color switch. Don't use bold, italic, or underline.
9. Every new comparison cell uses the three-state pill system: yellow fill (yes), paper with ink border (partial), ink fill (no).
10. Densely populate the grid. If a composition leaves more than two cells empty in a row, reconsider whether a card is missing.
## Known Gaps
- The system relies on a `<deck-stage>` web component loaded via `deck-stage.js`. Without this script, the 1920×1080 canvas will not scale to the viewport and slides will render at native pixel size.
- Photo regions use stylized CSS-generated noise textures (radial + diagonal stripe gradients) as placeholders. Real photography must be inserted by replacing the `.photo` cell contents with an `<img>` and ensuring the surrounding panel colors complement the photo's negative space.
- The QR-pattern tile is decorative — the 5×5 grid of squares does not encode a real scannable code. Real QR codes would need a separate SVG generated externally.
- Bar chart heights are set via inline `style="height: XX%"` declarations on each bar fill. There is no data-binding layer.
- The arrow SVG used between process steps is hand-pathed inside each slide template; if a slide adds or removes process nodes, the arrow positions must be recomputed manually.
- The `<deck-stage>` component is not loaded directly by this template's script tag — it's expected to be globally available via `deck-stage.js`. Missing the script will silently render slides as flat absolute-positioned divs.
- The system uses fixed pixel sizes throughout (no `vw`/`vh`). At unusual viewport aspect ratios, the deck-stage proportional scaling may letterbox the canvas with putty bars.
- The `{colors.muted}` (#8A8A85) token is defined but used only in low-opacity overlays on photo region tags — it has no role in the main type or panel system.
# Neo-Grid Bold Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/neo-grid-bold/design.md`
- Preview card: `bold-template-pack/templates/neo-grid-bold/preview.md`
## Selection Metadata
- Slug: `neo-grid-bold`
- Tagline: Editorial neo-brutalism with a single neon yellow accent on off-white paper.
- Mood: confident, punchy, editorial, modern
- Tone: bold, minimal, design-led, graphic
- Formality: medium
- Density: high
- Scheme: light
- Best for: Anything that should feel confident and editorial-graphic: design-led pitches, brand work, founder talks, conference keynotes. Excellent for stat-heavy slides, comparisons, and process flows. Just as strong for tech, research, or finance when the speaker wants to read as design-led rather than corporate.
- Avoid for: Contexts that need to feel quiet, traditional, or warm — the neon-yellow accent and uppercase display commit to a confident editorial voice.
## Visual Snapshot
A heavy editorial poster system built on a strict 12-column × 8-row block grid with neon-yellow accents on putty-ecru. Space Grotesk at weight 700 in strict uppercase carries every display moment; JetBrains Mono carries every label and metadata tag. Each slide reads as a magazine spread divided into colored panels — paper-ecru, ink-black, and electric lemon-yellow trading roles across cells. The aesthetic borrows from contemporary editorial print, brutalist annual reports, and the populist-poster end of design week showcases.
Neo-Grid Bold is a heavy editorial poster system built on a single structural premise: every slide is a 12-column × 8-row CSS grid inset 40px from the slide edges, with 12px gaps between cells. Composition happens by assigning colored panels to grid spans — grid-column: 4 / span 5 and grid-row: 1 / span 5 is how layout is described. The grid is rigid; the visual variety comes from how panels of {colors.paper}, {colors.ink}, and {colors.accent-lemon} are arranged across cells.
## Preview Ingredients
- Palette: paper #F5F4EF; bg #ECECE8; ink #0A0A0A; accent-lemon #E6FF3D; muted #8A8A85; stage-bg #1A1A1A
- Typography: Space Grotesk; JetBrains Mono
- Signature move: Universal 12-column × 8-row CSS grid ({components.frame}) inset 40px from each slide edge, with 12px gaps between cells.
- Signature move: Three-color panel system: paper ecru ({colors.paper}) as default, ink black ({colors.ink}) for inverted blocks, accent lemon ({colors.accent-lemon}) for signal blocks.
- Signature move: Space Grotesk weight 700 uppercase with negative letter-spacing for every display element.
- Signature move: JetBrains Mono uppercase with 0.08–0.12em tracking for every label, page number, axis tag.
- Signature move: A signature corner-mark and blockmark — small 2×2 block stamps that act as decorative identity tags.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: People's Platform
description: A WPA-poster-meets-political-campaign presentation system built on three typefaces and a five-color palette that reduces to three functional roles. Alfa Slab One — a compressed slab serif — does all the heavy lifting at extreme sizes in pure uppercase. Caveat Brush drops in as a handwritten human interrupt: lowercase, slightly rotated, emotionally warm. DM Mono carries all metadata at tight uppercase tracking. The palette is electric cobalt blue, amber orange, and hot red — with red functioning exclusively as a shadow/depth color, never as a surface fill. Every slide gets a paper grain overlay that makes the whole deck feel screen-printed. The aesthetic is loud, confident, and populist — the kind of visual language that belongs on a protest placard, a union newsletter, or a campaign bus.
colors:
blue: "#2C2CDC"
blue-deep: "#1B1BB0"
orange: "#F2A03A"
orange-deep: "#E89321"
red: "#E83A2A"
red-deep: "#B7281C"
cream: "#F4E9D6"
paper: "#F5F2EA"
ink: "#0E0E14"
typography:
display-jumbo:
fontFamily: "Alfa Slab One, serif"
fontSize: 540px
fontWeight: 400
lineHeight: 0.82
letterSpacing: -0.02em
textTransform: uppercase
display-hero:
fontFamily: "Alfa Slab One, serif"
fontSize: 260px
fontWeight: 400
lineHeight: 0.86
letterSpacing: 0.005em
textTransform: uppercase
display-title:
fontFamily: "Alfa Slab One, serif"
fontSize: 240px
fontWeight: 400
lineHeight: 0.86
letterSpacing: 0.005em
textTransform: uppercase
display-xl:
fontFamily: "Alfa Slab One, serif"
fontSize: 180px
fontWeight: 400
lineHeight: 0.88
letterSpacing: 0.005em
textTransform: uppercase
display-lg:
fontFamily: "Alfa Slab One, serif"
fontSize: 140px
fontWeight: 400
lineHeight: 0.88
letterSpacing: 0.005em
textTransform: uppercase
display-md:
fontFamily: "Alfa Slab One, serif"
fontSize: 120px
fontWeight: 400
lineHeight: 0.88
letterSpacing: 0.005em
textTransform: uppercase
display-sm:
fontFamily: "Alfa Slab One, serif"
fontSize: 108px
fontWeight: 400
lineHeight: 1.04
letterSpacing: 0.005em
textTransform: uppercase
stat-unit:
fontFamily: "Alfa Slab One, serif"
fontSize: 130px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0
textTransform: uppercase
section-num:
fontFamily: "Alfa Slab One, serif"
fontSize: 54px
fontWeight: 400
lineHeight: 1.0
textTransform: uppercase
card-title:
fontFamily: "Alfa Slab One, serif"
fontSize: 54px
fontWeight: 400
lineHeight: 1.0
textTransform: uppercase
kpi-value:
fontFamily: "Alfa Slab One, serif"
fontSize: 88px
fontWeight: 400
lineHeight: 0.9
textTransform: uppercase
quote-mark:
fontFamily: "Alfa Slab One, serif"
fontSize: 300px
fontWeight: 400
lineHeight: 0.7
textTransform: uppercase
quote-body:
fontFamily: "Alfa Slab One, serif"
fontSize: 78px
fontWeight: 400
lineHeight: 1.08
textTransform: uppercase
item-title:
fontFamily: "Alfa Slab One, serif"
fontSize: 38px
fontWeight: 400
lineHeight: 1.0
textTransform: uppercase
item-title-sm:
fontFamily: "Alfa Slab One, serif"
fontSize: 30px
fontWeight: 400
lineHeight: 1.0
textTransform: uppercase
toc-entry:
fontFamily: "Alfa Slab One, serif"
fontSize: 36px
fontWeight: 400
lineHeight: 1.0
textTransform: uppercase
subtitle:
fontFamily: "Alfa Slab One, serif"
fontSize: 72px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.01em
textTransform: uppercase
cta:
fontFamily: "Alfa Slab One, serif"
fontSize: 48px
fontWeight: 400
letterSpacing: 0.02em
textTransform: uppercase
stamp:
fontFamily: "Alfa Slab One, serif"
fontSize: 28px
fontWeight: 400
letterSpacing: 0.04em
textTransform: uppercase
url:
fontFamily: "Alfa Slab One, serif"
fontSize: 46px
fontWeight: 400
letterSpacing: 0.02em
textTransform: uppercase
script-lg:
fontFamily: "Caveat Brush, cursive"
fontSize: 96px
fontWeight: 400
textTransform: lowercase
script-md:
fontFamily: "Caveat Brush, cursive"
fontSize: 64px
fontWeight: 400
textTransform: lowercase
body-lg:
fontFamily: "Archivo Narrow, sans-serif"
fontSize: 30px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0
body-md:
fontFamily: "Archivo Narrow, sans-serif"
fontSize: 28px
fontWeight: 500
lineHeight: 1.35
letterSpacing: 0
body-sm:
fontFamily: "Archivo Narrow, sans-serif"
fontSize: 26px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0
body-xs:
fontFamily: "Archivo Narrow, sans-serif"
fontSize: 24px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0
label:
fontFamily: "DM Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.18em
textTransform: uppercase
label-wide:
fontFamily: "DM Mono, monospace"
fontSize: 24px
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.22em
textTransform: uppercase
label-accent:
fontFamily: "DM Mono, monospace"
fontSize: 32px
fontWeight: 600
lineHeight: 1.0
letterSpacing: 0.16em
textTransform: uppercase
signoff:
fontFamily: "DM Mono, monospace"
fontSize: 26px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0.20em
textTransform: uppercase
spacing:
slide-gutter: 90px
content-gutter: 120px
topbar-height: 90px
section-border: 6px
inner-border: 3px
grid-gap-lg: 90px
grid-gap-md: 30px
frame-inset: 48px
canvas:
width: 1920px
height: 1080px
components:
inset-frame:
border: "6px solid {colors.cream}"
position: absolute
inset: 48px
topbar:
position: absolute
top: 0
left: 0
right: 0
height: 90px
background: "{colors.blue}"
color: "{colors.cream}"
padding: 0 90px
fontFamily: "DM Mono, monospace"
fontSize: 24px
letterSpacing: 0.18em
borderBottom: "6px solid {colors.cream}"
section-divider:
borderBottom: "6px solid {colors.ink}"
height: 6px
toc-row:
display: grid
gridTemplateColumns: "90px 1fr 100px"
gap: 24px
padding: "20px 0"
borderBottom: "3px solid {colors.ink}"
toc-num:
fontFamily: "Alfa Slab One, serif"
fontSize: 54px
color: "{colors.orange}"
textShadow: "3px 3px 0 {colors.red}"
pillar-col:
padding: "60px 50px"
borderRight: "6px solid {colors.ink}"
background: "{colors.paper}"
pillar-col-alt:
background: "{colors.blue}"
color: "{colors.cream}"
pillar-tag:
fontFamily: "DM Mono, monospace"
fontSize: 24px
letterSpacing: 0.18em
borderTop: "3px solid {colors.ink}"
paddingTop: 18px
marginTop: 14px
alignSelf: flex-start
kpi-card:
border: "5px solid {colors.ink}"
padding: "28px 30px"
background: "{colors.paper}"
kpi-card-alt:
background: "{colors.blue}"
color: "{colors.cream}"
timeline-dot:
width: 60px
height: 60px
borderRadius: 50%
background: "{colors.orange}"
border: "6px solid {colors.ink}"
boxShadow: "6px 6px 0 {colors.red}"
timeline-dot-alt:
background: "{colors.blue}"
timeline-track:
height: 14px
background: "{colors.ink}"
compare-side-left:
background: "{colors.paper}"
borderRight: "6px solid {colors.ink}"
padding: "60px 70px"
compare-side-right:
background: "{colors.blue}"
color: "{colors.cream}"
padding: "60px 70px"
compare-label:
fontFamily: "DM Mono, monospace"
fontSize: 24px
letterSpacing: 0.22em
paddingBottom: 14px
borderBottom: "4px solid {colors.ink}"
alignSelf: flex-start
diamond-bullet:
width: 24px
height: 24px
background: "{colors.red}"
borderRadius: 4px
transform: rotate(45deg)
diamond-bullet-alt:
background: "{colors.orange}"
avatar:
width: 120px
height: 120px
borderRadius: 50%
background: "{colors.blue}"
border: "6px solid {colors.blue}"
boxShadow: "6px 6px 0 {colors.red}"
quote-stamp:
background: "{colors.blue}"
color: "{colors.orange}"
padding: "18px 32px"
transform: rotate(-3deg)
border: "5px solid {colors.cream}"
fontFamily: "Alfa Slab One, serif"
fontSize: 28px
letterSpacing: 0.04em
boxShadow: "6px 6px 0 {colors.red}"
textTransform: uppercase
circular-stamp:
width: 200px
height: 200px
borderRadius: 50%
background: "{colors.cream}"
color: "{colors.blue}"
border: "6px solid {colors.orange}"
transform: rotate(-9deg)
boxShadow: "8px 8px 0 {colors.red}"
meta-pill:
border: "3px solid {colors.cream}"
padding: "8px 20px"
borderRadius: 999px
ribbon:
position: absolute
bottom: 0
left: 0
right: 0
height: 60px
background: "{colors.orange}"
color: "{colors.blue}"
borderTop: "6px solid {colors.ink}"
fontFamily: "DM Mono, monospace"
fontSize: 24px
letterSpacing: 0.22em
fontWeight: 600
lede-block:
fontFamily: "Archivo Narrow, sans-serif"
fontWeight: 500
fontSize: 28px
lineHeight: 1.35
borderLeft: "4px solid {colors.ink}"
paddingLeft: 50px
lede-block-top:
borderTop: "6px solid {colors.ink}"
paddingTop: 24px
underline-rule:
height: 14px
background: "{colors.ink}"
width: "30%"
marginTop: 60px
kicker:
fontFamily: "DM Mono, monospace"
letterSpacing: 0.22em
fontSize: 26px
color: "{colors.red}"
marginBottom: 48px
grain-overlay:
position: absolute
inset: 0
pointerEvents: none
backgroundImage: "radial-gradient(rgba(0,0,0,.06) 1px, transparent 1px), radial-gradient(rgba(255,255,255,.05) 1px, transparent 1px)"
backgroundSize: "3px 3px, 5px 5px"
backgroundPosition: "0 0, 1px 2px"
mixBlendMode: multiply
opacity: 0.5
orange-dot:
width: 10px
height: 10px
borderRadius: 50%
background: "{colors.orange}"
---
## 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
People's Platform is a **WPA-poster-meets-political-campaign slide system** — the visual language of conviction, the graphic register of public address. The canvas is warm paper (`{colors.paper}` — #F5F2EA), a hair warmer than white, and every slide gets a grain texture applied via a CSS pseudo-element that makes the whole deck feel screen-printed rather than rendered.
The typeface stack is a three-way class system. **Alfa Slab One** owns the stage at extreme sizes — compressed, slab-heavy, all caps, intrinsically authoritative. It is the voice that shouts. **Caveat Brush** is the human interrupt — handwritten, lowercase, slightly rotated, emotionally present. It is the voice that whispers. **DM Mono** is the bureaucratic record-keeper — monospace, wide-tracked uppercase, 24px, always — the voice that accounts for things. Archivo Narrow is the workhorse body face: never used at display sizes, always condensed, weight 500 for readability.
The palette has five named colors but three functional roles. **Blue** (`{colors.blue}` — #2C2CDC) is the primary structural color: backgrounds for high-emphasis surfaces, borders for content dividers, text color on non-blue backgrounds. **Orange** (`{colors.orange}` — #F2A03A) is the energy color: stat figures, column numerals, accent text within blue surfaces. **Red** (`{colors.red}` — #E83A2A) is the depth color — it never appears as a surface fill, only as the first layer of a stacked text-shadow or box-shadow. Blue-deep and red-deep are the outer shadow layers in the double-stacked shadow system.
The signature depth technique is the **stacked offset text-shadow**: orange text casts a red shadow at 6–12px, which casts a red-deep shadow at 12–24px. This creates a three-layer quasi-3D letterpress effect that is the system's most recognisable trait. Box-shadows on interactive elements mirror the same treatment: `6px 6px 0 {colors.red}`.
**Key Characteristics:**
- Paper canvas (`{colors.paper}` — #F5F2EA) with grain overlay via CSS pseudo-element on every slide.
- Stacked double text-shadow: `Npx Npx 0 {colors.red}, 2Npx 2Npx 0 {colors.red-deep}`. Shadow size scales with font size.
- Alfa Slab One for all display and structural type — uppercase, line-height 0.82–1.04, letter-spacing 0.005em.
- Red (`{colors.red}`) functions exclusively as a shadow color — never a surface background.
- Heavy 6px ink borders for all major structural divisions (topbars, section headers, column separators, inset frames).
- DM Mono labels at exactly 24px with 0.18–0.22em tracking across all slides.
- Caveat Brush appears at 64–96px, always lowercase, always rotated 2–5 degrees — a deliberate roughness signal.
- Orange bottom ribbon: a horizontal marquee strip anchored to the bottom of data-heavy slides.
- Inset decorative frame (6px solid cream at `inset: 48px`) used on blue-background slides.
## Colors
### Primary Palette
- **Blue** (`{colors.blue}` — #2C2CDC): Electric cobalt. The dominant surface color for high-emphasis slides and structural elements. Used as full-slide background, column fills, topbar backgrounds, text on cream/paper surfaces, avatar fills, and compare-panel dark side.
- **Blue Deep** (`{colors.blue-deep}` — #1B1BB0): A darker blue. Used exclusively as the outermost layer of stacked text-shadows. Never a surface fill.
- **Orange** (`{colors.orange}` — #F2A03A): Warm amber. The energy accent. Used for oversized stat numerals, column ordinals, CTA button fill, ribbon background, accent text within blue surfaces, and text-shadow inner layer on stamp elements.
- **Orange Deep** (`{colors.orange-deep}` — #E89321): Darker amber. Reserved for the deepest shadow layer on orange elements. Not used as a surface fill.
- **Red** (`{colors.red}` — #E83A2A): Hot red. The depth color. Used exclusively in text-shadows and box-shadows — the first offset layer on most display text and buttons. Never appears as a background or primary text color.
- **Red Deep** (`{colors.red-deep}` — #B7281C): Dark red. The outermost layer of the double text-shadow on the largest display elements. Never a surface fill.
### Surface Palette
- **Cream** (`{colors.cream}` — #F4E9D6): Warm cream. Used as text/border color on blue surfaces (inverted mode), as the inset frame border, and as the full background on cream-tone slides.
- **Paper** (`{colors.paper}` — #F5F2EA): Off-white with a warm cast. The default slide background — slightly warmer and less stark than #fff. Most content slides use this.
- **Ink** (`{colors.ink}` — #0E0E14): Near-black with a barely-perceptible blue undertone. Used for all structural borders, body text, column dividers, timeline tracks, and KPI card borders.
### Color Roles Summary
- **Blue surfaces** = high-emphasis, conclusive, authoritative moments
- **Paper/cream surfaces** = content-first, readable, subordinate moments
- **Orange** = the number, the energy, the thing that matters most on a given slide
- **Red** = never a color you see directly — only a shadow you feel
## Typography
### Font Families
Three typefaces; each occupies a completely non-overlapping register:
**Alfa Slab One** is the primary voice. A compressed, heavy slab serif with strong verticals and blocky serifs. Used at weight 400 (the only weight available, which is intrinsically bold) in strict uppercase for every display moment from 28px stamps to 540px stat figures. Its compressed letterform means even massive sizes don't feel wide — they feel tall and column-like. The slight positive letter-spacing (0.005em) keeps glyphs from touching at large sizes.
**Caveat Brush** is the human voice. A rough handwritten script face used only at large sizes (64–96px), always lowercase, always with a small rotation (-2 to -5 degrees). It appears at moments of warmth, transition, or informality — a script annotation in an otherwise rigidly structured deck. It is never used for body copy or labels.
**DM Mono** is the accounting voice. Monospace, 24px, wide letter-spacing (0.18–0.22em), uppercase. It appears on topbars, footers, kicker labels, metadata rows, source citations, and ribbon text. It is always a supporting element — the technical spec printed at the bottom of a poster, not the headline.
**Archivo Narrow** is the body voice. A condensed sans used for all running body copy: pillar descriptions, list item paragraphs, compare list items, stat annotations. Weight 500 for most body text; 400 for smaller captions. Never used at display sizes.
### Display Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-jumbo}` | 540px | Alfa Slab One | 400 | Full-bleed oversized stat numeral |
| `{typography.display-hero}` | 260px | Alfa Slab One | 400 | Dominant closing or opening headline |
| `{typography.display-title}` | 240px | Alfa Slab One | 400 | Primary deck title |
| `{typography.display-xl}` | 180px | Alfa Slab One | 400 | Large column ordinal numeral |
| `{typography.display-lg}` | 140px | Alfa Slab One | 400 | Section headline, primary |
| `{typography.display-md}` | 120px | Alfa Slab One | 400 | Section headline, secondary |
| `{typography.display-sm}` | 108px | Alfa Slab One | 400 | Body-adjacent manifesto headline |
| `{typography.stat-unit}` | 130px | Alfa Slab One | 400 | Superscript unit symbol alongside stat |
| `{typography.quote-mark}` | 300px | Alfa Slab One | 400 | Decorative oversized quotation mark |
| `{typography.quote-body}` | 78px | Alfa Slab One | 400 | Pull quote body text |
| `{typography.kpi-value}` | 88px | Alfa Slab One | 400 | KPI or metric card value |
| `{typography.subtitle}` | 72px | Alfa Slab One | 400 | Subtitle or secondary title alongside a primary headline |
| `{typography.card-title}` | 54px | Alfa Slab One | 400 | Card or column heading |
| `{typography.section-num}` | 54px | Alfa Slab One | 400 | Section or item ordinal numeral |
| `{typography.cta}` | 48px | Alfa Slab One | 400 | CTA button label |
| `{typography.url}` | 46px | Alfa Slab One | 400 | URL or contact address |
| `{typography.item-title}` | 38px | Alfa Slab One | 400 | List item or node heading |
| `{typography.toc-entry}` | 36px | Alfa Slab One | 400 | Table of contents entry title |
| `{typography.item-title-sm}` | 30px | Alfa Slab One | 400 | Dense list item heading |
| `{typography.stamp}` | 28px | Alfa Slab One | 400 | Stamp or badge label |
### Script Scale
| Token | Size | Use |
|---|---|---|
| `{typography.script-lg}` | 96px | Prominent handwritten accent — transition word, emotional opener |
| `{typography.script-md}` | 64px | Smaller handwritten annotation — subtitle callout, sub-label |
Both script tokens are always lowercase and always applied with a rotation between -2deg and -5deg. Never use Caveat Brush without rotation.
### Body and Label Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.body-lg}` | 30px | Archivo Narrow | 500 | Stat annotation, primary body paragraph |
| `{typography.body-md}` | 28px | Archivo Narrow | 500 | Column body, lede paragraph, compare list |
| `{typography.body-sm}` | 26px | Archivo Narrow | 500 | Supporting body paragraphs |
| `{typography.body-xs}` | 24px | Archivo Narrow | 400 | Dense list items, captions |
| `{typography.label}` | 24px | DM Mono | 400 | Standard metadata label (0.18em tracking) |
| `{typography.label-wide}` | 24px | DM Mono | 400 | Footline and ribbon text (0.22em tracking) |
| `{typography.label-accent}` | 32px | DM Mono | 600 | Highlighted metadata (e.g. section count) |
| `{typography.signoff}` | 26px | DM Mono | 400 | Footer sign-off block (0.20em tracking) |
### Typography Principles
Alfa Slab One is always uppercase — never use it in sentence case or lowercase. Line-height at display sizes is tight: 0.82–0.88 for large headlines, 1.04 only for multi-line body-adjacent text where line collision would occur. The 0.005em letter-spacing is nearly invisible but prevents glyph collision at 100px+ sizes.
The stacked text-shadow is the inline styling rule for display text: orange display type always casts `{colors.red}` as its first shadow. At sizes above 200px, add a second `{colors.red-deep}` layer at double the offset. At sizes below 100px, a single 3px–6px offset in `{colors.red}` is sufficient.
DM Mono labels are always 24px regardless of context. The tracking varies by placement: 0.18em for topbar/footer, 0.22em for ribbon and footline, 0.16em for side labels in split panels. Never reduce tracking on DM Mono — at 24px without tracking, it reads as utilitarian rather than editorial.
Archivo Narrow is always weight 400 or 500. Never use it at display sizes. It is a supporting voice, not a headline voice.
## Layout
### Canvas System
Every slide is 1920×1080px. The `deck-stage` custom element handles scaling. All content is absolutely positioned or uses CSS grid — no scrolling.
### Gutter System
- **Slide gutter** (90px left/right): The standard edge padding for most content sections.
- **Content gutter** (120px left/right): Used for body content within slides that already have a structural header — provides extra breathing room for reading text.
- **Topbar height** (90px): The fixed-height blue topbar band that sits at the absolute top of a slide.
- **Frame inset** (48px): The distance from the slide edge to the decorative inset frame border used on blue-background slides.
### Universal Chrome
The system does not enforce a universal topbar on every slide. Two chrome patterns exist:
**Topbar pattern** — A full-width 90px blue bar anchored to the top (`position:absolute; top:0; left:0; right:0`). Contains DM Mono 24px label text at 0.18em tracking. Carries a 6px solid cream bottom border. Used on high-emphasis blue-background slides.
**Section-divider pattern** — A 6px solid ink horizontal rule between a header block and the content area below. The header block uses 90px left/right padding; the content below uses 90px padding. No topbar — the rule is the dividing element.
Both patterns can coexist on a single slide or be used independently.
## Depth and Elevation
### Stacked Text-Shadow (Primary Technique)
The system's signature. Display text casts layered offset shadows in the same direction (bottom-right), creating a quasi-3D letterpress effect. Three tiers by element size:
| Tier | Offset layer 1 | Offset layer 2 | Use |
|---|---|---|---|
| Small | `3px 3px 0 {colors.red}` | — | Items below 72px |
| Medium | `5px–6px 5px–6px 0 {colors.red}` | — | 72px–140px display |
| Large | `10px 10px 0 {colors.red}, 20px 20px 0 {colors.red-deep}` | | 140px–260px display |
| Jumbo | `12px 12px 0 {colors.red}, 24px 24px 0 {colors.red-deep}` | | 260px+ stat figures |
The orange display text is the "face" layer; red is the "body"; red-deep is the "foot." The illusion is of a letterform with physical thickness.
### Box-Shadow (Secondary Technique)
Interactive and decorative elements (stamps, avatars, CTA buttons, KPI cards) use the same offset logic in box-shadow form: `6px 6px 0 {colors.red}` or `8px 8px 0 {colors.red}`. This unifies the depth system: all elements in the deck cast shadows in the same direction at the same apparent light angle.
### Grain Texture (Atmospheric Depth)
Every slide carries a `.grain::before` pseudo-element: two overlapping radial-gradient dot grids at 3px and 5px pitch, with `mix-blend-mode: multiply` and 50% opacity. This simulates screen-print halftone texture, giving the flat digital surfaces a physical, printed quality. It is not elevation but atmosphere — the entire deck reads as produced rather than rendered.
### Flat Elements
DM Mono labels, ink section rules, body text, and grid lines are completely flat. No shadows on structural dividers.
## Shapes and Treatment
### Border Radius Scale
| Value | Use |
|---|---|
| 999px (pill) | Meta label pills in topbar/header areas |
| 50% (circle) | Avatar elements, timeline milestone dots, circular stamp |
| 4px | Diamond bullet pseudo-elements (rotated 45deg to form a diamond) |
| 0px | All structural elements: columns, cards, topbars, frames, ribbons, KPI cards, stamps |
The system is almost entirely square. The only soft shapes are the pill (for metadata chips), the circle (for avatars, dots, the closing stamp), and the diamond bullet. The squareness of structural elements reinforces the printed/constructed aesthetic.
### Border Weights
- **6px solid `{colors.ink}`** — Primary structural borders: section dividers, column separators, topbar bottom edges, inset frames, KPI card borders, CTA button border.
- **6px solid `{colors.cream}`** — Inverted structural borders on blue surfaces: inset frame, topbar divider in cream-on-blue mode.
- **5px solid** — Secondary structural borders: quote stamp, compare list item treatment.
- **4px solid** — Tertiary dividers: side labels in compare panels, lede left-border.
- **3px solid `{colors.ink}`** — Fine structural lines: TOC row separators, column tags, stat source dividers, inner timeline lines.
### Decorative Elements
**Inset frame** — A 6px solid cream border at `inset: 48px` creates a second inner rectangle on blue-background slides. It reinforces the poster/placard aesthetic — the design within a design.
**Orange ribbon** — A 60px bottom-anchored strip in `{colors.orange}` with 6px ink top border and repeating DM Mono text at 0.22em tracking. Functions as a marquee footer on data slides.
**Diamond bullet** — List item marker using a `::before` pseudo-element: 24px × 24px, `background: {colors.red}`, `border-radius: 4px`, `transform: rotate(45deg)`. On blue-background lists, uses `{colors.orange}` instead. The shape sits 48px left of the text (positioned absolutely).
**Circular stamp** — A 200px circle (`{components.circular-stamp}`) rotated -9deg with 6px orange border and an 8px red box-shadow. Functions as a seal — the physical-world approval mark on a bureaucratic document.
**Rotated rectangular stamp** — A rectangular block rotated -3deg with 5px cream border and 6px red box-shadow. Contains Alfa Slab One 28px text at 0.04em tracking. Lighter rotation than the circular stamp — feels like an address label placed at a slight angle.
**Script annotation** — Caveat Brush 64–96px, lowercase, rotated 2–5 degrees. Always appears adjacent to an Alfa Slab One headline it qualifies or interrupts — never alone.
**Column ordinal** — 180px Alfa Slab One orange numeral with a 5px red text-shadow, followed by a 3px ink top-border DM Mono tag label below it. This pairing (large orange numeral + small mono tag) is the system's standard way of labelling columns or sections.
**Underline rule** — A 14px tall solid ink rectangle, width 30% of its container, used as a full-stop after a manifesto headline. It is heavier than a hairline rule — closer to a redaction bar.
**Grain overlay** — The `.grain` class adds `::before` pseudo-element texture to every slide. It cannot be removed from a slide in this system — it is structural to the aesthetic.
## Do's and Don'ts
### Do
- Apply the grain overlay (`.grain::before`) to every slide. It is not decorative — it is the surface that everything else is printed on.
- Use the stacked text-shadow on all orange and cream display text. Shadowless Alfa Slab One reads flat and loses the letterpress character.
- Scale shadow offset proportionally to font size: small offset for small type, jumbo offset for jumbo type.
- Keep red exclusively as a shadow color. The moment red appears as a text color or background fill, the depth system collapses.
- Use Caveat Brush only at large sizes (64px+), always lowercase, always slightly rotated. Never for body text.
- Keep DM Mono labels at exactly 24px with at least 0.16em letter-spacing. The monospace face at body size with normal tracking reads as code, not editorial.
- Use the 6px border weight for major structural divisions. Thinner reads as SaaS; thicker looks like a design mistake.
- When a slide uses a blue background, use the inset frame — it distinguishes blue-background slides as "framed" rather than merely filled.
- Apply `{colors.orange}` as the numerals, values, and accent text on blue surfaces. Blue-on-orange or cream-on-blue are the only other permitted text combinations on dark surfaces.
### Don't
- Don't use red as a background or primary text color. It is a shadow material, not a surface material.
- Don't use Caveat Brush at body sizes or without rotation. Flat, small handwriting reads as untidy, not intentional.
- Don't apply Alfa Slab One in mixed case. The uppercase lock is essential to the slab's authority.
- Don't soften the border weights. 1px or 2px borders on structural elements break the printed-matter aesthetic.
- Don't round card or container corners. The inset frame and KPI cards are strictly square.
- Don't use Archivo Narrow for headlines. It is a body and lede face only — it lacks the visual weight for display use.
- Don't use blue-deep or red-deep as surface colors. They are shadow-only values — their role is depth, not fill.
- Don't omit the diamond bullet rotation on list items. A 45deg-rotated square is a diamond; an upright square is a box — the shape signals hand-crafted, not generic.
- Don't vary the DM Mono font size. 24px is the single fixed size for all monospace label text — increasing it for emphasis breaks the system; use `{typography.label-accent}` (32px, weight 600) as the sole exception.
## Responsive Behavior
This template is designed exclusively for 1920×1080 presentation display. The `deck-stage` custom element handles viewport scaling via CSS transforms — the 1920×1080 canvas scales proportionally to any screen size without layout changes.
Slides advance via keyboard or presentation clicker through `deck-stage.js`. No hover states, no interactive form elements, no responsive breakpoints.
For print and PDF export: at 96dpi, the 1920×1080 canvas maps to a 20×11.25 inch frame. The grain overlay uses `mix-blend-mode: multiply` — in PDF export, blend modes may flatten; test print output and consider disabling the grain for printed formats.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face | Chinese face | Weight |
|---|---|---|---|
| Display / title / quote (Alfa Slab One UPPERCASE) | Alfa Slab One | Noto Serif SC (思源宋体) | 900 |
| Script interrupt (Caveat Brush lowercase rotated) | Caveat Brush | — (no good equivalent; see Aesthetic Notes) | — |
| Body (Archivo Narrow 500) | Archivo Narrow | Noto Sans SC (思源黑体) | 500 |
| Label / mono (DM Mono UPPERCASE tracked) | DM Mono | Noto Sans SC | 400 (do not force monospace on CJK) |
### Mixed-Content Strategy
Strategy A — extend each token's `fontFamily` to include the Chinese face after the Latin face. Alfa Slab tokens become `"Alfa Slab One, Noto Serif SC, serif"`; Archivo Narrow tokens become `"Archivo Narrow, Noto Sans SC, sans-serif"`; DM Mono tokens become `"DM Mono, Noto Sans SC, monospace"`. Latin glyphs render in their original face; CJK falls through to the SC fallback automatically.
### 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=Alfa+Slab+One&family=Caveat+Brush&family=Archivo+Narrow:wght@400;500;600;700&family=DM+Mono:wght@300;400;500&family=Noto+Serif+SC:wght@400;500;700;900&family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation (,。:;!?「」())
- No period on display headlines (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence
### Aesthetic Notes for This System
People's Platform is a WPA-poster system built on three load-bearing typefaces, and **none of the three has a clean Chinese transfer**.
**Alfa Slab One** is a compressed slab serif at extreme sizes (up to 540px) in uppercase. There is no Chinese slab serif of equivalent weight and authority available on CDN. **Noto Serif SC at weight 900** is the closest match — it carries the slab-like heaviness and the structural authority — but it reads as more "literary monument" than "protest placard." Accept this register shift: Chinese versions of this system feel closer to a heritage-era public-notice board (think 大字报 or museum signage) than to a 1930s WPA poster. The stacked red text-shadow still applies and still carries the system's letterpress depth signature.
**Caveat Brush** is the "human interrupt" voice — lowercase, rotated, emotionally warm. **This does not transfer to Chinese.** Chinese brush calligraphy (Ma Shan Zheng / 马善政) carries cultural and traditional weight — it reads as ceremonial, formal, even bureaucratic, NOT the casual personal voice of Latin Caveat. **Recommended approach: leave the brush moment out entirely on pure-CJK slides.** A second option: use a short Latin word in Caveat Brush as the interrupt even within Chinese content (e.g., a script `yes!` annotation beside a Chinese headline) — this preserves the casual interrupt energy and signals "voice break" without invoking Chinese calligraphic tradition.
**DM Mono** uppercase tracked labels do not transfer to CJK. Set Chinese metadata in **Noto Sans SC 400** with letter-spacing reset to 0 and no uppercase. Pure-Latin tags (URLs, dates, edition numbers) keep DM Mono.
**Archivo Narrow** is condensed at weight 500. **Noto Sans SC has no condensed variant.** Use Noto Sans SC 500 at the original Archivo size and accept that Chinese body type sits slightly wider than Latin body type. The single-color paper canvas and the grain overlay absorb the width difference.
The stacked text-shadow (orange → red → red-deep) is the system's most recognizable trait. **It transfers perfectly to Chinese.** Apply it to every Chinese display headline in orange and the letterpress depth survives the script switch. The blue-and-orange-and-red palette is also fully script-agnostic.
The diamond bullet marker, the rotated rubber stamp, the inset cream frame, the 6px ink borders — all work unchanged in Chinese.
### Known CJK Gap
**Caveat Brush has no acceptable Chinese equivalent.** The "human interrupt" voice is structurally absent in a pure-CJK People's Platform deck. The two workarounds (drop the interrupt entirely; use Latin-in-Chinese for the script moments) are both visible aesthetic compromises — the populist-poster system loses one of its three voices when forced into pure Chinese. Mixed-content decks (English-led with Chinese accents, or vice versa) are the strongest fit for this template.
## Iteration Guide
1. The stacked shadow is a hard invariant — any new display element in orange or cream must carry it. Determine the offset by dividing the font size by approximately 20 to get the first shadow distance, double it for the second.
2. Any new slide with a blue background gets an inset frame (6px cream, `inset: 48px`) and, if it has a header bar, that bar uses the topbar pattern with a 6px cream bottom border.
3. New columns or side-by-side panels follow the 6px ink separator convention. Asymmetric layouts (e.g. 60/40 split) are fine as long as the separator border remains 6px.
4. New KPI or data cards use the `{components.kpi-card}` pattern: 5px ink border, paper background, optional alt variant in blue. The number inside uses Alfa Slab One with the standard text-shadow.
5. New list items always use the diamond bullet (24px × 24px, 4px radius, rotate 45deg). Use red for ink-background items, orange for blue-background items.
6. If a new decorative stamp or badge is needed, use Alfa Slab One with `letter-spacing: 0.04em`, a box-shadow of `6px 6px 0 {colors.red}`, and a slight rotation (–3 to –9deg). Circular stamps get 50% border-radius; rectangular ones stay square.
7. The grain overlay is a CSS pseudo-element on the `section` element — it must be present on every new slide via the `.grain` class.
8. Script (Caveat Brush) text is an interrupt, not a default. Use it once per slide maximum, and only at 64px+.
## Known Gaps
- `deck-stage.js` is an external script dependency not documented here. Slide navigation and scaling are handled by it entirely.
- The orange ribbon on data slides is implemented with static repeated text — there is no JavaScript marquee animation. At 1920px width, the text wraps naturally; for longer strings, manually duplicate the text.
- The grain overlay uses `mix-blend-mode: multiply`. This requires a semi-transparent background or a parent with a visible fill to produce the texture effect — on pure white or pure black surfaces the effect may be invisible.
- Speaker notes are embedded as a `<script type="application/json">` block in the template — this data is presentational, not part of the design system, and is not captured in these tokens.
- Archivo Narrow is loaded as a web font. It has broad system fallback (`system-ui, sans-serif`) but the condensed width of the system font stack fallback will differ significantly from Archivo Narrow and may break layouts at tight grid configurations.
- The `text-wrap: pretty` property on quote text is a modern CSS feature with limited browser support — it may not apply in older export environments.
# People's Platform (Block & Bold) Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/peoples-platform/design.md`
- Preview card: `bold-template-pack/templates/peoples-platform/preview.md`
## Selection Metadata
- Slug: `peoples-platform`
- Tagline: Activist poster energy: blue, orange, red on cream, with Alfa Slab + Caveat Brush.
- Mood: activist, loud, graphic, honest
- Tone: punchy, direct, expressive, warm-bold
- Formality: medium-low
- Density: medium-high
- Scheme: light
- Best for: Anything that should feel honest, loud, and graphic: cultural commentary, manifestos, civic and community decks, design talks, campaign pitches. Excellent for founder-vision moments, mission statements, or any deck — including across industries — that wants protest-poster energy instead of corporate polish.
- Avoid for: Contexts where institutional restraint is the actual goal — the saturated political-poster palette commits hard to expressive energy.
## Visual Snapshot
A WPA-poster-meets-political-campaign presentation system built on three typefaces and a five-color palette that reduces to three functional roles. Alfa Slab One — a compressed slab serif — does all the heavy lifting at extreme sizes in pure uppercase. Caveat Brush drops in as a handwritten human interrupt: lowercase, slightly rotated, emotionally warm. DM Mono carries all metadata at tight uppercase tracking. The palette is electric cobalt blue, amber orange, and hot red — with red functioning exclusively as a shadow/depth color, never as a surface fill. Every slide gets a paper grain overlay that makes the whole deck feel screen-printed. The aesthetic is loud, confident, and populist — the kind of visual language that belongs on a protest placard, a union newsletter, or a campaign bus.
People's Platform is a WPA-poster-meets-political-campaign slide system — the visual language of conviction, the graphic register of public address. The canvas is warm paper ({colors.paper} — #F5F2EA), a hair warmer than white, and every slide gets a grain texture applied via a CSS pseudo-element that makes the whole deck feel screen-printed rather than rendered.
## Preview Ingredients
- Palette: blue #2C2CDC; blue-deep #1B1BB0; orange #F2A03A; orange-deep #E89321; red #E83A2A; red-deep #B7281C; cream #F4E9D6; paper #F5F2EA
- Typography: Alfa Slab One; Caveat Brush; Archivo Narrow; DM Mono
- Signature move: Paper canvas ({colors.paper} — #F5F2EA) with grain overlay via CSS pseudo-element on every slide.
- Signature move: Stacked double text-shadow: Npx Npx 0 {colors.red}, 2Npx 2Npx 0 {colors.red-deep}. Shadow size scales with font size.
- Signature move: Alfa Slab One for all display and structural type — uppercase, line-height 0.82–1.04, letter-spacing 0.005em.
- Signature move: Red ({colors.red}) functions exclusively as a shadow color — never a surface background.
- Signature move: Heavy 6px ink borders for all major structural divisions (topbars, section headers, column separators, inset frames).
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Pin & Paper
description: A field-notebook editorial system rendered as yellow legal-pad paper with deep cobalt-blue ink. Every slide carries a fractalnoise paper-grain overlay, hand-drawn safety-pin SVG illustrations that "pin" cards to the page, and a hand-script Caveat face for personal annotations. Space Grotesk at heavy weights carries the printed headlines; DM Mono handles archival labels. The aesthetic borrows from analog field reports, vintage public-notice boards, and the diary pages of scientific notebooks — closer to a lab journal pinned to a corkboard than a polished deck.
colors:
paper: "#EFE56A"
paper-2: "#F5ECA0"
paper-3: "#E8D85A"
paper-extra: "#FBE6A4"
cream: "#F8F1D6"
kraft: "#C9A66B"
ink: "#1F3A8A"
ink-soft: "#2D4FB8"
ink-line: "#3457C4"
ink-deep: "#0E1430"
red: "#C2342B"
olive: "#6B7A2E"
orange: "#D8702A"
color-aliases:
c-bg: paper
c-text: ink
c-card: cream
c-stamp: red
typography:
display-mega:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 196px
fontWeight: 700
lineHeight: 1.08
letterSpacing: -0.04em
display-section:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 168px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.04em
display-stat:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 168px
fontWeight: 700
lineHeight: 0.85
letterSpacing: -0.04em
h1-cta:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 130px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.035em
h1-chart:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 110px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.035em
h2:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 96px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.03em
h2-md:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 84px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.03em
h2-sm:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 50px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.02em
quote-text:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 50px
fontWeight: 500
lineHeight: 1.1
letterSpacing: -0.02em
card-row:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 44px
fontWeight: 600
lineHeight: 1.0
letterSpacing: -0.02em
card-h3:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 38px
fontWeight: 700
lineHeight: 1.02
letterSpacing: -0.02em
card-h3-sm:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 28px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.015em
body:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 22px
fontWeight: 400
lineHeight: 1.45
body-md:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 21px
fontWeight: 400
lineHeight: 1.35
body-sm:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 19px
fontWeight: 400
lineHeight: 1.45
body-list:
fontFamily: "Space Grotesk, Helvetica Neue, Arial, sans-serif"
fontSize: 18px
fontWeight: 400
lineHeight: 1.4
scribble-mega:
fontFamily: "Caveat, cursive"
fontSize: 360px
fontWeight: 700
lineHeight: 0.8
scribble-lg:
fontFamily: "Caveat, cursive"
fontSize: 70px
fontWeight: 700
lineHeight: 0.9
scribble-md:
fontFamily: "Caveat, cursive"
fontSize: 60px
fontWeight: 700
lineHeight: 0.9
scribble-sm:
fontFamily: "Caveat, cursive"
fontSize: 38px
fontWeight: 600
lineHeight: 1.05
scribble-xs:
fontFamily: "Caveat, cursive"
fontSize: 32px
fontWeight: 600
lineHeight: 1.05
label-top:
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: 18px
fontWeight: 500
letterSpacing: 0.12em
textTransform: uppercase
label-meta:
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: 16px
fontWeight: 500
letterSpacing: 0.18em
textTransform: uppercase
label-footer:
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: 15px
fontWeight: 500
letterSpacing: 0.14em
textTransform: uppercase
stamp:
fontFamily: "DM Mono, monospace"
fontSize: 16px
fontWeight: 500
letterSpacing: 0.18em
textTransform: uppercase
spacing:
pad-edge: 64px
pad-top: 110px
pad-bottom: 90px
card-pad-md: "28px 28px 24px"
card-pad-lg: "32px 22px 22px"
card-pad-xl: "36px 28px 28px"
card-pad-quote: "60px 80px"
grid-gap-sm: 22px
grid-gap-md: 28px
grid-gap-lg: 32px
canvas:
width: 1920px
height: 1080px
components:
paper-surface:
background: "radial-gradient(120% 90% at 20% 10%, rgba(255,255,255,.18), transparent 60%), radial-gradient(140% 100% at 80% 95%, rgba(0,0,0,.05), transparent 55%), {colors.paper}"
description: "Default slide surface — yellow paper with a soft upper-left highlight gradient and a soft lower-right shadow gradient layered over the base paper color."
paper-grain-overlay:
selector: ".slide::before"
background: "fractalNoise SVG via data URI, baseFrequency=1.4, octaves=2"
opacity: 0.35
mixBlendMode: multiply
description: "Non-optional fractal-noise paper grain overlay on every slide. Lives on the ::before pseudo-element; opacity 0.35, multiply blend. On ink slides, opacity drops to 0.25 with screen blend."
pinned-card:
background: "{colors.cream}"
border: "1.5px solid {colors.ink}"
borderRadius: 4px
boxShadow: "5px 6px 0 0 {colors.ink}"
padding: "{spacing.card-pad-md}"
description: "Cream paper card with a 1.5px ink border, 4px micro-radius, and a hard 5px-6px ink-blue offset shadow. The system's universal card pattern — every card looks like a piece of paper pinned to the surface."
pinned-card-alt:
background: "{colors.paper-2}"
description: "Card variant using the lighter paper-2 tone. Used to break up adjacent same-tone cards."
pinned-card-alt2:
background: "{colors.paper-extra}"
transform: "rotate(0.6deg)"
description: "Card variant with the deepest paper tone and a slight rotation (0.6 to 1.5 degrees) — gives the impression of being pinned slightly askew."
pin-illustration:
width: "varies (110–640px)"
color: "currentColor"
transform: "rotate(-14deg to +20deg)"
description: "Hand-drawn safety-pin SVG illustration in ink-blue or paper (when on ink surface). Multiple variants: closed pin (#pin), open pin (#pin-open). Always rotated slightly off-axis. Acts as both decoration and the visual signal that a card is 'pinned' to the page."
scribble:
fontFamily: "Caveat, cursive"
color: "{colors.ink}"
lineHeight: 1.05
description: "Caveat hand-script face used for handwritten notes, marginalia, and 'me' voice annotations. May be rotated slightly (-3 to -1.5 degrees) and underlined via 2px solid ink for emphasis."
stamp:
border: "3px solid {colors.red}"
color: "{colors.red}"
padding: "6px 16px"
fontFamily: "DM Mono, monospace"
fontSize: 16px
letterSpacing: 0.18em
textTransform: uppercase
transform: "rotate(-4deg)"
description: "Cinnabar-red rubber stamp — 3px solid red border, red mono text, rotated -4 degrees. Used for status marks like CONFIDENTIAL or RECEIVED."
top-chrome:
position: "absolute; top: 44px; left: 64px; right: 64px"
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: 18px
fontWeight: 500
letterSpacing: 0.12em
textTransform: uppercase
description: "Top metadata band — brand lockup on left (with inline #mark SVG glyph), meta tags on right. Mono uppercase, line-height 1."
footer-chrome:
position: "absolute; left: 64px; right: 64px; bottom: 36px"
fontFamily: "DM Mono, ui-monospace, monospace"
fontSize: 15px
fontWeight: 500
letterSpacing: 0.14em
textTransform: uppercase
opacity: 0.65
description: "Bottom metadata band — typically left-source + right-page-position pair at 65% opacity."
pin-glyph-closed:
svgId: "#pin"
viewBox: "0 0 360 110"
description: "Closed safety-pin SVG glyph — coiled spring on the right, shaft sweeping left, oval clasp cap on the left."
pin-glyph-open:
svgId: "#pin-open"
viewBox: "0 0 360 130"
description: "Open safety-pin SVG glyph — clasp lifted, sharp point exposed pointing left."
mark-glyph:
svgId: "#mark"
viewBox: "0 0 32 16"
description: "Small inline mark glyph for the top-chrome brand lockup — circle on the right, arrow shaft pointing left."
table-cell:
padding: "18px 22px"
borderBottom: "1.5px solid rgba(31,58,138,.5)"
borderRight: "1.5px solid rgba(31,58,138,.5)"
fontSize: 21px
lineHeight: 1.35
description: "Comparison table cell with semi-transparent ink-blue dividers. Sits inside the same cream + ink-border + offset-shadow card pattern."
pill-yes:
background: "{colors.ink}"
color: "{colors.paper}"
border: "1.5px solid {colors.ink}"
borderRadius: 999px
padding: "4px 14px"
fontFamily: "Caveat, cursive"
fontSize: 28px
fontWeight: 600
description: "Affirmative pill — solid ink fill with paper text, rounded 999px, Caveat script face. Unusual treatment: handwritten letterforms inside a UI pill shape."
pill-no:
background: transparent
color: "{colors.red}"
border: "1.5px solid {colors.red}"
fontFamily: "DM Mono, monospace"
fontSize: 16px
letterSpacing: 0.14em
textTransform: uppercase
description: "Negative pill — red mono uppercase text in a red-bordered transparent pill. The only place red appears in regular use (outside the stamp component)."
pill-part:
background: "{colors.paper-2}"
color: "{colors.ink}"
fontFamily: "Caveat, cursive"
description: "Partial-state pill — light paper fill with Caveat script ink text."
number-script:
fontFamily: "Caveat, cursive"
fontWeight: 700
fontSize: "60–70px"
color: "{colors.ink}"
description: "Hand-script numeral used as step numbers in process diagrams and ordered CTA steps. The script face makes ordering feel hand-counted, not algorithmic."
---
## 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
Pin & Paper is a **field-notebook editorial system** built on a single material premise: every slide is yellow legal-pad paper. The paper is rendered through a base color (`{colors.paper}` — saturated cadmium yellow), two soft radial-gradient highlights (upper-left light, lower-right shadow), and a non-optional fractal-noise grain overlay on a `::before` pseudo-element with multiply blend. This stack creates a surface that reads as physical paper under raking light. Without the grain, the system collapses into flat cartoon-yellow; the texture is foundational, not decorative.
The typeface stack is a deliberate three-voice editorial pairing. **Space Grotesk** at weight 600–700 carries every printed headline and display moment — its tight geometric character at heavy weights reads as a poster or notice-board printout. **Caveat** (a hand-script face) carries every handwritten moment: marginalia, "me" voice annotations, step numerals, pill labels, oversized script ordinals. Caveat is the system's personal-voice mechanism — wherever script appears, the tone shifts from "official notice" to "handwritten note in the margin." **DM Mono** at weight 500 carries every archival metadata tag: top-chrome brand lockup, footer meta, source attribution, axis labels. The three voices — print headline, handwritten note, archival catalog tag — are non-overlapping, and the system's editorial rhythm depends on them staying in their lanes.
The palette is anchored to a yellow-and-blue complementary pair. **Paper yellow** (`{colors.paper}` and its three close variants) is every surface. **Ink blue** (`{colors.ink}` — a deep cobalt #1F3A8A) is every text moment, every border, every divider, every pin illustration. **Cream** (`{colors.cream}`) is the card background — a calmer off-white-ivory tone that lets cards visually recede from the loud yellow page. **Cinnabar red** (`{colors.red}` — #C2342B) is used in two specific roles only: the rotated rubber-stamp component and the negative-state pill. Red is never used as text, fill, or border outside these two roles. Tertiary colors (olive, orange, kraft) exist in the token list but are not actively deployed in the source.
Depth is created through a single signature mechanism: **the hard offset shadow**. Every card carries a `5px 6px 0 0 {colors.ink}` (or `4px 5px 0 0`, or `8px 9px 0 0` for the largest quote panel) — a solid ink-blue rectangle offset down and to the right with zero blur. This shadow plus the 4px micro-radius corner plus the 1.5px ink border defines the universal card pattern. Cards look pinned and slightly lifted from the page; the hard offset is the system's only depth language.
**Density philosophy: medium-dense, populated.** Pin & Paper reads as authoritative when its cards are pinned across the page in a clear arrangement — typically 3 to 6 cards per slide, each carrying a heading, a body block, and often a handwritten marginal annotation. A slide with one centered headline and otherwise empty space reads as broken — the system was designed as a populated field-notebook page, and a notebook page that's mostly blank reads as incomplete. Cards should be filled; pins should appear; the handwritten layer should add a marginal note in at least half the slides. The exception is the cover and section-divider slides, which are sparser by convention but compensate with oversized display type (196px) and large pin illustrations.
**Key Characteristics:**
- Yellow paper background (`{components.paper-surface}`) with two layered radial gradients and a non-optional fractal-noise grain overlay (`{components.paper-grain-overlay}`) on every slide.
- Deep cobalt-blue ink (`{colors.ink}`) as the universal text, border, divider, and pin-illustration color.
- Cream card surfaces (`{colors.cream}`) with 1.5px ink borders, 4px micro-radius, and **a hard ink-blue offset shadow** (5px–6px, zero blur).
- Hand-drawn safety-pin SVG illustrations (`{components.pin-illustration}`) — closed and open variants — pinned to cards at slight rotation angles.
- Three-voice typography: Space Grotesk for print headlines, Caveat hand-script for personal voice, DM Mono for archival labels.
- A signature cinnabar-red rotated rubber stamp (`{components.stamp}`) for status marks (CONFIDENTIAL, RECEIVED, etc.).
- 4px micro-radius on every card; pills go full 999px.
- Slight panel rotation (0.6 to 1.5 degrees) on alternating cards for the "pinned-askew" effect.
## Colors
### Palette
- **Paper Yellow** (`{colors.paper}` — #EFE56A): The dominant surface color. Saturated cadmium yellow. Combined with the layered radial gradients and grain overlay, this is what makes the slide read as physical paper.
- **Paper Light** (`{colors.paper-2}` — #F5ECA0): Lighter, less saturated yellow. Used as an alternate card fill to break adjacent same-tone cards.
- **Paper Deep** (`{colors.paper-3}` — #E8D85A): Deeper, more saturated yellow. Used on the `.deep` slide variant for higher-contrast moments.
- **Paper Extra** (`{colors.paper-extra}` — #FBE6A4): Warm yellow with a hint of cream, used as the most differentiated card variant — often paired with a slight rotation.
- **Cream** (`{colors.cream}` — #F8F1D6): The card background. A soft off-white ivory that lets cards recede from the loud yellow page. Used on every standard card surface.
- **Kraft** (`{colors.kraft}` — #C9A66B): A warm tan/kraft tone. Defined in the token system but not actively used in the source.
- **Ink Blue** (`{colors.ink}` — #1F3A8A): Deep cobalt navy. The universal text, border, divider, pin illustration, and shadow color. The system's structural identity.
- **Ink Soft** (`{colors.ink-soft}` — #2D4FB8): A slightly lighter cobalt variant; available but rarely used.
- **Ink Line** (`{colors.ink-line}` — #3457C4): A slightly brighter cobalt for line decorations; rarely used.
- **Ink Deep** (`{colors.ink-deep}` — #0E1430): Near-black with a slight blue cast. Used for the `.ink` slide variant background.
- **Cinnabar Red** (`{colors.red}` — #C2342B): The stamp color and the negative-pill border/text color. Used only in two roles — never as a general accent.
- **Olive** (`{colors.olive}`) and **Orange** (`{colors.orange}`): Defined but inactive. Available as reserved tertiary tones.
### Defaults
- **Default slide surface**: `{components.paper-surface}` — yellow paper with layered gradients. Always.
- **Default surface grain**: `{components.paper-grain-overlay}` at opacity 0.35 with multiply blend. Non-optional.
- **Default primary headline color**: `{colors.ink}` on yellow surfaces; `{colors.paper}` on ink surfaces.
- **Default body text color**: `{colors.ink}` on yellow/cream; `{colors.paper}` on ink (with `opacity: 0.85` for muted lead).
- **Default card surface**: `{colors.cream}`. Reach for `{colors.paper-2}` or `{colors.paper-extra}` to break up adjacent same-tone cards.
- **Default border color**: `{colors.ink}` at 1.5px. Always.
- **Default shadow**: `5px 6px 0 0 {colors.ink}` (hard offset, zero blur). Smaller cards may use `4px 5px 0 0`; the largest quote panel uses `8px 9px 0 0`.
- **Default label / metadata color**: `{colors.ink}` at opacity 0.65–0.75 for chrome and footer.
- **Default scribble / handwritten color**: `{colors.ink}`. Caveat is always ink-blue on yellow.
- **Default stamp color**: `{colors.red}` — the only routine use of red.
Cream is the card fill; yellow is the page fill. Mixing these breaks the visual hierarchy: a yellow card on a yellow page disappears; a cream card on a cream page collapses the layered-paper reading.
## Typography
### Font Family
The system loads three web fonts: **Space Grotesk** (weights 400, 500, 600, 700) carries all printed display and body type; **Caveat** (weights 500, 600, 700) carries all handwritten / personal-voice moments; **DM Mono** (weights 400, 500) carries all archival metadata.
The emotional register of each face is distinct and load-bearing:
- Space Grotesk reads as **printed, official, typeset** — the voice of the document itself.
- Caveat reads as **handwritten, personal, a note in the margin** — the voice of the person reading the document.
- DM Mono reads as **archival, catalog-card, indexical** — the voice of the system filing the document.
A key inline mixing rule: **a `<small>` element nested inside a Caveat number switches to a smaller Caveat at 60px** for unit suffixes (like `M`, `×`, `%`). The handwritten suffix preserves the hand-counted feeling of the parent numeral.
A second inline mixing rule: **a `.underline` span inside Caveat scribble text gets a 2px solid ink-blue underline** — used to mimic an underline drawn by hand for emphasis.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.scribble-mega}` | 360px | Caveat | 700 | Decorative oversized quote-mark glyph |
| `{typography.display-mega}` | 196px | Space Grotesk | 700 | Cover headline |
| `{typography.display-section}` | 168px | Space Grotesk | 700 | Section-divider headline (on ink slide) |
| `{typography.display-stat}` | 168px | Space Grotesk | 700 | Hero stat figure |
| `{typography.h1-cta}` | 130px | Space Grotesk | 700 | Closing CTA headline |
| `{typography.h1-chart}` | 110px | Space Grotesk | 700 | Chart-slide headline |
| `{typography.h2}` | 96px | Space Grotesk | 700 | Standard agenda or stats headline |
| `{typography.h2-md}` | 84px | Space Grotesk | 700 | Section heading inside dense slides |
| `{typography.scribble-lg}` | 70px | Caveat | 700 | Process step numerals |
| `{typography.scribble-md}` | 60px | Caveat | 700 | CTA step numerals, large script accents |
| `{typography.quote-text}` | 50px | Space Grotesk | 500 | Pull-quote body |
| `{typography.h2-sm}` | 50px | Space Grotesk | 700 | Notice-slide headline |
| `{typography.card-row}` | 44px | Space Grotesk | 600 | Agenda row label |
| `{typography.card-h3}` | 38px | Space Grotesk | 700 | Card title |
| `{typography.scribble-sm}` | 38px | Caveat | 600 | Handwritten marginal note on cover, notice-card meta |
| `{typography.scribble-xs}` | 32px | Caveat | 600 | Small in-card handwritten annotation |
| `{typography.card-h3-sm}` | 28px | Space Grotesk | 700 | Sub-card heading |
| `{typography.body}` | 22px | Space Grotesk | 400 | Standard body paragraph |
| `{typography.body-md}` | 21px | Space Grotesk | 400 | Body inside tables |
| `{typography.body-sm}` | 19px | Space Grotesk | 400 | Compact body inside dense cards |
| `{typography.body-list}` | 18px | Space Grotesk | 400 | List item inside a card |
| `{typography.label-top}` | 18px | DM Mono | 500 | Top-chrome brand lockup and meta |
| `{typography.label-meta}` | 16px | DM Mono | 500 | Date strip, attribution |
| `{typography.stamp}` | 16px | DM Mono | 500 | Stamp text |
| `{typography.label-footer}` | 15px | DM Mono | 500 | Footer chrome |
### Defaults
- **Default primary content headline**: `{typography.h2}` (96px Space Grotesk 700).
- **Default cover / opening headline**: `{typography.display-mega}` (196px).
- **Default section-break headline**: `{typography.display-section}` (168px), used on the ink-blue slide variant.
- **Default body paragraph size**: `{typography.body}` (22px). For dense multi-card slides, drop to `{typography.body-sm}` (19px).
- **Default card heading**: `{typography.card-h3}` (38px) for standard cards; `{typography.card-h3-sm}` (28px) for sub-cards.
- **Default stat figure**: `{typography.display-stat}` (168px) — with a Caveat `<small>` suffix for unit (M, %, ×).
- **Default label / chrome size**: `{typography.label-top}` (18px) for the top chrome; `{typography.label-footer}` (15px) for the bottom.
- **Default handwritten annotation size**: `{typography.scribble-sm}` (38px) for marginal notes; `{typography.scribble-lg}` (70px) for step numerals.
- **Default weight for any display element**: 700.
- **Default weight for body**: 400.
When unsure, the canonical card composition is: a 38px Space Grotesk card heading + a 22px Space Grotesk body paragraph + a 32px Caveat handwritten note at the bottom. That three-layer typography rhythm (print headline, print body, handwritten margin note) is the system's most recognizable internal pattern.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every slide carries the paper-grain overlay (`{components.paper-grain-overlay}`).** Without it, the paper aesthetic collapses. The grain is part of the surface, not a decorative flourish.
- **Every card carries a 1.5px solid ink border, 4px border-radius, AND a hard ink-blue offset shadow (5–8px offset, zero blur).** All three together — missing the shadow makes the card feel un-pinned; missing the border makes it feel un-printed.
- **Caveat is always ink-blue** (`{colors.ink}`) on yellow/cream surfaces, and always paper-yellow on ink surfaces. Caveat in any other color does not exist.
- **Pin illustrations (`{components.pin-illustration}`) are always rotated off-axis** (typical range: -14° to +20°). A pin rendered at 0° rotation breaks the hand-pinned aesthetic.
- **The stamp component (`{components.stamp}`) is always rotated -4°** with a 3px solid red border, red mono text, and zero radius. Stamp text is always DM Mono uppercase.
- **Every Space Grotesk display headline uses negative letter-spacing** in the -0.02 to -0.04em range. Tighter for larger sizes.
- **Hand-script numerals (Caveat at 60–70px) are the only step-numbering mechanism** in process diagrams and ordered CTA lists. Don't substitute Space Grotesk numerals.
- **The top-chrome lockup includes the inline `#mark` SVG glyph** alongside the brand text. The glyph is part of the brand identity, not optional.
### Typography Principles
The rhythm of Pin & Paper is **printed headline + printed body + handwritten margin note + mono archival tag** — four voices, each in its assigned face. Switching any voice (e.g., setting a marginal note in Space Grotesk, or a body paragraph in Caveat) collapses the system's editorial register.
Italic letterforms are not used. Underline is used only on `.underline` spans inside Caveat scribble text (2px solid ink). Bold inside body is rare; emphasis is achieved either by switching to a heavier Space Grotesk weight at a larger size, or by adding a Caveat handwritten annotation below.
## Layout
### Canvas System
The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component. All sizes are pixel-fixed; the stage handles proportional scaling to the browser viewport.
Most slides use **absolute positioning** with edge-anchored elements (`left: 64px`, `right: 64px`, `top: 110px`, `bottom: 100px`) for the content stage, plus targeted grid layouts for card rows. Pin illustrations are absolutely-positioned overlays on top of card stacks.
### Padding and Anchoring
| Anchor | Value | Use |
|---|---|---|
| `pad-edge` | 64px | Left and right edge insets on every slide |
| `pad-top` | 110px | Top inset for content (below the 44px top chrome) |
| `pad-bottom` | 90px | Bottom inset for content (above the 36px footer chrome) |
| `grid-gap-sm` | 22px | Process card gap |
| `grid-gap-md` | 28px | Notice / stats card gap |
| `grid-gap-lg` | 32px | Notecard grid gap |
Cards typically use `28px–36px` internal padding on the top and `22px–28px` on the sides, with `22px–28px` on the bottom.
### Chrome Frame
Every slide carries a **top chrome band** at 44px top / 64px sides — a brand lockup on the left (with inline #mark SVG glyph) and a meta-tag pair on the right. The chrome is DM Mono uppercase at 18px with 0.12em tracking.
Every slide also carries a **footer chrome** at 36px bottom / 64px sides — typically a source attribution on the left and a page-position marker on the right. The footer is DM Mono uppercase at 15px with 0.14em tracking at 65% opacity.
On ink-blue slides, both chromes flip color to `{colors.paper}` and the grain overlay shifts to opacity 0.25 with screen blend mode.
## Depth and Elevation
### Hard Offset Shadow (Primary Depth)
The system's only depth treatment is the **hard ink-blue offset shadow** on every card: `5px 6px 0 0 {colors.ink}` (standard), `4px 5px 0 0` (compact), `6px 7px 0 0 rgba(239,229,106,.25)` (chart-card with yellow-tinted shadow), or `8px 9px 0 0` (the largest quote panel). The shadow is always solid, always offset down-right, always zero blur. There are no blurred drop shadows anywhere in the system.
### Paper Texture Depth
The fractal-noise grain (`{components.paper-grain-overlay}`) at opacity 0.35 with multiply blend adds a subtle perceived depth — the texture creates micro-variation that reads as paper fiber. This is depth at the surface level, not at the element level.
### Pin Illustrations as Depth Signal
The hand-drawn safety-pin SVGs positioned at the top edge of cards (typically `position: absolute; top: -14 to -22px; left: 28–90px; transform: rotate(-6 to -12deg)`) create the visual illusion that the card has been pinned to the page. The pin is the depth narrative: a pin appearing at the top of a card explains why the card has a shadow and a rotation.
### Slight Rotation on Alternate Cards
Some card variants (`{components.pinned-card-alt2}`) carry a slight rotation (`transform: rotate(0.6deg)` to `rotate(1.5deg)`) that reads as a sheet of paper pinned slightly askew. This is a deliberate imperfection — used sparingly (one or two cards per slide), not on every card.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | Stamp, pin glyphs, page numbers |
| 4px | Cards, panels, table containers, image wrappers — the system's micro-radius |
| 999px | Pills only |
The system uses a **4px micro-radius** on every card — small enough to read as "printed corner with slight bleed" rather than rounded UI. Pills are the only round shape; pills with the unusual treatment of Caveat handwritten letterforms inside.
### Border Weights
- **1.5px solid `{colors.ink}`** — the universal card border. Used on every cream card, every table container, every panel.
- **1.5px dashed rgba(31,58,138,.45)** — used as a dotted separator between agenda rows, between CTA steps, and at the top of source notes inside cards. Adds the "graph-paper line break" feel.
- **3px solid `{colors.red}`** — used only on the stamp component (`{components.stamp}`).
- **2px solid `{colors.ink}`** — used only on the Caveat `.underline` span treatment.
### Decorative Element Types
**Pin illustration (`{components.pin-illustration}`)** — The defining visual signature. A hand-drawn safety-pin SVG (two variants: closed and open) rendered in `currentColor` and rotated at a slight angle. Pins appear at the top of cards, as decorative overlays on the cover, as oversized accent illustrations on section dividers (up to 640px wide), and pinned to agenda rows. The pin is the system's voice — wherever a pin appears, the page reads as a pinned document.
**Stamp (`{components.stamp}`)** — A cinnabar-red rotated rubber-stamp tag with 3px solid red border, red mono uppercase text, and -4° rotation. Used for status marks (CONFIDENTIAL, RECEIVED). The stamp is one of the two roles where red is used in this system.
**Scribble (`{components.scribble}`)** — A Caveat hand-script text block, often rotated -1.5° to -3° for the "handwritten" feel. Used for marginal notes, "me" voice annotations, large script accents. May include `.underline` spans for handwritten emphasis.
**Pinned card (`{components.pinned-card}`)** — The universal card pattern: cream fill, 1.5px ink border, 4px micro-radius, 5–6px hard ink offset shadow. Often carries a pin illustration overlapping its top edge. Three alternate fill colors break up adjacent same-tone cards.
**Top chrome lockup** — The brand text accompanied by an inline #mark SVG glyph (a circle on the right with an arrow shaft pointing left). The glyph is part of the brand's identity.
**Dashed border separators** — Used as inter-row dividers in agenda lists, CTA step lists, and inside cards as source-attribution separators. Always `1.5px dashed rgba(31,58,138,.45)`.
**Caveat pills (`{components.pill-yes}`, `{components.pill-part}`)** — Pills with hand-script letterforms inside (Caveat 28px) on solid or paper-tone fills. The mismatch between rounded UI shape and handwritten text is intentional.
**Process / CTA script numerals** — Caveat 60–70px ordinals inside cards or list rows. The hand-script number signals "step counted by hand, not by an algorithm."
**Oversized script quote-mark** — A Caveat at 360px rendered as the opening glyph on the quote slide. The script size pushes into the realm of decoration; the glyph is so large that it functions as composition, not punctuation.
## Do's and Don'ts
### Do
- Apply the paper-grain overlay (`{components.paper-grain-overlay}`) to every slide. The texture is foundational to the paper reading.
- Set every card with the universal pattern: 1.5px ink border + 4px radius + hard ink offset shadow. The three together define the card.
- Use Space Grotesk weight 700 in mixed case (with negative letter-spacing) for every printed headline.
- Use Caveat for every handwritten or personal-voice moment — marginal notes, step numerals, pill text. The script is the system's "me" voice.
- Use DM Mono uppercase at 0.12–0.18em tracking for every archival tag, chrome label, and footer string.
- Rotate every pin illustration off-axis (typical range -14° to +20°). A pin at 0° rotation breaks the hand-pinned aesthetic.
- Populate cards. The system reads as authoritative when 3–6 cards are pinned across the page, each with heading + body + marginal note.
- Use the rotated stamp component (`{components.stamp}`) for status marks. The -4° rotation is its identity.
- Pair a Caveat step numeral with a Space Grotesk card heading inside process and CTA lists. The script numeral is the system's ordering voice.
- Use a slight rotation (0.6° to 1.5°) on one card per slide for the "pinned-askew" effect. Don't rotate every card.
### Don't
- Don't omit the paper-grain overlay. Without it, the surface collapses into flat cartoon-yellow.
- Don't substitute a different list marker for the Caveat hand-script numeral. Step numbers are always hand-script.
- Don't use red outside the stamp and the negative pill. Red is a two-role accent only.
- Don't render pin illustrations at 0° rotation. The off-axis tilt is what makes them read as physical pins.
- Don't use blurred shadows. Cards use hard ink-blue offset shadows only.
- Don't fill a card with yellow on the yellow page surface. Cards are cream; the contrast between cream cards and yellow page is the layered-paper signal.
- Don't put body copy in Caveat. The hand-script is for marginal notes and accents, never paragraphs.
- Don't put headline copy in DM Mono. Mono is the archival voice, not the editorial voice.
- Don't use radius larger than 4px on cards. The micro-radius is the printed-corner signal; larger radius collapses into generic UI.
- Don't compose a near-empty slide. The system was designed as a populated notebook page; sparseness reads as broken.
## Responsive Behavior
The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component (loaded via `deck-stage.js`). The stage handles proportional scaling to the browser viewport — all pixel-fixed sizes inside the canvas scale uniformly.
### Presenter Behavior
- The `<deck-stage>` component manages navigation, scaling, and presenter chrome.
- Keyboard, touch, and mouse-wheel navigation are handled by the stage component.
- The slide canvas is constant 1920×1080 regardless of viewport size.
### Print Behavior
Print export depends on the deck-stage component's print handling. The fractal-noise grain overlay may not render in all PDF exports — test before assuming texture transfers.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face | Chinese face | Weight |
|---|---|---|---|
| Display / headline (Space Grotesk 700) | Space Grotesk | 龙藏体 Long Cang | 400 (only weight available) |
| Body (Space Grotesk 400) | Space Grotesk | 霞鹜文楷 LXGW WenKai | 400 |
| Handwritten / scribble (Caveat) | Caveat | 龙藏体 Long Cang | 400 |
| Label / mono (DM Mono UPPERCASE tracked) | DM Mono | 霞鹜文楷 LXGW WenKai | 400 (do not force monospace on CJK) |
### Mixed-Content Strategy
Strategy A — extend each token's `fontFamily` to include the Chinese face after the Latin face. Space Grotesk display tokens become `"Space Grotesk, Long Cang, Helvetica Neue, Arial, sans-serif"`; Space Grotesk body tokens become `"Space Grotesk, LXGW WenKai, Helvetica Neue, Arial, sans-serif"`; Caveat tokens become `"Caveat, Long Cang, cursive"`. Latin glyphs render in the original face; CJK falls through automatically.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Caveat:wght@500;600;700&family=DM+Mono:wght@400;500&family=Long+Cang&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-lxgw-wen-kai-regular/font.css" rel="stylesheet">
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation (,。:;!?「」())
- No period on display headlines (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence
### Aesthetic Notes for This System
Pin & Paper is the strongest fit for Chinese in this entire library. The yellow legal-pad surface, the cobalt ink, the safety-pin illustrations, and the field-notebook register all translate naturally into Chinese — the system reads as a 笔记本 / 手账 page in either script.
**龙藏体 Long Cang** is a hard-pen handwritten Chinese face — the brushless, ballpoint-on-paper equivalent of Chinese handwriting. It is the perfect Chinese substitute for the Space Grotesk + Caveat dual-role headline-and-scribble voices in this system. Long Cang at large sizes (96–168px) reads as a confident handwritten field-note headline — exactly what Pin & Paper is trying to evoke. Use it for both display headlines and the Caveat-equivalent scribble layer. Layering two visually-distinct hand-script faces in pure Chinese is unnecessary; Long Cang carries both roles.
**霞鹜文楷 LXGW WenKai** is a kaishu-derived body face designed for screen reading — it carries the warmth and slight irregularity of handwritten 楷书 but stays legible at body sizes (18–22px). It is the strongest counterweight to Long Cang's handwritten display and matches the system's "field-notebook personal voice" register exactly. Set every Chinese body paragraph in LXGW WenKai 400.
The pin illustrations, the rotated red stamp, the cream cards with hard ink offset shadows — all transfer unchanged. The Caveat pill component (handwritten letters inside a rounded pill) translates to Long Cang inside the same pill shape and reads as charmingly hand-counted in Chinese.
The system's most recognizable rhythm (printed headline + printed body + handwritten margin note) becomes (Long Cang headline + LXGW WenKai body + Long Cang margin note in a slightly different size). The voice distinction in pure Chinese comes from size, rotation, and color rather than from face swap — Long Cang at 38px rotated -3° in the margin reads clearly as "marginal annotation" against Long Cang at 96px upright in the headline.
DM Mono uppercase tracked labels do not transfer to CJK. Chinese metadata in the top chrome should use LXGW WenKai 400 mixed case with letter-spacing 0. Pure Latin metadata (date strings, source URLs) stays in DM Mono.
### Known CJK Gap
Long Cang and LXGW WenKai are visually adjacent — both carry handwritten kaishu DNA. The three-voice editorial pairing (print / handwritten / archival) collapses into a two-voice pairing in pure Chinese (handwritten-display / handwritten-body / archival-Latin-only). This is not a bug — pure-Chinese decks in Pin & Paper read as more uniformly hand-touched than their Latin counterparts, which is actually closer to the field-notebook aesthetic the system aims for.
## Iteration Guide
1. Every new slide background is the paper-surface (`{components.paper-surface}`) with the grain overlay on `::before`. Don't skip the texture.
2. Every new card uses the universal pattern: cream fill, 1.5px ink border, 4px radius, hard ink offset shadow. Don't customize.
3. Every new headline is Space Grotesk weight 700 mixed case with negative letter-spacing. Don't reach for a different weight.
4. Every new step numeral or ordered-list marker is Caveat hand-script at 60–70px. Don't substitute a numeric font.
5. Every new label or metadata tag is DM Mono uppercase with 0.12–0.18em tracking.
6. Every new pin illustration is rotated off-axis. Choose closed (#pin) for a "secured" feel; open (#pin-open) for a "lifted" feel.
7. To add personal voice to a card, append a Caveat marginal note at the bottom — usually with a `.underline` span for handwritten emphasis.
8. To mark a card with status, place the stamp component (`{components.stamp}`) at a slight rotation in the upper area of the card.
9. To break up adjacent same-tone cards, alternate between cream, paper-2, and paper-extra fills. Add a slight rotation on one card for variety.
10. To use the ink-blue surface variant (e.g., a section divider), flip text color to `{colors.paper}` and reduce grain opacity to 0.25 with screen blend mode.
## Known Gaps
- The system depends on a `<deck-stage>` web component loaded via `deck-stage.js`. Without it, the 1920×1080 canvas will not scale and slides will render at native pixel size.
- The pin illustrations are embedded as inline SVG symbol definitions at the top of the document. New slides that need pin illustrations must reference them via `<use href="#pin">` or `<use href="#pin-open">` — and the symbol definitions must be present in the document.
- The fractal-noise grain overlay uses a data-URI SVG with `feTurbulence`. Some browsers (especially older Safari versions) may render the noise inconsistently or skip it during PDF export.
- The Caveat font carries hand-script ligatures and may render inconsistently between operating systems. Default fallback is `cursive` which varies wildly across systems.
- The `kraft`, `olive`, and `orange` color tokens are defined but inactive in the source. They are reserved for future extension but have no current role.
- The pill-yes component uses Caveat letterforms inside a rounded pill shape — this is intentionally unusual but may read as a UI bug to viewers unfamiliar with the system.
- The paper-grain overlay uses `mix-blend-mode: multiply` on standard slides and `mix-blend-mode: screen` on ink slides. The blend mode flip is essential — using multiply on the dark ink slide turns the slide muddy.
- The bar chart and line chart components use SVG with manually-positioned points. There is no data-binding layer.
- The hand-drawn pin SVG is a fixed-path illustration. Re-coloring works via `currentColor`, but the pin proportions cannot be adjusted without editing the SVG path data.
# Pin & Paper Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/pin-and-paper/design.md`
- Preview card: `bold-template-pack/templates/pin-and-paper/preview.md`
## Selection Metadata
- Slug: `pin-and-paper`
- Tagline: Yellow paper with safety-pin illustrations, ink-blue handwritten Caveat, paper-grain texture.
- Mood: crafted, handmade, warm, thoughtful, literary
- Tone: literary, intimate, warm, grounded
- Formality: medium
- Density: medium
- Scheme: light
- Best for: Anything that should feel hand-crafted, warm, and literary: qualitative research findings, founder reflections, longform brand stories, workshop debriefs. The signature safety-pin illustrations and paper-grain texture make it especially good for any deck — including tech or business — that wants personality and warmth over polish.
- Avoid for: Decks that need to feel digital-native polished or rigorously data-driven — handwritten Caveat is intentionally informal.
## Visual Snapshot
A field-notebook editorial system rendered as yellow legal-pad paper with deep cobalt-blue ink. Every slide carries a fractalnoise paper-grain overlay, hand-drawn safety-pin SVG illustrations that "pin" cards to the page, and a hand-script Caveat face for personal annotations. Space Grotesk at heavy weights carries the printed headlines; DM Mono handles archival labels. The aesthetic borrows from analog field reports, vintage public-notice boards, and the diary pages of scientific notebooks — closer to a lab journal pinned to a corkboard than a polished deck.
Pin & Paper is a field-notebook editorial system built on a single material premise: every slide is yellow legal-pad paper. The paper is rendered through a base color ({colors.paper} — saturated cadmium yellow), two soft radial-gradient highlights (upper-left light, lower-right shadow), and a non-optional fractal-noise grain overlay on a ::before pseudo-element with multiply blend. This stack creates a surface that reads as physical paper under raking light. Without the grain, the system collapses into flat cartoon-yellow; the texture is foundational, not decorative.
## Preview Ingredients
- Palette: paper #EFE56A; paper-2 #F5ECA0; paper-3 #E8D85A; paper-extra #FBE6A4; cream #F8F1D6; kraft #C9A66B; ink #1F3A8A; ink-soft #2D4FB8
- Typography: Space Grotesk; Caveat; DM Mono
- Signature move: Yellow paper background ({components.paper-surface}) with two layered radial gradients and a non-optional fractal-noise grain overlay ({components.paper-grain-overlay}) on every slide.
- Signature move: Deep cobalt-blue ink ({colors.ink}) as the universal text, border, divider, and pin-illustration color.
- Signature move: Cream card surfaces ({colors.cream}) with 1.5px ink borders, 4px micro-radius, and a hard ink-blue offset shadow (5px–6px, zero blur).
- Signature move: Hand-drawn safety-pin SVG illustrations ({components.pin-illustration}) — closed and open variants — pinned to cards at slight rotation angles.
- Signature move: Three-voice typography: Space Grotesk for print headlines, Caveat hand-script for personal voice, DM Mono for archival labels.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Pink Script (After Hours)
description: A nocturnal couture editorial system rendered in hot fuchsia ink on dim warm-black paper, with a soft film-grain overlay and a hairline interior frame. DM Serif Display carries every script and editorial moment at sizes up to 600px; Inter at weight 300 carries the body voice; JetBrains Mono carries the boutique-catalog metadata. The aesthetic borrows from glossy fashion magazine spreads, late-night perfume advertising, and the editorial pages of high-end zines — closer to a Maison's seasonal lookbook than a startup deck.
colors:
ink-deep: "#060507"
ink-violet: "#0F0D11"
paper-blush: "#F5EDF1"
pink: "#ED3D8C"
pink-light: "#FF66A8"
pink-deep: "#B81D67"
line-pink: "rgba(237, 61, 140, 0.32)"
mute-paper: "rgba(245, 237, 241, 0.55)"
hair-paper: "rgba(245, 237, 241, 0.14)"
color-aliases:
c-bg: ink-deep
c-fg: paper-blush
c-accent: pink
c-line: line-pink
typography:
script-huge:
fontFamily: "DM Serif Display, serif"
fontSize: 540px
fontWeight: 400
lineHeight: 1.05
letterSpacing: -0.01em
color: "{colors.pink}"
script-section:
fontFamily: "DM Serif Display, serif"
fontSize: 600px
fontWeight: 400
lineHeight: 0.82
letterSpacing: -0.02em
color: "{colors.pink}"
script-giant:
fontFamily: "DM Serif Display, serif"
fontSize: 360px
fontWeight: 400
lineHeight: 1.05
color: "{colors.pink}"
script-cover:
fontFamily: "DM Serif Display, serif"
fontSize: 280px
fontWeight: 400
lineHeight: 1.02
letterSpacing: -0.015em
color: "{colors.pink}"
script-large:
fontFamily: "DM Serif Display, serif"
fontSize: 220px
fontWeight: 400
lineHeight: 1.04
color: "{colors.pink}"
script-med:
fontFamily: "DM Serif Display, serif"
fontSize: 156px
fontWeight: 400
lineHeight: 1.04
color: "{colors.pink}"
script-sm:
fontFamily: "DM Serif Display, serif"
fontSize: 132px
fontWeight: 400
lineHeight: 1.06
color: "{colors.pink}"
serif-cta:
fontFamily: "DM Serif Display, serif"
fontSize: 140px
fontWeight: 400
lineHeight: 1.04
letterSpacing: -0.015em
color: "{colors.paper-blush}"
serif-h2:
fontFamily: "DM Serif Display, serif"
fontSize: 132px
fontWeight: 400
lineHeight: 1.06
color: "{colors.paper-blush}"
serif-quote:
fontFamily: "DM Serif Display, serif"
fontSize: 92px
fontWeight: 400
lineHeight: 1.05
letterSpacing: -0.005em
color: "{colors.paper-blush}"
serif-chart-h:
fontFamily: "DM Serif Display, serif"
fontSize: 90px
fontWeight: 400
lineHeight: 1.06
color: "{colors.paper-blush}"
serif-section-h:
fontFamily: "DM Serif Display, serif"
fontSize: 88px
fontWeight: 400
lineHeight: 1.06
color: "{colors.paper-blush}"
serif-stat:
fontFamily: "DM Serif Display, serif"
fontSize: 116px
fontWeight: 400
lineHeight: 0.9
color: "{colors.pink}"
serif-toc-num:
fontFamily: "DM Serif Display, serif"
fontSize: 64px
fontWeight: 400
lineHeight: 1.0
color: "{colors.pink}"
serif-toc-title:
fontFamily: "DM Serif Display, serif"
fontSize: 56px
fontWeight: 400
lineHeight: 1.05
color: "{colors.paper-blush}"
serif-quote-attr:
fontFamily: "DM Serif Display, serif"
fontSize: 48px
fontWeight: 400
lineHeight: 1.05
color: "{colors.paper-blush}"
serif-process-h:
fontFamily: "DM Serif Display, serif"
fontSize: 38px
fontWeight: 400
lineHeight: 1.05
color: "{colors.paper-blush}"
serif-matrix-label:
fontFamily: "DM Serif Display, serif"
fontSize: 32px
fontWeight: 400
lineHeight: 1.2
color: "{colors.paper-blush}"
body:
fontFamily: "Inter, system-ui, sans-serif"
fontSize: 24px
fontWeight: 300
lineHeight: 1.55
color: "{colors.paper-blush}"
body-muted:
fontFamily: "Inter, system-ui, sans-serif"
fontSize: 22px
fontWeight: 300
lineHeight: 1.5
color: "{colors.mute-paper}"
body-toc-desc:
fontFamily: "Inter, system-ui, sans-serif"
fontSize: 24px
fontWeight: 300
lineHeight: 1.4
color: "{colors.mute-paper}"
mono-runner:
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
fontWeight: 400
letterSpacing: 0.14em
textTransform: uppercase
mono-kicker:
fontFamily: "JetBrains Mono, monospace"
fontSize: 22px
fontWeight: 400
letterSpacing: 0.14em
textTransform: uppercase
color: "{colors.pink}"
mono-label:
fontFamily: "JetBrains Mono, monospace"
fontSize: 22px
fontWeight: 400
letterSpacing: 0.14em
textTransform: uppercase
color: "{colors.paper-blush}"
mono-cover-pre:
fontFamily: "JetBrains Mono, monospace"
fontSize: 28px
fontWeight: 400
letterSpacing: 0.42em
textTransform: uppercase
color: "{colors.paper-blush}"
mono-pill:
fontFamily: "JetBrains Mono, monospace"
fontSize: 16px
fontWeight: 400
letterSpacing: 0.08em
textTransform: uppercase
spacing:
edge-x: 60px
edge-top-chrome: 60px
edge-bottom-chrome: 60px
content-top: 140px
content-bottom: 140px
inner-frame-inset: 36px
canvas:
width: 1920px
height: 1080px
components:
slide-surface:
background: "radial-gradient(ellipse 90% 70% at 30% 30%, #1A1218 0%, #0A0709 55%, #050306 100%)"
description: "Universal dark surface — radial ellipse from a slightly warmer #1A1218 in the upper-left fading to near-black in the lower-right. The off-center light source is part of the system's identity."
film-grain:
selector: ".slide::before"
background: "fractalNoise SVG via data URI, baseFrequency=0.9, octaves=2"
opacity: 0.08
mixBlendMode: screen
description: "Subtle film grain overlay on every slide via ::before. Opacity 0.08 with screen blend — barely visible but reads as photographic grain rather than digital flatness."
hairline-frame:
selector: ".slide::after"
position: "absolute; inset: 36px"
border: "1px solid {colors.hair-paper}"
description: "1px paper-blush-at-14%-opacity interior frame inset 36px from each slide edge. Always present. Functions as the editorial border of the magazine page."
runner:
position: "absolute; top: 60px; left: 60px; right: 60px"
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.14em
textTransform: uppercase
description: "Top metadata runner — brand name on left (colored pink), section / chapter tag on right (muted paper-blush)."
footer:
position: "absolute; bottom: 60px; left: 60px; right: 60px"
fontFamily: "JetBrains Mono, monospace"
fontSize: 24px
letterSpacing: 0.14em
textTransform: uppercase
description: "Bottom metadata runner — source / confidentiality on left, page-position (e.g. '03 / 09') on right. Page-position has paper-blush base text with a pink ::em for the current number."
pink-rule:
height: 1px
background: "{colors.pink}"
opacity: 0.45
description: "Hairline pink rule for soft section separators."
hair-rule:
height: 1px
background: "{colors.paper-blush}"
opacity: 0.25
description: "Hairline paper rule for muted section separators."
pink-glow:
textShadow: "0 0 80px rgba(237, 61, 140, 0.18)"
description: "Soft pink halo behind large script titles. Applied via text-shadow on hero serif text only."
pink-glow-mega:
textShadow: "0 0 120px rgba(237, 61, 140, 0.22)"
description: "Stronger pink halo for section-divider mega numerals."
callout-rail:
borderLeft: "1px solid {colors.pink}"
paddingLeft: 24px
description: "Pink left rule with right-aligned content — used as a callout container beside a chart, beside a chapter explanation."
matrix-cell:
padding: "16px 24px"
borderBottom: "1px solid {colors.line-pink}"
fontFamily: "Inter, sans-serif"
fontSize: 22px
fontWeight: 300
color: "{colors.paper-blush}"
description: "Comparison matrix cell. Rows are separated by hairline pink-at-32% rules; columns are gap-separated, no vertical borders."
matrix-cell-us:
background: "rgba(237, 61, 140, 0.08)"
description: "Highlighted matrix row variant — soft pink wash to mark the 'our' column."
pill-outline:
border: "1px solid {colors.pink}"
color: "{colors.pink}"
padding: "6px 14px"
fontFamily: "JetBrains Mono, monospace"
fontSize: 16px
letterSpacing: 0.08em
textTransform: uppercase
description: "Hollow pink pill — 1px pink border with pink mono text. The default pill state."
pill-solid:
background: "{colors.pink}"
color: "{colors.ink-deep}"
border: "1px solid {colors.pink}"
fontWeight: 500
description: "Solid pink pill — pink fill, deep-ink text. Affirmative / featured state."
pill-dim:
borderColor: "{colors.hair-paper}"
color: "{colors.mute-paper}"
description: "Dim pill — muted paper border, muted paper text. The de-emphasized state."
qr-tile:
width: 180px
height: 180px
background: "{colors.paper-blush}"
padding: 12px
description: "QR-code container — solid paper-blush square with 12px white padding around the SVG QR. The only large light-surface element in the system."
stat-row:
display: "grid; columns: 240px 1fr"
borderBottom: "1px solid {colors.hair-paper}"
paddingBottom: 16px
description: "Stat row pattern — large pink serif figure on the left (with a paper-blush superscript unit) paired with a mono label and Inter description on the right. Rows are separated by 1px paper hairline."
callout-num:
fontFamily: "DM Serif Display, serif"
fontSize: 120px
lineHeight: 0.9
color: "{colors.pink}"
description: "Chart callout number — large pink serif numeral with smaller paper-colored unit suffix."
arrow-glyph:
width: 24px
height: 24px
color: "{colors.pink}"
description: "Small pink right-arrow SVG used between process steps."
---
## 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
Pink Script is a **nocturnal couture editorial system** built on a single atmospheric premise: a deep warm-black surface lit from the upper-left by a slightly warmer #1A1218 ellipse that fades to near-black across the lower-right. The off-center light source reads as a studio softbox catching one corner of a magazine spread. Over this, a subtle film-grain overlay at 8% opacity with screen blend adds the photographic graininess of late-night editorial photography. Inside this surface sits a 1px hairline interior frame (paper-blush at 14% opacity, inset 36px from each edge) — the editorial border of every page. Without the lit gradient, the film grain, and the interior frame, the system collapses into flat dark UI.
The typeface stack is a deliberate three-voice editorial pairing. **DM Serif Display** carries every editorial moment — script titles (treated as the system's "pink script"), serif headlines, stat figures, quote text. It runs at weight 400 only; the face has just one weight and that's the system's display voice. The serif scales freely from 32px (table labels) all the way up to 600px (section-divider numerals). **Inter** at weight 300 carries every body paragraph, lead, description, and caption — the ultra-light geometric sans is the system's calm prose voice. **JetBrains Mono** at weight 400 carries every label, kicker, page number, axis tag, runner, and footer string — always uppercase with at least 0.08em positive tracking.
The palette is anchored to a single signature: **hot pink fuchsia** (`{colors.pink}` — #ED3D8C) against deep warm-black (`{colors.ink-deep}` — #060507). The pink is the entire editorial accent system; it appears as script title color, as kicker color, as chart line color, as pill border, as inline `<em>` switch inside paper-blush headlines, as callout numerals, as rule color, and as the soft halo (text-shadow glow) behind hero script titles. **Paper-blush** (`{colors.paper-blush}` — #F5EDF1) is the secondary text color — used for editorial sans-serif headlines, paragraph copy, and any moment that should read as ink rather than highlight. Muted paper at 55% opacity handles secondary text; hairline paper at 14% handles separators and the interior frame.
Depth is created through three layered mechanisms: the **off-center radial gradient surface** (lit from the upper-left), the **subtle film-grain overlay** (8% opacity, screen blend, adds photographic texture), and the **pink halo text-shadow** on hero script titles (a soft 80–120px glow that simulates the light bleed of large neon-saturated type on photographic paper). There are no drop shadows on any element; the depth is atmospheric and photographic, not structural.
**Density philosophy: sparse-medium with one hero moment.** Pink Script reads as elegant when a single oversized script anchors the slide and the rest is generous negative space punctuated by 2–4 small editorial fragments (a runner, a kicker, a paragraph, a footer). A slide with the hero script taking up 60–70% of the canvas and the supporting copy quietly orbiting the remaining margin is correct. Cramming the canvas with multiple equally-weighted regions breaks the late-night magazine feeling. The exception is the stats slide (5 stat rows side-by-side), the comparison matrix (full-grid table), and the system slide (multiple panels) — these slides are denser by design because the editorial purpose is reference, not poetry. Process and TOC slides are populated but always hierarchical: a giant script header dominates, with smaller card rows orbiting beneath.
**Key Characteristics:**
- Deep warm-black surface (`{components.slide-surface}`) lit from the upper-left by a radial gradient ellipse.
- A subtle film-grain overlay (`{components.film-grain}`) on every slide — opacity 0.08, screen blend.
- A 1px paper-blush interior frame (`{components.hairline-frame}`) inset 36px from each edge, present on every slide.
- Hot fuchsia pink (`{colors.pink}`) is the single chromatic accent — used as script color, kicker color, line color, pill outline, inline emphasis, and the soft halo behind hero scripts.
- DM Serif Display carries every editorial moment, scaling from 32px to 600px. There is no second display face.
- Inter at weight 300 carries every body paragraph — ultra-light sans is the system's prose voice.
- JetBrains Mono uppercase at 0.08em+ tracking carries every label, page number, and runner string.
- Top runner and bottom footer chromes appear on every slide; the runner brand text is pink, everything else in chrome is muted paper-blush.
- The inline `<em>` element switches paper-blush serif headlines to pink — the system's editorial emphasis mechanism.
## Colors
### Palette
- **Ink Deep** (`{colors.ink-deep}` — #060507): The base surface color. A near-black with a faint warm shift. Combined with the radial gradient, this anchors the dark editorial surface.
- **Ink Violet** (`{colors.ink-violet}` — #0F0D11): A slightly lifted dark with a violet cast. Reserved alternate dark — available but rarely used in current slide types.
- **Paper Blush** (`{colors.paper-blush}` — #F5EDF1): A warm off-white with a faint pink undertone. The primary editorial text color, the QR-tile background, and the secondary highlight surface. Reads as paper rather than pure white.
- **Pink** (`{colors.pink}` — #ED3D8C): Hot fuchsia. The system's single chromatic accent. Used as the script title color, kicker color, inline `<em>` color, callout numeral color, rule color, chart line color, pill outline color, and the source color for the halo text-shadow.
- **Pink Light** (`{colors.pink-light}` — #FF66A8): A brighter pink. Defined but not used in current slide types.
- **Pink Deep** (`{colors.pink-deep}` — #B81D67): A darker pink. Defined but not used in current slide types.
- **Line Pink** (`{colors.line-pink}` — rgba(237,61,140,0.32)): Pink at 32% opacity for table row dividers and chart axis lines.
- **Mute Paper** (`{colors.mute-paper}` — rgba(245,237,241,0.55)): Paper-blush at 55% for muted body text and metadata.
- **Hair Paper** (`{colors.hair-paper}` — rgba(245,237,241,0.14)): Paper-blush at 14% for the interior hairline frame, dim pill borders, and toc-row dividers.
### Defaults
- **Default slide surface**: `{components.slide-surface}` — the lit warm-black radial gradient. Always.
- **Default film grain**: `{components.film-grain}` at opacity 0.08 with screen blend. Non-optional.
- **Default interior frame**: `{components.hairline-frame}` at 1px paper-blush 14%. Non-optional.
- **Default primary headline color**: For a hero script moment, `{colors.pink}`. For an editorial headline that should read as ink (not highlight), `{colors.paper-blush}`.
- **Default body text color**: `{colors.paper-blush}` for primary copy; `{colors.mute-paper}` for muted lead and description.
- **Default kicker color**: `{colors.pink}`. The eyebrow label is always pink.
- **Default label / metadata color**: `{colors.mute-paper}` for runner, footer, and metadata.
- **Default line / divider color**: `{colors.pink}` at 45% opacity for soft pink rules; `{colors.hair-paper}` for muted hairlines.
- **Default emphasis mechanism inside a paper-blush headline**: wrap in `<em>` to switch that word to `{colors.pink}` (font-style stays upright).
- **Default pill state**: outline (`{components.pill-outline}`) — pink border, pink text.
- **Default chart series**: pink line for primary; muted paper-blush dashed for secondary.
The pink is the only chromatic color in regular use; the other pink variants (Pink Light, Pink Deep) are reserved. Don't introduce a second chromatic accent — Pink Script's identity is that it is monochromatically pink.
## Typography
### Font Family
The system loads three web fonts: **DM Serif Display** (weight 400, italic 0 only) carries every editorial / display moment from 32px up to 600px; **Inter** (weights 300, 400, 500, 600) carries every body paragraph and lead; **JetBrains Mono** (weights 400, 500) carries every label, runner, footer, and metadata string.
The emotional register of each face is distinct:
- DM Serif Display reads as **editorial, perfume-magazine, late-night couture** — the face has elegant high-contrast strokes and the system uses it for every moment that should feel literary or magazine-typeset.
- Inter at weight 300 reads as **calm, contemporary, neutrally elegant** — the ultra-light weight matches the editorial tone without competing with the serif.
- JetBrains Mono reads as **archival, boutique-catalog, edition-numbered** — the mono uppercase voice handles edition numbers, page positions, runner brand text, and section tags.
A key inline mixing rule: **the `<em>` element inside a DM Serif Display headline switches color to `{colors.pink}`** (font-style normalized to upright). This is the system's primary headline emphasis — pink ink inside paper-blush serif text.
A second inline mixing rule: **a `<sup>` element inside a stat figure renders at ~36px in `{colors.paper-blush}`** with a slight top-padding offset — used for unit suffixes (%, ×, M).
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.script-section}` | 600px | DM Serif Display | 400 | Section-divider mega numeral |
| `{typography.script-huge}` | 540px | DM Serif Display | 400 | Hero script in a feature display position |
| `{typography.script-giant}` | 360px | DM Serif Display | 400 | Large editorial script title |
| `{typography.script-cover}` | 280px | DM Serif Display | 400 | Cover script title |
| `{typography.script-large}` | 220px | DM Serif Display | 400 | TOC primary script |
| `{typography.script-med}` | 156px | DM Serif Display | 400 | Process slide primary headline |
| `{typography.serif-cta}` | 140px | DM Serif Display | 400 | Closing CTA headline (paper-blush color) |
| `{typography.script-sm}` | 132px | DM Serif Display | 400 | Stat-slide headline, matrix headline |
| `{typography.serif-stat}` | 116px | DM Serif Display | 400 | Stat row figure |
| `{typography.callout-num}` | 120px | DM Serif Display | 400 | Chart callout numeral |
| `{typography.serif-quote}` | 92px | DM Serif Display | 400 | Quote-slide body text |
| `{typography.serif-chart-h}` | 90px | DM Serif Display | 400 | Chart-slide headline |
| `{typography.serif-section-h}` | 88px | DM Serif Display | 400 | Section divider supporting headline |
| `{typography.serif-toc-num}` | 64px | DM Serif Display | 400 | TOC row numeral |
| `{typography.serif-toc-title}` | 56px | DM Serif Display | 400 | TOC row title |
| `{typography.serif-quote-attr}` | 48px | DM Serif Display | 400 | Quote attribution name |
| `{typography.serif-process-h}` | 38px | DM Serif Display | 400 | Process step heading |
| `{typography.serif-matrix-label}` | 32px | DM Serif Display | 400 | Matrix row label |
| `{typography.body}` | 24px | Inter | 300 | Standard body paragraph |
| `{typography.body-muted}` | 22px | Inter | 300 | Muted lead and description |
| `{typography.body-toc-desc}` | 24px | Inter | 300 | TOC row description |
| `{typography.mono-runner}` | 24px | JetBrains Mono | 400 | Top runner and bottom footer |
| `{typography.mono-kicker}` | 22px | JetBrains Mono | 400 | Pink kicker eyebrow |
| `{typography.mono-label}` | 22px | JetBrains Mono | 400 | Standard paper-blush label |
| `{typography.mono-cover-pre}` | 28px | JetBrains Mono | 400 | Cover preamble line (with 0.42em wide tracking) |
| `{typography.mono-pill}` | 16px | JetBrains Mono | 400 | Pill text |
### Defaults
- **Default primary content headline**: `{typography.script-sm}` (132px) — when the slide is a content moment with a strong headline.
- **Default cover / opening headline**: `{typography.script-cover}` (280px) — the cover script lockup.
- **Default section-divider mega numeral**: `{typography.script-section}` (600px).
- **Default body paragraph**: `{typography.body}` (24px Inter 300).
- **Default muted lead / description**: `{typography.body-muted}` (22px Inter 300, mute-paper color).
- **Default label / kicker**: `{typography.mono-kicker}` (22px JetBrains Mono, pink).
- **Default footer / runner**: `{typography.mono-runner}` (24px JetBrains Mono).
- **Default stat figure**: `{typography.serif-stat}` (116px) with a 36px paper-blush `<sup>` for unit.
- **Default weight for any display element**: 400 (DM Serif Display has only one weight).
- **Default weight for body**: 300.
When unsure, the canonical pattern is: a 22px pink kicker + a 132–156px DM Serif Display headline (with one `<em>`-wrapped word in pink if extra emphasis is needed) + a 22–24px Inter 300 paragraph in muted paper-blush. That three-element pattern is the system's most reliable rhythm.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every slide carries the radial-gradient surface, the film-grain overlay, AND the 1px paper-blush interior frame.** All three together. Removing any one collapses the editorial-magazine reading.
- **Every hero script element (sizes 280px and larger) carries the pink halo text-shadow.** `{components.pink-glow}` for hero scripts (80px blur); `{components.pink-glow-mega}` for section-divider mega numerals (120px blur). The halo simulates the light bleed of neon-saturated print.
- **Every script color is `{colors.pink}`.** DM Serif Display in any other color is not "script" — it becomes "serif headline." The pink color is what defines script vs. headline in this system.
- **Paper-blush serif headlines may switch one word to pink via `<em>`** — this is the system's headline emphasis mechanism. The `<em>` stays upright (font-style: normal).
- **DM Serif Display headlines always have `padding-bottom: .1em` (or `.12em` for the largest script).** This compensates for the serif descenders so the visual baseline reads correctly aligned.
- **All JetBrains Mono is uppercase with at least 0.08em positive tracking** (most chrome and labels use 0.12–0.18em; the cover preamble uses 0.42em).
- **Body text is always Inter at weight 300.** Inter at any other weight is not body — switching to 400 reads as a different tone.
- **The kicker is always pink** in `{colors.pink}`. The eyebrow color is non-negotiable.
- **Runner brand text on the left is always pink; the right-side meta is always muted paper-blush.** The pink brand text is the system's persistent identity signal.
- **The page-position footer uses paper-blush base text with a pink `<em>` for the current number.** Format: `<span>03 / 09</span>` where `03` is wrapped in `<em>` to render pink.
### Typography Principles
The rhythm of Pink Script is **oversized pink script + paper-blush serif paragraph headline + muted Inter prose + small mono editorial tag**. Switching any voice (e.g., setting a script in Inter, or body in DM Serif) collapses the system's editorial register. The serif scales freely from 32px to 600px; choose the size based on the slide's hero moment, not on a fixed scale.
Italic letterforms are not used (DM Serif Display does have an italic, but it's not loaded by the template). The `<em>` tag is repurposed as a pink color switch. Underline is not used. Bold weight is not available in DM Serif Display, and using bold Inter for body breaks the calm prose voice.
## Layout
### Canvas System
The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component. All sizes are pixel-fixed; the stage handles proportional scaling.
Most slides use **absolute positioning** with edge-anchored elements. The standard content area is `inset: 140px 60px 140px 60px` — a 140px top reserve for the runner + headline area, 140px bottom reserve for the footer, and 60px left/right edge margins.
### Padding and Anchoring
| Anchor | Value | Use |
|---|---|---|
| `edge-x` | 60px | Left and right edge margins for content |
| `edge-top-chrome` | 60px | Top inset for the runner chrome |
| `edge-bottom-chrome` | 60px | Bottom inset for the footer chrome |
| `content-top` | 140px | Top inset for slide body content (below runner) |
| `content-bottom` | 140px | Bottom inset for slide body content (above footer) |
| `inner-frame-inset` | 36px | The hairline interior frame inset |
### Chrome Frame
Every slide carries a **top runner** at 60px top / 60px sides — a brand name on the left (always pink) and a section / chapter tag on the right (muted paper-blush). The runner is JetBrains Mono uppercase at 24px with 0.14em tracking.
Every slide also carries a **bottom footer** at 60px bottom / 60px sides — typically a source or confidentiality string on the left and a page-position marker on the right. The page-position uses paper-blush base with a pink `<em>` for the current number (e.g., `01 / 09`).
The **hairline interior frame** at 1px paper-blush 14% sits at `inset: 36px` on every slide. It is the editorial border of the magazine page and present unconditionally.
## Depth and Elevation
### No Box Shadows, Atmospheric Depth Only
The system uses **zero box-shadow declarations** on any structural element. Depth comes from three atmospheric layers:
1. **The radial-gradient surface** (`{components.slide-surface}`) — lit from the upper-left by a warm dark ellipse fading to near-black across the lower-right. This creates the impression of a studio softbox catching one corner of the page.
2. **The film-grain overlay** (`{components.film-grain}`) — 8% opacity, screen blend, adds photographic graininess to the surface.
3. **The pink halo text-shadow** on hero script titles — a soft 80–120px blur in pink at low alpha that simulates the light bleed of large neon-saturated type on photographic paper.
### No Drop Shadows on Cards or Panels
Cards, tables, and panels do not carry shadows. The system's "card" pattern is structural rather than elevated: a region defined by a border or a left-rule, sitting flat on the surface.
### Hairline Rules as Structural Depth
Where the system needs to separate regions, it uses:
- 1px pink at 45% opacity (`{components.pink-rule}`) for soft pink rules.
- 1px paper-blush at 14% (`{components.hair-paper}`) for muted hairline separators.
- 1px pink at 32% (`{colors.line-pink}`) for table row dividers and chart axis lines.
Never a 2px or thicker rule. Never a colored rule outside pink and paper.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | Cards, panels, table cells, QR tiles, runner / footer text |
| 999px | None — pills here are explicitly rectangular |
The system has **zero border-radius** on any structural element. Pills are 0-radius rectangles (despite the "pill" naming convention). The only round element is the small chart-callout circle marker (an SVG `<circle>` element marking an inflection point).
### Border Weights
- **1px solid paper-blush at 14%** — the universal interior hairline frame.
- **1px solid pink** (`{colors.pink}`) — pill outlines.
- **1px solid pink at 32%** (`{colors.line-pink}`) — table dividers, chart axes.
- **1px solid paper-blush at 14%** — TOC row dividers, footer separators.
- **1px solid pink** at full opacity — left callout-rail border, top-of-step border in process slides.
- **1px dashed pink at 18%** — chart grid lines.
No other border weights exist. There is no 2px, 3px, or thicker border anywhere in the system.
### Decorative Element Types
**Hero script title** — A DM Serif Display headline at 220–600px in pink with the halo text-shadow. The defining moment of any slide that uses it. Always pink, always with the glow, always carries `padding-bottom: .1em` to compensate for descenders.
**Paper-blush serif headline** — A DM Serif Display headline at 88–140px in paper-blush. Used when the moment should read as ink rather than highlight. May contain `<em>` to switch one word to pink.
**Pink kicker** — A 22px JetBrains Mono uppercase eyebrow in `{colors.pink}` placed above a headline. The system's most consistent appearance of pink alongside the hero script.
**Mono runner / footer** — Standard JetBrains Mono chrome at 24px / 0.14em tracking. The brand on the runner is always pink; the rest is muted paper-blush.
**Pink rule (`{components.pink-rule}`)** — 1px pink at 45% opacity. Used as a soft separator.
**Hairline rule (`{components.hair-rule}`)** — 1px paper-blush at 14% opacity. Used as a muted separator and as the TOC row divider.
**Callout rail (`{components.callout-rail}`)** — A 1px pink left border with right-aligned content padding-left 24px. Used as a vertical callout container beside charts or beside a chapter explanation.
**Stat row (`{components.stat-row}`)** — A 240px serif figure paired with a mono label + Inter description, separated from the next row by a 1px paper hairline. Stat figures are pink; descriptions are muted paper-blush.
**Pills (`{components.pill-outline}`, `{components.pill-solid}`, `{components.pill-dim}`)** — Three pill states: hollow pink (default), solid pink with deep-ink text (affirmative / featured), and dim hairline (de-emphasized). All are 0-radius rectangles.
**QR tile (`{components.qr-tile}`)** — A 180×180 paper-blush square with 12px white padding and an SVG QR inside. The only large light-surface element in the system; it functions as a "ticket" object on the CTA slide.
**Chart callout** — A 120px pink serif numeral with a 0.5em paper-colored unit suffix, plus a small mono label and a 22px muted Inter description, anchored to the right of a chart by a 1px pink callout rail.
**Chart line** — A 3px solid pink line for the primary series; a 2px paper-blush dashed line for the secondary series. The inflection point on the primary line carries a 9px solid pink circle with an 18px hollow ring at 50% opacity and a vertical dashed line dropping to the axis.
**Process step** — A vertical column anchored by a 1px solid pink top border with a 96px pink serif numeral, a 38px paper-blush serif heading, and an Inter description. Steps are separated by a 24px gap and connected by a small pink arrow glyph.
**Matrix table** — A 4-column grid with the first column being a 32px paper-blush serif label, the column header row colored pink, and the "our column" row tinted with `rgba(237, 61, 140, 0.08)` to mark it.
## Do's and Don'ts
### Do
- Apply the radial-gradient surface, the film-grain overlay, and the 1px paper-blush interior frame to every slide. All three are non-optional.
- Set hero script titles in `{colors.pink}` with the halo text-shadow. The glow is part of the script's identity.
- Use DM Serif Display for every editorial / display moment. The serif is the system's only editorial face — don't substitute a second face.
- Set body paragraphs in Inter at weight 300. The ultra-light weight is the system's calm prose voice.
- Use JetBrains Mono uppercase with at least 0.08em tracking for every label, page number, runner, and footer string.
- Use `<em>` inside a paper-blush serif headline to switch one word to pink — the system's primary headline emphasis.
- Place a pink kicker above every primary headline. The pink eyebrow is the system's editorial signal.
- Use the pink left-rule callout (`{components.callout-rail}`) to anchor a stat, a callout, or a chapter explanation to the right of a chart or content region.
- Add `padding-bottom: .1em` to every DM Serif Display headline. The serif descenders need compensation.
- Use the page-position footer pattern with pink `<em>` for the current number: `<em>03</em> / 09`.
### Don't
- Don't omit the film grain or the interior hairline frame. The system's editorial atmosphere depends on both.
- Don't use box-shadow on any panel or card. Depth is atmospheric, not structural.
- Don't introduce a second chromatic accent. Pink is the only accent. Adding red, blue, or green breaks the system.
- Don't render the pink fuchsia as text on the paper-blush surface — the contrast inverts and looks like a typo.
- Don't put body copy in DM Serif Display. The serif is for editorial moments, not paragraphs.
- Don't put display headlines in Inter. The sans is the body voice, not the headline voice.
- Don't round any element. Cards, pills, tables, QR tiles — all strict rectangles.
- Don't use blurred shadows on any element. The only "shadow" in the system is the pink halo text-shadow on hero scripts, and that's a glow, not a drop shadow.
- Don't use italic letterforms. The `<em>` tag is repurposed as a pink color switch.
- Don't crowd a slide with multiple equally-weighted regions. The system reads as elegant when one hero moment dominates.
## Responsive Behavior
The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component. The stage handles proportional scaling to the browser viewport — all pixel-fixed sizes inside the canvas scale uniformly.
### Presenter Behavior
- Navigation, scaling, and presenter chrome are handled by the `<deck-stage>` component.
- Keyboard, touch, and mouse-wheel navigation are managed by the stage.
- The canvas is constant 1920×1080 regardless of viewport.
### Print Behavior
Print export depends on the deck-stage component's print handling. The pink halo text-shadow and the film-grain overlay may render inconsistently in PDF export — test before assuming visual parity.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face | Chinese face (recommended) | Weight | Notes |
|---|---|---|---|---|
| Script / display (DM Serif Display) | DM Serif Display | **思源宋体 Noto Serif SC** | **900** | Heavy serif that holds visual mass on dark backgrounds. The default choice. |
| Display alternate (delicate moments) | DM Serif Display | 站酷小薇体 ZCOOL XiaoWei | 400 | Couture-thin display face — use only at very large sizes (400px+) where delicacy reads as intentional. Too thin on dark backgrounds at typical headline sizes (40–200px). |
| Body (Inter 300) | Inter | Noto Serif SC (思源宋体) | 400 | Serif body keeps the editorial register cohesive with the heavy display. |
| Label / runner (JetBrains Mono UPPERCASE tracked) | JetBrains Mono | Noto Sans SC | 400 (do not force monospace on CJK) | |
### Mixed-Content Strategy
Strategy A — extend each token's `fontFamily` to include the Chinese face after the Latin face. DM Serif Display tokens become `"DM Serif Display, 'Noto Serif SC', serif"` with `font-weight: 900` on the Chinese run; Inter body tokens become `"Inter, 'Noto Serif SC', system-ui, sans-serif"`; JetBrains Mono tokens become `"JetBrains Mono, 'Noto Sans SC', monospace"`. Latin glyphs render in their original face; CJK falls through automatically.
**Critical**: when Chinese text uses the display role, set `font-weight: 900` explicitly. DM Serif Display's "single weight" is already visually heavy because it's a high-contrast display serif — the equivalent CJK heaviness lives at weight 900 in Noto Serif SC, not weight 400.
### 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=DM+Serif+Display&family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&family=Noto+Serif+SC:wght@400;500;700;900&family=Noto+Sans+SC:wght@400;500;700&family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation (,。:;!?「」())
- No period on display headlines (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence
### Aesthetic Notes for This System
Pink Script (After Hours) is a nocturnal couture system whose entire editorial identity rests on DM Serif Display in hot fuchsia pink at sizes up to 600px against dim warm-black paper. The visual weight of DM Serif Display at any size is substantial — high-contrast strokes, serif terminals, and a typographic mass that holds against the dark background.
The recommended Chinese equivalent is **思源宋体 Noto Serif SC at weight 900**. This carries the same visual mass as DM Serif Display: bold serif terminals, sufficient stroke density to read clearly against the dark surface, and the editorial register that defines the system. Weight 900 is non-negotiable for display moments — anything lighter (400, 500, even 700) will visually disappear against the pink-glow + dark-paper combination and break the entire couture register.
**站酷小薇体 ZCOOL XiaoWei** is a viable secondary option for moments where extreme delicacy reads as intentional — a single 400-px+ pull-quote, a hairline section divider title, a brand wordmark at the very top of a cover slide. Its single-weight 400 with extreme stroke contrast carries a different feeling: dressier, more whisper-thin, more vintage-Vogue than modern-fashion-editorial. For most display work, choose Noto Serif SC 900; reach for XiaoWei only when the moment is genuinely a delicate accent at extreme size.
The pink halo text-shadow (`{components.pink-glow}` at 80–120px blur) transfers perfectly to Chinese characters regardless of which display face you choose. **Apply the same glow to every Chinese display moment in pink** — the neon bleed effect is script-agnostic and the late-night magazine atmosphere survives the script switch fully.
The pink color (`{colors.pink}` — #ED3D8C) as the only chromatic accent works unchanged. The inline `<em>` color switch (paper-blush headline with one word in pink) is a clean transfer to Chinese — wrap one CJK character or one phrase in `<em>` and the pink ink switch reads exactly the same.
**Inter at weight 300 for body** does not transfer directly. Noto Serif SC at weight 400 is the recommended body face — its high-contrast serif stroke matches the couture register of the system's overall feel. Body color stays paper-blush (`{colors.paper-blush}`); the ultra-light register is achieved through size, paper-blush color, and the muted 55%-opacity lead, not through font weight.
JetBrains Mono uppercase tracked labels (runner brand, page numbers, footer chrome) do not transfer to CJK. Pure Latin chrome strings (the brand name itself, edition numbers like `01 / 09`) keep JetBrains Mono. For Chinese chrome text (a section / chapter tag in the upper-right), use Noto Sans SC 400 at the same 24px size with letter-spacing reset to 0 and no uppercase.
The radial-gradient surface, the film-grain overlay, the 1px paper-blush interior frame — all script-agnostic. The pink halo, the kicker, the callout rail, the stat-row pattern, the matrix-cell — all transfer unchanged.
### Known CJK Gap
DM Serif Display's "single weight" is misleading: it's a high-contrast display serif that reads as visually heavy at any size. The Chinese equivalent heaviness lives at Noto Serif SC **weight 900**, not weight 400 — using weight 400 for display will make Chinese headlines look limp and disconnected from the bold pink callouts. The system's reliance on size for hierarchy still works in Chinese, but you must lock display weight at 900 to preserve the visual mass.
ZCOOL XiaoWei is the only CDN-loadable Chinese face that captures the "high-contrast couture serif" character in its proportions, but its single-weight 400 is too thin for most display sizes on this template's dark surface. Treat XiaoWei as a niche option, not the default.
## Iteration Guide
1. Every new slide background is the lit radial gradient (`{components.slide-surface}`) with film grain and the interior hairline frame. Don't skip any of the three layers.
2. Every new hero script title is DM Serif Display in `{colors.pink}` with the halo text-shadow at 80–120px blur.
3. Every new editorial headline that should read as ink (not highlight) is DM Serif Display in `{colors.paper-blush}`. Use `<em>` inside to switch a word to pink.
4. Every new body paragraph is Inter at weight 300 in paper-blush (full) or mute-paper (muted).
5. Every new label, runner, footer, or metadata tag is JetBrains Mono uppercase at 0.08em+ tracking.
6. Every new kicker eyebrow is pink. Don't render a kicker in any other color.
7. Every new pill is a 0-radius rectangle. Choose outline (default), solid (affirmative), or dim (de-emphasized) state.
8. Every new table or matrix uses 1px pink-at-32% row dividers and no vertical borders.
9. Every chart uses a 3px solid pink line for primary and a 2px paper-blush dashed line for secondary. Don't introduce a third color.
10. The runner brand text is always pink; the right-side meta is always muted paper-blush. Don't swap.
## Known Gaps
- The system depends on a `<deck-stage>` web component loaded via `deck-stage.js`. Without it, the 1920×1080 canvas will not scale and slides will render at native pixel size.
- The film-grain overlay uses a data-URI SVG with `feTurbulence`. Some browsers (older Safari) render the noise inconsistently or skip it in PDF export.
- DM Serif Display has only weight 400. There is no bold or italic variant available — the system has no fallback weight scale and depends on size alone for hierarchy.
- The pink halo text-shadow uses fixed 80px and 120px blur values. At very small viewport scales, the glow may dominate the type; at very large scales, the glow may appear weak.
- The `{colors.pink-light}`, `{colors.pink-deep}`, and `{colors.ink-violet}` tokens are defined but inactive in current slide types. They are reserved for future variation.
- The QR-tile SVG inside the CTA slide is a hand-coded pattern of `<rect>` elements that does not encode a real scannable code. Real QR codes need to be generated externally.
- Chart line points and inflection markers are SVG `<polyline>` coordinates that must be computed manually. There is no data-binding layer.
- The cover script lockup uses `padding-left: 180px` on the second line for an indented hanging effect. This is a hardcoded layout decision and doesn't generalize to other word lengths — long second lines may break the centering.
- The runner and footer rely on `white-space: nowrap` to prevent line-wrap. Extremely long brand names or page-position strings may overflow the 60px edge margin.
- The matrix `cell.us` column highlight is a hardcoded `rgba(237, 61, 140, 0.08)` wash. Tinting other columns requires per-column class additions.
# Pink Script — After Hours Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/pink-script/design.md`
- Preview card: `bold-template-pack/templates/pink-script/preview.md`
## Selection Metadata
- Slug: `pink-script`
- Tagline: Black canvas, hot pink accent, pearl-cream paper, Instrument Serif headlines: late-night editorial luxury.
- Mood: nocturnal, moody, intentional, luxe, expressive
- Tone: literary, sultry, considered, magazine
- Formality: medium-high
- Density: low
- Scheme: dark
- Best for: Anything that should feel nocturnal, intentional, and a little luxe: fashion brand decks, creator personal brands, after-hours / nightlife / spirits launches, luxury product reveals, editorial features. Also a striking unexpected pick for a tech keynote, research synthesis, or business pitch that wants to land with magnetic confidence.
- Avoid for: Daytime corporate-professional and traditional B2B contexts where the dark canvas with hot-pink accent reads as too styled or too expressive.
## Visual Snapshot
A nocturnal couture editorial system rendered in hot fuchsia ink on dim warm-black paper, with a soft film-grain overlay and a hairline interior frame. DM Serif Display carries every script and editorial moment at sizes up to 600px; Inter at weight 300 carries the body voice; JetBrains Mono carries the boutique-catalog metadata. The aesthetic borrows from glossy fashion magazine spreads, late-night perfume advertising, and the editorial pages of high-end zines — closer to a Maison's seasonal lookbook than a startup deck.
Pink Script is a nocturnal couture editorial system built on a single atmospheric premise: a deep warm-black surface lit from the upper-left by a slightly warmer #1A1218 ellipse that fades to near-black across the lower-right. The off-center light source reads as a studio softbox catching one corner of a magazine spread. Over this, a subtle film-grain overlay at 8% opacity with screen blend adds the photographic graininess of late-night editorial photography. Inside this surface sits a 1px hairline interior frame (paper-blush at 14% opacity, inset 36px from each edge) — the editorial border of every page. Without the lit gradient, the film grain, and the interior frame, the system collapses...
## Preview Ingredients
- Palette: ink-deep #060507; ink-violet #0F0D11; paper-blush #F5EDF1; pink #ED3D8C; pink-light #FF66A8; pink-deep #B81D67
- Typography: DM Serif Display; Inter; JetBrains Mono
- Signature move: Deep warm-black surface ({components.slide-surface}) lit from the upper-left by a radial gradient ellipse.
- Signature move: A subtle film-grain overlay ({components.film-grain}) on every slide — opacity 0.08, screen blend.
- Signature move: A 1px paper-blush interior frame ({components.hairline-frame}) inset 36px from each edge, present on every slide.
- Signature move: Hot fuchsia pink ({colors.pink}) is the single chromatic accent — used as script color, kicker color, line color, pill outline, inline emphasis, and the soft halo behind hero scripts.
- Signature move: DM Serif Display carries every editorial moment, scaling from 32px to 600px. There is no second display face.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Playful
description: A warm, hand-crafted editorial system built on a peach-clay canvas with charcoal ink as the only "color." Display type runs in Syne (weight 700–800, tight negative tracking); body type runs in Space Grotesk at weight 400–500. The aesthetic borrows from independent studio decks, risograph zines, and sketchbook spreads: organic blob frames, scribbled SVG doodles, slightly rotated cards, and double-stroke offset borders give every slide a hand-touched, unpolished warmth. The effect is creative-studio editorial, not corporate pitch — confident but human, structured but loose.
colors:
bg: "#F0C8A0"
bg-alt: "#E8B88E"
light: "#F7DEC6"
text: "#1A1A1A"
color-aliases:
accent: text
typography:
display-hero:
fontFamily: "Syne, sans-serif"
fontSize: "clamp(4rem, 10vw, 9rem)"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.03em
display:
fontFamily: "Syne, sans-serif"
fontSize: "clamp(3rem, 8vw, 7rem)"
fontWeight: 800
lineHeight: 0.9
letterSpacing: -0.02em
headline:
fontFamily: "Syne, sans-serif"
fontSize: "clamp(2.5rem, 6vw, 5rem)"
fontWeight: 700
lineHeight: 1.0
letterSpacing: -0.01em
statement:
fontFamily: "Syne, sans-serif"
fontSize: "clamp(2.5rem, 5vw, 4.5rem)"
fontWeight: 700
lineHeight: 1.1
letterSpacing: -0.01em
title:
fontFamily: "Syne, sans-serif"
fontSize: "clamp(2rem, 4vw, 3.5rem)"
fontWeight: 700
lineHeight: 1.1
letterSpacing: -0.01em
title-sm:
fontFamily: "Syne, sans-serif"
fontSize: "1.3rem"
fontWeight: 700
lineHeight: 1.2
number-hero:
fontFamily: "Syne, sans-serif"
fontSize: "clamp(4rem, 8vw, 7rem)"
fontWeight: 800
lineHeight: 1.0
number-md:
fontFamily: "Syne, sans-serif"
fontSize: "2.5rem"
fontWeight: 800
lineHeight: 1.0
number-sm:
fontFamily: "Syne, sans-serif"
fontSize: "2rem"
fontWeight: 800
lineHeight: 1.0
body:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "clamp(1rem, 1.2vw, 1.1rem)"
fontWeight: 400
lineHeight: 1.7
body-md:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "1.2rem"
fontWeight: 500
lineHeight: 1.6
label-eyebrow:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.85rem"
fontWeight: 600
lineHeight: 1.2
letterSpacing: 0.15em
textTransform: uppercase
caption:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.85rem"
fontWeight: 500
lineHeight: 1.4
tag:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.75rem"
fontWeight: 600
lineHeight: 1.2
spacing:
pad-slide-lg: "4rem 5rem"
pad-slide-md: "3rem 4rem"
pad-card-lg: "2rem 3rem"
pad-card-md: "1.5rem"
gap-lg: "3rem"
gap-md: "2rem"
gap-sm: "1.5rem"
canvas:
width: 100vw
height: 100vh
components:
rough-box:
border: "3px solid {colors.text}"
background: "{colors.bg}"
padding: "1.5rem"
offsetShadowOffset: "6px 6px"
offsetShadowBorder: "2–3px solid {colors.text}"
description: "Generic content card with a double-stroke effect — the inner box has a 3px solid border, and an absolutely-positioned ::before pseudo-element offsets a second 2–3px border down-and-right by 6–8px to simulate a hand-drawn double outline. No fill on the offset; the canvas shows through."
filled-block:
background: "{colors.text}"
color: "{colors.bg}"
padding: "1.5rem"
description: "Inverted card: dark charcoal background with peach text. Used as the visual counterpoint to outlined cards in a collage of mixed treatments."
blob-frame-organic:
border: "3px solid {colors.text}"
borderRadius: "40% 60% 70% 30% / 40% 50% 60% 50%"
description: "Organic outlined blob, asymmetric border-radius. Decorative wrapper that holds a smaller solid filled-blob inside it."
blob-frame-pebble:
border: "3px solid {colors.text}"
borderRadius: "255px 15px 225px 15px / 15px 225px 15px 255px"
description: "Pebble-shaped frame with extreme alternating border-radius — two opposing corners pulled long, the other two pinched short. Reads as a hand-drawn lozenge."
blob-fill:
background: "{colors.text}"
borderRadius: "60% 40% 30% 70% / 60% 30% 70% 40%"
description: "Solid dark blob with asymmetric organic radius. Used inside an outlined blob-frame or floating on its own as decorative mass."
scribble-svg:
stroke: "{colors.text}"
strokeWidth: 2
fill: none
strokeLinecap: round
description: "Inline SVG path drawn as a single hand-drawn line — wavy stub, scribbled circle, star outline, squiggle, arrow. Always 2px stroke, rounded caps. Placed absolutely in corners and edges as decorative breath."
doodle-circle:
border: "3px solid {colors.text}"
borderRadius: "50%"
description: "Plain round outlined circle used as a decorative anchor in slide corners."
doodle-rect:
border: "3px solid {colors.text}"
rotation: "5–10deg"
description: "Plain outlined rectangle, slightly rotated, used as a decorative anchor in slide corners."
card-rotated:
transform: "rotate(-3deg to 3deg)"
description: "Any card or block can carry a small ±3deg rotation. Rotations stagger so adjacent cards rotate in opposite directions — never all in the same direction, never more than 3deg."
step-node-circle:
width: 64px
height: 64px
border: "3px solid {colors.text}"
borderRadius: "50%"
background: "{colors.bg}"
fontFamily: "Syne, sans-serif"
fontSize: 1.5rem
fontWeight: 800
description: "Round outlined node containing a single numeric digit at display weight. Used as a timeline or process marker; alternates between outlined (bg fill) and filled (charcoal fill, bg text)."
avatar-placeholder:
width: 60px
height: 60px
background: "{colors.text}"
borderRadius: "50%"
description: "Solid dark circle used as a portrait stand-in inside a team or people card."
tag-pill:
background: "{colors.text}"
color: "{colors.bg}"
padding: "0.4rem 0.8rem"
fontFamily: "Space Grotesk, sans-serif"
fontSize: "0.75rem"
fontWeight: 600
description: "Small charcoal pill with peach text, anchored to the bottom-left of an image frame as a category label."
bar-chart:
barFillSolid: "{colors.text}"
barFillOutlined: "3px solid {colors.text} + transparent"
axisStroke: "3px solid {colors.text}"
description: "Custom HTML bar chart. Bars are either solid charcoal (primary series) or outlined transparent (secondary series). Axes are 3px solid charcoal lines, no grid."
vertical-text:
fontFamily: "Syne, sans-serif"
fontWeight: 700
letterSpacing: 0.1em
transform: "rotate(90deg)"
description: "Display-weight text rotated 90deg, anchored to a slide edge as a magazine-style spine label."
ghost-blob:
background: "{colors.text}"
borderRadius: "40% 60% 70% 30% / 40% 50% 60% 50%"
opacity: 0.08
description: "Oversized organic blob at very low opacity placed behind content as atmospheric wallpaper. Functions like a watermark cloud."
---
## 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
Playful is a **hand-crafted editorial system** anchored by a single warm canvas — a peach-clay `{colors.bg}` (#F0C8A0) — with charcoal `{colors.text}` (#1A1A1A) as the only meaningful "color." Everything reads as ink-on-clay-paper. There are no secondary brand colors, no gradients, no chromatic accents. The system commits fully to a one-color discipline and finds its expressiveness in shape, weight, rotation, and hand-drawn marks rather than in palette variety.
The typeface stack is **Syne for display, Space Grotesk for body**. Syne is the personality — a high-contrast display sans with quirky humanist proportions that reads as a contemporary independent studio voice, not a corporate sans. It is used at weights 700 and 800 with tight negative letter-spacing (-0.01em to -0.03em) for every headline, statement, statistic, and number. Space Grotesk is the workhorse — a steady, neutral geometric sans at weight 400–500 for body and 500–600 for labels. The pairing reads as "expressive editorial built on a reliable grid."
The color philosophy is **monochrome warmth**: a single ink color on a single warm surface, plus two tonal siblings of the canvas (`{colors.bg-alt}` slightly darker for image placeholders, `{colors.light}` slightly lighter for gentle layering). The peach is saturated enough to read as a deliberate aesthetic choice, not a neutral. The ink is slightly softened from pure black (#1A1A1A) to sit comfortably on the warm paper. The system's emotional register is "studio sketchbook" — confident but warm, structured but unpolished.
Depth is **double-stroke offset borders** and **hand-drawn marks**, not blurred shadows. The signature treatment: a 3px charcoal border on a card, plus a `::before` pseudo-element offset down-and-right by 6–8px carrying a second 2–3px border — the visual effect is a hand-drawn double outline that suggests imperfect tracing. Combined with small rotations (±0.5deg to ±3deg on cards) and scribbled SVG paths placed in slide corners, the system reads as crafted-by-hand rather than rendered-by-software.
**Density philosophy: medium-low.** Each slide is anchored by a single dominant element — a statement, a chart, a roster — surrounded by deliberate breathing room and one or two decorative scribbles. Crowding the canvas with simultaneous cards, doodles, and copy collapses the hand-touched feeling into clutter. The correct density is one substantive moment per slide with one or two SVG scribbles or organic blobs serving as visual punctuation in the negative space.
**Key Characteristics:**
- Peach-clay canvas (`{colors.bg}`) with charcoal ink (`{colors.text}`) as the only color. No secondary brand palette.
- Syne at weight 700–800 with negative letter-spacing for every display and numeric moment; Space Grotesk at 400–500 for body.
- Double-stroke offset borders on cards — a 3px outline plus a 6–8px offset ghost border via `::before`.
- Small ±0.5deg to ±3deg rotations on cards, blocks, and statistics for a hand-placed feel.
- Organic blob shapes with asymmetric border-radius act as decorative frames and fills.
- Inline 2px-stroke SVG scribbles (squiggles, stars, circles, arrows) live in slide corners as hand-drawn punctuation.
- No web shadows. Depth comes from double borders, rotation, and ink-density contrast.
- One dominant element per slide with generous negative space — never wall-to-wall content.
## Colors
### Palette
- **Background** (`{colors.bg}` — #F0C8A0): The peach-clay canvas. The default surface for every slide. Saturated enough to be the system's signature; warm enough that charcoal ink reads softly rather than starkly.
- **Background Alt** (`{colors.bg-alt}` — #E8B88E): A slightly darker tonal sibling of the canvas. Used as a fill for image placeholder regions and for subtle surface differentiation when one card needs to read as "behind" another without committing to a new color.
- **Light** (`{colors.light}` — #F7DEC6): A slightly lighter tonal sibling of the canvas. Available for gentle layering when a region needs to lift off the background by a single tonal step without introducing white.
- **Text/Ink** (`{colors.text}` — #1A1A1A): Charcoal ink — the single non-canvas color in the system. Softened from pure black so it sits as warm ink on warm paper. Used for all body text, all display text, all borders, all SVG strokes, all filled blocks, all dark fills.
The `accent` alias resolves to `{colors.text}` — the system has no separate accent color. The "accent" in Playful is contrast against the canvas, not a third hue.
### Defaults
- **Default surface background**: `{colors.bg}` — every slide opens on peach-clay.
- **Default headline color**: `{colors.text}` — always. Headlines are never tinted or recolored.
- **Default body text color**: `{colors.text}` — sometimes at opacity 0.7–0.9 for de-emphasis, but the underlying color remains charcoal.
- **Default border color**: `{colors.text}` — every outlined card, blob, doodle, and chart axis is charcoal.
- **Default text color on filled charcoal blocks**: `{colors.bg}` — peach text on dark surfaces is the only color inversion.
- **Default image-placeholder fill**: `{colors.bg-alt}` — slightly darker than the canvas so the placeholder reads as a distinct region without using white.
- **Default decorative-blob fill**: `{colors.text}` at full opacity (foreground) or at 0.08 opacity (atmospheric ghost-blob behind content).
The system has no concept of "primary vs secondary color." Every visual decision is a binary between canvas (peach) and ink (charcoal), modulated by opacity, scale, and shape.
## Typography
### Font Family
The system pairs two carefully chosen Google Fonts:
- **Syne** (display): A contemporary humanist display sans with quirky letterforms, narrow apertures, and slightly compressed proportions. Used at weight 700 and 800 for every display moment — headlines, statements, titles, numerals, vertical labels. Its character is what distinguishes Playful from a generic warm-toned deck: Syne reads as an independent studio voice, not a corporate header.
- **Space Grotesk** (body): A clean, slightly geometric sans-serif with a friendly humanist warmth. Used at weight 400–500 for body paragraphs, 500–600 for labels and captions. Provides a steady, legible counterweight to Syne's expressiveness.
There is no third face. Italic and underline are not used. Emphasis comes from weight (700 → 800), size, and the Syne-vs-Space-Grotesk contrast itself.
### Type Scale
| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-hero}` | 4–9rem | Syne | 800 | Oversized cover or opening date/title |
| `{typography.display}` | 3–7rem | Syne | 800 | Closing or major declarative headline |
| `{typography.headline}` | 2.5–5rem | Syne | 700 | Primary section headline |
| `{typography.statement}` | 2.5–4.5rem | Syne | 700 | Long-form quoted statement or manifesto line |
| `{typography.title}` | 2–3.5rem | Syne | 700 | Region or section title |
| `{typography.number-hero}` | 4–7rem | Syne | 800 | Hero statistic numeral |
| `{typography.number-md}` | 2.5rem | Syne | 800 | Mid-scale ordinal or stat numeral |
| `{typography.number-sm}` | 2rem | Syne | 800 | Inline ordinal or step numeral |
| `{typography.title-sm}` | 1.3rem | Syne | 700 | Card title within a small block |
| `{typography.body-md}` | 1.2rem | Space Grotesk | 500 | Subtitle or emphasized body |
| `{typography.body}` | 1–1.1rem | Space Grotesk | 400 | Paragraph body |
| `{typography.label-eyebrow}` | 0.85rem | Space Grotesk | 600 | Section eyebrow above a headline, uppercase tracked |
| `{typography.caption}` | 0.85rem | Space Grotesk | 500 | Subtitle, fine print, footnote |
| `{typography.tag}` | 0.75rem | Space Grotesk | 600 | Pill tag text inside a charcoal label |
### Defaults
- **Default size for a primary section headline**: `{typography.headline}` (2.5–5rem clamp).
- **Default size for a cover or major opening moment**: `{typography.display-hero}` (4–9rem clamp).
- **Default size for paragraph body**: `{typography.body}` (1–1.1rem clamp).
- **Default size for a subtitle or emphasized lead body**: `{typography.body-md}` (1.2rem).
- **Default size for any inline caption, footnote, or fine print**: `{typography.caption}` (0.85rem).
- **Default size for a hero numerical figure**: `{typography.number-hero}` (4–7rem clamp).
- **Default size for a stat tile or ordinal numeral**: `{typography.number-md}` (2.5rem).
- **Default weight for any display element (headline, statement, title, numeral)**: 700 or 800 — never lower.
- **Default weight for any body element**: 400 or 500.
When unsure between `{typography.title}` and `{typography.headline}` for the primary text on a slide, reach for `{typography.headline}` — `{typography.title}` is for sub-regions within a slide.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every display element is set in Syne.** Headlines, statements, titles, numerals, vertical labels, decorative single-character marks — all Syne. Using Space Grotesk at large sizes is the wrong system signal.
- **Every Syne element uses negative letter-spacing**: -0.01em to -0.03em depending on size. Syne at default tracking reads as untreated; the negative tracking is what gives display type its tight, compressed personality.
- **Every body and label element is set in Space Grotesk.** Syne for body paragraphs reads as overwrought.
- **Eyebrow labels are uppercase with 0.15em letter-spacing.** A label without uppercase + tracked spacing reads as a body fragment, not a label.
- **Statistics and numerals are always weight 800.** Even mid-scale numerals (2rem) follow the display-weight convention. A weight-500 numeral reads as inventory, not a brag.
- **Numerals and statistics may carry a small rotation (±0.5deg to ±1deg)** when they sit as standalone stat-items rather than inside a chart or table. The rotation reinforces the hand-placed feeling.
### Typography Principles
The system's typographic rhythm comes from the **Syne-vs-Space-Grotesk contrast**, not from mixing weights within a face. A slide that uses only Syne at varying weights reads as monotonous; a slide that uses only Space Grotesk reads as understated to the point of corporate. The correct rhythm is Syne headline + Space Grotesk body, repeated with discipline.
Line-height: tight on display (0.85–1.1), generous on body (1.5–1.7). Never use tight line-height on body or generous line-height on display — both inversions break the rhythm.
Italic does not exist in this system. Underline does not exist. Emphasis is achieved by switching face (body → display) or weight (400 → 700), never by italicizing.
## Layout
### Canvas System
The system targets `100vw × 100vh` — full viewport. Every `.slide` is absolutely positioned to fill the viewport, and only the `.active` slide is visible (opacity 1, others at opacity 0). Slide navigation is JS-driven via arrow keys, space, click on next/prev buttons, and touch swipe. A 4px-tall charcoal progress bar runs along the bottom of the viewport, growing to indicate slide position. All sizes use `clamp()` so the layout fluidly scales without breakpoints down to a mobile reflow at 768px.
### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-slide-lg}` | 4rem 5rem | Cover, statement, and closing slides — generous outer padding |
| `{spacing.pad-slide-md}` | 3rem 4rem | Standard content slides — outer padding |
| `{spacing.pad-card-lg}` | 2rem 3rem | Large card or contact block interior padding |
| `{spacing.pad-card-md}` | 1.5rem | Standard card interior padding |
| `{spacing.gap-lg}` | 3rem | Large grid/flex gaps between major regions |
| `{spacing.gap-md}` | 2rem | Standard grid/flex gaps between cells |
| `{spacing.gap-sm}` | 1.5rem | Tight inline gaps |
### Chrome
A fixed 48px×48px navigation cluster sits at bottom-right (prev arrow, slide counter, next arrow — all outlined in 2px charcoal). A 4px-tall charcoal progress bar runs flush along the bottom edge of the viewport. Neither is part of the slide composition; they exist as the deck's persistent presenter chrome and should not be styled against.
The progress bar and nav buttons are the only persistent UI elements. Slides themselves carry no top bar, no footer chrome, no slide numbers within the canvas.
## Depth and Elevation
### Double-Stroke Offset Border (Primary Technique)
The signature depth treatment is a **double-stroke offset border**. A card carries a 3px solid charcoal border, and a `::before` pseudo-element absolutely positioned over the card carries a second 2–3px border offset 6–8px down-and-right. The offset border has no fill — the canvas shows through. The visual effect is a hand-drawn double outline that suggests imperfect tracing, like a pen pulled twice along an edge. This is the system's elevation device; it replaces what most systems would do with a `box-shadow`.
### Rotation (Secondary Technique)
Small rotations (±0.5deg to ±3deg) on cards, blocks, statistics, and decorative shapes provide a hand-placed feeling. Rotation directions alternate across adjacent elements — never two cards rotated the same direction next to each other — to suggest someone laid each piece down by hand rather than via a snapped grid.
### Atmospheric Ghost-Blob
A signature treatment: an oversized organic blob (`{components.ghost-blob}`) filled with charcoal at 0.08 opacity, placed absolutely in a slide corner as atmospheric wallpaper. The blob reads as a soft watermark cloud behind the content. Use sparingly — at most one ghost-blob per slide, anchored to a corner the primary content does not occupy.
### No Web Shadows
The system uses **no `box-shadow` blur values, no `drop-shadow`, no rgba shadows**. All apparent depth comes from the double-stroke offset border, rotation, and ink-density contrast. A blurred shadow on any element breaks the hand-crafted aesthetic — the marks should look drawn, not rendered.
## Shapes and Treatment
### Border Radius Scale
| Value | Use |
|---|---|
| 0px | Cards, blocks, tags, image frames, table cells |
| 50% | Round avatar placeholders, step-node circles, doodle circles |
| Asymmetric organic (e.g. `40% 60% 70% 30% / 40% 50% 60% 50%`) | Blob frames and blob fills only |
| Pebble-asymmetric (e.g. `255px 15px 225px 15px / 15px 225px 15px 255px`) | Pebble-shaped frames only |
The system avoids smooth medium radii (4px, 8px, 12px) — corners are either sharp, perfectly round, or organically blob-shaped. The middle ground reads as a generic web app, which is the wrong signal.
### Border Weights
- **3px solid `{colors.text}`** — the standard outlined-card and blob-frame border weight.
- **2–3px solid `{colors.text}`** — the offset ghost-border weight on the `::before` pseudo-element (slightly thinner than the primary).
- **3px solid `{colors.text}`** — the chart axis weight (X and Y axes on bar charts).
- **2px solid `{colors.text}`** — the nav-button border weight and the timeline-track horizontal line.
- **2px stroke** — the standard SVG scribble stroke weight with rounded line-caps.
### Decorative Element Types
**Rough-box card** — A rectangular content card with the signature double-stroke offset border. Background can be canvas peach (default), or solid charcoal (inverted card). Padding from the `{spacing.pad-card-*}` scale. Optional small rotation (±0.5–3deg).
**Organic blob frame** — A decorative outlined wrapper with asymmetric border-radius. Used as a portrait frame or decorative anchor; often holds a smaller solid blob-fill inside. Two characteristic shapes: the wavy organic blob (`{components.blob-frame-organic}`) and the pebble shape (`{components.blob-frame-pebble}`).
**Solid blob fill** — A charcoal organic shape with asymmetric border-radius. Used either inside an outlined blob-frame (creating a frame-and-mass pairing) or floating alone as a decorative mass.
**Scribble SVG** — Inline SVG path drawn as a single 2px-stroke charcoal line with round caps. The vocabulary: wavy stub, star outline, scribbled circle, squiggle waveform, arrow, concentric circles. Placed absolutely in slide corners or edges as decorative breath. Every slide gets at least one scribble; the most populated slides carry two or three.
**Doodle circle / doodle rect** — Plain outlined circle or rectangle, slightly rotated, placed absolutely in slide corners as a minimal decorative anchor. The simpler counterpart to the blob shapes — when a slide needs visual punctuation but a blob would feel too organic.
**Step-node circle** — A 64px round outlined node containing a single digit in Syne 800. Alternates between outlined (canvas fill, charcoal digit) and filled (charcoal fill, canvas digit) in sequence — odd steps filled, even steps outlined, or any consistent pattern.
**Tag pill** — A small charcoal rectangle with peach text at 0.75rem weight 600. Anchored to the bottom-left of an image frame as a category label. The only inverted text-on-charcoal element that is not a full card.
**Vertical spine label** — Syne 700 text at 1.5rem rotated 90deg, anchored to a slide's right edge with 0.1em letter-spacing. Reads as a magazine-spine wayfinder.
**Ghost-blob wallpaper** — Oversized organic blob at 0.08 opacity, placed absolutely in a slide corner as atmospheric wallpaper.
**Connector arrow doodle** — A small SVG sketched arrow (single 2px line with chevron head) used to suggest "next" or "see also" in the negative space of a slide.
## Do's and Don'ts
### Do
- Use Syne for every display moment (headline, statement, title, number, vertical label) and Space Grotesk for every body and label. The two-face contrast is the system's typographic rhythm.
- Apply negative letter-spacing (-0.01em to -0.03em) to every Syne element. Default tracking on Syne reads as untreated.
- Apply the double-stroke offset border to every primary content card — 3px main outline plus a 6–8px offset ghost border via `::before`. This is the system's signature elevation device.
- Place a scribbled SVG mark (squiggle, star, circle, arrow) in at least one corner of every slide as hand-drawn breath. The marks are punctuation, not content.
- Give cards, blocks, and statistics a small ±0.5–3deg rotation. Alternate rotation direction across adjacent elements so nothing reads as snapped to a grid.
- Use `{colors.text}` (charcoal) as the only ink color. Headlines, body, borders, scribbles, fills — all the same color.
- Reach for `{colors.bg-alt}` when a region needs to read as a distinct surface without introducing white or a new color.
- Let negative space breathe. One dominant element per slide plus one or two scribbles is the correct density.
- Pair an outlined blob frame with a smaller solid blob fill inside it when you need a portrait-like decorative anchor.
- Place an oversized ghost-blob (charcoal at 0.08 opacity) in a slide corner when the negative space feels empty but a scribble would be too small.
### Don't
- Don't introduce a third color. The system is peach-canvas + charcoal-ink only. No blues, no reds, no chart-segment palettes — chart bars are solid charcoal or outlined charcoal, never colored.
- Don't use blurred `box-shadow`. All depth comes from double borders and rotation. A blurred shadow breaks the hand-drawn aesthetic immediately.
- Don't apply medium border-radius values (4px, 8px, 12px). Corners are sharp, fully round, or organically blob-shaped — nothing between.
- Don't use Space Grotesk for headlines or display moments. Syne is the personality face; substituting Space Grotesk loses the studio voice.
- Don't use Syne for body paragraphs. It reads as overwrought at small sizes and at low weights.
- Don't rotate elements more than 3deg. Beyond ±3deg the hand-placed feeling tips into wonky and amateur.
- Don't rotate every element in the same direction. Alternate ±directions across adjacent elements; uniformity reads as a tilted canvas, not as hand-placement.
- Don't crowd a slide with simultaneous cards, statistics, and doodles. The system reads as expensive when sparse and broken when dense.
- Don't use italic or underline for emphasis. Switch face or weight instead.
- Don't put display-weight text at default tracking. Always tighten Syne with negative letter-spacing.
## Responsive Behavior
The system targets `100vw × 100vh` and uses `clamp()` throughout, so type and padding scale fluidly between viewport sizes without media queries. A single media query at `max-width: 768px` reflows multi-column grids to single-column, collapses the horizontal timeline track to vertical, and reduces slide padding to 2rem.
### Presenter Behavior
- Slides advance via `ArrowRight`, `Space`, or `Enter`.
- Slides reverse via `ArrowLeft`.
- The active slide carries the `.active` class; inactive slides are visibility-hidden at opacity 0.
- Slide transitions use a 0.6s opacity fade.
- A 4px-tall charcoal progress bar runs along the bottom of the viewport, growing as the deck advances.
- A bottom-right nav cluster shows prev/next buttons (48px outlined squares) and the current/total slide counter.
- Touch swipe horizontal on mobile advances/reverses.
### Print Behavior
No `@media print` rule is defined. The deck is web/viewport-first; printing will not render correctly without custom print styles.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face | Chinese face | Weight |
|---|---|---|---|
| Display / headline / numeral (Syne 700–800) | Syne | 站酷快乐体 ZCOOL KuaiLe | 400 (only weight available) |
| Body / label (Space Grotesk 400–600) | Space Grotesk | 悠哉字体 Yozai | 400 |
### Mixed-Content Strategy
Strategy A — extend each token's `fontFamily` to include the Chinese face after the Latin face. Syne tokens become `"Syne, ZCOOL KuaiLe, sans-serif"`; Space Grotesk tokens become `"Space Grotesk, Yozai, sans-serif"`. Latin glyphs render in the original face; CJK characters fall through automatically.
### 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=Syne:wght@700;800&family=Space+Grotesk:wght@400;500;600;700&family=ZCOOL+KuaiLe&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-yozai-regular/font.css" rel="stylesheet">
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation (,。:;!?「」())
- No period on display headlines (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence
### Aesthetic Notes for This System
Playful is a hand-crafted editorial system built on Syne (quirky humanist display) plus Space Grotesk (warm geometric body) on a peach-clay canvas. The Chinese transfer is exceptionally strong because both Chinese faces selected here carry the same "warm, hand-touched, independent studio" register as the Latin pairing.
**站酷快乐体 ZCOOL KuaiLe** is a rounded, friendly Chinese display face with quirky humanist proportions — the closest CDN-available equivalent to Syne's expressive studio voice. At display weights (4–9rem), KuaiLe reads as a contemporary independent Chinese studio voice, not a corporate or formal one. It pairs naturally with the peach canvas and charcoal ink. **Drop the negative letter-spacing (-0.01em to -0.03em) for Chinese display** — KuaiLe is designed on a square em-box and tightening causes glyph collision. The face's intrinsic warmth replaces what negative tracking does for Syne.
**悠哉字体 Yozai** is a Chinese sans-serif designed for relaxed body reading — slightly rounded terminals, friendly humanist proportions, designed to match the warmth that Space Grotesk brings to Latin. Set every Chinese body paragraph and label in Yozai 400. The eyebrow label treatment (0.15em letter-spacing + uppercase in Latin) does not transfer to CJK; for Chinese eyebrows, use Yozai at the same 0.85rem size with letter-spacing 0 and no uppercase — small size alone reads as label.
The double-stroke offset border, the small ±3deg rotations, the organic blob shapes, the SVG scribbles, the ghost-blob wallpaper — all script-agnostic. The single-color discipline (peach + charcoal) and the hand-crafted aesthetic survive the script switch fully.
The system's typographic rhythm (Syne-vs-Space-Grotesk contrast) becomes (KuaiLe-vs-Yozai contrast) in pure Chinese — both pairs carry the same "expressive editorial built on a reliable grid" rhythm. Statistics and numerals are pure digits and transfer unchanged in Syne 800; only when a stat carries a Chinese unit suffix (`亿`, `万`) does the suffix glyph fall through to KuaiLe.
### Known CJK Gap
ZCOOL KuaiLe and Yozai are both single-weight faces (400). The system's reliance on weight contrast (Syne 700 vs 800 for sub-display hierarchy; Space Grotesk 400 vs 500 vs 600 for label hierarchy) collapses to size-only hierarchy in pure Chinese. This is not a meaningful loss — Playful's hierarchy is primarily size-driven anyway, and the missing weight steps don't change the visual rhythm enough to matter. The rotation, scribble, and double-border treatments carry the system's character regardless of weight availability.
## Iteration Guide
1. Any new card uses the rough-box pattern: 3px charcoal border, peach background (or charcoal if inverted), padding from `{spacing.pad-card-*}`, and a `::before` ghost-border offset 6–8px down-and-right at 2–3px weight.
2. Any new card carries a small rotation (±0.5–3deg). Alternate rotation direction with neighboring cards; never align all cards to the same angle.
3. Any new headline uses Syne at weight 700–800 with negative letter-spacing. If the headline is the primary slide moment, reach for `{typography.headline}` or `{typography.display}` — not `{typography.title}` (which is sub-region scale).
4. Any new body or label uses Space Grotesk at weight 400–600. Use `{typography.label-eyebrow}` (0.85rem, weight 600, uppercase, 0.15em tracking) for the small label above a headline.
5. Any new statistic or numeral uses Syne at weight 800 with negative letter-spacing. Even small numerals (2rem) follow the display-weight convention.
6. Any new slide gets at least one scribbled SVG mark in a corner — squiggle, star, circle, arrow. Stroke 2px with rounded line-caps in `{colors.text}`.
7. Any decorative shape uses asymmetric organic border-radius (blob) or sharp 0px (rectangle) or 50% (round). Avoid medium radii.
8. If the slide negative space feels heavy, add a ghost-blob (charcoal at 0.08 opacity, oversized organic shape) anchored to a corner the content does not occupy.
9. Charts (bar, donut, line) use only `{colors.text}` and `{colors.bg-alt}` as fills. Do not introduce chromatic chart palettes.
10. Cards may be either outlined (default — canvas fill, charcoal border, charcoal text) or inverted (charcoal fill, peach text). Inverted cards are the system's emphasis device; reserve them for the cell you want to anchor the slide's attention.
## Known Gaps
- The system loads two Google Fonts (Syne, Space Grotesk) over the network. If fonts fail to load, the fallback sans-serif will render but the system's voice will be lost. Self-hosting is recommended for production.
- The double-stroke offset border (`::before` with 6–8px offset) requires the parent card to have `position: relative` and the pseudo-element to be visually inside the card's bounding box plus the offset. Cards near a slide edge may have their offset border clipped.
- The mobile responsive breakpoint at 768px reflows grids but does not adjust the absolutely-positioned decorative SVGs and blobs — they remain at desktop coordinates and may overlap or fall off-screen on small viewports. Treat the responsive behavior as basic, not polished.
- The peach canvas (#F0C8A0) has a strong cultural register (earthy, warm, slightly rustic). It does not pair well with cool-toned brand palettes and is not interchangeable with a neutral cream or white — the warmth is foundational.
- Image placeholders (`{colors.bg-alt}` fills with a centered "IMG 01" label) are stubs only. Production decks need real images that respect the warm palette; cool-toned photos will fight the canvas.
- There is no defined dark-mode variant. The system is single-mode (warm peach canvas only).
- The hover states on nav buttons (background fills to charcoal, text inverts to peach) are interactive presenter-chrome behaviors and are not part of the deck's slide composition.
# Playful Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/playful/design.md`
- Preview card: `bold-template-pack/templates/playful/preview.md`
## Selection Metadata
- Slug: `playful`
- Tagline: Sun-warm peach background with Syne display: a friendly indie launch deck.
- Mood: warm, approachable, indie, friendly
- Tone: upbeat, informal, welcoming
- Formality: low
- Density: medium
- Scheme: light
- Best for: Anything that should feel warm, indie, and approachable: creator portfolios, indie product launches, lifestyle brands, small-business pitches, newsletter / community decks. Also welcoming for any deck — including tech or research — that wants to feel friendly and human rather than corporate.
- Avoid for: Contexts where institutional credibility matters more than warmth — the peach palette is intentionally informal.
## Visual Snapshot
A warm, hand-crafted editorial system built on a peach-clay canvas with charcoal ink as the only "color." Display type runs in Syne (weight 700–800, tight negative tracking); body type runs in Space Grotesk at weight 400–500. The aesthetic borrows from independent studio decks, risograph zines, and sketchbook spreads: organic blob frames, scribbled SVG doodles, slightly rotated cards, and double-stroke offset borders give every slide a hand-touched, unpolished warmth. The effect is creative-studio editorial, not corporate pitch — confident but human, structured but loose.
Playful is a hand-crafted editorial system anchored by a single warm canvas — a peach-clay {colors.bg} (#F0C8A0) — with charcoal {colors.text} (#1A1A1A) as the only meaningful "color." Everything reads as ink-on-clay-paper. There are no secondary brand colors, no gradients, no chromatic accents. The system commits fully to a one-color discipline and finds its expressiveness in shape, weight, rotation, and hand-drawn marks rather than in palette variety.
## Preview Ingredients
- Palette: bg #F0C8A0; bg-alt #E8B88E; light #F7DEC6; text #1A1A1A
- Typography: Syne; Space Grotesk
- Signature move: Peach-clay canvas ({colors.bg}) with charcoal ink ({colors.text}) as the only color. No secondary brand palette.
- Signature move: Syne at weight 700–800 with negative letter-spacing for every display and numeric moment; Space Grotesk at 400–500 for body.
- Signature move: Double-stroke offset borders on cards — a 3px outline plus a 6–8px offset ghost border via ::before.
- Signature move: Small ±0.5deg to ±3deg rotations on cards, blocks, and statistics for a hand-placed feel.
- Signature move: Organic blob shapes with asymmetric border-radius act as decorative frames and fills.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Raw Grid
description: A neobrutalist presentation system where 3px solid black borders ARE the layout. Display type runs in the native system sans-serif stack (Segoe UI / system-ui) at weight 900 in strict uppercase — no web fonts loaded. The palette is white canvas + black structure + two muted pastel accents (blush pink #F2D4CF and sage green #E5EDD6) + a neutral gray. Depth comes from hard offset shadows in solid black at 4px and 6px — never blurred, never colored. The aesthetic borrows from brutalist editorial web design and zine layout: borders meet without gaps, contrast is high but warmed by the pastel accents, and large numerals sit at very low opacity behind content as decorative wallpaper. The effect is sharp, system-native, and unmistakably digital — closer to a Notion-meets-protest-poster than a polished pitch deck.
colors:
black: "#0A0A0A"
white: "#FFFFFF"
pink: "#F2D4CF"
green: "#E5EDD6"
gray: "#F5F5F5"
darkgray: "#333333"
borders:
primary: "3px solid {colors.black}"
shadows:
default: "6px 6px 0 {colors.black}"
small: "4px 4px 0 {colors.black}"
typography:
display:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(48px, 7vw, 96px)"
fontWeight: 900
lineHeight: 1.05
letterSpacing: -0.02em
textTransform: uppercase
headline:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(32px, 4.5vw, 64px)"
fontWeight: 900
lineHeight: 1.1
letterSpacing: -0.01em
textTransform: uppercase
title:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(24px, 2.5vw, 36px)"
fontWeight: 800
lineHeight: 1.2
letterSpacing: 0.01em
textTransform: uppercase
subtitle:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(16px, 1.4vw, 22px)"
fontWeight: 700
lineHeight: 1.3
letterSpacing: 0.04em
textTransform: uppercase
body:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(16px, 1.3vw, 20px)"
fontWeight: 500
lineHeight: 1.6
letterSpacing: 0
caption:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(11px, 1vw, 13px)"
fontWeight: 700
lineHeight: 1.2
letterSpacing: 0.08em
textTransform: uppercase
number:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(64px, 8vw, 120px)"
fontWeight: 900
lineHeight: 1.0
letterSpacing: -0.04em
number-md:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(36px, 4vw, 56px)"
fontWeight: 900
lineHeight: 1.0
letterSpacing: -0.02em
number-lg:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: "clamp(48px, 6vw, 80px)"
fontWeight: 900
lineHeight: 1.0
letterSpacing: -0.02em
label-text:
fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
fontSize: 11px
fontWeight: 800
lineHeight: 1.0
letterSpacing: 0.08em
textTransform: uppercase
spacing:
pad-lg: "clamp(32px, 4vw, 64px)"
pad-md: "clamp(20px, 2.5vw, 40px)"
pad-sm: "clamp(12px, 1.5vw, 20px)"
gap-lg: "clamp(24px, 3vw, 48px)"
gap-md: "clamp(16px, 2vw, 32px)"
gap-sm: "clamp(8px, 1vw, 16px)"
canvas:
width: 100vw
height: 100vh
components:
label:
background: "{colors.black}"
color: "{colors.white}"
padding: "6px 14px"
fontSize: 11px
fontWeight: 800
letterSpacing: 0.08em
textTransform: uppercase
line-h:
width: 60px
height: 4px
background: "{colors.black}"
line-v:
width: 4px
height: 60px
background: "{colors.black}"
line-full:
width: "100%"
height: 4px
background: "{colors.black}"
arrow-prefix:
content: "→\\00a0"
description: "Inline right-arrow glyph (U+2192) followed by a non-breaking space. Prepended via ::before on CTAs and interactive list items."
icon-box:
width: 48px
height: 48px
border: "3px solid {colors.black}"
background: "{colors.white}"
fontSize: "18px–20px"
fontWeight: 900
description: "Square white box with 3px black border, used for logos and feature icons. Contains 1–3 character glyph or Roman numeral."
bar-track:
width: "100%"
height: 32px
border: "3px solid {colors.black}"
background: "{colors.white}"
bar-fill-pink:
background: "{colors.pink}"
bar-fill-green:
background: "{colors.green}"
bar-fill-black:
background: "{colors.black}"
color: "{colors.white}"
stat-box:
border: "3px solid {colors.black}"
padding: "clamp(16px, 2vw, 28px)"
background: "{colors.white}"
card:
padding: "clamp(24px, 3vw, 48px)"
border: "3px solid {colors.black}"
description: "Generic content card. Background may be white, pink, green, or gray."
decorative-numeral:
fontWeight: 900
fontSize: "clamp(40px, 5vw, 72px)"
lineHeight: 1.0
opacity: 0.2–0.35
description: "Oversized numeral placed inside a card at very low opacity as decorative wallpaper behind the actual content."
decorative-quote-mark:
fontSize: "clamp(80px, 12vw, 160px)"
fontWeight: 900
opacity: 0.15
description: "Oversized opening quotation mark placed absolutely at the top-left of a quote region at very low opacity."
connector-node:
width: 32px
height: 32px
border: "3px solid {colors.black}"
background: "{colors.black}"
color: "{colors.white}"
fontSize: 16px
fontWeight: 900
description: "Small black square with white arrow glyph, used as a connector between sequential items in a horizontal flow."
legend-swatch:
width: 16px
height: 16px
border: "3px solid {colors.black}"
donut-stroke-width: 24
donut-track-stroke-width: 1.5
table-cell:
border: "3px solid {colors.black}"
padding: "clamp(12px, 1.5vw, 20px)"
fontWeight: 600
table-header:
background: "{colors.black}"
color: "{colors.white}"
fontWeight: 800
letterSpacing: 0.06em
textTransform: uppercase
table-zebra-row:
background: "{colors.gray}"
hover-highlight:
background: "{colors.green}"
transition: "background 0.15s"
---
## Frontend Slides Fixed-Stage Policy
When this design system is used by the `frontend-slides` skill, generate the final deck as a **fixed 1920×1080 stage** that scales uniformly to the browser viewport. The deck should preserve a 16:9 slide canvas on every screen, including phones; it may letterbox or pillarbox, but it should not reflow slide content for mobile.
This policy has higher priority than any source-template responsive behavior described later in this file. If a later section says the original template is viewport-fluid, treat that as source history only, not as the target generation model for `frontend-slides`.
This policy applies even if the source template was originally implemented with viewport-fluid CSS such as `100vw`, `100vh`, `vw`, `vh`, or `clamp()`. Treat those values as design proportions to translate into 1920×1080 stage coordinates, not as live responsive rules in the generated deck.
Use `deck-stage.js` or an equivalent inline stage scaler for final output: render each slide at 1920×1080, scale the whole stage with one transform, and verify rendered screenshots for both text overflow and panel overlap.
## Overview
Raw Grid is a **neobrutalist presentation system** built on a single structural premise: **3px solid black borders are the layout**. There are no margins between regions, no gaps between cells, no rounded corners, no gradients. When two regions meet, a 3px black line separates them — that line is the entire grid system.
The typeface choice is deliberately non-decorative. The system uses the **native system sans-serif stack** (`Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif`) — no Google Fonts, no web fonts, no licensing. Display text runs at weight 900 in strict uppercase with tight negative letter-spacing. Body text runs at weight 500 in sentence case. The visual contrast between heavy uppercase display and light sentence-case body is the typographic rhythm of the system. The choice of system fonts is itself an aesthetic statement: it reads as "this is software, not a print artifact" — the digital-native counterpart to the printed-zine aesthetic of most brutalist systems.
The palette has six tokens but functions in four roles. **White** (`{colors.white}`) is the canvas. **Black** (`{colors.black}`) is the structure: borders, headlines, body text, label fills, shadow color. **Pink** (`{colors.pink}` — a muted blush #F2D4CF) and **green** (`{colors.green}` — a sage celadon #E5EDD6) are the accent surfaces — warm and cool counterparts, never used on text, always used as region fills. **Gray** (`{colors.gray}` — #F5F5F5) is the neutral fill for table zebra-striping and tertiary surfaces. The pastels are pale enough that black text remains fully legible on them, which is essential: the system never inverts text color over accent surfaces.
Depth is entirely **hard offset shadow** at 6px and 4px offsets in solid black with zero blur. No `rgba(...)`, no `0 4px 12px`. Either the shadow is hard-edged solid black or there is no shadow at all.
**Density philosophy: medium.** The system uses borders to wall off regions cleanly, but each region holds restrained content — typically one display element paired with one body paragraph, or one stat paired with one caption. The borders are loud (3px solid black, no compromise); the content within each region is quiet. A slide that feels broken in this system is one where a region is *empty* or *over-stuffed*; the correct density is one substantive element per bordered region.
**Key Characteristics:**
- White (`{colors.white}`) canvas with 3px solid black (`{colors.black}`) borders dividing every region. No gaps between cells — borders meet edge-to-edge.
- System sans-serif at weight 900 uppercase for all display type; weight 500 sentence case for all body type.
- Hard offset shadows at 6px and 4px in solid black, no blur, ever.
- Two muted pastel accent surfaces — blush pink and sage green — used as region fills, never as text colors.
- A signature black-pill `label` component (`{components.label}`) — white uppercase text in a small black rectangle — appears as the universal section tag.
- Oversized decorative numerals at 0.15–0.35 opacity sit behind content as wallpaper.
- An arrow glyph (→ with non-breaking space) prepended via `::before` on CTAs and interactive list items.
- No rounded corners anywhere in the system. Every shape is a strict rectangle, square, or circle.
- The system loads zero external fonts; rendering is identical in any browser with default fonts available.
## Colors
### Palette
- **Black** (`{colors.black}` — #0A0A0A): The structural color. All borders, all headline text, all body text, all label fills, all shadow values. Slightly softer than pure #000000 but reads as black at any reasonable size.
- **White** (`{colors.white}` — #FFFFFF): The canvas. Used as the default slide background, the default card background, and the text color inside black surfaces (labels, table headers, the dark stat tile).
- **Pink** (`{colors.pink}` — #F2D4CF): Muted blush. The warm accent surface — region backgrounds, bar fills, stat tile fills. The pastel saturation keeps black text fully legible without inversion.
- **Green** (`{colors.green}` — #E5EDD6): Sage celadon. The cool accent surface — region backgrounds, bar fills, hover-state highlight, alternating cards. Always paired with pink as the two halves of the accent system; rarely appear without each other in the same composition.
- **Gray** (`{colors.gray}` — #F5F5F5): Off-white neutral. Used for table zebra-stripe rows and tertiary card backgrounds where a region needs separation from white without committing to a colored accent.
- **Dark Gray** (`{colors.darkgray}` — #333333): A reserved tertiary text color, present in the token system but used sparingly. Available for de-emphasized text that needs to read softer than pure black.
### Defaults
- **Default surface background**: `{colors.white}`.
- **Default headline color**: `{colors.black}` — always. Headlines never appear in pink, green, or gray; only in black (on light surfaces) or white (on the black surface).
- **Default body text color**: `{colors.black}`.
- **Default border color**: `{colors.black}` — always.
- **Default accent surface for warm regions**: `{colors.pink}`.
- **Default accent surface for cool regions**: `{colors.green}`.
- **Default neutral fill for tertiary regions**: `{colors.gray}`.
- **Default text color on `{colors.black}` surfaces**: `{colors.white}` — the only color inversion in the system.
The accent surfaces (pink, green) are interchangeable — neither has a fixed semantic role (e.g., pink is not "warning" and green is not "success"). Use whichever color contrast best serves the composition. When two accent regions appear adjacent, pair pink with green for warm/cool balance rather than doubling on one color.
## Typography
### Font Family
The entire system runs on the **native system sans-serif stack**: `Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif`. No web fonts are loaded. This is intentional — the digital-native aesthetic depends on the type rendering in the user's actual system font, not a downloaded display face. The result is consistent only in spirit, not in exact letterform: a macOS render will look slightly different from a Windows render, and that variability is acceptable inside the system's tolerance.
The weight axis is the entire expressive tool. Display text uses weight 900 (the heaviest), titles use 800, subtitles use 700, body uses 500, with no italic variants and no alternate faces. The contrast between weight 900 uppercase and weight 500 sentence case is the system's primary typographic rhythm.
### Display and Numerical Scale
| Token | Size (clamp) | Weight | Tracking | Use |
|---|---|---|---|---|
| `{typography.number}` | 64–120px | 900 | -0.04em | Hero numerical stat |
| `{typography.display}` | 48–96px | 900 | -0.02em | Section-opening or cover display |
| `{typography.number-lg}` | 48–80px | 900 | -0.02em | Large decorative or featured numeral |
| `{typography.headline}` | 32–64px | 900 | -0.01em | Primary section headline |
| `{typography.number-md}` | 36–56px | 900 | -0.02em | Stat tile or metric numeral |
| `{typography.title}` | 24–36px | 800 | 0.01em | Region or section title |
| `{typography.subtitle}` | 16–22px | 700 | 0.04em | Subtitle, intra-region heading |
| `{typography.body}` | 16–20px | 500 | 0 | Paragraph body |
| `{typography.caption}` | 11–13px | 700 | 0.08em | Caption, fine print, footnote |
| `{typography.label-text}` | 11px | 800 | 0.08em | Text inside black label pills |
### Defaults
- **Default size for a primary section headline**: `{typography.headline}` (32–64px clamp).
- **Default size for a cover or opening display**: `{typography.display}` (48–96px clamp).
- **Default size for paragraph body**: `{typography.body}` (16–20px clamp).
- **Default size for any inline label or caption**: `{typography.caption}` (11–13px clamp).
- **Default weight for any display element**: 900.
- **Default weight for any body element**: 500.
- **Default size for a hero numerical figure**: `{typography.number}` (64–120px clamp).
When unsure, reach for `{typography.headline}` for the slide's primary text moment, not `{typography.title}` (which is for region-level headings within a slide).
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every display, headline, title, and subtitle element is uppercase.** Sentence-case display type does not exist in this system. If text is `{typography.display}`, `{typography.headline}`, `{typography.title}`, or `{typography.subtitle}`, it must be uppercase.
- **Every body element is sentence case.** Never uppercase a `{typography.body}` element — the uppercase/sentence-case contrast between display and body is the system's typographic signal.
- **Every display element uses negative letter-spacing.** Display (–0.02em), headline (–0.01em), number (–0.04em). Display type with default tracking reads as untreated; the negative tracking is what gives the type its compressed, brutalist density.
- **Every caption and label uses positive letter-spacing of at least 0.06em.** Caption and label glyphs without tracking read as code, not editorial.
- **All numerical figures use weight 900 with negative letter-spacing.** Even small stat numerals (36–56px) follow the display-weight convention.
### Typography Principles
The weight 900 + uppercase + negative tracking combination is the system's primary "voice." Switching any of those three properties (e.g., using weight 700 uppercase, or weight 900 sentence case) reads as a different design system. Weight 800 is reserved for `{typography.title}` and labels; weight 700 is for `{typography.subtitle}` and `{typography.caption}`; weight 500 is for body. Do not use intermediate weights (400, 600) — the weight ladder is fixed.
Italic is not used anywhere in the system. Underline is not used. The only emphasis mechanism is weight contrast.
## Layout
### Canvas System
The system targets `100vw × 100vh` — full viewport. Each `.slide` is absolutely positioned to fill the viewport and only one slide is `display: flex` at a time (slide navigation is JS-driven via keyboard arrow keys, spacebar, and touch swipe). All sizes use CSS `clamp()` so the layout fluidly scales between minimum and maximum without breakpoints.
### Padding and Gap Scale
| Token | Range | Use |
|---|---|---|
| `{spacing.pad-lg}` | 32–64px | Outer slide-region padding, full-region cells |
| `{spacing.pad-md}` | 20–40px | Header bands, secondary regions |
| `{spacing.pad-sm}` | 12–20px | Compact regions, table cells |
| `{spacing.gap-lg}` | 24–48px | Large flex/grid gaps |
| `{spacing.gap-md}` | 16–32px | Standard flex/grid gaps |
| `{spacing.gap-sm}` | 8–16px | Tight inline gaps |
### Border-as-Layout Principle
The defining structural pattern: **regions are separated by 3px solid black borders, not by gaps**. When a slide is divided into a 2-column grid, the two columns share a 3px black vertical border between them and the cells meet that border directly — no `gap` property, no margin. When a header band sits above a content area, a 3px black horizontal line separates them and both regions abut the line. This is the system's most distinctive structural choice.
Internal padding within a region (`{spacing.pad-lg}`, etc.) provides the breathing room inside cells. Gaps between cells do not exist.
## Depth and Elevation
### Hard Offset Shadow (Only Technique)
The system uses exactly two shadow values:
- **`{shadows.default}`** = `6px 6px 0 {colors.black}` — the standard hard offset shadow for elevated elements (large cards, primary callouts).
- **`{shadows.small}`** = `4px 4px 0 {colors.black}` — the lighter offset for smaller elevated elements.
Both shadows are **solid black, zero blur, fixed offset bottom-right**. There is no shadow variation by color, no blurred drop shadow, no soft elevation. An element either casts a hard offset shadow or it casts no shadow.
### Border-Based Depth
Most of the system's apparent "depth" actually comes from borders, not shadows. A 3px solid black border around a card on a colored background reads as elevated regardless of whether the card carries a shadow. Use shadow only when an element needs to feel "lifted off" the surface beneath it — typically a card that overlaps or floats above its containing region.
### Decorative Wallpaper (Atmospheric Depth)
A signature treatment: oversized numerals placed inside a card at very low opacity (0.15 for the largest quote mark, 0.20 for step numerals, 0.35 for card ordinals) sit behind the actual content as decorative wallpaper. The numeral fills the upper-left or upper portion of the region, and the actual title sits in front of it at full opacity. This creates a layered effect — content over decoration — without using any z-index trickery.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | Everything except circles |
| 50% (circle) | Donut chart shapes only |
The system has **no rounded corners**. Cards, buttons, labels, icon boxes, stat tiles, table cells, image frames — all strict rectangles or squares. The only round shape is the SVG donut chart, which is a circle by geometric necessity.
### Border Weights
- **3px solid `{colors.black}`** — the universal border. Used on every structural division: region separators, card outlines, table cells, icon boxes, connector nodes, swatches, bar tracks, stat tile borders. Never thinner, never thicker, never colored, never dashed.
- **4px solid `{colors.black}`** — used only for the `{components.line-h}` and `{components.line-v}` decorative rule elements (60px stub lines).
- **4px solid `{colors.white}`** — used only on the image placeholder frame inside black image regions (inverted border treatment for white-on-black contexts).
- **1.5px stroke** — used only on the inner stroke of the SVG donut chart at 0.1 opacity (a barely-visible inner ring).
### Decorative Element Types
**Black label pill** — A small black rectangle containing white uppercase text at 11px / weight 800 / 0.08em letter-spacing, with 6px × 14px padding. The system's universal section tag, fiscal-year marker, or status chip. May be prepended with the `{components.arrow-prefix}` for CTA variants.
**Horizontal rule stub** — A 60px × 4px solid black rectangle (`{components.line-h}`) used as an inline visual separator or accent next to a label. Functions as a "section break" mark in editorial layouts.
**Icon box** — A 48px × 48px white square with 3px black border containing a 1–3 character glyph (initials, Roman numeral, single letter) at 18–20px weight 900. Used as logo marks and feature icons.
**Decorative oversized numeral** — A large numeric character (typically a step number or section ordinal) at weight 900 placed inside a card at 0.15–0.35 opacity. Sits behind or above the card's actual content as wallpaper.
**Connector node** — A 32px × 32px solid black square containing a white arrow glyph at weight 900. Positioned absolutely between sequential items in a horizontal flow (e.g., between timeline steps). Acts as the visual "→" between stages.
**Bar track** — A 32px-tall horizontal rectangle with 3px black border and white interior. The fill (in pink, green, or black) is a child `div` whose `width` percentage represents the data value, with the value label printed inside the fill at 12px weight 800. Bars in black get inverted text color (white).
**Stat tile** — A bordered card (`{components.stat-box}`) containing a large numeral (`{typography.number-md}`) above a small caption (`{typography.caption}`). Background may be white, pink, green, gray, or black (with appropriate text inversion).
**Arrow-prefixed text** — Text elements (CTAs, interactive list rows) get a `→` (U+2192) prepended via `::before` with a non-breaking space, indicating action or navigation. This is the system's interactivity signal.
**Donut chart** — Multi-segment SVG ring at 24px stroke width with a 1.5px inner divider ring at 0.1 opacity. Segments use the palette colors (black, pink, green) and the center holds a value + label pair.
## Do's and Don'ts
### Do
- Use 3px solid black borders on every structural division. The border weight is the system's identity — thinner reads as generic web app, thicker reads as broken.
- Set headline color to `{colors.black}` by default. Headlines in pink, green, or gray do not exist in this system.
- Pair pink and green as opposites when two accent surfaces appear together — warm with cool, never two pinks or two greens adjacent.
- Apply uppercase + negative letter-spacing + weight 900 together on every display element. The three traits are inseparable — using them individually loses the brutalist character.
- Use the black label pill (`{components.label}`) as the universal section tag. It is the system's most distinctive small component and should appear generously.
- Use the arrow-prefix (`→ + nbsp`) on every CTA and interactive list row. It is the system's interactivity signal.
- Render shadows as `6px 6px 0 {colors.black}` or `4px 4px 0 {colors.black}`. There are only two shadow values — pick one.
- Place oversized decorative numerals at 0.15–0.35 opacity behind content in cards that have a numerical identity (step number, ordinal, quote mark). The wallpaper-numeral pattern is a system signature.
- Let borders touch directly. Two regions meeting at a 3px black line is correct; a gap between them is wrong.
- Use weight 500 sentence case for body and weight 900 uppercase for display. The contrast between the two is the typographic rhythm.
### Don't
- Don't load any web fonts. The system runs on the native sans-serif stack — Segoe UI / system-ui / Helvetica. Adding Google Fonts breaks the digital-native aesthetic.
- Don't round any corner. Cards, buttons, labels, icon boxes — all strict rectangles. Border-radius is permitted only for circles (the donut chart).
- Don't use blurred shadows. `0 4px 12px rgba(0,0,0,0.1)` does not exist here. Either a 4px/6px hard solid black offset or nothing.
- Don't use color on borders. All structural borders are black. A colored border breaks the system.
- Don't use intermediate font weights (400, 600). The weight ladder is fixed at 500 / 700 / 800 / 900.
- Don't use italic or underline. The only emphasis mechanism is weight contrast.
- Don't put display-weight text in sentence case. Uppercase is non-negotiable on display, headline, title, subtitle, and caption tokens.
- Don't introduce a third accent surface color. Pink and green are the only accent surfaces. Adding a yellow or blue card breaks the warm/cool pairing system.
- Don't use gap properties between border-divided regions. Regions meet at borders; they do not have margins between them.
- Don't invert text color over pink, green, or gray surfaces. The pastels are designed for black text on top — inverted treatments only apply to the `{colors.black}` surface.
## Responsive Behavior
Unlike most templates in this library, Raw Grid is **viewport-fluid by design**. The entire system uses CSS `clamp()` for sizes and there is no fixed canvas dimension. Every `font-size`, `padding`, `gap`, and `width` value scales linearly between a minimum and maximum based on viewport width. The same composition renders correctly on a 1280×720 laptop, a 1920×1080 monitor, and a 2560×1440 display without media queries.
### Scaling Behavior
- Display headline scales from 48px at minimum viewport to 96px at maximum.
- Body text scales from 16px to 20px.
- Padding scales from 32px to 64px on `{spacing.pad-lg}`.
- Borders, label pill padding, and shadow offsets are fixed (3px, 6px 14px, 6px 6px) — they do not scale, which means at larger viewports the borders appear proportionally finer.
### Presenter Behavior
- Slides advance via `ArrowDown`, `ArrowRight`, or `Space`.
- Slides go back via `ArrowUp` or `ArrowLeft`.
- `Home` jumps to first, `End` to last.
- Touch swipe (vertical) advances/reverses on mobile.
- The active slide carries the `.active` class; non-active slides are `display: none`.
### Print Behavior
A `@media print` rule sets all slides to `display: flex` with `page-break-after: always` — printing the deck produces a sequential page-per-slide PDF.
### Hover States
The system uniquely has interactive hover states baked into the design — list items and table rows highlight to `{colors.green}` on hover via a 0.15s transition. This is unusual for a presentation system; it reflects Raw Grid's hybrid identity as both presentation and product mockup.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headline / Title / Subtitle | Segoe UI / system-ui (900) | **思源黑体 Noto Sans SC** | 900 |
| Body / Caption / Label | Segoe UI / system-ui (500–800) | **思源黑体 Noto Sans SC** | 500 (body), 700–800 (caption / label) |
### Mixed-Content Strategy
**Strategy A — single CJK family across the entire system.** Raw Grid is intentionally a one-family system: every weight (900 / 800 / 700 / 500) comes from the same Latin stack. Mirroring that with a single CJK family — Noto Sans SC — preserves the system's most defining property: typographic uniformity. Because the Latin stack is `system-ui` (Segoe UI on Windows, San Francisco on macOS), pairing with a single high-quality CJK web font keeps the rendering as close to "system-native" as the digital-native aesthetic demands. Using two CJK families would fracture the neobrutalist monoculture.
### Loading
```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@500;700;800;900&display=swap" rel="stylesheet">
```
Then append `'Noto Sans SC'` after the Latin stack in every font-family token:
```css
font-family: 'Segoe UI', system-ui, -apple-system, Helvetica, Arial, 'Noto Sans SC', sans-serif;
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence
### Aesthetic Notes for This System
- **The negative tracking that defines the Latin display voice does not transfer.** Set `letter-spacing: 0` on every CJK display element. Noto Sans SC at weight 900 already reads as dense and brutalist; negative tracking will jam glyphs together and read as a rendering bug, not as a design choice.
- **Uppercase is the entire Latin display voice — and it does not exist in Chinese.** Compensate by leaning harder on the weight contrast (900 display vs. 500 body) and on the label pill's white-on-black inversion. The brutalist density comes from the weight ladder, not from case.
- **The black label pill (`{components.label}`) survives the translation beautifully.** A 2–4 character Chinese label (品牌, 信号源, 第四季度) in Noto Sans SC 800 reads as more compact and arguably more striking than the English equivalent.
- **Decorative oversized numerals at 0.15–0.35 opacity should stay Latin** (Arabic numerals look correct in this system; full-width Chinese numerals 零一二三 do not carry the same wallpaper-numeral signal).
- **The arrow-prefix (`→`) renders identically in CJK contexts** and is the right interactivity signal for both languages.
### Known CJK Gap
Raw Grid's whole aesthetic argument is "this is the user's actual system font, not a downloaded display face." Loading Noto Sans SC technically violates that purity — but there is no acceptable substitute. macOS ships PingFang SC and Windows ships Microsoft YaHei, but the two render at noticeably different weights at "900," and the digital-native aesthetic depends on weight 900 reading consistently. Noto Sans SC is the smallest acceptable concession to web fonts; treat it as the one exception to the no-web-fonts rule, only for CJK content.
## Iteration Guide
1. Any new structural region uses a 3px solid black border to separate from its neighbor. Never use a gap or a margin between regions — borders are the separators.
2. Any new card or panel inherits the bordered-rectangle pattern: 3px solid black border, square corners, padding from the `{spacing.pad-*}` scale, background from the palette (white, pink, green, gray, or black).
3. Any new headline uses `{typography.headline}` (or `{typography.display}` for cover-level moments) in `{colors.black}` with uppercase. Don't reach for `{typography.title}` for the primary moment — that's a sub-headline.
4. Any new label or chip uses the `{components.label}` pattern: black background, white uppercase text at 11px / weight 800 / 0.08em.
5. Any new numerical figure follows the weight-900 + negative-tracking convention. Stat tiles use `{typography.number-md}`; hero stats use `{typography.number}`.
6. Any new accent surface picks pink or green based on warm/cool need. Don't introduce a third color.
7. Any new CTA or interactive element gets the `→` arrow prefix and, if elevated, a `6px 6px 0 {colors.black}` shadow.
8. If a card needs a "personality" element, add an oversized decorative numeral at 0.15–0.35 opacity rather than a graphic or icon. The wallpaper-numeral treatment is the system's signature decorative move.
9. Tables follow the bordered-cells + zebra-stripe + black-header pattern. Don't restyle them — the brutalist table aesthetic is part of the system identity.
## Known Gaps
- The `--darkgray` (#333333) CSS variable is defined but not actively used in any rule. It is available as a reserved tertiary text color but not deployed anywhere in the source.
- The system loads no external fonts — the rendered letterforms will differ between operating systems. macOS renders system-ui as San Francisco, Windows renders Segoe UI, Linux renders whatever sans-serif is configured. This visual inconsistency is by design but is worth noting.
- Hover states (list items → green, table rows → green) are interactive web behaviors that have no analog in print or static export. Treat them as bonus interactivity, not core design system.
- The slide navigation JavaScript is embedded inline — it handles keyboard, touch, and the active-class system. Any new slide must follow the `<div class="slide sN">` pattern and respect the `current` index.
- The SVG donut chart uses hardcoded `stroke-dasharray` values that must be computed manually based on segment percentages and the chart's 80px radius circumference (~502.4). There is no data-binding layer.
- The image placeholder on image-paired regions is just a 4px-white-bordered div with "[ Image Placeholder ]" text — actual image insertion requires replacing the placeholder div with an `<img>` and matching the parent background to the image's negative space.
- The `.s5-image-placeholder` includes the word "Cohots" (sic) which appears to be a typo for "Cohorts" in the source. Flag this when reusing content.
# Raw Grid Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/raw-grid/design.md`
- Preview card: `bold-template-pack/templates/raw-grid/preview.md`
## Selection Metadata
- Slug: `raw-grid`
- Tagline: Neo-brutalist deck with thick borders, offset shadows, and a pink/sage/ink palette.
- Mood: raw, punchy, energetic, confident
- Tone: direct, modern, no-nonsense, graphic
- Formality: medium-low
- Density: high
- Scheme: light
- Best for: Anything that should feel direct and graphic-confident: founder pitches, accelerator demos, brand decks, indie launches, creator portfolios. Strong for stat slides, comparison tables, and process flows. Equally good for tech, research, or finance when the speaker wants the deck to feel scrappy-confident rather than buttoned-up.
- Avoid for: Contexts that need to feel soft, warm, or intentionally quiet — the brutalist borders and offset shadows commit to a graphic voice.
## Visual Snapshot
A neobrutalist presentation system where 3px solid black borders ARE the layout. Display type runs in the native system sans-serif stack (Segoe UI / system-ui) at weight 900 in strict uppercase — no web fonts loaded. The palette is white canvas + black structure + two muted pastel accents (blush pink #F2D4CF and sage green #E5EDD6) + a neutral gray. Depth comes from hard offset shadows in solid black at 4px and 6px — never blurred, never colored. The aesthetic borrows from brutalist editorial web design and zine layout: borders meet without gaps, contrast is high but warmed by the pastel accents, and large numerals sit at very low opacity behind content as decorative wallpaper. The effect is sharp, system-native, and unmistakably digital — closer to a Notion-meets-protest-poster than a polished pitch deck.
Raw Grid is a neobrutalist presentation system built on a single structural premise: 3px solid black borders are the layout. There are no margins between regions, no gaps between cells, no rounded corners, no gradients. When two regions meet, a 3px black line separates them — that line is the entire grid system.
## Preview Ingredients
- Palette: black #0A0A0A; white #FFFFFF; pink #F2D4CF; green #E5EDD6; gray #F5F5F5; darkgray #333333
- Typography: Segoe UI
- Signature move: White ({colors.white}) canvas with 3px solid black ({colors.black}) borders dividing every region. No gaps between cells — borders meet edge-to-edge.
- Signature move: System sans-serif at weight 900 uppercase for all display type; weight 500 sentence case for all body type.
- Signature move: Hard offset shadows at 6px and 4px in solid black, no blur, ever.
- Signature move: Two muted pastel accent surfaces — blush pink and sage green — used as region fills, never as text colors.
- Signature move: A signature black-pill label component ({components.label}) — white uppercase text in a small black rectangle — appears as the universal section tag.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
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.
# Retro Windows Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/retro-windows/design.md`
- Preview card: `bold-template-pack/templates/retro-windows/preview.md`
## Selection Metadata
- Slug: `retro-windows`
- Tagline: Windows 95 chrome: gray title bars, MS Sans Serif, pixel typography, full nostalgia.
- Mood: nostalgic, retro, geeky, playful
- Tone: winking, nostalgic, geeky, fun
- Formality: low
- Density: medium
- Scheme: light
- Best for: Anything that should feel knowingly nostalgic: retro gaming, Y2K-aesthetic brands, creator portfolios with a 90s vibe, tech-history talks, deliberately tongue-in-cheek decks. A great choice anywhere a playful retro reference is the entire point.
- Avoid for: Decks that need to read as modern, elegant, or institutionally credible — the Win95 chrome will always read as a costume.
## Visual Snapshot
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.
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).
## Preview Ingredients
- Palette: bg-gray #C0C0C0; bg-light #D4D0C8; bg-dark #808080; white #FFFFFF; black #000000; text-dark #222222; blue-navy #000080; blue-bright #0000A0
- Typography: MS Sans Serif
- Signature move: Every slide is a {components.win-window} — beveled chrome with navy-gradient title bar and three system buttons (_, [], X).
- Signature move: A fixed 3px-period CRT scanline overlay ({components.crt-overlay}) sits above all content at 3% opacity.
- Signature move: Bevel-based depth: raised ({components.panel-raised}, {components.btn-retro}) and sunken ({components.panel-sunken}, {components.group-box}) — no blurred shadows.
- Signature move: The font stack is MS Sans Serif / Segoe UI / Tahoma fallback, with Press Start 2P and VT323 as nostalgic accents.
- Signature move: Status colors (green / red / yellow / cyan) carry semantic meaning: green = OK, red = warning, yellow = moderate, cyan = tertiary data.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Retro Zine
description: A risograph-zine editorial system on warm khaki paper with a deep forest-green accent and ink-black structure. Display type runs in Bebas Neue (condensed industrial sans, uppercase, generously tracked); body type runs in Space Grotesk at weight 300–500; handwritten emphasis runs in Caveat. A subtle SVG grain overlay sits over every slide, reinforcing the printed-paper feel. The aesthetic borrows from independent press, mid-century activist posters, and DIY zine culture: slightly rotated stamp marks, masking-tape pieces in collage layouts, drop caps, and offset paper-on-paper shadows. The effect is hand-printed editorial — warm but disciplined, confident but tactile.
colors:
bg: "#C8B99A"
bg-dark: "#B8A98A"
green: "#008F4D"
green-light: "#00A85D"
black: "#1A1A1A"
white: "#F4EFE6"
color-aliases:
line: black
typography:
display-hero:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(56px, 10vw, 160px)"
fontWeight: 400
lineHeight: 0.85
letterSpacing: 0.04em
textTransform: uppercase
display-cover:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(48px, 10vw, 140px)"
fontWeight: 400
lineHeight: 0.88
letterSpacing: 0.04em
textTransform: uppercase
display:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(48px, 8vw, 120px)"
fontWeight: 400
lineHeight: 0.9
letterSpacing: 0.04em
textTransform: uppercase
headline:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(42px, 6vw, 90px)"
fontWeight: 400
lineHeight: 0.95
letterSpacing: 0.03em
textTransform: uppercase
headline-md:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(36px, 5vw, 72px)"
fontWeight: 400
lineHeight: 0.95
letterSpacing: 0.03em
textTransform: uppercase
statement:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(36px, 6vw, 90px)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
textTransform: uppercase
title:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(24px, 3vw, 42px)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.04em
textTransform: uppercase
number-hero:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(80px, 12vw, 160px)"
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.02em
number-md:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(44px, 6vw, 80px)"
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.02em
drop-cap:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "clamp(48px, 6vw, 80px)"
fontWeight: 400
lineHeight: 0.8
letterSpacing: 0.02em
body:
fontFamily: "'Space Grotesk', sans-serif"
fontSize: "clamp(13px, 1.2vw, 16px)"
fontWeight: 400
lineHeight: 1.7
body-md:
fontFamily: "'Space Grotesk', sans-serif"
fontSize: "clamp(14px, 1.3vw, 18px)"
fontWeight: 400
lineHeight: 1.6
label-eyebrow:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "14–18px"
fontWeight: 400
lineHeight: 1.2
letterSpacing: 0.2em
textTransform: uppercase
label-spaced:
fontFamily: "'Space Grotesk', sans-serif"
fontSize: "12–14px"
fontWeight: 600
lineHeight: 1.2
letterSpacing: 0.25em
textTransform: uppercase
caption-feature:
fontFamily: "'Bebas Neue', sans-serif"
fontSize: "13–15px"
fontWeight: 400
lineHeight: 1.2
letterSpacing: 0.2em
textTransform: uppercase
hand-script:
fontFamily: "'Caveat', cursive"
fontSize: "clamp(22px, 3vw, 36px)"
fontWeight: 600
lineHeight: 1.3
hand-script-sm:
fontFamily: "'Caveat', cursive"
fontSize: "clamp(16px, 2vw, 22px)"
fontWeight: 400
lineHeight: 1.3
hand-script-lg:
fontFamily: "'Caveat', cursive"
fontSize: "clamp(24px, 3vw, 36px)"
fontWeight: 600
lineHeight: 1.3
spacing:
slide-pad: 60px
slide-pad-wide: "60px 80px"
card-pad-lg: 48px
card-pad-md: 32px
card-pad-sm: 24px
gap-lg: 60px
gap-md: 40px
gap-sm: 24px
canvas:
width: 100vw
height: 100vh
components:
grain-overlay:
backgroundImage: "SVG fractal-noise filter, base 200×200 tile"
opacity: 0.07
zIndex: 9999
description: "Fixed, full-viewport SVG grain overlay sitting above all content. Imitates the print-grain texture of a risograph or letterpress page. Pointer-events disabled. Required on every slide."
line-box:
border: "3px solid {colors.black}"
description: "Generic outlined card with 3px solid black border on khaki background. The system's default content container."
line-divider:
border: "3px solid {colors.black}"
description: "Strict 3px black rule used as a region divider. May be top, bottom, left, or right of a region; meets adjacent borders without gap."
line-thin:
border: "2px solid {colors.black}"
description: "2px black rule used inside a section for sub-region division (editorial column rule, ed-header bottom rule)."
line-fine:
border: "1.5px solid {colors.black}"
description: "1.5px black rule used inside grid containers for cell separation (sub-cells inside a 3px-bordered grid)."
stamp:
transform: "rotate(-8deg) or rotate(6deg)"
display: inline-block
description: "Any element may be rotated -8deg (stamp) or 6deg (stamp-alt) to read as a hand-pressed ink stamp or applied label. Reserve for badges, callouts, and decorative overlays."
stamp-mark:
background: "{colors.black}"
color: "{colors.green}"
fontFamily: "'Bebas Neue', sans-serif"
padding: "10px 24px"
border: "2px solid {colors.green}"
transform: "rotate(-8deg)"
fontSize: 18px
letterSpacing: 0.1em
description: "Approval / status stamp — black background, green text, green 2px border, rotated -8deg. Used as a 'stamp of authenticity' callout."
ribbon-bar:
background: "{colors.green}"
color: "{colors.white}"
padding: "4–8px 12–20px"
description: "Solid green color-block that contains light cream text — used as section labels, accent strips, and inline highlight bars."
inline-highlight:
background: "{colors.black}"
color: "{colors.bg}"
padding: "2px 8px"
fontWeight: 600
description: "Black-on-khaki marker highlight applied inline inside body paragraphs to lift a phrase. The print equivalent of a marker pen swipe."
drop-cap:
float: left
fontSize: "clamp(48px, 6vw, 80px)"
fontFamily: "'Bebas Neue', sans-serif"
color: "{colors.green}"
lineHeight: 0.8
marginRight: 12px
description: "Oversized green initial cap at the start of an editorial paragraph. Bebas Neue, line-height 0.8, floated left so body text wraps around."
card-offset:
background: "{colors.white}"
border: "3px solid {colors.black}"
positionBefore:
offset: "12px down, 12px right"
background: "{colors.green}"
zIndex: -1
description: "Card with a paper-on-paper offset effect — a solid green slab sits 12px behind the card, offset down-and-right. Reads as a colored shadow without using box-shadow."
collage-piece:
border: "3px solid {colors.black}"
padding: 24px
position: absolute
transform: "rotate(-5deg to 5deg)"
description: "Free-positioned collage panel with a 3px black border and small rotation. Backgrounds vary across pieces — white, khaki-dark, green, or black-with-inversion. Used in scatter-on-page compositions."
tape:
width: 80px
height: 24px
background: "rgba(255,255,255,0.4)"
border: "1px solid rgba(0,0,0,0.1)"
transform: "rotate(-40deg to 35deg)"
description: "Translucent masking-tape rectangle layered at random angles over a collage to suggest physically taped-down pieces. Positioned absolutely; 1px hairline border. Always semi-transparent white."
divider-stub:
width: 60–80px
height: 4px
background: "{colors.white} or {colors.green}"
description: "Short solid horizontal rule used as a centered visual breath above/below a statement or closing title. 4px tall."
rsvp-field:
borderBottom: "2px solid {colors.black}"
paddingBottom: 8px
description: "Form-field row pattern: small Bebas Neue green label, hand-script value drawn over a 2px black underline. Mimics a written form."
ledger-row:
borderBottom: "1.5px solid {colors.black} (header) or 1px solid rgba(black, 0.22) (body)"
padding: "10–18px 0"
description: "Horizontal data row pattern: date | title | edition | track | nr. Header row has stronger bottom border; body rows have hairline dividers."
chip:
padding: "4px 10px"
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "11–12px"
color: "{colors.white}"
textTransform: uppercase
letterSpacing: 0.06em
description: "Mono-font color chip used inline in tabular ledger rows to tag a row's category. Fill pulls from green / red-stamp / orange / pink / blue as a categorical palette extension."
---
## 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 Zine is a **risograph-zine editorial system** on a warm khaki canvas (`{colors.bg}` — #C8B99A) with deep forest-green (`{colors.green}` — #008F4D) as the meaningful accent and ink-black (`{colors.black}` — #1A1A1A) as the structural color. The aesthetic borrows from independent press culture, mid-century activist posters, and DIY zine layouts: condensed industrial display type, hand-script emphasis, slightly rotated stamps, masking-tape collage marks, drop caps, and a print-grain overlay that ties every surface to a printed-paper register.
The typeface stack pairs three faces with distinct emotional roles. **Bebas Neue** is the display voice — a condensed, all-caps industrial sans with generous tracking (0.02–0.04em) used for every headline, statement, statistic, numeral, and label. Its compressed verticality is the system's visual identity; substituting any other display sans loses the zine voice. **Space Grotesk** is the body voice — a clean humanist geometric sans at weight 300–500 for paragraphs, used at small sizes (13–18px) which preserves the magazine column-text density. **Caveat** is the hand-script voice — a casual ballpoint cursive used for author attributions, side notes, captions on display elements, and the form-field "writing" in RSVP-style layouts. The three faces together read as "an editorial spread typeset by a small press."
The color philosophy is **earth + forest**: a warm khaki paper canvas, a deeper khaki tonal sibling for layered surfaces, deep forest-green for accents and accent surfaces, ink-black for structure and body, and an off-white cream (`{colors.white}` — #F4EFE6) for cards and inverted text fills. The white is deliberately not pure — it's a soft cream that sits as paper inside paper rather than as a hard rectangle. Green carries the system's emotional voice: it is what activates a section, what stamps approval, what marks the brand. The same hex (#008F4D) appears as drop caps, ribbon bars, inline labels, statement backgrounds, and the progress bar.
Depth comes from **paper-on-paper offset blocks** and **slight rotations**, not blurred shadows. The signature treatment: a `{components.card-offset}` carries a solid green slab sitting 12px down-and-right behind it via an absolutely-positioned `::before` pseudo-element. The visual effect is a layered paper or letterpress underprint rather than a soft drop shadow. Rotations on stamps (`-8deg` or `6deg`) and on collage pieces (`-5deg` to `5deg`) add the hand-placed feeling.
**Density philosophy: medium-high.** The zine register depends on visual richness — collage compositions, multi-column editorial layouts, drop caps inside body text, tabular ledgers with chip categories, ribbon-bar headers stamped at angles. A slide that holds only one centered headline reads as underdesigned; the zine voice expects a layout to be packed with editorial moves. The correct density is one dominant text moment supported by multiple subordinate components (decorative stamps, eyebrow labels, divider stubs, hand-script attributions, drop caps). Reserve true sparseness for the manifesto / statement moment where a single large quote dominates a solid green field.
**Key Characteristics:**
- Warm khaki paper canvas (`{colors.bg}`) + deep forest-green accent (`{colors.green}`) + ink-black structure (`{colors.black}`).
- An SVG grain overlay (`{components.grain-overlay}`) sits over every slide at 0.07 opacity, reinforcing the printed-paper register.
- Bebas Neue uppercase + tracked for every display moment; Space Grotesk at small sizes for body; Caveat for hand-script emphasis.
- 3px solid black structural borders divide regions; 2px and 1.5px borders subdivide.
- Paper-on-paper offset cards: green slab sits 12px behind a white card via `::before`.
- Stamps and collage pieces carry small rotations (-8°, +6°, -5° to +5°).
- Translucent masking-tape pieces (`{components.tape}`) layered over collage compositions.
- Green drop caps, green ribbon bars, and green inline highlights mark editorial emphasis.
## Colors
### Palette
- **Background** (`{colors.bg}` — #C8B99A): The warm khaki paper canvas. The default surface for every slide. Saturated enough to read as paper-with-history rather than as a neutral; warm enough to harmonize with the forest-green accent.
- **Background Dark** (`{colors.bg-dark}` — #B8A98A): A slightly darker tonal sibling of the canvas. Used for layered surface regions when one half of a split-screen needs to sit visually behind the other, and for collage pieces that want to read as "paper on khaki paper."
- **Green** (`{colors.green}` — #008F4D): Deep forest green. The system's accent color — hero numerals, drop caps, ribbon bars, statement-slide backgrounds, progress bar, inline highlights, RSVP labels, the offset slab behind cards, divider stubs on the closing slide. The single most distinctive non-canvas color.
- **Green Light** (`{colors.green-light}` — #00A85D): A slightly brighter sibling of green. Available as a hover-state or secondary green where the deep green needs a step-up; rarely used in baseline static slides.
- **Black** (`{colors.black}` — #1A1A1A): Ink-black. The structural color — all borders, all body text, all dividers, all closing-slide backgrounds, all label fills (when inverted). Slightly softer than pure black (#000000) so it sits as warm ink on warm paper.
- **White / Cream** (`{colors.white}` — #F4EFE6): Soft cream. Used as card fills (paper-on-paper), as text inside black surfaces, and as the divider-stub color on statement slides. Critically, this is not pure white — it's a paper-cream that maintains the warm-paper register even when used as a "white" surface.
### Defaults
- **Default surface background**: `{colors.bg}` — every slide opens on warm khaki paper.
- **Default headline color**: `{colors.green}` for primary section headlines and hero titles; `{colors.black}` for body-paired headlines in two-column or split layouts. When in doubt, reach for `{colors.green}` — a green headline is the system's loudest editorial signal.
- **Default body text color**: `{colors.black}`.
- **Default border color**: `{colors.black}` — every structural border is black, no exceptions.
- **Default accent surface for emphasis (statement, hero callout)**: `{colors.green}` with `{colors.white}` text.
- **Default text color on a `{colors.green}` surface**: `{colors.white}` (cream).
- **Default text color on a `{colors.black}` surface**: `{colors.bg}` (the khaki canvas), so type still reads as "ink on paper" even in inversion. Green accents on a black surface (closing slide eyebrow + hand-script) lift the inversion.
- **Default eyebrow / label color**: `{colors.green}` for Bebas Neue labels; `{colors.black}` for letter-spaced Space Grotesk labels.
- **Default drop-cap color**: `{colors.green}`. Drop caps are the editorial fingerprint and they are always green.
- **Default hand-script color**: `{colors.black}` on khaki/cream surfaces; `{colors.green}` on black surfaces (closing).
- **Default inline highlight**: black-on-khaki (`{components.inline-highlight}`) — used to lift phrases inside body paragraphs as if marked with a pen.
The green and black accents are not interchangeable: **green = emphasis** (this is what we want you to notice), **black = structure** (this is what holds the page together). Reversing them — using black for emphasis and green for structure — flips the system's voice.
## Typography
### Font Family
The system pairs three Google Fonts:
- **Bebas Neue** (display): A condensed all-caps industrial sans-serif. Single weight (400) but reads bold by virtue of its dense vertical strokes. Used uppercase with 0.02–0.04em letter-spacing for every display moment — headlines, statements, statistics, ordinals, eyebrow labels. The narrow tracked Bebas voice is what makes the system unmistakably "zine."
- **Space Grotesk** (body): A clean humanist geometric sans-serif with subtle quirky proportions. Used at weights 300–500 for body paragraphs at small sizes (13–18px), and at weight 600 for letter-spaced Space Grotesk caps labels. Provides the readable counterpoint to Bebas's expressive density.
- **Caveat** (hand-script): A casual handwritten cursive. Used at weights 400–700 for author attributions ("— Our founding principle since day one"), side notes, decorative captions on display elements, value-fills in RSVP-style form layouts. Provides warmth and a human-hand voice against the otherwise typeset system.
There is no fourth face. Italic does not exist (Caveat is a script face, not an italic). Underline does not exist. Emphasis is achieved by switching face (Space Grotesk body → Caveat hand-script for a personal note, Bebas Neue display for a callout) or by color (`{colors.black}` → `{colors.green}`).
### Type Scale
| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-hero}` | 56–160px | Bebas Neue | 400 | Closing or oversized cover headline |
| `{typography.display-cover}` | 48–140px | Bebas Neue | 400 | Cover / opening display headline |
| `{typography.display}` | 48–120px | Bebas Neue | 400 | Major declarative or callout display |
| `{typography.headline}` | 42–90px | Bebas Neue | 400 | Primary section headline |
| `{typography.statement}` | 36–90px | Bebas Neue | 400 | Long-form quoted statement |
| `{typography.headline-md}` | 36–72px | Bebas Neue | 400 | Editorial section header |
| `{typography.title}` | 24–42px | Bebas Neue | 400 | Region or collage-piece title |
| `{typography.number-hero}` | 80–160px | Bebas Neue | 400 | Hero statistic numeral |
| `{typography.number-md}` | 44–80px | Bebas Neue | 400 | Tile or sub-stat numeral |
| `{typography.drop-cap}` | 48–80px | Bebas Neue | 400 | Initial cap leading an editorial paragraph |
| `{typography.body-md}` | 14–18px | Space Grotesk | 400 | Lead paragraph or emphasized body |
| `{typography.body}` | 13–16px | Space Grotesk | 400 | Standard paragraph body |
| `{typography.label-eyebrow}` | 14–18px | Bebas Neue | 400 | Eyebrow label above a headline, tracked 0.2em |
| `{typography.label-spaced}` | 12–14px | Space Grotesk | 600 | Tracked all-caps small label |
| `{typography.caption-feature}` | 13–15px | Bebas Neue | 400 | Tracked all-caps caption or feature-callout label |
| `{typography.hand-script}` | 22–36px | Caveat | 600 | Author attribution, decorative note, statement byline |
| `{typography.hand-script-sm}` | 16–22px | Caveat | 400 | Small handwritten label or descriptor |
| `{typography.hand-script-lg}` | 24–36px | Caveat | 600 | Larger handwritten subtitle |
### Defaults
- **Default size for a primary section headline**: `{typography.headline}` (42–90px clamp) in `{colors.green}`.
- **Default size for a cover or oversized opening headline**: `{typography.display-cover}` (48–140px clamp) in `{colors.green}`.
- **Default size for paragraph body**: `{typography.body}` (13–16px clamp) — the zine register expects small body type, not modern 18px+ paragraphs.
- **Default size for a lead paragraph or emphasized body**: `{typography.body-md}` (14–18px).
- **Default size for an eyebrow label above a headline**: `{typography.label-eyebrow}` (14–18px) in `{colors.green}`, tracked 0.2em uppercase.
- **Default size for a hero numerical figure**: `{typography.number-hero}` (80–160px clamp) in `{colors.green}`.
- **Default size for any hand-script attribution / side note**: `{typography.hand-script}` (22–36px clamp).
- **Default weight for any Bebas display element**: 400 (Bebas Neue ships at 400; weight changes are not part of the system).
- **Default weight for body**: 400; for tracked-caps small labels: 600.
When unsure between `{typography.headline}` and `{typography.title}` for the dominant text moment on a slide, reach for `{typography.headline}` — `{typography.title}` is for collage-piece or region-level subtitling within a slide.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Bebas Neue element is uppercase.** The font has lowercase glyphs but they are not used in this system. Sentence-case Bebas is not part of the vocabulary.
- **Every Bebas Neue element carries positive letter-spacing of at least 0.02em.** Default tracking on Bebas reads as cramped; the 0.02–0.04em opens it up. Labels and eyebrows track even more (0.2–0.25em).
- **Every primary section headline is set in `{colors.green}`.** Black headlines exist (for body-paired columns) but the system's loudest editorial voice is green-on-khaki.
- **Every editorial paragraph that opens a column may carry a drop cap.** The drop cap is always `{components.drop-cap}` — green, Bebas Neue, line-height 0.8, floated left. Use it as the opening flourish for a feature-length body column.
- **Every hand-script element uses Caveat.** Substituting another script face loses the personal-note voice.
- **Hand-script attributions follow display headlines on quote / statement layouts.** A statement without a hand-script byline reads as incomplete; the byline grounds the quote as a human voice.
- **Inline highlights inside body use the black-on-khaki pattern** (`{components.inline-highlight}`), not green-on-khaki. Green inline reads as a typo; black inline reads as a marker stripe.
### Typography Principles
The system's typographic rhythm comes from **three-face contrast**: condensed industrial Bebas display (loud, tracked, uppercase) → clean Space Grotesk body (quiet, small, sentence case) → expressive Caveat hand-script (personal, looser, signature-style). Slides that use only one face read as monotonous; slides that mix all three within a single composition read as zine-correct.
Line-height: tight on display (0.85–1.1), generous on body (1.6–1.7), loose on hand-script (1.3). Never invert these — tight body and loose display both break the rhythm.
## Layout
### Canvas System
The system targets `100vw × 100vh` — full viewport. Each `.slide` is absolutely positioned to fill the viewport; only the `.active` slide is visible (opacity 1, others at opacity 0). Slide transitions use a 0.6s opacity + translateY(20px) ease for a soft paper-shuffle feel. Navigation is JS-driven via arrow keys, space, click, and touch swipe. A 4px tall `{colors.green}` progress bar runs flush along the bottom edge.
### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad}` | 60px | Standard slide outer padding |
| `{spacing.slide-pad-wide}` | 60px 80px | Editorial column-spread outer padding |
| `{spacing.card-pad-lg}` | 48px | Inside hero cards (RSVP, large callout) |
| `{spacing.card-pad-md}` | 32px | Inside grid-box cells |
| `{spacing.card-pad-sm}` | 24px | Inside collage pieces, smaller card cells |
| `{spacing.gap-lg}` | 60px | Editorial column gap |
| `{spacing.gap-md}` | 40px | Standard region gap |
| `{spacing.gap-sm}` | 24px | Tight inline gap |
### Persistent Chrome
Three persistent elements live outside the slide composition:
- **Progress bar** flush along the bottom-left, 4px tall, fill in `{colors.green}`. Grows as the deck advances.
- **Slide counter** at bottom-right — Bebas Neue 14px in a 2px-bordered cream chip with khaki ink.
- **Nav hint** at bottom-center — a black-fill pill with cream text, fading in only on `body:hover` (0.4s opacity transition).
### Region Borders vs Internal Padding
The system follows a **border-as-divider** principle for grid containers — a parent container has a 3px solid black outer border, and each child cell has a 1.5px solid black border that creates a hairline cell-to-cell divider. Where regions abut at a slide-edge (split-screen layouts), the dividing line is 3px solid black with the two regions meeting it directly — no gap.
For free compositions (collage, hero, manifesto), regions are positioned absolutely with rotation and overlap; borders sit on individual pieces, not on the slide grid.
## Depth and Elevation
### Paper-on-Paper Offset Block (Primary Technique)
The signature depth treatment is the **offset color block**: a card carries a `::before` pseudo-element absolutely positioned, offset 12px down-and-right, filled in `{colors.green}` (or another accent), and z-indexed behind the card. The visual effect is a layered paper underprint — the card looks like it sits on top of a slightly-larger green sheet of paper, with the green showing through at the bottom-right edges. Used on hero RSVP cards and primary callout containers.
### Rotation (Secondary Technique)
Small rotations (`-8deg` stamp, `+6deg` stamp-alt, `-5deg` to `+5deg` collage) on stamp marks, RSVP labels, visual overlay callouts, and collage pieces give the system its hand-placed energy. Rotations are intentional — never accidental tilt — and reserved for elements meant to read as physical artifacts (stamps, taped pieces, applied labels).
### Grain Overlay (Atmospheric Texture)
A subtle SVG fractal-noise overlay sits over every slide at 0.07 opacity, tinting all surfaces with print grain. This is not depth in the strict sense — it's surface texture that grounds every flat color block in the printed-paper register. Removing the grain breaks the zine voice immediately.
### No Web Shadows
The system uses **no blurred `box-shadow`, no `drop-shadow`, no rgba shadow tints** for depth. The offset color block, the rotations, and the grain overlay are the entire depth grammar. A modern soft shadow on any element breaks the print aesthetic.
### Color-Block Contrast
Beyond shadows and rotations, **green-on-khaki and black-on-khaki contrast** provides regional depth. A green ribbon bar inside a khaki region visually projects forward; a black region behind a white card visually recedes. The palette's high contrast is the secondary depth signal.
## Shapes and Treatment
### Border Radius
The system has **no rounded corners**. Every shape — cards, ribbon bars, stamps, RSVP cards, table cells, drop caps, chips, divider stubs — is a strict rectangle or square. Border-radius is `0` system-wide.
### Border Weights
- **3px solid `{colors.black}`** — the universal structural border on cards, region dividers, grid container outer borders, collage pieces, RSVP cards, hero callouts.
- **2px solid `{colors.black}`** — used for editorial column rules, RSVP-field underlines, ed-header bottoms, and the stamp-mark green border.
- **1.5px solid `{colors.black}`** — used for grid cell sub-borders inside a 3px outer-bordered container, and for ledger header underlines.
- **1px solid rgba(black, 0.22)** — used for ledger row dividers and hairline tabular separations.
Borders are always black. Colored borders do not exist except the green border on the `{components.stamp-mark}` approval stamp.
### Decorative Element Types
**Line box** (`{components.line-box}`) — Generic 3px-bordered card on khaki background. The system's default content container. Padding from the `{spacing.card-pad-*}` scale.
**Card with offset** (`{components.card-offset}`) — White cream card with a 3px black border and a 12px-offset green slab sitting behind via `::before`. The signature paper-on-paper card.
**Stamp** (`{components.stamp}` / `{components.stamp-mark}`) — Any element may be rotated -8° (stamp) or +6° (stamp-alt) to read as a hand-pressed mark. The `stamp-mark` variant is a black rectangle with green text and green border. Used as approval seals, "CONTACT US" badges, and editorial stamps.
**Collage piece** (`{components.collage-piece}`) — Free-positioned panel with 3px black border and small rotation. Backgrounds rotate across pieces: green, white-cream, khaki-dark, black-inverted. Used in collage compositions where multiple pieces scatter across the slide with overlap.
**Tape** (`{components.tape}`) — Translucent white rectangle layered at random angle over collage pieces to suggest physical taped-down paper. Always semi-transparent, always at a sharp angle (-40° to +35°).
**Ribbon bar** (`{components.ribbon-bar}`) — Solid green color block with cream text — used as eyebrow strips, accent bars, and inline section labels. Read as a printed ribbon glued onto the page.
**Drop cap** (`{components.drop-cap}`) — Oversized green Bebas Neue initial that opens an editorial paragraph. Floated left, line-height 0.8, body text wraps around.
**Inline highlight** (`{components.inline-highlight}`) — Black-on-khaki marker swipe applied inline inside body paragraphs to lift a phrase. The print equivalent of a marker pen.
**RSVP field** (`{components.rsvp-field}`) — Form-field row pattern with a Bebas Neue green label paired with hand-script Caveat "writing" over a 2px black underline. The system's "filled-by-hand" form pattern.
**Ledger row** (`{components.ledger-row}`) — Horizontal data row pattern with date | title | edition | track | nr columns. Header row has 1.5px black underline; body rows have 1px hairline dividers. Each row may contain a color-coded chip (`{components.chip}`) tagging its category.
**Chip** (`{components.chip}`) — Mono-font color block (JetBrains Mono if used, else default mono) tagging a row category. Fill colors: green, plus the categorical-palette extension on slides that pull from the broader stamp palette.
**Divider stub** (`{components.divider-stub}`) — A short 4px solid horizontal rule (60–80px wide), centered, used as visual breath above/below a hero title or statement. White on green surfaces, green on black surfaces.
**Hand-script element** — Any text in Caveat. The system signal for "human voice" — attributions, side notes, captions, RSVP-field fills, closing-slide sign-offs.
## Do's and Don'ts
### Do
- Keep the SVG grain overlay (`{components.grain-overlay}`) on every slide at 0.07 opacity. It is the texture that anchors the entire deck to the printed-paper register.
- Use Bebas Neue uppercase with 0.02–0.04em tracking for every display, headline, statement, statistic, numeral, and eyebrow label.
- Reach for `{colors.green}` as the default headline color for primary section headlines. Green-on-khaki is the system's loudest editorial signal.
- Use the paper-on-paper offset pattern (`{components.card-offset}`) on hero callouts and RSVP-style cards — a green slab behind a white card via `::before`.
- Apply small rotations (-8° stamps, -5° to +5° collage pieces) to elements meant to read as physical artifacts. Rotation should always feel intentional.
- Use drop caps (`{components.drop-cap}`) to open editorial body columns. They are the system's editorial fingerprint.
- Mix the three faces — Bebas Neue display + Space Grotesk body + Caveat hand-script — within a single composition. Three-face contrast is the typographic rhythm.
- Set inline highlights inside body paragraphs in black-on-khaki (`{components.inline-highlight}`), mimicking a marker swipe.
- Pair every quote / statement with a Caveat hand-script byline below. The script attribution grounds the quote as a human voice.
- Layer translucent tape pieces (`{components.tape}`) at sharp angles over collage compositions to suggest physical taped-down paper.
### Don't
- Don't round any corner. Border-radius is 0 system-wide on every element.
- Don't use blurred `box-shadow`. All depth comes from the offset color block, rotation, and the grain overlay.
- Don't substitute another display face for Bebas Neue. The condensed industrial tracked-uppercase voice is the entire system identity.
- Don't use Bebas Neue in sentence case. Bebas always renders uppercase in this system; lowercase Bebas reads as wrong.
- Don't substitute another script face for Caveat. The casual ballpoint voice is part of the system; Lobster, Pacifico, etc. land elsewhere.
- Don't introduce a third brand color. Khaki + green + black + cream is the system. Adding blue or red breaks the earth-and-forest palette. The chip palette extension (orange / pink / blue / red) is reserved for categorical chip tags inside tabular ledgers — not for general accents.
- Don't use green-on-khaki for inline highlights. Inline marker swipes are black-on-khaki; green inline reads as a typo.
- Don't tilt elements more than ±8°. Beyond that, hand-placed becomes broken.
- Don't put body text larger than 18px. The zine column-density register depends on small body type (13–16px). Modern 20px+ body reads as overscaled.
- Don't use pure white (#FFFFFF) for cards. The cream (`{colors.white}` #F4EFE6) maintains the paper-on-paper register; pure white reads as digital.
## Responsive Behavior
The system targets `100vw × 100vh` and uses `clamp()` throughout for fluid scaling. A single media query at `max-width: 768px` reflows multi-column layouts to single-column, removes inter-column border rules and replaces them with bottom-borders, and reduces slide padding to 32px.
### Scaling Behavior
- Display headlines scale from 48px at minimum to 140–160px at maximum.
- Body text scales from 13px to 16–18px.
- Padding scales from 32px (mobile) to 60–80px (desktop).
- Borders, tape sizes, and stamp rotations are fixed — they do not scale with viewport.
### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, `Space`, `Enter`, `PageDown`, or a click on the right half of the viewport.
- Slides reverse via `ArrowLeft`, `ArrowUp`, `PageUp`, or a click on the left half.
- The active slide carries the `.active` class; inactive slides are at opacity 0 with `translateY(20px)`.
- Touch swipe horizontal advances/reverses on mobile.
- The nav hint at bottom-center fades in on `body:hover` (0.4s opacity).
### Print Behavior
No `@media print` rule is defined. The deck is web/viewport-first.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headline / Statement / Title / Number / Drop-cap / Label-eyebrow | Bebas Neue (400) | **思源宋体 Noto Serif SC** | 900 |
| Body / Body-md / Label-spaced | Space Grotesk (400 / 600) | **思源宋体 Noto Serif SC** | 400 (body), 600 (label) |
| Hand-script (Caveat) — Latin only | Caveat (400 / 600) | *(no CJK substitute)* | n/a |
### Mixed-Content Strategy
**Strategy A — single CJK family (思源宋体 Noto Serif SC) carries every typeset role.** Bebas Neue's condensed-industrial-uppercase voice has no Chinese sans equivalent that preserves the heavy poster weight without reading as a clichéd kanji-style display. Noto Serif SC at weight 900, however, carries genuine print-press weight that maps to the zine register: the deep serif strokes echo letterpress and woodblock printing, which is *closer* to the system's mid-century-activist-poster aesthetic than any Chinese sans would be. Pairing Latin Bebas + Chinese Noto Serif SC reads as "translated edition of the same zine," not as two competing systems. For body, the same family at weight 400 sits comfortably at small sizes (13–16px) and preserves the magazine column density.
### 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+Serif+SC:wght@400;600;700;900&display=swap" rel="stylesheet">
```
Then append `'Noto Serif SC'` to the appropriate font stacks:
```css
/* Display roles */
font-family: 'Bebas Neue', 'Noto Serif SC', sans-serif;
/* Body roles */
font-family: 'Space Grotesk', 'Noto Serif SC', sans-serif;
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence
### Aesthetic Notes for This System
- **The 0.02–0.04em positive tracking that defines Bebas display must drop to 0** on CJK. Tracked Chinese characters look broken — the spacing visually divides each character into a separate word. The compression-and-tracking signature of Bebas does not transfer; lean on weight 900 alone to carry the display voice.
- **Display line-height must open from 0.85–0.95 to 1.15–1.25.** Bebas's tight line-height is a Latin-display convention; CJK characters fully occupy their em-box and need vertical breathing room.
- **Drop caps need re-thinking.** A Bebas drop cap floats left of body text; a Noto Serif SC drop cap at the same size (`clamp(48px, 6vw, 80px)`) in `{colors.green}` works visually but lacks the editorial-tradition resonance — Chinese typography has historically not used drop caps. Either retain the treatment as a Western-editorial nod, or replace with a green vertical sidebar (3px wide, green fill) running alongside the opening paragraph.
- **Inline highlights, ribbon bars, and stamp marks all translate cleanly** — they are color-block treatments, not glyph-dependent.
- **Hand-script Caveat is the system's "human voice" — and has no Chinese equivalent that preserves the ballpoint-cursive personality.** Treat Caveat moments as Latin-only: attributions in Latin, side notes in Latin even on otherwise-Chinese slides, RSVP form fills in Latin. The contrast between Chinese typeset body and Latin handwritten margin notes can actually deepen the zine voice (it reads as "translator's annotation," which fits the small-press register).
- **Editorial body sizes (13–16px) still apply** — Noto Serif SC at this size reads as dense magazine column text, which is correct for the zine register.
### Known CJK Gap
The system's three-face contrast (Bebas display + Space Grotesk body + Caveat hand-script) is a Latin-typographic argument; collapsing it to a single CJK serif loses one rhythm and gains another. The decision to use a serif (Noto Serif SC) rather than a sans (Noto Sans SC) is deliberate — the zine's mid-century printed-press lineage maps better to Chinese serif tradition than to Chinese geometric sans. A deck that mixes Chinese and English will need to accept that the English Bebas voice and the Chinese Serif voice are different registers; this is unavoidable in any heavy-poster CJK adaptation.
## Iteration Guide
1. Every new slide carries the SVG grain overlay at 0.07 opacity. Removing the grain breaks the zine voice immediately.
2. Any new headline uses Bebas Neue uppercase, weight 400, tracking 0.02–0.04em. For the primary slide moment reach for `{typography.headline}` in `{colors.green}`; for splits or columns where the headline pairs with body, use `{colors.black}`.
3. Any new body uses Space Grotesk at 13–16px (or 14–18px for lead body). Line-height 1.6–1.7. Don't enlarge body beyond 18px.
4. Any new eyebrow label uses `{typography.label-eyebrow}` (Bebas Neue, 14–18px, 0.2em tracking) in `{colors.green}` for the most-emphasized eyebrow; switch to `{typography.label-spaced}` (Space Grotesk weight 600, 0.25em tracking) for secondary labels.
5. Any new card uses a 3px solid black border on white-cream or khaki background. For hero callouts, add the 12px-offset green slab via `::before` (`{components.card-offset}`).
6. Any new editorial column may carry a drop cap — green Bebas Neue, floated left, line-height 0.8. Drop caps are the editorial fingerprint.
7. Any new statement / quote slide pairs a Bebas Neue uppercase quote with a Caveat hand-script byline. The byline is not optional.
8. Any collage composition uses 3px-bordered collage pieces at small rotations (-5° to +5°), with translucent tape pieces at sharp angles overlapping the joints. Cycle backgrounds: green, white-cream, khaki-dark, black-inverted.
9. Any tabular ledger uses the `{components.ledger-row}` pattern with header underline at 1.5px and body row dividers at 1px hairline. Categorical tags use mono-font `{components.chip}` in green or the categorical chip palette.
10. Status / approval stamps use `{components.stamp-mark}` — black background, green text, green 2px border, rotated -8°. Reserve for moments that earn a stamp; overuse degrades the signal.
## Known Gaps
- The system loads three Google Fonts (Bebas Neue, Caveat, Space Grotesk) from a CDN. Bebas Neue is single-weight (400 only); attempting to use a heavier weight will fall back. Self-hosting is recommended for production.
- The grain overlay is an inline SVG data URI with `feTurbulence` — rendering will vary slightly across browsers, especially older Safari and Firefox versions.
- The paper-on-paper offset block depends on a `::before` pseudo-element with `z-index: -1`. Cards must have `position: relative` and the parent must not clip overflow, or the offset slab will be cut off.
- The chip color extension on ledger rows uses red / pink / orange / blue / green — pulled in only for categorical tagging inside tables. These colors are not part of the general system palette and should not appear elsewhere in a slide composition.
- The Caveat hand-script face has a strong cultural register (casual American handwriting). It does not pair well with non-Latin scripts; a CJK or Cyrillic deck would need a different hand-script substitution.
- The `body:hover` fade-in on the nav hint does not trigger on touch devices, which means mobile users may never see the nav hint. Treat the hint as desktop-only chrome.
- The closing slide uses a `{colors.black}` background with `{colors.bg}` (khaki) text. The grain overlay still applies but is much less visible at 0.07 opacity over black — the print register is weaker on the closing slide than on khaki-background slides.
- The form-field RSVP card uses hand-drawn underscores (`_________`) as the "blank line" — these are character-based, not rendered as actual `<input>` underlines, and will not align perfectly across system fonts.
# Retro Zine Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/retro-zine/design.md`
- Preview card: `bold-template-pack/templates/retro-zine/preview.md`
## Selection Metadata
- Slug: `retro-zine`
- Tagline: Beige paper with green accent and Bebas Neue + Caveat: a riso-printed zine in HTML form.
- Mood: crafted, lo-fi, underground, warm-retro
- Tone: scrappy, warm, intentional, DIY
- Formality: medium-low
- Density: medium
- Scheme: light
- Best for: Anything that should feel printed, lo-fi, and crafted: indie zines and publications, music / arts brands, creator portfolios, small-batch craft launches, community decks. Also a great underdog choice for tech, research, or business decks that want a riso-print warmth instead of digital polish.
- Avoid for: Contexts that demand digital-native polish or fast modern-tech energy — the layered zine aesthetic intentionally feels handmade.
## Visual Snapshot
A risograph-zine editorial system on warm khaki paper with a deep forest-green accent and ink-black structure. Display type runs in Bebas Neue (condensed industrial sans, uppercase, generously tracked); body type runs in Space Grotesk at weight 300–500; handwritten emphasis runs in Caveat. A subtle SVG grain overlay sits over every slide, reinforcing the printed-paper feel. The aesthetic borrows from independent press, mid-century activist posters, and DIY zine culture: slightly rotated stamp marks, masking-tape pieces in collage layouts, drop caps, and offset paper-on-paper shadows. The effect is hand-printed editorial — warm but disciplined, confident but tactile.
Retro Zine is a risograph-zine editorial system on a warm khaki canvas ({colors.bg} — #C8B99A) with deep forest-green ({colors.green} — #008F4D) as the meaningful accent and ink-black ({colors.black} — #1A1A1A) as the structural color. The aesthetic borrows from independent press culture, mid-century activist posters, and DIY zine layouts: condensed industrial display type, hand-script emphasis, slightly rotated stamps, masking-tape collage marks, drop caps, and a print-grain overlay that ties every surface to a printed-paper register.
## Preview Ingredients
- Palette: bg #C8B99A; bg-dark #B8A98A; green #008F4D; green-light #00A85D; black #1A1A1A; white #F4EFE6
- Typography: See full design doc after selection.
- Signature move: Warm khaki paper canvas ({colors.bg}) + deep forest-green accent ({colors.green}) + ink-black structure ({colors.black}).
- Signature move: An SVG grain overlay ({components.grain-overlay}) sits over every slide at 0.07 opacity, reinforcing the printed-paper register.
- Signature move: Bebas Neue uppercase + tracked for every display moment; Space Grotesk at small sizes for body; Caveat for hand-script emphasis.
- Signature move: 3px solid black structural borders divide regions; 2px and 1.5px borders subdivide.
- Signature move: Paper-on-paper offset cards: green slab sits 12px behind a white card via ::before.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Sakura Chroma
description: A cassette-package editorial system on warm cream paper with a six-color primary palette and warm-brown ink. Display type runs in Big Shoulders Display (condensed industrial display sans at weight 900); body in Albert Sans; tabular and tag content in JetBrains Mono; occasional Japanese accents in Noto Sans JP. The aesthetic borrows from 1970s consumer cassette packaging, Japanese print catalogues, and lo-fi product zines: petal-cluster blob clusters, diagonal multi-color ribbon bands, 12-point starburst seals, red rectangular stamps, and tracked uppercase micro-labels. The effect is hand-curated industrial editorial — warm but disciplined, playful but tightly typeset, with the cassette as its visual metaphor.
colors:
paper: "#F1E6CB"
paper-dk: "#E5D6B0"
ink: "#3A2516"
red: "#E5392A"
pink: "#E54489"
orange: "#F09131"
green: "#3D9F47"
blue: "#3F8BC4"
yellow: "#F0BC2A"
color-aliases:
line: ink
typography:
disp-hero:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(120px, min(14vw, 22vh), 280px)"
fontWeight: 900
lineHeight: 0.84
letterSpacing: -0.025em
disp-statement:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(70px, min(8.4vw, 14vh), 168px)"
fontWeight: 900
lineHeight: 0.86
letterSpacing: -0.022em
disp-title:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(80px, min(9vw, 14vh), 180px)"
fontWeight: 900
lineHeight: 0.86
letterSpacing: -0.022em
disp-lockup:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(56px, min(7vw, 11vh), 130px)"
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.015em
disp-section:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(52px, min(5.6vw, 9vh), 100px)"
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.018em
disp-quote:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(48px, min(5.4vw, 9vh), 110px)"
fontWeight: 900
lineHeight: 0.92
letterSpacing: -0.018em
disp-quote-lg:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(56px, min(6.4vw, 10.5vh), 130px)"
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.018em
disp-brand:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(32px, min(3.4vw, 5.4vh), 56px)"
fontWeight: 900
lineHeight: 0.92
letterSpacing: -0.02em
disp-card-name:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(28px, min(2.6vw, 4.6vh), 48px)"
fontWeight: 900
lineHeight: 0.94
letterSpacing: -0.012em
num-hero:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(110px, min(11vw, 18vh), 240px)"
fontWeight: 900
lineHeight: 0.86
letterSpacing: -0.025em
num-md:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(70px, min(7vw, 11vh), 150px)"
fontWeight: 900
lineHeight: 0.86
letterSpacing: -0.02em
ttl-row:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(22px, 1.7vw, 30px)"
fontWeight: 700
lineHeight: 1.1
letterSpacing: -0.005em
body:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(14px, 1vw, 17px)"
fontWeight: 400
lineHeight: 1.5
body-md:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(14px, 0.95vw, 15px)"
fontWeight: 400
lineHeight: 1.4
body-emphasis:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(15px, 1.1vw, 20px)"
fontWeight: 600
lineHeight: 1.4
micro:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(12px, 0.9vw, 14px)"
fontWeight: 700
lineHeight: 1.2
letterSpacing: 0.16em
textTransform: uppercase
micro-lg:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(12px, 0.9vw, 14px)"
fontWeight: 700
lineHeight: 1.2
letterSpacing: 0.2em
textTransform: uppercase
micro-xl:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(12px, 0.92vw, 14px)"
fontWeight: 700
lineHeight: 1.2
letterSpacing: 0.32em
textTransform: uppercase
micro-spec:
fontFamily: "'Albert Sans', sans-serif"
fontSize: "clamp(14px, 1.1vw, 20px)"
fontWeight: 700
lineHeight: 1.2
letterSpacing: 0.04em
mono:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "clamp(11px, 0.78vw, 12px)"
fontWeight: 400
lineHeight: 1.3
letterSpacing: 0.02em
mono-md:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "clamp(14px, 0.95vw, 16px)"
fontWeight: 400
lineHeight: 1.3
letterSpacing: 0.02em
mono-tag:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "clamp(12px, 0.85vw, 14px)"
fontWeight: 400
lineHeight: 1.0
letterSpacing: 0.04em
jp:
fontFamily: "'Noto Sans JP', sans-serif"
fontSize: "inherit"
fontWeight: 500
lineHeight: inherit
stamp-text:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(20px, 1.6vw, 28px)"
fontWeight: 900
lineHeight: 1.0
letterSpacing: 0.02em
seal-text:
fontFamily: "'Big Shoulders Display', sans-serif"
fontSize: "clamp(22px, 2vw, 38px)"
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.01em
spacing:
frame-inset: "clamp(36px, 3.6vw, 72px)"
frame-inset-bottom: "clamp(72px, 7vh, 110px)"
topbar-gap: "clamp(12px, 1.4vh, 22px)"
card-pad-x: "clamp(14px, 1.4vw, 20px)"
card-pad-y: "clamp(16px, 1.7vw, 24px)"
grid-gap: "clamp(16px, 1.6vw, 26px)"
col-gap: "clamp(28px, 3vw, 56px)"
pagenum-inset: "clamp(20px, 2.2vh, 36px) clamp(24px, 2.2vw, 44px)"
canvas:
width: 100vw
height: 100vh
components:
paper-texture:
backgroundImage: "radial-gradient(circle at 1px 1px, rgba(58,37,22,0.55) 1px, transparent 1.6px)"
backgroundSize: "4px 4px"
opacity: 0.16
zIndex: 1
description: "Subtle 4px-period halftone-dot paper texture sitting over every slide stage at 16% opacity. Drawn as a 1px-period radial-gradient. Required — it is the paper-grain that anchors every flat color block in the print register."
petals-cluster:
description: "A decorative cluster of 4–5 overlapping perfect circles (each `aspect-ratio: 1/1, border-radius: 50%`) in the primary palette colors. Circles overlap and tile within a bounded container. Used as a brand mark, decorative anchor in slide corners, or quote-page ornament."
ribbon-band:
height: "clamp(40px, 6vh, 96px)"
width: "160% (oversize so rotation clears the frame)"
transform: "rotate(-22deg) or rotate(22deg)"
description: "A bundle of 5 stacked solid-color horizontal bars (pink, orange, yellow, green, blue) rotated -22° or +22° to sweep diagonally across a region. Echoes the cassette-label color-stripe motif. Anchored to one edge of the slide and bleeds off the opposite edge."
ribbon-single:
height: "16–18%"
width: "160%"
transform: "rotate(±22deg)"
description: "A single solid-color ribbon in a multi-color stack; each ribbon is positioned with its own top/bottom percentage so the stack reads as parallel rays."
rosette-seal:
width: "clamp(60px, 6vw, 110px)"
aspectRatio: "1 / 1"
background: "{colors.ink}"
color: "{colors.paper}"
clipPath: "32-point starburst polygon"
description: "12+ point starburst clip-path shape filled ink with cream text. Used as an authority seal or volume marker. Always carries a 1–4 character glyph (a number, two-letter abbreviation, or short word) in Big Shoulders 900."
red-stamp:
background: "{colors.red}"
color: "{colors.paper}"
padding: "clamp(8px, 1vh, 14px) clamp(12px, 1.4vw, 22px)"
transform: "rotate(-3deg) or rotate(0)"
fontFamily: "'Big Shoulders Display', sans-serif"
fontWeight: 900
description: "Red rectangular stamp with cream text, optionally rotated -3°. Used for status badges (COMPLETE, AS SEEN ON, LIMITED) and product callouts."
card-product:
border: "1.5px solid {colors.ink}"
background: "{colors.paper}"
overflow: hidden
description: "Vertical product card with a 1.5px ink border, a colored topstrip header band, and a stacked body of name + description + extras + monospaced spec rows. The catalogue grid's primary unit."
card-topstrip:
height: "clamp(18px, 2vh, 32px)"
description: "Colored horizontal band running the full width of a product card's top — fills in red, pink, orange, or blue depending on the card variant. Reads as a Pantone color tab."
spec-checklist:
description: "Vertical column of inline rows with a 14–20px square ink-bordered box (filled or empty) followed by a small caps label (COLOR, LO-FI, STEREO, LP). Echoes the cassette package's feature-spec checklist."
bar-eq:
bgUntint: "rgba(58, 37, 22, 0.10)"
borderUntint: "rgba(58, 37, 22, 0.22)"
description: "Equalizer-style bar chart. Each column is a stack of 6 equal-height tiles (segments). 'On' segments fill with one of the primary colors (red, pink, orange, yellow, green, blue) per column; 'off' segments fill with a translucent ink tint. column-reverse stacking means on-segments stack from the bottom up, like a VU meter."
ledger-row:
gridColumns: "96px 1.4fr 0.9fr 0.6fr 64px"
paddingY: "clamp(10px, 1.2vh, 18px)"
borderBottom: "1px solid rgba(58,37,22,0.22)"
description: "5-column tabular row pattern: date | title | edition | chip | nr indicator. Header row uses a 1.5px ink border-bottom; body rows use 1px hairline ink-alpha dividers."
chip:
padding: "4px 10px"
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "11–12px"
color: "{colors.paper}"
textTransform: uppercase
letterSpacing: 0.06em
description: "Mono-font color chip tagging a ledger row's category. Background pulls from red, pink, orange, blue, or green."
topbar-rule:
borderBottom: "1.5px solid {colors.ink}"
paddingBottom: "clamp(12px, 1.4vh, 22px)"
description: "Section header underline pattern. A title (Big Shoulders 900 with optional red em-emphasis) on the left aligned-end with a tracked-caps label on the right, separated from the body by a 1.5px ink rule."
qbody-box:
background: "{colors.paper}"
border: "1.5px solid {colors.ink}"
boxShadow: "8px 8px 0 {colors.ink}"
padding: "clamp(20px, 2.4vh, 40px) clamp(28px, 2.6vw, 48px)"
description: "Quote body container with a 1.5px ink border and a hard 8px ink offset shadow. Sits on top of diagonal ribbons as a paper-on-ribbons callout."
petal:
aspectRatio: "1 / 1"
borderRadius: "50%"
description: "A single perfect circle in one of the primary colors. The atomic unit of petal-clusters and scattered blobs. Always perfectly round — never an ellipse."
pagenum:
fontFamily: "'JetBrains Mono', ui-monospace, monospace"
fontSize: "clamp(11px, 0.82vw, 13px)"
color: "{colors.ink}"
letterSpacing: 0.06em
description: "Bottom-right page indicator — mono font, formatted NN / TT. Required on every content slide."
nb-checkbox:
width: "clamp(14px, 1.1vw, 20px)"
aspectRatio: "1 / 1"
border: "2px solid {colors.ink}"
checkedFill: "{colors.ink}"
checkedMarker: "× (cream-colored multiplication sign in Big Shoulders 900)"
description: "Ink-bordered square checkbox used in spec-checklists and the cover footer. Checked state fills ink and centers a cream multiplication-sign glyph (not a checkmark)."
---
## 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
Sakura Chroma is a **cassette-package editorial system** that treats every slide as a printed product page from a small Japanese audio-products catalogue. The visual metaphor is total: petal-cluster blob marks, diagonal multi-color ribbon bands, 12-point starburst seals, red rectangular stamps, mono-font spec rows, color-coded chips, and equalizer-style bar charts. Everything reads as if pulled from the back-page spread of a 1970s consumer-audio brochure — warm, hand-curated, industrially typeset.
The typeface stack pairs four faces with distinct functional roles. **Big Shoulders Display** is the display voice — a condensed industrial sans at weight 900 with tight negative letter-spacing (-0.012em to -0.025em). It carries every display moment: hero numerals, statements, brand lockups, card names, section titles. Its compressed verticality and heavy weight give the system its loud, catalogue-front voice. **Albert Sans** is the body voice — a clean modern humanist sans at weight 400–700 for body paragraphs, micro-labels, and spec captions. **JetBrains Mono** is the tabular voice — used for spec rows, page numbers, dates, chips, equalizer ticks, and any moment that needs to read as "data" rather than as "editorial." **Noto Sans JP** is the cultural accent — used for occasional Japanese characters (限定版 "limited edition") that signal the Matsumoto-workshop voice. Together the four faces compose as "industrial display + clean body + monospaced data + Japanese spice."
The color philosophy is **warm-cream paper + ink-brown structure + six-color primary accent set**. The paper (`{colors.paper}` — #F1E6CB) is a warm cream, slightly darker than typical bone-white, with a darker tonal sibling (`{colors.paper-dk}` — #E5D6B0) for layered surfaces. The ink (`{colors.ink}` — #3A2516) is a deep warm brown rather than pure black, giving every type and border a print-on-paper warmth. Six primary colors (`red`, `pink`, `orange`, `yellow`, `green`, `blue`) appear as petal-cluster fills, ribbon bands, card topstrips, equalizer-bar fills, chip backgrounds, and red rectangular stamps. The reds and pinks dominate as emphasis colors; the orange / yellow / green / blue ladder serves as the categorical accent set.
Depth comes from **hard offset shadows** (8px 8px 0 ink), **paper-grain texture**, and **color-block layering** — not blurred drops. The signature treatments: the qbody-box (quote callout) carries an 8px hard ink-colored shadow with zero blur; every slide carries a 4px-period halftone-dot paper texture at 16% opacity that grounds every color block in the print register; diagonal multi-color ribbon bands sweep behind content as the system's most distinctive atmospheric layer.
**Density philosophy: medium-high.** The catalogue register depends on visual richness — product-card grids with 4 stacked cards each holding name + description + spec rows, ledger tables with 7+ rows, dashboards combining hero stats + equalizer charts, cover spreads stacking brand lockup + petals + ribbons + hero numeral + spec checklist + footer. A slide with only a single centered headline reads as a manifesto moment (deliberate sparsity in service of impact); every other slide should feel like a packed catalogue page. The correct density is "every region is doing concurrent work" — a topbar with title + meta-label, a body with primary visual + secondary panels, often a chip / stamp / seal as decorative punctuation.
**Key Characteristics:**
- Warm cream paper canvas (`{colors.paper}`) with warm-brown ink (`{colors.ink}`) as structure and six primary accent colors.
- A 4px-period halftone-dot paper texture (`{components.paper-texture}`) sits over every slide at 16% opacity. Required.
- Big Shoulders Display weight 900 with negative tracking for every display moment; Albert Sans for body; JetBrains Mono for tabular / data; Noto Sans JP for Japanese accents.
- Petal-cluster blob marks (4–5 overlapping perfect circles) as the signature decorative element.
- Diagonal multi-color ribbon bands (5 stacked colored bars at -22° or +22°) as atmospheric layering.
- 32-point starburst seal (`{components.rosette-seal}`) and red rectangular stamps (`{components.red-stamp}`) as authority marks.
- Hard offset shadows: 8px 8px 0 ink on quote callouts; no blur, no soft drops anywhere.
- Catalogue product cards with colored topstrip + name + description + dashed-rule + mono spec rows.
- Equalizer bar charts where each column stacks 6 tiles and "on" segments stack from the bottom up like a VU meter.
- Page numbers on every content slide in JetBrains Mono at bottom-right.
## Colors
### Palette
- **Paper** (`{colors.paper}` — #F1E6CB): The warm cream canvas. The default surface for every slide. Slightly darker and warmer than typical off-white, giving the deck a printed-paper warmth.
- **Paper Dark** (`{colors.paper-dk}` — #E5D6B0): A slightly darker tonal sibling of the canvas. Used for layered surfaces, half-region backgrounds, and where one paper region needs to read as sitting beneath another.
- **Ink** (`{colors.ink}` — #3A2516): Deep warm-brown ink. The structural color — all body text, all borders, all dividers, all hard-offset shadow color, all seal fills, all topbar rules. Slightly cool brown rather than pure black so it sits as warm ink on warm paper.
- **Red** (`{colors.red}` — #E5392A): The primary emphasis color and stamp color. Used for inline `em` emphasis inside Big Shoulders display headlines, for the red rectangular stamps, for catalogue-card topstrips on the first card, for hero numerals on data slides, and as the first ribbon-band color.
- **Pink** (`{colors.pink}` — #E54489): A bright magenta-pink. Used as the lockup-bar background on cover hero lockups, as a ribbon band color, as card-topstrip color for the second variant, and as a chip background.
- **Orange** (`{colors.orange}` — #F09131): A warm sunset orange. Used as a petal color, ribbon-band color, card-topstrip color for the third variant, and chip background.
- **Yellow** (`{colors.yellow}` — #F0BC2A): A mustard-warm yellow. Used as a petal color, ribbon-band color. Reserved as a categorical accent.
- **Green** (`{colors.green}` — #3D9F47): A medium grass green. Used as a petal color, ribbon-band color, chip background, and equalizer bar color.
- **Blue** (`{colors.blue}` — #3F8BC4): A warm mid-blue. Used as a petal color, ribbon-band color, card-topstrip color for the fourth variant, chip background, and as the second hero statistic color when the primary red statistic needs a paired counterpart.
### Defaults
- **Default surface background**: `{colors.paper}` — every slide opens on warm cream paper.
- **Default headline color**: `{colors.ink}` — display headlines are warm-brown ink, not red or another accent. Red appears only as inline `em` emphasis inside an ink headline.
- **Default body text color**: `{colors.ink}`.
- **Default border color**: `{colors.ink}` — every structural border is warm-brown ink, no exceptions.
- **Default tabular / mono text color**: `{colors.ink}`. Mono rows occasionally use `opacity: 0.7` on key labels for visual hierarchy.
- **Default emphasis color (inline `em` inside display headlines)**: `{colors.red}` for body and catalogue spreads; `{colors.blue}` for quote spreads when the body's color story already includes red.
- **Default hero numeral color**: `{colors.red}` — large data-slide statistics are red. Pair with `{colors.blue}` for a second statistic if two stats appear together.
- **Default stamp color**: `{colors.red}` background with `{colors.paper}` text on every red rectangular stamp.
- **Default seal color**: `{colors.ink}` background with `{colors.paper}` text on every starburst seal.
- **Default text color on `{colors.red}`, `{colors.pink}`, `{colors.orange}`, `{colors.green}`, `{colors.blue}` surfaces**: `{colors.paper}` (cream) — the only color inversion in the system.
- **Default text color on `{colors.ink}` surfaces**: `{colors.paper}` (cream) for inversions.
- **Default chip palette ordering** (for categorical chips in ledgers / tables): red → pink → orange → blue → green.
The six primary colors have **no fixed semantic meaning** (red is not "danger," green is not "success"). They serve as a categorical accent set — pick whichever color suits the composition. The exception is `{colors.red}` for emphasis: it carries an "attention" register that the cool colors do not, so reserve it for inline `em` and for the most-emphasized hero numerals.
## Typography
### Font Family
The system has four Google Fonts each with a distinct functional role:
- **Big Shoulders Display** (display): Condensed industrial sans-serif at weight 700 and 900. Used for every display moment — headlines, statements, hero numerals, brand lockups, card names, seal text, stamp text, ledger row titles. Always with negative letter-spacing (-0.012em to -0.025em). Its tall narrow condensed forms are the entire system's visual identity.
- **Albert Sans** (body): Clean modern humanist sans at weights 400, 500, 600, 700. Used for body paragraphs (weight 400), descriptions (weight 400), tracked-caps micro-labels (weight 700), and emphasis body (weight 600–700). The neutral counterpoint to Big Shoulders' expressiveness.
- **JetBrains Mono** (data): Monospace at weights 400, 500. Used for spec rows in product cards, date tags in ledgers, page numbers, equalizer-tick labels, chip text, navigation hints, meta tags. Any moment that reads as "data" rather than "editorial."
- **Noto Sans JP** (cultural accent): Japanese sans at weight 500, 700. Used sparingly for Japanese characters (限定版, 漢字, 平仮名) embedded in cover footers and brand marks. Provides the Matsumoto-workshop cultural register.
Italic does not exist. Underline does not exist. Emphasis is achieved by inline `<em>` (color shift to red or blue without italic style), by weight (Albert Sans 400 → 700), or by switching face (Albert Sans body → Big Shoulders display).
### Type Scale
| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.disp-hero}` | 120–280px | Big Shoulders Display | 900 | Hero numeral on a cover spread |
| `{typography.disp-title}` | 80–180px | Big Shoulders Display | 900 | Oversized title on a colophon / closing spread |
| `{typography.disp-statement}` | 70–168px | Big Shoulders Display | 900 | Manifesto / single-statement spread |
| `{typography.disp-lockup}` | 56–130px | Big Shoulders Display | 900 | Brand lockup bar on cover |
| `{typography.disp-quote-lg}` | 56–130px | Big Shoulders Display | 900 | Large pulled quote |
| `{typography.disp-section}` | 52–100px | Big Shoulders Display | 900 | Section topbar title |
| `{typography.disp-quote}` | 48–110px | Big Shoulders Display | 900 | Standard pulled quote |
| `{typography.disp-brand}` | 32–56px | Big Shoulders Display | 900 | Brand sub-mark or wordmark |
| `{typography.disp-card-name}` | 28–48px | Big Shoulders Display | 900 | Product card name |
| `{typography.num-hero}` | 110–240px | Big Shoulders Display | 900 | Primary hero statistic |
| `{typography.num-md}` | 70–150px | Big Shoulders Display | 900 | Secondary statistic |
| `{typography.ttl-row}` | 22–30px | Big Shoulders Display | 700 | Ledger row title |
| `{typography.body-emphasis}` | 15–20px | Albert Sans | 600 | Lead paragraph or emphasized body |
| `{typography.body}` | 14–17px | Albert Sans | 400 | Standard paragraph body |
| `{typography.body-md}` | 14–15px | Albert Sans | 400 | Compact body inside cards |
| `{typography.micro-spec}` | 14–20px | Albert Sans | 700 | Spec-checklist label (lightly tracked) |
| `{typography.micro-xl}` | 12–14px | Albert Sans | 700 | Loosest tracked-caps micro-label (0.32em) |
| `{typography.micro-lg}` | 12–14px | Albert Sans | 700 | Tracked-caps eyebrow label (0.2em) |
| `{typography.micro}` | 12–14px | Albert Sans | 700 | Standard tracked-caps micro-label (0.16em) |
| `{typography.mono-md}` | 14–16px | JetBrains Mono | 400 | Tabular date or value |
| `{typography.mono}` | 11–12px | JetBrains Mono | 400 | Spec row, page number, equalizer tick |
| `{typography.mono-tag}` | 12–14px | JetBrains Mono | 400 | Chip tag text |
| `{typography.stamp-text}` | 20–28px | Big Shoulders Display | 900 | Red rectangular stamp text |
| `{typography.seal-text}` | 22–38px | Big Shoulders Display | 900 | Starburst seal text |
| `{typography.jp}` | inherit | Noto Sans JP | 500 | Japanese character accent |
### Defaults
- **Default size for a primary section headline (topbar context)**: `{typography.disp-section}` (52–100px clamp) in `{colors.ink}`.
- **Default size for a manifesto / centered-statement spread**: `{typography.disp-statement}` (70–168px clamp) in `{colors.ink}` with optional `<em>` color shift.
- **Default size for paragraph body**: `{typography.body}` (14–17px clamp).
- **Default size for a tracked-caps micro-label or eyebrow**: `{typography.micro}` (12–14px Albert Sans weight 700, 0.16em tracking, uppercase) in `{colors.ink}`.
- **Default size for a hero statistic**: `{typography.num-hero}` (110–240px clamp) in `{colors.red}`.
- **Default size for a tabular date or mono value**: `{typography.mono-md}` (14–16px) in `{colors.ink}`.
- **Default size for a page number**: `{typography.mono}` (11–12px) in `{colors.ink}`.
- **Default weight for any Big Shoulders Display element**: 900. (700 is reserved for `{typography.ttl-row}` — the ledger row title, which is the only sub-display moment in the system.)
- **Default weight for body**: 400; for micro-labels: 700; for emphasis body: 600–700.
When unsure between `{typography.disp-section}` and `{typography.disp-statement}` for the dominant text moment, choose `{typography.disp-section}` if the slide carries a topbar/body grid; choose `{typography.disp-statement}` if the slide is dedicated to a single centered statement.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every Big Shoulders Display element carries negative letter-spacing** (-0.012em to -0.025em). Default tracking on Big Shoulders reads as untreated; the negative tracking is what gives display type its compressed, catalogue-cover density.
- **Every micro-label is uppercase with significant tracking** (0.16em, 0.18em, 0.2em, or 0.32em depending on context). A micro-label without uppercase + tracking reads as a body fragment, not a label.
- **Every page number uses JetBrains Mono** in the `NN / TT` format. Page numbers are non-optional on every content slide and live at bottom-right.
- **Every inline `<em>` inside a Big Shoulders display headline switches color** to `{colors.red}` (default) or `{colors.blue}` (on quote spreads where red is overloaded). Never use italic style; the color shift is the entire emphasis device.
- **Every spec row uses JetBrains Mono.** A spec row in Albert Sans reads as a body sentence, not as catalogue data.
- **Every starburst seal uses the 32-point clip-path polygon** with `{colors.ink}` fill and `{colors.paper}` text. Variations in point count or simplification (e.g., 8-point burst, 16-point) break the seal-recognition signal.
- **Every red stamp uses `{colors.red}` background with `{colors.paper}` text** and Big Shoulders 900. Stamp text is always uppercase, always tracked positively (0.02em).
### Typography Principles
The system's typographic rhythm comes from **face-to-face contrast**: Big Shoulders display (loud, condensed, ink) → Albert Sans body (quiet, neutral, sentence case) → JetBrains Mono data (mechanical, tabular, fixed-width) → Noto Sans JP (cultural punctuation). A slide that uses only one face reads as flat; a slide that uses Big Shoulders + Albert Sans + JetBrains Mono together reads as catalogue-correct.
Line-height: tight on display (0.84–0.94), generous on body (1.4–1.5), tight on micro and mono (1.0–1.3). Inverting these breaks the rhythm.
## Layout
### Canvas System
The system targets `100vw × 100vh`. The deck is wrapped in a `.deck` grid with a centered `.stage` filling the viewport. Each `.slide` is absolutely positioned inset 0 with opacity 0; only the `.active` slide has opacity 1. Transitions are 280ms ease opacity fades. Navigation is JS-driven via arrow keys, space, PageUp/Down, Home/End, and touch swipe.
### Frame Inset Pattern
Most content slides follow a frame-inset pattern: a `.frame` div sits inset from the slide edges by `clamp(36px, 3.6vw, 72px)` on top/left/right and `clamp(72px, 7vh, 110px)` at bottom (to clear the page number). Inside the frame, a topbar pattern (title + meta-label + 1.5px ink rule) sits above a body region.
Cover, manifesto, and quote spreads break the frame pattern — they layer petals, ribbons, hero numerals, and lockups freely across the canvas without the topbar/body grid.
### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.frame-inset}` | 36–72px | Frame inset from slide edges |
| `{spacing.frame-inset-bottom}` | 72–110px | Frame bottom inset (clears page number) |
| `{spacing.topbar-gap}` | 12–22px | Topbar pad-bottom and section gap |
| `{spacing.grid-gap}` | 16–26px | Card grid inter-cell gap |
| `{spacing.col-gap}` | 28–56px | Two-column body gap |
| `{spacing.card-pad-x}` / `{spacing.card-pad-y}` | 14–20px / 16–24px | Product card body padding |
| `{spacing.pagenum-inset}` | 20–36px / 24–44px | Page number inset from bottom-right |
### Persistent Chrome
Two persistent elements:
- **Page number** at bottom-right of every content slide — JetBrains Mono 11–13px `NN / TT` format.
- **Nav hint** at fixed bottom-left — JetBrains Mono 10–12px text reading `← / → · space`, at 0.36 opacity.
The page number is part of every slide composition (not a global overlay); the nav hint is a single global element.
## Depth and Elevation
### Hard Offset Shadow (Primary Technique)
The system uses **hard offset shadows in ink** at exactly one value: `8px 8px 0 {colors.ink}` (zero blur, solid ink). Applied to the qbody-box (quote callout) and other elevated paper-on-ribbons elements that need to lift off a busy underlying composition. The shadow is rare — most cards and panels rely on borders alone for definition, and the 8px ink shadow is reserved for the moment that earns it.
### Paper-Grain Texture (Atmospheric Layer)
The `{components.paper-texture}` halftone-dot pattern sits over every slide at 16% opacity. It is not depth in the strict sense but provides the foundational textural ground that makes every flat color block read as ink on paper. Removing it breaks the print register immediately. Required on every slide.
### Color-Block Layering
Depth comes primarily from **layered colored regions**: ribbon bands behind hero numerals; petals behind brand lockups; topstrip color tabs on top of paper cards; red stamps over diagonal ribbons. The high-contrast accents projecting forward against the warm cream backdrop is the system's primary depth grammar.
### Border Definition
Most cards and panels rely on 1.5px ink borders for definition, not shadows. A 1.5px ink border around a paper card on the same paper background reads as elevated through the boundary alone.
### No Soft Shadows
The system uses **no blurred `box-shadow`** (other than the single 8px hard offset on qbody-box), no `drop-shadow` filters, no rgba shadow tints. A soft modern shadow on any element breaks the print catalogue aesthetic.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | All cards, all stamps, all topbars, all bodies, all chips, all ledger rows |
| 50% | Petals (perfect circles) — used inside petal-clusters and scattered blobs only |
| Polygon clip-path (32-point starburst) | Rosette seal — the only complex shape primitive |
The system has **no rounded corner radii** other than perfect circles (petals) and the polygon-clipped starburst (seal). Every other shape is strict rectangular or square.
### Border Weights
- **1.5px solid `{colors.ink}`** — the standard border weight on cards, topbar rules, ledger header rules, qbody-box, the cover frame's bottom rule, the cover footer's top rule.
- **2px solid `{colors.ink}`** — used on the spec-checklist checkbox borders.
- **1px solid `{colors.ink}`** — used inside the equalizer for the ticks/labels separator.
- **1px solid rgba(58,37,22, 0.22)** — used as the hairline ledger row body divider and as equalizer-segment off-state borders.
- **1px dashed `{colors.ink}`** — used as the dashed rule separating a product card's description from its mono spec rows.
Borders are always ink (warm brown). Colored borders do not exist in this system except as a chip's implicit background-border.
### Decorative Element Types
**Petal cluster** (`{components.petals-cluster}`) — A bounded container holding 4–5 perfectly-circular colored blobs that overlap. Each petal is positioned absolutely within the container as a percentage offset. The colors rotate across the primary palette (red, pink, orange, yellow, green, blue) — never all the same color. Used as a brand mark anchor in slide corners and as decorative ornament on quote spreads. The signature decorative element.
**Ribbon band** (`{components.ribbon-band}`) — A stack of 5 solid-colored horizontal bars rotated -22° or +22° to sweep diagonally across a region. Bars stack vertically with each ribbon at a different `top` percentage, creating a parallel-rays effect. Anchored to one slide edge, oversized to bleed off the opposite edge. The system's atmospheric layering signature.
**Rosette seal** (`{components.rosette-seal}`) — A 32-point starburst clip-path shape filled `{colors.ink}` with cream text. Carries a 1–4 character glyph: a year number ("26"), a volume number ("VOL 26"), or a 2-3 letter abbreviation. Used as authority mark on covers and closing colophons.
**Red rectangular stamp** (`{components.red-stamp}`) — A red rectangle with cream text and optional -3° rotation. Used for status badges (COMPLETE, AS SEEN ON) and product callouts. Always Big Shoulders 900 uppercase.
**Product card** (`{components.card-product}`) — Vertical card with a 1.5px ink border, a colored top strip (red / pink / orange / blue variant), and a stacked body: card name in Big Shoulders 900 → description in Albert Sans 400 → dashed-rule → mono spec rows. The catalogue grid's primary unit.
**Card topstrip** (`{components.card-topstrip}`) — A 18–32px tall solid-color band running the full width of a product card's top. Reads as a Pantone color tab; identifies the card's variant within the grid.
**Spec checklist** (`{components.spec-checklist}`) — Vertical column of `nb-checkbox` + tracked-caps label rows. Each row has a 14–20px ink-bordered square box (filled or empty, filled state shows a cream `×` glyph) followed by an uppercase tracked label.
**Ledger row** (`{components.ledger-row}`) — 5-column tabular row pattern: date (mono) | title (Big Shoulders 700) | edition (Albert Sans) | chip | nr indicator (square boxes). Header row uses 1.5px ink border-bottom; body rows use 1px hairline ink-alpha dividers.
**Chip** (`{components.chip}`) — Mono-font color block tagging a ledger row category. Background pulls from the primary palette (red, pink, orange, blue, green). Always cream text.
**Topbar rule** (`{components.topbar-rule}`) — Section header underline pattern: title (display) on left aligned-end with a tracked-caps meta-label on right, separated from the body by a 1.5px ink rule.
**Equalizer bar chart** (`{components.bar-eq}`) — 8-column grid where each column stacks 6 equal-height tiles (segments). `column-reverse` flex direction means the first segment in source order sits at the bottom; "on" segments stack from the bottom up like a VU meter. On-segment color is set per column (red, pink, orange, yellow, green, or blue); off-segments are translucent ink tint.
**Qbody-box** (`{components.qbody-box}`) — Quote callout container with 1.5px ink border and 8px hard ink shadow. Sits on top of diagonal ribbons.
**Brand lockup** — Big Shoulders 900 wordmark over Albert Sans 600 sub-mark, positioned absolutely near the cover petals.
## Do's and Don'ts
### Do
- Keep the paper-grain halftone-dot texture (`{components.paper-texture}`) on every slide at 16% opacity. It is the foundational print register; removing it makes the deck look like a flat web template.
- Use Big Shoulders Display at weight 900 with negative letter-spacing (-0.012em to -0.025em) for every display moment.
- Apply tracked uppercase to every micro-label — 0.16em standard, 0.2em for eyebrows, 0.32em for the loosest manifesto kicker. Default tracking reads as a body sentence.
- Set hero statistics in `{colors.red}` at Big Shoulders 900. Pair with `{colors.blue}` for a second statistic.
- Use inline `<em>` in display headlines to shift color (red default, blue on quote spreads). Never italicize.
- Compose petal-cluster blob marks (4–5 overlapping perfect circles in primary colors) as decorative anchors in slide corners.
- Sweep diagonal multi-color ribbon bands (-22° or +22°) behind hero content as atmospheric layering on cover and closing spreads.
- Place a page number on every content slide in JetBrains Mono at bottom-right (`NN / TT` format).
- Use JetBrains Mono for spec rows, dates, chips, and any tabular data — anything that should read as "data" instead of "editorial."
- Reserve the 32-point starburst seal and the red rectangular stamp for authority moments (covers, colophons, product callouts). They are signature marks; overuse degrades them.
### Don't
- Don't round any corner. Cards, stamps, chips, topbars — all strict rectangles. Petals (circles) and the starburst seal (polygon clip-path) are the only non-rectangular shapes.
- Don't use blurred `box-shadow`. The only shadow in the system is the 8px hard ink offset on quote callouts. Soft modern shadows break the print register.
- Don't substitute another display face for Big Shoulders Display. The condensed industrial 900 voice is the entire system identity.
- Don't substitute another mono face for JetBrains Mono. The tabular voice is part of the catalogue conceit.
- Don't use Big Shoulders Display for body paragraphs. It reads as overwrought at small body sizes.
- Don't use Albert Sans for display moments. Albert Sans is the neutral body face; display moments need Big Shoulders.
- Don't italicize for emphasis. Use inline `<em>` with red or blue color, or switch weight (Albert 400 → 700).
- Don't introduce a seventh primary color. The palette is locked at red / pink / orange / yellow / green / blue. Adding purple, cyan, or other hues breaks the catalogue color story.
- Don't fill a card border with a saturated accent color (red border, blue border). Borders are always ink.
- Don't omit the page number on a content slide. It is a non-optional editorial signal.
## Responsive Behavior
The system targets `100vw × 100vh` and uses `clamp()` throughout with `min(Xvw, Yvh)` patterns that combine viewport-width and viewport-height constraints. This produces fluid scaling across desktop sizes without responsive breakpoints. There is no defined mobile breakpoint — the deck is presentation-first.
### Scaling Behavior
- Display headlines scale via `min(Xvw, Yvh)` so they shrink when the viewport gets short, not only when it gets narrow.
- Body, mono, and micro labels scale within their clamp range based on viewport width.
- Petals, ribbons, seals, and stamps use `vw`/`vmin` units so they scale proportionally with the canvas.
- The 4px paper-grain texture period is fixed regardless of viewport.
### Presenter Behavior
- Slides advance via `ArrowRight`, `PageDown`, or `Space`.
- Slides reverse via `ArrowLeft` or `PageUp`.
- `Home` jumps to first, `End` to last.
- Touch swipe horizontal advances/reverses.
- The active slide carries the `.active` class; inactive slides are at opacity 0.
### Print Behavior
No `@media print` rule is defined.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headline / Statement / Hero numeral / Card name / Seal / Stamp / Lockup | Big Shoulders Display (900) | **站酷小薇体 ZCOOL XiaoWei** | regular (single weight) |
| Body / Body-md / Body-emphasis / Micro labels | Albert Sans (400 / 600 / 700) | **霞鹜文楷 LXGW WenKai** | regular |
| Tabular / Spec rows / Chips / Page numbers / Mono labels | JetBrains Mono (400 / 500) | **霞鹜文楷 LXGW WenKai** (or keep mono Latin-only for spec rows) | regular |
| Japanese accents | Noto Sans JP | *(unchanged)* | 500 / 700 |
### Mixed-Content Strategy
**Strategy A — display CJK + body CJK, each with its own character.** The cassette-package aesthetic is feminine-floral with industrial discipline, and the Chinese pairing should honor both halves. **ZCOOL XiaoWei (站酷小薇体)** is a graceful condensed display face with elegant high-contrast strokes — it echoes Big Shoulders Display's condensed verticality while carrying a softer, distinctly feminine voice that matches the petal-cluster decorative system. **LXGW WenKai (霞鹜文楷)** is a warm KaiTi-style body face based on Fontworks Klee — it has the friendly hand-curated quality that matches Albert Sans's role as the body voice, and reads beautifully at small sizes against the warm cream paper. Together the two CJK faces preserve the "industrial display + warm body" rhythm of the Latin system while landing the Chinese deck in a distinctly hand-curated, slightly-feminine register that suits Sakura Chroma's name and its floral motifs.
### Loading
```html
<link href="https://chinese-fonts-cdn.deno.dev/packages/zcool-xiaowei/dist/ZCOOLXiaoWei-Regular/result.css" rel="stylesheet">
<link href="https://chinese-fonts-cdn.deno.dev/packages/lxgwwenkai/dist/LXGWWenKai-Regular/result.css" rel="stylesheet">
```
Then append the CJK families to the appropriate font stacks:
```css
/* Display roles */
font-family: 'Big Shoulders Display', 'ZCOOL XiaoWei', sans-serif;
/* Body / micro roles */
font-family: 'Albert Sans', 'LXGW WenKai', sans-serif;
/* Mono roles (if used for CJK content) */
font-family: 'JetBrains Mono', 'LXGW WenKai', ui-monospace, monospace;
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence
### Aesthetic Notes for This System
- **The negative tracking on Big Shoulders display (-0.012em to -0.025em) must drop to 0** on CJK. ZCOOL XiaoWei is already a condensed face; negative tracking will collide glyphs.
- **The tracked-caps micro-labels (0.16em, 0.2em, 0.32em) have no CJK equivalent.** Drop tracking to 0 for CJK micro-labels and let the warm-brown ink color + bold weight carry the categorical-label signal. A "限定版 LIMITED EDITION" eyebrow can mix CJK + Latin in the same label — keep tracking 0 on the CJK characters and 0.16em+ on the Latin.
- **Inline `<em>` color shifts (to red or blue) work identically in CJK** — color emphasis is glyph-agnostic and lands beautifully on ZCOOL XiaoWei display headlines.
- **Petal clusters, ribbon bands, starburst seals, and red rectangular stamps are all glyph-agnostic** — they carry the system's industrial-catalogue voice equally well behind Chinese content.
- **The 32-point starburst seal carrying a 2–4 character glyph** works exceptionally well with a single Chinese character (限, 新, 季) at ZCOOL XiaoWei in `{colors.paper}` cream. The bold display weight makes the central glyph read as a maker's mark.
- **Spec rows in JetBrains Mono** present the trickiest decision: pure-Latin spec rows (`44.1 KHZ`, `LP / 33⅓`) preserve the catalogue conceit; localized spec rows in LXGW WenKai (`立体声`, `限定版`) read as a Chinese-market catalogue but lose the technical-spec voice. The right move is **mixed-language spec rows where Latin values stay mono and Chinese descriptors switch to LXGW WenKai inline.**
- **Noto Sans JP accents (限定版) remain unchanged** — Japanese characters share glyphs with Simplified Chinese in many cases but the Noto Sans JP rendering is intentional (Japanese-edition affect). On a Chinese-primary deck, swap to LXGW WenKai for these characters so they read as Chinese rather than as a Japanese loan.
### Known CJK Gap
ZCOOL XiaoWei is a single-weight face — there is no 900-equivalent. The Big Shoulders 900-weight loudness that defines the Latin display voice cannot be exactly matched. Compensate by reserving CJK display for moments where the soft elegance is welcome (cover spreads, quote slides) rather than where pure brutalist weight is needed (hero stats). For hero numerals, keep the figures in Latin numerals at Big Shoulders 900 — Chinese numerals (一二三四) don't carry the catalogue-cover statistical voice anyway.
## Iteration Guide
1. Every new content slide carries the paper-grain halftone-dot texture, a frame-inset region (36–72px from edges, 72–110px from bottom), and a page number at bottom-right.
2. Any new content slide that follows the frame pattern opens with a topbar: display-section title on the left, tracked-caps meta-label on the right, separated from the body by a 1.5px ink rule.
3. Any new headline uses Big Shoulders Display weight 900 with negative tracking. For section topbars use `{typography.disp-section}`; for single-statement spreads use `{typography.disp-statement}`; for hero numerals use `{typography.num-hero}` in red.
4. Any new body uses Albert Sans 400; tracked-caps labels use Albert Sans 700 uppercase with 0.16–0.32em tracking; tabular content uses JetBrains Mono 400.
5. Any new card uses a 1.5px ink border, optional colored topstrip (red / pink / orange / blue), and a body pattern of display name → Albert body → dashed-rule → mono spec rows.
6. Any new ledger / tabular pattern uses the 5-column ledger-row grid with header underline (1.5px ink) and hairline body dividers (1px ink-alpha). Categorical tags use mono chips with primary-palette backgrounds.
7. Any new decorative anchor uses a petal-cluster (4–5 overlapping perfect-circle petals in mixed primary colors). Avoid ellipses — petals are always perfectly round.
8. Any new authority mark uses the 32-point starburst seal (ink-filled, cream text) or the red rectangular stamp. Seals are formal; stamps are punchy.
9. Any inline emphasis inside a display headline uses `<em>` with color shift to `{colors.red}` (default) or `{colors.blue}` (when red is overloaded). Never italicize.
10. Atmospheric layering — diagonal ribbon bands at -22° or +22° behind hero content — appears on cover, closing, and stripe-spread moments. It is not a routine slide element; reserve it for spreads that earn atmospheric ambition.
## Known Gaps
- The system loads four Google Fonts (Big Shoulders Display, Albert Sans, JetBrains Mono, Noto Sans JP). Big Shoulders is multi-weight (500, 700, 800, 900); the system uses 700 and 900. Self-hosting recommended for production.
- The paper-grain texture is a CSS radial-gradient (not an SVG noise filter) so it tiles deterministically across browsers and is performant. The dot period (4px) is fixed and does not scale with viewport.
- The 32-point starburst clip-path polygon is hardcoded; modifying the seal shape requires rewriting the polygon point list. The system is consistent only because the same polygon is reused everywhere — switching to a different starburst polygon breaks visual cohesion.
- The diagonal ribbon bands use `transform: rotate(-22deg)` and oversize widths (160%) to bleed off the slide edges. On very tall viewports the ribbon coverage may look thinner than on standard 16:9 viewports.
- The equalizer bar chart uses `display: flex; flex-direction: column-reverse;` to stack on-segments from the bottom up. This is a subtle layout pattern that can be fragile under aggressive overrides — modifying the eq segments requires preserving the column-reverse behavior.
- Hero statistics use inline `<sub>` and inline-style `font-size` overrides for sub-units (`26K`, `61%`), which sidesteps the typography token system. New stats should follow the same pattern: oversized numeral + smaller inline unit at ~34% the numeral's size in ink color.
- Noto Sans JP is loaded but used only once (限定版 "limited edition" in the cover footer). If a deck contains no Japanese content, the font load is unused weight; consider removing the import for non-Japanese decks.
- The nav hint at bottom-left has very low opacity (0.36) and may be difficult to see at default presenter brightness. It is intended as ambient chrome, not as a prominent affordance.
# Sakura Chroma Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/sakura-chroma/design.md`
- Preview card: `bold-template-pack/templates/sakura-chroma/preview.md`
## Selection Metadata
- Slug: `sakura-chroma`
- Tagline: Vintage Japanese cassette-package aesthetic: cream paper, diagonal rainbow ribbons, condensed bold type, JIS-style spec checkboxes.
- Mood: retro, playful, kawaii-tech, warm, tactile, product-catalogue
- Tone: playful, confident, warm, tactile, 80s-Japanese-tech
- Formality: low
- Density: medium
- Scheme: light
- Best for: Anything that should feel like a vintage Japanese cassette package or a TDK / Sony / Sakura Color product catalogue: indie hardware brand decks, music-label release schedules, analog studio retrospectives, zine and magazine pitches, kawaii-tech product launches, creative-studio annual reports. Equally good for any deck wanting bold colour, condensed display type, and a tactile printed-product personality.
- Avoid for: Decks that need restrained, corporate, or quiet typography — the bold condensed lockups, ribbon stripes, and primary-colour palette are intentionally loud and product-page-y.
## Visual Snapshot
A cassette-package editorial system on warm cream paper with a six-color primary palette and warm-brown ink. Display type runs in Big Shoulders Display (condensed industrial display sans at weight 900); body in Albert Sans; tabular and tag content in JetBrains Mono; occasional Japanese accents in Noto Sans JP. The aesthetic borrows from 1970s consumer cassette packaging, Japanese print catalogues, and lo-fi product zines: petal-cluster blob clusters, diagonal multi-color ribbon bands, 12-point starburst seals, red rectangular stamps, and tracked uppercase micro-labels. The effect is hand-curated industrial editorial — warm but disciplined, playful but tightly typeset, with the cassette as its visual metaphor.
Sakura Chroma is a cassette-package editorial system that treats every slide as a printed product page from a small Japanese audio-products catalogue. The visual metaphor is total: petal-cluster blob marks, diagonal multi-color ribbon bands, 12-point starburst seals, red rectangular stamps, mono-font spec rows, color-coded chips, and equalizer-style bar charts. Everything reads as if pulled from the back-page spread of a 1970s consumer-audio brochure — warm, hand-curated, industrially typeset.
## Preview Ingredients
- Palette: paper #F1E6CB; paper-dk #E5D6B0; ink #3A2516; red #E5392A; pink #E54489; orange #F09131; green #3D9F47; blue #3F8BC4
- Typography: See full design doc after selection.
- Signature move: Warm cream paper canvas ({colors.paper}) with warm-brown ink ({colors.ink}) as structure and six primary accent colors.
- Signature move: A 4px-period halftone-dot paper texture ({components.paper-texture}) sits over every slide at 16% opacity. Required.
- Signature move: Big Shoulders Display weight 900 with negative tracking for every display moment; Albert Sans for body; JetBrains Mono for tabular / data; Noto Sans JP for Japanese accents.
- Signature move: Petal-cluster blob marks (4–5 overlapping perfect circles) as the signature decorative element.
- Signature move: Diagonal multi-color ribbon bands (5 stacked colored bars at -22° or +22°) as atmospheric layering.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Scatterbrain
description: A Post-it-note-and-cork-board presentation system. Every content block is a colored sticky note on a textured paper or cork surface, layered with red thumbtacks, masking tape, and decorative doodles. Display type runs in Shrikhand (a chunky decorative display serif) on every headline; body type runs in Zilla Slab (a friendly slab serif); handwritten emphasis runs in Caveat. The palette is pastel sticky-note colors (yellow, blue, pink, green, orange, purple) on cream paper / cork / warm gradient backgrounds. The aesthetic borrows from creative-workshop wall art, brainstorming boards, and indie-studio mood boards: scattered slight rotations, multiple background texture variants per slide, pin / tape / drop-shadow combinations. The effect is warmth, play, and tactile creative-process energy.
colors:
yellow: "#ffe066"
yellow-deep: "#ffd43b"
blue: "#a5d8ff"
blue-deep: "#74c0fc"
pink: "#ffc9c9"
pink-deep: "#ff9f9f"
green: "#b2f2bb"
green-deep: "#8ce99a"
orange: "#ffcc80"
purple: "#d0bfff"
cream: "#faf8f3"
paper: "#f7f5f0"
ink: "#2d2a26"
ink-light: "#5c5750"
shadow: "rgba(45, 42, 38, 0.15)"
shadow-deep: "rgba(45, 42, 38, 0.25)"
typography:
display-hero:
fontFamily: "'Shrikhand', cursive"
fontSize: "clamp(2.5rem, 5vw, 4.5rem)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
statement:
fontFamily: "'Shrikhand', cursive"
fontSize: "clamp(2rem, 4vw, 3.5rem)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
headline:
fontFamily: "'Shrikhand', cursive"
fontSize: "clamp(1.8rem, 3.5vw, 3rem)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
title:
fontFamily: "'Shrikhand', cursive"
fontSize: "clamp(1.3rem, 2.5vw, 1.8rem)"
fontWeight: 400
lineHeight: 1.1
letterSpacing: 0.02em
body:
fontFamily: "'Zilla Slab', serif"
fontSize: "clamp(1rem, 1.5vw, 1.25rem)"
fontWeight: 400
lineHeight: 1.7
list-item:
fontFamily: "'Zilla Slab', serif"
fontSize: "1.1rem"
fontWeight: 400
lineHeight: 1.6
handwritten:
fontFamily: "'Caveat', cursive"
fontSize: "clamp(1.2rem, 2vw, 1.6rem)"
fontWeight: 400
lineHeight: 1.4
handwritten-lg:
fontFamily: "'Caveat', cursive"
fontSize: "clamp(1.4rem, 2.5vw, 2rem)"
fontWeight: 600
lineHeight: 1.3
handwritten-sm:
fontFamily: "'Caveat', cursive"
fontSize: "clamp(1.2rem, 1.5vw, 1.4rem)"
fontWeight: 500
lineHeight: 1.3
label-script:
fontFamily: "'Caveat', cursive"
fontSize: "0.9rem"
fontWeight: 400
lineHeight: 1.2
letterSpacing: 0.15em
textTransform: uppercase
stat-value:
fontFamily: "'Shrikhand', cursive"
fontSize: "1.8rem"
fontWeight: 400
lineHeight: 1.1
caption-subtitle:
fontFamily: "'Zilla Slab', serif"
fontSize: "1.3rem"
fontWeight: 400
lineHeight: 1.6
spacing:
slide-pad: 3rem
post-it-pad-lg: "3rem 4rem"
post-it-pad-md: "2.5rem"
post-it-pad-sm: "1.5rem"
post-it-pad-statement: "3.5rem 4rem"
gap-lg: "3rem"
gap-md: "2.5rem"
gap-sm: "2rem"
canvas:
width: 100vw
height: 100vh
components:
bg-cork:
backgroundLayers: "radial-gradient ellipse + linear-gradient (warm browns) + SVG plus-sign pattern at 15% opacity"
description: "Cork-board background variant. Warm tan/brown tonal gradient with a faint pattern of small plus-sign marks suggesting cork texture. Used on slides that feel like 'a wall of pinned notes.'"
bg-paper:
backgroundLayers: "linear-gradient (cream) + 40px grid lines at 8% opacity"
description: "Desk-paper background variant. Cream gradient with a faint 40px grid overlay suggesting graph or notebook paper. Used on slides that feel like 'notes arranged on a desk.'"
bg-warm:
backgroundLayers: "multiple radial-gradients (yellow/blue/pink soft glows) + linear-gradient cream base"
description: "Warm gradient background variant. Cream base with soft-glow ellipses of yellow, blue, and pink suggesting morning light. Used on slides that need a softer, less-textured atmosphere."
grain-overlay:
backgroundImage: "SVG fractal-noise filter, 256×256 tile"
opacity: 0.04
zIndex: 9999
description: "Fixed full-viewport SVG grain texture above all content at 4% opacity. Reinforces the paper-and-cork tactile register. Always present."
post-it:
padding: "2rem"
boxShadow: "2px 3px 15px {colors.shadow}, 0 1px 3px {colors.shadow-deep}"
description: "Generic colored sticky-note base. Soft drop-shadow simulates the note's slight lift off the surface. Always carries a background color from the post-it palette (yellow, blue, pink, green, orange, purple, or white)."
post-it-yellow:
background: "linear-gradient(135deg, {colors.yellow} 0%, {colors.yellow-deep} 100%)"
description: "Yellow sticky variant. Soft 135° gradient from light to deep yellow."
post-it-blue:
background: "linear-gradient(135deg, {colors.blue} 0%, {colors.blue-deep} 100%)"
description: "Blue sticky variant."
post-it-pink:
background: "linear-gradient(135deg, {colors.pink} 0%, {colors.pink-deep} 100%)"
description: "Pink sticky variant."
post-it-green:
background: "linear-gradient(135deg, {colors.green} 0%, {colors.green-deep} 100%)"
description: "Green sticky variant."
post-it-orange:
background: "{colors.orange}"
description: "Orange sticky variant. Flat fill (no gradient) — the only post-it that ships flat."
post-it-purple:
background: "{colors.purple}"
description: "Purple sticky variant. Flat fill."
post-it-white:
background: "#fff"
border: "2px solid {colors.ink}"
description: "White note variant. Carries a 2px ink border (because pure white otherwise disappears into cream/paper backgrounds). Used as a 'plain note' in timelines or comparisons."
pin:
width: 16px
height: 16px
position: "::before, top: -12px, centered"
background: "radial-gradient(circle at 30% 30%, #ff6b6b, #c92a2a)"
boxShadow: "0 2px 4px {colors.shadow-deep}, inset -2px -2px 4px rgba(0,0,0,0.2)"
description: "Red thumbtack mark sitting at the top-center of a post-it via ::before. Radial-gradient gives it a 3D bead-shaped highlight; inset shadow adds dimension. The default pin color."
pin-blue:
background: "radial-gradient(circle at 30% 30%, #4dabf7, #1864ab)"
description: "Blue thumbtack variant."
pin-green:
background: "radial-gradient(circle at 30% 30%, #69db7c, #2f9e44)"
description: "Green thumbtack variant."
pin-gold:
background: "radial-gradient(circle at 30% 30%, #ffd43b, #f59f00)"
description: "Gold thumbtack variant."
tape:
width: 80px
height: 25px
position: "::after, top: -15px, centered, rotate(-2deg)"
background: "rgba(255, 255, 255, 0.4)"
border: "1px solid rgba(255, 255, 255, 0.3)"
description: "Masking-tape mark across the top-center of a post-it via ::after. Translucent white, slightly rotated. Often combined with .pin so a single note has both tape and a tack."
card-rotation:
rotation: "±1° to ±15°"
description: "Every post-it carries a small rotation. Statement and feature cards: ±1° to ±3°. Accent / floating notes: ±5° to ±15° (more dramatic to read as 'casually applied'). Rotations alternate direction across adjacent notes."
feature-icon:
width: 60px
height: 60px
border: "3px solid {colors.ink}"
borderRadius: "50%"
fontFamily: "'Shrikhand', cursive"
fontSize: 1.5rem
description: "Round ink-bordered icon containing a single character (letter, number, or symbol) in Shrikhand display. Used as a category marker at the top of feature post-its."
versus-circle:
width: 60px
height: 60px
background: "{colors.ink}"
color: "{colors.paper}"
borderRadius: "50%"
fontFamily: "'Shrikhand', cursive"
fontSize: 1.2rem
boxShadow: "0 2px 8px {colors.shadow-deep}"
description: "Ink-filled circle with cream text used between two compare-cards. Centered between the two cards with absolute positioning; reads as a 'vs' / 'and' connector."
photo-frame:
background: "#fff"
padding: "1rem"
boxShadow: "2px 3px 15px {colors.shadow}"
rotation: "±1° to ±2°"
description: "Polaroid-style image frame. White paper with 1rem padding around the inner image area; same drop shadow as post-its; small rotation. The inner image area has a 4:3 aspect ratio."
chart-canvas:
background: "#fff"
padding: "2.5rem"
boxShadow: "2px 3px 15px {colors.shadow}"
rotation: "±1°"
description: "White paper card hosting an inline SVG chart. Same drop shadow as post-its and photo-frames; small rotation. Charts use the post-it color palette for fills."
stat-row:
borderBottom: "1px dashed rgba(45, 42, 38, 0.2)"
padding: "1rem 0"
description: "A label-and-value row inside a stat post-it. Label in Zilla Slab body color; value in Shrikhand stat-value. Bottom-divider is a dashed ink-alpha hairline."
doodle:
opacity: 0.15
stroke: "{colors.ink}"
strokeWidth: 3
description: "Decorative SVG mark placed absolutely in slide corners — a circle, squiggle, triangle, line, or X+ pair. All at 0.15 opacity, all in 3px ink stroke. Slides have 0–2 doodles each."
timeline-connector:
height: 60px
pathStyle: "Q (quadratic) bezier curve at 0.3 opacity, stroke-dasharray '8 4', polygon arrowhead at end"
description: "Dashed quadratic-bezier line between timeline nodes. Curve direction alternates row to row (concave up, concave down). Always ends with a triangle arrowhead."
custom-cursor:
cursor: "URL data-svg red-and-white thumbtack, 24×24, hotspot 12×12"
description: "Browser cursor replaced with a tiny SVG thumbtack circle (red outer, white center) when hovering over any slide. Reinforces the 'pinning ideas to a board' metaphor."
---
## 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
Scatterbrain is a **Post-it-note-and-cork-board presentation system**. Every content block is a colored sticky note (`{components.post-it}`) layered onto one of three textured background variants — cork board, desk paper, or warm gradient — with red / blue / green / gold thumbtacks pinning the notes and translucent masking tape sometimes added on top. The visual metaphor is total: the deck is a creative-workshop wall, a brainstorming board, or a thinker's desk, and the content is the cluster of sticky notes pinned across it.
The typeface stack pairs three Google Fonts with distinct emotional roles. **Shrikhand** is the display voice — a chunky decorative display serif with playful curves and high contrast. Used at weight 400 (the only weight available) for every headline, statement, feature icon glyph, stat value, and oversized callout. Its loud, friendly personality is the system's primary signal: it reads as hand-lettered marker pen rather than typeset publication. **Zilla Slab** is the body voice — a friendly modern slab serif with humanist proportions. Used at weights 300–700 for body paragraphs, list items, and labels. Its slab serifs match the warm hand-drawn register of Shrikhand without competing for attention. **Caveat** is the hand-script voice — a casual cursive. Used for personal notes, side annotations, label-script eyebrows, stat-divider quips, and any moment that should read as "scribbled on the note in pen."
The color philosophy is **pastel sticky-note palette on tactile paper backgrounds**. Seven sticky-note colors (`yellow`, `blue`, `pink`, `green`, `orange`, `purple`, plus bordered `white`) provide categorical variety; each has a deeper sibling that drives the 135° gradient fill. The ink (`{colors.ink}` — #2d2a26) is a soft warm charcoal rather than pure black, sitting comfortably on warm pastels. Three background variants — cork (`bg-cork`), paper (`bg-paper`), warm gradient (`bg-warm`) — provide tactile variation across slides so the deck doesn't read as monotonous. The pastels are pale enough that ink text remains legible on every sticky-note color without inversion.
Depth comes from **soft drop shadows + small rotations + layered tactile elements** (pins, tape, doodles). The signature treatment: every post-it carries a soft blurred drop shadow (`2px 3px 15px {colors.shadow}`) that suggests a slight lift off the surface, plus a small rotation (±1° to ±15°) that reads as hand-placed rather than grid-snapped. Optional pins (red thumbtacks via `::before`) and tape (translucent white via `::after`) add tactile depth without using box-shadow tricks.
**Density philosophy: medium.** Each slide is anchored by 1–4 sticky notes plus 1–2 accent decorations (floating side-notes, doodles, decorative shapes). A slide with one large centered post-it reads as a manifesto moment; a slide with three feature-cards reads as a layout slide; a slide with one main post-it plus 2–4 small floating accent post-its reads as a hero spread. Crowding the canvas with simultaneous overlapping notes collapses the playful energy into chaos. The correct density is enough notes to feel like a creative-process spread, with enough negative space to read each note clearly.
**Key Characteristics:**
- Three textured background variants: cork (`{components.bg-cork}`), paper (`{components.bg-paper}`), warm gradient (`{components.bg-warm}`). Each slide picks one.
- A fixed SVG grain overlay at 4% opacity sits above all content, reinforcing the paper register.
- Seven sticky-note colors: yellow, blue, pink, green, orange, purple, white-bordered. Each gradient-filled (except orange / purple / white).
- Every post-it carries a soft drop shadow + small rotation. Rotations alternate direction across adjacent notes.
- Red thumbtacks (and blue / green / gold variants) via `::before`. Masking tape via `::after`. Often combined on a single note.
- Display headlines in Shrikhand (chunky display serif). Body in Zilla Slab (friendly slab). Personal annotations in Caveat (casual script).
- Decorative SVG doodles (circles, squiggles, triangles, X marks) live in slide corners at 0.15 opacity.
- Custom thumbtack cursor reinforces the "pinning ideas to a board" metaphor.
## Colors
### Palette
**Sticky-note colors** (gradient-filled or flat):
- **Yellow** (`{colors.yellow}` — #ffe066 → `{colors.yellow-deep}` — #ffd43b): Classic sticky-note yellow. Most common note color. The system's "default" sticky.
- **Blue** (`{colors.blue}` — #a5d8ff → `{colors.blue-deep}` — #74c0fc): Soft sky blue. The system's "secondary" sticky.
- **Pink** (`{colors.pink}` — #ffc9c9 → `{colors.pink-deep}` — #ff9f9f): Soft rose pink. The system's "warm accent" sticky.
- **Green** (`{colors.green}` — #b2f2bb → `{colors.green-deep}` — #8ce99a): Mint green. The system's "cool accent" sticky.
- **Orange** (`{colors.orange}` — #ffcc80): Warm peach-orange. Flat fill, no gradient. Used as a tertiary accent for variety.
- **Purple** (`{colors.purple}` — #d0bfff): Lavender purple. Flat fill, no gradient. Used as a tertiary accent for variety.
**Special note colors**:
- **White** (`#fff`): A bordered white sticky used in timelines and comparisons where a "plain" or "neutral" note is needed. Always carries a 2px ink border because pure white otherwise disappears into the cream/paper backgrounds.
**Paper / surface colors**:
- **Cream** (`{colors.cream}` — #faf8f3): The lightest paper variant. Used inside the `bg-paper` and `bg-warm` background gradients.
- **Paper** (`{colors.paper}` — #f7f5f0): The body background — sits just behind every slide as the page color visible through the bg overlays. Used as the inverted text color on dark ink surfaces.
**Ink / text colors**:
- **Ink** (`{colors.ink}` — #2d2a26): The structural color. All headlines, all body text, all borders, all doodle strokes. Slightly softer than pure black for warmth.
- **Ink Light** (`{colors.ink-light}` — #5c5750): Secondary text color for body paragraphs, captions, and de-emphasized text.
**Shadow tokens**:
- `{colors.shadow}` (rgba(45, 42, 38, 0.15)): Soft drop shadow — used on every post-it.
- `{colors.shadow-deep}` (rgba(45, 42, 38, 0.25)): Stronger contact shadow — used as the second layer of the post-it drop shadow.
### Defaults
- **Default surface background**: pick one of `{components.bg-cork}` / `{components.bg-paper}` / `{components.bg-warm}` per slide. Cork is the default for tactile / wall-of-notes moments; paper for desk / focused-content moments; warm-gradient for hero / atmospheric moments.
- **Default post-it color**: `{components.post-it-yellow}` — yellow is the most-common sticky and reads as the system's baseline.
- **Default headline color**: `{colors.ink}` (#2d2a26) — Shrikhand display in soft warm charcoal on every post-it.
- **Default body text color**: `{colors.ink-light}` (#5c5750) for paragraph body; `{colors.ink}` for list items and emphasized body.
- **Default border color**: `{colors.ink}` for the white-note 2px border and for the feature-icon round border. Most sticky notes have no border (the gradient fill defines them).
- **Default pin color**: `{components.pin}` (red) — the system's "default" thumbtack. Use blue / green / gold variants to match the post-it color underneath when visual variety is needed.
- **Default tape**: applied sparingly — typically on hero / statement post-its where the note feels "officially posted" with both a pin and a strip of tape.
- **Default text color on ink surfaces**: `{colors.paper}` (#f7f5f0).
- **Default decorative doodle color**: `{colors.ink}` at 0.15 opacity, 3px stroke.
The seven sticky-note colors have **no fixed semantic meaning** — yellow is not "warning," green is not "success." They serve as a categorical palette where the choice signals "which note in the cluster is this." Cycle through colors for visual variety; pair gradient-filled notes (yellow, blue, pink, green) with flat-filled notes (orange, purple) for textural variation.
## Typography
### Font Family
The system has three Google Fonts each with a distinct role:
- **Shrikhand** (display): A chunky decorative display serif with high stroke contrast, playful curves, and a hand-lettered marker-pen feel. Single weight (400). Used for every display moment — headlines, statements, titles, feature-icon glyphs, stat values, versus-circle text. Its loud personality is the system's primary identity; substituting another display serif loses the workshop voice.
- **Zilla Slab** (body): A friendly modern slab serif with humanist warmth. Multi-weight (300–700, with italic variants 300 and 400). Used at weight 400 for body paragraphs (the default), 300 for the lightest captions, 500–700 for emphasis. The slabs read as warm-handed rather than mechanical.
- **Caveat** (hand-script): A casual cursive with multiple weights (400–700). Used for personal notes, side annotations, label-script eyebrows (uppercase tracked 0.15em), closing-slide sign-offs, decorative quips inside stat-divider rows.
Italic exists for Zilla Slab (300 and 400 italic) but is rarely used — emphasis comes from weight switching or face switching, not from italics. Underline is not used.
### Type Scale
| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-hero}` | 2.5–4.5rem | Shrikhand | 400 | Cover or closing oversized headline |
| `{typography.statement}` | 2–3.5rem | Shrikhand | 400 | Centered statement or pulled quote |
| `{typography.headline}` | 1.8–3rem | Shrikhand | 400 | Primary slide headline / section headline |
| `{typography.title}` | 1.3–1.8rem | Shrikhand | 400 | Sub-region or card title |
| `{typography.caption-subtitle}` | 1.3rem | Zilla Slab | 400 | Slide subtitle below a hero headline |
| `{typography.body}` | 1–1.25rem | Zilla Slab | 400 | Standard paragraph body |
| `{typography.list-item}` | 1.1rem | Zilla Slab | 400 | Bulleted / check-marked list row |
| `{typography.handwritten}` | 1.2–1.6rem | Caveat | 400 | Decorative quip, personal note |
| `{typography.handwritten-lg}` | 1.4–2rem | Caveat | 600 | Larger handwritten subtitle |
| `{typography.handwritten-sm}` | 1.2–1.4rem | Caveat | 500 | Small accent label |
| `{typography.label-script}` | 0.9rem | Caveat | 400 | Tracked-caps eyebrow label |
| `{typography.stat-value}` | 1.8rem | Shrikhand | 400 | Numerical value in a stat-row |
### Defaults
- **Default size for a primary section headline (inside a post-it)**: `{typography.headline}` (1.8–3rem clamp) in Shrikhand.
- **Default size for a cover or closing oversized headline**: `{typography.display-hero}` (2.5–4.5rem clamp).
- **Default size for a centered manifesto / pulled-quote statement**: `{typography.statement}` (2–3.5rem clamp).
- **Default size for paragraph body**: `{typography.body}` (1–1.25rem clamp) in Zilla Slab 400.
- **Default size for list rows (bulleted, check-marked, or compare-list)**: `{typography.list-item}` (1.1rem) in Zilla Slab 400.
- **Default size for a side note or quip**: `{typography.handwritten}` (1.2–1.6rem clamp) in Caveat 400.
- **Default size for an eyebrow label above a card headline**: `{typography.label-script}` (0.9rem) in Caveat, uppercase, 0.15em tracking.
- **Default size for a stat value**: `{typography.stat-value}` (1.8rem) in Shrikhand.
- **Default weight for Shrikhand**: 400 (the only weight).
- **Default weight for Zilla Slab body**: 400. For emphasized body: 500–700. For light captions: 300.
- **Default weight for Caveat**: 400 for casual notes; 500–700 for emphasis.
When unsure between `{typography.headline}` and `{typography.title}` for a card's primary text, reach for `{typography.headline}` if the card is the slide's dominant element; reach for `{typography.title}` if it is one of several smaller cards.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every display headline is set in Shrikhand.** Substituting Zilla Slab or another display face loses the workshop voice. Even small titles (1.3rem) inside feature cards use Shrikhand.
- **Every body paragraph and list item is set in Zilla Slab.** Setting body in Shrikhand reads as overproduced and unreadable.
- **Every casual / personal note is set in Caveat.** This includes side notes, decorative quips ("Jot it down before you forget!", "OK", ":)"), and stat-divider personal observations. Switching to italic Zilla loses the hand-drawn voice.
- **Every label-script eyebrow is uppercase with 0.15em tracking.** Caveat at normal tracking reads as a body cursive; the uppercase + tracking turns it into a categorical label.
- **Every feature-icon round border is 3px ink with a Shrikhand glyph inside.** Variations (2px border, sans-serif glyph) break the icon's visual signature.
- **Every post-it that hosts a primary headline gets a thumbtack pin via `::before`.** A pinless headline-post-it reads as floating and undefined.
- **Every hero / statement post-it carries both a pin and a strip of tape** (`.pin .tape` classes together). This is the system's "officially posted" treatment for the most-emphasized note.
### Typography Principles
The system's typographic rhythm comes from **three-face contrast**: Shrikhand display (loud, decorative, friendly serif) → Zilla Slab body (steady, readable, slab serif) → Caveat hand-script (personal, casual, cursive). A slide that uses only one face reads as monotonous; a slide that combines all three reads as workshop-correct.
Line-height: tight on display (1.1), generous on body (1.6–1.7), moderate on hand-script (1.3–1.4). Letter-spacing on display is subtly positive (0.02em) which gives Shrikhand a touch more openness than its default; body has no tracking; hand-script labels carry 0.15em uppercase tracking.
## Layout
### Canvas System
The system targets `100vw × 100vh`. Each `.slide` is absolutely positioned to fill the viewport with `display: none` by default; the `.active` slide is `display: flex` centered. Navigation is JS-driven via arrow keys, space, PageUp/Down, Home/End, touch swipe, and mouse wheel (with 700ms lock to prevent multi-skip).
### Slide Composition Patterns
The system supports several composition patterns without prescribing layouts:
- **Centered single-card**: one large post-it (statement, closing, RSVP-style).
- **2-column or 3-column grid**: aligned grid of post-its with small rotations.
- **Chart + legend**: a white chart-card on one side, a colored post-it legend on the other.
- **Image + text**: a polaroid-style photo-frame on one side, a text-post-it cluster on the other.
- **Free cluster**: a hero post-it surrounded by 2–4 small accent post-its at various rotations and positions.
- **Timeline rows**: alternating left/right node + dashed-curve connector + content card per row.
- **Compare**: two post-its side by side with a centered ink versus-circle between them.
In every pattern, individual post-its sit on one of the three background textures with small rotations and decorative doodle marks in unoccupied corners.
### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad}` | 3rem | Slide outer padding |
| `{spacing.post-it-pad-lg}` | 3rem 4rem | Hero / title post-it interior padding |
| `{spacing.post-it-pad-statement}` | 3.5rem 4rem | Statement post-it interior padding |
| `{spacing.post-it-pad-md}` | 2.5rem | Standard post-it interior padding |
| `{spacing.post-it-pad-sm}` | 1.5rem | Small accent post-it interior padding |
| `{spacing.gap-lg}` | 3rem | Multi-column grid gap |
| `{spacing.gap-md}` | 2.5rem | Feature grid gap |
| `{spacing.gap-sm}` | 2rem | Timeline row gap |
### Persistent Chrome
The system has no persistent slide chrome — no progress bar, no slide counter, no nav hint. The custom thumbtack cursor is the only persistent visual signal. Navigation is purely keyboard / swipe / wheel driven.
## Depth and Elevation
### Soft Drop Shadow (Primary Technique)
The system's defining depth treatment is the **soft drop shadow** on every post-it, photo-frame, chart-card, and diagram-canvas: `2px 3px 15px {colors.shadow}, 0 1px 3px {colors.shadow-deep}`. The 15px-blur outer shadow with 2px horizontal and 3px vertical offset suggests the note hovers slightly above the cork or paper surface. The 1px-blur inner shadow with 1px vertical offset adds the contact shadow at the bottom edge. Together they read as "lifted note pinned to a board."
This is the **only system that defines depth via soft blurred shadows** — most other templates in this library prohibit them. Scatterbrain embraces them because the visual metaphor depends on the tactile lift of a paper note off a textured surface.
### Rotation (Secondary Technique)
Every post-it carries a small rotation (±1° to ±15°). Hero / statement / feature post-its take small rotations (±1° to ±3°); accent / floating / closing-cluster post-its take larger rotations (±5° to ±15°). Rotations alternate direction across adjacent notes so the cluster reads as casually applied, not grid-snapped.
### Tactile Layering (Pins + Tape)
Optional layered marks on individual post-its provide additional depth:
- **Pin** (`{components.pin}`) — a 16px round red thumbtack via `::before` at the top-center of the note. The radial-gradient highlight + inset shadow + drop shadow make it read as a 3D bead.
- **Tape** (`{components.tape}`) — an 80×25px translucent white tape strip via `::after` at the top-center, slightly rotated.
Pins and tape can combine on a single note (the `.pin.tape` class pair). Color variants of pins (`pin-blue`, `pin-green`, `pin-gold`) match the underlying note color for visual cohesion.
### Background Texture (Atmospheric Layer)
The three background variants (`bg-cork`, `bg-paper`, `bg-warm`) and the full-viewport grain overlay (`{components.grain-overlay}` at 4% opacity) provide the foundational textural ground. Without the background variants the deck reads as floating notes on white; with them, the deck reads as physically grounded on cork, desk paper, or morning light.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0px | All post-its, chart-cards, photo-frames, diagram-canvases, compare-cards |
| 50% (circle) | Feature-icon round border, versus-circle, thumbtack pins |
| 3px | Chart bar `<rect>` corner radius (inline SVG) |
| Custom (no fixed token) | Photo-frame inner image area follows the polaroid aspect ratio 4:3 |
Most surfaces are strict rectangles. Round shapes are reserved for icons, pins, and the versus-marker. The chart bars carry a subtle 3px round corner (inside SVG) for friendliness.
### Border Weights
- **2px solid `{colors.ink}`** — used on the white-note border and on chart SVG `<rect>` strokes.
- **3px solid `{colors.ink}`** — used on feature-icon round border and on doodle SVG paths.
- **1px dashed rgba(ink, 0.2)** — used as stat-row hairline divider.
- **1px solid rgba(ink, 0.1)** — used as compare-list row divider.
Borders are universally ink (warm charcoal). Colored borders do not appear.
### Decorative Element Types
**Post-it** (`{components.post-it}`) — Colored sticky-note in one of seven variants (yellow, blue, pink, green, orange, purple, bordered-white). Padding from the `{spacing.post-it-pad-*}` scale. Always carries the soft drop shadow. Almost always carries a small rotation. Usually carries a pin and sometimes tape.
**Pin** (`{components.pin}`) — Red thumbtack via `::before`. Default color red; variants blue, green, gold. Sits at top-center of the note.
**Tape** (`{components.tape}`) — Translucent white masking-tape mark via `::after` at top-center of the note, slightly rotated.
**Feature icon** (`{components.feature-icon}`) — 60px round ink-bordered circle with a Shrikhand glyph (single character) inside. Used at the top of feature post-its as a category marker.
**Versus circle** (`{components.versus-circle}`) — Ink-filled circle with cream Shrikhand text, centered between two compare-post-its with absolute positioning. Carries its own drop shadow.
**Photo frame** (`{components.photo-frame}`) — Polaroid-style white card with 1rem padding around a 4:3 inner image area. Same drop shadow as post-its; small rotation.
**Chart canvas** (`{components.chart-canvas}`) — White card hosting an inline SVG chart. Same drop shadow as post-its; small rotation. SVG charts use the post-it color palette (yellow, blue, pink, green) for bars / segments. Axis labels in Zilla Slab; value labels in Caveat.
**Diagram canvas** — White card hosting a circular donut / pie SVG. Same treatment as chart canvas. SVG segments use post-it palette; legend rows use ink text.
**Stat row** (`{components.stat-row}`) — Label-value row inside a stat post-it. Zilla Slab label + Shrikhand stat-value, separated by a dashed ink-alpha bottom border.
**Timeline node + connector** — Each timeline row has a left post-it (timeline node with phase-label Caveat caption) + a center dashed-bezier SVG connector + a right white-bordered post-it (timeline content body). Row direction alternates (left/right) via `flex-direction: row-reverse` on even rows.
**Doodle SVG** (`{components.doodle}`) — Decorative SVG mark placed absolutely in slide corners: circle, squiggle, triangle, line, X+ pair. 3px ink stroke at 0.15 opacity. Slides have 0–2 doodles each.
**Custom cursor** — SVG thumbtack cursor (red outer circle + white center) replaces the default cursor when hovering over slides.
## Do's and Don'ts
### Do
- Pick a background variant per slide: `{components.bg-cork}` for "wall of notes" energy, `{components.bg-paper}` for "desk surface" focus, `{components.bg-warm}` for "morning light" atmosphere. Vary across slides for tactile variety.
- Keep the SVG grain overlay (`{components.grain-overlay}`) on every slide at 4% opacity. It is the texture that ties the deck to its paper register.
- Use Shrikhand for every display moment (headlines, titles, feature icons, stat values) and Zilla Slab for every body paragraph and list item.
- Use Caveat for casual / personal notes — side annotations, decorative quips ("Jot it down before you forget!", ":)"), and label-script eyebrows. The hand-script is the system's most distinctive voice.
- Give every post-it a small rotation (±1° to ±15°). Alternate rotation direction across adjacent notes; nothing should align to a grid.
- Apply the standard soft drop shadow (`2px 3px 15px shadow, 0 1px 3px shadow-deep`) to every post-it, photo-frame, chart-card, and diagram-canvas.
- Pin every primary post-it with a red thumbtack via `::before`. Use color-matched pin variants (blue / green / gold) when the post-it color suggests it.
- Combine pin + tape on hero / statement post-its for the "officially posted" treatment.
- Place small SVG doodles (circles, squiggles, triangles) in slide corners at 0.15 opacity as decorative punctuation. 1–2 doodles per slide is plenty.
- Cycle through post-it colors (yellow → blue → pink → green → orange → purple) for visual variety in multi-card grids. Don't repeat one color across all cards.
### Don't
- Don't omit background textures and let post-its float on a plain white viewport. The textured backgrounds are the system's foundational visual ground.
- Don't substitute another display face for Shrikhand. The chunky decorative serif is the system's identity; replacing it with a sans or another serif loses the workshop voice.
- Don't substitute another script face for Caveat. The casual cursive voice anchors the "scribbled by hand" register.
- Don't use Zilla Slab for headlines or Shrikhand for body paragraphs. The pairing is locked: Shrikhand display + Zilla Slab body + Caveat script.
- Don't assign semantic meaning to post-it colors (yellow = warning, green = good). The colors are categorical only.
- Don't rotate post-its more than ±15°. Beyond that, hand-placed becomes wonky.
- Don't rotate every post-it in the same direction. Alternate ±directions across adjacent notes; uniformity reads as tilted-canvas, not hand-placement.
- Don't use pure white as a post-it fill without the 2px ink border. White-on-cream backgrounds becomes invisible.
- Don't omit the pin on a headline post-it. Pinless headlines read as floating and undefined.
- Don't crowd a slide with overlapping post-its. The playful energy collapses when notes pile up; the correct density is 1–4 main notes plus 1–2 small accent / floating notes.
## Responsive Behavior
The system targets `100vw × 100vh` and uses `clamp()` throughout for fluid scaling. A single media query at `max-width: 900px` reflows multi-column grids and timelines to single-column, neutralizes some rotations (versus-circle becomes inline rather than absolute), and stacks compare-cards vertically.
### Scaling Behavior
- Display headlines scale via `clamp(2.5rem, 5vw, 4.5rem)` patterns — fluid between minimum and maximum.
- Body text scales from 1rem at minimum to 1.25rem at maximum.
- Post-it padding does not scale by viewport — fixed at the values in the spacing scale.
- Drop shadows, pin sizes, tape sizes, and decorative SVG sizes are fixed regardless of viewport.
### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, `Space`, or `PageDown`.
- Slides reverse via `ArrowLeft`, `ArrowUp`, or `PageUp`.
- `Home` jumps to first, `End` to last.
- Touch swipe horizontal advances/reverses on mobile.
- Mouse wheel advances/reverses, locked for 700ms between scrolls to prevent multi-skip on trackpads.
- The custom thumbtack cursor reinforces the metaphor on every hover.
### Print Behavior
A `@media print` rule sets `page-break-after: always` on each slide with `min-height: 100vh`. Printing produces a sequential page-per-slide output.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headline / Statement / Title / Stat-value / Feature-icon glyph | Shrikhand (400) | **站酷快乐体 ZCOOL KuaiLe** | regular (single weight) |
| Body / List-item / Caption-subtitle | Zilla Slab (400) | **悠哉字体 Yozai** | regular |
| Hand-script (Caveat) — Latin only | Caveat (400 / 500 / 600) | *(no CJK substitute)* | n/a |
### Mixed-Content Strategy
**Strategy A — display CJK + body CJK, each with its own personality.** Scatterbrain's whole register is playful-tactile-warmth, and the Chinese pairing should land in the same emotional register. **ZCOOL KuaiLe (站酷快乐体)** is a chunky decorative display face with rounded curves and a hand-drawn marker-pen feel — it is the closest CJK match for Shrikhand's chunky decorative serif voice. Both faces share the "loud and friendly" personality that defines the workshop-board aesthetic. **Yozai (悠哉字体)** is a warm rounded body face derived from M+ Rounded — it carries the same friendly humanist quality as Zilla Slab's slab serif, with soft terminals that feel like written notes rather than typeset text. Together the two CJK faces preserve the playful-chunky-display + warm-friendly-body rhythm that makes Scatterbrain's voice work.
### Loading
```html
<link href="https://chinese-fonts-cdn.deno.dev/packages/zcool-kuaile/dist/ZCOOLKuaiLe-Regular/result.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-yozai-regular/font.css" rel="stylesheet">
```
Then append the CJK families to the appropriate font stacks:
```css
/* Display roles */
font-family: 'Shrikhand', 'ZCOOL KuaiLe', cursive;
/* Body roles */
font-family: 'Zilla Slab', 'Yozai', serif;
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence
### Aesthetic Notes for This System
- **The 0.02em positive tracking on Shrikhand display must drop to 0** on ZCOOL KuaiLe. Tracked Chinese display characters look broken.
- **Display line-height should open from 1.1 to 1.2–1.3** for ZCOOL KuaiLe — the rounded chunky strokes need more vertical breathing.
- **Feature-icon round borders work beautifully with a single Chinese character** (新, 巧, 趣) inside the 60px circle at ZCOOL KuaiLe. The chunky display weight makes the single character read as a stamped category mark.
- **Versus circles work with short Chinese words** (对比, 与) at smaller display weight; the cream-on-ink contrast carries through.
- **The label-script Caveat eyebrow (uppercase tracked 0.15em) becomes the trickiest translation.** Options: (1) keep eyebrows in Latin (`CHAPTER ONE`, `THE SETUP`) for the hand-script signature; (2) replace with a Yozai eyebrow at 0.9rem, no tracking, no uppercase — which loses the categorical-label affordance. Option (1) preserves the system's most distinctive small voice and works well when the Latin eyebrow sits above a Chinese headline (the deck reads as a Chinese article with an English kicker, which is a common editorial convention).
- **Personal notes / decorative quips in Caveat (`Jot it down before you forget!`, `:)`) should stay Latin** — the casual ballpoint script has no acceptable Chinese substitute. On Chinese-primary slides, treat hand-script moments as Latin margin notes; this can actually deepen the workshop voice (the deck reads as a Chinese brainstorm with English asides, which is plausible for any modern Chinese creative team).
- **Post-it pins, tape, drop shadows, rotations, custom cursor, doodle SVGs, background textures** are all glyph-agnostic — they carry the playful-tactile system equally well behind Chinese content.
- **Stat-row label-and-value pattern** works cleanly with Chinese labels (用户数量, 转化率) in Yozai and Latin numerical values in ZCOOL KuaiLe.
### Known CJK Gap
Caveat — the system's most distinctive voice (the casual ballpoint hand-script that anchors every personal note) — has no CJK equivalent. There are handwritten-style Chinese web fonts (悠果手写体, 站酷庆科黄油体), but the cultural register of casual cursive handwriting differs sharply between Latin and CJK traditions, and no Chinese face will read as "the same voice as Caveat." The recommended workaround is to retain Caveat for Latin margin annotations even on otherwise-Chinese slides — the Chinese-body-with-English-handwriting pattern is common in modern Chinese editorial design and lands as authentic rather than as a translation gap.
## Iteration Guide
1. Every new slide picks one of three background variants (`{components.bg-cork}`, `{components.bg-paper}`, `{components.bg-warm}`). Vary across slides for tactile variety.
2. Every new content block is a post-it in one of seven colors (yellow, blue, pink, green, orange, purple, bordered-white). Yellow is the default; cycle through colors for multi-card variety.
3. Every new post-it carries a small rotation. Hero / statement post-its: ±1–3°. Accent / floating post-its: ±5–15°. Alternate directions across neighbors.
4. Every new post-it carries the standard soft drop shadow (`2px 3px 15px shadow, 0 1px 3px shadow-deep`).
5. Every new primary post-it carries a pin via `::before` (red default; blue / green / gold variants for color cohesion).
6. Hero / statement / closing post-its add a tape strip via `::after` for the "officially posted" treatment.
7. Headlines use Shrikhand at sizes from `{typography.title}` (1.3rem) for small card titles up to `{typography.display-hero}` (4.5rem) for cover/closing. Body uses Zilla Slab. Personal notes use Caveat.
8. Feature post-its open with a 60px round ink-bordered feature-icon containing a single Shrikhand character (A/B/C, 1/2/3, !/✓/✗).
9. Decorative SVG doodles (circles, squiggles, triangles, X marks) live in 1–2 unoccupied corners per slide at 0.15 opacity, 3px ink stroke.
10. Charts and diagrams sit inside a white chart-canvas (`{components.chart-canvas}`) with the same drop shadow + small rotation as post-its. SVG fills use the post-it palette (yellow, blue, pink, green).
## Known Gaps
- The system loads three Google Fonts (Shrikhand, Zilla Slab, Caveat). Shrikhand is single-weight (400 only); attempting a heavier weight will fall back. Self-hosting is recommended for production.
- The custom SVG thumbtack cursor (`{components.custom-cursor}`) does not render on all browsers identically — Safari and Firefox may scale or position the cursor hotspot differently than Chrome. On touch-only devices the cursor is irrelevant.
- The background textures (`bg-cork`, `bg-paper`, `bg-warm`) use combinations of CSS gradients and inline SVG data-URI patterns. Rendering is consistent across modern browsers but the tonal warmth varies slightly with screen color profiles.
- Pins (`::before`) and tape (`::after`) consume both pseudo-element slots on a post-it. If additional decorative marks are needed (a corner curl, a stain, etc.), they would require a real child element instead of pseudo-elements.
- The soft drop shadow on every post-it adds rendering overhead. Slides with 10+ post-its may show slight shadow rendering lag on lower-end devices.
- The custom cursor and absolute-positioned pins / tape do not interact with screen readers as expected. The decorative elements should remain hidden from assistive tech.
- Inline SVG charts (bar, donut, pie) are hardcoded — bar heights, segment paths, and labels are baked into the SVG. There is no data-binding layer; new chart values require manual SVG path / position recalculation.
- The custom cursor (red thumbtack) appears on every slide including text-heavy ones, which may be visually noisy when users are reading body paragraphs. Treat the cursor as a deck-wide accent, not a per-slide affordance.
- The mouse-wheel navigation lock (700ms) is unusual and may surprise users expecting smooth-scroll. Trackpad users especially may find the wheel-step behavior counter-intuitive.
# Scatterbrain Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/scatterbrain/design.md`
- Preview card: `bold-template-pack/templates/scatterbrain/preview.md`
## Selection Metadata
- Slug: `scatterbrain`
- Tagline: Post-it inspired: pastel sticky notes, Caveat handwriting, Shrikhand and Zilla Slab type stack.
- Mood: playful, creative, warm, messy-on-purpose, workshop
- Tone: informal, warm, expressive, human
- Formality: low
- Density: high
- Scheme: light
- Best for: Anything that should feel like a designer's whiteboard: brainstorms, workshops, creative-agency credentials, design-thinking sessions, ideation pitches, art-direction reviews. Equally fun for any deck — including tech, research, or business — that wants to read as in-progress thinking rather than polished conclusions.
- Avoid for: Contexts that demand precision and institutional weight — the post-it sticky-note aesthetic intentionally reads as warm and unfinished.
## Visual Snapshot
A Post-it-note-and-cork-board presentation system. Every content block is a colored sticky note on a textured paper or cork surface, layered with red thumbtacks, masking tape, and decorative doodles. Display type runs in Shrikhand (a chunky decorative display serif) on every headline; body type runs in Zilla Slab (a friendly slab serif); handwritten emphasis runs in Caveat. The palette is pastel sticky-note colors (yellow, blue, pink, green, orange, purple) on cream paper / cork / warm gradient backgrounds. The aesthetic borrows from creative-workshop wall art, brainstorming boards, and indie-studio mood boards: scattered slight rotations, multiple background texture variants per slide, pin / tape / drop-shadow combinations. The effect is warmth, play, and tactile creative-process energy.
Scatterbrain is a Post-it-note-and-cork-board presentation system. Every content block is a colored sticky note ({components.post-it}) layered onto one of three textured background variants — cork board, desk paper, or warm gradient — with red / blue / green / gold thumbtacks pinning the notes and translucent masking tape sometimes added on top. The visual metaphor is total: the deck is a creative-workshop wall, a brainstorming board, or a thinker's desk, and the content is the cluster of sticky notes pinned across it.
## Preview Ingredients
- Palette: yellow #FFE066; yellow-deep #FFD43B; blue #A5D8FF; blue-deep #74C0FC; pink #FFC9C9; pink-deep #FF9F9F; green #B2F2BB; green-deep #8CE99A
- Typography: See full design doc after selection.
- Signature move: Three textured background variants: cork ({components.bg-cork}), paper ({components.bg-paper}), warm gradient ({components.bg-warm}). Each slide picks one.
- Signature move: A fixed SVG grain overlay at 4% opacity sits above all content, reinforcing the paper register.
- Signature move: Seven sticky-note colors: yellow, blue, pink, green, orange, purple, white-bordered. Each gradient-filled (except orange / purple / white).
- Signature move: Every post-it carries a soft drop shadow + small rotation. Rotations alternate direction across adjacent notes.
- Signature move: Red thumbtacks (and blue / green / gold variants) via ::before. Masking tape via ::after. Often combined on a single note.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Signal
description: A literary editorial presentation system in the spirit of a long-form magazine — The Economist's restraint crossed with a private intelligence briefing. Source Serif 4 carries every headline with roman/italic mixing mid-sentence in antique gold, DM Sans steps back for body, and IBM Plex Mono runs all the timestamps, kickers, and chrome. The dual surface system is warm cream paper (#F0ECE3) and deep editorial navy (#1C2644), connected by a single hot accent — antique gold (#C8A870) — used only on rules, italic emphasis, and numerical figures. A near-invisible 80px grid texture overlays every dark slide as a fingerprint. The effect is sober, considered, and a little bit aristocratic.
colors:
navy: "#1C2644"
navy-alt: "#232F55"
cream: "#F0ECE3"
cream-alt: "#E6E0D4"
text-warm: "#E2DCD0"
text-muted-dark: "#8A96A8"
text-hint-dark: "#4E5A6E"
ink: "#1A2030"
text-muted-light: "#5A6270"
text-hint-light: "#9AA0A8"
gold: "#C8A870"
border-dark: "#2E3D5C"
border-light: "#CAC4B4"
color-aliases:
c-bg: navy
c-bg-alt: navy-alt
c-bg-light: cream
c-bg-light-alt: cream-alt
c-fg: text-warm
c-fg-2: text-muted-dark
c-fg-3: text-hint-dark
c-fg-light: ink
c-fg-light-2: text-muted-light
c-fg-light-3: text-hint-light
c-accent: gold
c-border: border-dark
c-border-light: border-light
typography:
display:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 9.5vw
fontWeight: 700
lineHeight: 0.96
letterSpacing: -0.02em
h1:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 5.2vw
fontWeight: 600
lineHeight: 1.08
letterSpacing: -0.01em
h2:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 3vw
fontWeight: 600
lineHeight: 1.18
h3:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 1.9vw
fontWeight: 500
lineHeight: 1.3
lead:
fontFamily: "DM Sans, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.4vw
fontWeight: 400
lineHeight: 1.58
body:
fontFamily: "DM Sans, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.05vw
fontWeight: 400
lineHeight: 1.65
caption:
fontFamily: "DM Sans, Noto Sans SC, system-ui, sans-serif"
fontSize: 0.82vw
fontWeight: 400
lineHeight: 1.5
label:
fontFamily: "IBM Plex Mono, JetBrains Mono, monospace"
fontSize: 0.7vw
fontWeight: 500
letterSpacing: 0.14em
textTransform: uppercase
stat-value:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 5.5vw
fontWeight: 600
lineHeight: 1
letterSpacing: -0.02em
quote-text:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 3.6vw
fontWeight: 400
lineHeight: 1.28
letterSpacing: -0.01em
quote-mark:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 8vw
fontWeight: 300
lineHeight: 0.6
editorial-headline:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 2.75vw
fontWeight: 600
lineHeight: 1.2
dense-headline:
fontFamily: "Source Serif 4, Noto Serif SC, Georgia, serif"
fontSize: 2.4vw
fontWeight: 600
lineHeight: 1.2
spacing:
pad-x: 7.5vw
pad-y: 5.5vh
gap-lg: 4vh
gap-md: 2.5vh
gap-sm: 1.2vh
grid-cell: 80px
canvas:
width: 100vw
height: 100vh
components:
rule-short:
width: 36px
height: 1px
background: "{colors.gold}"
description: "Short gold rule used as a kicker separator above headlines and as a chapter accent mark."
rule-full:
width: "100%"
height: 1px
background: "{colors.border-dark}"
description: "Full-width hairline divider, color shifts to {colors.border-light} on cream surfaces."
kicker:
color: "{colors.gold}"
typography: "{typography.label}"
description: "Mono uppercase label in antique gold, sits above a headline."
tag:
border: "1px solid {colors.gold}"
color: "{colors.gold}"
padding: "0.3em 0.8em"
typography: "{typography.label}"
description: "Outlined gold pill containing a mono uppercase label."
chrome-bar:
borderBottom: "1px solid {colors.border-dark}"
paddingBottom: "{spacing.gap-sm}"
marginBottom: "{spacing.gap-md}"
description: "Top chrome strip with mono label left, mono counter right, hairline rule beneath."
foot-bar:
borderTop: "1px solid {colors.border-dark}"
paddingTop: "{spacing.gap-sm}"
marginTop: "{spacing.gap-md}"
description: "Bottom chrome strip, mirror of chrome-bar."
stat-card:
borderTop: "1px solid {colors.border-dark}"
padding: "{spacing.gap-md} {spacing.gap-md} {spacing.gap-md} 0"
description: "Stat tile with a top hairline rule, big gold serif numeral above a sans label and mono note."
bullet-marker:
content: "—"
color: "{colors.gold}"
fontFamily: "{typography.label.fontFamily}"
description: "Em-dash bullet rendered in mono gold prefixes every list item."
vt-spine:
width: 1px
background: "{colors.border-dark}"
description: "Vertical hairline spine for timeline column, with a 9px gold dot marking each entry."
vt-dot:
width: 9px
height: 9px
borderRadius: 50%
background: "{colors.gold}"
description: "Gold node sitting on the timeline spine at each date."
pie-donut:
borderRadius: 50%
innerCutout: "22% inset, painted to match slide background"
description: "SVG/CSS donut chart, segments in palette colors with a 1px gold ring divider where used."
bar-fill-default:
background: "{colors.text-hint-dark}"
description: "Default bar fill in muted slate; switches to gold for the highlighted bar."
bar-fill-accent:
background: "{colors.gold}"
compare-divider:
borderRight: "1px solid {colors.border-dark}"
description: "Single vertical hairline separating two comparison panels."
pyramid-band:
borderLeft: "3px solid {colors.gold}"
padding: "1.3vh 2.5vw"
fillFunction: "color-mix(in srgb, {colors.gold} N%, {colors.navy})"
description: "Horizontal band in pyramid layouts; opacity of gold mix decreases from top tier to bottom."
grid-texture:
background: "linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px)"
backgroundSize: "80px 80px"
description: "Near-invisible 80px grid overlay applied to every dark slide via ::before pseudo-element."
cycle-step:
borderTop: "2px solid {colors.gold}"
padding: "{spacing.gap-md}"
description: "Cycle/process step card with a 2px gold rule at top, gold numeral, serif title, sans body."
---
## 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
Signal is a **literary editorial** presentation system — what a long-form intelligence briefing or a quarterly review from a serious magazine would look like if it ran as a deck. The visual premise is the marriage of two faces: a Scottish-roast editorial serif (Source Serif 4) carrying the voice, and a precision grotesque (DM Sans) carrying the substance, with a condensed monospace (IBM Plex Mono) for every timestamp, kicker, and piece of chrome metadata. The result reads like a quiet authority — the deck does not need to shout because the typography already telegraphs seriousness.
The system runs on a **dual-surface** model. The dark surface is `{colors.navy}` (#1C2644) — a deep editorial blue that sits warmer than navy and cooler than midnight. The light surface is `{colors.cream}` (#F0ECE3) — a warm aged-paper tone, never pure white. Both surfaces carry the same typographic vocabulary at the same scale; what changes is the foreground color. On dark surfaces, primary text is `{colors.text-warm}` (a warm off-white, never pure white). On cream, primary text is `{colors.ink}` (a near-black with a navy bias). The two surfaces are interchangeable from slide to slide — adjacent slides may alternate without any explanation, and the cream surface acts as a "reset" within a longer dark run.
There is exactly one accent color: **antique gold** (`{colors.gold}` — #C8A870). Gold appears only in three contexts: the short rule that separates a kicker from a headline; an `<em>` tag mixed into a roman serif headline (the "Signal moment"); and any numerical figure. Gold never carries a body paragraph and never fills a background. It is a precision tool, used sparingly so that when it appears, it carries weight.
Depth is **flat plus hairline**. There are no drop shadows, no rounded card chrome, no elevation system. Regions separate via 1px hairline rules in `{colors.border-dark}` (or `{colors.border-light}` on cream). The only "texture" in the system is a near-invisible 80px grid overlay on dark slides at 3% white opacity — visible only to the eye that's looking for it. It is the system's fingerprint.
**Density philosophy: medium-low and asymmetric.** Signal is an editorial system; it breathes. A typical slide uses a small fraction of its real estate — a kicker, a headline, a single sentence, a footer. The cover and chapter slides are the sparsest (one display headline against acres of cream or navy). The dense editorial layouts are the exception, not the rule, and even those leave generous interior padding. A slide that feels broken in Signal is one that fills the canvas edge-to-edge with content; the correct register is "I have one thing to say and I will say it carefully."
**Key Characteristics:**
- Source Serif 4 carries every headline with a roman/italic mix mid-sentence; italics in headlines are always gold.
- DM Sans for body and IBM Plex Mono for every timestamp, kicker, label, and chrome element.
- Dual surfaces — `{colors.navy}` (dark) and `{colors.cream}` (light) — used interchangeably, never blended in the same slide except in special split layouts.
- Antique gold (`{colors.gold}`) is the only accent. It marks rules, italic emphasis, and numerical figures, and appears nowhere else.
- Hairline 1px borders in `{colors.border-dark}` / `{colors.border-light}` separate every region. No card chrome, no rounded panels.
- A near-invisible 80px grid texture overlays every dark slide as a barely-perceived fingerprint.
- Em-dash bullet markers in gold mono replace the standard list dot.
- Mono uppercase chrome at the top of every standard slide carries a section label and a slide counter.
- No drop shadows, no gradients (except the bottom-up scrim on fullbleed image slides), no rounded corners (except the donut chart).
## Colors
### Palette
- **Navy** (`{colors.navy}` — #1C2644): The dark surface. A deep editorial blue, warmer than midnight, cooler than indigo. The "intelligence" color — authority without aggression.
- **Navy Alt** (`{colors.navy-alt}` — #232F55): A slightly lifted navy reserved for secondary dark surfaces (placeholder panels, image fallbacks). Visually nearly identical to navy; only differs in close adjacency.
- **Cream** (`{colors.cream}` — #F0ECE3): The light surface. A warm aged-paper tone, never neutral and never bright. Reads as "broadsheet" or "manuscript," not "screen white."
- **Cream Alt** (`{colors.cream-alt}` — #E6E0D4): A slightly cooler cream for secondary light surfaces. Same role as navy alt but on the light side.
- **Text Warm** (`{colors.text-warm}` — #E2DCD0): Warm off-white. The primary text color on navy surfaces. Never `#FFFFFF` — pure white would clash with the warm paper logic of the system.
- **Text Muted Dark** (`{colors.text-muted-dark}` — #8A96A8): Muted blue-grey. Secondary text on navy — descriptions, lead paragraphs that want to recede.
- **Text Hint Dark** (`{colors.text-hint-dark}` — #4E5A6E): Tertiary text on navy. Used for stat notes, mono captions, and elements that should be readable but quiet.
- **Ink** (`{colors.ink}` — #1A2030): Near-black with a navy bias. Primary text on cream. Picks up the dark surface color rather than fighting it.
- **Text Muted Light** (`{colors.text-muted-light}` — #5A6270): Secondary text on cream.
- **Text Hint Light** (`{colors.text-hint-light}` — #9AA0A8): Tertiary text on cream.
- **Gold** (`{colors.gold}` — #C8A870): Antique gold. The single accent color of the system. Appears on rules, italic emphasis inside headlines, statistical numerals, kicker labels, and bullet markers. Never used as a fill, never used on body text.
- **Border Dark** (`{colors.border-dark}` — #2E3D5C): Hairline divider on navy surfaces. Visible but quiet.
- **Border Light** (`{colors.border-light}` — #CAC4B4): Hairline divider on cream surfaces. Warm greige.
### Defaults
- **Default surface**: alternate between `{colors.navy}` (dark) and `{colors.cream}` (light) across the deck. There is no "primary" surface — both are first-class. If unsure, reach for navy for chapter openers and statement slides, cream for dense editorial reads.
- **Default primary text on navy**: `{colors.text-warm}`.
- **Default primary text on cream**: `{colors.ink}`.
- **Default secondary text on navy**: `{colors.text-muted-dark}`.
- **Default secondary text on cream**: `{colors.text-muted-light}`.
- **Default tertiary/hint text**: `{colors.text-hint-dark}` on navy, `{colors.text-hint-light}` on cream — for mono captions, stat notes, footnotes.
- **Default accent**: `{colors.gold}` — applied to rules, italic emphasis inside headlines, statistical figures, kicker labels.
- **Default border**: `{colors.border-dark}` on navy, `{colors.border-light}` on cream.
- **Default kicker color**: `{colors.gold}`.
The two surfaces are interchangeable and carry the same gold accent — a gold rule on navy reads identically to a gold rule on cream. Body text never appears in gold. Gold never serves as a region fill.
## Typography
### Font Family
Signal runs four font families in carefully separated roles:
- **Source Serif 4** (`{typography.display.fontFamily}`) — a Scottish-roast editorial serif. Carries every headline at every scale (display, h1, h2, h3, editorial-headline, dense-headline, quote-text, stat-value). The face has a full italic axis, and the system's most distinctive typographic move is **mixing roman and italic mid-sentence**: the roman type carries the sentence and an `<em>` tag inside switches to italic in `{colors.gold}`. This is the "Signal moment."
- **DM Sans** (`{typography.body.fontFamily}`) — a humanist grotesque used for body, lead paragraphs, bullet items, and stat labels. DM Sans is the structural understudy — it never leads, it always supports. When `<em>` appears inside a sans `.lead` paragraph, the emphasis switches to **italic serif in gold** (a font-family change), not italic sans.
- **IBM Plex Mono** (`{typography.label.fontFamily}`) — a condensed editorial monospace. Carries every label, every kicker, every chrome element (top bar, footer, slide counter), every chapter number, every mono caption, every stat note, every timeline date. Mono is the system's "metadata voice."
- **Noto Serif SC / Noto Sans SC** — Chinese fallbacks for the serif and sans roles. Wired into every font-family stack so the system renders identically with Chinese content.
The emotional contrast is: serif = voice, sans = substance, mono = timestamp. Mixing them in one sentence (a sans lead with an italic serif gold `<em>` inside) is the system's small choreography.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | 9.5vw | Source Serif 4 | 700 | Hero cover headline at maximum scale |
| `{typography.h1}` | 5.2vw | Source Serif 4 | 600 | Chapter title or single-statement headline |
| `{typography.stat-value}` | 5.5vw | Source Serif 4 | 600 | Large statistical numeral in gold |
| `{typography.quote-mark}` | 8vw | Source Serif 4 | 300 | Decorative opening quotation glyph in gold |
| `{typography.quote-text}` | 3.6vw | Source Serif 4 | 400 | Pull-quote body |
| `{typography.h2}` | 3vw | Source Serif 4 | 600 | Primary slide headline |
| `{typography.editorial-headline}` | 2.75vw | Source Serif 4 | 600 | Headline for editorial / newsletter layouts |
| `{typography.dense-headline}` | 2.4vw | Source Serif 4 | 600 | Headline for two-column dense text layouts |
| `{typography.h3}` | 1.9vw | Source Serif 4 | 500 | Sub-headline, panel title, intra-region heading |
| `{typography.lead}` | 1.4vw | DM Sans | 400 | Lead paragraph, intro sentence, list item body |
| `{typography.body}` | 1.05vw | DM Sans | 400 | Paragraph body, bullet body |
| `{typography.caption}` | 0.82vw | DM Sans | 400 | Caption, footnote, source attribution |
| `{typography.label}` | 0.7vw | IBM Plex Mono | 500 | Mono uppercase chrome label, kicker, tag, mono metadata |
### Defaults
- **Default size for a primary section headline**: `{typography.h2}` (3vw).
- **Default size for a chapter opener**: `{typography.h1}` (5.2vw).
- **Default size for a cover hero**: `{typography.display}` (9.5vw).
- **Default size for a paragraph**: `{typography.body}` (1.05vw).
- **Default size for a lead sentence beneath a headline**: `{typography.lead}` (1.4vw).
- **Default size for any chrome, kicker, or metadata label**: `{typography.label}` (0.7vw).
- **Default size for a statistical numeral**: `{typography.stat-value}` (5.5vw), in `{colors.gold}`.
- **Default headline color**: primary text color for the surface (`{colors.text-warm}` on navy, `{colors.ink}` on cream). Never gold.
When unsure between `{typography.h2}` and `{typography.h3}` for a primary moment, reach for `{typography.h2}` — `h3` is for sub-headlines within a region, not for the slide's main statement.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **An `<em>` tag inside any serif headline (`display`, `h1`, `h2`, `h3`, `editorial-headline`, `dense-headline`) must render in italic Source Serif 4 in `{colors.gold}`.** This is the system's most distinctive typographic moment — mixing roman and italic mid-sentence with a color shift. A headline with an emphasized phrase without this treatment reads as a different design system.
- **An `<em>` tag inside a sans `.lead` or body paragraph must switch font-family to Source Serif 4, italic, in `{colors.gold}`.** Emphasis in body never stays in DM Sans italic — the font switch is the emphasis.
- **Every kicker is mono uppercase in `{colors.gold}` with at least 0.14em letter-spacing.** A kicker that is sans, lowercase, or not in gold is not a kicker.
- **Every statistical numeral is in Source Serif 4 600 in `{colors.gold}` with -0.02em letter-spacing.** Stats in sans, or stats in primary text color, break the system.
- **Every chrome bar carries a 1px hairline rule beneath it in `{colors.border-dark}` / `{colors.border-light}`.** The hairline is what makes the chrome read as chrome rather than as floating text.
- **Every chapter slide carries a 36px gold rule between the chapter number and the chapter title.** The rule is the section break — no rule, no chapter.
- **Bullet lists use an em-dash in mono gold as the marker.** Standard dot bullets do not exist in this system.
### Typography Principles
The font ladder is fixed: serif for voice (display through h3), sans for substance (lead through caption), mono for metadata (label only). Never use serif for body, never use sans for headlines, never use mono outside metadata roles. Crossing those rails breaks the editorial separation.
Italic is structural, not decorative — it is the emphasis vehicle inside headlines and inside lead paragraphs. Underline does not exist. Bold within body does not exist; if body needs emphasis, switch to the italic serif gold `<em>` pattern.
Line-height runs tight at display scale (0.96 on display, 1.08 on h1) and opens as size decreases (1.5–1.72 on caption and body). Letter-spacing is negative on display and h1 (–0.01 to –0.02em) and zero on body. Mono labels carry tracking of 0.14em to 0.22em — generous letter-spacing is how mono reads as editorial rather than as code.
## Layout
### Canvas System
The system targets `100vw × 100vh` — full viewport. Each `.slide` flexes to fill the viewport exactly, and slides sit side-by-side in a horizontal strip that translates left/right on navigation. All sizes use viewport-relative units (`vw`, `vh`) so the layout scales with window size — there are no fixed pixel measurements except chrome dot/counter sizes.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 7.5vw | Horizontal slide padding |
| `{spacing.pad-y}` | 5.5vh | Vertical slide padding |
| `{spacing.gap-lg}` | 4vh | Between major content sections |
| `{spacing.gap-md}` | 2.5vh | Between related elements |
| `{spacing.gap-sm}` | 1.2vh | Between tightly coupled elements |
Quote slides increase pad-x to 1.1× and pad-y to 1.2× to give the pull-quote extra breathing room. Compare layouts use `pad-x * 0.55` as inset padding on each panel.
### Chrome Frame
Standard slides carry a top chrome bar and a bottom foot bar — both are flex rows with a mono label left, mono counter right, separated from the body by a 1px hairline rule. The chrome and foot disappear on cover, chapter, statement, quote, and end slides — those layouts are chromeless and let the type breathe edge to edge.
Each slide is a CSS grid with `grid-template-rows: auto 1fr auto` — the chrome and foot are the auto rows, the body is the 1fr row that fills.
### Grid Texture
Every dark slide carries a near-invisible 80px × 80px grid overlay drawn with two linear-gradient backgrounds at 3% white opacity. The grid is the system's visual fingerprint — it is not meant to be consciously perceived, only sensed as "this slide has structure." Cream slides do not carry this overlay.
## Depth and Elevation
Signal is **flat by design**. There are no drop shadows. There are no rounded card elevations. There is no elevation system at all — every element sits flush with the surface.
What looks like depth is actually **hairline separation**. Regions separate via 1px solid borders in `{colors.border-dark}` (on navy) or `{colors.border-light}` (on cream). A stat tile, a chrome bar, an editorial column — all separated by hairlines, not by shadows or backgrounds.
The single exception is the **fullbleed gradient scrim**: on fullbleed image slides, a linear gradient from transparent to `rgba(15, 20, 36, 0.9)` runs bottom-up across the lower portion of the slide so the type beneath remains legible against the image. This is the only gradient in the system; everywhere else, surfaces are solid.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0 | Every shape in the system except donut charts and donut center wells |
| 50% (circle) | Donut chart shapes, the 9px timeline dots, the 2px round-ended border on swatches |
| 2px | Pie legend swatch (subtle softening only) |
Signal has effectively **no rounded chrome**. Stat tiles, chrome bars, compare panels, image frames — all rectangular with sharp corners.
### Border Weights
- **1px solid** — the universal hairline border. Used on every chrome bar, every stat tile top rule, every column divider, every compare panel divider, every editorial column boundary. Color follows the surface (`{colors.border-dark}` or `{colors.border-light}`).
- **1px dashed** — used only inside the chart plot for grid lines (rgba transparency, very low opacity).
- **2px solid `{colors.gold}`** — used on the top rule of a cycle/process step.
- **3px solid `{colors.gold}`** — used as the left-border on pyramid bands.
### Decorative Element Types
**Short gold rule** — a 36px × 1px solid gold horizontal bar. Sits between a kicker and a headline, or as a chapter accent mark. The smallest atomic decorative element in the system.
**Full hairline rule** — a 100% × 1px horizontal rule in `{colors.border-dark}` / `{colors.border-light}`. Used as section dividers, chrome separators, stat-tile top edges, column boundaries.
**Outlined gold tag** — a small inline-block with a 1px gold border around mono uppercase gold text. The "pill" version of a kicker — same typographic spec, with an outline.
**Editorial column divider** — a 1px hairline running floor-to-ceiling between two columns in editorial layouts. Padding inside the columns is `pad-x * 0.38`.
**Vertical timeline spine** — a 1px vertical hairline running the height of a vertical timeline, with 9px circular gold dots positioned at each entry along the spine.
**Pyramid band** — a horizontal band with a 3px solid gold left-border, filled with `color-mix(in srgb, gold N%, navy)` where N decreases from 70% at the top tier to 8% at the bottom tier. Each tier is also progressively wider (38% → 100%). This creates the visual pyramid through color saturation and width, without any actual triangular geometry.
**Donut center well** — the inner 22% inset of a pie donut is filled with the slide background color (navy or cream) to create the donut hole.
**Connector arrow** — in cycle and diagram layouts, a low-contrast arrow glyph in `{colors.border-dark}` (or `{colors.border-light}`) sits between sequential steps. The arrow is intentionally muted — the steps lead, the connector recedes.
**Mono dash bullet** — every list item carries an em-dash (`—`) in mono gold as the bullet marker, with a 1.2em column for the marker and 0.5em gap.
## Do's and Don'ts
### Do
- Mix roman and italic Source Serif 4 inside the same headline, with the italic in `{colors.gold}` — this is the Signal moment, and the system depends on it appearing throughout the deck.
- Use IBM Plex Mono for every kicker, label, tag, chrome element, slide counter, chapter number, and statistical note. Mono is the metadata voice.
- Render every kicker in mono uppercase gold with at least 0.14em letter-spacing — the tracking is what makes mono read as editorial.
- Set every chrome bar to carry a 1px hairline beneath it in the surface-appropriate border color. The hairline is non-negotiable; chrome without a rule reads as floating text.
- Alternate navy and cream surfaces freely across a deck. Neither is "the" background — both are first-class.
- Color every statistical numeral in `{colors.gold}` using Source Serif 4 600 with -0.02em tracking. Stats are the second most-recognizable element after the italic gold headline emphasis.
- Replace standard bullet dots with em-dashes in mono gold. Standard dots break the editorial register.
- Use the 36px gold rule as the chapter break and the kicker separator. It is the system's small punctuation.
- Apply the 80px grid texture overlay to every dark slide via `::before`. It is the system's fingerprint and should never be removed.
- Pad with `{spacing.pad-x}` 7.5vw / `{spacing.pad-y}` 5.5vh — Signal needs the breathing room; tight padding breaks the editorial restraint.
### Don't
- Don't use gold on body text or fill backgrounds with gold. Gold appears only on rules, italic emphasis, and numerical figures.
- Don't use pure white (`#FFFFFF`) for text on navy. Always use `{colors.text-warm}` — the warm off-white is what keeps the system tied to its paper register.
- Don't add drop shadows or rounded card chrome. The system is flat-plus-hairline; elevation breaks the editorial frame.
- Don't put serif type on body or paragraph text. The serif/sans separation is structural — serif leads, sans supports.
- Don't bold inside body text for emphasis. Use the italic serif gold `<em>` pattern instead — the font switch is the emphasis.
- Don't round corners on chrome, panels, stat tiles, or image frames. The only round shapes in the system are the donut chart and the 9px timeline dots.
- Don't introduce a second accent color. Antique gold is the only hot color; adding a second accent dilutes its weight.
- Don't fill more than half a typical slide with content. The system reads as broken when crowded — restraint is the register.
- Don't use mono outside metadata roles (label, kicker, chrome, counter, caption note). Mono in body or headline breaks the typographic ladder.
- Don't omit the 1px hairline beneath chrome or above a stat tile. Hairlines are the system's depth substitute; without them the elements float.
## Responsive Behavior
Signal targets a 1920×1080 viewport but is implemented entirely in viewport-relative units (`vw`, `vh`), so it scales fluidly between 1280×720 and 2560×1440 without breakpoints. The 80px grid texture is the only fixed-pixel measurement that persists across viewport changes — it becomes proportionally finer at larger viewports.
### Scaling Behavior
- Display headline scales with viewport: at 1920px, 9.5vw renders as ~182px. At 1280px, ~122px.
- Body text scales: 1.05vw → ~20px at 1920px, ~13px at 1280px.
- Padding scales: pad-x 7.5vw → ~144px at 1920px, ~96px at 1280px.
### Presenter Behavior
The deck is JS-driven. Slides advance via the navigation strip (translateX on the deck container), with nav dots and a slide counter fixed at the bottom. Each slide carries `is-active` when current; elements with `[data-anim]` attributes animate in via fade-up, fade-in, reveal-right, reveal-left, or scale-in keyframes with staggered `data-delay` (0–6). Animations are short (0.5–0.85s) and use a sharp `cubic-bezier(0.77, 0, 0.175, 1)` slide ease and a spring-y `cubic-bezier(0.16, 1, 0.3, 1)` entrance ease.
### Print Behavior
There is no dedicated print stylesheet. Static export should render each slide as a sequential page; the deck container's horizontal layout would need to be unwound for print fidelity.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headlines (h1, h2, h3) / Stat-value / Quote-text / Editorial-headline / Dense-headline | Source Serif 4 (500–700) | **思源黑体 Noto Sans SC** | 700 |
| Lead / Body / Caption | DM Sans (400) | **思源黑体 Noto Sans SC** | 400 |
| Label / Kicker / Chrome / Slide counter | IBM Plex Mono (500) | **思源黑体 Noto Sans SC** | 500 (uppercase + tracking removed) |
### Mixed-Content Strategy
**Strategy A — single CJK family (思源黑体 Noto Sans SC) across all roles.** Signal's Latin system already wires Noto Serif SC and Noto Sans SC into every font-family stack as fallbacks — the system was designed with CJK in mind. The recommended consolidation is to use **Noto Sans SC for every role** rather than mixing Noto Serif SC (display) + Noto Sans SC (body) — and the reason is the system's most distinctive treatment: the gold italic `<em>` emphasis inside headlines. Noto Serif SC does not ship an italic axis, which means the Signal moment (roman-to-italic mid-sentence color shift) cannot be reproduced in Chinese. Collapsing to Noto Sans SC across the system and reserving the color-only emphasis (gold without italic) for CJK `<em>` lands cleaner than fighting an italic-less serif. The serif vs sans contrast that defines the Latin ladder is lost in CJK, but the editorial restraint of the system — hairlines, mono kickers, antique gold accents, dual surfaces — carries through unaffected.
### Loading
The system already loads Noto Sans SC via the existing font-family stacks. If using a CDN preconnect pattern:
```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">
```
The existing CSS variables already include Noto Sans SC and Noto Serif SC in every font stack. For a CJK-primary deck, swap the serif stacks to use Noto Sans SC as the active CJK face (rather than Noto Serif SC) so the entire system collapses to one Chinese family:
```css
/* Display / headline roles (CJK-primary) */
font-family: 'Source Serif 4', 'Noto Sans SC', Georgia, serif;
/* Body roles */
font-family: 'DM Sans', 'Noto Sans SC', system-ui, sans-serif;
/* Mono roles */
font-family: 'IBM Plex Mono', 'Noto Sans SC', monospace;
```
### Universal CJK Adjustments
- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence
### Aesthetic Notes for This System
- **The Signal moment (italic gold `<em>` mid-sentence) becomes color-only on CJK.** Noto Sans SC has no italic variant; even Noto Serif SC ships without italic. For Chinese headlines, render `<em>` as a color shift to `{colors.gold}` *without* italic — the emphasis still lands because gold is the system's most-loaded color. Treat this as a deliberate translation of the Signal moment to its color-only essence in CJK.
- **Negative letter-spacing on display (-0.02em on display, -0.01em on h1/h2) must drop to 0 on CJK.** The system's tight tracking is a Latin-display convention that breaks CJK rendering.
- **Mono kickers in IBM Plex Mono uppercase with 0.14–0.22em tracking are Latin-only.** For CJK kickers, drop tracking to 0 and rely on the gold color + small size to signal "this is a kicker." A mixed CJK + Latin kicker (`第一章 / CHAPTER ONE`) can keep the Latin half tracked and the CJK half at 0 tracking — the asymmetric mono voice reads as editorial bilingualism.
- **Statistical numerals at Source Serif 4 600 in gold** remain Latin numerals (the Western-numeral convention for stats is universal in modern editorial design). Don't substitute Chinese numerals (一二三四) — they lose the catalogue-statistical voice.
- **The em-dash bullet (`—` in mono gold) translates perfectly** — em-dash bullets are equally idiomatic in Chinese typography.
- **The 80px grid texture, hairline borders, dual surface (navy + cream), gold rules, chapter slides, fullbleed image scrim, chromeless statement layouts** are all glyph-agnostic. The editorial restraint and intelligence-briefing register carry through unaffected.
- **Line-height on CJK body should open from 1.58–1.72 to 1.75–1.85** — Chinese characters fill their em-box and need additional vertical breathing for readability at the system's body sizes (1.05vw, 1.4vw).
- **Quote-mark glyph (the 8vw decorative opening quotation)** should switch to a Chinese opening guillemet (「) or curly quote (") — Latin opening-quote glyphs read as alien on Chinese pull-quotes.
### Known CJK Gap
The system's most distinctive typographic treatment (roman + italic-gold mid-sentence inside Source Serif 4 headlines) is fundamentally a Latin-typographic move that does not translate. Neither Noto Serif SC nor Noto Sans SC ships an italic axis, and inventing one via CSS `font-style: italic` produces an oblique/slanted glyph that reads as broken rather than as emphasis. Collapsing CJK `<em>` to a color-only shift (gold without italic) is the cleanest workaround; mixed-language headlines where the emphasized phrase is Latin (and therefore can take italic gold) and the surrounding sentence is Chinese will land as the strongest CJK execution of the Signal moment.
## Iteration Guide
1. Any new headline uses Source Serif 4 and is eligible for an `<em>` mid-sentence in italic gold. If the headline has no emphasized phrase, consider whether it should — the Signal voice depends on the gold italic moment appearing.
2. Any new region separator is a 1px hairline in `{colors.border-dark}` / `{colors.border-light}`. Never a thicker border, never a colored border, never a shadow.
3. Any new label, kicker, or chrome element is mono uppercase in `{colors.gold}` (for kickers) or surface-appropriate muted color (for chrome). Letter-spacing at least 0.14em.
4. Any new statistical figure uses Source Serif 4 600 in `{colors.gold}` at -0.02em tracking. Stats are always gold serif, regardless of surface.
5. Any new accent treatment uses `{colors.gold}` — there is no second accent. If a slide needs more visual differentiation, vary the surface (navy vs. cream) rather than adding color.
6. Any new bullet list uses the em-dash gold mono marker. Adding a different bullet style breaks the system.
7. Cover, chapter, statement, quote, and end layouts are chromeless. Standard layouts carry chrome and foot. Don't mix — a chromeless statement is correct; a chromed statement reads as a different system.
8. The 80px grid overlay is part of the dark-surface identity. Any new dark slide should inherit `.slide.dark` so the `::before` overlay applies automatically.
9. New layouts should keep the editorial breathing room. If a layout requires content edge-to-edge, reconsider — Signal is a restrained system.
10. Italic in body text always means font-family switch to Source Serif 4 italic in `{colors.gold}`. Italic DM Sans is not a system primitive.
## Known Gaps
- The four font families load from Google Fonts at runtime. If fonts fail to load (network issues, ad blockers), fallbacks are Georgia (for serif), system-ui (for sans), and Courier-style monospace — the resulting rendering loses much of the editorial character but remains legible.
- Chinese fallbacks (Noto Serif SC, Noto Sans SC) are wired into every font-family stack but render slightly different metrics from the Latin faces; pure Chinese decks will read slightly tighter.
- The 80px grid texture is a magic number tied to viewport scale; at very large viewports (>2560px), the grid may begin to feel coarse rather than imperceptible.
- The slide navigation is JavaScript-driven with hardcoded `transform: translateX(...)` on the deck container. The system depends on this engine; replacing it requires preserving the `is-active` class behavior for animations to fire.
- The `--c-bg-alt`, `--c-bg-light-alt`, and several muted color tokens are defined but used sparingly — they exist as a reserve for adjacent-surface differentiation that the source template uses only occasionally.
- The pyramid layout uses `color-mix(in srgb, ...)` which requires modern browser support; older browsers may render bands as flat fill rather than tiered.
- The fullbleed slide gradient is hardcoded to `rgba(15, 20, 36, 0.9)` (close to navy but not parameterized via a token). Changing the navy color requires updating this gradient in parallel.
# Signal Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/signal/design.md`
- Preview card: `bold-template-pack/templates/signal/preview.md`
## Selection Metadata
- Slug: `signal`
- Tagline: Deep navy canvas with bone paper and a single muted-gold accent; institutional with quiet weight.
- Mood: institutional, trustworthy, considered, weighty
- Tone: sober, polished, established, literary
- Formality: high
- Density: high
- Scheme: mixed
- Best for: Anything that should feel weighty, considered, and credibly institutional: investor decks, board presentations, consulting deliverables, legal / policy briefs, advisory pitches. Also a strong choice for tech, research, or brand work that wants to read as quietly authoritative rather than loud.
- Avoid for: Contexts that should feel hot, fast, or intentionally playful — the navy + gold restraint commits to a sober voice.
## Visual Snapshot
A literary editorial presentation system in the spirit of a long-form magazine — The Economist's restraint crossed with a private intelligence briefing. Source Serif 4 carries every headline with roman/italic mixing mid-sentence in antique gold, DM Sans steps back for body, and IBM Plex Mono runs all the timestamps, kickers, and chrome. The dual surface system is warm cream paper (#F0ECE3) and deep editorial navy (#1C2644), connected by a single hot accent — antique gold (#C8A870) — used only on rules, italic emphasis, and numerical figures. A near-invisible 80px grid texture overlays every dark slide as a fingerprint. The effect is sober, considered, and a little bit aristocratic.
Signal is a literary editorial presentation system — what a long-form intelligence briefing or a quarterly review from a serious magazine would look like if it ran as a deck. The visual premise is the marriage of two faces: a Scottish-roast editorial serif (Source Serif 4) carrying the voice, and a precision grotesque (DM Sans) carrying the substance, with a condensed monospace (IBM Plex Mono) for every timestamp, kicker, and piece of chrome metadata. The result reads like a quiet authority — the deck does not need to shout because the typography already telegraphs seriousness.
## Preview Ingredients
- Palette: navy #1C2644; navy-alt #232F55; cream #F0ECE3; cream-alt #E6E0D4; text-warm #E2DCD0; text-muted-dark #8A96A8; text-hint-dark #4E5A6E; ink #1A2030
- Typography: Source Serif 4; DM Sans; IBM Plex Mono; {typography.label.fontFamily}
- Signature move: Source Serif 4 carries every headline with a roman/italic mix mid-sentence; italics in headlines are always gold.
- Signature move: DM Sans for body and IBM Plex Mono for every timestamp, kicker, label, and chrome element.
- Signature move: Dual surfaces — {colors.navy} (dark) and {colors.cream} (light) — used interchangeably, never blended in the same slide except in special split layouts.
- Signature move: Antique gold ({colors.gold}) is the only accent. It marks rules, italic emphasis, and numerical figures, and appears nowhere else.
- Signature move: Hairline 1px borders in {colors.border-dark} / {colors.border-light} separate every region. No card chrome, no rounded panels.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Soft Editorial
description: A warm magazine spread aesthetic — the kind of layout a small print quarterly with field-notes pretensions would commission. Cormorant Garamond carries every headline and ornamental moment with mixed roman and italic; Work Sans recedes into supporting body. The palette is cream paper with a quartet of pastel candy accents (dusty pink, chartreuse lemon, soft peach blush, sage green, lilac) used as colored card backgrounds. Generous rounded cards (24–36px radius) float on translucent white over the cream field. The mood is editorial calm with a sprinkling of riso-print color — closer to a literary research notebook than a corporate deck.
colors:
paper: "#F2EEDF"
paper-2: "#ECE6D2"
ink: "#2A241B"
ink-soft: "#5C5345"
pink: "#E1A4C2"
lemon: "#D6DD63"
blush: "#E8C9B6"
sage: "#B7C7A8"
lilac: "#C9BEDC"
card-fill: "rgba(255,255,255,0.55)"
rule-soft: "rgba(42,36,27,0.18)"
rule-medium: "rgba(42,36,27,0.35)"
color-aliases:
background: paper
text-primary: ink
text-secondary: ink-soft
typography:
display:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 232px
fontWeight: 500
lineHeight: 0.92
letterSpacing: -0.02em
title:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 188px
fontWeight: 500
lineHeight: 0.95
letterSpacing: -0.015em
closer:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 168px
fontWeight: 500
lineHeight: 0.95
letterSpacing: -0.015em
numeral-hero:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 320px
fontWeight: 500
lineHeight: 0.9
letterSpacing: -0.02em
numeral-lg:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 200px
fontWeight: 500
lineHeight: 0.9
letterSpacing: -0.02em
panel-headline:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 124px
fontWeight: 500
lineHeight: 0.98
letterSpacing: -0.01em
section-headline:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 96px
fontWeight: 500
lineHeight: 0.98
letterSpacing: -0.01em
page-headline:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 88px
fontWeight: 500
lineHeight: 1
letterSpacing: -0.01em
quote-text:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 88px
fontWeight: 500
lineHeight: 1.05
letterSpacing: -0.01em
quote-mark:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 220px
fontWeight: 500
lineHeight: 0.7
fontStyle: italic
card-headline:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 72px
fontWeight: 500
lineHeight: 1
letterSpacing: -0.01em
drop-cap:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 132px
fontWeight: 500
lineHeight: 0.85
opener:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 56px
fontWeight: 500
fontStyle: italic
lineHeight: 1.1
numeral-step:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 92px
fontWeight: 500
fontStyle: italic
lineHeight: 0.9
numeral-card:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 64px
fontWeight: 500
fontStyle: italic
lineHeight: 1
subhead-lg:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 56px
fontWeight: 500
fontStyle: italic
lineHeight: 1.1
subhead-md:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 44px
fontWeight: 500
lineHeight: 1.05
subhead-sm:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 38px
fontWeight: 500
lineHeight: 1.05
kicker:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 38px
fontWeight: 400
fontStyle: italic
lineHeight: 1.2
marker:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 32px
fontWeight: 400
fontStyle: italic
lineHeight: 1.3
card-sub:
fontFamily: "Work Sans, sans-serif"
fontSize: 32px
fontWeight: 500
lineHeight: 1.1
eyebrow:
fontFamily: "Work Sans, sans-serif"
fontSize: 28px
fontWeight: 400
letterSpacing: -0.005em
page-marker:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 26px
fontWeight: 400
fontStyle: italic
footer:
fontFamily: "Cormorant Garamond, Garamond, serif"
fontSize: 26px
fontWeight: 400
fontStyle: italic
body:
fontFamily: "Work Sans, sans-serif"
fontSize: 26px
fontWeight: 400
lineHeight: 1.5
body-md:
fontFamily: "Work Sans, sans-serif"
fontSize: 24px
fontWeight: 400
lineHeight: 1.5
attr:
fontFamily: "Work Sans, sans-serif"
fontSize: 24px
fontWeight: 500
lineHeight: 1.3
swatch-label:
fontFamily: "Work Sans, sans-serif"
fontSize: 11px
fontWeight: 400
letterSpacing: 0.06em
textTransform: uppercase
spacing:
pad-outer: 80px
pad-top: 60px
pad-bottom: 50px
card-pad-lg: "64px 48px"
card-pad-md: "48px 52px"
card-pad-sm: "28px 30px"
gap-cards: 28px
gap-cards-lg: 36px
gap-stack: 36px
canvas:
width: 1920px
height: 1080px
components:
card-soft:
background: "{colors.card-fill}"
borderRadius: "24px to 36px"
padding: "{spacing.card-pad-sm} to {spacing.card-pad-lg}"
description: "Translucent white card floating on the cream field. The system's default container — used for stats, columns, panels, content blocks."
card-color:
background: "any of pink, lemon, blush, sage, lilac"
borderRadius: "22px to 36px"
padding: "{spacing.card-pad-sm}"
description: "Saturated pastel card containing numerals, step content, or featured items. Text stays ink/ink-soft on every accent fill — never inverted."
pill:
borderRadius: "999px"
padding: "4px 14px"
fontWeight: 500
description: "Status pill in a pastel fill (lemon=yes, blush=partial, pink=no) or translucent white with a soft border for notes."
swatch-dot:
width: 56px
height: 56px
borderRadius: "50%"
description: "Circular accent disc shown in a row at the top of cover slides — the visual signature of the system's color palette."
swatch-tile:
aspectRatio: "1/1.2"
borderRadius: "16px"
description: "Rounded rectangle paint chip used in palette displays and design-system layouts."
rule-dashed:
borderColor: "{colors.rule-soft}"
borderStyle: "dashed"
borderWidth: "1px"
description: "1px dashed warm-ink hairline used inside matrix tables, panel dividers, and any subdivision that wants to read softer than a solid rule."
rule-solid:
borderColor: "{colors.rule-medium}"
borderStyle: "solid"
borderWidth: "1.5px"
description: "Slightly heavier hairline for major dividers inside cards (head-row underlines, column rules)."
drop-cap:
typography: "{typography.drop-cap}"
float: "left"
description: "First letter of an opener paragraph floats left at ~132px, line-height 0.85, with 8px 14px 0 0 padding. The visible signature of editorial reads."
legend-bar:
width: 28px
height: 12px
borderRadius: "6px"
description: "Rounded color bar used as a chart legend swatch."
marker-rule:
width: "auto"
borderTop: "1px dashed {colors.rule-soft}"
description: "Dashed top-rule used to mark source attributions or sign-offs beneath content."
action-bar:
background: "{colors.lemon}"
borderRadius: "24px"
padding: "24px 36px"
description: "Lemon-yellow action band running near the top of a slide, containing a tag separator and a serif headline — used for important CTAs or callouts."
chrome-eyebrow:
position: "absolute top-left at 60px / 80px"
typography: "{typography.eyebrow}"
color: "{colors.ink}"
description: "Section name in plain sans, sits at the top-left corner of standard slides."
chrome-pagedot:
position: "absolute top-right at 60px / 80px"
typography: "{typography.page-marker}"
color: "{colors.ink-soft}"
description: "Roman or arabic page numeral in italic serif at the top-right corner."
chrome-footer:
position: "absolute bottom at 50px"
typography: "{typography.footer}"
color: "{colors.ink-soft}"
description: "Two-column italic serif footer running across the bottom — date left, publication name right."
---
## 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
Soft Editorial is a **warm magazine spread** presentation system that takes its visual cues from small-press literary quarterlies and design-research notebooks. The premise is a single typeface (Cormorant Garamond) doing nearly all the talking, supported by a sober humanist sans (Work Sans) only where the serif would tire. The cream paper field is the constant — every slide sits on `{colors.paper}` (#F2EEDF), a warm aged-cream that reads as physical paper, not screen white. On top of the field, rounded cards float in two registers: translucent white softness for default content, and saturated pastel candy for accent moments.
The typography system is **single-family with mixed style**. Headlines are Cormorant Garamond medium (weight 500), but a roman headline often carries an `<em>` mid-sentence that switches to italic at weight 400 — the italic phrase is a lighter weight of the same family, which gives the system its characteristic "gentle emphasis" tone. Italic also runs the small ornamental text (kickers, markers, page numerals, sign-offs, opener paragraphs, step numerals). Work Sans steps in only for body paragraphs, eyebrows, and a small set of meta labels where the serif's personality would be too much.
The color philosophy is **cream plus five pastels**. The pastels — dusty pink (`{colors.pink}`), chartreuse lemon (`{colors.lemon}`), soft peach blush (`{colors.blush}`), sage green (`{colors.sage}`), and lilac (`{colors.lilac}`) — are interchangeable card fills. None of them carries a fixed semantic role (lemon is not "warning," pink is not "error"). They are color paints — the deck cycles through them for variety, often with three or four visible on a single slide. Text on every pastel surface stays in `{colors.ink}` (a warm near-black, #2A241B). The system never inverts text color on accent surfaces.
Depth comes from **soft rounded cards** with large border-radius values (24–36px on default cards; up to 999px on pills) and translucent white fills that sit slightly above the cream field. There are no drop shadows — depth is implied by the translucency and the rounded form. Hairlines inside cards are dashed in a warm ink with low opacity, which reinforces the "notebook" feel.
**Density philosophy: medium-high inside cards, generous between cards.** The cards themselves can hold substantial content — multi-column matrices, dense step grids, lengthy quoted text. But the slide canvas leaves comfortable air around them: 80px outer padding, 28–36px gaps between cards, plenty of cream field showing through. A slide that feels broken in this system is either (a) cards crammed together with no breathing field, or (b) a slide so sparse that the paper field reads as empty rather than as a deliberate margin. The target is "a generously laid-out magazine page where the cards group, breathe, and lead the eye."
**Key Characteristics:**
- Single warm cream surface (`{colors.paper}`) across every slide; pastels appear only as card fills, never as the slide background (except the full-bleed closer slide which fills with `{colors.pink}`).
- Cormorant Garamond carries every display, headline, kicker, and ornamental moment; Work Sans is reserved for body and eyebrows.
- Mixed roman + italic inside headlines is the system's typographic signal — italic phrases drop to weight 400 from the headline's weight 500.
- Saturated pastels (`{colors.pink}`, `{colors.lemon}`, `{colors.blush}`, `{colors.sage}`, `{colors.lilac}`) are interchangeable card fills with no fixed semantic meaning.
- Rounded cards (24–36px radius) are the default container; pills are fully rounded (999px); translucent white (`{colors.card-fill}`) is the default card fill.
- No drop shadows. Depth comes from translucency on top of the cream field and from the cards' rounded chrome.
- Page chrome is italic serif (page numerals and footers) plus plain sans (eyebrows) — never mono, never uppercase.
- Drop caps appear at the start of long-form opener paragraphs at ~132px Cormorant Garamond medium.
## Colors
### Palette
- **Paper** (`{colors.paper}` — #F2EEDF): The cream page. The default slide background, the constant across the deck. Warm and aged, never bright.
- **Paper Alt** (`{colors.paper-2}` — #ECE6D2): A slightly cooler cream reserved for adjacent-surface separation. Used sparingly; many decks never reach for it.
- **Ink** (`{colors.ink}` — #2A241B): Warm near-black with a brown bias. Primary text color on every surface — never pure black.
- **Ink Soft** (`{colors.ink-soft}` — #5C5345): A muted warm grey-brown. Secondary text — captions, leads, descriptions, page markers, sign-offs.
- **Pink** (`{colors.pink}` — #E1A4C2): Dusty rose pastel. The most-used accent fill — appears on cover swatches, step cards, full-bleed closer slides, status pills (where it reads as "no" in matrices).
- **Lemon** (`{colors.lemon}` — #D6DD63): Chartreuse yellow-green. The brightest accent — used on hero numeral cards, action bars, "yes" pills.
- **Blush** (`{colors.blush}` — #E8C9B6): Soft peach. The most neutral of the pastels — used on step cards, "partial" pills, and any slot needing warm neutrality.
- **Sage** (`{colors.sage}` — #B7C7A8): Muted green. The "extra" accent that joins for variety — process diagrams, design-system grids, secondary step cards.
- **Lilac** (`{colors.lilac}` — #C9BEDC): Soft violet-grey. The cool counterpart to sage — appears mostly in five-step process flows where all five pastels rotate.
- **Card Fill** (`{colors.card-fill}` — rgba(255,255,255,0.55)): Translucent white. The default card background — sits on the cream field as a "lifted" surface without committing to a saturated color.
- **Rule Soft** (`{colors.rule-soft}` — rgba(42,36,27,0.18)): Low-opacity warm ink for dashed internal hairlines.
- **Rule Medium** (`{colors.rule-medium}` — rgba(42,36,27,0.35)): Slightly heavier hairline for major dividers inside cards.
### Defaults
- **Default slide background**: `{colors.paper}` — every standard slide.
- **Default primary text color**: `{colors.ink}` — on every surface, including all pastel cards. Text is never inverted to white on pastel fills.
- **Default secondary text color**: `{colors.ink-soft}` — for descriptions, lead paragraphs, captions, page markers, sign-offs.
- **Default card fill**: `{colors.card-fill}` — translucent white. Reach for this whenever a content container doesn't need a saturated color.
- **Default accent card fill (when one is needed)**: `{colors.pink}` for the warmest moment, `{colors.lemon}` for the brightest, `{colors.blush}` for neutral warmth, `{colors.sage}` for cool variety, `{colors.lilac}` for the fifth slot in a five-up grid.
- **Default headline color**: `{colors.ink}`.
- **Default eyebrow color**: `{colors.ink}` (eyebrow is the top-left chrome label).
- **Default footer color**: `{colors.ink-soft}`.
Pastels do not carry semantic meaning. In matrix layouts, the convention is lemon = positive / partial / yes; blush = partial; pink = negative / no. Outside the matrix, any pastel can fill any card without conveying status.
## Typography
### Font Family
Soft Editorial runs **two families** in carefully separated roles:
- **Cormorant Garamond** (`{typography.display.fontFamily}`) — a refined old-style serif with a beautifully expressive italic axis. Carries every headline at every scale (display, title, closer, page-headline, card-headline, all subheads), every numeral, every quote, every kicker, every ornamental marker, every page numeral, every footer, every drop cap. The italic of this face is delicate and personal, and the system uses it generously — italic carries kickers, markers, page numerals, footers, step numerals, sign-offs, and any `<em>` inside a headline.
- **Work Sans** (`{typography.body.fontFamily}`) — a humanist grotesque. Reserved for body paragraphs, eyebrows, card sub-labels, attributions, and Work Sans-specific labels (the small uppercase swatch-label in palette displays). Work Sans never carries a headline.
The system's typographic signal is **mixed weight inside the same headline**: a serif headline at weight 500 carries an `<em>` that drops to weight 400 (italic). The weight difference is gentle — it reads as a softening, not as bold emphasis. This is opposite the magazine convention of italic-for-bold; here italic is the lighter, more intimate tone.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.numeral-hero}` | 320px | Cormorant Garamond | 500 | Featured hero numeral in a span-two stat card |
| `{typography.display}` | 232px | Cormorant Garamond | 500 | Cover-scale display headline |
| `{typography.numeral-lg}` | 200px | Cormorant Garamond | 500 | Standalone large statistical numeral |
| `{typography.title}` | 188px | Cormorant Garamond | 500 | Section or chapter title at near-cover scale |
| `{typography.closer}` | 168px | Cormorant Garamond | 500 | Closing or "moment" headline on a full-bleed colored slide |
| `{typography.panel-headline}` | 124px | Cormorant Garamond | 500 | Headline filling one panel of a two-column layout |
| `{typography.section-headline}` | 96px | Cormorant Garamond | 500 | Chart, comparison, or analysis section headline |
| `{typography.numeral-step}` | 92px | Cormorant Garamond italic | 500 | Italic ordinal numeral (i., ii., iii.) on step cards |
| `{typography.page-headline}` | 88px | Cormorant Garamond | 500 | Process diagram or general page headline |
| `{typography.quote-text}` | 88px | Cormorant Garamond | 500 | Pull-quote body text |
| `{typography.card-headline}` | 72px | Cormorant Garamond | 500 | Headline that fills the head of a square accent card |
| `{typography.numeral-card}` | 64px | Cormorant Garamond italic | 500 | Italic ordinal numeral on smaller item cards |
| `{typography.opener}` | 56px | Cormorant Garamond italic | 500 | Italic opener paragraph for foreword / long-form reads |
| `{typography.subhead-lg}` | 56px | Cormorant Garamond italic | 500 | Italic large subhead used for column-pair openers |
| `{typography.subhead-md}` | 44px | Cormorant Garamond | 500 | Card or column heading |
| `{typography.subhead-sm}` | 38px | Cormorant Garamond | 500 | Sub-headline within a panel; item headlines in lists |
| `{typography.kicker}` | 38px | Cormorant Garamond italic | 400 | Italic kicker above a cover headline |
| `{typography.card-sub}` | 32px | Work Sans | 500 | Sub-label beneath a serif card head (the only sans subhead) |
| `{typography.marker}` | 32px | Cormorant Garamond italic | 400 | Italic marker text (sign-offs, edition labels, "vol. iii") |
| `{typography.eyebrow}` | 28px | Work Sans | 400 | Plain-sans section name at top-left of standard slides |
| `{typography.page-marker}` | 26px | Cormorant Garamond italic | 400 | Roman or arabic page numeral at top-right |
| `{typography.footer}` | 26px | Cormorant Garamond italic | 400 | Italic serif footer line (date, publication) |
| `{typography.body}` | 26px | Work Sans | 400 | Default paragraph body |
| `{typography.body-md}` | 24px | Work Sans | 400 | Card body, list item body, dense paragraphs inside cards |
| `{typography.attr}` | 24px | Work Sans | 500 | Quote attribution name |
| `{typography.drop-cap}` | 132px | Cormorant Garamond | 500 | Drop cap at the start of a long-form opener paragraph |
| `{typography.swatch-label}` | 11px | Work Sans uppercase | 400 | Small uppercase label inside a swatch tile (palette display) |
### Defaults
- **Default size for a primary section headline**: `{typography.section-headline}` (96px) on standard slides, `{typography.panel-headline}` (124px) when the headline fills one panel of a two-up layout.
- **Default size for a cover or chapter headline**: `{typography.title}` (188px) to `{typography.display}` (232px).
- **Default size for a paragraph body**: `{typography.body}` (26px) on the open slide; `{typography.body-md}` (24px) inside cards or denser columns.
- **Default size for a kicker or marker**: `{typography.kicker}` (38px) for cover kickers; `{typography.marker}` (32px) for smaller ornamental notes.
- **Default size for a featured statistical numeral**: `{typography.numeral-lg}` (200px); reach for `{typography.numeral-hero}` (320px) only when one stat dominates a layout.
- **Default size for a step or item numeral**: `{typography.numeral-step}` (92px) on full step cards, `{typography.numeral-card}` (64px) on smaller items.
- **Default headline weight**: 500 (medium). Italic `<em>` inside drops to 400.
- **Default headline color**: `{colors.ink}`.
When unsure between sizes for a slide's primary moment, reach for `{typography.section-headline}` (96px) — it is the workhorse size for editorial reads.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every headline that includes an emphasized phrase renders the `<em>` in italic Cormorant Garamond at weight 400** (the surrounding headline runs at weight 500). The italic weight drop is the system's primary typographic signal.
- **All page chrome (eyebrow, page-marker, footer) is positioned absolute at fixed offsets** (eyebrow top-left 60/80px; pagedot top-right 60/80px; footer left/right 80px / bottom 50px). The chrome positions are non-negotiable across standard slides.
- **Eyebrows are plain Work Sans at 28px**, not italic, not uppercase. They are the only sans chrome element.
- **Page numerals and footers are italic serif at 26px in `{colors.ink-soft}`.** They are never sans, never uppercase, never bold.
- **Step numerals are italic serif lowercase Roman numerals (i., ii., iii., iv., v.)** — never arabic, never uppercase. The roman numeral is part of the editorial register.
- **Drop caps in opener paragraphs are Cormorant Garamond at weight 500, ~132px, with line-height 0.85 and padding `8px 14px 0 0`.** A drop cap that isn't this exact spec reads as a different system.
- **Cards always have border-radius in the 22–36px range** (or 999px for pills). Square cards do not exist in this system.
### Typography Principles
The serif/sans split is structural: Cormorant Garamond carries personality (every headline, every numeral, every ornament), Work Sans carries substance (every paragraph, every eyebrow, every Work Sans-only label). Crossing those rails breaks the editorial calm.
Italic is generous, not reserved. Italic serif appears on kickers, markers, page numerals, footers, step numerals, opener paragraphs, headline `<em>` phrases, and any small ornamental moment. Sans never italic — Work Sans should always render upright.
Line-height runs tight at display scale (0.9–0.98) and opens to 1.4–1.55 on body and card body. Letter-spacing is slightly negative on the largest sizes (–0.01 to –0.02em) and zero or near-zero on body. The 11px Work Sans swatch-label is the only uppercase element in the system — and it carries a generous 0.06em letter-spacing that makes its 11px size legible.
## Layout
### Canvas System
Soft Editorial targets a **fixed 1920×1080 canvas** via the `<deck-stage>` element. Layout is built on absolute positioning from the slide edges — every element is positioned via `position: absolute` with `top`/`left`/`right`/`bottom` offsets relative to the slide. The system does not use viewport-relative units; it relies on the deck-stage's scaling to handle viewport differences.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-outer}` | 80px | Standard left/right inset for content blocks |
| `{spacing.pad-top}` | 60px | Top inset for the eyebrow / pagedot chrome |
| `{spacing.pad-bottom}` | 50px | Bottom inset for the footer chrome |
| `{spacing.card-pad-lg}` | 64px 48px | Card padding for spacious cards (insights, closer) |
| `{spacing.card-pad-md}` | 48px 52px | Card padding for medium cards (next-step panels) |
| `{spacing.card-pad-sm}` | 28px 30px | Card padding for compact cards (columns, design-system tiles) |
| `{spacing.gap-cards}` | 28px | Standard gap between cards in a row or grid |
| `{spacing.gap-cards-lg}` | 36px | Larger gap between major panels |
| `{spacing.gap-stack}` | 36px | Vertical gap between stacked text elements |
### Chrome Frame
Every standard slide carries three chrome elements at fixed positions:
- **Eyebrow** — section name at top-left (60px from top, 80px from left), Work Sans 28px in `{colors.ink}`.
- **Pagedot** — page numeral at top-right (60px from top, 80px from right), italic Cormorant Garamond 26px in `{colors.ink-soft}`.
- **Footer** — two-column footer at bottom (50px from bottom, 80px from each side), italic Cormorant Garamond 26px in `{colors.ink-soft}` (date left, publication name right).
The cover slide swaps the pagedot for a row of three circular pastel swatches at top-right (the visual signature of the deck's palette). Full-bleed accent slides (the closer) shift chrome to dark ink on the colored field while preserving positions.
## Depth and Elevation
Soft Editorial uses **no drop shadows**. Depth comes entirely from translucency and rounded form:
- **Translucent white cards** — `{colors.card-fill}` (rgba 255,255,255,0.55) — sit on top of the cream field. The translucency lets the warm paper bleed through and makes the card feel "lifted" without any shadow.
- **Saturated pastel cards** — pink, lemon, blush, sage, lilac fills — sit on the cream field at full opacity. The visual difference between card and field is the color, not the elevation.
- **Rounded corners** — every card has a generous border-radius (22–36px), which softens the form and reads as "physical card" rather than "screen rectangle."
There is no second tier of elevation. Cards do not stack on cards. If a layout needs visual hierarchy, it uses size and color, not z-stacking.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 999px (pill) | Status pills (yes/partial/no/note) |
| 36px | Large insight cards, closer card |
| 32px | Method step cards |
| 28px | Item cards, process nodes, chart frames |
| 24px | Default panel cards, consult columns, design-system tiles, action bars |
| 22px | Larger system tiles in design-system grids |
| 18px | Decorative timeline bar |
| 16px | Palette swatch tiles |
| 14px | Smallest decorative chips inside design-system grids |
| 6px | Chart legend swatch (a flat rounded bar) |
| 50% (circle) | Cover swatch dots |
There are **no square corners in the system**. Every container is at least 14px rounded; cards are 22–36px rounded; pills are fully rounded.
### Border Weights
- **No solid borders on standard cards**. The card's background and rounded form provide its definition.
- **1px dashed** in `{colors.rule-soft}` (rgba 42,36,27,0.18) — internal hairlines for table cells, matrix dividers, source-line markers, system-tile separators.
- **1.5px solid** in `{colors.rule-medium}` (rgba 42,36,27,0.35) — heavier dividers for matrix head-row underlines, column header rules.
- **1px solid** in a similar low-opacity ink — used on chart plot edges and a small set of "note" pills.
### Decorative Element Types
**Soft card** — the default content container. A translucent white card with 24–36px border-radius and 28–64px internal padding. Sits on the cream field as a lifted region.
**Color card** — a saturated pastel card (pink, lemon, blush, sage, lilac) with 22–36px border-radius. Used for stats, step cards, insight cards, and any moment that wants color. Text inside stays ink/ink-soft — never inverted.
**Status pill** — a fully rounded 999px-radius pill with mixed serif/sans contents. Pastel-filled (lemon, blush, pink) for affirmative/partial/negative status; translucent white with a 1px ink border for "note."
**Action bar** — a full-width lemon-filled rounded card (24px radius) running across the top of a slide, containing a tag-separator structure and a serif headline. Used for callouts, CTAs, or attention-grabbing meta moments.
**Cover swatch row** — a row of 3–5 circular 56px discs in the deck's accent palette, positioned at top-right of the cover slide. The visual signature of the system's color philosophy.
**Drop cap** — a 132px Cormorant Garamond medium first letter that floats left at the start of an opener paragraph, with 8px 14px 0 0 padding. The single most editorial typographic moment in the system.
**Italic step numeral** — an italic Cormorant Garamond Roman numeral (i., ii., iii.) in the 64–92px range, sitting at the top of a step card above a serif headline and sans body. The Roman numeral is non-negotiable for steps.
**Quote mark** — a single italic Cormorant Garamond `"` at 220px in `{colors.blush}`, sitting above a centered pull-quote. The quote mark's color is its own signal — soft peach, not ink.
**Legend bar** — a 28px × 12px rounded-end (6px radius) horizontal bar in a chart's accent color, paired with a label.
**Source line** — a dashed-top-rule italic serif line at the bottom of a column or panel, marking a source attribution or sign-off.
## Do's and Don'ts
### Do
- Use Cormorant Garamond at weight 500 for every headline, and drop italic `<em>` phrases to weight 400 inside. The weight drop is the system's voice.
- Set the slide background to `{colors.paper}` on every standard slide — the warm cream field is the constant.
- Default cards to translucent white (`{colors.card-fill}`) at 24–36px border-radius. Reach for pastel fills when a card needs color or status, not by default.
- Keep text in `{colors.ink}` on every surface, including all pastel cards. The system never inverts to white on pastels.
- Use italic serif (Cormorant Garamond italic) for kickers, markers, page numerals, footers, step numerals, sign-offs, and any small ornamental moment.
- Apply a drop cap to opener paragraphs in long-form reads — 132px Cormorant Garamond medium, line-height 0.85, padding 8px 14px 0 0.
- Use Roman numerals (lowercase italic: i., ii., iii.) for step ordinals. Arabic step numbers break the editorial register.
- Render every page numeral as italic Cormorant Garamond at 26px in `{colors.ink-soft}`, positioned absolute at top-right.
- Use Work Sans only for body, eyebrows, attributions, and the small uppercase swatch-labels. Work Sans never carries a headline.
- Pad slides with 80px outer insets and leave 28–36px gaps between cards. The cream field breathing around cards is part of the design.
### Don't
- Don't fill the slide background with a pastel — the pastels are card fills (with one exception: the full-bleed closer slide can take a full pink field for a single "moment"). Default slides stay on cream.
- Don't invert text to white on pastel cards. Text always reads ink-on-color.
- Don't use square corners on any card or container. The minimum acceptable radius is 14px; cards live at 22–36px.
- Don't add drop shadows. The system's depth comes from translucency and form, not from elevation.
- Don't use a third typeface. Cormorant Garamond and Work Sans are the only families. Adding a display font or a mono breaks the editorial register.
- Don't bold inside body. If body needs emphasis, switch to italic serif or use a strong tag at weight 500 inside Work Sans (rare).
- Don't render kickers, markers, or footers in roman serif. The ornamental small text is always italic.
- Don't use uppercase outside the 11px swatch-label. The system is sentence case throughout.
- Don't use mono. There is no monospace in this system — every label is sans or italic serif.
- Don't crowd cards edge-to-edge. The 28–36px gaps and the cream field around cards are load-bearing.
## Responsive Behavior
Soft Editorial is a **fixed 1920×1080** system rendered inside a `<deck-stage>` web component. The deck-stage handles scaling: the slide content is laid out at exact 1920×1080 pixel dimensions and the component scales the entire stage to fit the viewport (letterboxing or fitting as configured by the stage). All `top`/`left`/`right`/`bottom`/`width`/`height` values inside slides are in pixels and assume the fixed 1920×1080 canvas.
### Scaling Behavior
Because the deck-stage scales uniformly, all elements maintain their relative positions and sizes at any output viewport. A 232px display headline remains 232px on the deck-stage's internal canvas; the stage scales the entire canvas to fit the browser viewport.
### Presenter Behavior
Navigation is handled by the `deck-stage.js` script (an external dependency, not embedded). Each slide carries a `data-label` attribute identifying it in the presenter UI. Slides advance via the deck-stage's own controls.
### Print Behavior
There is no embedded print stylesheet. Static export depends on the deck-stage component's print/export behavior; for PDF generation, the deck-stage should render each slide as a single page at the 1920×1080 canvas size.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face (default) | Chinese face | Weight | Notes |
|---|---|---|---|---|
| Display / Headline | Cormorant Garamond 500 | 霞鹜文楷 LXGW WenKai (LXGW WenKai TC) | 400 | LXGW WenKai is a hand-written-feel kaiti that mirrors Cormorant's literary register. The single regular weight matches Cormorant's gentle medium. |
| Italic emphasis (`<em>`) | Cormorant Garamond italic 400 | 霞鹜文楷 LXGW WenKai | 400 | LXGW WenKai has no true italic — emphasis instead drops to `{colors.ink-soft}` or a faint underline. Do not synthesize italic. |
| Body | Work Sans 400 | 思源宋体 / Noto Serif SC | 400 | The system body switches from sans to serif in CJK to preserve the literary register; Work Sans loses its editorial calm beside a kaiti headline. |
| Body — alt sans (optional) | Work Sans 400 | Noto Sans SC | 400 | Only use if the deck has very dense data; default to Noto Serif SC. |
| Kicker / marker / page numeral | Cormorant Garamond italic 400 | 霞鹜文楷 LXGW WenKai 400 | 400 | Italic ornament becomes upright kaiti; rely on `{colors.ink-soft}` color shift instead of italic for the same "soft ornament" feel. |
### Mixed-Content Strategy
This template uses **Strategy C (literary)**: keep the Latin face for English glyphs and let the CJK fallback in only when a Chinese character appears, via a stacked `font-family`. Cormorant Garamond is part of Soft Editorial's brand identity — replacing it with a kaiti for every headline strips the system of its old-style serif personality. Letting Latin stay in Cormorant while Chinese drops into LXGW WenKai preserves both registers.
```css
font-family: 'Cormorant Garamond', 'LXGW WenKai TC', 'Noto Serif SC', serif; /* headlines */
font-family: 'Work Sans', 'Noto Serif SC', sans-serif; /* body */
```
**Warning — baseline mismatch at display sizes.** Cormorant Garamond's x-height sits noticeably lower than LXGW WenKai's optical center. At 96px+ headlines, a phrase like `Soft Editorial 软编辑` will show the Chinese characters floating slightly above the Latin baseline. Mitigations:
- Add `font-feature-settings: "palt"` on the Chinese segment to tighten metrics.
- Wrap CJK in a `<span lang="zh">` with a small `vertical-align: -0.04em` adjustment on display tokens (display, title, closer, numeral-hero, panel-headline).
- For pure-CJK headlines (no Latin), the issue disappears — the mismatch only surfaces in mixed-script lines.
### Loading
Add to `<head>` (Google Fonts hosts LXGW WenKai TC and Noto Serif SC):
```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=Cormorant+Garamond:ital,wght@0,400;0,500;1,400;1,500&family=Work+Sans:wght@400;500&family=LXGW+WenKai+TC&family=Noto+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
LXGW WenKai TC is the Traditional Chinese cut on Google Fonts; it includes the full CJK Unified Ideographs range and renders Simplified Chinese cleanly. Noto Serif SC carries body text in Simplified Chinese with proper hinting.
### Universal CJK Adjustments
Apply on any element rendering Chinese content (typically scope via `:lang(zh)` or `<span lang="zh">`):
- **Line-height**: body 1.75–1.85 (Soft Editorial's 1.5 sans-default needs more air for CJK strokes); display 1.15–1.25 (tighter than Latin 0.92–1 because CJK glyphs already include intrinsic spacing).
- **Letter-spacing**: 0 on CJK. The system's negative tracking (-0.01 to -0.02em) on display Latin is wrong for Chinese — CJK glyphs are pre-spaced; negative tracking causes overlap.
- **Text-transform**: no uppercase on CJK. Chinese has no case, and CSS `text-transform: uppercase` is a no-op on Han characters anyway, but make sure no parent rule attempts it.
- **Full-width punctuation**: use `,。:;!?` (full-width) not `,.:;!?` (half-width). The full-width forms include their own surrounding whitespace and align to the CJK em-box.
- **No period on display headlines**: Chinese headlines drop the terminal `。` — the headline's visual closure is enough. (Latin headlines in this system already drop periods; the rule extends to CJK.)
- **Pangu spacing (盘古之白)**: insert a thin space between CJK and adjacent Latin/numerals. Write `使用 Claude` not `使用Claude`; `2024 年` not `2024年`. This is editorial convention in good Chinese typography and matches Soft Editorial's literary care.
- **One font per sentence**: don't mix LXGW WenKai and Noto Serif SC inside a single line. Use one or the other for the entire run; switching mid-sentence creates a metric jolt.
### Aesthetic Notes for This System
LXGW WenKai is exceptionally well-matched to Soft Editorial's register. The kaiti's slight hand-written warmth picks up where Cormorant Garamond's old-style italic leaves off — both faces read as personal, considered, slightly intimate against the cream paper field. On a pastel card (pink, lemon, blush, sage, lilac), LXGW WenKai at headline scale reads as a calligraphic moment, which strengthens rather than weakens the editorial calm. The drop cap treatment (132px Cormorant Garamond medium) does not translate to CJK — kaiti drop caps look severed rather than ornamental; for Chinese opener paragraphs, drop the drop cap entirely and rely on the italic kicker above the paragraph for the "essay opening" cue.
The serif body switch (Work Sans → Noto Serif SC) is the most consequential change. Work Sans's humanist grotesque feels paired with Cormorant in Latin, but a sans body beside a kaiti headline reads as a cheap textbook in Chinese. Noto Serif SC's Song-style strokes resonate with both the cream field and the literary headline face, preserving the small-press literary quarterly mood across languages. Keep eyebrows (28px) in Noto Sans SC if you want a small register shift from the body, mirroring the Latin sans-vs-serif distinction.
### Known CJK Gap
- LXGW WenKai has only a single weight (regular). The system's signature "weight drop" inside headlines (Cormorant 500 → italic 400) cannot be reproduced in CJK. Substitute with a color shift to `{colors.ink-soft}` for emphasis, or accept that Chinese headlines read as one consistent weight.
- LXGW WenKai TC's Traditional-cut glyphs may render a small number of characters with Traditional forms (e.g., 設 instead of 设). For pure Simplified Chinese decks, prefer `font-family: 'Noto Serif SC'` as the primary CJK face and reserve LXGW WenKai for accent moments (cover title, chapter titles).
- The italic ornament moments (kickers, page numerals, footers, sign-offs) lose their italic in CJK because no CJK face carries true italic. Compensate by using `{colors.ink-soft}` and slightly smaller sizes to keep the "ornamental whisper" register.
- Baseline mismatch at display sizes (see Mixed-Content Strategy) requires per-deck tuning if covers carry mixed-script headlines.
## Iteration Guide
1. Any new headline uses Cormorant Garamond at weight 500, with italic `<em>` phrases dropping to weight 400. The weight drop is the editorial signal.
2. Any new card defaults to translucent white (`{colors.card-fill}`) at 24–36px border-radius. Pastel fills are for moments that need color, not for every card.
3. Any new step ordinal is an italic lowercase Roman numeral (i., ii., iii.) in Cormorant Garamond italic at 64–92px.
4. Any new kicker, marker, page numeral, footer, or sign-off is italic Cormorant Garamond at 26–38px in `{colors.ink-soft}` or `{colors.ink}`.
5. Any new pastel introduction (a sixth color) breaks the system. The five-pastel palette (pink, lemon, blush, sage, lilac) is closed.
6. Any new pill uses 999px border-radius with a pastel fill or translucent white. Pills are sub-headline emphasis units, not chrome.
7. The cover swatch row (three circular discs at top-right) is the system's identity mark. Preserve it on cover slides.
8. Page chrome (eyebrow, pagedot, footer) sits at fixed absolute positions on every standard slide. Don't drift the positions.
9. Long-form paragraph reads should open with a drop cap (132px Cormorant Garamond medium) — this is the system's most distinctive editorial moment.
10. The cream field around and between cards is load-bearing. If a layout needs to be denser, increase card content rather than shrinking the field.
## Known Gaps
- The system depends on the external `deck-stage.js` script for slide scaling and navigation. The script is referenced but not embedded; without it, slides will render at intrinsic 1920×1080 without viewport scaling.
- Cormorant Garamond and Work Sans both load from Google Fonts. If fonts fail, the serif falls back to Garamond/serif and the sans falls back to Helvetica/sans-serif; the editorial character degrades significantly without Cormorant.
- The full-bleed closer slide is the only place where a pastel covers the entire canvas. The pattern is intentional but should be used sparingly — every closer at full pink would diminish the cream-as-default identity.
- The five pastels (`{colors.pink}`, `{colors.lemon}`, `{colors.blush}`, `{colors.sage}`, `{colors.lilac}`) are listed as semantically interchangeable, but the source template uses lemon = yes / blush = partial / pink = no inside the matrix layout. New decks may follow or ignore this convention.
- The drop cap treatment depends on CSS `:first-letter` rendering, which has slight cross-browser variation in metric handling. Padding and line-height values are tuned for Cormorant Garamond and may need adjustment if the font fails to load.
- The translucent white card fill (`rgba(255,255,255,0.55)`) depends on the cream paper showing through. On a different background color, the card would read differently — the spec assumes `{colors.paper}` is the surface.
- Card padding values vary across layouts (28/30, 48/52, 64/48) without a strict scale; the rule is "compact, medium, spacious" rather than a fixed token system.
# Soft Editorial Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/soft-editorial/design.md`
- Preview card: `bold-template-pack/templates/soft-editorial/preview.md`
## Selection Metadata
- Slug: `soft-editorial`
- Tagline: Cormorant Garamond serif on warm paper with sage, blush, and lemon accents.
- Mood: literary, elegant, quiet, warm-classical
- Tone: literary, considered, warm, magazine
- Formality: high
- Density: low
- Scheme: light
- Best for: Anything that should feel literary, elegant, and unhurried: editorial features, longform brand stories, gallery / museum decks, advisory deliverables, wedding / lifestyle media, founder essays. Equally good for tech, research, or business decks that want a Sunday-supplement warmth instead of corporate polish.
- Avoid for: Decks that need visual heat or punch — the warm-paper palette and Cormorant serif are intentionally quiet.
## Visual Snapshot
A warm magazine spread aesthetic — the kind of layout a small print quarterly with field-notes pretensions would commission. Cormorant Garamond carries every headline and ornamental moment with mixed roman and italic; Work Sans recedes into supporting body. The palette is cream paper with a quartet of pastel candy accents (dusty pink, chartreuse lemon, soft peach blush, sage green, lilac) used as colored card backgrounds. Generous rounded cards (24–36px radius) float on translucent white over the cream field. The mood is editorial calm with a sprinkling of riso-print color — closer to a literary research notebook than a corporate deck.
Soft Editorial is a warm magazine spread presentation system that takes its visual cues from small-press literary quarterlies and design-research notebooks. The premise is a single typeface (Cormorant Garamond) doing nearly all the talking, supported by a sober humanist sans (Work Sans) only where the serif would tire. The cream paper field is the constant — every slide sits on {colors.paper} (#F2EEDF), a warm aged-cream that reads as physical paper, not screen white. On top of the field, rounded cards float in two registers: translucent white softness for default content, and saturated pastel candy for accent moments.
## Preview Ingredients
- Palette: paper #F2EEDF; paper-2 #ECE6D2; ink #2A241B; ink-soft #5C5345; pink #E1A4C2; lemon #D6DD63; blush #E8C9B6; sage #B7C7A8
- Typography: Cormorant Garamond; Work Sans
- Signature move: Single warm cream surface ({colors.paper}) across every slide; pastels appear only as card fills, never as the slide background (except the full-bleed closer slide which fills with {colors.pink}).
- Signature move: Cormorant Garamond carries every display, headline, kicker, and ornamental moment; Work Sans is reserved for body and eyebrows.
- Signature move: Mixed roman + italic inside headlines is the system's typographic signal — italic phrases drop to weight 400 from the headline's weight 500.
- Signature move: Saturated pastels ({colors.pink}, {colors.lemon}, {colors.blush}, {colors.sage}, {colors.lilac}) are interchangeable card fills with no fixed semantic meaning.
- Signature move: Rounded cards (24–36px radius) are the default container; pills are fully rounded (999px); translucent white ({colors.card-fill}) is the default card fill.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Stencil & Tablet
description: A West Coast skate-poster meets municipal stencil signage system. Stardos Stencil carries every headline, numeral, and chunky display moment with its characteristic ink-break gaps; Barlow Condensed runs all metadata and uppercase chrome at extra-heavy weights; Inter handles body. The palette is bone (#E2DCC9) and black, energized by a saturated retro-print accent set — sienna, magenta, orange, teal, blue, mustard, olive. Soft rounded "tablet" cards (22–26px radius) tile across slides in colored blocks. Type runs huge and uppercase, numerals dominate at 160–540px, and color blocks act as the layout. The mood is industrial poster, vintage workshop sign, and music festival lineup all at once.
colors:
bone: "#E2DCC9"
black: "#000000"
ink: "#0A0A0A"
paper: "#F4EFE0"
sienna: "#A06A3C"
magenta: "#C73B7A"
orange: "#EE7A2E"
teal: "#2D7E73"
blue: "#3F73B7"
mustard: "#D8A93B"
olive: "#6F7A2E"
typography:
cover-hero:
fontFamily: "Stardos Stencil, serif"
fontSize: 220px
fontWeight: 700
lineHeight: 0.82
letterSpacing: -0.015em
textTransform: uppercase
numeral-mega:
fontFamily: "Stardos Stencil, serif"
fontSize: 540px
fontWeight: 700
lineHeight: 0.8
numeral-card-xl:
fontFamily: "Stardos Stencil, serif"
fontSize: 240px
fontWeight: 700
lineHeight: 0.85
letterSpacing: -0.02em
numeral-tablet:
fontFamily: "Stardos Stencil, serif"
fontSize: 220px
fontWeight: 700
lineHeight: 0.9
letterSpacing: -0.02em
numeral-stat:
fontFamily: "Stardos Stencil, serif"
fontSize: 160px
fontWeight: 700
lineHeight: 0.85
letterSpacing: -0.02em
section-headline:
fontFamily: "Stardos Stencil, serif"
fontSize: 120px
fontWeight: 700
lineHeight: 0.92
letterSpacing: -0.005em
textTransform: uppercase
chart-headline:
fontFamily: "Stardos Stencil, serif"
fontSize: 110px
fontWeight: 700
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
page-headline:
fontFamily: "Stardos Stencil, serif"
fontSize: 92px
fontWeight: 700
lineHeight: 0.92
letterSpacing: -0.01em
textTransform: uppercase
quote-text:
fontFamily: "Stardos Stencil, serif"
fontSize: 60px
fontWeight: 400
lineHeight: 1.05
letterSpacing: -0.005em
quote-mark:
fontFamily: "Bowlby One, Stardos Stencil, serif"
fontSize: 320px
fontWeight: 700
lineHeight: 0.8
numeral-process:
fontFamily: "Stardos Stencil, serif"
fontSize: 64px
fontWeight: 700
lineHeight: 0.9
date-mark:
fontFamily: "Stardos Stencil, serif"
fontSize: 36px
fontWeight: 700
textTransform: uppercase
card-headline:
fontFamily: "Stardos Stencil, serif"
fontSize: 34px
fontWeight: 700
lineHeight: 1.15
textTransform: uppercase
letterSpacing: -0.005em
meta-headline:
fontFamily: "Stardos Stencil, serif"
fontSize: 32px
fontWeight: 700
lineHeight: 1.1
card-h3:
fontFamily: "Stardos Stencil, serif"
fontSize: 30px
fontWeight: 700
lineHeight: 1.05
textTransform: uppercase
letterSpacing: 0.02em
matrix-row:
fontFamily: "Stardos Stencil, serif"
fontSize: 26px
fontWeight: 700
lineHeight: 1.1
textTransform: uppercase
letterSpacing: 0.01em
matrix-head:
fontFamily: "Stardos Stencil, serif"
fontSize: 24px
fontWeight: 700
textTransform: uppercase
letterSpacing: 0.02em
topbar:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 32px
fontWeight: 800
letterSpacing: 0.04em
textTransform: uppercase
lineHeight: 1
super:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 28px
fontWeight: 800
letterSpacing: 0.12em
textTransform: uppercase
who-name:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 30px
fontWeight: 700
letterSpacing: 0.04em
textTransform: uppercase
attribution:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 26px
fontWeight: 800
letterSpacing: 0.08em
textTransform: uppercase
meta:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 24px
fontWeight: 600
letterSpacing: 0.06em
section-eyebrow:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 24px
fontWeight: 800
letterSpacing: 0.14em
textTransform: uppercase
footer:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 22px
fontWeight: 600
letterSpacing: 0.08em
textTransform: uppercase
process-sub:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 22px
fontWeight: 600
letterSpacing: 0.06em
textTransform: uppercase
timeline-marker:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 20px
fontWeight: 700
letterSpacing: 0.08em
textTransform: uppercase
legend:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 22px
fontWeight: 700
letterSpacing: 0.06em
textTransform: uppercase
pill:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 18px
fontWeight: 700
letterSpacing: 0.08em
textTransform: uppercase
chart-axis:
fontFamily: "Barlow Condensed, sans-serif"
fontSize: 18px
fontWeight: 600
letterSpacing: 0.06em
body-lg:
fontFamily: "Inter, sans-serif"
fontSize: 24px
fontWeight: 400
lineHeight: 1.4
body:
fontFamily: "Inter, sans-serif"
fontSize: 22px
fontWeight: 400
lineHeight: 1.4
body-sm:
fontFamily: "Inter, sans-serif"
fontSize: 20px
fontWeight: 400
lineHeight: 1.45
body-xs:
fontFamily: "Inter, sans-serif"
fontSize: 18px
fontWeight: 400
lineHeight: 1.4
spacing:
pad-outer: 64px
pad-top: 48px
pad-bottom: 36px
card-pad: "24px 22px to 38px 32px"
gap-card: "22px to 28px"
radius-card: 22px
radius-card-lg: 26px
radius-action: 22px
radius-pill: 999px
radius-mark: 14px
radius-timeline: 18px
canvas:
width: 1920px
height: 1080px
components:
tablet:
borderRadius: 26px
padding: "38px 32px 32px"
background: "any palette accent or {colors.bone}"
color: "{colors.ink} on light fills, {colors.bone} on dark fills"
description: "The system's namesake container — a rounded rectangle holding a giant stencil numeral above a stencil headline and Inter body. Numerals run to 220px+ inside."
card-color:
borderRadius: 22px
padding: "{spacing.card-pad}"
description: "Generic color-block card in any palette accent (sienna, magenta, orange, teal, blue, mustard, olive, paper)."
pill-status:
borderRadius: "{spacing.radius-pill}"
padding: "6px 16px"
typography: "{typography.pill}"
description: "Uppercase Barlow Condensed pill used as a matrix cell value. teal=yes, mustard=partial, magenta=no, paper-with-ink-border=note."
action-bar:
background: "{colors.mustard}"
borderRadius: 22px
padding: "24px 32px"
description: "Mustard-yellow callout bar running across the top of a slide, containing a tag separator and a stencil headline. Used for important section openers."
num-mega:
typography: "{typography.numeral-mega}"
color: "{colors.orange} (default) or any saturated accent"
description: "Giant 540px stencil numeral used as a section divider — the number IS the layout. Sits absolute top-left while the section headline runs bottom-right."
num-tablet:
typography: "{typography.numeral-tablet}"
description: "220px stencil numeral inside a tablet card, paired with a stencil headline and Inter body underneath."
num-stat:
typography: "{typography.numeral-stat}"
suffix: "{typography.attribution}"
description: "160px stencil stat numeral with optional small-caps Barlow suffix (e.g., '%') at vertical-align top, 40px."
cover-lockup:
description: "Cover-bottom row containing a small rounded mark (56px square, 14px radius, accent fill), an uppercase Barlow name with small subtitle, and a stencil date."
cover-mark:
width: 56px
height: 56px
borderRadius: 14px
background: "any accent (default orange)"
description: "Small rounded square 'logo' tile in the cover lockup."
section-num-block:
description: "Section divider where a 540px stencil numeral fills the left side, a small Barlow eyebrow sits top-right, and a 120px stencil headline runs bottom-right."
process-node:
borderRadius: 22px
padding: "24px 22px 22px"
description: "Process step card with a 64px stencil ordinal at top, an uppercase stencil h3, and small Inter body. Each step takes a different accent fill."
timeline-bar:
background: "{colors.paper}"
borderRadius: 14px
padding: "0 28px"
height: 50px
description: "Paper-fill horizontal bar at the bottom of process diagrams, containing uppercase Barlow timeline markers spread evenly."
matrix-cell:
border: "1.5px solid rgba(10,10,10,0.35)"
padding: "18px 22px"
description: "Matrix table cell with a single warm-ink hairline border. Head row inverts to black fill with bone text. Last row drops bottom border."
legend-bar:
width: 32px
height: 6px
description: "Flat horizontal bar (no border-radius) used as a chart legend swatch."
quote-panel:
background: "{colors.magenta} (or any saturated accent)"
borderRadius: 26px
padding: "60px 80px"
description: "Large rounded panel filling most of the slide, containing a 320px Bowlby One quote mark beside a 60px stencil quote text."
organic-shape:
description: "Decorative organic blob (SVG) sitting behind agenda items on the dark agenda layout, in any accent color. The shape is the background, the number and label float on top."
topbar:
position: "absolute top 48px, left/right 64px"
typography: "{typography.topbar}"
description: "Top chrome strip with section name left and meta columns right. Uppercase Barlow Condensed 800."
footer-chrome:
position: "absolute bottom 36px, left/right 64px"
typography: "{typography.footer}"
description: "Bottom chrome strip with date left and deck name right. Uppercase Barlow Condensed 600 at 0.75 opacity."
---
## 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
Stencil & Tablet is a **poster-loud, type-led** presentation system. The premise is a single display face — Stardos Stencil — handling every headline, every numeral, every featured moment, with characteristic stencil ink-breaks giving each glyph a slightly-distressed industrial register. The supporting cast is Barlow Condensed (extra-heavy 600–900, uppercase, generous tracking) running all metadata, chrome, pills, and legends — and Inter handling the small set of body paragraphs that exist mostly to caption the loud type above them.
The visual logic is **color blocks as layout**. The bone-cream field (`{colors.bone}` — #E2DCC9) is the default page; on top of it sit rounded "tablet" cards in saturated retro-print colors — sienna brown, magenta pink, orange, teal, deep blue, mustard yellow, olive green. The accents are not pastels — they read as printed ink, slightly muted but unmistakably saturated. The cards do the work of dividing the canvas; you can identify a slide's structure from across the room because the color blocks tile geometrically. A dark-bone alternate (`{colors.black}` field with bone-colored type) appears on agenda-style and bold-statement slides.
The typographic register is **huge and uppercase**. Cover titles run at 220px. Numerals inside tablets at 220–240px. Section dividers at 540px (yes, more than half the canvas in single-character height). Statement headlines at 120px. Even stat numerals start at 160px. The system's identity depends on running type at sizes that would be impossible on most decks — Stencil & Tablet uses scale as the primary expressive tool, with color as the secondary tool, and body text only as the supporting cast.
Depth is **flat with rounded chrome**. There are no drop shadows. No gradients. Cards have generous border-radius (22–26px) and saturated fills, and that's the entire depth system. Inside cards, dividers are 1.5–2px solid hairlines in warm ink — heavier than Soft Editorial's whisper-dashed rules because the system overall has more visual weight.
**Density philosophy: high and confident.** Stencil & Tablet is meant to feel filled. A typical slide covers most of its canvas in color blocks — tablets tile across, action bars run wide, section numerals fill half the slide. The bone field is visible mostly as gaps between cards (22–28px) and as the outer 64px slide padding. A slide that feels broken in this system is one that's mostly empty bone — the design needs the color blocks to hold its identity. The exception is the section-divider slide, where a single 540px numeral against a dark field IS the design and the empty space is intentional.
**Key Characteristics:**
- Bone (`{colors.bone}`) field on most slides; black field with bone type on agenda-style and bold-divider slides.
- Stardos Stencil for every headline, every numeral, every featured stencil moment — the ink-break stencil glyphs are the system's identity.
- Barlow Condensed extra-heavy uppercase for all chrome, metadata, pills, legends, and labels. Generous letter-spacing (0.06–0.14em).
- Inter for body — small role, supporting the loud type above.
- Seven-color accent palette (`{colors.sienna}`, `{colors.magenta}`, `{colors.orange}`, `{colors.teal}`, `{colors.blue}`, `{colors.mustard}`, `{colors.olive}`) plus paper (`{colors.paper}`) — used as full card fills.
- Tablet cards with 22–26px border-radius hold a giant stencil numeral above a stencil headline above Inter body. The numeral usually fills more than half the card height.
- Numerals run massive — section dividers at 540px, tablet cards at 220–240px, stats at 160px.
- All headlines uppercase. All metadata uppercase. Sentence case appears only in Inter body.
- No drop shadows, no gradients — flat blocks of color with rounded corners.
## Colors
### Palette
- **Bone** (`{colors.bone}` — #E2DCC9): The default page field. A warm cream with a slight green-grey undertone — reads as canvas, kraft paper, or a slightly-aged poster.
- **Black** (`{colors.black}` — #000000): The dark field. True black, used for agenda-style and section-divider slides where the type inverts to bone.
- **Ink** (`{colors.ink}` — #0A0A0A): Near-black for text on light surfaces. Slightly softer than pure black to read as ink rather than digital.
- **Paper** (`{colors.paper}` — #F4EFE0): A lighter cream than bone, used for cards that need to sit "lighter" against the bone field (matrix tables, chart frames, timeline bars).
- **Sienna** (`{colors.sienna}` — #A06A3C): Warm brown-orange. The earthiest of the accents — process steps, principle cards.
- **Magenta** (`{colors.magenta}` — #C73B7A): Saturated retro pink-red. The loudest warm accent — covers, quotes, statements, matrix "no" pills.
- **Orange** (`{colors.orange}` — #EE7A2E): Bright orange. The system's most-used accent — section dividers, principle cards, cover marks, stat cards.
- **Teal** (`{colors.teal}` — #2D7E73): Deep blue-green. The cool counterpart to orange — process cards, matrix "yes" pills, chart accents.
- **Blue** (`{colors.blue}` — #3F73B7): Mid-tone process blue. Used for fifth-step process cards and cool variety.
- **Mustard** (`{colors.mustard}` — #D8A93B): Saturated yellow-orange. Action bars, stat cards, matrix "partial" pills.
- **Olive** (`{colors.olive}` — #6F7A2E): Muted yellow-green. The least-used accent, reserved for variety in seven-up palettes or sixth-position cards.
### Defaults
- **Default page field**: `{colors.bone}` for content slides; `{colors.black}` for agenda-style, section-divider, stats-headline, and quote-panel-containing slides.
- **Default primary text color**: `{colors.ink}` on bone/paper/light-accent surfaces; `{colors.bone}` on black/teal/blue/dark accent surfaces.
- **Default text color on each accent**: ink on sienna, magenta, orange, mustard, olive, paper (warm or mid-tone accents stay with ink); bone on teal, blue, black (cool/dark accents flip to bone).
- **Default accent for sections (single-color moments)**: `{colors.orange}` — the system's loudest, most-used accent.
- **Default accent for warm color moments**: `{colors.magenta}` or `{colors.orange}`.
- **Default accent for cool color moments**: `{colors.teal}`.
- **Default accent for callout / action bar**: `{colors.mustard}`.
- **Default text-on-fill rule**: text never inverts to white. Light text on dark fills is always `{colors.bone}`, never white.
### Matrix Pill Color Conventions
Inside comparison matrices, status pills follow a fixed convention:
- `{colors.teal}` fill with bone text = yes / affirmative
- `{colors.mustard}` fill with ink text = partial / qualified
- `{colors.magenta}` fill with bone text = no / negative
- `{colors.paper}` fill with ink text and 1.5px ink border = note / annotation
Outside the matrix, accents are interchangeable. A process card can be magenta or teal without conveying yes/no — color is decorative there, not semantic.
## Typography
### Font Family
Stencil & Tablet runs **three families** plus one display-only specialist:
- **Stardos Stencil** (`{typography.cover-hero.fontFamily}`) — a single-weight (700, with a 400 italic for quotes) stencil display face. The ink-break gaps in every glyph are the system's identity. Used for every headline, every numeral, every featured stencil moment from 24px matrix-head all the way up to 540px section-numeral.
- **Bowlby One** — a single-purpose extra-heavy display face used only for the 320px quote-mark inside quote panels. The face has a different visual register (fatter, more solid) than Stardos Stencil and is reserved for that one element.
- **Barlow Condensed** (`{typography.topbar.fontFamily}`) — a tall narrow grotesque at weights 500–900. Carries every uppercase chrome, every metadata label, every pill, every legend item, every footer, every supporting label. The condensed width and heavy weights let it pack tight uppercase rows at small sizes (18–32px).
- **Inter** (`{typography.body.fontFamily}`) — a humanist grotesque at weights 400–600. Reserved for body paragraphs and card body copy at 18–24px. Inter is the system's "quiet" voice — used for sentence-case prose where Barlow would be too loud.
The emotional split is: Stardos = scale and signage; Barlow = metadata and labels; Inter = body; Bowlby = the quote-mark glyph only.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.numeral-mega}` | 540px | Stardos Stencil | 700 | Section-divider numeral that fills most of a slide |
| `{typography.quote-mark}` | 320px | Bowlby One | 700 | Opening quote glyph inside a quote panel |
| `{typography.numeral-card-xl}` | 240px | Stardos Stencil | 700 | Mega numeral inside a principle/feature card |
| `{typography.numeral-tablet}` | 220px | Stardos Stencil | 700 | Standard numeral inside a tablet card |
| `{typography.cover-hero}` | 220px | Stardos Stencil | 700 | Cover title at maximum scale |
| `{typography.numeral-stat}` | 160px | Stardos Stencil | 700 | Statistical numeral inside a stat card |
| `{typography.section-headline}` | 120px | Stardos Stencil | 700 | Headline on a section-divider slide |
| `{typography.chart-headline}` | 110px | Stardos Stencil | 700 | Large headline on chart slides |
| `{typography.page-headline}` | 92px | Stardos Stencil | 700 | Standard slide headline |
| `{typography.numeral-process}` | 64px | Stardos Stencil | 700 | Step ordinal at the top of a process node |
| `{typography.quote-text}` | 60px | Stardos Stencil | 400 | Pull-quote body inside a quote panel |
| `{typography.date-mark}` | 36px | Stardos Stencil | 700 | Date or marker in cover lockup |
| `{typography.card-headline}` | 34px | Stardos Stencil | 700 | Headline inside an action bar |
| `{typography.meta-headline}` | 32px | Stardos Stencil | 700 | Heavy meta headline inside a consult column |
| `{typography.card-h3}` | 30px | Stardos Stencil | 700 | Card sub-headline at the bottom of tablets |
| `{typography.topbar}` | 32px | Barlow Condensed | 800 | Top chrome label |
| `{typography.super}` | 28px | Barlow Condensed | 800 | Superscript label above cover headlines |
| `{typography.who-name}` | 30px | Barlow Condensed | 700 | Cover lockup name label |
| `{typography.attribution}` | 26px | Barlow Condensed | 800 | Quote attribution name |
| `{typography.matrix-row}` | 26px | Stardos Stencil | 700 | Matrix row-label cell |
| `{typography.matrix-head}` | 24px | Stardos Stencil | 700 | Matrix head-row cell |
| `{typography.meta}` | 24px | Barlow Condensed | 600 | Top chrome meta columns |
| `{typography.section-eyebrow}` | 24px | Barlow Condensed | 800 | Section eyebrow on divider slides |
| `{typography.body-lg}` | 24px | Inter | 400 | Standard body paragraph |
| `{typography.footer}` | 22px | Barlow Condensed | 600 | Bottom chrome footer |
| `{typography.process-sub}` | 22px | Barlow Condensed | 600 | Process diagram sub-headline |
| `{typography.legend}` | 22px | Barlow Condensed | 700 | Chart legend label |
| `{typography.body}` | 22px | Inter | 400 | Default body inside tablets and cards |
| `{typography.timeline-marker}` | 20px | Barlow Condensed | 700 | Timeline bar marker label |
| `{typography.body-sm}` | 20px | Inter | 400 | Consult column body, dense card body |
| `{typography.pill}` | 18px | Barlow Condensed | 700 | Pill label inside matrix or status chip |
| `{typography.chart-axis}` | 18px | Barlow Condensed | 600 | Chart axis tick label |
| `{typography.body-xs}` | 18px | Inter | 400 | Smallest body, process card descriptions |
### Defaults
- **Default size for a primary section headline**: `{typography.page-headline}` (92px) on standard slides, `{typography.chart-headline}` (110px) on chart-style headers, `{typography.section-headline}` (120px) on section-divider slides.
- **Default size for a cover hero**: `{typography.cover-hero}` (220px).
- **Default size for a featured numeral inside a tablet**: `{typography.numeral-tablet}` (220px); reach for `{typography.numeral-card-xl}` (240px) when the numeral dominates and `{typography.numeral-mega}` (540px) for section dividers.
- **Default size for a statistical numeral**: `{typography.numeral-stat}` (160px).
- **Default size for body**: `{typography.body}` (22px) inside cards; `{typography.body-lg}` (24px) for stand-alone body paragraphs.
- **Default size for any chrome label, pill, or legend**: `{typography.footer}` (22px) to `{typography.topbar}` (32px) depending on the chrome tier.
- **Default headline color**: `{colors.ink}` on light fills, `{colors.bone}` on dark fills.
When unsure between `{typography.page-headline}` (92px) and `{typography.chart-headline}` (110px), pick 92px — 110px is reserved for slides where the headline anchors a chart frame.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every headline is uppercase.** Stardos Stencil at any size, in any context, runs uppercase. Sentence-case stencil text does not exist in this system.
- **Every chrome, metadata, pill, and legend element is uppercase Barlow Condensed with at least 0.04em letter-spacing** (most run at 0.06–0.14em). Barlow Condensed without tracking reads as broken.
- **Numerals are always Stardos Stencil at weight 700** — never weight 400, never a different face. Even small numerals (matrix-head at 24px) follow the convention.
- **The 540px section-divider numeral always renders in a saturated accent on a dark (`{colors.black}` or near-black) field**, typically `{colors.orange}` or `{colors.magenta}`. A 540px numeral on a light field breaks the section-divider register.
- **Tablet cards always carry a numeral above their headline.** A tablet without a numeral is not a tablet — it's a generic card. The numeral is the tablet's defining feature.
- **Stat numerals use a Barlow Condensed superscript suffix at vertical-align top** for units (% sign, ×, K, M). The suffix runs at 40px / weight 800 / Barlow.
- **Body in Inter is always sentence case.** Uppercasing Inter breaks the contrast that lets it read as the "quiet voice."
- **Quote panels always use Bowlby One for the quote-mark glyph (not Stardos Stencil).** The chunkier face is non-negotiable for that one element.
### Typography Principles
The face ladder is fixed: Stardos for stencil display and numerals; Barlow for uppercase chrome/metadata/pills; Inter for sentence-case body; Bowlby for the single quote-mark application. Crossing the rails — e.g., using Stardos for body, or using Inter uppercase for chrome — breaks the typographic register.
Line-height runs tight at display scale (0.8–0.92 on numerals and headlines) and opens to 1.4–1.45 on body. Letter-spacing on stencil headlines is slightly negative (–0.005 to –0.02em) at large sizes; chrome and labels run with generous positive tracking (0.04–0.14em). Numerals at all sizes use negative letter-spacing (typically –0.02em).
Bold within body is not used. Strong tags inside Inter remain at weight 400; emphasis is achieved by switching to Barlow Condensed uppercase, not by bolding Inter.
## Layout
### Canvas System
Stencil & Tablet targets a **fixed 1920×1080 canvas** via the `<deck-stage>` component. Layout uses absolute positioning from slide edges. Top chrome sits at top: 48px, left/right: 64px. Bottom chrome at bottom: 36px, left/right: 64px. Card grids inset from those chrome positions with 22–28px gaps between cards.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-outer}` | 64px | Standard slide left/right inset |
| `{spacing.pad-top}` | 48px | Top inset for chrome |
| `{spacing.pad-bottom}` | 36px | Bottom inset for chrome |
| Internal card pad | 24–38px | Padding inside cards (compact to spacious) |
| `{spacing.gap-card}` | 22–28px | Gap between cards in a row or grid |
### Chrome Frame
Every standard slide carries top chrome and footer chrome:
- **Top bar** — left-aligned section name + right-aligned meta columns (one or two columns of 24px Barlow Condensed labels). Both uppercase, condensed, heavy-weight.
- **Footer** — left-aligned date or slide marker + right-aligned deck name. Both uppercase Barlow Condensed at 22px / 0.75 opacity.
The cover, agenda, section-divider, quote-panel, and CTA slides typically omit standard chrome — those layouts contain their own layout-specific top labels (the cover's "super" + lockup, the section-divider's eyebrow, etc.).
## Depth and Elevation
Stencil & Tablet is **flat by design**. There are no drop shadows. No box-shadows. No gradients. Depth comes entirely from:
- **Color blocks** — saturated accent fills against the bone field. A magenta tablet next to a teal tablet reads as two distinct surfaces because the colors carry the separation.
- **Rounded chrome** — 22–26px border-radius on every card softens the form and lets the eye read "tablet" rather than "rectangle."
- **Tablet stack order** — tablets are flat siblings, never stacked. No card sits on top of another card.
The single exception is the **organic-shape background** on the dark agenda layout: SVG blob shapes sit absolutely behind each agenda item in an accent color, and the number/label float on top with z-index. This is the only z-index in the system.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 999px (pill) | Status pills (yes/partial/no/note) |
| 26px | Tablet cards, principles cards, quote panel, CTA panels |
| 22px | Standard cards, action bars, process nodes, matrix table, chart frames, consult columns, stats cards |
| 18px | Decorative timeline bar |
| 14px | Cover mark (small lockup square), timeline tablet |
| 0 (square) | Chart plot box edges (the 2px solid black plot frame), legend bars, organic-shape SVG (which has no border-radius by definition) |
Cards are uniformly 22–26px rounded. Square corners appear only on chart plot frames (where the geometry of the axis lines demands it) and on legend bars (flat 32×6px rectangles for chart legends).
### Border Weights
- **2px solid `{colors.ink}`** — used on chart plot frames (left and bottom edges of the chart area) and on consult column h3 underlines.
- **1.5px solid rgba(10,10,10,0.35)** — used on matrix cell borders. The matrix is the densest table in the system and needs visible cell dividers.
- **1px dashed rgba(10,10,10,0.18–0.35)** — used inside chart plots as grid lines and as source-attribution top rules.
- **2px solid `{colors.ink}`** as a vertical separator — used inside action bars and consult headers to divide a tag from a headline.
### Decorative Element Types
**Tablet card** — the system's namesake container. A 22–26px rounded card holding a 220px+ stencil numeral above a stencil headline above Inter body. The numeral fills the upper half of the card; the headline and body sit at the bottom via `margin-top: auto`. Background takes any accent fill; text color follows the surface (ink on warm/light fills, bone on cool/dark fills).
**Color card** — a generic 22–26px rounded card in any accent fill, used for principles, process nodes, stats, and consult columns. Contains a stencil headline, optional body, and optional accent elements.
**Section-divider numeral** — a 540px stencil numeral in an accent color (typically `{colors.orange}` or `{colors.magenta}`) sitting absolute on a black field, paired with a small Barlow eyebrow at top-right and a 120px stencil headline at bottom-right. The numeral IS the layout.
**Action bar** — a full-width mustard-filled rounded card (22px radius) running near the top of a slide, containing a left-aligned uppercase Barlow tag, a vertical ink rule separator, and a stencil headline at 34px. Used for important section-opening callouts.
**Status pill** — a fully rounded (999px) pill with uppercase Barlow text. Color-coded for matrix status (teal/mustard/magenta/paper-bordered).
**Matrix table** — a paper-fill rounded card containing a grid of 1.5px-bordered cells. Head row inverts to black fill with bone stencil type. Row-label cells use stencil uppercase. Status cells contain pills.
**Process node** — a small rounded card (22px radius) holding a 64px stencil ordinal, a 28px stencil h3, and small Inter body. Process nodes sit in a 5-up grid with arrow connectors between them.
**Timeline bar** — a paper-fill rounded card (14px radius) running across the bottom of process diagrams, height 50px, with uppercase Barlow timeline markers spread evenly inside.
**Cover lockup** — a row at the bottom of a cover slide containing a small 56px rounded-square accent mark, an uppercase Barlow name + subtitle stack, and a stencil date. Defines the cover-bottom convention.
**Quote panel** — a magenta-filled 26px-rounded panel filling most of the slide, with a 320px Bowlby One quote-mark on the left and 60px stencil quote-text on the right.
**Organic blob shape** — SVG amoeba-like shapes sitting behind agenda items in a saturated accent color. The blob is the background; the number and label float on top.
**Legend bar** — a flat 32×6px rectangle (no border-radius) in a chart color, used as a chart legend swatch beside an uppercase Barlow label.
**Stat suffix** — a Barlow Condensed superscript at 40px / weight 800, vertical-align top, sitting beside a 160px stencil numeral. Standard units (% sign, ×, K, M).
## Do's and Don'ts
### Do
- Set every headline in Stardos Stencil uppercase at weight 700, regardless of size. The stencil ink-break glyphs are the system's identity.
- Use Barlow Condensed extra-heavy (600–900) uppercase for every chrome, label, pill, legend, footer, and metadata element — with letter-spacing of at least 0.04em.
- Render numerals huge — tablets at 220px, stats at 160px, section dividers at 540px. Scale is the system's primary expressive tool.
- Tile cards in saturated accents (sienna, magenta, orange, teal, blue, mustard, olive) across the bone field. Color blocks ARE the layout.
- Round every card to 22–26px. Square corners on cards break the tablet register.
- Pair stencil headlines and numerals with Inter body — the loud/quiet contrast is the typographic rhythm.
- Use `{colors.bone}` (not white) for text on dark fills. The bone-on-black inversion is the system's only color inversion and white would clash.
- Apply the matrix pill convention (teal/mustard/magenta/paper-bordered) consistently — yes/partial/no/note. The convention earns its weight by appearing repeatedly.
- Use Bowlby One for the quote-mark glyph inside a quote panel. It's the only place that face appears.
- Position chrome at fixed offsets (top: 48px / 64px, bottom: 36px / 64px). Chrome positions are non-negotiable across standard slides.
### Don't
- Don't lowercase a stencil headline. Stardos Stencil at any scale is uppercase only.
- Don't render chrome or metadata in sentence case. Barlow Condensed in this system is always uppercase.
- Don't add drop shadows or gradients. The system is flat blocks of saturated color.
- Don't square the corners on cards, action bars, or pills. The minimum acceptable card radius is 22px; pills are 999px.
- Don't invert text to pure white on dark fills. Use `{colors.bone}` — the off-white keeps the system tied to its bone/paper register.
- Don't use Inter for headlines or chrome. Inter is the body voice; it never leads.
- Don't use Stardos Stencil for body paragraphs. The stencil face at body scale (under 22px) becomes illegible — Inter is the body voice for a reason.
- Don't introduce an eighth accent color. The seven-accent palette plus bone/black/paper is closed.
- Don't use the section-divider 540px numeral on a light field. The mega-numeral pattern lives on dark fields only.
- Don't crowd cards with less than 22px gaps. The bone field visible between cards is structural.
## Responsive Behavior
Stencil & Tablet is a **fixed 1920×1080** system rendered inside a `<deck-stage>` web component. Layout uses absolute pixel positioning; the deck-stage scales the entire 1920×1080 canvas uniformly to fit the viewport. There are no media queries.
### Scaling Behavior
All elements maintain relative position and size at any viewport. A 540px section numeral remains 540px on the deck-stage's internal canvas; the stage scales the canvas to the browser. The system depends on the deck-stage component for this scaling.
### Presenter Behavior
Navigation is handled by the external `deck-stage.js` script. Each slide carries a `data-label` attribute identifying it. Slides advance via the deck-stage's controls; some slides carry `data-om-validate="false"` to opt out of certain auto-validation.
### Print Behavior
There is no embedded print stylesheet. Static export depends on the deck-stage component; for PDF generation, each slide renders as a single 1920×1080 page.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face (default) | Chinese face | Weight | Notes |
|---|---|---|---|---|
| Display / Cover hero / Section divider | Stardos Stencil 700 uppercase | 思源宋体 / Noto Serif SC | 900 | Stardos Stencil's industrial signage register translates best to Noto Serif SC at the heaviest weight (900) — Song-style strokes carry equivalent visual mass at 120–540px scale. |
| Numerals (tablet, stat, mega) | Stardos Stencil 700 | 思源宋体 / Noto Serif SC | 900 | Chinese numerals (一二三四五 or 〇一二三四) rendered in NSC 900 hold their weight against accent fills. Latin/Arabic digits inside Chinese decks should stay in Stardos for the stencil break. |
| Chrome / metadata / pill | Barlow Condensed 800 uppercase | 思源黑体 / Noto Sans SC | 700–900 | Barlow Condensed has no condensed CJK equivalent on CDN — fall back to Noto Sans SC heavy. Use tighter `font-stretch` is not available; rely on shorter labels. |
| Body | Inter 400 | 思源宋体 / Noto Serif SC | 400 | NSC body matches the loud/quiet contrast; the serif body softens the industrial register slightly but stays legible. |
### Mixed-Content Strategy
This template uses **Strategy A**: replace the Latin display face entirely with the CJK display face for any element rendering Chinese characters. Stardos Stencil's ink-break gaps are physically tied to the Latin alphabet's stroke topology — there is no Chinese stencil face on CDN that reproduces the effect, and forcing Stardos to display CJK either fails (no glyph coverage) or renders an ugly fallback. Replace the entire `font-family` with Noto Serif SC 900 for any Chinese-content element.
```css
font-family: 'Noto Serif SC', 'Stardos Stencil', serif; /* display / headlines — CJK first */
font-family: 'Noto Sans SC', 'Barlow Condensed', sans-serif; /* chrome / pills — heavy weights only */
font-family: 'Noto Serif SC', 'Inter', sans-serif; /* body */
```
Putting NSC first in the stack means Chinese characters render in NSC and any Latin/numeric content mixed inside the same element also gets NSC, which loses the stencil register for mixed lines. **Recommendation**: for cover slides with mixed-script headlines (e.g., `STUDIO 工作室`), split into two `<span>` elements — one in Stardos for the Latin word, one in NSC 900 for the Chinese phrase, sized so the visual weight matches (NSC 900 at the same px renders slightly heavier than Stardos 700).
### Loading
Add to `<head>` (Google Fonts hosts Noto Serif SC and Noto Sans SC; both ship with weight 900):
```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=Stardos+Stencil:wght@400;700&family=Bowlby+One&family=Barlow+Condensed:wght@500;600;700;800;900&family=Inter:wght@400;500;600&family=Noto+Serif+SC:wght@400;500;700;900&family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
```
Noto Serif SC 900 is critical — it's the only weight that holds visual parity with Stardos Stencil at large scale. Lighter weights (700 or below) render Chinese headlines as "thin" beside Stencil Latin.
### Universal CJK Adjustments
Apply on any element rendering Chinese content (typically scope via `:lang(zh)` or `<span lang="zh">`):
- **Line-height**: body 1.75–1.85 (Stencil & Tablet's 1.4 Inter-default is too tight for CJK strokes); display 1.15–1.25 (looser than Latin 0.8–0.92 because CJK glyphs at 220–540px need vertical breathing room or strokes collide).
- **Letter-spacing**: 0 on CJK. Stencil & Tablet's negative tracking on Latin display (-0.005 to -0.02em) and positive tracking on Barlow chrome (0.04–0.14em) are both wrong for Chinese — CJK glyphs are pre-spaced; tracking creates either overlap or unnatural gaps.
- **Text-transform**: no uppercase on CJK. Stencil & Tablet uppercases nearly everything in Latin; on Chinese this is a no-op but ensure no parent rule attempts it (some browsers may render unpredictably).
- **Full-width punctuation**: use `,。:;!?` (full-width) not `,.:;!?` (half-width). The full-width forms include their own surrounding whitespace and align to the CJK em-box.
- **No period on display headlines**: Chinese headlines drop the terminal `。` — the headline's visual closure is enough.
- **Pangu spacing (盘古之白)**: insert a thin space between CJK and adjacent Latin/numerals. Write `使用 Claude` not `使用Claude`; `2024 年` not `2024年`. Especially important in this system since Stardos numerals frequently sit beside Chinese labels.
- **One font per sentence**: don't mix NSC and Noto Sans SC inside a single line. The serif/sans switch should happen at element boundaries, not mid-phrase.
### Aesthetic Notes for This System
Noto Serif SC 900 against a saturated accent fill (magenta, orange, teal) reproduces the poster-loud register of the system well — the heavy Song strokes have similar visual mass to Stardos Stencil's chunky stencil glyphs. The system's identity (industrial signage / municipal stencil) shifts slightly toward "Chinese newspaper headline" in CJK, which is a related but distinct register; for projects where the industrial stencil feel is essential, lean on Stardos for Latin words and accept that pure-Chinese headlines will read as authoritative newspaper-poster type rather than skate-deck stencil.
The matrix pill convention (teal=yes, mustard=partial, magenta=no) translates directly — replace the uppercase Barlow text inside pills with NSC 700 sentence-case Chinese labels (`是` / `部分` / `否`). Pill width may grow to accommodate Chinese (single-character labels are tightest); keep the 999px radius and accept slightly wider pills.
The 540px section-divider numeral pattern is one of the system's strongest moments and works beautifully with Chinese — `一` `二` `三` rendered at 540px NSC 900 against the black field carries equal visual authority to Stardos at the same size. For two-digit numerals, NSC 900 will be narrower than Stardos at the same px, so consider bumping to 600–620px to maintain the "numeral fills the canvas" register.
### Known CJK Gap
- Barlow Condensed has no condensed CJK equivalent. The system's uppercase-heavy-condensed-tracked chrome aesthetic cannot be reproduced; Noto Sans SC 900 is the closest fallback but lacks the condensed proportion. Accept that Chinese chrome will feel slightly wider than Latin chrome.
- Bowlby One is Latin-only and lives in a single place (the 320px quote-mark inside quote panels). For Chinese quote panels, replace with `「` (full-width left corner bracket) or `『` rendered in NSC 900 at 320px in the original `{colors.magenta}` or `{colors.teal}` — this is the conventional Chinese quote-opening glyph and reads correctly without the Bowlby weight.
- Stardos Stencil is a single weight (700). NSC ships with 400, 500, 700, 900; the system specifies weight 700 for everything in Stardos, but for CJK you should use NSC 900 to match visual mass — the spec's "weight 700" is a Latin convention that doesn't apply.
- The pill convention's `letter-spacing: 0.04–0.14em` is meaningless on CJK and should be zeroed for any Chinese pill content.
## Iteration Guide
1. Any new headline uses Stardos Stencil uppercase at weight 700. The stencil ink-break is the system's most recognizable trait.
2. Any new card uses 22–26px border-radius and a saturated accent fill from the seven-color palette. The tablet form factor is the default container.
3. Any new tablet must include a stencil numeral above its headline. A tablet without a numeral is just a card.
4. Any new chrome, label, pill, or legend uses uppercase Barlow Condensed at weight 600–900 with letter-spacing of at least 0.04em.
5. Any new body paragraph uses Inter at 18–24px. Inter is the system's only sentence-case face.
6. Status pills inside matrix layouts follow the fixed color convention (teal/mustard/magenta/paper-bordered). Don't invent new statuses with new colors — extend by reusing the existing palette.
7. Numerals always run weight 700 with negative letter-spacing (typically –0.02em). Smaller weight stencil numerals break the system.
8. Cool fills (teal, blue, black) flip text to `{colors.bone}`. Warm and mid fills (sienna, magenta, orange, mustard, olive, paper, bone) stay with `{colors.ink}`.
9. Section-divider slides use the 540px-numeral + 120px-headline + black-field pattern. Don't compress section dividers into smaller frames — the scale IS the divider.
10. The bone field visible between and around cards is structural. Don't shrink it to fit more content; if content doesn't fit, reduce content.
## Known Gaps
- The system depends on the external `deck-stage.js` script for slide scaling and navigation. Without it, slides render at intrinsic 1920×1080.
- All four font families (Stardos Stencil, Bowlby One, Barlow Condensed, Inter) load from Google Fonts. If fonts fail, fallbacks (serif, sans-serif, Helvetica, Arial) lose the stencil and condensed personality entirely.
- Stardos Stencil is a single-weight typeface — there is no weight axis. The system uses font-weight: 700 as a label but the face actually has only one weight; specifying 400 in the quote-text token renders nearly identically.
- Bowlby One appears in exactly one place (the 320px quote-mark). It is a heavyweight asset for a single glyph; if the quote panel is unused, Bowlby One is dead weight in the font load.
- The organic-shape SVG blobs on the agenda slide are inline SVG paths with hand-tuned bezier curves — they are not parametric and adding a new shape requires drawing it.
- The chart plot SVG uses hardcoded coordinates inside a fixed-aspect SVG; data updates require manually recomputing point positions.
- The seven-accent palette doesn't strictly map colors to semantic roles outside the matrix. Decks may follow loose conventions (orange = primary, teal = secondary) but the system doesn't enforce them.
- Cover hero, numeral-tablet, and section-headline all use generous letter-spacing in the negative direction — at very small viewport scaling, glyphs may touch. The deck-stage's uniform scaling avoids this in practice.
# Stencil & Tablet Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/stencil-tablet/design.md`
- Preview card: `bold-template-pack/templates/stencil-tablet/preview.md`
## Selection Metadata
- Slug: `stencil-tablet`
- Tagline: Bone paper with stencil-cut headlines and a six-color earth palette: archaeology meets brand.
- Mood: archival, earthy, tactile, considered, graphic
- Tone: weighty, considered, tactile, literary
- Formality: medium-high
- Density: medium
- Scheme: light
- Best for: Anything that should feel archival, tactile, and weighty-graphic: museum and cultural-institution decks, art / architecture brands, longform research, heritage and craft brands, manifestos. A great choice anytime — including across tech and business — when you want the deck to feel like a field manual rather than a slide deck.
- Avoid for: Contexts that demand digital-native polish or playful pop — the stencil-cut display and earth-tone palette commit to a deliberate analog feel.
## Visual Snapshot
A West Coast skate-poster meets municipal stencil signage system. Stardos Stencil carries every headline, numeral, and chunky display moment with its characteristic ink-break gaps; Barlow Condensed runs all metadata and uppercase chrome at extra-heavy weights; Inter handles body. The palette is bone (#E2DCC9) and black, energized by a saturated retro-print accent set — sienna, magenta, orange, teal, blue, mustard, olive. Soft rounded "tablet" cards (22–26px radius) tile across slides in colored blocks. Type runs huge and uppercase, numerals dominate at 160–540px, and color blocks act as the layout. The mood is industrial poster, vintage workshop sign, and music festival lineup all at once.
Stencil & Tablet is a poster-loud, type-led presentation system. The premise is a single display face — Stardos Stencil — handling every headline, every numeral, every featured moment, with characteristic stencil ink-breaks giving each glyph a slightly-distressed industrial register. The supporting cast is Barlow Condensed (extra-heavy 600–900, uppercase, generous tracking) running all metadata, chrome, pills, and legends — and Inter handling the small set of body paragraphs that exist mostly to caption the loud type above them.
## Preview Ingredients
- Palette: bone #E2DCC9; black #000000; ink #0A0A0A; paper #F4EFE0; sienna #A06A3C; magenta #C73B7A; orange #EE7A2E; teal #2D7E73
- Typography: Stardos Stencil; Bowlby One; Barlow Condensed; Inter
- Signature move: Bone ({colors.bone}) field on most slides; black field with bone type on agenda-style and bold-divider slides.
- Signature move: Stardos Stencil for every headline, every numeral, every featured stencil moment — the ink-break stencil glyphs are the system's identity.
- Signature move: Barlow Condensed extra-heavy uppercase for all chrome, metadata, pills, legends, and labels. Generous letter-spacing (0.06–0.14em).
- Signature move: Inter for body — small role, supporting the loud type above.
- Signature move: Seven-color accent palette ({colors.sienna}, {colors.magenta}, {colors.orange}, {colors.teal}, {colors.blue}, {colors.mustard}, {colors.olive}) plus paper ({colors.paper}) — used as full card fills.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Studio
description: A "Boring Studios" agency presentation system — type-as-graphic-mass in the spirit of contemporary design-studio decks (Pentagram, Anti, Order). The entire system runs on Barlow at weight 900 uppercase, with type so heavy at display scale that it stops being type and starts being a shape. The palette is binary plus one: near-black field (#1C1C1C), acid yellow type (#F5D200), and the same yellow as a full slide background. IBM Plex Mono carries every footer metadata, slide counter, and three-column lockup. No drop shadows, no rounded corners, no accent colors — the headline IS the design, and the only chromatic decision per slide is dark-yellow-on-near-black or near-black-on-acid-yellow.
colors:
near-black: "#1C1C1C"
near-black-alt: "#242422"
acid-yellow: "#F5D200"
acid-yellow-alt: "#F0CC00"
text-on-dark-2: "rgba(245,210,0,0.58)"
text-on-dark-3: "rgba(245,210,0,0.32)"
text-on-light-2: "rgba(28,28,28,0.62)"
text-on-light-3: "rgba(28,28,28,0.35)"
border-dark: "#2E2E2C"
border-light: "rgba(28,28,28,0.18)"
color-aliases:
c-bg: near-black
c-bg-alt: near-black-alt
c-bg-light: acid-yellow
c-bg-light-alt: acid-yellow-alt
c-fg: acid-yellow
c-fg-light: near-black
c-accent: acid-yellow
c-fg-2: text-on-dark-2
c-fg-3: text-on-dark-3
c-fg-light-2: text-on-light-2
c-fg-light-3: text-on-light-3
typography:
display:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: 12vw
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.02em
textTransform: uppercase
h1:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: 7.5vw
fontWeight: 900
lineHeight: 0.92
letterSpacing: -0.02em
textTransform: uppercase
h2:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: 4.8vw
fontWeight: 900
lineHeight: 0.95
letterSpacing: -0.01em
textTransform: uppercase
h3:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: 2.8vw
fontWeight: 700
lineHeight: 1.1
textTransform: uppercase
quote-text:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: 3.8vw
fontWeight: 900
lineHeight: 1.05
letterSpacing: -0.02em
textTransform: uppercase
stat-value:
fontFamily: "Barlow, Noto Sans SC, sans-serif"
fontSize: 5.5vw
fontWeight: 900
lineHeight: 0.9
letterSpacing: -0.03em
textTransform: uppercase
lead:
fontFamily: "Barlow, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.6vw
fontWeight: 500
lineHeight: 1.45
body:
fontFamily: "Barlow, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.15vw
fontWeight: 400
lineHeight: 1.6
caption:
fontFamily: "Barlow, Noto Sans SC, system-ui, sans-serif"
fontSize: 0.85vw
fontWeight: 400
lineHeight: 1.5
label:
fontFamily: "IBM Plex Mono, monospace"
fontSize: 0.72vw
fontWeight: 500
letterSpacing: 0.06em
spacing:
pad-x: 5vw
pad-y: 5vh
gap-lg: 3.5vh
gap-md: 2vh
gap-sm: 1vh
canvas:
width: 100vw
height: 100vh
components:
chrome-bar:
borderBottom: "1px solid {colors.border-dark} (or {colors.border-light} on yellow)"
paddingBottom: "{spacing.gap-sm}"
marginBottom: "{spacing.gap-md}"
description: "Top chrome bar — mono label left, mono counter right, hairline rule beneath."
foot-bar:
borderTop: "1px solid {colors.border-dark} (or {colors.border-light} on yellow)"
paddingTop: "{spacing.gap-sm}"
marginTop: "{spacing.gap-md}"
description: "Bottom chrome bar — mirror of chrome-bar."
cover-meta:
display: "grid 1fr 1fr 1fr"
borderTop: "1px solid rgba(245,210,0,0.25)"
description: "Three-column mono metadata footer over the cover image: studio × client + date, presentation title (center), studio name (right). The signature 'Boring Studios' lockup."
stat-card:
borderTop: "2px solid (acid-yellow on dark, near-black on yellow)"
padding: "{spacing.gap-md} {spacing.gap-md} {spacing.gap-md} 0"
description: "Stat tile with a 2px top rule. Value at 5.5vw weight 900 in the surface's foreground color; label and mono note beneath."
bullet-marker:
content: "—"
color: "acid-yellow on dark, near-black on yellow"
fontFamily: "{typography.body.fontFamily}"
description: "Em-dash bullet prefix on every list item; color follows the surface accent."
compare-divider:
borderRight: "2px solid (near-black on yellow, dark-text-3 on dark)"
description: "Single vertical 2px rule separating two compare panels."
bar-fill-default:
background: "muted text-on-surface (dark-text-3 or light-text-3)"
description: "Default chart bar fill — muted version of the surface text color."
bar-fill-accent:
background: "acid-yellow on dark, near-black on yellow"
description: "Highlighted chart bar — the surface's primary foreground color."
chart-baseline:
height: "2px"
background: "muted accent (dark-text-3 or border-light)"
description: "Heavier 2px baseline beneath chart bars — Studio uses thicker rules than Signal."
cover-img-area:
position: "absolute inset 0"
background: "{colors.near-black-alt}"
description: "Cover image placeholder filling the entire slide behind the cover-type and cover-meta. Image-or-placeholder occupies the whole canvas; type sits on top."
img-placeholder:
background: "near-black-alt on dark, acid-yellow-alt on yellow"
description: "Warm-toned rectangular placeholder for images, centered mono label inside, no border on dark / hairline border on yellow."
---
## 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
Studio is a **type-as-graphic-mass** presentation system — the visual register of contemporary design-studio decks (Pentagram, Anti, Order, "Boring Studios" agency aesthetic). The premise is reductive to the point of severity: a single typeface (Barlow), at a single weight (900), in strict uppercase, at scales so large that type stops behaving like type and starts behaving like a graphic shape. The headline IS the design — there are no decorative elements, no accent colors, no ornaments. If you removed every other element from a Studio slide and left only the headline, the slide would still read as Studio.
The palette is **binary plus one**. The dark surface is `{colors.near-black}` (#1C1C1C) — a warm dark, not cold neutral. The light surface is `{colors.acid-yellow}` (#F5D200) — a saturated cadmium yellow that fills the entire slide, not as an accent but as the environment. On dark slides, text is `{colors.acid-yellow}`. On yellow slides, text is `{colors.near-black}`. That's the entire color system: dark/yellow, yellow/dark. There are no secondary colors, no grays, no warming accents. Even muted text is just the same color at reduced opacity (yellow at 58%, near-black at 62%).
The typeface stack is **functional rather than expressive**. Barlow at weight 900 carries every headline at every scale — from 1.15vw body all the way up to 12vw cover display. Barlow at 500 carries body and lead paragraphs. IBM Plex Mono carries the metadata footer, slide counter, and three-column cover lockup — and is the only point in the system where a second face appears. Mono is the system's "spec sheet" voice; everywhere else, Barlow dominates.
Depth is **flat and severe**. No drop shadows. No rounded corners. No gradients. Borders are 1px or 2px hairlines in `{colors.border-dark}` or `{colors.border-light}`. The 2px chart baseline and 2px stat-card top-rule are the heaviest lines in the system. The system reads as an architectural drawing or a manifesto poster — every line is intentional, nothing decorative.
**Density philosophy: low and deliberate.** Studio is sparse by design. A statement slide is one headline filling most of the canvas with empty surface above and below. A chapter slide is a small mono label and a headline. A cover is an image placeholder behind a single word at 12vw. Padding runs tighter than Signal (5vw / 5vh vs 7.5vw / 5.5vh) because the type itself runs nearly to the edge — the heading is the spatial fill, not the margin. A slide that feels broken in Studio is one that contains multiple competing elements or fills its canvas with body paragraphs. The correct register is "one massive thing, said once, in 900 weight uppercase."
**Key Characteristics:**
- Binary palette — `{colors.near-black}` field with `{colors.acid-yellow}` type, or `{colors.acid-yellow}` field with `{colors.near-black}` type. No third color.
- Barlow at weight 900 uppercase for every headline at every scale; Barlow 400/500 for body; IBM Plex Mono only for metadata chrome.
- Headlines run massive — cover display at 12vw (~230px at 1920px viewport), statements at 7.5vw, section headers at 4.8vw.
- Tight negative letter-spacing on all display type (-0.01 to -0.03em); uppercase non-negotiable.
- Flat: no drop shadows, no rounded corners, no gradients, no accent colors beyond the yellow/dark binary.
- Hairline 1px borders on chrome; 2px on stat-card tops, chart baselines, and compare panel dividers.
- Three-column mono metadata footer on the cover slide is the system's signature lockup (studio × client / presentation title / studio name).
- Em-dash bullet markers in the surface accent color (yellow on dark, near-black on yellow).
- Body and chrome opacity-tuned versions of the same color (yellow at 58%/32%, near-black at 62%/35%) — never a separate grey color.
## Colors
### Palette
- **Near-Black** (`{colors.near-black}` — #1C1C1C): The dark surface. A warm dark, slightly biased toward brown rather than cold neutral. The "ink" of the system.
- **Near-Black Alt** (`{colors.near-black-alt}` — #242422): A barely-lifted near-black for image placeholders and secondary dark surfaces. Visually nearly identical to near-black.
- **Acid Yellow** (`{colors.acid-yellow}` — #F5D200): The light surface AND the primary text color on dark surfaces. Cadmium yellow, saturated and slightly warm. On dark slides, this is the type color. On light slides, this is the background. Same color, two roles.
- **Acid Yellow Alt** (`{colors.acid-yellow-alt}` — #F0CC00): A slightly cooler yellow for adjacent-surface differentiation on light slides. Used sparingly.
- **Text on Dark 2** (`{colors.text-on-dark-2}` — rgba(245,210,0,0.58)): Secondary text on dark — yellow at 58% opacity. The system never uses a separate "grey" color; muting is opacity only.
- **Text on Dark 3** (`{colors.text-on-dark-3}` — rgba(245,210,0,0.32)): Tertiary text on dark — yellow at 32%.
- **Text on Light 2** (`{colors.text-on-light-2}` — rgba(28,28,28,0.62)): Secondary text on yellow — near-black at 62%.
- **Text on Light 3** (`{colors.text-on-light-3}` — rgba(28,28,28,0.35)): Tertiary text on yellow — near-black at 35%.
- **Border Dark** (`{colors.border-dark}` — #2E2E2C): Hairline border color on dark surfaces. Slightly lifted from near-black so it reads as a line, not a void.
- **Border Light** (`{colors.border-light}` — rgba(28,28,28,0.18)): Hairline border color on yellow surfaces. Low-opacity near-black for subtle separation.
### Defaults
- **Default surface**: alternate between `{colors.near-black}` (dark) and `{colors.acid-yellow}` (light) across the deck. Both surfaces are first-class. If unsure, reach for near-black for cover/quote/statement slides, acid-yellow for chapter and end slides.
- **Default primary text on dark**: `{colors.acid-yellow}`.
- **Default primary text on yellow**: `{colors.near-black}`.
- **Default secondary text on dark**: `{colors.text-on-dark-2}` (yellow at 58% opacity).
- **Default secondary text on yellow**: `{colors.text-on-light-2}` (near-black at 62%).
- **Default tertiary text** (mono captions, chart axis labels, stat notes): tier-3 opacity on the surface accent.
- **Default border on dark**: `{colors.border-dark}`.
- **Default border on yellow**: `{colors.border-light}`.
- **Default headline color**: surface accent — yellow on dark, near-black on yellow. Never any other color.
- **Default chart accent fill**: surface accent (yellow on dark, near-black on yellow). The "highlighted" bar is just the primary text color; "default" bars are tier-3 muted.
There are no semantic color roles. Yellow does not mean "warning"; near-black does not mean "primary." They are simply the two surfaces. Choice between them is rhythmic — alternate to vary the visual cadence, or run several dark slides in a row for a quiet section followed by a single yellow slide for a punctuation moment.
## Typography
### Font Family
Studio runs **two families** in strictly separated roles:
- **Barlow** (`{typography.display.fontFamily}`) — a contemporary grotesque with a wide weight axis. Carries every headline at every scale (display through h3), every numeral (stat-value), every quote, all body, and all lead paragraphs. The system uses weight 900 for all display and headline tokens; weight 700 for h3; weight 500 for lead and bullet markers; weight 400 for body and caption.
- **IBM Plex Mono** (`{typography.label.fontFamily}`) — a precision monospace. Used **only** for metadata labels — chrome bars, slide counters, chapter numbers, the three-column cover lockup, stat notes, mono captions inside cover-meta. Mono is the system's "metadata voice"; everywhere else, Barlow dominates.
The emotional split is binary: Barlow for content (loud, uppercase, dominant); IBM Plex Mono for spec-sheet metadata (small, precise, supportive). There is no third face.
Barlow weight 900 at display scale stops behaving like a typeface and starts behaving like a graphic shape — the letterforms are so heavy that counters (the holes inside letters) become structural negative space, and the headline reads as a black or yellow geometric block before it reads as words. This is the system's identity.
### Type Scale
| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | 12vw | Barlow | 900 | Cover hero at maximum scale |
| `{typography.h1}` | 7.5vw | Barlow | 900 | Chapter title, full-slide statement headline |
| `{typography.stat-value}` | 5.5vw | Barlow | 900 | Statistical numeral inside a stat card |
| `{typography.h2}` | 4.8vw | Barlow | 900 | Primary slide headline |
| `{typography.quote-text}` | 3.8vw | Barlow | 900 | Pull-quote body (uppercase, no quote marks) |
| `{typography.h3}` | 2.8vw | Barlow | 700 | Sub-headline, panel title |
| `{typography.lead}` | 1.6vw | Barlow | 500 | Lead paragraph, intro sentence |
| `{typography.body}` | 1.15vw | Barlow | 400 | Default body paragraph, bullet body |
| `{typography.caption}` | 0.85vw | Barlow | 400 | Caption, source attribution |
| `{typography.label}` | 0.72vw | IBM Plex Mono | 500 | Mono chrome, slide counter, chapter number, stat note, cover-meta |
### Defaults
- **Default size for a primary section headline**: `{typography.h2}` (4.8vw).
- **Default size for a chapter or statement headline**: `{typography.h1}` (7.5vw).
- **Default size for a cover hero**: `{typography.display}` (12vw).
- **Default size for a paragraph body**: `{typography.body}` (1.15vw).
- **Default size for a lead sentence**: `{typography.lead}` (1.6vw).
- **Default size for any chrome label, counter, or mono caption**: `{typography.label}` (0.72vw).
- **Default size for a statistical numeral**: `{typography.stat-value}` (5.5vw) in the surface accent.
- **Default weight for any headline**: 900.
- **Default weight for any body element**: 400 (lead = 500).
When unsure between sizes, lean larger. Studio's identity depends on type running massive — a 4.8vw h2 reads as the system; a 2.8vw h3 used as a primary headline reads as a different system.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every display, h1, h2, h3, quote-text, and stat-value is uppercase.** Sentence-case display type does not exist. Even h3 (2.8vw) at weight 700 runs uppercase.
- **Every display headline uses weight 900.** Display, h1, h2, quote-text, and stat-value are all weight 900 — no exceptions. Using weight 800 or 700 at display scale breaks the type-as-graphic-mass effect.
- **Every display element uses negative letter-spacing.** Display at –0.02em, h1 at –0.02em, h2 at –0.01em, stat-value at –0.03em. Display Barlow 900 without negative tracking reads as untreated; the negative tracking is what gives the type its compressed density.
- **All chrome, labels, counters, and metadata are IBM Plex Mono at 0.06em tracking.** No exceptions. Mono labels in Barlow break the metadata/content separation.
- **Headlines are always rendered in the surface accent color** — yellow on dark, near-black on yellow. Never a muted opacity, never a different color.
- **Body bullets use an em-dash in the surface accent color**, never a dot, never a different glyph. The em-dash carries surface-aware color (yellow on dark, near-black on yellow).
- **Stat cards have a 2px (not 1px) top rule** in the surface accent (or muted accent on the dark side). The 2px rule is heavier than chrome hairlines because stats are anchors.
- **The three-column cover-meta lockup uses IBM Plex Mono with column 1 left-aligned, column 2 centered, column 3 right-aligned.** This is the "Boring Studios" signature; the column structure is non-negotiable.
### Typography Principles
The face ladder is fixed: Barlow for everything except metadata; IBM Plex Mono for metadata only. Mono outside metadata roles, or Barlow inside metadata roles, breaks the typographic separation.
The weight ladder is fixed too: 900 / 700 / 500 / 400. Intermediate weights (600, 800) are not used. The four-tier weight system is the entire expressive register of the typography.
Line-height runs tight at display scale (0.9 on display, 0.92 on h1) and opens to 1.5–1.6 on body. Letter-spacing is uniformly negative on display (–0.01 to –0.03em), zero on body, positive 0.06em on mono labels.
Italic is not used. Underline is not used. There is no font-style variation in the system; emphasis is achieved purely by weight contrast (900 headline against 400 body).
## Layout
### Canvas System
Studio targets `100vw × 100vh` — full viewport. Each `.slide` flexes to fill the viewport exactly, and slides sit side-by-side in a horizontal strip that translates left/right on navigation. All sizes use viewport-relative units (`vw`, `vh`) so layout scales fluidly.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 5vw | Horizontal slide padding |
| `{spacing.pad-y}` | 5vh | Vertical slide padding |
| `{spacing.gap-lg}` | 3.5vh | Between major content sections |
| `{spacing.gap-md}` | 2vh | Between related elements |
| `{spacing.gap-sm}` | 1vh | Between tightly coupled elements |
Statement and chapter slides increase bottom padding to 1.5× pad-y so the headline drops to the lower portion of the slide with deliberate empty space above. The cover slide uses zero outer padding because the image area fills the entire canvas.
### Chrome Frame
Standard slides carry a top chrome bar and a bottom foot bar:
- **Chrome bar** — left-aligned mono label, right-aligned mono counter, 1px hairline rule beneath. Padding-bottom is `{spacing.gap-sm}`, margin-bottom is `{spacing.gap-md}`.
- **Foot bar** — left-aligned mono label, right-aligned mono counter, 1px hairline rule above. Mirror of the chrome bar.
The cover, chapter, statement, quote, and end slides omit standard chrome — those layouts use either the cover-meta lockup (cover) or nothing (chapter, statement, quote, end).
### Cover Lockup
The cover slide is the system's signature layout:
- An image placeholder fills the entire canvas behind everything.
- A single display headline (typically one word at 12vw) sits in the top area as `cover-type`.
- A three-column mono metadata footer sits at the bottom — column 1 left ("studio × client" + date), column 2 center (presentation title), column 3 right (studio name) — separated from the image area by a 1px hairline in yellow at 25% opacity.
## Depth and Elevation
Studio is **flat by design**. There are no drop shadows. No rounded card elevation. No gradients. Every element sits flush with the surface.
Apparent depth comes from:
- **Surface contrast** — near-black against acid-yellow when both appear (compare panels, image placeholders).
- **Hairline separation** — 1px and 2px borders divide regions.
- **Heavy type** — display headlines at weight 900 create visual mass that reads as foreground against the flat surface.
The system is intentionally severe. If a layout requires elevation to read correctly, the layout is wrong for Studio — reduce content or reorganize so that the flat surface plus heavy type plus hairlines provide enough hierarchy.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0 | Everything in the system |
| 50% (circle) | Nav dots and slide-counter UI only (not part of the slide content) |
Studio has **no rounded chrome**. Cards, panels, stat tiles, chart frames, image placeholders, compare panels — all strict rectangles with sharp corners. The only round shapes are the navigation dots and the underlying slide counter UI, which are deck-stage chrome, not slide content.
### Border Weights
- **1px solid** in `{colors.border-dark}` (on near-black) or `{colors.border-light}` (on yellow) — the universal hairline. Used on chrome bars, foot bars, cover-meta separator.
- **2px solid** in the surface accent (yellow on dark, near-black on yellow) — the heavier rule. Used on stat-card top rules, compare panel vertical dividers, chart baselines, chart bar-track left rules.
- **No dashed borders.** Every border in the system is solid.
### Decorative Element Types
**Display headline as graphic mass** — Barlow at weight 900 at display scale (4.8vw and above) sits as a black or yellow geometric block. The headline is the primary decorative element of every slide; there are no additional ornaments.
**Hairline rule** — a 1px solid line in the surface border color. Used to separate chrome from body, body from foot, and inside compare panels. The rule is the system's only structural divider.
**Heavy rule** — a 2px solid line in the surface accent (or muted accent). Used on stat-card tops, chart baselines, compare-panel vertical dividers. Heavier than the chrome hairline; reads as "anchor" rather than "separator."
**Stat card** — a flat region with a 2px top rule, a stat numeral (5.5vw Barlow 900) in the surface accent, a stat label (1.15vw Barlow 500), and an optional mono stat-note (0.85vw IBM Plex Mono at tier-3 opacity). Padding right and bottom; left padding is zero (the rule starts flush with the card's left edge).
**Cover-meta lockup** — the three-column mono footer at the bottom of the cover slide. Column 1: studio × client name on row 1, date on row 2. Column 2: presentation title (centered). Column 3: studio name (right-aligned). Separated from the cover-type by a 1px hairline in yellow at 25% opacity.
**Image placeholder** — a flat rectangle filled with `{colors.near-black-alt}` (on dark) or `{colors.acid-yellow-alt}` with a hairline border (on yellow), containing centered IBM Plex Mono text at tier-3 opacity. Used for image slots that haven't been filled.
**Chart bar** — a flat vertical rectangle in muted text-on-surface color (default) or the surface accent (highlighted). No rounded ends, no gradient. The "hi" variant uses the full accent color and weight 900 on its numerical label.
**Chart baseline** — a 2px solid line in muted surface accent (yellow tier-3 on dark, border-light on yellow) running the full width of the chart wrapper, below the bar tops.
**Em-dash bullet** — `—` prefix on every list item in the surface accent color, with 0.5em right margin. Color flips with the surface.
## Do's and Don'ts
### Do
- Use Barlow at weight 900 uppercase for every headline at every scale, with negative letter-spacing of at least -0.01em. The type-as-graphic-mass effect is the system's identity.
- Alternate `{colors.near-black}` and `{colors.acid-yellow}` surfaces freely. Both are first-class; the rhythm of dark/yellow alternation is the system's pacing.
- Color every headline in the surface accent — yellow on dark, near-black on yellow. Never a muted version, never a third color.
- Use IBM Plex Mono only for metadata (chrome labels, slide counters, chapter numbers, cover-meta lockup, stat notes, mono captions). Mono is the spec-sheet voice; never use it for content.
- Render the cover-meta footer as a three-column mono lockup (left/center/right). This is the system's signature pattern.
- Mute secondary text with opacity (.58 on yellow, .62 on near-black), not with a separate grey color. The system has no greys — only opacity variants of yellow and near-black.
- Apply 2px rules to stat-card tops, chart baselines, and compare-panel dividers. The 2px weight differentiates "anchor" elements from chrome hairlines.
- Use em-dashes in the surface accent color as bullet markers — never dots, never circles.
- Pad slides tight (5vw / 5vh) so display type runs near the edge. Studio depends on type filling the canvas; generous padding breaks the scale effect.
- Leave statement and chapter slides deliberately sparse. One massive headline against empty surface is the correct register for those slide types.
### Don't
- Don't lowercase a headline. Every Barlow 900 element runs uppercase, no exceptions.
- Don't use weight 800 or 700 at display scale. Display = 900 weight, always.
- Don't add a third color to the palette. The system is binary plus opacity variants — adding red, blue, or any accent breaks the binary logic.
- Don't round any corner. Strict rectangles everywhere; only the nav dots are circles.
- Don't add drop shadows or gradients. The system is severely flat — depth comes from contrast and weight, not elevation.
- Don't use Barlow for chrome metadata. Mono is the metadata voice; chrome in Barlow reads as content rather than spec.
- Don't use Mono for headlines or body. Mono lives in the metadata role only.
- Don't add italic, underline, or color variants for emphasis. The only emphasis mechanism is weight contrast (900 vs 400).
- Don't introduce dashed borders. Every line in the system is solid.
- Don't fill more than ~60% of a typical slide with content. The empty surface is structural — Studio reads as broken when crowded.
## Responsive Behavior
Studio targets a 1920×1080 viewport and uses viewport-relative units (`vw`, `vh`) throughout, so layout scales fluidly between 1280×720 and 2560×1440 without breakpoints. There are no fixed pixel measurements except deck-chrome dots and the slide counter.
### Scaling Behavior
- Display headline scales: 12vw → ~230px at 1920px viewport, ~154px at 1280px.
- Body text scales: 1.15vw → ~22px at 1920px, ~15px at 1280px.
- Padding scales: pad-x 5vw → ~96px at 1920px, ~64px at 1280px.
The 2px and 1px border weights are fixed pixel sizes that do not scale; at large viewports, borders read proportionally finer.
### Presenter Behavior
The deck is JS-driven, with slides arranged side-by-side in a horizontal strip that translates left/right on navigation. The current slide carries `is-active`, which triggers any `[data-anim]` elements to animate in. Animations are sharper and shorter than Signal (0.5s duration vs 0.65s; 0.75s slide vs 0.85s) — "agency urgency, not editorial grace," per the source comment. Animation keyframes include fade-up, fade-in, reveal-right, reveal-left, scale-in with staggered `data-delay` (0–6).
Nav dots and a slide counter sit fixed at the bottom of the viewport — small white-on-dark UI that is intentionally subtle.
### Print Behavior
There is no embedded print stylesheet. The horizontal-strip layout would need to be unwound for static export.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face (default) | Chinese face | Weight | Notes |
|---|---|---|---|---|
| Display / h1 / h2 / quote-text / stat-value | Barlow 900 uppercase | 思源宋体 / Noto Serif SC | 700 | Studio's defining "type-as-graphic-mass" effect depends on a single typeface at maximum weight. NSC 700 is the heaviest Song-style serif on CDN that holds visual mass at 12vw / 7.5vw / 4.8vw display sizes. |
| h3 | Barlow 700 uppercase | 思源宋体 / Noto Serif SC | 700 | Sub-headline weight matches. |
| Lead / Body / Caption | Barlow 500 / 400 | 思源宋体 / Noto Serif SC | 400 | Minimal editorial body — NSC 400 reads cleanly in the system's sparse layouts. |
| Metadata / chrome / label / stat-note | IBM Plex Mono 500 | IBM Plex Mono + Noto Sans Mono CJK fallback | 400–500 | Mono CJK is rarely needed (most metadata stays in Latin: dates, counters, studio names) but if Chinese appears in chrome, use Noto Sans Mono CJK SC. |
### Mixed-Content Strategy
This template uses **Strategy A**: replace the Latin face entirely with the CJK face for any element rendering Chinese characters. Studio's identity is type-as-graphic-mass — and Barlow 900 cannot render CJK glyphs (no glyph coverage). Mixing Barlow Latin with NSC CJK in the same line via stack fallback creates a metric mismatch at display scale that breaks the "single typeface, single weight" register. Replace the entire `font-family` with NSC for any Chinese-content element.
```css
font-family: 'Noto Serif SC', 'Barlow', sans-serif; /* display / headlines — CJK first */
font-family: 'Noto Serif SC', 'Barlow', sans-serif; /* body — CJK first */
font-family: 'IBM Plex Mono', 'Noto Sans Mono CJK SC', monospace; /* mono — Latin first, CJK only if needed */
```
For pure-Chinese decks, the system's "uppercase" identity drops away (Chinese has no case), so Studio's character shifts from "industrial agency manifesto" toward "editorial Chinese newspaper headline." This is a real register change — Chinese Studio reads as serious and severe, but no longer reads as Pentagram/Anti. Accept this trade-off or scope Chinese to specific slides while keeping the cover and section dividers in Latin Barlow.
### Loading
Add to `<head>` (Google Fonts hosts Noto Serif SC and Noto Sans SC):
```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=Barlow:wght@400;500;700;900&family=IBM+Plex+Mono:wght@400;500&family=Noto+Serif+SC:wght@400;500;700;900&family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
The Barlow stack in the original design.md already wires Noto Sans SC as the CJK fallback. We're upgrading to Noto Serif SC for headlines and body because the Song-style serif at 900 weight carries graphic mass equivalent to Barlow 900, where Noto Sans SC at the same weight reads as too smooth/round and loses the "graphic block" character. Keep Noto Sans SC available for body-only decks where the cleaner sans is preferred.
### Universal CJK Adjustments
Apply on any element rendering Chinese content (typically scope via `:lang(zh)` or `<span lang="zh">`):
- **Line-height**: body 1.75–1.85 (Studio's 1.5–1.6 Barlow-default is fine for Latin but tight for CJK strokes); display 1.15–1.25 (looser than Latin 0.9–0.95 because CJK glyphs at 12vw need vertical breathing).
- **Letter-spacing**: 0 on CJK. Studio's negative tracking (-0.01 to -0.03em) on display Latin is wrong for Chinese — CJK glyphs are pre-spaced; negative tracking causes glyphs to touch or overlap at display scale.
- **Text-transform**: no uppercase on CJK. Studio's `text-transform: uppercase` on display tokens is a no-op on Han characters, but ensure no parent rule attempts unexpected behavior. The "uppercase" identity of the system drops away in Chinese.
- **Full-width punctuation**: use `,。:;!?` (full-width) not `,.:;!?` (half-width). The full-width forms include their own surrounding whitespace and align to the CJK em-box.
- **No period on display headlines**: Chinese headlines drop the terminal `。` — Studio headlines never carry periods in Latin and the rule extends to CJK.
- **Pangu spacing (盘古之白)**: insert a thin space between CJK and adjacent Latin/numerals. Write `使用 Claude` not `使用Claude`; `2024 年` not `2024年`. Studio's mono metadata frequently sits beside Chinese labels — pangu spacing is essential there.
- **One font per sentence**: don't mix NSC and Noto Sans SC inside a single line. The serif/sans switch should happen at element boundaries.
### Aesthetic Notes for This System
Studio's binary palette (acid yellow on near-black, near-black on acid yellow) is perfectly preserved in CJK — no color decisions change. NSC 700 in `{colors.acid-yellow}` against the `{colors.near-black}` field at 12vw display size carries the same visual punch as Barlow 900 in the same role; the saturated yellow against the warm dark surface makes Chinese characters read with the same poster-like authority.
The "type-as-graphic-mass" effect is genuinely altered in CJK, but in an interesting way: where Barlow 900 uppercase blocks read as Western signage / industrial manifesto, NSC 700 at display scale reads as **Chinese woodblock or letterpress poster** — equally severe, equally graphic, but in a different cultural register. For Chinese-language audiences this reads as authoritative and well-designed; for mixed audiences it shifts the perceived tone slightly toward "editorial publication" and away from "design agency."
The em-dash bullet markers translate directly — keep `—` in the surface accent color. The three-column mono cover-meta lockup also translates without modification — write the studio × client / presentation title / studio name in either Chinese or Latin and the IBM Plex Mono renders both cleanly (with CJK falling back to Noto Sans Mono CJK SC if Chinese appears in the lockup).
Stat cards work well in CJK — the 5.5vw italic-style stat numeral can render in NSC 700 if the value is a Chinese numeral (`三百万`) or stay in Barlow if Arabic (`3M`). The 2px top rule and the stat-note (mono) are unaffected.
### Known CJK Gap
- The "uppercase + negative tracking + weight 900" formula that defines the system cannot be reproduced in CJK. Chinese gets weight 700 (the heaviest NSC weight), no case transformation, and zero tracking. The system loses ~30% of its Latin character in pure-Chinese mode.
- IBM Plex Mono is Latin-only at its full feature set. If Chinese characters appear in metadata (rare in Studio decks), they fall back to Noto Sans Mono CJK SC or system monospace, which may have visually different proportions than the Plex Mono around them.
- NSC 900 weight (which would better match Barlow 900) exists on Google Fonts but is heavy enough at large sizes that counter shapes start to close — at 12vw display, NSC 900 may render some characters as near-solid blocks. NSC 700 is the recommended ceiling; for extreme display moments, test NSC 900 case-by-case.
- The system's "alternate dark/yellow surfaces" rhythm is unaffected by CJK, but Chinese readers may parse the rhythm differently than Western readers (cultural reading conventions for color affect pacing perception).
## Iteration Guide
1. Any new headline uses Barlow weight 900 uppercase with negative letter-spacing. Without all three (weight, case, tracking), the type loses its graphic-mass character.
2. Any new slide alternates surface from the previous — generally don't run more than 2–3 dark slides in a row before a yellow break, or vice versa. Rhythm is part of the design.
3. Any new chrome, metadata, label, or counter uses IBM Plex Mono. Mono in any other role breaks the metadata separation.
4. Any new color introduces a third option to the binary palette — don't. Stick to yellow and near-black, with opacity variants for muting.
5. Any new bullet list uses em-dash markers in the surface accent. Dot bullets break the system.
6. Stat cards use the 2px top rule plus a 5.5vw weight 900 numeral. Smaller stats, sentence-case stats, or rounded stat tiles break the pattern.
7. Cover slides use the three-column mono lockup at the bottom. Don't omit it; it is the system's most identifiable pattern.
8. Chapter, statement, quote, and end slides are chromeless. Standard slides carry chrome and foot. Don't blend the two — a chromeless quote is correct; a chromed quote reads as a different system.
9. New layouts should aim for one dominant element (the headline) plus minimal supporting elements. Multi-element layouts (more than 4–5 distinct regions) crowd the design.
10. The 2px rule weight is reserved for anchors (stat-tops, baselines, compare dividers). Chrome and structural separators stay at 1px.
## Known Gaps
- The two font families (Barlow, IBM Plex Mono) load from Google Fonts. If fonts fail, fallbacks are Noto Sans SC / system-ui (for Barlow) and monospace (for IBM Plex Mono); the system degrades significantly without Barlow 900, since the type-as-graphic-mass effect depends on the specific letterforms.
- Chinese fallback (Noto Sans SC) is wired into the Barlow stack but ships with weights 400, 500, 700, 900 only — using h3 (700) and lead (500) in Chinese content renders cleanly; intermediate weights would fall back to closest available.
- The `--c-bg-alt`, `--c-bg-light-alt`, and several muted color tokens are defined but used sparingly — they exist as a reserve for adjacent-surface differentiation.
- The slide navigation JS is embedded inline; the system depends on it for the slide deck transform behavior and the `is-active` class management.
- The cover image placeholder uses a hardcoded `IMAGE PLACEHOLDER` label and a flat near-black-alt fill; real image insertion requires replacing the placeholder div with a background-image-styled element matching the parent canvas.
- The 5vw / 5vh padding is intentionally tight, which means at very small viewports headlines may approach the edge uncomfortably; the system is tuned for 16:9 displays at 1280px and above.
- The compare panel uses a 2px right border on the left panel only (no left border on the right), creating an asymmetry between the two panels — this is intentional but worth noting if extending the compare layout to 3-up.
# Studio Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/studio/design.md`
- Preview card: `bold-template-pack/templates/studio/preview.md`
## Selection Metadata
- Slug: `studio`
- Tagline: Black canvas with electric-yellow type; high-voltage design studio aesthetic.
- Mood: electric, bold, graphic, design-led, high-contrast
- Tone: graphic, loud, modern, intentional
- Formality: medium
- Density: medium
- Scheme: dark
- Best for: Anything that should feel electric and design-led: studio credentials, creative agency pitches, brand showcases, art-direction reviews, fashion / sneaker brand work. Also a striking unexpected choice for tech, research, or business decks where the speaker wants the deck to *be* a brand statement.
- Avoid for: Contexts that should feel quiet or institutional — the black-and-electric-yellow palette is the loudest in the library.
## Visual Snapshot
A "Boring Studios" agency presentation system — type-as-graphic-mass in the spirit of contemporary design-studio decks (Pentagram, Anti, Order). The entire system runs on Barlow at weight 900 uppercase, with type so heavy at display scale that it stops being type and starts being a shape. The palette is binary plus one: near-black field (#1C1C1C), acid yellow type (#F5D200), and the same yellow as a full slide background. IBM Plex Mono carries every footer metadata, slide counter, and three-column lockup. No drop shadows, no rounded corners, no accent colors — the headline IS the design, and the only chromatic decision per slide is dark-yellow-on-near-black or near-black-on-acid-yellow.
Studio is a type-as-graphic-mass presentation system — the visual register of contemporary design-studio decks (Pentagram, Anti, Order, "Boring Studios" agency aesthetic). The premise is reductive to the point of severity: a single typeface (Barlow), at a single weight (900), in strict uppercase, at scales so large that type stops behaving like type and starts behaving like a graphic shape. The headline IS the design — there are no decorative elements, no accent colors, no ornaments. If you removed every other element from a Studio slide and left only the headline, the slide would still read as Studio.
## Preview Ingredients
- Palette: near-black #1C1C1C; near-black-alt #242422; acid-yellow #F5D200; acid-yellow-alt #F0CC00; border-dark #2E2E2C
- Typography: Barlow; IBM Plex Mono; {typography.body.fontFamily}
- Signature move: Binary palette — {colors.near-black} field with {colors.acid-yellow} type, or {colors.acid-yellow} field with {colors.near-black} type. No third color.
- Signature move: Barlow at weight 900 uppercase for every headline at every scale; Barlow 400/500 for body; IBM Plex Mono only for metadata chrome.
- Signature move: Headlines run massive — cover display at 12vw (~230px at 1920px viewport), statements at 7.5vw, section headers at 4.8vw.
- Signature move: Tight negative letter-spacing on all display type (-0.01 to -0.03em); uppercase non-negotiable.
- Signature move: Flat: no drop shadows, no rounded corners, no gradients, no accent colors beyond the yellow/dark binary.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
---
version: alpha
name: Vellum
description: An essay-pinned-to-a-wall presentation system — a single monochromatic field of deep periwinkle (#2A3870) with warm chartreuse-yellow type (#E8D85C) floating centered on it, every slide. Italic Cormorant Garamond carries every headline at all sizes — the italic serif is the personality, against the bold colorfield. DM Sans handles body in a quiet supporting role. Courier Prime mono provides the typed annotation voice — appearing as a "pin-note" attribution sitting in the bottom-left corner of every slide. The mood is gallery exhibition wall meets archive folder — quiet, monochromatic, deeply still. One color, two warm typefaces, zero motion.
colors:
navy: "#2A3870"
navy-alt: "#343F80"
navy-deep: "#1F2858"
navy-mid: "#34407A"
yellow: "#E8D85C"
yellow-2: "rgba(232,216,92,0.62)"
yellow-3: "rgba(232,216,92,0.32)"
emphasis-yellow: "#F5E168"
teal: "#3A7878"
border: "rgba(232,216,92,0.20)"
color-aliases:
c-bg: navy
c-bg-alt: navy-alt
c-bg-light: navy
c-fg: yellow
c-fg-2: yellow-2
c-fg-3: yellow-3
c-fg-light: yellow
c-emphasis: emphasis-yellow
c-accent: teal
c-border: border
typography:
display:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 11vw
fontWeight: 400
fontStyle: italic
lineHeight: 0.92
letterSpacing: -0.01em
h1:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 7vw
fontWeight: 400
fontStyle: italic
lineHeight: 0.95
letterSpacing: -0.01em
h2:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 4vw
fontWeight: 400
fontStyle: italic
lineHeight: 1.05
h3:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 2.4vw
fontWeight: 500
fontStyle: italic
lineHeight: 1.15
quote-text:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 3.2vw
fontWeight: 400
fontStyle: italic
lineHeight: 1.25
quote-mark:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 7vw
fontWeight: 400
fontStyle: italic
lineHeight: 0.6
color: "{colors.teal}"
stat-value:
fontFamily: "Cormorant Garamond, Noto Serif SC, Georgia, serif"
fontSize: 5.5vw
fontWeight: 400
fontStyle: italic
lineHeight: 1
letterSpacing: -0.02em
lead:
fontFamily: "DM Sans, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.5vw
fontWeight: 400
lineHeight: 1.6
body:
fontFamily: "DM Sans, Noto Sans SC, system-ui, sans-serif"
fontSize: 1.05vw
fontWeight: 400
lineHeight: 1.65
caption:
fontFamily: "DM Sans, Noto Sans SC, system-ui, sans-serif"
fontSize: 0.85vw
fontWeight: 400
lineHeight: 1.5
label:
fontFamily: "Courier Prime, Courier New, monospace"
fontSize: 0.72vw
fontWeight: 400
letterSpacing: 0.06em
pin-note:
fontFamily: "Courier Prime, Courier New, monospace"
fontSize: 1.15vw
fontWeight: 500
lineHeight: 1.5
color: "{colors.teal}"
letterSpacing: 0.01em
bar-val:
fontFamily: "Courier Prime, Courier New, monospace"
fontSize: 1.1vw
fontWeight: 400
lineHeight: 1
spacing:
pad-x: 6vw
pad-y: 6vh
gap-lg: 5vh
gap-md: 3vh
gap-sm: 1.5vh
canvas:
width: 100vw
height: 100vh
components:
pin-annotation:
position: "absolute bottom-left, padding ~0.9 * pad-y from bottom and 1 * pad-x from left"
typography: "{typography.pin-note}"
color: "{colors.teal}"
maxWidth: "22vw"
description: "The system's signature element — a small stack of Courier Prime mono lines in dusty teal, sitting in the bottom-left of every slide. Holds slide counter (e.g., '03 / 09'), a short pinned label, and an optional second pin note. Functions as the 'tag stuck to the wall.'"
kicker:
typography: "{typography.label}"
color: "{colors.teal}"
description: "Small Courier Prime mono label in dusty teal, sits above a headline as a section marker."
rule:
width: 28px
height: 1px
background: "{colors.teal}"
description: "A 28px hairline accent rule in dusty teal, used as a small kicker separator."
chrome-bar:
borderBottom: "1px solid {colors.border}"
paddingBottom: "{spacing.gap-sm}"
marginBottom: "{spacing.gap-md}"
description: "Top chrome bar — mono label left, mono counter right, low-opacity hairline rule beneath."
foot-bar:
borderTop: "1px solid {colors.border}"
paddingTop: "{spacing.gap-sm}"
marginTop: "{spacing.gap-md}"
description: "Bottom chrome bar — mirror of chrome-bar."
bullet-list-numbered:
listStyle: "none"
counter: "list-counter"
markerFontFamily: "{typography.label.fontFamily}"
markerColor: "{colors.teal}"
markerSize: "{typography.label.fontSize}"
description: "Numbered list using CSS counters — the counter renders in Courier Prime mono at label size in dusty teal, with a 2em column for the number and 0.5em gap to the body."
pin-stat:
borderRight: "1px solid {colors.border}"
padding: "{spacing.gap-md}"
description: "Vertically-arranged centered stat (italic serif numeral above mono label), separated from neighbors by a single 1px low-opacity hairline. Last stat in row drops the border."
pin-stat-val:
typography: "{typography.stat-value}"
color: "{colors.yellow}"
description: "Large italic serif stat numeral (5.5vw italic Cormorant Garamond), centered in a pin-stat tile."
pin-stat-label:
typography: "{typography.caption}"
fontFamily: "{typography.label.fontFamily}"
color: "{colors.yellow-2}"
description: "Small mono caption beneath a pin-stat numeral."
compare-panel-dark:
background: "{colors.navy-deep}"
description: "Left compare panel — a slightly deeper navy to create internal contrast against the standard navy field."
compare-panel-light:
background: "{colors.navy-mid}"
borderLeft: "1px solid {colors.border}"
description: "Right compare panel — a slightly lighter navy with a hairline left-border, creating the two-shade panel pair."
bar-fill-default:
background: "{colors.yellow-3}"
description: "Default chart bar fill — yellow at 32% opacity (the tier-3 muted color)."
bar-fill-accent:
background: "{colors.yellow}"
description: "Highlighted chart bar — full yellow."
chart-baseline:
height: 1px
background: "{colors.border}"
description: "1px hairline baseline beneath chart bars."
img-placeholder:
background: "rgba(42,56,112,0.12)"
border: "1px dashed {colors.border}"
description: "Image slot — translucent navy fill with a dashed yellow-low-opacity border, centered mono label inside."
quote-mark:
typography: "{typography.quote-mark}"
color: "{colors.teal}"
description: "A 7vw italic Cormorant Garamond opening quote glyph in dusty teal, sitting centered above a centered pull-quote. The teal color is the system's only large-graphic accent."
---
## 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
Vellum is a **monochromatic essay-on-a-wall** presentation system. The visual premise is severe and tender at once: every slide is the same deep periwinkle navy field (`{colors.navy}` — #2A3870), with warm chartreuse-yellow type (`{colors.yellow}` — #E8D85C) floating centered on it. There is no alternate surface. There is no light/dark theme. There is no second background color. The field is the constant; the type and a single small annotation in the bottom-left corner are everything else.
The typographic premise is **italic serif as personality**. Cormorant Garamond runs every headline at every scale — display through h3, quote-text, stat-value — in italic at weight 400. The italic serif at large scale against the bold periwinkle field reads as gallery wall text: personal, considered, slightly intimate. DM Sans steps in for body and lead paragraphs in a quiet supporting role; the body is meant to recede so the italic serif headlines lead the eye. Courier Prime monospace plays the most distinctive role: it carries the "pin-note" — a small stack of typed-attribution lines that sits in the bottom-left corner of every slide. The pin-note in dusty teal looks like a typewriter label pinned to the wall beside the framed essay; it's the system's signature.
The color philosophy is **one field, two accents**. The field is `{colors.navy}`. Type is `{colors.yellow}` at full opacity for primary, 62% for secondary, 32% for tertiary. The first accent is `{colors.emphasis-yellow}` (#F5E168) — a brighter yellow used only for `<em>` emphasis inside italic headlines and for small accent text. The second accent is `{colors.teal}` (#3A7878) — a dusty desaturated teal used only for: the large quote-mark glyph, the pin-note text, kickers, the 28px accent rule, and list counter markers. The teal is the only non-yellow visible color in the system, and it appears in carefully limited contexts.
Depth is **flat and centered**. There are no drop shadows. No rounded corners. No gradients. Borders are 1px hairlines at 20% yellow opacity — barely visible, present mostly as faint structural marks rather than dividers. The compare layout is the single exception: it uses two slightly-different navy shades (`{colors.navy-deep}` and `{colors.navy-mid}`) to create a visible split panel, but even there, the difference is subtle. Animation is set to zero duration — slides do not transition. The system is, by design, completely still.
**Density philosophy: sparse and centered.** Vellum slides are pinned essays — each slide holds a small amount of content, centered in the canvas with significant breathing room above, below, and to the sides. A statement slide is one short headline centered on the field. A cover is a kicker, a display title, a lead sentence, and the pin-note in the corner — that's it. A list slide is four numbered rules in a 60% width column at center. The system reads as broken when crowded; the empty navy field around the content is structural, not negative space. It's wall.
**Key Characteristics:**
- Single monochromatic field — `{colors.navy}` (deep periwinkle) — on every slide. No light theme, no inversion.
- Italic Cormorant Garamond at weight 400 for every headline, every numeral, every featured serif moment.
- DM Sans for body and lead paragraphs; Courier Prime mono for chrome labels and the pin-note signature.
- Yellow type (`{colors.yellow}`) is the primary; brighter `{colors.emphasis-yellow}` is the only `<em>` color inside headlines.
- Dusty teal (`{colors.teal}`) is the second accent — used only for the large quote-mark glyph, the pin-note text, kickers, the 28px rule, and list counter markers.
- The pin-annotation (Courier Prime mono lines in dusty teal in the bottom-left corner of every slide) is the system's signature element.
- Content is centered on every slide — text-align center on most layouts, with content occupying 55–80% of canvas width.
- Hairline 1px borders at 20% yellow opacity for chrome separators; otherwise no borders, no shadows, no elevation.
- Zero motion — slide transitions and entrance animations are set to 0 duration. The system is meant to be still.
- Italic is structural, not decorative: serif italic at display scale is the system's identity, never the upright roman.
## Colors
### Palette
- **Navy** (`{colors.navy}` — #2A3870): Deep periwinkle field. The single surface across every slide. Slightly warmer than midnight, slightly cooler than ultramarine — sits in a contemplative blue register.
- **Navy Alt** (`{colors.navy-alt}` — #343F80): A slightly lifted navy for adjacent-surface differentiation. Rarely used in practice.
- **Navy Deep** (`{colors.navy-deep}` — #1F2858): The darker compare-panel shade. Used only on the left side of compare layouts to create internal panel contrast.
- **Navy Mid** (`{colors.navy-mid}` — #34407A): The lighter compare-panel shade. Used only on the right side of compare layouts.
- **Yellow** (`{colors.yellow}` — #E8D85C): The warm chartreuse-yellow primary text color. Warm, slightly green-biased — reads as aged vellum or chartreuse silk against the navy field.
- **Yellow 2** (`{colors.yellow-2}` — rgba(232,216,92,0.62)): Secondary text — yellow at 62% opacity. Used for lead paragraphs and descriptions.
- **Yellow 3** (`{colors.yellow-3}` — rgba(232,216,92,0.32)): Tertiary text — yellow at 32%. Used for muted captions, chart axis labels, default chart bars.
- **Emphasis Yellow** (`{colors.emphasis-yellow}` — #F5E168): Brighter yellow. Used only for `<em>` emphasis inside italic headlines (the `<em>` renders as roman non-italic in this brighter shade — see Signature Treatments) and for small accent text labels.
- **Teal** (`{colors.teal}` — #3A7878): Dusty desaturated teal. The system's second accent. Used only for: the large quote-mark glyph, the pin-note text, kicker labels, the 28px accent rule, list counter markers, and the bullet-list marker. The teal is the system's color signature beyond the yellow/navy binary.
- **Border** (`{colors.border}` — rgba(232,216,92,0.20)): Hairline border color — yellow at 20% opacity. Used on chrome bars, stat dividers, image placeholders.
### Defaults
- **Default surface**: `{colors.navy}` — every slide.
- **Default primary text color**: `{colors.yellow}`.
- **Default secondary text color**: `{colors.yellow-2}` (yellow at 62% opacity).
- **Default tertiary text color**: `{colors.yellow-3}` (yellow at 32%).
- **Default emphasis color (inside headlines)**: `{colors.emphasis-yellow}` — applied to `<em>` tags inside `display`, `h1`, `h2` (the emphasis renders roman non-italic in this brighter yellow, providing the system's `<em>` mechanism).
- **Default kicker / pin-note / accent rule color**: `{colors.teal}`.
- **Default large-graphic accent color**: `{colors.teal}` — used for the quote-mark glyph specifically.
- **Default border**: `{colors.border}` — yellow at 20% opacity. Hairline only.
There is no semantic mapping between colors. Teal is not "warning," yellow is not "highlight." Yellow is just the type; teal is the annotation voice; emphasis-yellow is just the emphasis flag. The palette is small enough that semantic roles aren't necessary.
## Typography
### Font Family
Vellum runs **three families** in carefully separated roles:
- **Cormorant Garamond** (`{typography.display.fontFamily}`) — an old-style serif with a beautifully expressive italic axis. Carries every headline (display through h3), every numeral (stat-value), every featured serif moment, the quote-text, and the quote-mark glyph. The headline tokens specify `fontStyle: italic` — italic is the default presentation, not an emphasis variant. Weight is 400 (regular) on display/h1/h2/quote-text; weight 500 on h3. Italic Cormorant Garamond at display scale against the periwinkle field is the system's defining visual moment.
- **DM Sans** (`{typography.body.fontFamily}`) — a clean humanist grotesque. Carries body, lead paragraphs, and bullet body text. DM Sans recedes behind the personality type — it's the substance, not the voice.
- **Courier Prime** (`{typography.label.fontFamily}`) — a typewriter-style monospace. Carries every chrome label, every slide counter, the pin-note in the bottom-left corner of every slide, list counter markers, and stat labels. Mono is the "typed-note voice" — it gives the system its archival/exhibition register.
The emotional split: italic serif for the personal essay voice (headlines, quotes); sans for the supporting substance (body); mono for the typed annotation (pin-notes, chrome). The mix of italic-serif + typed-mono is unusual and is the system's most distinctive typographic combination.
### Type Scale
| Token | Size | Family | Weight | Style | Use |
|---|---|---|---|---|---|
| `{typography.display}` | 11vw | Cormorant Garamond | 400 | italic | Cover hero at maximum scale |
| `{typography.h1}` | 7vw | Cormorant Garamond | 400 | italic | Chapter or statement headline |
| `{typography.quote-mark}` | 7vw | Cormorant Garamond | 400 | italic | Decorative opening quote glyph (in teal) |
| `{typography.stat-value}` | 5.5vw | Cormorant Garamond | 400 | italic | Large italic serif stat numeral |
| `{typography.h2}` | 4vw | Cormorant Garamond | 400 | italic | Primary slide headline |
| `{typography.quote-text}` | 3.2vw | Cormorant Garamond | 400 | italic | Pull-quote body |
| `{typography.h3}` | 2.4vw | Cormorant Garamond | 500 | italic | Sub-headline, compare panel title |
| `{typography.lead}` | 1.5vw | DM Sans | 400 | upright | Lead paragraph, intro sentence |
| `{typography.pin-note}` | 1.15vw | Courier Prime | 500 | upright | Pin-annotation text (in teal), bar-val accent |
| `{typography.bar-val}` | 1.1vw | Courier Prime | 400 | upright | Chart bar value label |
| `{typography.body}` | 1.05vw | DM Sans | 400 | upright | Default body paragraph |
| `{typography.caption}` | 0.85vw | DM Sans | 400 | upright | Caption, secondary text |
| `{typography.label}` | 0.72vw | Courier Prime | 400 | upright | Chrome label, slide counter, kicker, stat-label |
### Defaults
- **Default size for a primary section headline**: `{typography.h2}` (4vw).
- **Default size for a chapter or statement headline**: `{typography.h1}` (7vw).
- **Default size for a cover hero**: `{typography.display}` (11vw).
- **Default size for body paragraph**: `{typography.body}` (1.05vw).
- **Default size for a lead sentence**: `{typography.lead}` (1.5vw).
- **Default size for any chrome label, kicker, or mono metadata**: `{typography.label}` (0.72vw).
- **Default size for the pin-note**: `{typography.pin-note}` (1.15vw).
- **Default size for a statistical numeral**: `{typography.stat-value}` (5.5vw italic).
- **Default headline weight**: 400 italic.
- **Default headline color**: `{colors.yellow}`.
When unsure between sizes, lean larger. Vellum is sparse — the headline often is the slide, so it should be sized to anchor the empty field around it.
### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:
- **Every headline is italic Cormorant Garamond at weight 400** (h3 is the exception at weight 500, still italic). Roman (non-italic) serif at display scale does not exist in this system except as `<em>` emphasis.
- **An `<em>` tag inside an italic headline (`display`, `h1`, `h2`) renders as upright roman Cormorant Garamond at weight 600 in `{colors.emphasis-yellow}`.** This is the system's emphasis mechanism — the inversion of italic to roman, plus the color shift, is non-negotiable. It is opposite the conventional "italic for emphasis" pattern; here, italic is the default and roman is the emphasis.
- **Every slide carries a pin-annotation in the bottom-left corner.** The pin-annotation is a stack of Courier Prime mono lines in `{colors.teal}` — typically a slide counter (e.g., "03 / 09") plus 1–2 short pin notes (label, attribution, or phrase). The pin-annotation is positioned absolute at `bottom: ~0.9 * pad-y`, `left: pad-x`, with max-width 22vw. A slide without a pin-annotation reads as a different system.
- **The pin-note typography uses Courier Prime at weight 500 in `{colors.teal}`** with letter-spacing 0.01em. Substituting any other face or color breaks the annotation register.
- **Kickers use Courier Prime mono at label size in `{colors.teal}`.** Sans kickers, italic kickers, or yellow kickers break the kicker convention.
- **The large quote-mark glyph (7vw italic Cormorant Garamond) renders in `{colors.teal}`, not yellow.** The teal quote mark is the only place a large-scale graphic is colored teal; everywhere else teal appears in small text (label-size).
- **Bullet-lists use a numbered counter rendered in Courier Prime mono at label size in `{colors.teal}`** — never bullet dots, never em-dashes. The numbered convention is the system's list signature.
- **Content is centered** on every layout (text-align: center, items aligned center on flex columns). Left-aligned headlines break the gallery-wall pinned-essay register.
### Typography Principles
The face ladder is fixed: italic serif (Cormorant Garamond italic) for headlines, numerals, quotes, and any personality moment; sans (DM Sans) for body and lead; mono (Courier Prime) for chrome, pin-notes, kickers, and list counters. Crossing the rails (e.g., using italic serif for body, or sans for headlines) breaks the gallery-wall register.
Italic is structural, not emphatic. Headlines default to italic; emphasis is achieved by switching to roman at weight 600 in `{colors.emphasis-yellow}`. This inverted pattern is the system's most distinctive typographic move.
Line-height runs tight at display scale (0.92 on display, 0.95 on h1) and opens to 1.5–1.65 on body. Letter-spacing on display is slightly negative (–0.01em); body and label are nearly neutral. Mono labels carry 0.06em tracking; pin-notes carry 0.01em (tighter than chrome labels).
Bold within body is not used. Underline is not used. Emphasis inside body text is achieved by the same roman-in-emphasis-yellow pattern as inside headlines — switch font-style from italic to upright at a heavier weight in the brighter yellow.
## Layout
### Canvas System
Vellum targets `100vw × 100vh` — full viewport. Each `.slide` flexes to fill the viewport exactly, and slides sit side-by-side in a horizontal strip. All sizes use viewport-relative units (`vw`, `vh`) so layout scales fluidly.
### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-x}` | 6vw | Horizontal slide padding |
| `{spacing.pad-y}` | 6vh | Vertical slide padding |
| `{spacing.gap-lg}` | 5vh | Between major content sections |
| `{spacing.gap-md}` | 3vh | Between related elements |
| `{spacing.gap-sm}` | 1.5vh | Between tightly coupled elements |
Quote slides use 1.2× pad-y and 1.4× pad-x to give the centered quote extra breathing room. Compare layouts override slide padding to 0 because each panel carries its own internal padding.
### Chrome Frame
Standard slides carry chrome and foot bars (1px hairlines at 20% yellow opacity with mono labels). Chromeless layouts include cover, statement, quote, end, and any slide where the content is meant to float without structural framing — most of the deck.
The system's universal chrome element is the **pin-annotation in the bottom-left corner**, present on every slide regardless of whether the slide carries chrome/foot bars. The pin-annotation is the system's persistent identification mark.
### Content Centering
Every slide layout centers its content. Cover, statement, quote, end use `align-items: center; justify-content: center` with `text-align: center`. List, stats, chart use a centered body container at 60–80% width. Compare splits into two equal panels with each panel's content vertically centered.
Content rarely fills more than 70% of the canvas width or 60% of the canvas height. The remaining navy field is the pinned-wall context.
## Depth and Elevation
Vellum is **completely flat**. There are no drop shadows. No rounded corners. No gradients. No elevation system whatsoever.
What looks like differentiation comes from:
- **Color shifts within the navy family** — `{colors.navy-deep}` and `{colors.navy-mid}` on compare panels create a subtle two-shade pairing.
- **Hairline borders at 20% yellow opacity** — visible but quiet structural marks.
- **Opacity tiers in yellow** — the three opacity tiers (full, 62%, 32%) provide enough text-color contrast to create hierarchy without introducing additional colors.
The system is intentionally still. There is no motion (slide and entrance animation durations are set to 0). There is no shadow elevation. Slides are meant to be read like pages in a folio — one at a time, with no transition.
## Shapes and Treatment
### Border Radius
| Value | Use |
|---|---|
| 0 | Everything except navigation dots |
| 50% (circle) | Nav dots (deck-stage chrome only, not slide content) |
Vellum has **no rounded chrome**. Cards, panels, stat tiles, image placeholders, compare panels — all strict rectangles. The only round shapes are the deck navigation dots, which are part of the deck-stage UI rather than slide content.
### Border Weights
- **1px solid** in `{colors.border}` (yellow at 20% opacity) — the universal hairline. Used on chrome bars, foot bars, stat dividers, chart baselines, compare-panel left edges.
- **1px dashed** in `{colors.border}` — used on the image placeholder frame (the dashed border marks "this is a slot").
- **1px solid** at slightly higher opacity (rgba(232,216,92,0.18)) — used on the compare panel left/right divider.
There are no heavier borders in the system. Every line is 1px.
### Decorative Element Types
**Italic display headline** — Cormorant Garamond italic at weight 400, 4–11vw, centered on the slide in `{colors.yellow}`. The headline is the dominant visual element of every content slide.
**Pin-annotation** — a stack of 1–3 Courier Prime mono lines in `{colors.teal}`, positioned absolute at the bottom-left corner of every slide. Lines typically include a slide counter (e.g., "04 / 09"), a short typed label, and an optional second pin phrase. Lines stack with 0.3vh gap, max-width 22vw. This is the system's signature.
**Teal quote-mark glyph** — a 7vw italic Cormorant Garamond `"` in `{colors.teal}`, centered above a centered pull-quote. The only large-scale teal element in the system.
**Kicker** — Courier Prime mono at label size (0.72vw) in `{colors.teal}`, with 0.1em letter-spacing. Sits above a headline.
**28px accent rule** — a 28px × 1px horizontal bar in `{colors.teal}`. Used as a small kicker separator or chapter accent.
**Numbered list** — uses CSS `counter-reset: list-counter; counter-increment: list-counter` to render numbers in Courier Prime mono at label size in `{colors.teal}`, with a 2em column for the number and 0.5em gap to the body text (DM Sans lead).
**Pin-stat** — a centered column containing an italic serif stat numeral (5.5vw) above a mono caption in muted yellow. In a row, pin-stats are separated by single 1px hairlines at 20% yellow opacity; the last stat in row drops the border.
**Compare panel pair** — two side-by-side panels filling the slide. Left panel: `{colors.navy-deep}` background. Right panel: `{colors.navy-mid}` background with a 1px left-border. Each panel contains a small mono compare-label in `{colors.yellow-2}`, an italic h3, an italic lead, and a numbered list.
**Image placeholder** — a 1px-dashed rectangle in `{colors.border}` with a faint navy interior, centered Courier Prime mono label, minimum 28vh height. The dashed border is the "slot" indication.
**Chart bar** — a flat vertical rectangle in `{colors.yellow-3}` (default) or `{colors.yellow}` (accent). Bar values render in Courier Prime mono (`{typography.bar-val}`).
## Do's and Don'ts
### Do
- Fill every slide with `{colors.navy}` — the monochromatic field is the constant. There is no light alternate.
- Render every headline in italic Cormorant Garamond at weight 400, in `{colors.yellow}`. The italic serif at display scale is the system's identity.
- Place a pin-annotation in the bottom-left corner of every slide — Courier Prime mono in `{colors.teal}`, 1.15vw, max-width 22vw. The pin-annotation is the system's persistent signature.
- Use `<em>` inside headlines as upright roman (non-italic) at weight 600 in `{colors.emphasis-yellow}`. This italic-to-roman emphasis pattern is non-negotiable.
- Color kickers, list counter markers, the 28px rule, and the large quote-mark glyph in `{colors.teal}`. Teal is the second accent and appears only in those specific contexts.
- Center content on every slide. Text-align center, items aligned center. Left-aligned headlines break the pinned-essay register.
- Use Courier Prime mono for chrome labels, slide counters, pin-notes, list counter markers, and bar values. Mono is the typed-annotation voice.
- Number bullet lists with Courier Prime mono counters in `{colors.teal}`. Bullet dots and em-dashes do not exist in this system.
- Leave generous empty navy field around every content block. Sparse is the correct register.
- Pad slides with `{spacing.pad-x}` 6vw and `{spacing.pad-y}` 6vh, increasing 1.2–1.4× on quote slides.
### Don't
- Don't introduce a second background color. The navy field is the single surface. Even compare layouts use two near-identical navy shades, not contrasting backgrounds.
- Don't render headlines in upright roman. Italic at display scale is the default; roman appears only as the `<em>` emphasis mechanism.
- Don't add drop shadows, rounded corners, or gradients. The system is severely flat.
- Don't use yellow on the quote-mark glyph or as a kicker color. Those moments are teal; substituting yellow flattens the teal-as-accent role.
- Don't use bullet dots or em-dashes. Lists are numbered with Courier Prime mono counters in teal.
- Don't motion the slides. The deck is intentionally still — slide transitions and entrance animations are both 0 duration.
- Don't omit the pin-annotation. It is on every slide — chromeless or chromed — and removing it breaks the system's signature.
- Don't introduce a third typeface. The three families (Cormorant Garamond italic, DM Sans, Courier Prime) are the entire stack.
- Don't render small text in italic serif. Italic is for display scale only; body and caption stay upright sans.
- Don't crowd slides edge-to-edge. The empty navy field is structural — sparse content centered with breathing room above and below is the register.
## Responsive Behavior
Vellum targets a 1920×1080 viewport and uses viewport-relative units (`vw`, `vh`) throughout, so layout scales fluidly between 1280×720 and 2560×1440. There are no media queries and no fixed-pixel sizes except deck-chrome dots and the pin-annotation positioning offsets (which are pad-relative and scale with the slide padding).
### Scaling Behavior
- Display headline scales: 11vw → ~211px at 1920px viewport, ~141px at 1280px.
- Body text scales: 1.05vw → ~20px at 1920px, ~13px at 1280px.
- Pin-annotation positioning is relative to `pad-y` and `pad-x`, so it scales with slide padding.
### Presenter Behavior
The deck is JS-driven, but slide transitions are zero-duration (the system is intentionally still). Slides sit side-by-side and navigate via the deck-stage's translateX, but the user perceives instant cuts rather than animated transitions. There is no entrance animation system — `[data-anim]` attributes have no associated keyframes because animation durations are 0.
Nav dots and a slide counter sit fixed at the bottom of the viewport.
### Print Behavior
There is no embedded print stylesheet. Static export depends on the deck container being unwound for sequential page rendering.
## CJK & International Content
### Recommended Chinese Pairing
| Role | Latin face (default) | Chinese face | Weight | Notes |
|---|---|---|---|---|
| Display / h1 / h2 / quote-text / stat-value | Cormorant Garamond italic 400 | 霞鹜文楷 LXGW WenKai (LXGW WenKai TC) | 400 | LXGW WenKai's hand-written kaiti warmth mirrors Cormorant's italic personality — the only CJK face on CDN that carries an italic-like personal register. |
| h3 | Cormorant Garamond italic 500 | 霞鹜文楷 LXGW WenKai | 400 | Single-weight kaiti; the visual step from h2 to h3 must come from size, not weight. |
| Quote-mark glyph (7vw, teal) | Cormorant Garamond italic 400 | LXGW WenKai 400 or `「`/`『` in NSC | 400 | For Chinese quotes, replace `"` with `「` (full-width corner bracket) in LXGW WenKai or NSC at the same teal color. |
| Body / lead | DM Sans 400 | 思源宋体 / Noto Serif SC | 400 | The system body switches from sans to serif in CJK to preserve the literary register — DM Sans beside kaiti reads as a textbook in Chinese. |
| Pin-note / kicker / chrome label / list counter | Courier Prime 400–500 | Courier Prime + Noto Sans Mono CJK SC fallback | 400–500 | Pin-notes are usually in Latin; if Chinese appears, fall back to Noto Sans Mono CJK SC. The teal color is preserved. |
### Mixed-Content Strategy
This template uses **Strategy C (literary)**: keep the Latin face for English glyphs and let the CJK fallback in only when a Chinese character appears, via a stacked `font-family`. Cormorant Garamond italic is Vellum's defining brand identity — replacing it with a kaiti for every headline strips the system of its italic-serif-against-periwinkle moment. Letting Latin stay in Cormorant italic while Chinese drops into LXGW WenKai preserves both registers.
```css
font-family: 'Cormorant Garamond', 'LXGW WenKai TC', 'Noto Serif SC', Georgia, serif; /* headlines */
font-family: 'DM Sans', 'Noto Serif SC', system-ui, sans-serif; /* body */
font-family: 'Courier Prime', 'Noto Sans Mono CJK SC', 'Courier New', monospace; /* pin-note / chrome */
```
**Warning — baseline mismatch at display sizes.** Cormorant Garamond italic's optical center sits below LXGW WenKai's optical center, especially at 11vw display and 7vw h1. A phrase like `Vellum 羊皮纸` will show the Chinese characters floating slightly high relative to the italic Latin baseline. Mitigations:
- Add `font-feature-settings: "palt"` on the Chinese segment to tighten metrics.
- Wrap CJK in a `<span lang="zh">` with a `vertical-align: -0.05em` adjustment on display tokens (display, h1, h2, quote-text, stat-value). The italic Latin's slope makes the baseline mismatch more visible than in upright pairings, so the offset may need to be slightly larger than in non-italic systems.
- For pure-CJK headlines (no Latin), the issue disappears entirely.
### Loading
Add to `<head>` (Google Fonts hosts LXGW WenKai TC, Noto Serif SC, and Courier Prime):
```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=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=DM+Sans:wght@400;500&family=Courier+Prime:wght@400;700&family=LXGW+WenKai+TC&family=Noto+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```
LXGW WenKai TC is the Traditional Chinese cut on Google Fonts; it includes the full CJK Unified Ideographs range and renders Simplified Chinese cleanly. Noto Serif SC carries body text in Simplified Chinese with proper hinting. The Cormorant italic axis stays as-is for Latin.
### Universal CJK Adjustments
Apply on any element rendering Chinese content (typically scope via `:lang(zh)` or `<span lang="zh">`):
- **Line-height**: body 1.75–1.85 (Vellum's 1.65 DM Sans-default is close, but bump for CJK strokes); display 1.15–1.25 (looser than Latin 0.92–1.05 because CJK glyphs at 7–11vw need vertical breathing).
- **Letter-spacing**: 0 on CJK. Vellum's negative tracking (-0.01 to -0.02em) on display Latin is wrong for Chinese — CJK glyphs are pre-spaced; negative tracking causes overlap.
- **Text-transform**: no uppercase on CJK. Vellum doesn't use uppercase on Latin either (italic serif is sentence case throughout), so this is just confirming no parent rule attempts it.
- **Full-width punctuation**: use `,。:;!?` (full-width) not `,.:;!?` (half-width). For Chinese quotes, replace `"…"` with `「…」` or `『…』` (full-width corner brackets) — these are the conventional Chinese quote glyphs and match the teal quote-mark treatment of the system.
- **No period on display headlines**: Chinese headlines drop the terminal `。` — the headline's visual closure is enough.
- **Pangu spacing (盘古之白)**: insert a thin space between CJK and adjacent Latin/numerals. Write `使用 Claude` not `使用Claude`; `2024 年` not `2024年`. This is editorial convention in good Chinese typography and matches Vellum's careful gallery-wall register.
- **One font per sentence**: don't mix LXGW WenKai and Noto Serif SC inside a single line. Use one or the other for the entire run; switching mid-sentence creates a metric jolt that's especially visible in this sparse, centered layout.
### Aesthetic Notes for This System
LXGW WenKai is an excellent match for Vellum's gallery-essay register. The kaiti's hand-written warmth is closely related to Cormorant Garamond italic's intimate personal voice — both faces read as personal, considered, slightly intimate. Against the deep periwinkle field in warm chartreuse-yellow, LXGW WenKai at 7–11vw display reads as **handwritten chartreuse on a gallery wall** — arguably more poetic in Chinese than the original Cormorant treatment in English. The kaiti's stroke modulation pairs naturally with the yellow's warmth.
The `<em>` emphasis mechanism (italic → upright roman in `{colors.emphasis-yellow}` at weight 600) does not translate to CJK because LXGW WenKai has no separate italic/roman pair. The CJK equivalent for emphasis is to switch to **NSC 700 in `{colors.emphasis-yellow}`** — a heavier weight + brighter color creates the same "this is the moment" signal. Keep the upright-not-italic inversion logic by ensuring the emphasis weight differs visibly from the kaiti regular.
The pin-annotation (Courier Prime mono in teal, bottom-left corner) is the system's signature and works without modification in mixed-script decks. For pure-Chinese pin-notes, fall back to Noto Sans Mono CJK SC — the typewriter texture is partially preserved (mono spacing) but the typewriter character is lost. Consider keeping pin-notes in Latin (dates, slide counters, studio names) even on Chinese decks; this is conventional in Chinese gallery exhibition design and feels deliberate rather than incomplete.
The numbered-list convention (Courier Prime counters in teal) translates directly — use `01.` `02.` `03.` numerals from Courier Prime rather than Chinese numerals (`一、` `二、`) to preserve the typed-annotation register. The teal color and 2em column width are unchanged.
### Known CJK Gap
- LXGW WenKai has only a single weight (regular). The system's h3 (weight 500 italic) cannot step up in weight in CJK — the visual hierarchy step must come from size alone (h2 4vw → h3 2.4vw). For decks that need stronger sub-headline emphasis, consider NSC 500 as an h3 alternate.
- LXGW WenKai has no italic axis. Vellum's defining italic-as-default convention is impossible to reproduce in CJK — the upright kaiti is the closest analogue, which sacrifices the system's italic register for an alternate "handwritten warmth" register. This is the largest aesthetic loss in CJK adaptation.
- The italic-to-roman `<em>` emphasis mechanism does not exist in CJK. Substitute with NSC 700 in `{colors.emphasis-yellow}` for the equivalent "emphasis flag" effect.
- LXGW WenKai TC's Traditional-cut glyphs may render a small number of characters with Traditional forms (e.g., 設 instead of 设). For pure Simplified Chinese decks, prefer `font-family: 'Noto Serif SC'` as the primary CJK face and reserve LXGW WenKai for accent moments (cover title, chapter titles).
- The teal quote-mark glyph (`"` at 7vw in `{colors.teal}`) does not exist in CJK conventions. Use `「` or `『` (full-width corner bracket) at the same 7vw size in teal — this is the correct Chinese equivalent and preserves the system's "teal quote moment" signal.
- Baseline mismatch at display sizes (see Mixed-Content Strategy) is more pronounced in italic-Latin + upright-CJK pairings than in upright-upright pairings. Per-deck tuning is required for mixed-script covers.
## Iteration Guide
1. Any new headline uses italic Cormorant Garamond at weight 400 in `{colors.yellow}`. Italic is the default, not the emphasis.
2. Any emphasized phrase inside a headline switches to upright roman at weight 600 in `{colors.emphasis-yellow}`. The italic-to-roman inversion is the system's `<em>` mechanism.
3. Every new slide must include a pin-annotation in the bottom-left corner. The pin-annotation contains 1–3 lines of Courier Prime mono in `{colors.teal}`: typically a slide counter plus one or two short typed phrases.
4. Any new kicker, list counter marker, or 28px accent rule uses `{colors.teal}`. Teal is the second accent and is reserved for these specific elements.
5. Any new list is numbered with Courier Prime mono counters in teal. Dot and dash bullets do not exist in this system.
6. Any new layout centers its content. Text-align center, items aligned center. Left-aligned layouts break the gallery register.
7. Any new background introduces a system break — there is only one surface color, `{colors.navy}`. Compare layouts use slight navy variants but do not introduce a different hue.
8. Any new font is forbidden. Cormorant Garamond, DM Sans, Courier Prime are the entire stack.
9. Any new chart, table, or data display uses 1px hairlines at 20% yellow opacity. No heavier borders, no shadows, no rounded chrome.
10. Content density should be low and centered. If a slide feels crowded, remove content rather than adjusting padding or shrinking text.
## Known Gaps
- The three font families (Cormorant Garamond, DM Sans, Courier Prime) load from Google Fonts. If fonts fail, fallbacks are Georgia (for the italic serif), system-ui (for sans), and Courier New (for mono). The system loses much of its character without Cormorant italic — Georgia italic substitutes acceptably but with different proportions.
- Chinese fallbacks (Noto Serif SC, Noto Sans SC) are wired into the stacks but Noto Serif SC has no true italic — Chinese italic headlines will fall back to upright Noto Serif SC, losing the system's defining italic moment.
- The `.light` class is preserved for backwards compatibility but renders identically to `.dark` (both use the navy field). The `.light` token aliases (`--c-bg-light`, `--c-fg-light`) are pointed at the dark tokens.
- Animation durations are set to 0 — the system is intentionally still. The animation keyframes and `[data-anim]` infrastructure exist in the engine but are no-ops in Vellum. Re-enabling motion would require changing `--dur-slide` and `--dur-enter` in the token block.
- The pin-annotation positioning uses `bottom: calc(var(--pad-y) * 0.9)` which is just slightly inside the pad-y boundary; at very small viewports the pin-note may approach the slide edge.
- The compare panel uses two near-identical navy shades (`{colors.navy-deep}` and `{colors.navy-mid}`) — at low-contrast displays or in heavy ambient light, the panel split may be hard to perceive.
- The teal accent color (`{colors.teal}` — #3A7878) is desaturated and may read as a muted blue rather than a teal on some displays.
- The system has no light theme, no inversion, and no alternate surface. Decks that require a "reset" slide (a different color background to break a long sequence) must either accept the monochromatic limitation or step outside the design system.
# Vellum Preview Card
Use this small file for title-slide previews only. For final deck generation, read the full design doc listed below.
## Files
- Full design doc: `bold-template-pack/templates/vellum/design.md`
- Preview card: `bold-template-pack/templates/vellum/preview.md`
## Selection Metadata
- Slug: `vellum`
- Tagline: Deep navy canvas with warm-yellow Cormorant serifs and a single dusty teal accent. A quiet, scholarly aesthetic.
- Mood: scholarly, literary, considered, quiet, intellectual
- Tone: literary, considered, patient, intelligent
- Formality: high
- Density: low
- Scheme: dark
- Best for: Anything that should feel scholarly, literary, and quietly intelligent: research synthesis, white papers, academic and policy briefs, advisory deliverables, longform editorial pieces, founder reflections. Equally strong for any deck — including tech, business, or creator work — that wants a calm, considered atmosphere instead of energetic visuals.
- Avoid for: Contexts that need visual heat or pop — the navy + warm-yellow Cormorant aesthetic is intentionally low-tempo.
## Visual Snapshot
An essay-pinned-to-a-wall presentation system — a single monochromatic field of deep periwinkle (#2A3870) with warm chartreuse-yellow type (#E8D85C) floating centered on it, every slide. Italic Cormorant Garamond carries every headline at all sizes — the italic serif is the personality, against the bold colorfield. DM Sans handles body in a quiet supporting role. Courier Prime mono provides the typed annotation voice — appearing as a "pin-note" attribution sitting in the bottom-left corner of every slide. The mood is gallery exhibition wall meets archive folder — quiet, monochromatic, deeply still. One color, two warm typefaces, zero motion.
Vellum is a monochromatic essay-on-a-wall presentation system. The visual premise is severe and tender at once: every slide is the same deep periwinkle navy field ({colors.navy} — #2A3870), with warm chartreuse-yellow type ({colors.yellow} — #E8D85C) floating centered on it. There is no alternate surface. There is no light/dark theme. There is no second background color. The field is the constant; the type and a single small annotation in the bottom-left corner are everything else.
## Preview Ingredients
- Palette: navy #2A3870; navy-alt #343F80; navy-deep #1F2858; navy-mid #34407A; yellow #E8D85C; emphasis-yellow #F5E168; teal #3A7878
- Typography: Cormorant Garamond; DM Sans; Courier Prime; {typography.label.fontFamily}
- Signature move: Single monochromatic field — {colors.navy} (deep periwinkle) — on every slide. No light theme, no inversion.
- Signature move: Italic Cormorant Garamond at weight 400 for every headline, every numeral, every featured serif moment.
- Signature move: DM Sans for body and lead paragraphs; Courier Prime mono for chrome labels and the pin-note signature.
- Signature move: Yellow type ({colors.yellow}) is the primary; brighter {colors.emphasis-yellow} is the only <em> color inside headlines.
- Signature move: Dusty teal ({colors.teal}) is the second accent — used only for the large quote-mark glyph, the pin-note text, kickers, the 28px rule, and list counter markers.
## International / CJK Preview Note
- If the preview uses Chinese or other CJK text, keep CJK letter-spacing at 0, loosen line-height, and avoid uppercase transforms on CJK runs.
- Use the full `design.md` CJK section after selection for exact font pairings and script-specific adjustments.
## Preview Rules
- Build exactly one title slide at 1920x1080 inside the fixed-stage model.
- Preserve the palette, type roles, surface rhythm, and decorative vocabulary described above.
- Use the user's real title/subtitle/context; do not copy demo slide content.
- The rendered preview must look like a real first slide, not a template-selection card.
- Never place internal workflow text on the slide: no `preview`, `generated from`, `preview.md`, `template`, `preset`, `style option`, `Option A/B/C`, file names, paths, or source-doc labels.
- Never place the template name or slug on the slide itself; mention it only in the chat message.
- Never place user requirement notes such as desired vibe, audience, or internal-use labels on the slide unless the user explicitly wants those exact words in the deck.
- Use only real deck content for visible chrome: deck title, real section title, date, author, company, page number, or genuine content phrases from the user material.
- Do not read `template.html` for preview generation.
- Do not read other templates' `design.md` files.
- After the user picks this template for the full deck, read the full design doc before generating final slides.
# HTML Presentation Template
Reference architecture for generating slide presentations. Every presentation follows a fixed 16:9 stage model: slides are authored at 1920×1080 and the whole stage scales to fit the browser window.
## Base HTML Structure
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Presentation Title</title>
<!-- Fonts: use Fontshare or Google Fonts — never system fonts -->
<link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=...">
<style>
/* ===========================================
CSS CUSTOM PROPERTIES (THEME)
Change these to change the whole look
=========================================== */
:root {
/* Colors — from chosen style preset */
--bg-primary: #0a0f1c;
--bg-secondary: #111827;
--text-primary: #ffffff;
--text-secondary: #9ca3af;
--accent: #00ffcc;
--accent-glow: rgba(0, 255, 204, 0.3);
/* Typography — authored at 1920×1080 stage size */
--font-display: 'Clash Display', sans-serif;
--font-body: 'Satoshi', sans-serif;
--title-size: 112px;
--subtitle-size: 34px;
--body-size: 28px;
/* Spacing — authored at 1920×1080 stage size */
--slide-padding: 72px;
--content-gap: 32px;
/* Animation */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--duration-normal: 0.6s;
}
/* ===========================================
BASE STYLES
=========================================== */
* { margin: 0; padding: 0; box-sizing: border-box; }
/* --- PASTE viewport-base.css CONTENTS HERE --- */
/* ===========================================
ANIMATIONS
Trigger via .visible class on the active slide
=========================================== */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity var(--duration-normal) var(--ease-out-expo),
transform var(--duration-normal) var(--ease-out-expo);
}
.slide.visible .reveal {
opacity: 1;
transform: translateY(0);
}
/* Stagger children for sequential reveal */
.reveal:nth-child(1) { transition-delay: 0.1s; }
.reveal:nth-child(2) { transition-delay: 0.2s; }
.reveal:nth-child(3) { transition-delay: 0.3s; }
.reveal:nth-child(4) { transition-delay: 0.4s; }
/* ... preset-specific styles ... */
</style>
</head>
<body>
<div class="deck-viewport">
<main class="deck-stage" id="deckStage">
<section class="slide title-slide active">
<h1 class="reveal">Presentation Title</h1>
<p class="reveal">Subtitle or author</p>
</section>
<section class="slide">
<div class="slide-content">
<h2 class="reveal">Slide Title</h2>
<p class="reveal">Content...</p>
</div>
</section>
<!-- More slides... -->
</main>
</div>
<script>
/* ===========================================
SLIDE PRESENTATION CONTROLLER
=========================================== */
class SlidePresentation {
constructor() {
this.slides = document.querySelectorAll('.slide');
this.currentSlide = 0;
this.stage = document.getElementById('deckStage');
this.setupStageScale();
this.setupKeyboardNav();
this.setupTouchNav();
this.showSlide(0);
}
setupStageScale() {
const scale = () => {
const factor = Math.min(window.innerWidth / 1920, window.innerHeight / 1080);
const x = (window.innerWidth - 1920 * factor) / 2;
const y = (window.innerHeight - 1080 * factor) / 2;
this.stage.style.transform = `translate(${x}px, ${y}px) scale(${factor})`;
};
scale();
window.addEventListener('resize', scale);
}
setupKeyboardNav() {
// Arrow keys, Space, Page Up/Down
}
setupTouchNav() {
// Touch/swipe support for mobile
}
showSlide(index) {
this.currentSlide = Math.max(0, Math.min(index, this.slides.length - 1));
this.slides.forEach((slide, i) => {
slide.classList.toggle('active', i === this.currentSlide);
slide.classList.toggle('visible', i === this.currentSlide);
});
}
}
new SlidePresentation();
</script>
</body>
</html>
```
## Required JavaScript Features
Every presentation must include:
1. **SlidePresentation Class** — Main controller with:
- Keyboard navigation (arrows, space, page up/down)
- Touch/swipe support
- Mouse wheel navigation
- Optional progress indicator or page count, kept outside the slide stage
2. **Stage Scaling** — For fixed 16:9 presentation behavior:
- Keep all slides at 1920×1080 inside `.deck-stage`
- Scale the whole stage with one transform
- Letterbox/pillarbox as needed; never reflow slide content per device
3. **Optional Enhancements** (match to chosen style):
- Custom cursor with trail
- Particle system background (canvas)
- Parallax effects
- 3D tilt on hover
- Magnetic buttons
- Counter animations
4. **Inline Editing** (included by default after draft generation):
- Edit toggle button (hidden by default, revealed via hover hotzone or `E` key)
- Auto-save to localStorage
- Export/save file functionality
- See "Inline Editing Implementation" section below
## Inline Editing Implementation
Inline editing is a lightweight post-draft affordance. Do not ask the user whether they want it during the pre-generation Q&A. Include it by default unless the user explicitly asks for a locked/export-only presentation or no editing controls.
**Do NOT use CSS `~` sibling selector for hover-based show/hide.** The CSS-only approach (`edit-hotzone:hover ~ .edit-toggle`) fails because `pointer-events: none` on the toggle button breaks the hover chain: user hovers hotzone -> button becomes visible -> mouse moves toward button -> leaves hotzone -> button disappears before click.
**Required approach: JS-based hover with 400ms delay timeout.**
HTML:
```html
<div class="edit-hotzone"></div>
<button class="edit-toggle" id="editToggle" title="Edit mode (E)">✏️</button>
```
CSS (visibility controlled by JS classes only):
```css
/* Do NOT use CSS ~ sibling selector for this!
pointer-events: none breaks the hover chain.
Must use JS with delay timeout. */
.edit-hotzone {
position: fixed; top: 0; left: 0;
width: 80px; height: 80px;
z-index: 10000;
cursor: pointer;
}
.edit-toggle {
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
z-index: 10001;
}
.edit-toggle.show,
.edit-toggle.active {
opacity: 1;
pointer-events: auto;
}
```
JS (three interaction methods):
```javascript
// 1. Click handler on the toggle button
document.getElementById('editToggle').addEventListener('click', () => {
editor.toggleEditMode();
});
// 2. Hotzone hover with 400ms grace period
const hotzone = document.querySelector('.edit-hotzone');
const editToggle = document.getElementById('editToggle');
let hideTimeout = null;
hotzone.addEventListener('mouseenter', () => {
clearTimeout(hideTimeout);
editToggle.classList.add('show');
});
hotzone.addEventListener('mouseleave', () => {
hideTimeout = setTimeout(() => {
if (!editor.isActive) editToggle.classList.remove('show');
}, 400);
});
editToggle.addEventListener('mouseenter', () => {
clearTimeout(hideTimeout);
});
editToggle.addEventListener('mouseleave', () => {
hideTimeout = setTimeout(() => {
if (!editor.isActive) editToggle.classList.remove('show');
}, 400);
});
// 3. Hotzone direct click
hotzone.addEventListener('click', () => {
editor.toggleEditMode();
});
// 4. Keyboard shortcut (E key, skip when editing text)
document.addEventListener('keydown', (e) => {
if ((e.key === 'e' || e.key === 'E') && !e.target.getAttribute('contenteditable')) {
editor.toggleEditMode();
}
});
```
## Image Pipeline (Skip If No Images)
If user chose "No images" in Phase 1, skip this entirely. If images were provided, process them before generating HTML.
**Dependency:** `pip install Pillow`
### Image Processing
```python
from PIL import Image, ImageDraw
# Circular crop (for logos on modern/clean styles)
def crop_circle(input_path, output_path):
img = Image.open(input_path).convert('RGBA')
w, h = img.size
size = min(w, h)
left, top = (w - size) // 2, (h - size) // 2
img = img.crop((left, top, left + size, top + size))
mask = Image.new('L', (size, size), 0)
ImageDraw.Draw(mask).ellipse([0, 0, size, size], fill=255)
img.putalpha(mask)
img.save(output_path, 'PNG')
# Resize (for oversized images that inflate HTML)
def resize_max(input_path, output_path, max_dim=1200):
img = Image.open(input_path)
img.thumbnail((max_dim, max_dim), Image.LANCZOS)
img.save(output_path, quality=85)
```
| Situation | Operation |
|-----------|-----------|
| Square logo on rounded aesthetic | `crop_circle()` |
| Image > 1MB | `resize_max(max_dim=1200)` |
| Wrong aspect ratio | Manual crop with `img.crop()` |
Save processed images with `_processed` suffix. Never overwrite originals.
### Image Placement
**Use direct file paths** (not base64) — presentations are viewed locally:
```html
<img src="assets/logo_round.png" alt="Logo" class="slide-image logo">
<img src="assets/screenshot.png" alt="Screenshot" class="slide-image screenshot">
```
```css
.slide-image {
max-width: 100%;
max-height: min(50vh, 400px);
object-fit: contain;
border-radius: 8px;
}
.slide-image.screenshot {
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.slide-image.logo {
max-height: min(30vh, 200px);
}
```
**Adapt border/shadow colors to match the chosen style's accent.** Never repeat the same image on multiple slides (except logos on title + closing).
**Placement patterns:** Logo centered on title slide. Screenshots in two-column layouts with text. Full-bleed images as slide backgrounds with text overlay (use sparingly).
---
## Code Quality
**Comments:** Every section needs clear comments explaining what it does and how to modify it.
**Accessibility:**
- Semantic HTML (`<section>`, `<nav>`, `<main>`)
- Keyboard navigation works fully
- ARIA labels where needed
- `prefers-reduced-motion` support (included in viewport-base.css)
## File Structure
Single presentations:
```
presentation.html # Self-contained, all CSS/JS inline
assets/ # Images only, if any
```
Multiple presentations in one project:
```
[name].html
[name]-assets/
```
#!/usr/bin/env bash
# deploy.sh — Deploy a slide deck to Vercel for instant sharing
#
# Usage:
# bash scripts/deploy.sh <path-to-slide-folder-or-html>
#
# Examples:
# bash scripts/deploy.sh ./my-pitch-deck/
# bash scripts/deploy.sh ./presentation.html
#
# What this does:
# 1. Checks if Vercel CLI is installed (installs if not)
# 2. Checks if user is logged in (guides through login if not)
# 3. Deploys the slide deck to a public URL
# 4. Prints the live URL
#
# The deployed URL is permanent and works on any device (mobile, tablet, desktop).
# No server to maintain — Vercel hosts it for free.
set -euo pipefail
# ─── Colors ────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${CYAN}ℹ${NC} $*"; }
ok() { echo -e "${GREEN}✓${NC} $*"; }
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
err() { echo -e "${RED}✗${NC} $*" >&2; }
# ─── Input validation ─────────────────────────────────────
if [[ $# -lt 1 ]]; then
err "Usage: bash scripts/deploy.sh <path-to-slide-folder-or-html>"
err ""
err "Examples:"
err " bash scripts/deploy.sh ./my-pitch-deck/"
err " bash scripts/deploy.sh ./presentation.html"
exit 1
fi
INPUT="$1"
# If input is a single HTML file, create a temp directory with it as index.html
if [[ -f "$INPUT" && "$INPUT" == *.html ]]; then
DEPLOY_DIR=$(mktemp -d)
cp "$INPUT" "$DEPLOY_DIR/index.html"
PARENT_DIR=$(dirname "$INPUT")
# Parse the HTML for local file references (src="...", url('...'), href="...")
# and copy any referenced local files into the deploy directory
grep -oE '(src|href|url\()["'"'"']?[^"'"'"'>)]+' "$INPUT" 2>/dev/null | \
sed "s/^src=//; s/^href=//; s/^url(//; s/[\"']//g" | \
grep -v '^http' | grep -v '^data:' | grep -v '^#' | grep -v '^/' | \
sort -u | while read -r ref; do
# Resolve the reference relative to the HTML file's directory
SOURCE_FILE="$PARENT_DIR/$ref"
if [[ -e "$SOURCE_FILE" ]]; then
# Preserve directory structure for nested paths (e.g., assets/img.png)
TARGET_DIR="$DEPLOY_DIR/$(dirname "$ref")"
mkdir -p "$TARGET_DIR"
cp -r "$SOURCE_FILE" "$TARGET_DIR/"
fi
done
# Also copy any assets/ folder if it exists (common convention)
if [[ -d "$PARENT_DIR/assets" ]]; then
cp -r "$PARENT_DIR/assets" "$DEPLOY_DIR/assets" 2>/dev/null || true
fi
CLEANUP_TEMP=true
info "Single HTML file detected — preparing for deployment..."
elif [[ -d "$INPUT" ]]; then
# Verify the folder has an index.html
if [[ ! -f "$INPUT/index.html" ]]; then
err "Folder '$INPUT' does not contain an index.html file."
err "Make sure your presentation folder has an index.html."
exit 1
fi
DEPLOY_DIR="$INPUT"
CLEANUP_TEMP=false
else
err "'$INPUT' is not a valid HTML file or directory."
exit 1
fi
# ─── Step 1: Check for Vercel CLI ─────────────────────────
echo ""
echo -e "${BOLD}╔══════════════════════════════════════╗${NC}"
echo -e "${BOLD}║ Deploy Slides to Vercel ║${NC}"
echo -e "${BOLD}╚══════════════════════════════════════╝${NC}"
echo ""
if ! command -v npx &>/dev/null; then
err "Node.js is required but not installed."
err ""
err "Install Node.js:"
err " macOS: brew install node"
err " or visit https://nodejs.org and download the installer"
exit 1
fi
info "Checking Vercel CLI..."
# Check if vercel is available (either globally or via npx)
if command -v vercel &>/dev/null; then
VERCEL_CMD="vercel"
ok "Vercel CLI found"
elif npx --yes vercel --version &>/dev/null 2>&1; then
VERCEL_CMD="npx --yes vercel"
ok "Vercel CLI available via npx"
else
info "Installing Vercel CLI..."
npm install -g vercel
VERCEL_CMD="vercel"
ok "Vercel CLI installed"
fi
# ─── Step 2: Check login status ───────────────────────────
echo ""
info "Checking Vercel login status..."
# Try to check if logged in by running whoami
if ! $VERCEL_CMD whoami &>/dev/null 2>&1; then
echo ""
warn "You're not logged in to Vercel yet."
echo ""
echo -e "${BOLD}To log in, run this command and follow the prompts:${NC}"
echo ""
echo " vercel login"
echo ""
echo "If you don't have a Vercel account yet:"
echo " 1. Go to https://vercel.com/signup"
echo " 2. Sign up with GitHub, GitLab, email, or any method"
echo " 3. Come back here and run: vercel login"
echo " 4. Then re-run this deploy script"
echo ""
# Try interactive login
echo -e "${YELLOW}Attempting interactive login now...${NC}"
echo ""
$VERCEL_CMD login || {
err "Login failed. Please run 'vercel login' manually and try again."
[[ "$CLEANUP_TEMP" == "true" ]] && rm -rf "$DEPLOY_DIR"
exit 1
}
echo ""
ok "Logged in to Vercel!"
fi
VERCEL_USER=$($VERCEL_CMD whoami 2>/dev/null || echo "unknown")
ok "Logged in as: $VERCEL_USER"
# ─── Step 3: Deploy ───────────────────────────────────────
echo ""
info "Deploying slides..."
echo ""
# Deploy with sensible defaults:
# --yes: skip confirmation prompts
# --prod: deploy to production URL (not preview)
# --name: use the folder name as the project name
DECK_NAME=$(basename "$DEPLOY_DIR")
# If we used a temp dir, use the original filename without .html
if [[ "$CLEANUP_TEMP" == "true" ]]; then
DECK_NAME=$(basename "$INPUT" .html)
fi
# Sanitize project name for Vercel:
# - lowercase, replace spaces/special chars with hyphens
# - collapse multiple hyphens, trim to 100 chars
DECK_NAME=$(echo "$DECK_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9._-]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-100)
# Vercel uses the directory name as the project name, so rename the deploy
# directory to the sanitized deck name (avoids deprecated --name flag)
if [[ "$CLEANUP_TEMP" == "true" ]]; then
RENAMED_DIR="$(dirname "$DEPLOY_DIR")/$DECK_NAME"
mv "$DEPLOY_DIR" "$RENAMED_DIR"
DEPLOY_DIR="$RENAMED_DIR"
fi
DEPLOY_OUTPUT=$($VERCEL_CMD deploy "$DEPLOY_DIR" --yes --prod 2>&1) || {
err "Deployment failed:"
echo "$DEPLOY_OUTPUT"
[[ "$CLEANUP_TEMP" == "true" ]] && rm -rf "$DEPLOY_DIR"
exit 1
}
# Extract the URL from output
DEPLOY_URL=$(echo "$DEPLOY_OUTPUT" | grep -o 'https://[^ ]*' | tail -1)
# ─── Step 4: Success ──────────────────────────────────────
echo ""
echo -e "${BOLD}════════════════════════════════════════${NC}"
ok "Slides deployed successfully!"
echo ""
echo -e " ${BOLD}Live URL:${NC} $DEPLOY_URL"
echo ""
echo " This URL works on any device — phones, tablets, laptops."
echo " Share it via Slack, email, text, or anywhere."
echo ""
echo -e " ${CYAN}Tip:${NC} To take it down later, visit https://vercel.com/dashboard"
echo -e " and delete the project '${DECK_NAME}'."
echo -e "${BOLD}════════════════════════════════════════${NC}"
echo ""
# ─── Cleanup ──────────────────────────────────────────────
if [[ "$CLEANUP_TEMP" == "true" ]]; then
rm -rf "$DEPLOY_DIR"
fi
#!/usr/bin/env bash
# export-pdf.sh — Export an HTML presentation to PDF
#
# Usage:
# bash scripts/export-pdf.sh <path-to-html> [output.pdf]
#
# Examples:
# bash scripts/export-pdf.sh ./my-deck/index.html
# bash scripts/export-pdf.sh ./presentation.html ./presentation.pdf
#
# What this does:
# 1. Starts a local server to serve the HTML (fonts and assets need HTTP)
# 2. Uses Playwright to screenshot each slide at 1920x1080
# 3. Combines all screenshots into a single PDF
# 4. Cleans up the server and temp files
#
# The PDF preserves colors, fonts, and layout — but not animations.
# Perfect for email attachments, printing, or embedding in documents.
set -euo pipefail
# ─── Colors ────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${CYAN}ℹ${NC} $*"; }
ok() { echo -e "${GREEN}✓${NC} $*"; }
warn() { echo -e "${YELLOW}⚠${NC} $*"; }
err() { echo -e "${RED}✗${NC} $*" >&2; }
# ─── Parse flags ──────────────────────────────────────────
# Default resolution: 1920x1080 (full HD, ~1-2MB per slide)
# Compact resolution: 1280x720 (HD, ~50-70% smaller files)
VIEWPORT_W=1920
VIEWPORT_H=1080
COMPACT=false
POSITIONAL=()
for arg in "$@"; do
case $arg in
--compact)
COMPACT=true
VIEWPORT_W=1280
VIEWPORT_H=720
;;
*)
POSITIONAL+=("$arg")
;;
esac
done
set -- "${POSITIONAL[@]}"
# ─── Input validation ─────────────────────────────────────
if [[ $# -lt 1 ]]; then
err "Usage: bash scripts/export-pdf.sh <path-to-html> [output.pdf] [--compact]"
err ""
err "Examples:"
err " bash scripts/export-pdf.sh ./my-deck/index.html"
err " bash scripts/export-pdf.sh ./presentation.html ./slides.pdf"
err " bash scripts/export-pdf.sh ./presentation.html --compact # smaller file size"
exit 1
fi
INPUT_HTML="$1"
if [[ ! -f "$INPUT_HTML" ]]; then
err "File not found: $INPUT_HTML"
exit 1
fi
# Resolve to absolute path
INPUT_HTML=$(cd "$(dirname "$INPUT_HTML")" && pwd)/$(basename "$INPUT_HTML")
# Output PDF path: use second argument or derive from input name
if [[ $# -ge 2 ]]; then
OUTPUT_PDF="$2"
else
OUTPUT_PDF="$(dirname "$INPUT_HTML")/$(basename "$INPUT_HTML" .html).pdf"
fi
# Resolve output to absolute path
OUTPUT_DIR=$(dirname "$OUTPUT_PDF")
mkdir -p "$OUTPUT_DIR"
OUTPUT_PDF="$OUTPUT_DIR/$(basename "$OUTPUT_PDF")"
echo ""
echo -e "${BOLD}╔══════════════════════════════════════╗${NC}"
echo -e "${BOLD}║ Export Slides to PDF ║${NC}"
echo -e "${BOLD}╚══════════════════════════════════════╝${NC}"
echo ""
# ─── Step 1: Check dependencies ───────────────────────────
info "Checking dependencies..."
if ! command -v npx &>/dev/null; then
err "Node.js is required but not installed."
err ""
err "Install Node.js:"
err " macOS: brew install node"
err " or visit https://nodejs.org and download the installer"
exit 1
fi
ok "Node.js found"
# ─── Step 2: Create the export script ─────────────────────
# We use a temporary Node.js script with Playwright to:
# 1. Start a local server (so fonts load correctly)
# 2. Navigate to each slide
# 3. Screenshot each slide at 1920x1080 (16:9 landscape)
# 4. Combine into a single PDF
TEMP_DIR=$(mktemp -d)
TEMP_SCRIPT="$TEMP_DIR/export-slides.mjs"
# Figure out which directory to serve (the folder containing the HTML)
SERVE_DIR=$(dirname "$INPUT_HTML")
HTML_FILENAME=$(basename "$INPUT_HTML")
cat > "$TEMP_SCRIPT" << 'EXPORT_SCRIPT'
// export-slides.mjs — Playwright script to export HTML slides to PDF
//
// How it works:
// 1. Starts a local HTTP server (needed for fonts/assets to load)
// 2. Opens the presentation in a headless browser at 1920x1080
// 3. Counts the total number of slides
// 4. Screenshots each slide one by one
// 5. Generates a PDF with all slides as landscape pages
import { chromium } from 'playwright';
import { createServer } from 'http';
import { readFileSync, existsSync, mkdirSync, unlinkSync, writeFileSync } from 'fs';
import { join, extname, resolve } from 'path';
import { execSync } from 'child_process';
const SERVE_DIR = process.argv[2];
const HTML_FILE = process.argv[3];
const OUTPUT_PDF = process.argv[4];
const SCREENSHOT_DIR = process.argv[5];
const VP_WIDTH = parseInt(process.argv[6]) || 1920;
const VP_HEIGHT = parseInt(process.argv[7]) || 1080;
// ─── Simple static file server ────────────────────────────
// (We need HTTP so that Google Fonts and relative assets load correctly)
const MIME_TYPES = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'application/javascript',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.webp': 'image/webp',
'.woff': 'font/woff',
'.woff2': 'font/woff2',
'.ttf': 'font/ttf',
'.eot': 'application/vnd.ms-fontobject',
};
const server = createServer((req, res) => {
// Decode URL-encoded characters (e.g., %20 → space) so filenames with spaces resolve correctly
const decodedUrl = decodeURIComponent(req.url);
let filePath = join(SERVE_DIR, decodedUrl === '/' ? HTML_FILE : decodedUrl);
try {
const content = readFileSync(filePath);
const ext = extname(filePath).toLowerCase();
res.writeHead(200, { 'Content-Type': MIME_TYPES[ext] || 'application/octet-stream' });
res.end(content);
} catch {
res.writeHead(404);
res.end('Not found');
}
});
// Find a free port
const port = await new Promise((resolve) => {
server.listen(0, () => resolve(server.address().port));
});
console.log(` Local server on port ${port}`);
// ─── Screenshot each slide ────────────────────────────────
const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: VP_WIDTH, height: VP_HEIGHT },
});
// Load the presentation
await page.goto(`http://localhost:${port}/`, { waitUntil: 'networkidle' });
// Wait for fonts to load
await page.evaluate(() => document.fonts.ready);
// Extra wait for animations to settle on the first slide
await page.waitForTimeout(1500);
// Count slides
const slideCount = await page.evaluate(() => {
return document.querySelectorAll('.slide').length;
});
console.log(` Found ${slideCount} slides`);
if (slideCount === 0) {
console.error(' ERROR: No .slide elements found in the presentation.');
console.error(' Make sure your HTML uses <div class="slide"> or <section class="slide">.');
await browser.close();
server.close();
process.exit(1);
}
// Screenshot each slide
mkdirSync(SCREENSHOT_DIR, { recursive: true });
const screenshotPaths = [];
for (let i = 0; i < slideCount; i++) {
// Navigate to slide by simulating the presentation's navigation
// Most frontend-slides presentations use a currentSlide index and show/hide
await page.evaluate((index) => {
const slides = document.querySelectorAll('.slide');
// Try multiple navigation strategies used by frontend-slides:
// Strategy 1: Direct slide manipulation (most common in generated decks)
slides.forEach((slide, idx) => {
if (idx === index) {
slide.style.display = '';
slide.style.opacity = '1';
slide.style.visibility = 'visible';
slide.style.position = 'relative';
slide.style.transform = 'none';
slide.classList.add('active');
} else {
slide.style.display = 'none';
slide.classList.remove('active');
}
});
// Strategy 2: If there's a SlidePresentation class instance, use it
if (window.presentation && typeof window.presentation.goToSlide === 'function') {
window.presentation.goToSlide(index);
}
// Strategy 3: Scroll-based (some decks use scroll snapping)
slides[index]?.scrollIntoView({ behavior: 'instant' });
}, i);
// Wait for any slide transition animations to finish
await page.waitForTimeout(300);
// Wait for intersection observer animations to trigger
await page.waitForTimeout(200);
// Force all .reveal elements on the current slide to be visible
// (animations normally trigger on scroll/intersection, but we need them visible now)
await page.evaluate((index) => {
const slides = document.querySelectorAll('.slide');
const currentSlide = slides[index];
if (currentSlide) {
currentSlide.querySelectorAll('.reveal').forEach(el => {
el.style.opacity = '1';
el.style.transform = 'none';
el.style.visibility = 'visible';
});
}
}, i);
await page.waitForTimeout(100);
const screenshotPath = join(SCREENSHOT_DIR, `slide-${String(i + 1).padStart(3, '0')}.png`);
await page.screenshot({ path: screenshotPath, fullPage: false });
screenshotPaths.push(screenshotPath);
console.log(` Captured slide ${i + 1}/${slideCount}`);
}
await browser.close();
server.close();
// ─── Combine screenshots into PDF ─────────────────────────
// Use a second Playwright page to generate a PDF from the screenshots
console.log(' Assembling PDF...');
const browser2 = await chromium.launch();
const pdfPage = await browser2.newPage();
// Build an HTML page with all screenshots, one per page
const imagesHtml = screenshotPaths.map((p) => {
const imgData = readFileSync(p).toString('base64');
return `<div class="page"><img src="data:image/png;base64,${imgData}" /></div>`;
}).join('\n');
const pdfHtml = `<!DOCTYPE html>
<html>
<head>
<style>
* { margin: 0; padding: 0; }
@page { size: ${VP_WIDTH}px ${VP_HEIGHT}px; margin: 0; }
.page {
width: ${VP_WIDTH}px;
height: ${VP_HEIGHT}px;
page-break-after: always;
overflow: hidden;
}
.page:last-child { page-break-after: auto; }
img {
width: ${VP_WIDTH}px;
height: ${VP_HEIGHT}px;
display: block;
object-fit: contain;
}
</style>
</head>
<body>${imagesHtml}</body>
</html>`;
await pdfPage.setContent(pdfHtml, { waitUntil: 'load' });
await pdfPage.pdf({
path: OUTPUT_PDF,
width: `${VP_WIDTH}px`,
height: `${VP_HEIGHT}px`,
printBackground: true,
margin: { top: 0, right: 0, bottom: 0, left: 0 },
});
await browser2.close();
// Clean up screenshots
screenshotPaths.forEach(p => unlinkSync(p));
console.log(` ✓ PDF saved to: ${OUTPUT_PDF}`);
EXPORT_SCRIPT
# ─── Step 3: Install Playwright in temp directory ──────────
# We install Playwright locally in the temp dir so the Node script can import it.
# This avoids polluting global packages and ensures the script is self-contained.
info "Setting up Playwright (headless browser for screenshots)..."
info "This may take a moment on first run..."
echo ""
cd "$TEMP_DIR"
# Create a minimal package.json so npm install works
cat > "$TEMP_DIR/package.json" << 'PKG'
{ "name": "slide-export", "private": true, "type": "module" }
PKG
# Install Playwright into the temp directory
npm install playwright &>/dev/null || {
err "Failed to install Playwright."
err "Try running: npm install playwright"
rm -rf "$TEMP_DIR"
exit 1
}
# Ensure Chromium browser binary is downloaded
npx playwright install chromium 2>/dev/null || {
err "Failed to install Chromium browser for Playwright."
err "Try running manually: npx playwright install chromium"
rm -rf "$TEMP_DIR"
exit 1
}
ok "Playwright ready"
echo ""
# ─── Step 4: Run the export ───────────────────────────────
SCREENSHOT_DIR="$TEMP_DIR/screenshots"
info "Exporting slides to PDF..."
echo ""
# Run from the temp dir so Node can find the locally-installed playwright
if [[ "$COMPACT" == "true" ]]; then
info "Using compact mode (1280×720) for smaller file size"
fi
node "$TEMP_SCRIPT" "$SERVE_DIR" "$HTML_FILENAME" "$OUTPUT_PDF" "$SCREENSHOT_DIR" "$VIEWPORT_W" "$VIEWPORT_H" || {
err "PDF export failed."
rm -rf "$TEMP_DIR"
exit 1
}
# ─── Step 5: Cleanup and success ──────────────────────────
rm -rf "$TEMP_DIR"
echo ""
echo -e "${BOLD}════════════════════════════════════════${NC}"
ok "PDF exported successfully!"
echo ""
echo -e " ${BOLD}File:${NC} $OUTPUT_PDF"
echo ""
FILE_SIZE=$(du -h "$OUTPUT_PDF" | cut -f1 | xargs)
echo " Size: $FILE_SIZE"
echo ""
echo " This PDF works everywhere — email, Slack, Notion, print."
echo " Note: Animations are not preserved (it's a static export)."
echo -e "${BOLD}════════════════════════════════════════${NC}"
echo ""
# Open the PDF automatically
if command -v open &>/dev/null; then
open "$OUTPUT_PDF"
elif command -v xdg-open &>/dev/null; then
xdg-open "$OUTPUT_PDF"
fi
#!/usr/bin/env python3
"""
Extract all content from a PowerPoint file (.pptx).
Returns a JSON structure with slides, text, and images.
Usage:
python extract-pptx.py <input.pptx> [output_dir]
Requires: pip install python-pptx
"""
import json
import os
import sys
from pptx import Presentation
def extract_pptx(file_path, output_dir="."):
"""
Extract all content from a PowerPoint file.
Returns a list of slide data dicts with text, images, and notes.
"""
prs = Presentation(file_path)
slides_data = []
# Create assets directory for extracted images
assets_dir = os.path.join(output_dir, "assets")
os.makedirs(assets_dir, exist_ok=True)
for slide_num, slide in enumerate(prs.slides):
slide_data = {
"number": slide_num + 1,
"title": "",
"content": [],
"images": [],
"notes": "",
}
for shape in slide.shapes:
# Extract text content
if shape.has_text_frame:
if shape == slide.shapes.title:
slide_data["title"] = shape.text
else:
slide_data["content"].append(
{"type": "text", "content": shape.text}
)
# Extract images
if shape.shape_type == 13: # Picture type
image = shape.image
image_bytes = image.blob
image_ext = image.ext
image_name = f"slide{slide_num + 1}_img{len(slide_data['images']) + 1}.{image_ext}"
image_path = os.path.join(assets_dir, image_name)
with open(image_path, "wb") as f:
f.write(image_bytes)
slide_data["images"].append(
{
"path": f"assets/{image_name}",
"width": shape.width,
"height": shape.height,
}
)
# Extract speaker notes
if slide.has_notes_slide:
notes_frame = slide.notes_slide.notes_text_frame
slide_data["notes"] = notes_frame.text
slides_data.append(slide_data)
return slides_data
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python extract-pptx.py <input.pptx> [output_dir]")
sys.exit(1)
input_file = sys.argv[1]
output_dir = sys.argv[2] if len(sys.argv) > 2 else "."
slides = extract_pptx(input_file, output_dir)
# Write extracted data as JSON
output_path = os.path.join(output_dir, "extracted-slides.json")
with open(output_path, "w") as f:
json.dump(slides, f, indent=2)
print(f"Extracted {len(slides)} slides to {output_path}")
for s in slides:
img_count = len(s["images"])
print(f" Slide {s['number']}: {s['title'] or '(no title)'} — {img_count} image(s)")
/* ===========================================
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;
}
}