Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 36 additions & 152 deletions templates/slides/.agents/skills/create-deck/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pnpm action add-slide --deckId=<id> --layout content --content "..."
Every slide's `content` must use this exact outer div:

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: flex-start; font-family: var(--ds-body-font, sans-serif);">
<div class="fmd-slide" style="padding: 64px 80px; display: flex; flex-direction: column; justify-content: flex-start; font-family: var(--ds-body-font, Inter, sans-serif);">
<!-- slide content here -->
</div>
```
Expand All @@ -171,22 +171,25 @@ Poppins, cyan, white, black, or a stock radius into new markup.
## Fit budget

The canvas is fixed at its aspect-ratio dimensions. With the standard 16:9
canvas (960x540) and `padding: 80px 110px`, the usable content area is only
740x380px. Treat that as a hard budget for the main flow: use at most two title
canvas (960x540) and `padding: 64px 80px`, the usable content area is only
800x412px. Treat that as a hard budget for the main flow: use at most two title
lines, three short bullets or cards, and two or three short items per column.
Split dense source material across slides instead of shrinking it into a dense
stack. Keep body text at or above 16px. Never hide overflow with zoom,
`transform: scale()`, clipping, or scroll overflow. A later structural repair
may reduce the slide's explicit padding, and that padding must remain intact
when the saved HTML is rendered.

Background is pure black (`bg-[#000000]`) — set by the renderer, not the slide HTML.

When no reference deck or hydrated design system is available, use a restrained,
content-first visual language. Do not invent colorful cards, boxes, or
decorative rectangles behind or over text. Add a colored shape only when it has
a clear semantic role and leaves the text unobscured; prefer typography,
spacing, alignment, and one restrained accent.
When no reference deck or hydrated design system is available, use the fallback
direction: warm neutral paper (`#F5F2EA`), ink text (`#1F2933`), Inter or a
close sans-serif, 64px vertical and 80px horizontal padding, and one restrained
blue or coral accent. Build an intentional composition beyond a text dump: use
a title block, two-column split, metric treatment, rule, callout, visual
placeholder, or simple diagram where it fits the message. Never use a black
background with white text as the generic fallback, never omit the padded
wrapper, and never let body copy touch the canvas edge. Do not add decorative
cards or shapes without a semantic role, and keep any accent treatment away
from text so contrast stays readable.

## Bounded visual QA

Expand All @@ -200,149 +203,46 @@ was rendered and compared.

## Ready-to-Use Templates

Copy and fill in the bracketed values. Use `\` to escape quotes inside the JSON string.

---
Copy and fill in the bracketed values. Keep the wrapper styles and replace
tokens with the hydrated design-system values when available.

### Title Slide

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; font-family: 'Poppins', sans-serif;">
<div style="font-size: 16px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 24px;">[LABEL OR DATE]</div>
<h1 style="font-size: 64px; font-weight: 900; color: #fff; line-height: 1.1; letter-spacing: -2px; margin: 0 0 24px 0;">[TITLE]</h1>
<p style="font-size: 22px; color: rgba(255,255,255,0.55); margin: 0;">[SUBTITLE OR PRESENTER]</p>
<div class="fmd-slide" style="padding: 64px 80px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 18px; font-family: var(--ds-body-font, Inter, sans-serif);">
<div style="font-size: 14px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ds-accent, #2457D6);">[LABEL OR DATE]</div>
<h1 style="font-size: 56px; font-weight: 750; color: var(--ds-text, #1F2933); line-height: 1.05; letter-spacing: -0.04em; margin: 0; max-width: 760px;">[TITLE]</h1>
<p style="font-size: 20px; color: var(--ds-text-muted, #667085); margin: 4px 0 0;">[SUBTITLE OR PRESENTER]</p>
</div>
```

---

### Section Divider
### Content or Two-Column Slide

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; font-family: 'Poppins', sans-serif;">
<div style="font-size: 16px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 20px;">[SECTION NUMBER, e.g. 01]</div>
<h2 style="font-size: 72px; font-weight: 900; color: #fff; line-height: 1.05; letter-spacing: -2px; margin: 0;">[SECTION TITLE]</h2>
</div>
```

---

### Content Slide (bullets)

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: flex-start; font-family: 'Poppins', sans-serif;">
<div style="font-size: 14px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 16px;">[SECTION LABEL]</div>
<h2 style="font-size: 40px; font-weight: 900; color: #fff; line-height: 1.15; letter-spacing: -1px; margin: 0 0 48px 0;">[SLIDE HEADING]</h2>
<div style="display: flex; flex-direction: column; gap: 20px;">
<div style="display: flex; align-items: flex-start; gap: 16px;">
<span style="font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;">&#x25CF;</span>
<span style="font-size: 22px; color: rgba(255,255,255,0.85); line-height: 1.5;">[BULLET TEXT]</span>
</div>
<div style="display: flex; align-items: flex-start; gap: 16px;">
<span style="font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;">&#x25CF;</span>
<span style="font-size: 22px; color: rgba(255,255,255,0.85); line-height: 1.5;">[BULLET TEXT]</span>
</div>
<div style="display: flex; align-items: flex-start; gap: 16px;">
<span style="font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;">&#x25CF;</span>
<span style="font-size: 22px; color: rgba(255,255,255,0.85); line-height: 1.5;">[BULLET TEXT]</span>
<div class="fmd-slide" style="padding: 64px 80px; display: flex; flex-direction: column; justify-content: flex-start; gap: 18px; font-family: var(--ds-body-font, Inter, sans-serif);">
<div style="font-size: 13px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ds-accent, #2457D6);">[SECTION LABEL]</div>
<h2 style="font-size: 34px; font-weight: 750; color: var(--ds-text, #1F2933); line-height: 1.12; letter-spacing: -0.03em; margin: 0 0 18px;">[SLIDE HEADING]</h2>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start;">
<div style="display: flex; flex-direction: column; gap: 14px;">
<div style="border-left: 3px solid var(--ds-accent, #2457D6); padding: 12px 16px; background: var(--ds-surface, #FFFFFF); border-radius: var(--ds-radius, 14px); font-size: 18px; line-height: 1.4;">[KEY POINT]</div>
<div style="border-left: 3px solid var(--ds-secondary, #C85C3A); padding: 12px 16px; background: var(--ds-surface, #FFFFFF); border-radius: var(--ds-radius, 14px); font-size: 18px; line-height: 1.4;">[KEY POINT]</div>
</div>
<div class="fmd-img-placeholder" style="min-height: 220px; border-radius: var(--ds-radius, 14px);">[VISUAL OR IMAGE DESCRIPTION]</div>
</div>
</div>
```

---

### Two-Column Slide (text left, image/visual right)

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: flex-start; font-family: 'Poppins', sans-serif;">
<div style="font-size: 14px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 16px;">[SECTION LABEL]</div>
<h2 style="font-size: 40px; font-weight: 900; color: #fff; line-height: 1.15; letter-spacing: -1px; margin: 0 0 40px 0;">[HEADING]</h2>
<div style="display: flex; gap: 60px; flex: 1;">
<div style="flex: 1; display: flex; flex-direction: column; gap: 20px;">
<div style="display: flex; align-items: flex-start; gap: 16px;">
<span style="font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;">&#x25CF;</span>
<span style="font-size: 20px; color: rgba(255,255,255,0.85); line-height: 1.5;">[BULLET]</span>
</div>
<div style="display: flex; align-items: flex-start; gap: 16px;">
<span style="font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;">&#x25CF;</span>
<span style="font-size: 20px; color: rgba(255,255,255,0.85); line-height: 1.5;">[BULLET]</span>
</div>
</div>
<div class="fmd-img-placeholder" style="flex: 1; border-radius: 12px; min-height: 300px;">[IMAGE DESCRIPTION]</div>
</div>
</div>
```

---

### Statement / Quote Slide

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; font-family: 'Poppins', sans-serif;">
<div style="width: 60px; height: 4px; background: #00E5FF; margin-bottom: 40px;"></div>
<p style="font-size: 48px; font-weight: 800; color: #fff; line-height: 1.2; letter-spacing: -1px; margin: 0 0 32px 0;">&ldquo;[STATEMENT OR QUOTE]&rdquo;</p>
<p style="font-size: 18px; color: rgba(255,255,255,0.45); margin: 0;">[SOURCE OR ATTRIBUTION]</p>
</div>
```

---

### Metrics / Stats Slide

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: flex-start; font-family: 'Poppins', sans-serif;">
<div style="font-size: 14px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 16px;">[SECTION LABEL]</div>
<h2 style="font-size: 40px; font-weight: 900; color: #fff; line-height: 1.15; letter-spacing: -1px; margin: 0 0 60px 0;">[HEADING]</h2>
<div style="display: flex; gap: 60px;">
<div style="flex: 1;">
<div style="font-size: 72px; font-weight: 900; color: #00E5FF; letter-spacing: -2px; line-height: 1;">[METRIC]</div>
<div style="font-size: 18px; color: rgba(255,255,255,0.55); margin-top: 12px;">[LABEL]</div>
</div>
<div style="flex: 1;">
<div style="font-size: 72px; font-weight: 900; color: #00E5FF; letter-spacing: -2px; line-height: 1;">[METRIC]</div>
<div style="font-size: 18px; color: rgba(255,255,255,0.55); margin-top: 12px;">[LABEL]</div>
</div>
<div style="flex: 1;">
<div style="font-size: 72px; font-weight: 900; color: #00E5FF; letter-spacing: -2px; line-height: 1;">[METRIC]</div>
<div style="font-size: 18px; color: rgba(255,255,255,0.55); margin-top: 12px;">[LABEL]</div>
</div>
</div>
</div>
```

---

### Closing / CTA Slide

```html
<div class="fmd-slide" style="padding: 80px 110px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; font-family: 'Poppins', sans-serif;">
<div style="font-size: 16px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 24px;">[LABEL, e.g. GET STARTED]</div>
<h2 style="font-size: 64px; font-weight: 900; color: #fff; line-height: 1.1; letter-spacing: -2px; margin: 0 0 32px 0;">[CLOSING STATEMENT]</h2>
<p style="font-size: 22px; color: rgba(255,255,255,0.55); margin: 0;">[CONTACT OR NEXT STEP]</p>
</div>
```
Use the same wrapper and tokens for section, statement, metrics, and closing
slides, changing only the composition. An image placeholder, metric row,
short rule, or callout should support the message, not fill empty space.

## Image Placeholders

When a slide needs a visual, use this div — it renders as a styled placeholder and can later be replaced with a generated image:

```html
<div class="fmd-img-placeholder" style="width: 100%; height: 300px; border-radius: 12px;">[Description of what image should show]</div>
```

## Bold Terms with Description

For definition-style bullets:
When a slide needs a visual, use this div. It renders as a styled placeholder
and can later be replaced with a generated image:

```html
<div style="display: flex; align-items: flex-start; gap: 16px;">
<span style="font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;">&#x25CF;</span>
<span style="font-size: 22px; line-height: 1.5;">
<strong style="font-weight: 800; color: #fff;">[Term]</strong>
<span style="color: rgba(255,255,255,0.55);"> — [description]</span>
</span>
</div>
<div class="fmd-img-placeholder" style="width: 100%; min-height: 220px; border-radius: var(--ds-radius, 14px);">[Description of what image should show]</div>
```

## Bulk Replacement Only
Expand All @@ -351,24 +251,8 @@ Use a non-empty `create-deck --slides '[...]'` payload only for imports or an
intentional atomic bulk replacement. For normal AI-generated decks, use the
empty-deck plus sequential `add-slide` workflow above.

A bulk payload looks like this:

```bash
pnpm action create-deck --title "Product Vision 2025" --slides '[
{
"id": "slide-1",
"layout": "title",
"content": "<div class=\"fmd-slide\" style=\"padding: 80px 110px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; font-family: '\''Poppins'\'', sans-serif;\"><div style=\"font-size: 16px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 24px;\">ANNUAL STRATEGY</div><h1 style=\"font-size: 64px; font-weight: 900; color: #fff; line-height: 1.1; letter-spacing: -2px; margin: 0 0 24px 0;\">Product Vision 2025</h1><p style=\"font-size: 22px; color: rgba(255,255,255,0.55); margin: 0;\">Engineering Leadership — Q1 2025</p></div>"
},
{
"id": "slide-2",
"layout": "content",
"content": "<div class=\"fmd-slide\" style=\"padding: 80px 110px; display: flex; flex-direction: column; justify-content: flex-start; font-family: '\''Poppins'\'', sans-serif;\"><div style=\"font-size: 14px; font-weight: 700; letter-spacing: 3px; text-transform: uppercase; color: #00E5FF; margin-bottom: 16px;\">OVERVIEW</div><h2 style=\"font-size: 40px; font-weight: 900; color: #fff; line-height: 1.15; letter-spacing: -1px; margin: 0 0 48px 0;\">Three Core Priorities</h2><div style=\"display: flex; flex-direction: column; gap: 20px;\"><div style=\"display: flex; align-items: flex-start; gap: 16px;\"><span style=\"font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;\">&#x25CF;</span><span style=\"font-size: 22px; color: rgba(255,255,255,0.85); line-height: 1.5;\">Ship the agent platform by March</span></div><div style=\"display: flex; align-items: flex-start; gap: 16px;\"><span style=\"font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;\">&#x25CF;</span><span style=\"font-size: 22px; color: rgba(255,255,255,0.85); line-height: 1.5;\">Grow to 10k active teams</span></div><div style=\"display: flex; align-items: flex-start; gap: 16px;\"><span style=\"font-size: 8px; color: #fff; margin-top: 8px; flex-shrink: 0;\">&#x25CF;</span><span style=\"font-size: 22px; color: rgba(255,255,255,0.85); line-height: 1.5;\">Reduce time-to-value to under 5 minutes</span></div></div></div>"
}
]'
```

After creating, navigate to the deck:
For a bulk replacement, pass the same fully styled HTML templates in the
`slides` array. After creating, navigate to the deck:
```bash
pnpm action navigate --deckId=<id>
```
1 change: 1 addition & 0 deletions templates/slides/actions/add-slide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export default defineAction({
"For an agent-generated deck with a persisted target slide count, stop once that count is reached. If the user explicitly asks for more slides after the target, re-read the deck and set targetSlideCountOverride to the new total on the first add-slide call. " +
"Before the first slide you add to an existing deck, call `get-deck` with compact=true once and use its `designSystem`, `deckStyle`, and `representativeSlideId`; if designSystem.scope is summary, call `get-design-system` once with its id. Reuse that context for every following slide. Never use generic slide styling from an id alone. " +
"Pass presenter-only speaker notes in `notes`; keep them out of the slide HTML. " +
"Every new slide must be a fully styled composition with the exact padded `fmd-slide` wrapper, a clear type hierarchy, intentional alignment, readable contrast, and at least one visual or structural treatment beyond plain text. If no design system is linked, use a light neutral canvas with ink text and one or two restrained accents; never default to a black canvas with white text. " +
"For a single-call bulk append, use `patch-deck` with add-slide operations. " +
"Returns the new slide ID, 1-based slideNumber, updated slide count, and pending layoutFit identity that can be checked later with get-layout-overflows.",
schema: z.object({
Expand Down
2 changes: 1 addition & 1 deletion templates/slides/actions/create-deck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export default defineAction({
"For longer decks or live in-app generation, create the deck with slides: [] and then use add-slide sequentially so progress appears live; the new deck is also opened in the connected Slides UI. " +
"Pass presenter-only speaker notes in each slide's `notes` field; keep them out of slide HTML. " +
"Pass deckId to replace an existing deck. " +
"Returns the deck id, title, effective designSystemId, linked designSystem.agentContext when readable, and slide count. Apply that context before authoring slides.",
"Returns the deck id, title, effective designSystemId, linked designSystem.agentContext when readable, and slide count. Apply that context before authoring slides. Every generated slide must be a fully styled composition with the exact padded `fmd-slide` wrapper, a clear type hierarchy, intentional alignment, readable contrast, and at least one visual or structural treatment beyond plain text. If no design system is linked, use a light neutral canvas with ink text and one or two restrained accents; never default to a black canvas with white text.",
schema: z.object({
title: z.string().describe("Deck title"),
slides: SlidesSchema.describe(
Expand Down
Loading
Loading