Skip to content
Engine has no release yet: these pages describe unreleased main.

Slide Format

A slides artifact is a deck: an index and one file per slide, in Claude’s slide format without its project/ prefix, so a deck moves between the two and an agent that writes one writes the other. The engine holds every version of a deck to this format when it is published (internal/artifacts/slideformat) and refuses one outside it, naming the file, the line and the rule broken; the dashboard draws, presents and prints the deck from the canonical tree the same parser produces, and never parses a slide’s markup itself.

Everything below is a closed set. What is not listed is refused, never silently dropped: a deck that publishes is a deck that draws.

PathWhat it is
deck.jsonThe index, and the version’s entry. A deck’s kind is told by this path: crewlet artifacts publish infers slides from a directory holding it
slides/<id>.htmlOne slide. The id is 1 to 64 letters, digits, _ and -, and is the slide’s name in the index, the file and its section
Any other pathImages and font files the slides and the index name, by their path from the deck’s root (images/team.png, fonts/inter.woff2)

A deck holds HTML only as its slides: every slides/<id>.html is in the index’s order, every id in order has its file, and no other .html file is accepted.

{
"title": "Quarterly plan",
"order": ["cover", "plan", "numbers"],
"cover": "cover",
"sections": {
"s1": { "description": "Where we are", "start": "cover" },
"s2": { "description": "What we will do", "start": "plan" }
},
"faces": {
"source-serif-4": { "family": "Source Serif 4", "src": "fonts/source-serif-4.woff2" }
}
}
KeyRule
titleRequired, at most 120 bytes
orderRequired: the slide ids in deck order, each once, 1 to 500
coverOptional: the slide the gallery draws as the card’s cover, else the first
sectionsOptional: the outline, any key to a run’s one sentence (at most 300 bytes) and the slide it starts at. No two start at one slide
themeOptional: the look the deck began in, one of nightshade, ink, paper, signal, studio, grove. Crewlet’s own key, written by the starter; the slides hold their own styles, so a deck naming none draws the same. The deck editor adds a slide from that theme’s layouts, and duplicates a slide in a deck naming none. See Themes and layouts
facesOptional, at most 4: a typeface keyed by its family lowercased with spaces as -, its family and the font file of the version it loads from (src). See Images and typefaces
v, createdOnFiles, listsClaude’s own bookkeeping: accepted and kept as written, never read. lists may only be css
designSystemsMust be empty or absent: a Crewlet deck installs no design system

Any other key is refused, so a misspelt key is an error rather than a setting that does nothing.

A slide file is exactly one <section>, with nothing before or after it but whitespace and comments: no doctype, <html>, <head> or <body>. Every element is closed explicitly (<br>, <img> and <hr> take no closing tag, and inside a drawing an empty element may close itself, <rect/>).

<section id="plan" data-transition="fade" style="background:#fbfbf8;color:#1a1a1a;font-family:Georgia, serif;padding:128px;display:flex;flex-direction:column;gap:48px">
<h2 style="font-size:72px;font-weight:400;line-height:1.1">The plan</h2>
<div style="display:flex;gap:32px">
<p style="flex:1;font-size:32px">Every request lands in one place.</p>
<img src="images/team.png" alt="The support team" style="width:480px;height:360px;object-fit:cover;border-radius:16px">
</div>
<p style="position:absolute;left:128px;bottom:64px;width:800px;font-size:24px;color:#6a7179">Source: support desk</p>
<aside>Take the questions first.</aside>
</section>
  • The stage is 1920 by 1080 CSS pixels, 16:9, laid out at that size and scaled as a whole wherever it is drawn, so a thumbnail, the editor and a projector show the same line breaks.
  • The section carries id (the slide’s id, its file’s name), style (which must set a background, so the slide reads the same in every theme), and optionally hidden (Present skips it, Print leaves it out) and data-transition (fade or push: how the slide leaves the stage in Present).
  • Layout. A section or <div> that names no display lays its children out as a column; display:flex is a row, display:grid a grid. Children flow; position:absolute with left, top, right, bottom, width and height pins one to the slide (or to a position:relative <div>). Later children paint over earlier ones: there is no z-index.
  • Defaults. h1, h2, h3 are 96, 64 and 44px at weight 600; text elsewhere inherits from its container, 32px by default. Set sizes yourself: nothing under 24px reads from the back of a room.
  • Speaker notes are plain text in one <aside>, the section’s last child, at most 4,000 characters. Everyone who can open the deck can read them.
