CrispDeck Schema Guide
CrispDeck is a client-side declarative presentation engine. It parses structured JSON generated by Large Language Models (LLMs) and renders it into pixel-perfect, responsive, native D3-driven slides instantly—no server or API required.
Pro Tip: CrispDeck relies on a strict TypeScript schema. Copy and paste the schema provided below directly into your AI assistant's system prompt (ChatGPT, Claude, Gemini) to guarantee perfectly compliant presentation arrays every time.
AI System Schema (For LLMs)
To optimize for AI generation, provide this exact TypeScript definition to your LLM. It maps perfectly to CrispDeck's internal layout and component engine.
// 1. Global Deck Configuration
type ThemeDef = { bg?: string; surface?: string; border?: string; text?: string; inverted?: string; accent?: string; kicker?: string; head?: string; fontHeading?: string; fontBody?: string; };
type Deck = { deckTitle: string; footerText: string; theme?: ThemeDef; slides: Slide[]; };
// 2. Slide Level Configurations
type Slide = {
id: string;
layout: "title" | "divider" | "hero" | "canvas" | "multi-row" | "multi-col" | "dynamic-grid" | "split-30-70" | "split-70-30";
gridColumns?: number; // Only required for 'dynamic-grid'
kicker?: string;
title: string;
subtitle?: string;
tracker?: string;
zoneStyles?: { flex?: string | number, width?: string, height?: string, justifyContent?: string, alignItems?: string }[];
zones?: Component[][];
};
// 3. Base Component & Styling Overrides
type BaseComponent = {
style?: { flex?: string | number, width?: string, height?: string, maxWidth?: string, maxHeight?: string, textAlign?: string, margin?: string, padding?: string }
};
// 4. Core Components
type Component = BaseComponent & (
| { type: "text", variant: "markdown" | "quote" | "poster", content: string }
| { type: "html", content: string }
| { type: "list", variant: "toc" | "comparison", items: ({ text: string, positive?: boolean } | string)[] }
| { type: "indicator", variant: "kpi", label: string, value: string | number, trend?: string }
| { type: "indicator", variant: "rag", label: string, value: "red" | "amber" | "green" }
| { type: "indicator", variant: "harvey", label: string, value: number }
| { type: "chevron-flow", steps: { label: string, active: boolean }[] }
| { type: "timeline", events: { date: string, title: string, desc?: string }[] }
| { type: "logic-tree", title: string, desc?: string, children?: any[] } // Recursive tree structure
| { type: "matrix-2x2", xAxis: string, yAxis: string, quadrants: { name: string, items: string[] }[] }
| { type: "data-table", headers: string[], rows: (string | number)[][] }
| { type: "gantt", timeline: string[], tasks: { label: string, start: number, duration: number, desc?: string, status?: "done" | "progress" | "delayed" }[] }
| { type: "image", url?: string, imageQuery?: string, caption?: string, alt?: string }
| { type: "media-block", variant: "profile" | "icon", title: string, subtitle: string, role?: string, iconName?: string, url?: string }
| ChartComponent
);
// 5. D3.js Chart Components
type ChartComponent = BaseComponent & (
| { type: "chart", variant: "bar" | "pie" | "donut" | "line" | "area" | "waterfall" | "funnel" | "treemap", title?: string, data: { label: string, value: number, isTotal?: boolean }[] }
| { type: "chart", variant: "stacked-bar", title?: string, data: { label: string, series: { name: string, value: number }[] }[] }
| { type: "chart", variant: "scatter", title?: string, data: { x: number, y: number, r: number, label: string }[] }
| { type: "chart", variant: "radar", title?: string, features: string[], data: { values: number[] }[] }
| { type: "chart", variant: "heatmap", title?: string, xLabels: string[], yLabels: string[], data: number[][] }
| { type: "chart", variant: "map", region?: "world" | "us" | "europe" | "asia" | "africa" | "middle_east" | "india" | "south_america" | "canada" | "oceania", title?: string, data: { label: string, value: number }[], pins?: { label: string, lat: number, lng: number, value?: string | number }[] }
);
Global Rules & Styling Overrides
To ensure beautiful outputs without manual formatting, adhere to these engine rules:
- Smart Paste Auto-Cleaning: CrispDeck automatically extracts JSON from conversational filler. You can paste the raw LLM output (including the
```jsonmarkdown backticks) directly into the editor and the engine will clean it automatically. - The 30/70 Spatial Rule: Place dense components (like Gantt charts or multi-series tables) in wider columns (70%), and tall/narrow components in smaller columns (30%).
- Title/Hero Overrides: Slides using the
title,canvas, orherolayouts do not support standardzones. They act as full-bleed cinematic states. - Markdown Support: The engine uses
marked.jsunder the hood. All standard string fields in components (likecontent,desc, table cells, or timeline events) natively support markdown formatting like**bold**,*italic*, and links. - Custom Fonts: You can inject ANY Google Font or local font via the Theme UI. If defined in the JSON
themeobject (e.g.,"'Space Grotesk', sans-serif"), CrispDeck handles the external CSS fetch automatically.
Component-Level Styling
Every component in the system accepts a style object that maps to standard CSS properties. Use this to override the default layout engine rules (e.g., restricting the height of a specific chart to let another component grow).
{
"type": "chart",
"variant": "pie",
"data": [...],
"style": { "height": "200px", "margin": "0 auto" }
}
Slide Layouts
Every slide object requires an id, a title, and a layout string. The engine maps these layouts into optimized CSS Flexbox and Grid structures dynamically.
Cinematic Layouts
title, hero, canvas, divider
Grid Layouts
multi-col, multi-row, split-30-70, split-70-30, dynamic-grid
{
"id": "slide_01",
"layout": "split-30-70",
"kicker": "Market Analysis",
"title": "Q3 Growth Trajectory",
"zones": [ ... ]
}
Zones & Columns
If using a Grid Layout, the zones array defines your columns. It is an array of arrays. Each inner array represents a column containing your components.
You can also pass an optional zoneStyles array at the slide level to control the CSS Flexbox/Grid properties of each specific column.
"zoneStyles": [
{ "justifyContent": "space-between" },
{ "padding": "20px" }
],
"zones": [
[
// Column 1 Components
{ "type": "text", "content": "..." }
],
[
// Column 2 Components
{ "type": "chart", "variant": "bar", "data": [...] }
]
]
Typography & Lists
Text Component
The text component supports rich markdown rendering. Variants alter the display context.
markdown: Standard body text. Supports headers, bold, italics, code, and lists.quote: Stylized blockquote intended for Hero layouts or emphasis.poster: Full-bleed overlay text designed specifically forcanvaslayouts.
List Component
Variants include toc (Table of Contents numbering) and comparison (Check/X marks).
{
"type": "list",
"variant": "comparison",
"items": [
{ "text": "Auto-scaling typography", "positive": true },
{ "text": "Manual pixel pushing", "positive": false }
]
}
Media & HTML Embeds
CrispDeck supports dynamic assets and raw code injections for edge cases.
image: You can provide a directurl, or useimageQuery(e.g.,"corporate, boardroom"). The engine will automatically format the keywords and fetch a dynamic stock image via LoremFlickr (with a built-in fallback to Picsum).media-block(Profile): Generates an automated avatar with initials viaui-avatars.comif nourlis provided or if a placeholder URL is detected.media-block(Icon): TheiconNamefield natively supports any standard Lucide Icon string.html: Allows you to break out of the JSON schema by embedding external libraries via secure iFrames, such as Plotly 3D surfaces, Vis.js network graphs, or custom Leaflet Maps. The PDF export engine automatically attempts to resize, flatten, and capture these webGL canvases during generation.
{
"type": "media-block",
"variant": "profile",
"title": "Jane Doe",
"role": "Lead Engineer",
"subtitle": "Architect of the new data pipeline."
}
Indicators & Status
Use the indicator type to build data-dense dashboards.
kpi: Large numerical metrics with an optionaltrendfield (e.g., "↑ 12%"). Sequential KPIs in the same zone will automatically wrap into a horizontal flex-group.rag: Red/Amber/Green traffic light status for system health tracking.harvey: Consulting-grade Harvey Balls. The engine parses values mathematically (0, 25, 50, 75, 100).
Structural Frameworks
Render complex logic diagrams seamlessly natively without HTML manipulation.
Gantt & Timelines
Use timeline for chronological steps, or gantt for complex workstream rendering. Gantt tasks use a 0-based start index corresponding to the length of the timeline array.
Matrices & Flow Diagrams
matrix-2x2: Generates a quadrant matrix.quadrantsmust be an array of 4 objects containing anameand an array of stringitems.logic-tree: A recursive component that builds hierarchical trees. Nodes contain atitle, optionaldesc, and achildrenarray containing more nodes.chevron-flow: A sequential chevron process diagram supportingactive/inactive states.
Data Tables
Tables in CrispDeck are highly intelligent. They automatically scan columns for numeric values and right-align them for proper financial readability.
Harvey Ball Injection: You can seamlessly inject Harvey Balls directly into any table cell using the string token macro: [harvey: 75].
{
"type": "data-table",
"headers": ["Feature", "Completion"],
"rows": [
["Authentication", "[harvey: 100] Native"],
["Database Sync", "[harvey: 25] Partial"]
]
}
Standard D3 Charts
All charts are rendered dynamically using native D3.js. They automatically adopt your brand theme colors and scale flawlessly to fill their designated container zone.
Variants: bar, pie, donut, line, area, waterfall, funnel, treemap.
{
"type": "chart",
"variant": "waterfall",
"title": "Effort Walkdown",
"data": [
{ "label": "Base Effort", "value": 100, "isTotal": true },
{ "label": "Auto-Layout", "value": -40 },
{ "label": "D3 Charts", "value": -25 },
{ "label": "Final Polish", "value": 35, "isTotal": true }
]
}
Advanced D3 Charts
Advanced multi-series charts utilize slightly different data array structures to accommodate deeper data dimensionality.
Stacked Bar
Requires a nested series array for each label grouping.
{
"type": "chart",
"variant": "stacked-bar",
"data": [
{
"label": "Q1",
"series": [
{ "name": "Revenue", "value": 40 },
{ "name": "Costs", "value": 30 }
]
}
]
}
Scatter Plot
Requires specific x, y, and r (radius) coordinates for each point.
{
"type": "chart",
"variant": "scatter",
"data": [
{ "x": 10, "y": 85, "r": 20, "label": "Hero" },
{ "x": 40, "y": 90, "r": 15, "label": "Split" }
]
}
Radar / Spider Chart
Requires a features array defining the axes, and a data array containing matching values.
{
"type": "chart",
"variant": "radar",
"features": ["Speed", "Design", "Data Viz", "Ease of Use"],
"data": [
{ "values": [95, 90, 95, 85] },
{ "values": [30, 80, 50, 95] }
]
}
Heatmap
Requires xLabels, yLabels, and a two-dimensional data matrix containing the values.
{
"type": "chart",
"variant": "heatmap",
"xLabels": ["Text", "Lists", "Charts"],
"yLabels": ["Ease", "Power"],
"data": [
[10, 8, 2],
[3, 5, 10]
]
}
Geospatial Maps
Maps fetch TopoJSON on the fly and colorize regions based on data values. You can overlay specific location pins using explicit Longitude/Latitude coordinates.
Supported Regions: world, us, europe, asia, africa, middle_east, india, south_america, canada, oceania.
{
"type": "chart",
"variant": "map",
"region": "europe",
"data": [
{ "label": "Germany", "value": 100 },
{ "label": "France", "value": 80 }
],
"pins": [
{ "label": "Berlin", "lat": 52.5200, "lng": 13.4050 }
]
}