
Pptx Generator
- 253 installs
- 805 repo stars
- Updated January 24, 2026
- coleam00/second-brain-skills
Generate polished PowerPoint decks from structured outlines—slides, layouts, charts, and speaker notes—for pitches, reports, and knowledge-base exports via agent workflows.
About
pptx-generator skill from second-brain-skills turns agent-authored outlines into formatted PowerPoint files—layouts, charts, notes—so teams produce pitch decks and reports without manual slide building.
- Slide layout and theme application
- Bullet-to-slide content structuring
- Chart and table insertion patterns
- Speaker notes and appendix slides
- Automated export to .pptx files
Pptx Generator by the numbers
- 253 all-time installs (skills.sh)
- Ranked #206 of 687 Office & Documents skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/coleam00/second-brain-skills --skill pptx-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 253 |
|---|---|
| repo stars | ★ 805 |
| Last updated | January 24, 2026 |
| Repository | coleam00/second-brain-skills ↗ |
What it does
Generate polished PowerPoint decks from structured outlines—slides, layouts, charts, and speaker notes—for pitches, reports, and knowledge-base exports via agent workflows.
Files
PPTX Slide Generator
Generate professional, on-brand presentation slides using python-pptx. This skill supports:
- Slide Generation - Create presentations for any brand in
brands/ - Carousel Generation - Create LinkedIn carousels (square format, exports to PDF)
- Slide Editing - Modify existing PPTX files
- Layout Management - Create, edit, update cookbook layouts
IMPORTANT: All skill resources are in .claude/skills/pptx-generator/. Always use Glob patterns starting with .claude/skills/pptx-generator/ to find files.
---
⚠️ CRITICAL: Batch Generation Rules
NEVER generate more than 5 slides at once.
| Rule | Details |
|---|---|
| Max slides per batch | 5 (can be 1, 2, 3, 4, or 5) |
| After each batch | STOP and validate output |
| Validation required | Check: no duplicate titles, proper spacing, correct colors |
| Continue when | Validation passes |
| After ALL batches | COMBINE into single file and DELETE part files |
This prevents token limit errors and catches quality issues early.
CRITICAL: Always clean up part files after combining. The user should only see ONE final PPTX file, not multiple part files.
---
⚠️ PREREQUISITE: Brand Check
Before generating slides, check if any brands exist.
Glob: .claude/skills/pptx-generator/brands/*/brand.jsonIf NO brands found (only `template/` exists):
1. STOP - Do not proceed with slide generation 2. Ask the user:
"No brands are configured yet. Would you like me to help you create a brand first?
I'll need your brand colors, fonts, and style guidelines to set this up."
3. If user wants to create a brand, follow the Creating a New Brand section below.
4. If user declines, explain that slides require a brand configuration and offer to use generic styling as a fallback.
---
Creating a New Brand
When no brands exist or user requests a new brand:
Step 1: Read the Template
Read: .claude/skills/pptx-generator/brands/template/README.md
Read: .claude/skills/pptx-generator/brands/template/brand.json
Read: .claude/skills/pptx-generator/brands/template/config.jsonStep 2: Gather Brand Information
Ask the user for (or extract from provided materials):
| Required | Description |
|---|---|
| Brand name | Folder name (lowercase, no spaces) |
| Colors | Background, text, accent colors (hex codes) |
| Fonts | Heading font, body font, code font |
| Optional | Description |
|---|---|
| Output directory | Where to save generated files (default: output/{brand}) |
| Logo | Path to logo file (PNG/SVG) |
| Brand guidelines | Existing style guide or website to reference |
| Tone of voice | Writing style, vocabulary preferences |
Step 3: Create Brand Files
1. Create the brand folder:
mkdir -p .claude/skills/pptx-generator/brands/{brand-name}2. Create brand.json with the gathered values:
{
"name": "Brand Name",
"description": "One-line description",
"colors": {
"background": "hex-without-hash",
"background_alt": "hex-without-hash",
"text": "hex-without-hash",
"text_secondary": "hex-without-hash",
"accent": "hex-without-hash",
"accent_secondary": "hex-without-hash",
"accent_tertiary": "hex-without-hash",
"code_bg": "hex-without-hash",
"card_bg": "hex-without-hash",
"card_bg_alt": "hex-without-hash"
},
"fonts": {
"heading": "Font Name",
"body": "Font Name",
"code": "Monospace Font"
},
"assets": {
"logo": "assets/logo.png",
"logo_dark": null,
"icon": null
}
}3. Create config.json with output settings:
{
"output": {
"directory": "output/{brand}",
"naming": "{name}-{date}",
"keep_parts": false
},
"generation": {
"slides_per_batch": 5,
"auto_combine": true,
"open_after_generate": false
},
"defaults": {
"slide_width_inches": 13.333,
"slide_height_inches": 7.5
}
}4. Create brand-system.md - Copy from template and fill in brand guidelines
5. Create tone-of-voice.md - Copy from template and fill in voice guidelines
6. Add assets - Copy logo/images to brands/{brand-name}/assets/
Step 4: Verify
After creating the brand, verify with:
Glob: .claude/skills/pptx-generator/brands/{brand-name}/*Then proceed to slide generation.
---
Skill Modes
This skill operates in three modes:
Mode 1: Generate Presentation Slides
User wants presentation slides (16:9) created using a brand's styling. → Follow: Brand Discovery → Layout Selection → Content Adaptation → Execute → Layouts in: cookbook/*.py
Mode 2: Generate LinkedIn Carousels
User wants a LinkedIn carousel (square 1:1 format) for social media. → Follow: Brand Discovery → Carousel Planning → Generate → Export PDF → Layouts in: cookbook/carousels/*.py
Mode 3: Manage Cookbook Layouts
User wants to create, edit, or improve layout templates. → Follow: Layout CRUD Operations section
---
Mode 1: Generate Presentation Slides
Step 1: Brand Discovery
1. List available brands:
Glob: .claude/skills/pptx-generator/brands/*/brand.jsonExtract unique brand names from paths (e.g., brands/rasmus/... → "rasmus")
2. Read the brand configuration files:
Read: .claude/skills/pptx-generator/brands/{brand-name}/brand.json
Read: .claude/skills/pptx-generator/brands/{brand-name}/config.jsonbrand.json- Colors, fonts, assetsconfig.json- Output directory, generation settings
3. Read supporting markdown files for context:
Glob: .claude/skills/pptx-generator/brands/{brand-name}/*.mdThese provide voice, tone, and design philosophy.
4. Extract from brand files:
- From brand.json: Colors (hex without #), fonts, asset paths
- From config.json: Output directory, slides per batch, naming convention
- From markdown: Voice, tone, vocabulary, visual principles
If brand not found, list available brands and ask user to choose.
Step 2: Layout Discovery (READ ALL FRONTMATTERS)
⚠️ MANDATORY: Read ALL layout frontmatters before selecting any layout.
This step is critical for making informed layout decisions. You must understand what ALL layouts offer before choosing.
Step 2a: Discover all layouts:
Glob: .claude/skills/pptx-generator/cookbook/*.pyStep 2b: Read EVERY layout file (not just one or two):
For each .py file found, read the first 40 lines to extract the # /// layout frontmatter block. Build a mental map of:
- What each layout is for (
purpose,best_for) - What each layout should NOT be used for (
avoid_when) - Limits and constraints (
max_*,min_*,*_max_chars)
The frontmatter block looks like this:
# /// layout
# name = "floating-cards-slide"
# purpose = "Feature highlights, process steps, multiple equal items with depth"
# best_for = [
# "Exactly 3 related features or concepts",
# "Process with 3 steps",
# ]
# avoid_when = [
# "More than 3 items - use multi-card-slide instead",
# "Long card titles (over 15 characters)",
# ]
# max_cards = 3
# card_title_max_chars = 15
# instructions = [
# "EXACTLY 3 cards required - no more, no less",
# "Card titles must be SHORT: 1-2 words, max 15 characters",
# ]
# ///Key frontmatter fields:
| Field | Description |
|---|---|
name | Layout identifier |
purpose | What this layout is for |
best_for | Ideal use cases (array) |
avoid_when | When NOT to use this layout (array) |
max_* / min_* | Item limits (cards, bullets, stats) |
instructions | Specific tips for using this layout |
Step 2c: Select layouts (only AFTER reading all frontmatters):
Now that you know all available layouts and their constraints:
1. User specifies layout → Use that layout (but verify it fits the content) 2. User describes content → Match to best-fitting best_for criteria 3. Check `avoid_when` → Don't use a layout in situations it warns against 4. Respect limits → If content exceeds max_*, use a different layout 5. Multiple slides needed → Select appropriate layout for each 6. No good fit → Create a custom layout (see Mode 2)
Example selection process:
- User wants "5 pillars of AI infrastructure"
- You've read all frontmatters and know:
floating-cards-slide:max_cards = 3→ Won't workmulti-card-slide:max_cards = 5→ Perfect fit- Select
multi-card-slide
Why read ALL frontmatters?
- Layouts reference each other in
avoid_when(e.g., "use multi-card-slide instead") - You can't make the right choice without knowing all options
- Prevents backtracking when a layout doesn't fit
Step 2d: Visual-First Layout Selection (CRITICAL FOR VARIETY)
🎨 DEFAULT TO VISUAL LAYOUTS. Content-slide is the LAST RESORT, not the default.
The Variety Problem
The biggest mistake in presentation generation is defaulting to content-slide (title + bullets) whenever you have information to convey. This creates repetitive, boring presentations.
Common failure pattern:
- 11 out of 30 slides = content-slide (37% repetition)
- User says "this lacks variety"
- You think "but I used 11 different layout types!"
- Reality: Layout variety exists, but distribution is terrible
Variety Enforcement Rules
HARD LIMITS: 1. Never use the same layout more than 2-3 times consecutively 2. Content-slide should be <25% of total slides (not 35-40%) 3. Visual layouts (cards, stats, columns, hero, diagonal) should be 50%+ of slides 4. Section breaks are NOT variety - they're structural (don't count toward variety)
Decision Tree: "Should I Use content-slide?"
Ask these questions IN ORDER before defaulting to content-slide:
Do I have 3-5 equal items?
YES → Use multi-card-slide (not content-slide)
Do I have 2-4 big numbers/metrics?
YES → Use stats-slide (not content-slide)
Am I comparing two things?
YES → Use two-column-slide (not content-slide)
Do I have a central concept with surrounding items?
YES → Use circular-hero-slide (not content-slide)
Do I have exactly 3 related items?
YES → Use floating-cards-slide (not content-slide)
Do I have 1-3 words I want to emphasize dramatically?
YES → Use giant-focus-slide or bold-diagonal-slide (not content-slide)
Do I have a powerful quote or principle?
YES → Use quote-slide (not content-slide)
Is this the ONLY way to present this information?
YES → NOW you can use content-slide
NO → Go back through the decision treeTransforming Bullets Into Visual Layouts
Example 1: "Validation Patterns"
❌ BAD (content-slide):
Title: Validation Patterns
Bullets:
- Run comprehensive test suites
- Type checking and linting
- Code review by humans and AI
- Deployment previews✅ GOOD (multi-card-slide):
Title: Validation Patterns
Cards:
1. Testing | Run comprehensive test suites after every change
2. Linting | Type checking and formatting as guardrails
3. Review | Human and AI code review process
4. Preview | Deployment previews for visual regressionExample 2: "Why PIV Works"
❌ BAD (content-slide):
Title: Why PIV Works
Bullets:
- Forces planning before implementation
- Validation catches issues immediately
- Iterative improvements compound
- System gets smarter with every bug✅ GOOD (floating-cards-slide with 3 cards):
Title: Why PIV Works
Cards:
1. Plan First | Forces architectural thinking before coding
2. Fast Feedback | Validation catches issues immediately
3. Compounds | System improves with every bug(Note: Reduced from 4 to 3 items to fit floating-cards-slide max_cards limit)
Example 3: "Human-in-the-Loop Strategy"
❌ BAD (content-slide):
Title: Human-in-the-Loop Strategy
Bullets:
- In-the-loop: Human approves before execution
- On-the-loop: Human reviews after completion
- Code review remains critical
- AI generates, humans validate✅ GOOD (two-column-slide):
Title: Human-in-the-Loop Strategy
Left: In-the-Loop
- Human approves before execution
- Critical for production changes
- Quality gateway
Right: On-the-Loop
- Human reviews after completion
- Faster iteration cycles
- AI generates, human validatesActive Visual Thinking
Before planning any slide, ask yourself:
1. "Can this be more visual?" - The answer is almost always YES 2. "Have I used content-slide in the last 2 slides?" - If yes, use something else 3. "Does this slide look like the previous slide?" - If yes, change the layout 4. "Am I falling into a pattern?" - Break it immediately 5. "Would this be more engaging as cards/columns/stats?" - Usually yes
When content-slide IS Appropriate
Use content-slide ONLY when:
- You've genuinely tried all other layouts and they don't fit
- The information is inherently linear and textual (rare)
- You need a "breather" slide between two complex visuals
- You're at your layout distribution limits (already used all the visual ones recently)
Never use content-slide as your default thinking.
Quick Reference: Content Type → Best Layout
| Content Type | Best Layout | Why |
|---|---|---|
| 3-5 equal features/steps | multi-card-slide | Cards create visual hierarchy |
| Exactly 3 featured items | floating-cards-slide | Elevated cards add depth |
| 2-4 metrics/KPIs | stats-slide | Big numbers grab attention |
| Before/after comparison | two-column-slide | Side-by-side shows contrast |
| Hub concept with types | circular-hero-slide | Radiating pattern shows relationships |
| Dramatic emphasis (1-3 words) | giant-focus-slide | Scale creates impact |
| High-energy warning | bold-diagonal-slide | Dynamic shapes convey urgency |
| Powerful quote/principle | quote-slide | Attribution adds authority |
| List of related items | multi-card-slide | Better than bullets |
| Process with steps | floating-cards-slide | Visual flow beats text |
| Technical comparison | two-column-slide | Structured comparison |
Only use content-slide when:
- None of the above fit
- Information is truly linear
- Need a text-heavy breather between visual slides
- Already hit variety limits
Step 3: Slide Planning (ALWAYS DO THIS)
Before generating ANY slides, create a written plan.
This applies to single slides, batches, and full presentations. Planning prevents:
- Duplicate content across slides
- Wrong layout choices
- Missing key information
- Poor flow and structure
Create a slide plan table:
| # | Layout | Title | Key Content | Notes |
|---|--------|-------|-------------|-------|
| 1 | title-slide | [Title] | [Subtitle, author] | Opening slide |
| 2 | content-slide | [Title] | [3-4 bullet points] | Main concepts |
| 3 | stats-slide | [Title] | [2-3 metrics] | Impact data |
| ... | ... | ... | ... | ... |For each slide, specify:
- Slide number - Position in presentation
- Layout - Which cookbook layout to use
- Title - Exact title text (check for duplicates!)
- Key content - Bullet points, stats, quotes, etc.
- Notes - Any special considerations
Planning checklist:
- [ ] No duplicate titles across slides
- [ ] Logical flow from slide to slide
- [ ] Appropriate layout for each content type
- [ ] Content fits the chosen layout
- [ ] Batches are logically grouped (5 slides max each)
- [ ] VARIETY CHECK: Content-slide used <25% of total slides
- [ ] VARIETY CHECK: No more than 2-3 consecutive slides with same layout
- [ ] VARIETY CHECK: Visual layouts (cards, stats, columns, hero) are 50%+ of slides
- [ ] VARIETY CHECK: Each content-slide was evaluated against decision tree first
After planning, briefly present the plan before generating.
Example of good variety distribution for 30-slide presentation:
- Content-slide: 6-7 slides (20-23%)
- Section breaks: 5 slides (17%)
- Visual layouts: 15-16 slides (50-53%)
- Multi-card: 3-4 slides
- Two-column: 2-3 slides
- Stats: 1-2 slides
- Floating-cards: 2-3 slides
- Circular-hero: 1-2 slides
- Giant-focus/Bold-diagonal: 2-3 slides
- Quote: 1 slide
- Title/Closing: 2-3 slides (7-10%)
Step 4: Content Adaptation
For each slide in your plan:
Presentation Text Formatting Rules
IMPORTANT: Follow these rules for ALL slide text.
| Element | Rule | Example |
|---|---|---|
| Titles | No trailing periods or commas | "Why AI Matters" not "Why AI Matters." |
| Subtitles | No trailing punctuation | "The future of coding" not "The future of coding." |
| Bullet points | No trailing periods (unless full sentences) | "Faster development" not "Faster development." |
| Headlines | Minimal punctuation, no ellipsis | "What's Next" not "What's Next..." |
| Stats/Numbers | Clean format, no trailing punctuation | "50%" not "50%." |
| CTAs | No trailing punctuation | "Get Started" not "Get Started." |
| Labels | Short, no punctuation | "Step 1" not "Step 1:" |
Avoid:
- Trailing periods on titles, bullets, labels
- Ellipsis (...) in headlines
- Excessive commas in short phrases
- Colons at end of labels/headers
- Semicolons in bullet points
Exception: Full sentence descriptions or quotes may use appropriate punctuation.
Brand Value Mapping
1. Map brand.json values to layout placeholders:
| Layout Placeholder | brand.json Path |
|---|---|
BRAND_BG | colors.background |
BRAND_BG_ALT | colors.background_alt |
BRAND_TEXT | colors.text |
BRAND_TEXT_SECONDARY | colors.text_secondary |
BRAND_ACCENT | colors.accent |
BRAND_ACCENT_SECONDARY | colors.accent_secondary |
BRAND_ACCENT_TERTIARY | colors.accent_tertiary |
BRAND_CODE_BG | colors.code_bg |
BRAND_CARD_BG | colors.card_bg |
BRAND_CARD_BG_ALT | colors.card_bg_alt |
BRAND_HEADING_FONT | fonts.heading |
BRAND_BODY_FONT | fonts.body |
BRAND_CODE_FONT | fonts.code |
Note: All color values in brand.json are hex WITHOUT the # prefix.
2. Write content in brand's voice (from tone-of-voice.md) 3. Preserve layout structure (decorative elements, spacing, hierarchy)
Step 5: Batch Generation (CRITICAL)
MAXIMUM 5 SLIDES PER BATCH. This is a hard limit.
When generating multiple slides: 1. Generate 1-5 slides in a single PPTX file 2. STOP and review the output before generating more 3. Only after validation passes, continue with the next batch 4. Repeat until all slides are generated
Why batching matters:
- Prevents token limit errors
- Allows quality checks between batches
- Catches issues early before they propagate
⚠️ CRITICAL BACKGROUND BUG FIX:
EVERY slide MUST have its background explicitly set. If you don't set slide.background.fill.solid() and slide.background.fill.fore_color.rgb, the slide will use PowerPoint's default WHITE background, making text unreadable on dark-themed brands.
Mandatory for every slide:
slide = prs.slides.add_slide(prs.slide_layouts[6])
slide.background.fill.solid() # ← REQUIRED
slide.background.fill.fore_color.rgb = hex_to_rgb(BRAND_BG) # ← REQUIREDThis is especially critical when:
- Generating multiple batches (each batch is a new Presentation object)
- Using helper functions to create slides
- Combining separate PPTX files
Execution:
PREFERRED: Use heredoc (no files created):
uv run --with python-pptx==1.0.2 python << 'EOF'
# [Adapted code with brand values and content]
EOFIF heredoc fails (Windows issues): Use temp directory:
# Create temp directory if needed
mkdir -p .claude/skills/pptx-generator/.tmp
# Write script to temp directory
# (create file at .claude/skills/pptx-generator/.tmp/gen.py)
# Execute
uv run --with python-pptx==1.0.2 python .claude/skills/pptx-generator/.tmp/gen.py
# MANDATORY: Clean up immediately after execution
rm .claude/skills/pptx-generator/.tmp/gen.pyCRITICAL: Never create Python files in the repository root. Always use heredoc or temp directory within the skill folder.
Step 6: Quality Validation (MANDATORY)
After EVERY batch, validate before continuing:
1. Open the generated PPTX and visually inspect it 2. Check for these common issues:
| Issue | What to Look For | Fix |
|---|---|---|
| White background | Slide has white background instead of brand color | Add slide.background.fill.solid() and set fore_color.rgb |
| Duplicate titles | Same title text appearing twice on a slide | Remove duplicate text boxes |
| Spacing problems | Title too close to subtitle/content | Increase Y position of lower elements |
| Text overflow | Content extending beyond slide bounds | Reduce font size or split content |
| Missing elements | Decorative elements not rendering | Check shape positions and colors |
| Wrong colors | Colors not matching brand | Verify hex values (no # prefix in code) |
| Bad punctuation | Trailing periods/commas on titles/bullets | Remove unnecessary punctuation |
3. If issues found:
- Fix the current batch before continuing
- Note the issue to avoid repeating in future batches
4. If validation passes:
- Continue to next batch of slides
Step 7: Output
Use the output settings from config.json:
| Config Setting | Default | Description |
|---|---|---|
output.directory | output/{brand} | Where to save files |
output.naming | {name}-{date} | File naming pattern |
output.keep_parts | false | Keep part files after combining |
Resolve placeholders:
{brand}→ Brand folder name{name}→ Presentation name from user request{date}→ Current date (YYYY-MM-DD)
# Create output directory from config
mkdir -p {resolved-output-directory}Batched generation workflow: 1. Generate each batch as {name}-part1.pptx, {name}-part2.pptx, etc. 2. Validate each batch before continuing 3. After ALL batches complete, combine into final file (if auto_combine is true) 4. Delete part files (if keep_parts is false)
Step 8: Combine Batches (for multi-batch presentations)
🚨 CRITICAL BUG WARNING: BACKGROUND MUST BE SET WHEN COMBINING 🚨
When combining presentations, add_slide() creates slides with DEFAULT WHITE BACKGROUNDS. Shape copying does NOT copy the slide background property. You MUST explicitly set the background immediately after creating each new slide.
This is the most common source of white slides in combined presentations.
After all batches are validated, combine them into a single PPTX:
uv run --with python-pptx==1.0.2 python << 'SCRIPT'
from pptx import Presentation
from pptx.dml.color import RGBColor
from pathlib import Path
import shutil
def hex_to_rgb(hex_color: str) -> RGBColor:
h = hex_color.lstrip("#")
return RGBColor(int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))
# Brand background color (get from brand.json)
BRAND_BG = "REPLACE_WITH_BRAND_BACKGROUND" # e.g., "07090F"
# List all part files in order
output_dir = Path("output/{brand-name}")
part_files = sorted(output_dir.glob("{name}-part*.pptx"))
if len(part_files) > 1:
# Start with first part as base
combined = Presentation(part_files[0])
# Add slides from remaining parts
for part_file in part_files[1:]:
part_prs = Presentation(part_file)
for slide in part_prs.slides:
# Copy slide layout and add to combined
blank_layout = combined.slide_layouts[6]
new_slide = combined.slides.add_slide(blank_layout)
# 🚨 CRITICAL: Set background IMMEDIATELY after creating slide
# PowerPoint defaults to WHITE background - this MUST be set before copying shapes
new_slide.background.fill.solid()
new_slide.background.fill.fore_color.rgb = hex_to_rgb(BRAND_BG)
# Copy all shapes from source slide
for shape in slide.shapes:
# Clone shape to new slide
el = shape.element
new_slide.shapes._spTree.insert_element_before(
el, 'p:extLst'
)
# Save combined file
combined.save(output_dir / "{name}-final.pptx")
print(f"Combined {len(part_files)} parts into {name}-final.pptx")
# MANDATORY: Clean up part files - user should only see final file
for part_file in part_files:
part_file.unlink()
print(f"Deleted {part_file.name}")
else:
# Single part, just rename
shutil.move(part_files[0], output_dir / "{name}-final.pptx")
SCRIPTFinal output: output/{brand-name}/{name}-final.pptx
Why this bug happens:
combined.slides.add_slide()creates a NEW slide object with PowerPoint's default white backgroundshapes._spTree.insert_element_before()copies shapes (text, rectangles, images) but NOT the background- The background is a slide property, not a shape, so it must be set separately
- Without explicit background setting, slides 6-30 (or however many are added after the base) will be white
Testing checklist after combining:
- [ ] Open the combined PPTX
- [ ] Scroll through ALL slides (not just the first few)
- [ ] Verify EVERY slide has the correct background color
- [ ] If any white slides found, the combination code is missing the background setting
---
Mode 2: Generate LinkedIn Carousels
LinkedIn carousels are multi-page PDFs in square (1:1) format. Each page is a swipeable slide.
Carousel vs Presentation
| Aspect | Presentation | Carousel |
|---|---|---|
| Dimensions | 16:9 (13.333" × 7.5") | 1:1 (7.5" × 7.5") |
| Layouts | cookbook/*.py | cookbook/carousels/*.py |
| Output | PPTX | PDF (via PPTX conversion) |
| Slides | 10-50+ typical | 5-10 optimal |
| Text size | Standard | Larger (mobile readable) |
| Content | Detailed | One idea per slide |
Step 1: Brand Discovery
Same as Mode 1 - read brand.json, config.json, and tone-of-voice.md.
Step 2: Carousel Layout Discovery
Discover carousel-specific layouts:
Glob: .claude/skills/pptx-generator/cookbook/carousels/*.pyAvailable carousel layouts:
| Layout | Purpose | Best For |
|---|---|---|
hook-slide | Opening attention-grabber | First slide only |
single-point-slide | One key point with explanation | Body content |
numbered-point-slide | Numbered list item with big number | Listicles, steps |
quote-slide | Quote with attribution | Social proof, insights |
cta-slide | Call to action | Last slide only |
Read frontmatters to understand limits and constraints for each.
Step 3: Carousel Planning
Typical carousel structure (5-10 slides):
| # | Layout | Content |
|---|--------|---------|
| 1 | hook-slide | Attention-grabbing hook |
| 2-8 | single-point or numbered-point | Body content |
| 9/10 | cta-slide | Call to action |Carousel content rules:
- One idea per slide - Don't cram multiple points
- Large text - Must be readable on mobile
- Short copy - Max 50 chars for headlines, 150 for body
- Clear flow - Each slide should make sense if viewed alone
- Strong hook - First slide stops the scroll
- Clear CTA - Last slide tells them what to do
Step 4: Generate Carousel
Carousel dimensions (square 1:1):
prs.slide_width = Inches(7.5)
prs.slide_height = Inches(7.5)Generate all slides as a single PPTX file (carousels are typically 5-10 slides, so batching rarely needed).
Execution:
uv run --with python-pptx==1.0.2 python << 'SCRIPT'
# Carousel generation code with 7.5" x 7.5" dimensions
SCRIPTStep 5: Export to PDF
LinkedIn requires PDF for carousel posts. Convert the PPTX to PDF:
Option A: Using LibreOffice (recommended)
libreoffice --headless --convert-to pdf --outdir output/rasmus output/rasmus/carousel.pptxOption B: Using soffice
soffice --headless --convert-to pdf output/rasmus/carousel.pptxNote: LibreOffice must be installed. On macOS: brew install --cask libreoffice
Step 6: Output
Save both files:
output/{brand}/{name}-carousel.pptx- Editable sourceoutput/{brand}/{name}-carousel.pdf- LinkedIn-ready
Carousel Checklist
- [ ] Read brand configuration
- [ ] Read carousel layout frontmatters from
cookbook/carousels/ - [ ] Plan carousel structure (hook → body → CTA)
- [ ] Keep text SHORT (check character limits in frontmatter)
- [ ] Use 7.5" × 7.5" dimensions
- [ ] Generate PPTX
- [ ] Validate output
- [ ] Export to PDF
- [ ] Test PDF in LinkedIn preview
---
Mode 3: Layout CRUD Operations
Creating New Layouts
When user requests a new layout type:
1. Study existing layouts for patterns:
Glob: .claude/skills/pptx-generator/cookbook/*.pyRead 2-3 layouts to understand:
- Code structure and imports
- How brand variables are used
- Decorative element patterns
- Positioning conventions
2. Design with these quality standards:
MUST be production-ready:
- Professional, polished appearance
- Visually engaging (not plain or generic)
- Distinctive decorative elements
- Strong visual hierarchy
- Proper use of whitespace
Use appropriate elements:
- Charts - Pie, doughnut, bar, column for data visualization
- Images - Placeholder shapes for screenshots, photos
- Shapes - Circles, rectangles, parallelograms for visual interest
- Cards - Floating cards with shadows for depth
- Geometric patterns - Bold shapes anchored to corners/edges
Avoid:
- Plain text-only layouts
- Generic bullet points without styling
- Tiny decorative elements that don't make impact
- Centered-everything boring compositions
3. Write the layout file with detailed frontmatter:
⚠️ CRITICAL: The frontmatter is documentation for future AI agents.
Every layout MUST include comprehensive frontmatter that teaches future AI agents:
- WHEN to use this layout (and when NOT to)
- HOW to use it correctly
- WHAT limits and constraints exist
- WHY certain choices matter
#!/usr/bin/env -S uv run
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "python-pptx==1.0.2",
# ]
# ///
# /// layout
# name = "layout-name"
# purpose = "When to use this layout - be specific"
# best_for = [
# "Ideal use case 1",
# "Ideal use case 2",
# ]
# avoid_when = [
# "Situation to avoid 1 - and what to use instead",
# "Situation to avoid 2 - and what to use instead",
# ]
# max_items = 5 # or other relevant limits
# instructions = [
# "Specific tip 1",
# "Specific tip 2",
# ]
# ///
"""
LAYOUT: [Name]
PURPOSE: [When to use this layout - be specific]
CUSTOMIZE:
- [List customizable elements]
"""
# ... implementationRequired frontmatter fields (be DETAILED and SPECIFIC):
| Field | Description | Example |
|---|---|---|
name | Layout identifier (matches filename) | "multi-card-slide" |
purpose | Clear one-line description | "Multiple items as cards in a row, 3-5 cards" |
best_for | Detailed array of ideal scenarios | ["Exactly 3 related features", "Process with 3 steps"] |
avoid_when | Specific situations with alternatives | ["More than 3 items - use multi-card-slide instead"] |
instructions | Actionable tips for correct usage | ["Card titles must be SHORT: 1-2 words, max 15 chars"] |
Optional but recommended fields:
| Field | Description | Example |
|---|---|---|
max_* / min_* | Hard limits on items | max_cards = 3, min_surrounding_items = 4 |
*_max_chars | Character limits for text | card_title_max_chars = 15 |
Writing good frontmatter:
✅ DO: Be specific and actionable
# avoid_when = [
# "More than 3 items - use multi-card-slide instead",
# "Long card titles (over 15 characters) - abbreviate or use content-slide",
# ]
# instructions = [
# "EXACTLY 3 cards required - no more, no less",
# "Card titles must be SHORT: 1-2 words, max 15 characters",
# "If titles are too long, abbreviate or use different layout",
# ]❌ DON'T: Be vague or unhelpful
# avoid_when = ["Too many items", "Wrong content"]
# instructions = ["Use correctly", "Follow the pattern"]Think of frontmatter as teaching a colleague - what would they need to know to use this layout correctly without asking you questions?
4. Save to cookbook:
.claude/skills/pptx-generator/cookbook/{layout-name}-slide.py5. Test by generating a sample with the new layout
Editing Existing Layouts
1. Find the layout:
Glob: .claude/skills/pptx-generator/cookbook/*{name}*.py2. Read and understand current structure including the frontmatter
3. Make modifications while preserving:
- The script header format
- Brand variable naming conventions
- Docstring format (LAYOUT, PURPOSE, CUSTOMIZE)
4. Update the frontmatter if your changes affect:
- What the layout is best for (
best_for) - When to avoid it (
avoid_when) - Item limits (
max_*,min_*) - Usage instructions (
instructions)
5. Save back to the same file
6. Test the modified layout
Updating/Improving Layouts
When asked to improve layout quality:
1. Analyze current weaknesses:
- Is it visually engaging?
- Does it have enough decorative elements?
- Is there good visual hierarchy?
- Does it use space well?
2. Apply improvements:
- Add bold geometric shapes
- Improve color usage
- Add depth (shadows, overlapping)
- Better typography sizing
- More distinctive decorative elements
3. Preserve functionality - Don't break what works
4. Review and enhance frontmatter:
- Are
best_forandavoid_whenstill accurate? - Do
instructionsreflect any new constraints? - Add any lessons learned from the improvements
- Update limits if element sizes/counts changed
Deleting Layouts
Simply remove the file:
rm .claude/skills/pptx-generator/cookbook/{layout-name}.py---
Editing Existing PPTX Files
When user provides an existing PPTX:
1. Read the file:
from pptx import Presentation
prs = Presentation("path/to/existing.pptx")2. Analyze: Number of slides, styling, content structure
3. Apply changes: Add/remove slides, update content, modify styling
4. Save to output directory (don't overwrite original unless requested)
---
Technical Reference
Slide dimensions (16:9):
- Width: 13.333 inches
- Height: 7.5 inches
- Safe margins: 0.5 inches
Always use:
- Blank layout:
prs.slide_layouts[6] - python-pptx version: 1.0.2
Common imports:
from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.dml.color import RGBColor
from pptx.enum.chart import XL_CHART_TYPE, XL_LEGEND_POSITION
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, PtChart types available:
XL_CHART_TYPE.PIE- Pie chartXL_CHART_TYPE.DOUGHNUT- Doughnut chartXL_CHART_TYPE.BAR_CLUSTERED- Horizontal barsXL_CHART_TYPE.COLUMN_CLUSTERED- Vertical columnsXL_CHART_TYPE.LINE- Line chart
Adding charts:
chart_data = CategoryChartData()
chart_data.categories = ["A", "B", "C"]
chart_data.add_series("Values", [10, 20, 30])
slide.shapes.add_chart(
XL_CHART_TYPE.DOUGHNUT,
Inches(x), Inches(y),
Inches(width), Inches(height),
chart_data
)Adding images:
slide.shapes.add_picture(
"path/to/image.png",
Inches(x), Inches(y),
width=Inches(w) # Height auto-calculated
)---
Preview All Layouts
To see all available layouts:
uv run .claude/skills/pptx-generator/generate-cookbook-preview.pyThis generates cookbook-preview.pptx with every layout.
---
Checklist
For Slide Generation:
- [ ] Read brand.json for colors/fonts
- [ ] Read config.json for output directory and settings
- [ ] Read markdown files for voice/tone
- [ ] Read ALL cookbook layout frontmatters (first 40 lines of each .py):
- [ ] Glob all
.claude/skills/pptx-generator/cookbook/*.py - [ ] Read every file to extract
# /// layoutblocks - [ ] Build understanding of all
best_for,avoid_when, limits - [ ] Then select layouts based on complete knowledge:
- [ ] Match content to
best_forcriteria - [ ] Respect
avoid_whenwarnings - [ ] Check
max_*/min_*limits - [ ] Follow
instructionsfor chosen layouts - [ ] Create slide plan table BEFORE generating:
- [ ] List all slides with layout, title, content
- [ ] Check for duplicate titles
- [ ] Verify logical flow
- [ ] Group into batches (max 5 per batch)
- [ ] VARIETY CHECK: Content-slide <25% of total
- [ ] VARIETY CHECK: No 3+ consecutive same-layout slides
- [ ] VARIETY CHECK: Visual layouts 50%+ of presentation
- [ ] VARIETY CHECK: Used decision tree to evaluate each content-slide
- [ ] Present plan briefly before proceeding
- [ ] Apply brand colors and fonts
- [ ] Write content in brand's voice
- [ ] Generate MAX 5 slides per batch (or
slides_per_batchfrom config) - [ ] Execute via UV REPL
- [ ] Validate output before continuing:
- [ ] No duplicate titles
- [ ] Proper spacing between elements
- [ ] Content fits within bounds
- [ ] Colors match brand
- [ ] No trailing punctuation on titles/bullets
- [ ] Save batch to output directory from config
- [ ] Repeat for next batch if needed
- [ ] Combine all batches into final PPTX (if
auto_combineis true) - [ ] Clean up part files (if
keep_partsis false)
For Creating Layouts:
- [ ] Study existing layouts for patterns
- [ ] Design with production-ready quality
- [ ] Include distinctive decorative elements
- [ ] Use charts/images/shapes appropriately
- [ ] Add TOML-style frontmatter with:
- [ ]
name,purpose - [ ]
best_for,avoid_whenarrays - [ ]
instructionsarray with usage tips - [ ]
max_*/min_*limits as needed - [ ] Write proper docstring (LAYOUT, PURPOSE, CUSTOMIZE)
- [ ] Test the new layout
Dynamous — Brand System
A complete design system for AI education content, community, and products.
---
Brand Philosophy
Core Principles
1. Technical but Approachable Complex AI topics made accessible without dumbing them down. Show the sophistication, explain it clearly.
2. Clean over Flashy No unnecessary decoration. Every visual element has a purpose. Elegance through restraint.
3. Dark Mode by Default Modern, developer-focused aesthetic. Easy on the eyes for people who stare at screens all day.
4. Diagrams Should Argue, Not Display Visual content makes a point. Shapes mirror meaning. If you removed the text, the structure alone should communicate the concept.
---
Logo
The Dynamous Mark
A stylized blue flame/droplet shape — fluid, dynamic, and modern. Represents energy, transformation, and forward momentum.
Logo file: .claude/DynamousLogo.png
Usage rules:
- Maintain aspect ratio
- Minimum clear space: 20% of logo width on all sides
- On dark backgrounds: use as-is
- On light backgrounds: use as-is (blue on white works)
- Never distort, rotate, or add effects
Logo colors:
- Primary fill:
#3B82F6(Dynamous Blue) - Highlight gradient: lighter blue toward top-left
- Outline:
#2563EB(slightly darker)
---
Color System
Primary Accent — Dynamous Blue
The signature brand color. Used for primary actions, links, highlights, and the logo.
| Name | Hex | HSL | Use |
|---|---|---|---|
| Dynamous Blue | #3B82F6 | 217° 91% 60% | Primary buttons, links, logo |
| Dynamous Dark | #2563EB | 217° 91% 53% | Hover states, outlines |
| Dynamous Light | #60A5FA | 217° 91% 67% | Secondary accents, highlights |
| Dynamous Cyan | #0EA5E9 | 199° 89% 48% | Tertiary accents, variations |
| Dynamous Pale | #DBEAFE | 214° 95% 93% | Light mode backgrounds, fills |
Rule: Dynamous Blue is the hero. Use it for actions and emphasis. Don't dilute it by overusing.
CRITICAL: NO PURPLE. Dynamous uses blue variations only. Never use purple (#6D28D9 or similar). For tertiary accents or AI/LLM representations, use Dynamous Cyan (#0EA5E9) or darker blues (#1E40AF) instead.
Secondary Accents — Functional Colors
Used sparingly for specific semantic purposes.
| Purpose | Fill | Stroke | When to Use |
|---|---|---|---|
| AI/LLM | #DBEAFE | #0EA5E9 | Representing AI, agents, LLMs in diagrams |
| Success/Start | #A7F3D0 | #047857 | Completed states, starting points, announcements |
| Warning/Decision | #FEF3C7 | #B45309 | Decision points, caution, ratings |
| Error/Stop | #FECACA | #B91C1C | Errors, destructive actions, end states |
| Trigger/Input | #FED7AA | #C2410C | Input points, triggers in workflows |
Rule: These are semantic, not decorative. Use them to encode meaning in diagrams and UI states.
Theme Bases
Dark Theme (Default)
Background: #07090F (near-black with blue tint)
Background Alt: #080A13 (slightly warmer)
Surface: rgba(0, 0, 0, 0.4) (glass cards)
Border: rgba(255, 255, 255, 0.1)
Text Primary: rgba(255, 255, 255, 0.98)
Text Secondary: rgba(255, 255, 255, 0.80)
Text Muted: rgba(255, 255, 255, 0.70)Light Theme (Diagrams/Excalidraw)
Background: #FFFFFF
Surface: #F1F5F9 (slate-100)
Border: #E5E7EB (gray-200)
Text Primary: #1E293B (slate-800)
Text Secondary: #374151 (gray-700)
Text Muted: #64748B (slate-500)Gradient Backgrounds
Hero gradient (website):
background: linear-gradient(to bottom, #07090f, rgba(30, 58, 138, 0.9), #080a13);
background-attachment: fixed;Blue glow effect:
box-shadow: 0 0 15px rgba(59, 130, 246, 0.5), 0 0 30px rgba(59, 130, 246, 0.3);---
Typography
Font Stack
- Primary: Inter — Clean, modern sans-serif for all UI and body text
- Thumbnails: Montserrat Bold or Inter Black — High-impact, readable at small sizes
- Code: JetBrains Mono or system monospace
Type Scale
| Token | Size | Use |
|---|---|---|
xs | 0.75rem (12px) | Labels, badges, meta |
sm | 0.875rem (14px) | Secondary text, descriptions |
base | 1rem (16px) | Body text, paragraphs |
lg | 1.125rem (18px) | Lead paragraphs, emphasis |
xl | 1.25rem (20px) | Section headers |
2xl | 1.5rem (24px) | Card titles |
3xl | 1.875rem (30px) | Page headers |
4xl | 2.25rem (36px) | Hero subheadings |
5xl | 3rem (48px) | Hero headings (mobile) |
6xl | 3.75rem (60px) | Hero headings (desktop) |
Typography Rules
| Element | Font | Weight | Size | Line Height |
|---|---|---|---|---|
| Display/Hero | Inter | 700 (Bold) | 4xl-6xl | 1.1 |
| H1 | Inter | 700 | 3xl | 1.2 |
| H2 | Inter | 600 | 2xl | 1.3 |
| H3 | Inter | 600 | xl | 1.4 |
| Body | Inter | 400 | base | 1.6 |
| Small | Inter | 400 | sm | 1.5 |
| Code | JetBrains Mono | 400 | sm | 1.5 |
| Buttons | Inter | 500 | sm-base | 1 |
| Thumbnail Text | Montserrat | 800 | - | 1.1 |
Text Color Usage
| Context | Color | Notes |
|---|---|---|
| Headings | white (98%) | Full contrast for emphasis |
| Body content | white/80 | Comfortable reading |
| Descriptions | white/70 | Secondary information |
| Muted/meta | white/60 | Timestamps, labels |
| Links | Dynamous Blue | #3B82F6 with hover glow |
---
Spacing System
Base unit: 4px
| Token | Value | Use |
|---|---|---|
xs | 4px | Tight spacing, icon gaps |
sm | 8px | Related elements |
md | 12px | Form inputs internal |
base | 16px | Standard component padding |
lg | 24px | Section padding |
xl | 32px | Card padding |
2xl | 48px | Section margins |
3xl | 64px | Major section breaks |
Rule: When in doubt, use multiples of 8px.
---
Buttons
Button Types
| Type | Background | Text | Use |
|---|---|---|---|
| Primary | Dynamous Blue | White | Main actions, CTAs |
| Secondary | white/10 | White | Secondary actions |
| Outline | Transparent | White | Tertiary, paired with primary |
| Ghost | Transparent | White | Navigation, subtle actions |
Button Specs
- Font: Inter, 500 weight
- Border radius: 8px (0.5rem)
- Padding:
- sm: 6px 12px
- md: 8px 16px
- lg: 12px 24px
- Transition: 200ms ease-out
- Primary shadow:
0 4px 14px -4px rgba(59, 130, 246, 0.4)
Signature Button Effect
Shimmer animation on hover:
.shimmer {
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
animation: shimmer 2s linear infinite;
}---
Motion
Timing
| Type | Duration | Use |
|---|---|---|
| Micro | 150ms | Button states, toggles |
| Fast | 200ms | Dropdowns, small transitions |
| Normal | 300ms | Cards, modals |
| Slow | 600ms | Page transitions, fade-ins |
Rule: Nothing should take longer than 600ms. Snappy > smooth.
Easing
- Entrances:
ease-outorcubic-bezier(0, 0, 0.2, 1) - Exits:
ease-inorcubic-bezier(0.4, 0, 1, 1) - Never use: Linear for UI transitions (feels robotic)
Signature Animations
Float (decorative elements):
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
animation: float 6s ease-in-out infinite;Fade-in (content entrance):
@keyframes fade-in {
0% { opacity: 0; transform: translateY(10px); }
100% { opacity: 1; transform: translateY(0); }
}
animation: fade-in 0.6s ease-out forwards;Glow pulse (emphasis):
@keyframes glow {
0%, 100% { box-shadow: 0 0 5px rgba(59, 130, 246, 0.5); }
50% { box-shadow: 0 0 20px rgba(59, 130, 246, 0.8); }
}What Moves
- Buttons (hover, active states)
- Cards (hover lift)
- Decorative logos (floating)
- Page sections (scroll reveal)
- Modals (entrance/exit)
What Doesn't Move
- Body text
- Navigation (stays grounded)
- Form inputs (stable)
- Critical UI elements
---
Icons
Specifications
| Property | Value |
|---|---|
| Library | Lucide React |
| Style | Outline, 2px stroke |
| Size (inline) | 14-16px |
| Size (UI) | 18-20px |
| Size (emphasis) | 24px |
| Default color | currentColor (inherits text) |
| Interactive | Opacity change on hover |
Usage Rules
- Icons accompany text, rarely standalone
- Use consistent sizing within a component
- Match icon weight to surrounding text weight
- Don't use icons purely for decoration
---
Signature Elements
Glass Card
The defining UI pattern for Dynamous. Frosted glass effect over dark backgrounds.
Use for:
- Content cards
- Video containers
- Feature highlights
- Testimonials
Do NOT use for:
- Buttons (too subtle)
- Navigation
- Form inputs
Implementation:
.glass-card {
background: rgba(0, 0, 0, 0.4);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
}Blue Glow
Signature emphasis effect. Creates a soft halo around important elements.
Use for:
- Hero text highlights
- Primary buttons
- Featured content
- The logo in hero sections
Rule: Use sparingly. If everything glows, nothing does.
Implementation:
.blue-glow {
box-shadow: 0 0 15px rgba(59, 130, 246, 0.5),
0 0 30px rgba(59, 130, 246, 0.3);
}
.text-glow {
text-shadow: 0 0 10px rgba(59, 130, 246, 0.5),
0 0 20px rgba(59, 130, 246, 0.3);
}Grid Pattern
Subtle background texture that adds depth without distraction.
Use only on: Hero sections, large empty backgrounds
Implementation:
.grid-pattern {
background-image:
linear-gradient(to right, rgba(99, 102, 241, 0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(99, 102, 241, 0.05) 1px, transparent 1px);
background-size: 40px 40px;
}---
Diagrams (Excalidraw)
Color Palette for Diagrams
| Semantic Purpose | Fill | Stroke |
|---|---|---|
| Primary/Neutral | #3B82F6 | #1E3A5F |
| Secondary | #60A5FA | #1E3A5F |
| Tertiary/AI | #DBEAFE | #0EA5E9 |
| Start/Trigger | #FED7AA | #C2410C |
| End/Success | #A7F3D0 | #047857 |
| Warning/Reset | #FEE2E2 | #DC2626 |
| Decision | #FEF3C7 | #B45309 |
Diagram Rules
- Background: White (
#FFFFFF) for maximum readability - Text color:
#1E3A5F(deep blue) - Font: Virgil (Excalidraw default) or Hand-drawn style
- Stroke width: 2px
- Roughness: 1 (slight hand-drawn feel)
- Rule: Always pair darker stroke with lighter fill
Shape Meaning
| Concept Type | Shape |
|---|---|
| Start, trigger, input | Ellipse |
| End, output, result | Ellipse |
| Decision, condition | Diamond |
| Process, action, step | Rectangle |
| Abstract state, context | Overlapping ellipses (cloud) |
---
YouTube Thumbnails
Specifications
- Dimensions: 1280 × 720px
- Text: 2-5 words maximum
- Font: Montserrat Extra Bold (800) or Inter Black
- Text color: White with dark outline/shadow for readability
- Background: Dark with blue accents, or screenshot-based
Common Patterns
1. GitHub repo style — Screenshot with logo "swoosh" 2. Excalidraw diagram — Workflow visualization 3. You + logos — Personal image surrounded by tech logos 4. Bold text + concept — Large text with supporting visual
Thumbnail Rules
- Face included when possible (increases CTR)
- High contrast text (readable at small sizes)
- Consistent blue accent somewhere in frame
- No more than 5 words of text
- Test readability at mobile size (small thumbnail preview)
---
Image Treatment
Screenshots & UI
- Border radius: 12px
- Border: 1px solid rgba(255, 255, 255, 0.1)
- Shadow:
0 4px 12px -2px rgba(0, 0, 0, 0.3) - Optional: Blue glow on featured screenshots
Photos
- Border radius: 8px or full (for avatars)
- Filters: Slight cool tone to match blue palette
- Backgrounds: Dark preferred, blur if busy
---
CSS Variables Reference
:root {
/* Colors - Primary */
--dynamous-blue: #3B82F6;
--dynamous-dark: #2563EB;
--dynamous-light: #60A5FA;
--dynamous-cyan: #0EA5E9;
--dynamous-pale: #DBEAFE;
/* Colors - Semantic */
--success: #047857;
--success-bg: #A7F3D0;
--warning: #B45309;
--warning-bg: #FEF3C7;
--error: #B91C1C;
--error-bg: #FECACA;
--ai-cyan: #0EA5E9;
--ai-cyan-bg: #DBEAFE;
/* Colors - Theme (Dark) */
--background: #07090F;
--background-alt: #080A13;
--surface: rgba(0, 0, 0, 0.4);
--border: rgba(255, 255, 255, 0.1);
--text-primary: rgba(255, 255, 255, 0.98);
--text-secondary: rgba(255, 255, 255, 0.8);
--text-muted: rgba(255, 255, 255, 0.7);
/* Spacing */
--space-xs: 4px;
--space-sm: 8px;
--space-md: 12px;
--space-base: 16px;
--space-lg: 24px;
--space-xl: 32px;
--space-2xl: 48px;
--space-3xl: 64px;
/* Typography */
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
--font-display: 'Montserrat', var(--font-sans);
/* Motion */
--duration-micro: 150ms;
--duration-fast: 200ms;
--duration-normal: 300ms;
--duration-slow: 600ms;
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0, 1, 1);
/* Radii */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-full: 9999px;
}---
Quick Reference
Dynamous Blue vs Other Blues
| Dynamous Blue | Other Blues |
|---|---|
| Primary buttons | Never |
| Links | - |
| Logo | - |
| Accent glows | Secondary accents use semantic colors |
| Hero highlights | Diagram fills use palette system |
| Featured elements | - |
Inter vs Montserrat
| Inter | Montserrat |
|---|---|
| All UI text | YouTube thumbnail text |
| Body copy | Bold headlines (optional) |
| Buttons | - |
| Navigation | - |
| Everything else | Only when maximum impact needed |
---
Last updated: 2026-01-13
{
"name": "Dynamous",
"description": "AI education content, community, and products with a modern dark aesthetic",
"colors": {
"background": "07090F",
"background_alt": "080A13",
"text": "FAFAFA",
"text_secondary": "CCCCCC",
"accent": "3B82F6",
"accent_secondary": "60A5FA",
"accent_tertiary": "0EA5E9",
"code_bg": "0A0C12",
"card_bg": "0D1117",
"card_bg_alt": "161B22"
},
"fonts": {
"heading": "Inter",
"body": "Inter",
"code": "JetBrains Mono"
},
"assets": {
"logo": "DynamousLogo.png",
"logo_dark": null,
"icon": null
}
}
{
"output": {
"directory": "Dynamous/Content-Ideation/Presentations",
"naming": "{name}",
"keep_parts": false
},
"generation": {
"slides_per_batch": 5,
"auto_combine": true,
"open_after_generate": false
},
"defaults": {
"slide_width_inches": 13.333,
"slide_height_inches": 7.5
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamous Design System</title>
<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=Inter:wght@400;500;600;700;800;900&family=Montserrat:wght@700;800;900&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
/* ========================================
CSS VARIABLES
======================================== */
:root {
/* Colors - Primary */
--dynamous-blue: #3B82F6;
--dynamous-dark: #2563EB;
--dynamous-light: #60A5FA;
--dynamous-pale: #DBEAFE;
/* Colors - Semantic */
--success: #047857;
--success-bg: #A7F3D0;
--warning: #B45309;
--warning-bg: #FEF3C7;
--error: #B91C1C;
--error-bg: #FECACA;
--ai-purple: #6D28D9;
--ai-purple-bg: #DDD6FE;
--trigger-orange: #C2410C;
--trigger-bg: #FED7AA;
/* Colors - Theme (Dark) */
--background: #07090F;
--background-alt: #080A13;
--surface: rgba(0, 0, 0, 0.4);
--border: rgba(255, 255, 255, 0.1);
--text-primary: rgba(255, 255, 255, 0.98);
--text-secondary: rgba(255, 255, 255, 0.8);
--text-muted: rgba(255, 255, 255, 0.7);
/* Colors - Diagram */
--diagram-stroke: #1E3A5F;
--diagram-fill: #3B82F6;
--diagram-secondary: #60A5FA;
/* Spacing */
--space-xs: 4px;
--space-sm: 8px;
--space-md: 12px;
--space-base: 16px;
--space-lg: 24px;
--space-xl: 32px;
--space-2xl: 48px;
--space-3xl: 64px;
/* Typography */
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
--font-display: 'Montserrat', var(--font-sans);
/* Motion */
--duration-micro: 150ms;
--duration-fast: 200ms;
--duration-normal: 300ms;
--duration-slow: 600ms;
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0, 1, 1);
/* Radii */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-full: 9999px;
}
/* ========================================
BASE STYLES
======================================== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: var(--font-sans);
background: #07090F;
color: var(--text-primary);
line-height: 1.6;
min-height: 100vh;
}
/* ========================================
LAYOUT
======================================== */
.container {
max-width: 1200px;
margin: 0 auto;
padding: var(--space-xl);
}
.header {
text-align: center;
padding: var(--space-3xl) var(--space-xl);
border-bottom: 1px solid var(--border);
margin-bottom: var(--space-3xl);
}
.header h1 {
font-size: 3rem;
font-weight: 700;
margin-bottom: var(--space-base);
}
.header .subtitle {
color: var(--text-secondary);
font-size: 1.125rem;
}
.logo-display {
width: 80px;
height: 80px;
margin: 0 auto var(--space-lg);
}
.logo-display img {
width: 100%;
height: 100%;
object-fit: contain;
}
/* Navigation */
.nav {
position: sticky;
top: 0;
background: rgba(7, 9, 15, 0.9);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
z-index: 100;
padding: var(--space-base) var(--space-xl);
}
.nav-inner {
max-width: 1200px;
margin: 0 auto;
display: flex;
gap: var(--space-lg);
flex-wrap: wrap;
justify-content: center;
}
.nav a {
color: var(--text-secondary);
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
transition: color var(--duration-fast) var(--ease-out);
}
.nav a:hover {
color: var(--dynamous-blue);
}
/* Sections */
.section {
margin-bottom: var(--space-3xl);
padding-bottom: var(--space-3xl);
border-bottom: 1px solid var(--border);
}
.section:last-child {
border-bottom: none;
}
.section-title {
font-size: 1.875rem;
font-weight: 700;
margin-bottom: var(--space-lg);
display: flex;
align-items: center;
gap: var(--space-sm);
}
.section-title::before {
content: '';
width: 4px;
height: 1.5em;
background: var(--dynamous-blue);
border-radius: 2px;
}
.subsection {
margin-bottom: var(--space-2xl);
}
.subsection-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: var(--space-base);
color: var(--text-secondary);
}
.description {
color: var(--text-muted);
font-size: 0.875rem;
margin-bottom: var(--space-base);
}
/* ========================================
COLOR SWATCHES
======================================== */
.color-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: var(--space-base);
}
.color-swatch {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
overflow: hidden;
cursor: pointer;
transition: transform var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.color-swatch:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.color-preview {
height: 100px;
display: flex;
align-items: center;
justify-content: center;
}
.color-info {
padding: var(--space-base);
background: rgba(0, 0, 0, 0.3);
}
.color-name {
font-weight: 600;
margin-bottom: var(--space-xs);
}
.color-hex {
font-family: var(--font-mono);
font-size: 0.875rem;
color: var(--text-muted);
}
.color-var {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
margin-top: var(--space-xs);
}
/* Semantic colors with stroke */
.color-preview.color-semantic {
display: flex;
gap: 2px;
align-items: stretch;
justify-content: stretch;
padding: 0;
}
.color-semantic .fill {
flex: 2;
}
.color-semantic .stroke {
flex: 1;
}
/* ========================================
TYPOGRAPHY
======================================== */
.type-scale {
display: flex;
flex-direction: column;
gap: var(--space-lg);
}
.type-sample {
display: flex;
align-items: baseline;
gap: var(--space-xl);
padding: var(--space-base);
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-md);
}
.type-label {
flex-shrink: 0;
width: 80px;
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--dynamous-blue);
}
.type-size {
flex-shrink: 0;
width: 80px;
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
}
.type-text {
flex: 1;
}
.type-xs { font-size: 0.75rem; }
.type-sm { font-size: 0.875rem; }
.type-base { font-size: 1rem; }
.type-lg { font-size: 1.125rem; }
.type-xl { font-size: 1.25rem; }
.type-2xl { font-size: 1.5rem; }
.type-3xl { font-size: 1.875rem; }
.type-4xl { font-size: 2.25rem; }
.type-5xl { font-size: 3rem; }
.type-6xl { font-size: 3.75rem; }
.font-inter { font-family: var(--font-sans); }
.font-montserrat { font-family: var(--font-display); }
.font-mono { font-family: var(--font-mono); }
.weight-400 { font-weight: 400; }
.weight-500 { font-weight: 500; }
.weight-600 { font-weight: 600; }
.weight-700 { font-weight: 700; }
.weight-800 { font-weight: 800; }
/* Text colors */
.text-colors {
display: flex;
flex-direction: column;
gap: var(--space-sm);
padding: var(--space-lg);
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
}
.text-primary-demo { color: var(--text-primary); }
.text-secondary-demo { color: var(--text-secondary); }
.text-muted-demo { color: var(--text-muted); }
.text-link-demo { color: var(--dynamous-blue); }
/* ========================================
BUTTONS
======================================== */
.button-grid {
display: flex;
flex-wrap: wrap;
gap: var(--space-base);
align-items: center;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-sm);
font-family: var(--font-sans);
font-weight: 500;
border-radius: var(--radius-md);
border: none;
cursor: pointer;
transition: all var(--duration-fast) var(--ease-out);
position: relative;
overflow: hidden;
}
.btn::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
transform: translateX(-100%);
transition: transform 0.5s ease;
}
.btn:hover::before {
transform: translateX(100%);
}
/* Button Sizes */
.btn-sm {
font-size: 0.75rem;
padding: 6px 12px;
}
.btn-md {
font-size: 0.875rem;
padding: 8px 16px;
}
.btn-lg {
font-size: 1rem;
padding: 12px 24px;
}
/* Button Variants */
.btn-primary {
background: var(--dynamous-blue);
color: white;
box-shadow: 0 4px 14px -4px rgba(59, 130, 246, 0.4);
}
.btn-primary:hover {
background: var(--dynamous-dark);
box-shadow: 0 6px 20px -4px rgba(59, 130, 246, 0.5);
transform: translateY(-1px);
}
.btn-secondary {
background: rgba(255, 255, 255, 0.1);
color: white;
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.15);
}
.btn-outline {
background: transparent;
color: white;
border: 1px solid rgba(59, 130, 246, 0.5);
}
.btn-outline:hover {
background: rgba(59, 130, 246, 0.1);
border-color: var(--dynamous-blue);
}
.btn-ghost {
background: transparent;
color: white;
}
.btn-ghost:hover {
background: rgba(255, 255, 255, 0.05);
}
/* ========================================
SPACING
======================================== */
.spacing-grid {
display: flex;
flex-direction: column;
gap: var(--space-base);
}
.spacing-item {
display: flex;
align-items: center;
gap: var(--space-lg);
}
.spacing-label {
width: 60px;
font-family: var(--font-mono);
font-size: 0.875rem;
color: var(--dynamous-blue);
}
.spacing-value {
width: 50px;
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
}
.spacing-bar {
height: 24px;
background: var(--dynamous-blue);
border-radius: var(--radius-sm);
opacity: 0.7;
}
/* ========================================
BORDER RADIUS
======================================== */
.radius-grid {
display: flex;
flex-wrap: wrap;
gap: var(--space-lg);
}
.radius-item {
text-align: center;
}
.radius-preview {
width: 80px;
height: 80px;
background: var(--dynamous-blue);
margin-bottom: var(--space-sm);
}
.radius-label {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
}
/* ========================================
GLASS CARDS
======================================== */
.glass-demo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: var(--space-lg);
}
.glass-card {
background: rgba(0, 0, 0, 0.4);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: var(--radius-lg);
padding: var(--space-xl);
}
.glass-card-title {
font-size: 1.25rem;
font-weight: 600;
margin-bottom: var(--space-sm);
}
.glass-card-text {
color: var(--text-secondary);
font-size: 0.875rem;
}
/* ========================================
GLOW EFFECTS
======================================== */
.glow-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: var(--space-xl);
}
.glow-demo {
padding: var(--space-xl);
border-radius: var(--radius-lg);
text-align: center;
}
.blue-glow {
box-shadow: 0 0 15px rgba(59, 130, 246, 0.5), 0 0 30px rgba(59, 130, 246, 0.3);
background: var(--surface);
border: 1px solid var(--border);
}
.text-glow {
text-shadow: 0 0 10px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.3);
}
.glow-demo-title {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: var(--space-sm);
}
.glow-demo-label {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
}
/* ========================================
ANIMATIONS
======================================== */
.animation-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--space-lg);
}
.animation-demo {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: var(--space-xl);
text-align: center;
}
.animation-box {
width: 60px;
height: 60px;
background: var(--dynamous-blue);
border-radius: var(--radius-md);
margin: 0 auto var(--space-base);
}
.animation-label {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--text-muted);
}
/* Float animation */
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.animate-float {
animation: float 6s ease-in-out infinite;
}
/* Fade in */
@keyframes fade-in {
0% { opacity: 0; transform: translateY(10px); }
100% { opacity: 1; transform: translateY(0); }
}
.animate-fade-in {
animation: fade-in 0.6s ease-out forwards;
}
/* Glow pulse */
@keyframes glow-pulse {
0%, 100% { box-shadow: 0 0 5px rgba(59, 130, 246, 0.5); }
50% { box-shadow: 0 0 20px rgba(59, 130, 246, 0.8); }
}
.animate-glow {
animation: glow-pulse 2s ease-in-out infinite;
}
/* Shimmer */
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.animate-shimmer {
background: linear-gradient(90deg, var(--dynamous-blue) 0%, var(--dynamous-light) 50%, var(--dynamous-blue) 100%);
background-size: 200% 100%;
animation: shimmer 2s linear infinite;
}
/* ========================================
DIAGRAM COLORS
======================================== */
.diagram-color-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: var(--space-base);
}
.diagram-swatch {
border-radius: var(--radius-md);
overflow: hidden;
border: 2px solid;
}
.diagram-fill {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
font-size: 0.875rem;
}
.diagram-info {
padding: var(--space-sm);
background: rgba(0, 0, 0, 0.5);
}
.diagram-label {
font-size: 0.75rem;
font-weight: 600;
margin-bottom: var(--space-xs);
}
.diagram-codes {
font-family: var(--font-mono);
font-size: 0.625rem;
color: var(--text-muted);
}
/* ========================================
FORM INPUTS
======================================== */
.input-grid {
display: flex;
flex-direction: column;
gap: var(--space-base);
max-width: 400px;
}
.input {
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: var(--space-md) var(--space-base);
color: var(--text-primary);
font-family: var(--font-sans);
font-size: 1rem;
transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.input:focus {
outline: none;
border-color: var(--dynamous-blue);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}
.input::placeholder {
color: var(--text-muted);
}
.input-label {
font-size: 0.875rem;
font-weight: 500;
margin-bottom: var(--space-xs);
}
/* ========================================
THUMBNAIL PREVIEW
======================================== */
.thumbnail-preview {
aspect-ratio: 16/9;
max-width: 640px;
background: linear-gradient(135deg, var(--background) 0%, rgba(30, 58, 138, 0.3) 100%);
border-radius: var(--radius-lg);
border: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.thumbnail-text {
font-family: var(--font-display);
font-weight: 800;
font-size: 3rem;
color: white;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5), 0 0 20px rgba(59, 130, 246, 0.5);
text-align: center;
padding: var(--space-xl);
}
.thumbnail-glow {
position: absolute;
width: 200px;
height: 200px;
background: var(--dynamous-blue);
filter: blur(80px);
opacity: 0.3;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* ========================================
CODE BLOCKS
======================================== */
.code-block {
background: rgba(0, 0, 0, 0.5);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: var(--space-base);
font-family: var(--font-mono);
font-size: 0.8125rem;
overflow-x: auto;
position: relative;
}
.code-block code {
color: var(--text-secondary);
}
.code-block .keyword { color: var(--dynamous-light); }
.code-block .property { color: #A7F3D0; }
.code-block .value { color: #FED7AA; }
.code-block .comment { color: var(--text-muted); }
.copy-btn {
position: absolute;
top: var(--space-sm);
right: var(--space-sm);
background: rgba(255, 255, 255, 0.1);
border: none;
border-radius: var(--radius-sm);
padding: var(--space-xs) var(--space-sm);
color: var(--text-muted);
font-size: 0.75rem;
cursor: pointer;
transition: all var(--duration-fast) var(--ease-out);
}
.copy-btn:hover {
background: rgba(255, 255, 255, 0.2);
color: var(--text-primary);
}
/* ========================================
UTILITIES
======================================== */
.flex { display: flex; }
.flex-wrap { flex-wrap: wrap; }
.gap-sm { gap: var(--space-sm); }
.gap-base { gap: var(--space-base); }
.gap-lg { gap: var(--space-lg); }
.items-center { align-items: center; }
.grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-lg);
}
@media (max-width: 768px) {
.grid-2 {
grid-template-columns: 1fr;
}
}
/* Toast notification */
.toast {
position: fixed;
bottom: var(--space-xl);
right: var(--space-xl);
background: var(--dynamous-blue);
color: white;
padding: var(--space-md) var(--space-lg);
border-radius: var(--radius-md);
font-size: 0.875rem;
font-weight: 500;
transform: translateY(100px);
opacity: 0;
transition: all var(--duration-normal) var(--ease-out);
z-index: 1000;
}
.toast.show {
transform: translateY(0);
opacity: 1;
}
/* ========================================
SCROLLBAR
======================================== */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: var(--background);
}
::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.3);
}
</style>
</head>
<body>
<!-- Navigation -->
<nav class="nav">
<div class="nav-inner">
<a href="#colors">Colors</a>
<a href="#typography">Typography</a>
<a href="#buttons">Buttons</a>
<a href="#spacing">Spacing</a>
<a href="#radius">Border Radius</a>
<a href="#glass">Glass Cards</a>
<a href="#glows">Glow Effects</a>
<a href="#animations">Animations</a>
<a href="#inputs">Inputs</a>
<a href="#diagrams">Diagram Colors</a>
<a href="#thumbnails">Thumbnails</a>
<a href="#css">CSS Variables</a>
</div>
</nav>
<div class="container">
<!-- Header -->
<header class="header">
<div class="logo-display">
<img src="DynamousLogo.png" alt="Dynamous Logo">
</div>
<h1>Dynamous <span class="text-glow" style="color: var(--dynamous-blue);">Design System</span></h1>
<p class="subtitle">A complete visual reference for AI education content, community, and products.</p>
</header>
<!-- Colors Section -->
<section class="section" id="colors">
<h2 class="section-title">Colors</h2>
<div class="subsection">
<h3 class="subsection-title">Primary — Dynamous Blue</h3>
<p class="description">The signature brand color. Click any swatch to copy the hex code.</p>
<div class="color-grid">
<div class="color-swatch" onclick="copyToClipboard('#3B82F6', this)">
<div class="color-preview" style="background: #3B82F6;"></div>
<div class="color-info">
<div class="color-name">Dynamous Blue</div>
<div class="color-hex">#3B82F6</div>
<div class="color-var">--dynamous-blue</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#2563EB', this)">
<div class="color-preview" style="background: #2563EB;"></div>
<div class="color-info">
<div class="color-name">Dynamous Dark</div>
<div class="color-hex">#2563EB</div>
<div class="color-var">--dynamous-dark</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#60A5FA', this)">
<div class="color-preview" style="background: #60A5FA;"></div>
<div class="color-info">
<div class="color-name">Dynamous Light</div>
<div class="color-hex">#60A5FA</div>
<div class="color-var">--dynamous-light</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#DBEAFE', this)">
<div class="color-preview" style="background: #DBEAFE;"></div>
<div class="color-info">
<div class="color-name">Dynamous Pale</div>
<div class="color-hex">#DBEAFE</div>
<div class="color-var">--dynamous-pale</div>
</div>
</div>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">Semantic Colors</h3>
<p class="description">Used for specific purposes: success, warning, error, AI elements.</p>
<div class="color-grid">
<div class="color-swatch" onclick="copyToClipboard('#A7F3D0', this)">
<div class="color-preview color-semantic">
<div class="fill" style="background: #A7F3D0;"></div>
<div class="stroke" style="background: #047857;"></div>
</div>
<div class="color-info">
<div class="color-name">Success</div>
<div class="color-hex">Fill: #A7F3D0 | Stroke: #047857</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#FEF3C7', this)">
<div class="color-preview color-semantic">
<div class="fill" style="background: #FEF3C7;"></div>
<div class="stroke" style="background: #B45309;"></div>
</div>
<div class="color-info">
<div class="color-name">Warning</div>
<div class="color-hex">Fill: #FEF3C7 | Stroke: #B45309</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#FECACA', this)">
<div class="color-preview color-semantic">
<div class="fill" style="background: #FECACA;"></div>
<div class="stroke" style="background: #B91C1C;"></div>
</div>
<div class="color-info">
<div class="color-name">Error</div>
<div class="color-hex">Fill: #FECACA | Stroke: #B91C1C</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#DDD6FE', this)">
<div class="color-preview color-semantic">
<div class="fill" style="background: #DDD6FE;"></div>
<div class="stroke" style="background: #6D28D9;"></div>
</div>
<div class="color-info">
<div class="color-name">AI / LLM</div>
<div class="color-hex">Fill: #DDD6FE | Stroke: #6D28D9</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#FED7AA', this)">
<div class="color-preview color-semantic">
<div class="fill" style="background: #FED7AA;"></div>
<div class="stroke" style="background: #C2410C;"></div>
</div>
<div class="color-info">
<div class="color-name">Trigger / Input</div>
<div class="color-hex">Fill: #FED7AA | Stroke: #C2410C</div>
</div>
</div>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">Dark Theme</h3>
<p class="description">Background, surface, and text colors for the dark theme.</p>
<div class="color-grid">
<div class="color-swatch" onclick="copyToClipboard('#07090F', this)">
<div class="color-preview" style="background: #07090F; border: 1px solid rgba(255,255,255,0.1);"></div>
<div class="color-info">
<div class="color-name">Background</div>
<div class="color-hex">#07090F</div>
<div class="color-var">--background</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('#080A13', this)">
<div class="color-preview" style="background: #080A13; border: 1px solid rgba(255,255,255,0.1);"></div>
<div class="color-info">
<div class="color-name">Background Alt</div>
<div class="color-hex">#080A13</div>
<div class="color-var">--background-alt</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('rgba(0, 0, 0, 0.4)', this)">
<div class="color-preview" style="background: rgba(0, 0, 0, 0.4); border: 1px solid rgba(255,255,255,0.1);"></div>
<div class="color-info">
<div class="color-name">Surface</div>
<div class="color-hex">rgba(0, 0, 0, 0.4)</div>
<div class="color-var">--surface</div>
</div>
</div>
<div class="color-swatch" onclick="copyToClipboard('rgba(255, 255, 255, 0.1)', this)">
<div class="color-preview" style="background: linear-gradient(to right, #07090F 49%, rgba(255,255,255,0.3) 50%);"></div>
<div class="color-info">
<div class="color-name">Border</div>
<div class="color-hex">rgba(255, 255, 255, 0.1)</div>
<div class="color-var">--border</div>
</div>
</div>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">Text Colors</h3>
<div class="text-colors">
<p class="text-primary-demo"><strong>Primary (98%)</strong> — Main headings and emphasis</p>
<p class="text-secondary-demo"><strong>Secondary (80%)</strong> — Body text and descriptions</p>
<p class="text-muted-demo"><strong>Muted (70%)</strong> — Meta info, timestamps, labels</p>
<p class="text-link-demo"><strong>Link (Dynamous Blue)</strong> — Interactive text elements</p>
</div>
</div>
</section>
<!-- Typography Section -->
<section class="section" id="typography">
<h2 class="section-title">Typography</h2>
<div class="subsection">
<h3 class="subsection-title">Font Families</h3>
<div class="type-scale">
<div class="type-sample">
<span class="type-label">Inter</span>
<span class="type-size">Primary</span>
<span class="type-text font-inter type-xl">The quick brown fox jumps over the lazy dog.</span>
</div>
<div class="type-sample">
<span class="type-label">Montserrat</span>
<span class="type-size">Display</span>
<span class="type-text font-montserrat weight-800 type-xl">THE QUICK BROWN FOX JUMPS</span>
</div>
<div class="type-sample">
<span class="type-label">JetBrains</span>
<span class="type-size">Mono</span>
<span class="type-text font-mono type-base">const agent = new AIAgent({ model: 'claude-sonnet' });</span>
</div>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">Type Scale</h3>
<div class="type-scale">
<div class="type-sample">
<span class="type-label">6xl</span>
<span class="type-size">3.75rem</span>
<span class="type-text type-6xl weight-700">Hero Display</span>
</div>
<div class="type-sample">
<span class="type-label">5xl</span>
<span class="type-size">3rem</span>
<span class="type-text type-5xl weight-700">Hero Mobile</span>
</div>
<div class="type-sample">
<span class="type-label">4xl</span>
<span class="type-size">2.25rem</span>
<span class="type-text type-4xl weight-700">Hero Subheading</span>
</div>
<div class="type-sample">
<span class="type-label">3xl</span>
<span class="type-size">1.875rem</span>
<span class="type-text type-3xl weight-700">Page Headers</span>
</div>
<div class="type-sample">
<span class="type-label">2xl</span>
<span class="type-size">1.5rem</span>
<span class="type-text type-2xl weight-600">Card Titles</span>
</div>
<div class="type-sample">
<span class="type-label">xl</span>
<span class="type-size">1.25rem</span>
<span class="type-text type-xl weight-600">Section Headers</span>
</div>
<div class="type-sample">
<span class="type-label">lg</span>
<span class="type-size">1.125rem</span>
<span class="type-text type-lg">Lead paragraphs and emphasis</span>
</div>
<div class="type-sample">
<span class="type-label">base</span>
<span class="type-size">1rem</span>
<span class="type-text type-base">Body text for paragraphs and content.</span>
</div>
<div class="type-sample">
<span class="type-label">sm</span>
<span class="type-size">0.875rem</span>
<span class="type-text type-sm" style="color: var(--text-secondary);">Secondary text and descriptions</span>
</div>
<div class="type-sample">
<span class="type-label">xs</span>
<span class="type-size">0.75rem</span>
<span class="type-text type-xs" style="color: var(--text-muted);">Labels, badges, and meta information</span>
</div>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">Font Weights</h3>
<div class="type-scale">
<div class="type-sample">
<span class="type-label">400</span>
<span class="type-size">Regular</span>
<span class="type-text type-lg weight-400">Body text and paragraphs</span>
</div>
<div class="type-sample">
<span class="type-label">500</span>
<span class="type-size">Medium</span>
<span class="type-text type-lg weight-500">Buttons and labels</span>
</div>
<div class="type-sample">
<span class="type-label">600</span>
<span class="type-size">Semibold</span>
<span class="type-text type-lg weight-600">Subheadings and emphasis</span>
</div>
<div class="type-sample">
<span class="type-label">700</span>
<span class="type-size">Bold</span>
<span class="type-text type-lg weight-700">Headings and titles</span>
</div>
<div class="type-sample">
<span class="type-label">800</span>
<span class="type-size">Extra Bold</span>
<span class="type-text type-lg weight-800 font-montserrat">Thumbnails and display</span>
</div>
</div>
</div>
</section>
<!-- Buttons Section -->
<section class="section" id="buttons">
<h2 class="section-title">Buttons</h2>
<div class="subsection">
<h3 class="subsection-title">Button Variants</h3>
<div class="button-grid">
<button class="btn btn-primary btn-md">Primary</button>
<button class="btn btn-secondary btn-md">Secondary</button>
<button class="btn btn-outline btn-md">Outline</button>
<button class="btn btn-ghost btn-md">Ghost</button>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">Button Sizes</h3>
<div class="button-grid">
<button class="btn btn-primary btn-sm">Small</button>
<button class="btn btn-primary btn-md">Medium</button>
<button class="btn btn-primary btn-lg">Large</button>
</div>
</div>
<div class="subsection">
<h3 class="subsection-title">With Icons</h3>
<div class="button-grid">
<button class="btn btn-primary btn-md">
Get Started
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
</button>
<button class="btn btn-outline btn-md">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
Watch Demo
</button>
</div>
</div>
</section>
<!-- Spacing Section -->
<section class="section" id="spacing">
<h2 class="section-title">Spacing</h2>
<p class="description">Base unit: 4px. All spacing is a multiple of the base.</p>
<div class="spacing-grid">
<div class="spacing-item">
<span class="spacing-label">xs</span>
<span class="spacing-value">4px</span>
<div class="spacing-bar" style="width: 4px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">sm</span>
<span class="spacing-value">8px</span>
<div class="spacing-bar" style="width: 8px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">md</span>
<span class="spacing-value">12px</span>
<div class="spacing-bar" style="width: 12px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">base</span>
<span class="spacing-value">16px</span>
<div class="spacing-bar" style="width: 16px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">lg</span>
<span class="spacing-value">24px</span>
<div class="spacing-bar" style="width: 24px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">xl</span>
<span class="spacing-value">32px</span>
<div class="spacing-bar" style="width: 32px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">2xl</span>
<span class="spacing-value">48px</span>
<div class="spacing-bar" style="width: 48px;"></div>
</div>
<div class="spacing-item">
<span class="spacing-label">3xl</span>
<span class="spacing-value">64px</span>
<div class="spacing-bar" style="width: 64px;"></div>
</div>
</div>
</section>
<!-- Border Radius Section -->
<section class="section" id="radius">
<h2 class="section-title">Border Radius</h2>
<div class="radius-grid">
<div class="radius-item">
<div class="radius-preview" style="border-radius: 4px;"></div>
<div class="radius-label">sm (4px)</div>
</div>
<div class="radius-item">
<div class="radius-preview" style="border-radius: 8px;"></div>
<div class="radius-label">md (8px)</div>
</div>
<div class="radius-item">
<div class="radius-preview" style="border-radius: 12px;"></div>
<div class="radius-label">lg (12px)</div>
</div>
<div class="radius-item">
<div class="radius-preview" style="border-radius: 16px;"></div>
<div class="radius-label">xl (16px)</div>
</div>
<div class="radius-item">
<div class="radius-preview" style="border-radius: 9999px;"></div>
<div class="radius-label">full (pill)</div>
</div>
</div>
</section>
<!-- Glass Cards Section -->
<section class="section" id="glass">
<h2 class="section-title">Glass Cards</h2>
<p class="description">The signature UI pattern for Dynamous. Frosted glass effect over dark backgrounds.</p>
<div class="glass-demo-grid">
<div class="glass-card">
<h3 class="glass-card-title">Default Glass Card</h3>
<p class="glass-card-text">Background: rgba(0, 0, 0, 0.4)<br>Backdrop blur: 16px<br>Border: rgba(255, 255, 255, 0.1)<br>Border radius: 12px</p>
</div>
<div class="glass-card" style="border-color: var(--dynamous-blue); box-shadow: 0 0 20px rgba(59, 130, 246, 0.2);">
<h3 class="glass-card-title">Highlighted Card</h3>
<p class="glass-card-text">Same base with blue border and subtle glow for emphasis.</p>
</div>
<div class="glass-card" style="border-color: rgba(74, 222, 128, 0.3);">
<h3 class="glass-card-title" style="color: #4ADE80;">Announcement Card</h3>
<p class="glass-card-text">Green border variant for announcements and success states.</p>
</div>
</div>
<div class="subsection" style="margin-top: var(--space-xl);">
<h3 class="subsection-title">CSS Implementation</h3>
<div class="code-block">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<code><span class="keyword">.glass-card</span> {
<span class="property">background</span>: <span class="value">rgba(0, 0, 0, 0.4)</span>;
<span class="property">backdrop-filter</span>: <span class="value">blur(16px)</span>;
<span class="property">-webkit-backdrop-filter</span>: <span class="value">blur(16px)</span>;
<span class="property">border</span>: <span class="value">1px solid rgba(255, 255, 255, 0.1)</span>;
<span class="property">border-radius</span>: <span class="value">12px</span>;
}</code>
</div>
</div>
</section>
<!-- Glow Effects Section -->
<section class="section" id="glows">
<h2 class="section-title">Glow Effects</h2>
<p class="description">Signature emphasis effects. Use sparingly — if everything glows, nothing does.</p>
<div class="glow-grid">
<div class="glow-demo blue-glow">
<div class="glow-demo-title">Box Glow</div>
<div class="glow-demo-label">box-shadow: 0 0 15px rgba(59, 130, 246, 0.5)</div>
</div>
<div class="glow-demo" style="background: var(--surface); border: 1px solid var(--border);">
<div class="glow-demo-title text-glow" style="color: var(--dynamous-blue);">Text Glow</div>
<div class="glow-demo-label">text-shadow: 0 0 10px rgba(59, 130, 246, 0.5)</div>
</div>
<div class="glow-demo" style="background: var(--surface); border: 1px solid var(--border);">
<div class="glow-demo-title" style="color: var(--dynamous-blue);">Combined</div>
<div class="glow-demo-label">
<span class="text-glow" style="color: var(--dynamous-blue);">Text</span> +
<span style="display: inline-block; padding: 2px 8px; border-radius: 4px;" class="blue-glow">Box</span>
</div>
</div>
</div>
<div class="subsection" style="margin-top: var(--space-xl);">
<h3 class="subsection-title">CSS Implementation</h3>
<div class="code-block">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<code><span class="keyword">.blue-glow</span> {
<span class="property">box-shadow</span>: <span class="value">0 0 15px rgba(59, 130, 246, 0.5),
0 0 30px rgba(59, 130, 246, 0.3)</span>;
}
<span class="keyword">.text-glow</span> {
<span class="property">text-shadow</span>: <span class="value">0 0 10px rgba(59, 130, 246, 0.5),
0 0 20px rgba(59, 130, 246, 0.3)</span>;
}</code>
</div>
</div>
</section>
<!-- Animations Section -->
<section class="section" id="animations">
<h2 class="section-title">Animations</h2>
<p class="description">Hover over each to see the animation. Nothing should take longer than 600ms.</p>
<div class="animation-grid">
<div class="animation-demo">
<div class="animation-box animate-float"></div>
<div class="animation-label">Float (6s infinite)</div>
</div>
<div class="animation-demo">
<div class="animation-box animate-glow"></div>
<div class="animation-label">Glow Pulse (2s infinite)</div>
</div>
<div class="animation-demo">
<div class="animation-box animate-shimmer"></div>
<div class="animation-label">Shimmer (2s infinite)</div>
</div>
<div class="animation-demo" id="fade-demo">
<div class="animation-box" id="fade-box"></div>
<div class="animation-label">Fade In (0.6s) — <a href="javascript:void(0)" onclick="replayFadeIn()" style="color: var(--dynamous-blue);">Replay</a></div>
</div>
</div>
<div class="subsection" style="margin-top: var(--space-xl);">
<h3 class="subsection-title">Timing</h3>
<div class="grid-2">
<div class="code-block">
<code><span class="comment">/* Timing */</span>
<span class="property">--duration-micro</span>: <span class="value">150ms</span>; <span class="comment">/* Button states */</span>
<span class="property">--duration-fast</span>: <span class="value">200ms</span>; <span class="comment">/* Dropdowns */</span>
<span class="property">--duration-normal</span>: <span class="value">300ms</span>; <span class="comment">/* Cards, modals */</span>
<span class="property">--duration-slow</span>: <span class="value">600ms</span>; <span class="comment">/* Page transitions */</span></code>
</div>
<div class="code-block">
<code><span class="comment">/* Easing */</span>
<span class="property">--ease-out</span>: <span class="value">cubic-bezier(0, 0, 0.2, 1)</span>;
<span class="property">--ease-in</span>: <span class="value">cubic-bezier(0.4, 0, 1, 1)</span>;
<span class="comment">/* Never use linear for UI */</span></code>
</div>
</div>
</div>
</section>
<!-- Form Inputs Section -->
<section class="section" id="inputs">
<h2 class="section-title">Form Inputs</h2>
<div class="input-grid">
<div>
<label class="input-label">Default Input</label>
<input type="text" class="input" placeholder="Enter your email...">
</div>
<div>
<label class="input-label">Focused Input</label>
<input type="text" class="input" placeholder="Click to see focus state" style="border-color: var(--dynamous-blue); box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);">
</div>
<div>
<label class="input-label">With Value</label>
<input type="text" class="input" value="hello@dynamous.ai">
</div>
</div>
</section>
<!-- Diagram Colors Section -->
<section class="section" id="diagrams">
<h2 class="section-title">Diagram Colors (Excalidraw)</h2>
<p class="description">Color palette for diagrams. Always pair darker stroke with lighter fill.</p>
<div class="diagram-color-grid">
<div class="diagram-swatch" style="border-color: #1E3A5F;">
<div class="diagram-fill" style="background: #3B82F6; color: white;">Primary</div>
<div class="diagram-info">
<div class="diagram-label">Primary / Neutral</div>
<div class="diagram-codes">Fill: #3B82F6 | Stroke: #1E3A5F</div>
</div>
</div>
<div class="diagram-swatch" style="border-color: #1E3A5F;">
<div class="diagram-fill" style="background: #60A5FA; color: #1E3A5F;">Secondary</div>
<div class="diagram-info">
<div class="diagram-label">Secondary</div>
<div class="diagram-codes">Fill: #60A5FA | Stroke: #1E3A5F</div>
</div>
</div>
<div class="diagram-swatch" style="border-color: #C2410C;">
<div class="diagram-fill" style="background: #FED7AA; color: #C2410C;">Start</div>
<div class="diagram-info">
<div class="diagram-label">Start / Trigger</div>
<div class="diagram-codes">Fill: #FED7AA | Stroke: #C2410C</div>
</div>
</div>
<div class="diagram-swatch" style="border-color: #047857;">
<div class="diagram-fill" style="background: #A7F3D0; color: #047857;">End</div>
<div class="diagram-info">
<div class="diagram-label">End / Success</div>
<div class="diagram-codes">Fill: #A7F3D0 | Stroke: #047857</div>
</div>
</div>
<div class="diagram-swatch" style="border-color: #B45309;">
<div class="diagram-fill" style="background: #FEF3C7; color: #B45309;">Decision</div>
<div class="diagram-info">
<div class="diagram-label">Decision / Warning</div>
<div class="diagram-codes">Fill: #FEF3C7 | Stroke: #B45309</div>
</div>
</div>
<div class="diagram-swatch" style="border-color: #6D28D9;">
<div class="diagram-fill" style="background: #DDD6FE; color: #6D28D9;">AI/LLM</div>
<div class="diagram-info">
<div class="diagram-label">AI / LLM</div>
<div class="diagram-codes">Fill: #DDD6FE | Stroke: #6D28D9</div>
</div>
</div>
<div class="diagram-swatch" style="border-color: #B91C1C;">
<div class="diagram-fill" style="background: #FECACA; color: #B91C1C;">Error</div>
<div class="diagram-info">
<div class="diagram-label">Error / Stop</div>
<div class="diagram-codes">Fill: #FECACA | Stroke: #B91C1C</div>
</div>
</div>
</div>
</section>
<!-- Thumbnail Section -->
<section class="section" id="thumbnails">
<h2 class="section-title">YouTube Thumbnails</h2>
<p class="description">1280×720px. Montserrat Extra Bold. 2-5 words max. High contrast.</p>
<div class="thumbnail-preview">
<div class="thumbnail-glow"></div>
<div class="thumbnail-text">AI AGENTS<br>MADE SIMPLE</div>
</div>
<div class="subsection" style="margin-top: var(--space-xl);">
<h3 class="subsection-title">Thumbnail Text Styles</h3>
<div class="type-scale">
<div class="type-sample" style="background: linear-gradient(135deg, #07090F, #1E3A8A);">
<span class="type-label">Display</span>
<span class="type-size">Bold</span>
<span class="type-text font-montserrat weight-800 type-4xl" style="text-shadow: 0 2px 4px rgba(0,0,0,0.5), 0 0 20px rgba(59,130,246,0.5);">THE COMPLETE GUIDE</span>
</div>
</div>
</div>
</section>
<!-- CSS Variables Section -->
<section class="section" id="css">
<h2 class="section-title">CSS Variables Reference</h2>
<p class="description">Copy this entire block into your project's CSS root.</p>
<div class="code-block" style="max-height: 600px; overflow-y: auto;">
<button class="copy-btn" onclick="copyCode(this)">Copy All</button>
<code><span class="keyword">:root</span> {
<span class="comment">/* Colors - Primary */</span>
<span class="property">--dynamous-blue</span>: <span class="value">#3B82F6</span>;
<span class="property">--dynamous-dark</span>: <span class="value">#2563EB</span>;
<span class="property">--dynamous-light</span>: <span class="value">#60A5FA</span>;
<span class="property">--dynamous-pale</span>: <span class="value">#DBEAFE</span>;
<span class="comment">/* Colors - Semantic */</span>
<span class="property">--success</span>: <span class="value">#047857</span>;
<span class="property">--success-bg</span>: <span class="value">#A7F3D0</span>;
<span class="property">--warning</span>: <span class="value">#B45309</span>;
<span class="property">--warning-bg</span>: <span class="value">#FEF3C7</span>;
<span class="property">--error</span>: <span class="value">#B91C1C</span>;
<span class="property">--error-bg</span>: <span class="value">#FECACA</span>;
<span class="property">--ai-purple</span>: <span class="value">#6D28D9</span>;
<span class="property">--ai-purple-bg</span>: <span class="value">#DDD6FE</span>;
<span class="comment">/* Colors - Theme (Dark) */</span>
<span class="property">--background</span>: <span class="value">#07090F</span>;
<span class="property">--background-alt</span>: <span class="value">#080A13</span>;
<span class="property">--surface</span>: <span class="value">rgba(0, 0, 0, 0.4)</span>;
<span class="property">--border</span>: <span class="value">rgba(255, 255, 255, 0.1)</span>;
<span class="property">--text-primary</span>: <span class="value">rgba(255, 255, 255, 0.98)</span>;
<span class="property">--text-secondary</span>: <span class="value">rgba(255, 255, 255, 0.8)</span>;
<span class="property">--text-muted</span>: <span class="value">rgba(255, 255, 255, 0.7)</span>;
<span class="comment">/* Spacing */</span>
<span class="property">--space-xs</span>: <span class="value">4px</span>;
<span class="property">--space-sm</span>: <span class="value">8px</span>;
<span class="property">--space-md</span>: <span class="value">12px</span>;
<span class="property">--space-base</span>: <span class="value">16px</span>;
<span class="property">--space-lg</span>: <span class="value">24px</span>;
<span class="property">--space-xl</span>: <span class="value">32px</span>;
<span class="property">--space-2xl</span>: <span class="value">48px</span>;
<span class="property">--space-3xl</span>: <span class="value">64px</span>;
<span class="comment">/* Typography */</span>
<span class="property">--font-sans</span>: <span class="value">'Inter', ui-sans-serif, system-ui, sans-serif</span>;
<span class="property">--font-mono</span>: <span class="value">'JetBrains Mono', ui-monospace, monospace</span>;
<span class="property">--font-display</span>: <span class="value">'Montserrat', var(--font-sans)</span>;
<span class="comment">/* Motion */</span>
<span class="property">--duration-micro</span>: <span class="value">150ms</span>;
<span class="property">--duration-fast</span>: <span class="value">200ms</span>;
<span class="property">--duration-normal</span>: <span class="value">300ms</span>;
<span class="property">--duration-slow</span>: <span class="value">600ms</span>;
<span class="property">--ease-out</span>: <span class="value">cubic-bezier(0, 0, 0.2, 1)</span>;
<span class="property">--ease-in</span>: <span class="value">cubic-bezier(0.4, 0, 1, 1)</span>;
<span class="comment">/* Radii */</span>
<span class="property">--radius-sm</span>: <span class="value">4px</span>;
<span class="property">--radius-md</span>: <span class="value">8px</span>;
<span class="property">--radius-lg</span>: <span class="value">12px</span>;
<span class="property">--radius-xl</span>: <span class="value">16px</span>;
<span class="property">--radius-full</span>: <span class="value">9999px</span>;
}</code>
</div>
</section>
</div>
<!-- Toast notification -->
<div class="toast" id="toast">Copied to clipboard!</div>
<script>
// Copy hex code to clipboard
function copyToClipboard(text, element) {
navigator.clipboard.writeText(text).then(() => {
showToast('Copied: ' + text);
});
}
// Copy code block
function copyCode(button) {
const codeBlock = button.parentElement;
const code = codeBlock.querySelector('code').innerText;
navigator.clipboard.writeText(code).then(() => {
showToast('Code copied!');
});
}
// Show toast notification
function showToast(message) {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 2000);
}
// Replay fade-in animation
function replayFadeIn() {
const box = document.getElementById('fade-box');
box.style.animation = 'none';
box.offsetHeight; // Trigger reflow
box.style.animation = 'fade-in 0.6s ease-out forwards';
}
// Initialize fade-in demo
document.addEventListener('DOMContentLoaded', () => {
replayFadeIn();
});
</script>
</body>
</html>
Tone of Voice
How Cole Medin sounds across all content.
---
The Cole Medin Voice
Enthusiastic Expert + Practical Teacher + Humble Builder
Cole's voice is genuinely excited about AI without tipping into hype. He teaches by showing iterations, admits when things don't work, and always grounds advice in what he's actually built. Technical depth delivered with warmth.
---
Voice Signature
Vocabulary Patterns
These words and phrases appear constantly in Cole's natural speech:
Intensifiers:
- "Super" (super easy, super powerful, super excited, super stoked)
- "Really really" (doubled for emphasis)
- "Incredibly" / "Incredible"
- "So stinking easy"
Authenticity Markers:
- "Honestly" / "Honestly think" (before direct statements)
- "I'm gonna be honest" (signaling realness)
- "Here's the deal"
Connectors:
- "So" (extremely common, starts many sentences)
- "And so" (establishing logical flow)
- "So with that" (transitions)
- "Cuz" instead of "because" (informal)
- "Alright" / "All right" (section breaks)
Enthusiasm:
- "The best part is..."
- "I'm super excited about..."
- "If you're not pumped about this, I don't know what to tell you"
- "I cannot wait for this"
- "It's just such a good combination"
Teaching:
- "Let me show you..."
- "That's what we're going to be doing"
- "I'm looking forward to..."
Direct Address:
- "YOU" (often capitalized for emphasis)
- "I want that to be you too"
- "That's why I'm here"
Sentence Structure
- Uses contractions liberally (don't, can't, it's, you're, gonna)
- Short punchy sentences mixed with longer explanatory ones
- Questions to audience: "Ask yourself these questions"
- Exclamation points for genuine excitement (but not excessive)
---
The Formula
Cole's voice draws from three influences, layered together:
Dan Koe's calm confidence
+ Network Chuck's energy and "learning with you" vibe
+ ThePrimeagen's developer credibility and unfiltered honesty
= Cole MedinThis isn't three modes you switch between. It's one voice with layers that are always present.
---
Voice Layers
Layer 1: Dan Koe (The Anchor)
Present in everything. This is the baseline calm confidence.
What this layer contributes:
- Confidence that doesn't need to shout
- Philosophical grounding beneath practical advice
- Making complex ideas feel inevitable, not overwhelming
- A sense that you've thought deeply about this
Sounds like:
"The people who are the most successful are the ones who don't overcomplicate it - and I want that to be you too."
"I will die on that hill."
---
Layer 2: Network Chuck (The Energy)
Makes the calm confidence approachable. Adds warmth and genuine excitement.
What this layer contributes:
- Enthusiasm that's contagious, not performed
- "I'm learning alongside you" energy
- Making technical content feel like a conversation
- Excitement about possibilities without veering into hype
Sounds like:
"But here's where it gets wild. Claude Code is now writing its own codebase. It's literally improving itself."
"Let's get into it!"
"And you heard that right..."
---
Layer 3: ThePrimeagen (The Credibility)
Makes everything honest and real. Developer credibility and willingness to call out BS.
What this layer contributes:
- You've actually built this stuff
- Unfiltered opinions backed by experience
- Humor that's natural, not forced
- Willingness to call out BS when you see it
Sounds like:
"And look, I get it - that's how most of us started."
"I'm gonna be honest, at first I thought he was crazy."
"People tell me it's overwhelming all of the time, but take a deep breath, that's why I'm here."
---
Teaching Methodology
1. Problem-First Framing
Identify pain points before solutions.
"Most agent failures aren't model failures—they're context failures."
"The internet is filled with guides; but the problem is, most of them just get you started with the bare bones."
2. Show Iterations, Not Just Results
Use versioning to show evolution. Don't hide the messy middle.
"Version one we're going to start with this here so I'm not getting right into the meat."
This is a key differentiator from other creators who only show polished end results.
3. Comparative Contrasts
Use contrasts to make concepts stick.
"Context Engineering is 10x better than prompt engineering and 100x better than vibe coding."
"Prompt engineering is like giving someone a sticky note while context engineering is like writing a full screenplay."
4. The "What NOT To" Move
For every concept, explicitly tell them what to ignore. This removes overwhelm.
"What NOT to worry about - picking the perfect LLM - very easy to test different ones later."
"What NOT to focus on - multi-agent systems to handle many tools and specialization."
5. Balance Code AND No-Code
Acknowledge both approaches have their place.
"There's a time and place for each approach."
Recommend proof-of-concept prototypes before production code.
---
Core Belief
Capabilities over tools. Systems over hacks. The right process makes AI work.
You're not teaching people to use AI tools — you're teaching them to build systems that let them delegate to AI while staying in the driver's seat. The tool doesn't matter. The workflow does.
---
Convictions
These aren't predictions. This is what you believe is already true.
You should be able to build a system for AI coding where you can delegate all the coding to agents.
This isn't future speculation - it's happening now. The people who build reliable systems for planning, implementing, and validating are already shipping code they've never manually written. The key is staying in the driver's seat for the thinking, not the typing.
Generative AI is the biggest shift in tech right now.
Not blockchain, not VR, not Web3. This is the magnitude 9 earthquake reshaping how software gets built. If you're a developer and you're not paying attention, you're already falling behind.
Vibe coding doesn't work. You need a systematic approach.
Just prompting and hoping is not a strategy. The people getting real results have processes - they sandwich implementation between planning and validation. Every bug is an opportunity to improve the system, not just fix the code.
The people who are most successful are the ones who don't overcomplicate it.
You can learn 90% of what you need from the fundamentals. The advanced stuff matters later, but most people fail because they're trying to solve problems they don't have yet.
---
The Humble Builder
Cole admits limitations openly. This builds trust and sets him apart from hype creators.
Yes:
"Archon is currently in beta! Expect things to not work 100%."
"I was initially so surprised at how good Claude Code is - it's genuinely changing how I work."
"Some other coding agents have disappointed me. They're just not there yet."
No:
"This tool will 10x your productivity overnight!"
"AI is going to replace all developers."
"Just use [framework] and everything will be easy."
---
Signature Phrases
"And here's the thing"
Transition into a key insight. Used when shifting from setup to substance.
"And here's the thing - he's not alone."
"And here's the thing - it's not about which tool they use."
"But honestly"
Adds authenticity before a direct statement. Signals you're about to be real.
"But honestly you can learn 90% of what you need to know from this video."
"But honestly, I've regretted using them in the past."
"Super [adjective]"
Cole's most distinctive intensifier. Use naturally, not forced.
"It's super easy to get started."
"I'm super stoked about this."
"This is super powerful."
"I've got you covered" / "That's why I'm here"
Reassurance that removes overwhelm.
"People tell me it's overwhelming all of the time, but take a deep breath, that's why I'm here."
"The people who are most successful are the ones who..."
Sets up a principle by pointing to evidence.
"The people who are the most successful are the ones who don't overcomplicate it."
"I want that to be you too"
Direct audience connection. Makes the viewer feel included in the success story.
"No matter what/how you're..."
Universal applicability. Signals the advice works regardless of their situation.
"No matter what software you want to build..."
"No matter how you're building your agents..."
---
What Cole Sounds Like
Real examples from actual content:
Video Announcement:
"Just dropped a new video: Context Engineering 101: The Simple Strategy to 100x AI Coding. Stop relying on vibe coding, start leveraging context engineering with PRPs to build real-world AI coding assistants that scale."
YouTube Intro:
"Not only have I built hundreds of AI agents myself, I've seen other people build thousands of AI agents for every use case under the sun. The people who are the most successful are the ones who don't overcomplicate it - and I want that to be you too."
YouTube Description:
"It's easy to think building AI agents is super complicated, but honestly you can learn 90% of what you need to know from this video. No matter how you're building your agents, I'll show you here what you need to think about, and more importantly what you shouldn't worry about when you're first creating your agent."
Teaching/Explanation:
"AI agents are simply Large Language Models that have been given the ability to interact with the outside world. They can do things like draft emails, book appointments in your CRM, create tasks in task management software, and really anything you can dream of."
Personal/Entrepreneurial:
"My 9-5 was amazing. I learned so much and grew so much. But my biggest transformation didn't happen while I was in that corporate role... it happened when I decided to step out and go all-in on the entrepreneurial path. Now, I get to build AI agents for businesses and teach others how to do the same. Education has always been my #1 passion, and getting to live that every single day? Unreal."
Hot Take:
"The IDE is dying. So is tool calling. OpenAI won't win. And you'll be shipping code you've never read even as an experienced engineer."
---
What Cole Doesn't Sound Like
| Avoid | Why |
|---|---|
| Hype bro | Bullish but grounded - no empty excitement |
| Corporate speaker | Talks like a developer, not a marketer |
| Overpromiser | Admits limitations, shows iterations |
| Doom and gloom | Focuses on possibilities, not fears |
| Condescending explainer | Assumes intelligence, teaches with respect |
| Hedge-everything academic | Takes positions and backs them up |
---
Cole vs Generic AI Creators
| Cole Medin | Generic AI Creators |
|---|---|
| Admits limitations openly | Overpromises capabilities |
| Shows iterations/versions | Only shows final product |
| "Best tool for the job" mentality | Pushes one solution for everything |
| Balances code + no-code | Usually one or the other |
| Community-driven development | Solo creator approach |
| Practical, immediately usable | Theoretical, abstract |
| Humble about complexity | Oversimplifies |
---
Sentence Patterns
Opening hooks:
- Problem identification: "One of the biggest problems with [X] is..."
- Bold statement: "The IDE is dying. So is tool calling."
- Direct address: "Something massive is happening in [X] right now, and if you're not paying attention, you're already falling behind."
Taking a position:
- "I will die on that hill."
- "I'm gonna be honest..."
- "Here's the thing..."
- "And therein lies the problem with [X]."
Showing the work:
- "Not only have I [done X] myself, I've seen other people [do Y]."
- "After studying the workflows of developers who are genuinely [result]..."
- "I've developed a complete system for..."
---
Writing Patterns
Practical First, Theory Second
Lead with what to do, then explain why.
Yes:
"Start every project with a PRD. Before ANY code, document what you're building. The PRD becomes your source of truth for every conversation."
No:
"Understanding the theoretical underpinnings of documentation-driven development helps us appreciate why starting with a PRD is considered a best practice in the industry..."
Numbers and Specifics
Ground everything in real numbers, not vague claims.
Yes:
"259 pull requests, 497 commits, 40,000 lines added - was written entirely by Claude Code."
No:
"A significant amount of code was generated using AI tools."
---
Avoiding Robotic Patterns
If AI assists with writing, catch and fix these patterns:
Over-qualification
Robotic:
"It might be worth considering that perhaps the traditional approach could potentially be somewhat less effective than some alternatives in certain contexts."
Human (Cole):
"Traditional prompt engineering wastes time. Here's what works better."
Empty Transitions
Robotic:
"Let's dive deeper into this fascinating topic and explore the nuances..."
Human (Cole):
"Here's why this matters."
Performative Excitement
Robotic:
"I'm SO EXCITED to share this INCREDIBLE new feature!! This is HUGE!!"
Human (Cole):
"This is the feature I've wanted for two years. It changes how I work daily."
Abstract Frameworks
Robotic:
"The 7-step framework for optimizing your workflow leverages synergistic principles..."
Human (Cole):
"5 skills that separate top engineers. None require special tools. They're just better ways of working."
---
Audience Feeling
When someone consumes Cole's content, they should feel:
| Beginners | Experienced |
|---|---|
| "This is actually doable" | "Finally, someone who gets it" |
| "I know exactly what to focus on" | "I can respect this approach" |
| "I'm excited to try this" | "This confirms what I've been thinking" |
---
Voice Test
Before posting, ask:
1. Does this sound like Cole explaining this to a developer friend over coffee? 2. Is there genuine "super excited" energy or forced hype? 3. Am I backing this with real experience, not just theory? 4. Did I show what NOT to focus on, not just what to do? 5. Is there a sharper, shorter way to say this? 6. Would a beginner feel "this is doable"? Would an experienced dev feel "this person gets it"?
---
Quick Reference
| Always | Never |
|---|---|
| Use "super", "honestly", "so" naturally | Force vocabulary that doesn't fit |
| Be direct and confident | Hedge with qualifiers |
| Include specific numbers | Make vague claims |
| Say what NOT to focus on | Only give the "to-do" list |
| Show iterations and admit limitations | Only show polished results |
| Back claims with experience | Cite theory without practice |
| Keep it practical | Over-intellectualize |
| Use "cuz", contractions, informal tone | Sound corporate or stiff |
| Address hype honestly | Be purely negative or dismissive |
---
Last updated: 2025-01-15
# Place brand assets here:
# - logo.png (primary logo)
# - logo-dark.png (logo for dark backgrounds, if different)
# - icon.png (square icon/favicon)
# - Any other brand imagery
[Brand Name] — Brand System
REPLACE with a one-line brand description.
---
Brand Philosophy
Core Principles
1. Principle One REPLACE with description.
2. Principle Two REPLACE with description.
3. Principle Three REPLACE with description.
---
Color System
Primary Accent
| Name | Hex | Use |
|---|---|---|
| Accent | #REPLACE | Primary buttons, links, highlights |
| Accent Dark | #REPLACE | Hover states, outlines |
| Accent Light | #REPLACE | Secondary accents |
Theme Base
Background: #REPLACE
Background Alt: #REPLACE
Surface: #REPLACE
Text Primary: #REPLACE
Text Secondary: #REPLACE---
Typography
Font Stack
- Heading: REPLACE (headlines, titles, buttons)
- Body: REPLACE (paragraphs, descriptions)
- Code: REPLACE (code blocks, terminal)
Usage Guidelines
| Element | Font | Weight | Size |
|---|---|---|---|
| Display | Heading | 700 | 36px+ |
| H1 | Heading | 700 | 30px |
| H2 | Heading | 600 | 24px |
| Body | Body | 400 | 16-18px |
| Code | Code | 400 | 14px |
---
Signature Elements
REPLACE: Describe any unique visual patterns, decorative elements, or signature design choices for this brand.
---
Last updated: REPLACE
{
"name": "REPLACE",
"description": "REPLACE with a one-line description of the brand",
"colors": {
"background": "REPLACE",
"background_alt": "REPLACE",
"text": "REPLACE",
"text_secondary": "REPLACE",
"accent": "REPLACE",
"accent_secondary": "REPLACE",
"accent_tertiary": "REPLACE",
"code_bg": "REPLACE",
"card_bg": "REPLACE",
"card_bg_alt": "REPLACE"
},
"fonts": {
"heading": "REPLACE",
"body": "REPLACE",
"code": "REPLACE"
},
"assets": {
"logo": null,
"logo_dark": null,
"icon": null
}
}
{
"output": {
"directory": "output/{brand}",
"naming": "{name}-{date}",
"keep_parts": false
},
"generation": {
"slides_per_batch": 5,
"auto_combine": true,
"open_after_generate": false
},
"defaults": {
"slide_width_inches": 13.333,
"slide_height_inches": 7.5
}
}
[Brand Name] — Tone of Voice
Voice Character
REPLACE: Describe the brand's personality in 2-3 sentences. How should it "sound" when speaking?
Core Attributes
1. REPLACE Attribute
REPLACE with description of how this attribute manifests in writing.
2. REPLACE Attribute
REPLACE with description.
3. REPLACE Attribute
REPLACE with description.
---
Writing Guidelines
Do
- REPLACE with positive writing guideline
- REPLACE
- REPLACE
Don't
- REPLACE with what to avoid
- REPLACE
- REPLACE
---
Example Phrases
Headlines
- "REPLACE with example headline"
- "REPLACE"
CTAs
- "REPLACE with example CTA"
- "REPLACE"
Descriptions
- "REPLACE with example description style"
---
Last updated: REPLACE
Related skills
Forks & variants (1)
Pptx Generator has 1 known copy in the catalog totaling 1 installs. They canonicalize to this original listing.
- coleam00 - 1 installs