ElementHoldsAttributes
sectionblocks, then one asideid, style, hidden, data-transition
divblocks (at most 15 nested)style, data-text (a text box; its value is a list indent in px, 0 to 200)
h1 h2 h3 ptext and inline marksstyle
ul olli only (one level)style
litext and inline marksstyle
b i u spantext and inline marksspan: style
atext and b, i, u, span, brhref, an https:// address
brnothingnone
imgnothingsrc and alt (both required; alt="" for decoration), style
tabletr onlystyle
trth and tdstyle (background only)
th tdtext and inline marksstyle
hrnothingstyle
svga drawingaria-label (required: what it shows), drawing attributes, style
x-shapenothingkind: rect, rounded, ellipse, diamond, arrow-right, arrow-left, arrow-up, arrow-down, line; style
x-iconnothingname, one of Activity, Book, Chart, Chat, Check, CheckCircle, Clock, Code, Database, Globe, Home, Key, Lightning, Link, Lock, PaperPlane, Search, Settings, Star, Tool, Trust, Users, Warning, Wrench; style
asideplain textnone

A block is h1 to h3, p, ul, ol, div, img, table, hr, svg, x-shape and x-icon. Text sits in a text element, never directly in a section or div.

An x-icon draws its glyph at half its box, centred, as Claude’s format does; the rest of the box is padding. A width:64px; height:64px icon draws a 32px glyph, so size the box at twice the glyph you want: at least 32px, and 48px beside 24px body text.

Every style is inline, in style, from the table below, and only on the elements its row names. A value is read by its property’s grammar and stored in one canonical form: a bare number is pixels (width:480 is 480px), a point size becomes pixels (36pt is 48px), keywords are lowercased and a family name is quoted.

GrammarMeans
LENNpx or a bare number of pixels (pt converts); never em, rem, vw, vh or %
PCTN%
COLOR#rgb, #rgba, #rrggbb, #rrggbbaa, rgb(), rgba(), hsl(), hsla(), a CSS named colour, or transparent; never currentcolor or var()
ANGLENdeg, Nturn or Nrad
FAMILYup to eight family names, quoted or not, each a letter then letters, digits, spaces, _ and -, at most 40; or serif, sans-serif, monospace, cursive, system-ui
PropertyValueOn
positionabsolute, relativeplaced elements
left, topLEN, PCT, auto, calc(PCT ± LEN)pinned elements
right, bottomLEN, PCT, autopinned elements
widthLEN, PCT, autoplaced elements, th, td
heightLEN, PCT, autoplaced elements
min-widthLEN, min-content, max-contentplaced elements
min-height, max-width, max-heightLENplaced elements
displayflex, grid, nonesection, div
flex-directionrow, column, row-reverse, column-reversesection, div
flex-wrapwrap, nowrapdiv
gapLEN, 0 to 512section, div
align-itemsstart, center, end, stretch, baseline and the flex-/self- formssection, div
justify-contentstart, center, end, flex-start, flex-end, space-between, space-around, space-evenlysection, div
justify-itemsstart, center, end, stretchsection, div
align-selfas align-items, or autoplaced elements
justify-selfauto, start, center, end, stretchplaced elements
flexnone, auto, or grow [shrink] [basis]placed elements
flex-grow, flex-shrinkNplaced elements
flex-basisLEN, autoplaced elements
grid-template-columns, grid-template-rowstracks of LEN, Nfr, auto and repeat(N, …), at most 24section, div
grid-column, grid-rowspan N, 1 to 24placed elements
aspect-ratioN or N / Nplaced elements
paddingone to four LEN, 0 to 256section, div, text elements, table, th, td
overflowhidden, visiblediv
font-familyFAMILYsection, div, text elements, table, th, td
font-sizeLEN, 8 to 400as font-family
font-weightnormal, bold, 100 to 900 in hundredsas font-family, and span
font-stylenormal, italicas font-family, and span
font[italic] [weight] size[/line-height] familyas font-family
line-heighta multiplier 0.5 to 4, PCT, or LENas font-family
letter-spacingnormal, LEN −24 to 32, or Nemas font-family
text-alignleft, center, right, justifyas font-family
text-transformnone, uppercase, lowercase, capitalizeas font-family
white-spacenormal, nowrapas font-family
text-decorationnone, underline or line-through, an optional style and COLOR (underline only on a span)as font-family, and span
font-variant-numericnormal, tabular-numsas font-family
-webkit-text-strokeLEN 0 to 8 and COLORas font-family
colorCOLORas font-family, and span, x-icon, hr
backgroundCOLOR, or one linear-gradient(), repeating-linear-gradient() or radial-gradient() of 2 to 8 stops with an optional COLOR under it (a tr, x-shape or hr takes a COLOR)painted elements
background-colorCOLORpainted elements
background-clip, -webkit-background-cliptexttext elements
-webkit-text-fill-colortransparent, or currentcolor on a spantext elements, span
border, border-top, border-right, border-bottom, border-left[LEN 0 to 16] solid|dashed|dotted|double|none [COLOR] (the style word is required), or nonepainted elements
border-radiusone to four LEN or PCTdiv, img, table, x-shape, text elements
box-shadowup to eight [inset] x y [blur [spread]] COLORdiv, img, table, x-icon, x-shape, text elements
text-shadowup to eight x y [blur] COLORtext elements, table
opacity0 to 1placed elements, section
transformtranslate(), translateX(), translateY(), rotate(), scale() (0.5 to 2), skew(), skewX(), skewY() (±60deg), each once, in that order (rotate() alone on a shape)placed elements
filter, backdrop-filterblur() (to 20px), brightness(), contrast(), saturate(), grayscale(), sepia(), invert(), hue-rotate()div, img, x-shape, text elements
mix-blend-modenormal, multiply, screen, overlay, darken, lightendiv, img, x-shape, text elements
object-fitcover, containimg
margin, box-sizing, grid-template0, border-box, none only, accepted and left out

