Open SlideClark · Raw markdown
Version 4.0.0 · canonical copy: https://slideclark.com/ai-guide.md · also inside the app: SlideClark.guide()
SlideClark (called Pitchcraft until October 2026) is a browser presentation studio at https://slideclark.com/app. A deck is plain JSON. You write or edit that JSON, the user opens it in SlideClark, edits it visually and presents it. There is no server: everything is validated and rendered in the user's browser. This guide is generated from the same specs the app runs on, so it is always accurate for version 4.0.0.
Plain-text routes. If your tool rewrites URLs, equals signs or long output, fetch this guide as plain markdown (https://slideclark.com/ai-guide.md) or together with the schema in one file (https://slideclark.com/llms-full.txt). In the page, SlideClark.guide(9) returns one section at a time.
Three ways to build a slide, and you can mix them in one deck.
headline and items. Fast and consistent. Best for plain text, lists and simple charts (section 4).SlideClark API (section 11). Read sections 3 to 10 first so your edits are valid.<deck-name>.sldc whose entire content is the deck JSON. The user drops it onto SlideClark (Open, or drag it anywhere on the page). `json ``` code block, with no commentary inside it. The user copies it and uses Open, then pastes it.... placeholders..sldc (a SlideClark deck) and "format": "slideclark". Files named .pitchcraft with "format": "pitchcraft" are from before the rename. SlideClark still opens them and upgrades them on save, so you may read one, but do not create new ones.{ "format": "slideclark", "version": 3,
"meta": { "name": "Deck title", "theme": "studio", "numbers": false, "transition": "fade" },
"slides": [ { "id": "s1", "layout": "title", "...": "layout fields" } ] }
meta.theme: one of studio, editorial, contrast, aurora, brutal. meta.transition: none, fade, slide, zoom, rise, blur. meta.numbers: show slide numbers. meta.css: optional shared CSS for custom slides (section 9).id (unique, letters digits - _), layout, bg ("", tint, dark, accent, grad), tone (accent colour: coral, amber, teal, green, blue, violet, pink), transition (per-slide override), notes (speaker notes), fill (custom background colour), bgImage (https or data:image/... picture behind everything), objects (section 6), tweaks (section 7).studio: Studio. Clean and confident. Bricolage Grotesque headlines.editorial: Editorial. Instrument Serif on warm paper. Reads like a magazine.contrast: Contrast. Loud, dark and uppercase. Syne headlines. (dark theme)aurora: Aurora. Deep gradients and glass cards. (dark theme)brutal: Brutalist. Hard borders, hard shadows, no apologies.Every slide has exactly one layout. Pick the layout whose fields match your content. Fields not listed for a layout are ignored.
blank: Blank. An empty canvas. Add text, images and shapes anywhere. Fields: objects:[{id,type:"text"|"shape"|"image"|"icon",x,y,w,h?,...}] - the whole slide is free-form objects on the 1280x720 stage (see "Free-form objects" in the AI guide). No kicker/headline/body.title: Title. Big opening statement. Fields: kicker, headline, bodystatement: Statement. One idea, centred. Fields: kicker, headline, bodysection: Section. Chapter divider with a huge number. Fields: kicker (the number, e.g. "02"), headline, bodyquote: Quote. A pull quote with attribution. Fields: headline (the quote), body (who said it)closing: Closing. Final call to action. Fields: kicker, headline, body, items:[{icon?,label,value}]metrics: Metrics. Big-number KPI cards. Fields: kicker, headline, items:[{value,label,trend:"up"|"down"?,note?}] (2-4 items)chart: Chart. Bar, line, area or donut with insight. Fields: kicker, headline, body (insight), chartType:"bar"|"hbar"|"line"|"area"|"donut", chartData:{labels:[],series:[{name,values:[]}]} or {segments:[{label,value}],centerLabel?,centerSub?}, items?:[{value,label}] calloutsdemo: Data → slide. Shows the JSON next to what it renders. Fields: same fields as chart; the code panel is generated from chartDatatable: Table. Reference table. Fields: kicker, headline, tableData:{headers:[],rows:[[]]}split: Split. Two big ideas side by side. Fields: kicker, headline, columns:[{icon?,headline,body}] (2-3)cards: Cards. Three or four icon cards. Fields: kicker, headline, items:[{icon,title,body}] (3-4)comparison: Comparison. Before / after, us / them. Fields: kicker, headline, columns:[{headline,body,items:["line",…]}] (exactly 2; first is the "old", second the "new")bullets: Bullets. Numbered points beside a headline. Fields: kicker, headline, body, items:[{title,body}] (3-5)process: Process. Steps left to right. Fields: kicker, headline, items:[{step?,icon?,title,body}] (3-5)timeline: Timeline. Milestones along a line. Fields: kicker, headline, items:[{date,title,body,status:"done"|"now"|"next"?}] (3-5)flow: Flow diagram. Inputs → hub → outputs. Fields: kicker, headline, items:[{col:"in"|"hub"|"out",icon,title,body}] (1-3 "in", exactly 1 "hub", 1-3 "out")bento: Bento. Mixed-size tile grid. Fields: kicker, headline, items:[{size:"s"|"w"|"t"|"l",tone?,icon?,title,value?,body?}] (aim for tiles that fill a 4x3 grid: e.g. one "l", one "w" and six "s")anatomy: Editor anatomy. Annotated diagram of the editor. Fields: kicker, headline, body, items:[{title,body}] (up to 5; numbered hotspots on a drawing of the editor)themes: Themes. Live previews of the built-in themes. Fields: kicker, headline, items:[{theme:"studio"|"editorial"|"contrast"|"aurora"|"brutal",title,body}]code: Code. Syntax-highlighted window. Fields: kicker, headline, body, code:{language:"json"|"js"|"html"|"css"|"bash",filename?,source}image: Image. Picture beside text. Fields: kicker, headline, body, image:{src (https URL or data URI),alt}custom: HTML, CSS and JS. Write the slide as code: any layout, brand style or animation. Fields: headline (a NAME only, not drawn), custom:{html,css?,js?,base?,interactive?}. html is the whole 1280x720 slide: write anything. See "Custom layout" in the AI guide.Icon names (for icon fields and icon objects): bolt, layers, sparkles, chart, lock, globe, wand, cursor, clock, check, users, user, target, rocket, shield, cpu, box, link, star, type, image, table, pie, terminal, flag, presentation, heart, key, puzzle, git, compass, mail, feather, gauge, edit, tag, map, file, code, download, upload, eye, palette, grid, play
bold, italic, ==accent highlight== and ` code . Use ==highlight==` on one or two words of a headline. Line breaks inside free-form text objects are kept; generated fields are single-line.
Decide per slide. The three routes mix freely, so a deck can be mostly templates with a few custom slides, or custom all the way through.
meta.css. Custom slides cost more effort to write, and they are edited as code rather than field by field.objects; they float above the layout. Good for a logo, a sticker, an annotation.If the user said nothing about style, a good default is templates for the plain slides and custom slides for the two or three that carry the story.
objects is an array, drawn in order: later items are on top. The stage is 1280 wide, 720 tall, origin top-left, all units are pixels, rot is degrees clockwise. Maximum 120 objects per slide.
Common fields: id (unique on the slide; generated if you omit it), type, x, y, w, h (optional for text: it grows with its content), rot, opacity (0 to 1), shadow (true), name (label shown in the editor's layers list), flipH / flipV (mirror), locked (the editor will not move or edit it), group (objects sharing a group id select and move together), link (https://, mailto: or #slide-id, followed when presenting), alt (alternative text for shapes, icons and lines).
A slide can also be hidden from the presentation with "hidden": true (it stays in the editor and is skipped when presenting and exporting to PDF).
| type | extra fields |
|---|---|
text | text, font, size (px), weight (100 to 900), italic, underline, caps (uppercase), align (left, center, right, justify), valign (top, middle, bottom; only when h is set), color, lh (line height multiple), ls (letter spacing in em) |
shape | shape, fill, fill2 + gradAngle (a two-colour gradient), stroke, strokeW, dash (solid, dashed, dotted), radius (rect only), and all the text fields above for text inside the shape. Put a label in the shape's own text; do not lay a separate text object over it |
line | kind (straight, elbow for right-angle corners, curve), stroke, strokeW, dash, arrowStart / arrowEnd (none, triangle, stealth, open, dot, diamond), vert (elbow and curve leave vertically instead of horizontally), bend (0.05 to 0.95: where the middle run sits), from / to (glue an end to another object: "objectId:t", :r, :b or :l; the line follows when that object moves). The start is the top-left of the box and the end the bottom-right, unless flipH / flipV mirror it |
image | src (https URL or data:image/...), alt (always write it), fit (cover, contain, fill), radius, stroke, strokeW |
icon | icon (name from the list in section 4), color |
Shapes: rect (Rectangle), round (Rounded rectangle), ellipse (Ellipse), triangle (Triangle), diamond (Diamond), hexagon (Hexagon), star (Star), arrow (Right arrow), chevron (Chevron), arrowleft (Left arrow), arrowup (Up arrow), arrowdown (Down arrow), arrowboth (Left-right arrow), pentagon (Pentagon), octagon (Octagon), parallelogram (Parallelogram), trapezoid (Trapezoid), plus (Cross), callout (Speech bubble), donut (Ring), cylinder (Cylinder), heart (Heart), line (Line (old)), connector (Arrow line (old)). For a diagram, glue connectors to boxes with from / to rather than guessing coordinates: { "type": "line", "kind": "elbow", "from": "a:r", "to": "b:l", "arrowEnd": "triangle", "stroke": "var(--muted)", "strokeW": 3 }. Their x, y, w, h are recomputed from the glue.
Fonts (font): body (Theme body), display (Theme heading), inter (Inter), bricolage (Bricolage Grotesque), serif (Instrument Serif), syne (Syne), mono (JetBrains Mono), arial (Arial), georgia (Georgia), times (Times New Roman), verdana (Verdana), trebuchet (Trebuchet MS), courier (Courier New), dmsans (DM Sans), manrope (Manrope), plusjakartasans (Plus Jakarta Sans), spacegrotesk (Space Grotesk), outfit (Outfit), montserrat (Montserrat), worksans (Work Sans), sora (Sora), figtree (Figtree), urbanist (Urbanist), poppins (Poppins), raleway (Raleway), nunito (Nunito), lato (Lato), rubik (Rubik), archivo (Archivo), epilogue (Epilogue), ibmplexsans (IBM Plex Sans), josefinsans (Josefin Sans), quicksand (Quicksand), cabin (Cabin), playfairdisplay (Playfair Display), lora (Lora), fraunces (Fraunces), sourceserif4 (Source Serif 4), cormorantgaramond (Cormorant Garamond), librebaskerville (Libre Baskerville), dmserifdisplay (DM Serif Display), oswald (Oswald), anton (Anton), bebasneue (Bebas Neue), abrilfatface (Abril Fatface), pacifico (Pacifico), lobster (Lobster), caveat (Caveat), spacemono (Space Mono), ibmplexmono (IBM Plex Mono), firacode (Fira Code), inconsolata (Inconsolata). Any other plain family name (letters, digits, spaces and - . _ & +) also works but only renders if installed on the viewer's machine, so prefer the keys. They are all bundled and load on demand.
Colours (color, fill, stroke): hex (#1a1a2e), rgb()/rgba(), a plain colour name, or a theme token that follows the deck theme and the slide background. Prefer tokens so the slide survives a theme change: var(--fg) text, var(--muted) muted text, var(--shape) accent, var(--on-shape) on accent, var(--card) card, var(--slide-bg) background, #ffffff white, #000000 black, var(--c1) palette 1, var(--c2) palette 2, var(--c3) palette 3, var(--c4) palette 4, var(--c5) palette 5, var(--c6) palette 6.
Defaults when a field is omitted:
text: w 520, size 36, weight 400, font "body", align "left", valign "top", color "var(--fg)", lh 1.25, ls 0shape: w 260, h 160, shape "rect", fill "var(--shape)", stroke "", strokeW 0, radius 0, dash "solid", size 28, weight 600, font "body", align "center", valign "middle", color "var(--on-shape)", lh 1.2, ls 0image: w 480, h 320, fit "cover", radius 0, stroke "", strokeW 0icon: w 96, h 96, color "var(--shape)"line: w 320, h 0, kind "straight", stroke "var(--shape)", strokeW 5, dash "solid", arrowStart "none", arrowEnd "none", bend 0.5Rules for good free-form slides:
font: "display".var(--on-shape); on the slide use var(--fg).w for its longest line; it wraps inside w.Every editable text in a template slide has a path (headline, body, kicker, items.1.title) and every card or row has an item key (items.1). tweaks nudges or restyles them without leaving the layout:
"tweaks": { "headline": { "dx": 40, "dy": -20, "size": 96, "color": "var(--shape)" }, "items.1": { "dx": 0, "dy": 24 } }
dx and dy are pixel offsets. Text fields also accept font, size, weight, italic, underline, caps, align, color, lh, ls. Tweaks are optional: do not add them unless the user asks for a specific move or restyle.
title slide, end with a closing slide.bg (dark, accent, tint) every few slides for rhythm.[NEEDS EVIDENCE] or label the kicker "Sample data".bg and fill on the same slide (bg wins).notes) when the user will be presenting.Slides are read in seconds, so weak writing shows. Write natural, precise British English, the way a knowledgeable person with one specific point to make would write it. Aim for clarity and accuracy, not polish, enthusiasm or impact. Swapping banned words for synonyms is not enough: avoid the patterns underneath (artificial contrast, neat triads, manufactured punchiness, inflated abstraction, repeated summaries).
Titles and headings
Start and end
Words
Sentences and structure
Claims and tone
{ "id": "s5", "layout": "custom", "headline": "short name", "custom": { "html": "...", "css": "...", "js": "...", "interactive": false } }
custom.html is the whole 1280 x 720 slide body (no <html>, <head> or <script>). The root is an empty position:relative; overflow:hidden box: use absolute positioning, grid, flex, inline SVG or canvas.js runs. What is blocked: external scripts (<script src>), iframes, forms, fetch and other network calls, and storage. Images and fonts: data: URIs always work; https: images and fonts load but may fail offline, so embed brand assets.var(--fg), var(--muted), var(--acc), var(--on-acc), var(--slide-bg), var(--card), var(--line), var(--radius), var(--shadow), var(--c1) to var(--c6), var(--font-d), var(--font-b), var(--f-mono). Helper classes: .kicker, .display, .h2, .lead, mark.hl, .rv (fades up when presenting).@font-face, logo classes) belongs in meta.css, not in each slide.interactive: true only if the slide has buttons or inputs.style on that element (translate or left/top, width/height, color, font-*, background-color ...), so when you are later asked to edit the slide, read the style attributes and keep them. To make your slide pleasant to edit, build it from real elements: give the main blocks an id or a meaningful class, put each text in its own element (h1, p, div), prefer absolute or flex/grid layout over text tricks, and put repeated styling in css or meta.css rather than relying on js to restyle things. Elements a script creates have no place in the HTML, so they cannot be selected (their container can).js. They draw the slide from html + css, so it must look complete before js runs. If something only appears after js runs (a canvas, ripples, counters), the sidebar thumbnail will not show it. That is expected.prefers-reduced-motion.Headline fonts differ a lot. The Contrast theme sets headlines in uppercase Syne ExtraBold, roughly twice the width of Editorial's serif. Do not assume a character is half its font size. Estimate with these averages (em per character, measured on mixed English text; multiply by the font size in px to get the width of one character):
| theme | headline font | em per character, headline | em per character, body |
|---|---|---|---|
studio | Bricolage Grotesque | 0.47 | 0.48 |
editorial | Instrument Serif | 0.33 | 0.48 |
contrast | Syne, UPPERCASE | 1.01 | 0.48 |
aurora | Bricolage Grotesque | 0.47 | 0.48 |
brutal | Syne | 0.77 | 0.48 |
Characters per line is about box width / (font size x em). Example: a 900 px box at 64 px in Contrast fits about 900 / (64 x 1.01) = 13 characters per line; in Editorial it fits about 42. Size from the widest theme the deck might use, or measure: SlideClark.measureText("Quarterly results", { font: "display", size: 72, w: 900 }) returns the real width, height and line count in the current theme. Long words never wrap, so check the longest word.
SlideClark.audit() cannot see inside a custom slide (the slide is a sandboxed iframe), so it returns checked: false for those. Use await SlideClark.auditAll(): it runs each custom slide in a hidden sandbox, waits for its js and fonts, and measures the rendered text. It reports text-off-slide, outside-safe-area, clipped (hidden by an overflow:hidden container), text-wider-than-box, text-overlap and script-error. It checks text only: it cannot judge colour contrast, images or canvas drawings, so still look at a screenshot when you can.
SlideClark.addCustomSlide({
html: '<div class="wrap"><h1>Hello</h1><canvas id="c" width="600" height="300"></canvas></div>',
css: '.wrap{position:absolute;inset:0;padding:90px} h1{font:800 96px var(--font-d);margin:0}',
js: 'const c=document.getElementById("c").getContext("2d"); c.fillStyle="#5b4bff"; c.fillRect(0,0,300,150);',
interactive: false
}, undefined, "Hello"); // returns the slide index
SlideClark.setCustom(2, { css: "h1{color:var(--acc)}" }); // patch one field later
SlideClark.setMeta({ css: "@font-face{...} .logo{...}" }); // brand CSS shared by every custom slide
The machine-readable description of all of this is the JSON Schema: SlideClark.schema(), or https://slideclark.com/slideclark.schema.json.
This deck is validated against the importer when the guide is built.
{
"format": "slideclark",
"version": 3,
"meta": {
"name": "Quarterly review",
"theme": "studio",
"numbers": false,
"transition": "fade"
},
"slides": [
{
"id": "s1",
"layout": "title",
"kicker": "Q3 review",
"headline": "Growth, **on purpose**",
"body": "What worked, what did not, and what we do next",
"notes": "Open with the headline number."
},
{
"id": "s2",
"layout": "blank",
"notes": "One big number, placed by hand.",
"objects": [
{
"id": "label",
"type": "text",
"x": 80,
"y": 90,
"w": 700,
"text": "Revenue growth",
"size": 28,
"weight": 700,
"caps": true,
"ls": 0.08,
"color": "var(--shape)"
},
{
"id": "big",
"type": "text",
"x": 80,
"y": 150,
"w": 720,
"text": "**42%**",
"size": 220,
"weight": 800,
"font": "display",
"lh": 1
},
{
"id": "card",
"type": "shape",
"shape": "round",
"x": 820,
"y": 150,
"w": 380,
"h": 300,
"fill": "var(--shape)",
"text": "Sample data: replace with your number",
"size": 30,
"color": "var(--on-shape)"
},
{
"id": "rule",
"type": "shape",
"shape": "line",
"x": 80,
"y": 520,
"w": 1120,
"h": 14,
"stroke": "var(--muted)",
"strokeW": 3
},
{
"id": "note",
"type": "text",
"x": 80,
"y": 560,
"w": 1000,
"text": "Quarter on quarter, all regions. Source: [NEEDS EVIDENCE]",
"size": 26,
"color": "var(--muted)"
}
]
},
{
"id": "s3",
"layout": "closing",
"kicker": "Next",
"headline": "Three bets for Q4",
"body": "We will know by December.",
"tweaks": {
"headline": {
"dy": -10
}
}
}
]
}
When SlideClark is open in the tab you control, use the global SlideClark object (for example through the page's JavaScript console). The old name Pitchcraft is kept as an alias of the same object, so a script written for it still runs. There is no separate "AI import" button because you do not need one: SlideClark.importText(json) loads a whole deck, SlideClark.addCustomSlide(...) adds an HTML/CSS/JS slide, and SlideClark.schema() / SlideClark.manifest() describe everything. (Humans use the AI button, then Import.) Every call is validated and undoable (the user can press Ctrl+Z). ref is a slide id ("s3") or a 0-based index.
Read
SlideClark.guide(section?): The complete AI guide as markdown (this document). Pass a section number such as 9, or a word from its heading, to get just that part. Read it before editing.SlideClark.manifest(): JSON: version, guide URL, every method below, layouts, themes, object types, limits.SlideClark.getDeck(): Copy of the whole deck JSON.SlideClark.getSlide(ref): Copy of one slide. ref = slide id ("s3") or 0-based index.SlideClark.getObjects(ref): Copy of the free-form objects on a slide.SlideClark.html(ref): The rendered HTML of one slide (what the DOM contains).SlideClark.prettyHtml(ref): The same, indented for reading.SlideClark.exportPptx(): Async. Builds a native PowerPoint file from the deck and returns { filename, base64, report } (report lists slides, pictures, fonts and warnings). Text stays editable text; shapes stay shapes. Does not download anything; save the base64 yourself.SlideClark.exportJSON(): The deck as a JSON string, exactly what a .sldc file contains.SlideClark.audit(deck?): Fast layout audit of templated and blank slides: finds text that clips or leaves the safe area. Returns one entry per slide with a problems list. It cannot see inside custom slides: those come back with status "unknown", checked:false and problems:null (never an empty list that looks clean). Use auditAll() for them.SlideClark.auditAll(deck?): Async. Everything audit() does, plus it runs each custom slide in a hidden sandbox and measures the rendered text: text off the slide, outside the safe area, clipped by its container, overlapping other text, short labels that wrap (label-wraps), text that straddles a box edge (text-crosses-edge) and text jammed against its box (text-cramped). Each entry has status "clean", "issues" or "unknown". The first measurement is retried once with more time. Await it.SlideClark.measureText(text, opts?): Measure text before you place it. opts {font "display"|"body"|"mono"|a CSS family, size (px, default 28), weight, caps, ls, lh, w (box width px)}. Returns {width, height, lines, em}: width of the longest line, height at the wrapped width, and the average em per character in this theme.SlideClark.current(): Index of the selected slide.SlideClark.count(): Number of slides.SlideClark.schema(): JSON Schema (draft 2020-12) of a deck, including slide custom {html, css, js}, objects and tweaks. Also published as slideclark.schema.json.Deck
SlideClark.shareLink(): Async. A link that contains this whole deck (nothing is uploaded). Returns the URL, or an empty string when the deck is too big for a link: use exportJSON() or save the file instead.SlideClark.setDeck(deckOrJson): Replace the whole deck (object or JSON string). Returns {slides, warnings}. Undoable. The deck it replaced is kept in backups().SlideClark.backups(): The last few decks that were replaced or undone away: [{index, title, slides, reason, t}]. They survive a reload.SlideClark.restoreBackup(index): Put one of those decks back. Undoable. Returns true on success.SlideClark.importPptx(base64OrBytes, mode?, name?): Async. Open a PowerPoint (.pptx) file as HTML slides. data = base64 string or Uint8Array; mode "replace" (default) or "append". Every slide becomes a custom HTML slide (text, shapes, pictures, tables and simple charts positioned on the 1280x720 stage). Returns {deck, warnings, report}; warnings list what could not be carried over.SlideClark.importText(text, mode?): Open deck JSON text (what the Open dialog does with pasted or dropped text). mode "replace" (default) or "append". Returns {deck, warnings}.SlideClark.setMeta(patch): Patch deck meta: {name, theme, numbers, transition, css}.SlideClark.setTheme(theme): Set the deck theme key.SlideClark.newDeck(): Replace the deck with a fresh one-slide deck (the starter). Undoable. The New deck button asks the user to save first; this call does not.SlideClark.loadTemplate(id): Load a built-in template deck (for example "tour").Slides
SlideClark.addSlide(layout, at?): Insert a slide with a layout key at an index. Returns its index. Use "blank" for a free-form slide.SlideClark.removeSlide(ref): Delete a slide.SlideClark.duplicateSlide(ref): Duplicate a slide.SlideClark.moveSlide(from, to): Reorder slides.SlideClark.updateSlide(ref, patch): Shallow-merge a patch into a slide (validated). Returns the slide.SlideClark.setPath(ref, path, value): Set one nested field, for example setPath("s2", "items.0.value", "42").SlideClark.setLayout(ref, layout): Change a slide layout, keeping compatible content. To blank converts the text to text boxes.SlideClark.addCustomSlide(custom, at?, name?): Add a free-form HTML/CSS/JS slide in one call. custom = {html, css, js, interactive}. Returns its index. See section 9 of the guide.SlideClark.setCustom(ref, patch): Patch the html, css, js or interactive flag of a custom slide (converts the slide to custom first if it is not one). Returns the slide.SlideClark.goTo(ref): Select and scroll to a slide.Objects
SlideClark.addObject(ref, object): Add a free-form object (text, shape, image or icon) to any slide. Returns the cleaned object with its id. Sits on top of the stack.SlideClark.updateObject(ref, id, patch): Patch an object. A null value removes a property. Returns the cleaned object.SlideClark.removeObject(ref, id): Delete an object. Returns true. Throws (listing the existing ids) if the id is not on that slide.SlideClark.setTweak(ref, key, patch): Move or restyle a text field or card that a template layout generated. key = data-path ("headline") or list item ("items.1"). A patch of null resets it.Present
SlideClark.preparePrint(): Builds the print layout (one page per slide) that the PDF button uses. Rarely needed by an AI.SlideClark.present(from?): Start presenting from a slide index.SlideClark.closePresent(): Stop presenting.SlideClark.isPresenting(): True while presenting.History
SlideClark.undo(): Undo the last change.SlideClark.redo(): Redo.Workflow:
SlideClark.guide() (this document; SlideClark.guide(9) for one section) and SlideClark.getDeck() to understand the current state. If your tool mangles URLs or equals signs in long output, use the plain-text copies named at the top of this guide.updateObject, setPath, setCustom and setTweak over replacing whole slides.await SlideClark.auditAll() afterwards: every slide's problems list should be empty and checked should be true. Fix what it reports. SlideClark.audit() is the instant version and marks custom slides checked: false.Direct DOM route (read-only, useful for finding things): every slide is <section data-slide-id="s1" data-layout="title">; every editable text has data-path; free-form objects are .ob[data-obj="<id>"]. Custom slides render in a sandboxed iframe, so edit their custom.html/custom.css/custom.js strings instead.
Examples:
SlideClark.addSlide("blank"); // returns the new index
SlideClark.addObject(2, { type: "text", text: "Q3 results", x: 80, y: 80, w: 900, size: 72, weight: 700, font: "display" });
SlideClark.addObject(2, { type: "shape", shape: "round", x: 80, y: 260, w: 360, h: 200, fill: "var(--shape)", text: "**42%** growth", color: "var(--on-shape)" });
SlideClark.updateObject(2, "o1", { x: 120, size: 64 });
SlideClark.setTweak("s1", "headline", { dx: 0, dy: -30, size: 88 });
SlideClark.setPath("s3", "items.0.value", "42");
format: "slideclark", version: 3, unique slide ids.layout is one of: blank, title, statement, section, quote, closing, metrics, chart, demo, table, split, cards, comparison, bullets, process, timeline, flow, bento, anatomy, themes, code, custom, image.type; image objects have alt.await SlideClark.auditAll() shows no problems and every slide checked: true..sldc file, or one JSON code block if files are impossible.