A placed element is any block a container holds; a text element is h1 to h3, p, ul, ol and li; a painted element is a div, img, table, x-icon, x-shape, hr, a text element or a cell.

No value may carry url(, image-set(, var(, env(, attr(, expression, @, a backslash, a comment, !important, <, >, { or }, whatever its property.

A chart or a diagram is one <svg> with an aria-label, at most 52 KB of source: g, defs, path, rect, circle, ellipse, line, polyline, polygon, text, tspan, title, desc, use, symbol, marker, pattern, clipPath, mask, linearGradient, radialGradient, stop, filter and the feGaussianBlur, feOffset, feBlend, feColorMatrix, feFlood, feComposite, feMerge, feMergeNode and feDropShadow primitives, with their geometry and presentation attributes (fill, stroke, stroke-width, opacity, transform, viewBox and the rest the engine’s table lists).

A drawing reaches nothing outside itself: no <script>, no event attribute, no <foreignObject>, no <style> element or style attribute (use presentation attributes), and every reference (href, url(#…)) is to an id the same drawing declares. Ids are a letter then letters, digits, _, . and -. The dashboard gives each drawn copy of a drawing its own id prefix, so a slide drawn twice (its thumbnail and the stage) never resolves the other copy’s gradients.

An image is an <img> whose src is a PNG, JPEG, GIF, WebP or SVG file of the same version, by its path from the deck’s root. Never a URL, a data: address, a path starting with / or ./, or one holding ... The dashboard reads the file with the viewer’s own sign-in and shows it through an object URL of its own, so a deck makes no request a slide names.

A typeface is a faces entry whose src is a woff2, woff, ttf or otf file of the version. The dashboard loads it from the file’s bytes; a slide names it in font-family like any family, and a family that is not declared falls back to the next one the slide names, as in any stylesheet. A Google Fonts href, which Claude’s format accepts, is refused here with how to fix it: download the font file and include it in the version, so the deck draws the same wherever it is opened.

BoundValue
Slides in a deck500
Elements on a slide (a drawing counted once)200
Nested <div>s15
Pinned children of one <div>24
Characters of text on a slide, notes aside20,000
Inline marks (b, i, u, a, span) on a slide100
Rows of a table, cells of a row, cells on a slide100, 24, 4,000
Characters of speaker notes4,000
One inline drawing’s source52 KB
Typefaces4

A version’s own bounds apply too: 511 files, and each file’s size by its type.

What is refused, and what to write instead

Section titled “What is refused, and what to write instead”
RefusedWrite instead
class, <style>, <link>, margin, z-index, em, var(), url()Inline styles from the table; paint order is source order
<script>, an on… attribute, <iframe>, <object>, <canvas>, form controlsNothing runs on a slide; draw in an inline <svg>
x-embed (a live page on a slide)A picture of it as an <img>
x-connectorA line in an inline <svg>
data-build-in, data-build-out (builds)Show the element from the start, or split the slide
data-transition="magic", an id on any element but the sectionfade or push
data-section on a slidesections in deck.json
data-cropCrop the image file itself; object-fit covers or contains it in its box
<thead>, <tbody>, <h4>, <em>, <strong>, <pre>, <code>, <blockquote><tr> directly, <h3>, <i>, <b>, a styled <p>
A Google Fonts href in faces, a design systemA font file of the version in src; the company’s look comes from its own decks

A refusal lists every finding at once (up to 50), each as file:line: rule: message, under the code slide_format.

A deck begun in the dashboard is composed by the engine from a plan: the theme it is drawn in and the slides it opens with, each a layout and its title. The engine writes ordinary slides, held to this format like any version, and names the theme in the index so a slide added later is drawn from the same theme’s layouts. GET /artifacts/starters/slides answers every theme and layout (see API Endpoints).

ThemeLook
nightshadePeriwinkle on blue-black, set in Inter
inkNavy and paper, set in Georgia (the default)
paperWhite, quiet and exact, set in Helvetica Neue
signalYellow on black, for a big room
studioWarm cream and terracotta, Palatino over Avenir Next
groveDeep green and mint, set in the system face
LayoutHolds
coverThe deck’s title and who it is for; its title is the deck’s
agendaA numbered list of the parts to come
sectionOpens a part of the deck; it starts a section of the outline under its title
pointsA title and a short list
columnsTwo cards side by side
numberOne figure, large, and what it measures
quoteA quote, large, and who said it
closingThe one decision or ask to end on

A slide’s id is its layout’s, numbered from two when a layout is used again (points, points-2).

  • theme in the index. Added as an optional key, so every deck written before it is still in the format. A deck that names a theme outside the list above is refused, naming the themes there are.
  • Read. GET /artifacts/{id}/versions/{n}/deck answers the canonical tree (see API Endpoints), and GET …/outline a deck’s titles and cover slide for the gallery. An agent reads the outline with get_artifact and view: "outline", then only the slide files it changes.
  • Edit. A person with editor edits text in place, speaker notes, the order and the deck’s title, and deletes slides; Save publishes a version against the one they opened. The editor writes each changed slide back in this format’s canonical form, every value as the engine stores it, so a slide a person saved reads back to the same tree. A save refused because somebody published since is merged onto their version slide by slide, and what both changed differently is the person’s to resolve.
  • Present. Present draws the slide as large as fits, full screen on the reader’s press, with the keys a clicker sends (Right, Down, Page Down, Space and Enter forward; Left, Up, Page Up and Backspace back; Home and End; Escape out), each slide announced by its number and title. Full screen is a projector’s: the slide on black, its controls floating over its foot and put away with the cursor while the pointer rests (a clicker’s keys do not bring them back). The Presenter window, the dashboard’s own, shows the slide, the next one, the notes and a timer, and moves the room’s screen. Anybody in the room can Follow the presenter, a phone included, and is moved to the slide they are on.
  • Print. Print draws every shown slide on its own 16:9 page, so the browser’s Save as PDF is the deck as a PDF.
  • Compare. History compares two versions By slide: each slide’s two versions side by side under their versions’ names, paired by id, with changed, added, removed and moved slides said in words, and unchanged ones folded away.
  • Start. New › Deck, or POST /artifacts with "kind": "slides" and "starter": true, begins a deck from the engine’s starter slides.

Part of Crewlet. Generated from crewlet/crewlet main at ee70177.