lumina-slides 9.0.1 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -180,8 +180,28 @@ engine.load(myDeckData);</code></pre>
180
180
  ]
181
181
  }</code></pre>
182
182
 
183
- <h3>Common slide-level properties</h3>
184
- <p>Any slide can include: <code>sizing</code> (<code>"viewport"</code> | <code>"container"</code>), <code>background</code> (image URL or <code>{ type: "video", src, ... }</code>), <code>notes</code> (speaker notes), <code>class</code>, <code>timelineTracks</code> (for keyframe animations; see <em>Timeline (keyframes)</em>). Layout-specific props (e.g. <code>image</code>, <code>timeline</code>, <code>features</code>) are described in each layout reference.</p>
183
+ <h3>Common slide-level properties (SlideBase)</h3>
184
+ <p>Every slide inherits these optional properties. Layout-specific props are in each layout reference.</p>
185
+ <div class="overflow-x-auto border border-white/10 rounded-lg my-6">
186
+ <table class="w-full text-left text-sm text-gray-400">
187
+ <thead class="bg-white/5 text-white font-bold">
188
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
189
+ </thead>
190
+ <tbody class="divide-y divide-white/5">
191
+ <tr><td class="p-3 font-mono text-blue-400">sizing</td><td class="p-3 font-mono text-xs">"viewport" | "container"</td><td class="p-3">Height behavior. Default: "viewport" (min 100vh). "container" = 100% of parent.</td></tr>
192
+ <tr><td class="p-3 font-mono text-blue-400">background</td><td class="p-3 font-mono text-xs">string | VideoProperties</td><td class="p-3">Image URL or <code>{ type: "video", src, poster?, autoplay?, loop?, muted? }</code>.</td></tr>
193
+ <tr><td class="p-3 font-mono text-blue-400">backgroundOpacity</td><td class="p-3 font-mono text-xs">number</td><td class="p-3">0–1. Default: 1 (or 0.2 for default overlay).</td></tr>
194
+ <tr><td class="p-3 font-mono text-blue-400">notes</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Speaker notes (basic markdown). For exportState and speaker window.</td></tr>
195
+ <tr><td class="p-3 font-mono text-blue-400">class</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Extra CSS class on the slide content container.</td></tr>
196
+ <tr><td class="p-3 font-mono text-blue-400">timelineTracks</td><td class="p-3 font-mono text-xs">Record&lt;id, Keyframes&gt;</td><td class="p-3">Remotion-style: <code>{ [elementId]: { "0": { opacity, x, y, scale, rotate?, visible? }, "1": {...} } }</code>. Use with <code>engine.seekTo(progress)</code>.</td></tr>
197
+ <tr><td class="p-3 font-mono text-blue-400">reveal</td><td class="p-3 font-mono text-xs">RevealInSequenceOptions?</td><td class="p-3">When set, engine runs <code>revealInSequence</code> on ready and slideChange. <code>delayMs</code>, <code>staggerMode</code>, <code>preset</code>, etc.</td></tr>
198
+ <tr><td class="p-3 font-mono text-blue-400">ids</td><td class="p-3 font-mono text-xs">Record&lt;path, string&gt;?</td><td class="p-3">Override element ids: <code>{ "tag": "intro-tag", "features.0": "hero" }</code>. For <code>engine.element(id)</code>.</td></tr>
199
+ <tr><td class="p-3 font-mono text-blue-400">meta</td><td class="p-3 font-mono text-xs">object?</td><td class="p-3">Slide-specific: <code>orbColor</code>, <code>orbPos</code>, <code>backgroundSize</code>, or custom.</td></tr>
200
+ <tr><td class="p-3 font-mono text-blue-400">id</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Unique slide ID. Used by exportState and navigation.</td></tr>
201
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Fallback for exportState/speaker notes when the layout has no required title.</td></tr>
202
+ </tbody>
203
+ </table>
204
+ </div>
185
205
  </div>
186
206
 
187
207
  <!-- SLIDE LAYOUTS -->
@@ -360,7 +380,7 @@ engine.load(myDeckData);</code></pre>
360
380
  <h3>Navigation</h3>
361
381
  <p>Control how users move between slides (buttons, keyboard, touch):</p>
362
382
  <ul>
363
- <li><code>navigation</code> — Master switch. If <code>false</code>, prev/next buttons are disabled and keyboard/touch do nothing. Default: <code>true</code>.</li>
383
+ <li><code>navigation</code> — Master switch. If <code>false</code>, prev/next arrow buttons are hidden and keyboard/touch do nothing. Default: <code>true</code>.</li>
364
384
  <li><code>keyboard</code> — Enable keyboard shortcuts for next/prev. Only applies when <code>navigation</code> is true. Default: <code>true</code>.</li>
365
385
  <li><code>touch</code> — Enable touch/swipe for next/prev. Only applies when <code>navigation</code> is true. Default: <code>true</code>.</li>
366
386
  <li><code>ui.showControls</code> — Show or hide the prev/next (and speaker-notes) buttons in the footer. When hidden, keyboard and touch still work if enabled. Default: <code>true</code>.</li>
@@ -1815,11 +1835,54 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
1815
1835
  <span class="text-gray-500">// "User is on slide ${state.currentSlide.index + 1} (${state.currentSlide.type}). ${state.narrative}"</span></code></pre>
1816
1836
  </div>
1817
1837
 
1838
+ <!-- TEMPLATE TAGS & engine.data -->
1839
+ <div v-else-if="activeSection === 'template-tags'">
1840
+ <h1>Template Tags & Key-Value Store</h1>
1841
+ <p class="lead">Use <code>engine.data</code> as a key-value store and <code v-pre>{{key}}</code> placeholders in slide strings. Values resolve at render time and update reactively when <code>engine.data</code> changes.</p>
1842
+
1843
+ <h2>Key-Value Store (engine.data)</h2>
1844
+ <p>Store and read arbitrary values at any time. Persists across <code>load()</code> and <code>patch()</code>; useful for preferences, flags, or app state to share with your agent or between handlers.</p>
1845
+ <pre><code><span class="text-gray-500">// Set and get</span>
1846
+ engine.data.set(<span class="text-green-400">"theme"</span>, <span class="text-green-400">"dark"</span>);
1847
+ engine.data.get(<span class="text-green-400">"theme"</span>); <span class="text-gray-500">// "dark"</span>
1848
+
1849
+ <span class="text-gray-500">// Check, delete, list keys</span>
1850
+ engine.data.has(<span class="text-green-400">"theme"</span>); <span class="text-gray-500">// true</span>
1851
+ engine.data.delete(<span class="text-green-400">"theme"</span>);
1852
+ engine.data.keys(); <span class="text-gray-500">// ["otherKey", ...]</span>
1853
+
1854
+ <span class="text-gray-500">// Chainable set; clear all</span>
1855
+ engine.data.set(<span class="text-green-400">"a"</span>, <span class="text-cyan-400">1</span>).set(<span class="text-green-400">"b"</span>, <span class="text-cyan-400">2</span>);
1856
+ engine.data.clear();</code></pre>
1857
+
1858
+ <h2>Template Tags in Slide Content</h2>
1859
+ <p>Any string in slide content (title, subtitle, description, features, steps, timeline, etc.) can use <code v-pre>{{key}}</code> placeholders. At render time they are replaced with <code>engine.data.get(key)</code>; missing keys become an empty string. When you change values via <code>engine.data.set(key, value)</code>, the presentation updates automatically.</p>
1860
+ <pre><code>engine.data.set(<span class="text-green-400">"product"</span>, <span class="text-green-400">"Lumina"</span>);
1861
+ engine.data.set(<span class="text-green-400">"version"</span>, <span class="text-green-400">"2.0"</span>);
1862
+ engine.load({
1863
+ meta: { title: <span class="text-green-400">"Welcome"</span> },
1864
+ slides: [
1865
+ { type: <span class="text-green-400">"statement"</span>, title: <span class="text-green-400">"&#123;&#123;product&#125;&#125; v&#123;&#123;version&#125;&#125;"</span>, subtitle: <span class="text-green-400">"Hello &#123;&#123;user&#125;&#125;"</span> }
1866
+ ]
1867
+ });
1868
+ <span class="text-gray-500">// Renders: "Lumina v2.0" / "Hello " (user not set)</span>
1869
+
1870
+ engine.data.set(<span class="text-green-400">"user"</span>, <span class="text-green-400">"World"</span>);
1871
+ <span class="text-gray-500">// Renders: "Lumina v2.0" / "Hello World" (updates in place)</span></code></pre>
1872
+ <p>Keys: letters, numbers, underscore (e.g. <code v-pre>{{name}}</code>, <code v-pre>{{user_name}}</code>). Values are coerced to string; <code>null</code>/<code>undefined</code> → <code>""</code>.</p>
1873
+
1874
+ <p class="mt-8">
1875
+ <router-link to="/deck/layout-template-tags"
1876
+ class="inline-flex items-center gap-2 px-5 py-2.5 rounded-xl bg-blue-500/20 text-blue-400 border border-blue-500/40 hover:bg-blue-500/30 transition font-medium">
1877
+ View Template Tags demo →
1878
+ </router-link>
1879
+ </p>
1880
+ </div>
1881
+
1818
1882
  <!-- REF: STATEMENT -->
1819
1883
  <div v-else-if="activeSection === 'ref-statement'">
1820
1884
  <h1>Statement Slide</h1>
1821
- <p class="lead">Used for high-impact titles, opening covers, or emphatic quotes. It is designed
1822
- to be punchy and minimal.</p>
1885
+ <p class="lead">High-impact titles, opening covers, or emphatic quotes. Punchy and minimal. Supports <code>sizing</code>, <code>background</code>, <code>notes</code>, <code>class</code>, <code>timelineTracks</code>, <code>reveal</code>, <code>ids</code>, <code>meta</code> (SlideBase).</p>
1823
1886
 
1824
1887
  <div class="my-8">
1825
1888
  <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
@@ -1833,34 +1896,14 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
1833
1896
  </tr>
1834
1897
  </thead>
1835
1898
  <tbody class="divide-y divide-white/5">
1836
- <tr>
1837
- <td class="p-3 font-mono text-purple-400">type</td>
1838
- <td class="p-3 font-mono text-xs">"statement"</td>
1839
- <td class="p-3">Required. Identifies the layout.</td>
1840
- </tr>
1841
- <tr>
1842
- <td class="p-3 font-mono text-blue-400">title</td>
1843
- <td class="p-3 font-mono text-xs">string</td>
1844
- <td class="p-3">Main headline. Keep it short (3-6 words).</td>
1845
- </tr>
1846
- <tr>
1847
- <td class="p-3 font-mono text-blue-400">subtitle</td>
1848
- <td class="p-3 font-mono text-xs">string?</td>
1849
- <td class="p-3">Optional supporting text.</td>
1850
- </tr>
1851
- <tr>
1852
- <td class="p-3 font-mono text-blue-400">tag</td>
1853
- <td class="p-3 font-mono text-xs">string?</td>
1854
- <td class="p-3">Small eyebrow tag above the title.</td>
1855
- </tr>
1856
- <tr>
1857
- <td class="p-3 font-mono text-cyan-400">notes</td>
1858
- <td class="p-3 font-mono text-xs">string?</td>
1859
- <td class="p-3">Speaker notes (available on any slide via <code>SlideBase</code>).</td>
1860
- </tr>
1899
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"statement"</td><td class="p-3">Required. Identifies the layout.</td></tr>
1900
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Main headline. Keep it short (3–6 words). Alias: <code>t</code>.</td></tr>
1901
+ <tr><td class="p-3 font-mono text-blue-400">subtitle</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Optional supporting text. Alias: <code>s</code>.</td></tr>
1902
+ <tr><td class="p-3 font-mono text-blue-400">tag</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Small eyebrow tag above the title.</td></tr>
1861
1903
  </tbody>
1862
1904
  </table>
1863
1905
  </div>
1906
+ <p class="text-white/50 text-sm mt-2">Element ids: <code>s{N}-tag</code>, <code>s{N}-title</code>, <code>s{N}-subtitle</code>. Override via <code>ids</code>.</p>
1864
1907
  </div>
1865
1908
 
1866
1909
  <div class="my-8">
@@ -1872,63 +1915,29 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
1872
1915
  <!-- REF: HALF -->
1873
1916
  <div v-else-if="activeSection === 'ref-half'">
1874
1917
  <h1>Half / Split Slide</h1>
1875
- <p class="lead">Image or video on one side, text on the other. Ideal for product showcases or "about me" sections. <strong>One of <code>image</code> or <code>video</code> is required.</strong></p>
1918
+ <p class="lead">Image or video on one side, text on the other. Product showcases, "about me", explainers. <strong>Provide <code>image</code> or <code>video</code> (one required).</strong> Plus SlideBase (sizing, background, notes, class, timelineTracks, reveal, ids, meta).</p>
1876
1919
 
1877
1920
  <div class="my-8">
1878
1921
  <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
1879
1922
  <div class="overflow-x-auto border border-white/10 rounded-lg">
1880
1923
  <table class="w-full text-left text-sm text-gray-400">
1881
1924
  <thead class="bg-white/5 text-white font-bold">
1882
- <tr>
1883
- <th class="p-3 border-b border-white/10">Property</th>
1884
- <th class="p-3 border-b border-white/10">Type</th>
1885
- <th class="p-3 border-b border-white/10">Description</th>
1886
- </tr>
1925
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
1887
1926
  </thead>
1888
1927
  <tbody class="divide-y divide-white/5">
1889
- <tr>
1890
- <td class="p-3 font-mono text-purple-400">type</td>
1891
- <td class="p-3 font-mono text-xs">"half"</td>
1892
- <td class="p-3">Required.</td>
1893
- </tr>
1894
- <tr>
1895
- <td class="p-3 font-mono text-blue-400">image</td>
1896
- <td class="p-3 font-mono text-xs">string?</td>
1897
- <td class="p-3">Image URL. Omit if using <code>video</code>.</td>
1898
- </tr>
1899
- <tr>
1900
- <td class="p-3 font-mono text-blue-400">video</td>
1901
- <td class="p-3 font-mono text-xs">VideoProperties?</td>
1902
- <td class="p-3"><code>{ type: "video", src, autoplay?, muted?, loop? }</code>. Use instead of <code>image</code>.</td>
1903
- </tr>
1904
- <tr>
1905
- <td class="p-3 font-mono text-blue-400">imageSide</td>
1906
- <td class="p-3 font-mono text-xs">"left" | "right"</td>
1907
- <td class="p-3">Which side the media is on. Default: "left".</td>
1908
- </tr>
1909
- <tr>
1910
- <td class="p-3 font-mono text-blue-400">tag</td>
1911
- <td class="p-3 font-mono text-xs">string?</td>
1912
- <td class="p-3">Optional eyebrow label above the title.</td>
1913
- </tr>
1914
- <tr>
1915
- <td class="p-3 font-mono text-blue-400">title</td>
1916
- <td class="p-3 font-mono text-xs">string</td>
1917
- <td class="p-3">Headline text.</td>
1918
- </tr>
1919
- <tr>
1920
- <td class="p-3 font-mono text-blue-400">paragraphs</td>
1921
- <td class="p-3 font-mono text-xs">string[]</td>
1922
- <td class="p-3">Array of text blocks.</td>
1923
- </tr>
1924
- <tr>
1925
- <td class="p-3 font-mono text-blue-400">cta</td>
1926
- <td class="p-3 font-mono text-xs">string?</td>
1927
- <td class="p-3">Optional button label.</td>
1928
- </tr>
1928
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"half"</td><td class="p-3">Required.</td></tr>
1929
+ <tr><td class="p-3 font-mono text-blue-400">image</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Image URL. Omit if using <code>video</code>.</td></tr>
1930
+ <tr><td class="p-3 font-mono text-blue-400">video</td><td class="p-3 font-mono text-xs">VideoProperties?</td><td class="p-3"><code>{ type: "video", src, poster?, autoplay?, loop?, muted?, controls?, className? }</code>. Use instead of <code>image</code>.</td></tr>
1931
+ <tr><td class="p-3 font-mono text-blue-400">imageSide</td><td class="p-3 font-mono text-xs">"left" | "right"</td><td class="p-3">Which side the media is on. Default: "left".</td></tr>
1932
+ <tr><td class="p-3 font-mono text-blue-400">imageClass</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Extra CSS class on the <code>img</code> (e.g. filters, scale).</td></tr>
1933
+ <tr><td class="p-3 font-mono text-blue-400">tag</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Eyebrow label above the title.</td></tr>
1934
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Headline.</td></tr>
1935
+ <tr><td class="p-3 font-mono text-blue-400">paragraphs</td><td class="p-3 font-mono text-xs">string[]</td><td class="p-3">Array of text blocks. Rendered as separate <code>&lt;p&gt;</code>.</td></tr>
1936
+ <tr><td class="p-3 font-mono text-blue-400">cta</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Button label. Click emits <code>action</code> with <code>type: "cta"</code>, <code>label</code>.</td></tr>
1929
1937
  </tbody>
1930
1938
  </table>
1931
1939
  </div>
1940
+ <p class="text-white/50 text-sm mt-2">Element ids: <code>s{N}-media</code>, <code>s{N}-tag</code>, <code>s{N}-title</code>, <code>s{N}-paragraphs</code>, <code>s{N}-cta</code>.</p>
1932
1941
  </div>
1933
1942
 
1934
1943
  <div class="my-8">
@@ -1940,43 +1949,40 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
1940
1949
  <!-- REF: FEATURES -->
1941
1950
  <div v-else-if="activeSection === 'ref-features'">
1942
1951
  <h1>Features Slide</h1>
1943
- <p class="lead">Displays a grid of cards, perfect for listing benefits, stats, or services.</p>
1952
+ <p class="lead">Grid of cards for benefits, stats, or services. Responsive: 1 column on mobile, auto-fit on desktop. SlideBase (sizing, background, notes, class, timelineTracks, reveal, ids, meta) applies.</p>
1944
1953
 
1945
1954
  <div class="my-8">
1946
- <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
1955
+ <h2 class="text-xl font-bold text-white mb-4">Slide configuration</h2>
1947
1956
  <div class="overflow-x-auto border border-white/10 rounded-lg">
1948
1957
  <table class="w-full text-left text-sm text-gray-400">
1949
1958
  <thead class="bg-white/5 text-white font-bold">
1950
- <tr>
1951
- <th class="p-3 border-b border-white/10">Property</th>
1952
- <th class="p-3 border-b border-white/10">Type</th>
1953
- <th class="p-3 border-b border-white/10">Description</th>
1954
- </tr>
1959
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
1955
1960
  </thead>
1956
1961
  <tbody class="divide-y divide-white/5">
1957
- <tr>
1958
- <td class="p-3 font-mono text-purple-400">type</td>
1959
- <td class="p-3 font-mono text-xs">"features"</td>
1960
- <td class="p-3">Required.</td>
1961
- </tr>
1962
- <tr>
1963
- <td class="p-3 font-mono text-blue-400">title</td>
1964
- <td class="p-3 font-mono text-xs">string</td>
1965
- <td class="p-3">Section header.</td>
1966
- </tr>
1967
- <tr>
1968
- <td class="p-3 font-mono text-blue-400">description</td>
1969
- <td class="p-3 font-mono text-xs">string?</td>
1970
- <td class="p-3">Optional context.</td>
1971
- </tr>
1972
- <tr>
1973
- <td class="p-3 font-mono text-blue-400">features</td>
1974
- <td class="p-3 font-mono text-xs">FeatureItem[]</td>
1975
- <td class="p-3">Array: <code>{ class?, title, desc, icon?, id? }</code>. <code>class</code> can be <code>""</code>; <code>desc</code> or <code>description</code>.</td>
1976
- </tr>
1962
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"features"</td><td class="p-3">Required.</td></tr>
1963
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Section header.</td></tr>
1964
+ <tr><td class="p-3 font-mono text-blue-400">description</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Context below the header. Alias: <code>d</code>, <code>desc</code>.</td></tr>
1965
+ <tr><td class="p-3 font-mono text-blue-400">features</td><td class="p-3 font-mono text-xs">FeatureItem[]</td><td class="p-3">Array of feature cards. See FeatureItem below.</td></tr>
1977
1966
  </tbody>
1978
1967
  </table>
1979
1968
  </div>
1969
+
1970
+ <h3 class="text-lg font-bold text-white mt-8 mb-4">FeatureItem (each card)</h3>
1971
+ <div class="overflow-x-auto border border-white/10 rounded-lg">
1972
+ <table class="w-full text-left text-sm text-gray-400">
1973
+ <thead class="bg-white/5 text-white font-bold">
1974
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
1975
+ </thead>
1976
+ <tbody class="divide-y divide-white/5">
1977
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Card title.</td></tr>
1978
+ <tr><td class="p-3 font-mono text-blue-400">description</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Body text. Alias: <code>desc</code>.</td></tr>
1979
+ <tr><td class="p-3 font-mono text-blue-400">icon</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Icon name. Phosphor: <code>ph-star</code>, <code>ph-check</code>; or <code>star</code> (prefix <code>ph-</code> applied).</td></tr>
1980
+ <tr><td class="p-3 font-mono text-blue-400">class</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Extra CSS class on the card. Use <code>""</code> if omitted.</td></tr>
1981
+ <tr><td class="p-3 font-mono text-blue-400">id</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Override for <code>engine.element(id)</code>. Default: <code>s{N}-features-{i}</code>.</td></tr>
1982
+ </tbody>
1983
+ </table>
1984
+ </div>
1985
+ <p class="text-white/50 text-sm mt-2">Element ids: <code>s{N}-header</code>, <code>s{N}-features-0</code>, <code>s{N}-features-1</code>, …</p>
1980
1986
  </div>
1981
1987
 
1982
1988
  <div class="my-8">
@@ -1988,43 +1994,41 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
1988
1994
  <!-- REF: TIMELINE -->
1989
1995
  <div v-else-if="activeSection === 'ref-timeline'">
1990
1996
  <h1>Timeline Slide</h1>
1991
- <p class="lead">Vertical chronological list for events, roadmaps, or history. Do not confuse with <em>Timeline (keyframes)</em> for <code>slide.timelineTracks</code>.</p>
1997
+ <p class="lead">Vertical chronological list for events, roadmaps, or history. Alternating left/right on desktop. <em>Not</em> the same as <code>slide.timelineTracks</code> (keyframe animation). SlideBase applies.</p>
1992
1998
 
1993
1999
  <div class="my-8">
1994
- <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
2000
+ <h2 class="text-xl font-bold text-white mb-4">Slide configuration</h2>
1995
2001
  <div class="overflow-x-auto border border-white/10 rounded-lg">
1996
2002
  <table class="w-full text-left text-sm text-gray-400">
1997
2003
  <thead class="bg-white/5 text-white font-bold">
1998
- <tr>
1999
- <th class="p-3 border-b border-white/10">Property</th>
2000
- <th class="p-3 border-b border-white/10">Type</th>
2001
- <th class="p-3 border-b border-white/10">Description</th>
2002
- </tr>
2004
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2003
2005
  </thead>
2004
2006
  <tbody class="divide-y divide-white/5">
2005
- <tr>
2006
- <td class="p-3 font-mono text-purple-400">type</td>
2007
- <td class="p-3 font-mono text-xs">"timeline"</td>
2008
- <td class="p-3">Required.</td>
2009
- </tr>
2010
- <tr>
2011
- <td class="p-3 font-mono text-blue-400">title</td>
2012
- <td class="p-3 font-mono text-xs">string</td>
2013
- <td class="p-3">Header.</td>
2014
- </tr>
2015
- <tr>
2016
- <td class="p-3 font-mono text-blue-400">subtitle</td>
2017
- <td class="p-3 font-mono text-xs">string?</td>
2018
- <td class="p-3">Optional.</td>
2019
- </tr>
2020
- <tr>
2021
- <td class="p-3 font-mono text-blue-400">timeline</td>
2022
- <td class="p-3 font-mono text-xs">TimelineItem[]</td>
2023
- <td class="p-3">Array: <code>{ date, title, description, icon?, id? }</code>. Aliases: <code>t</code>→title, <code>desc</code>→description.</td>
2024
- </tr>
2007
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"timeline"</td><td class="p-3">Required.</td></tr>
2008
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Header. Alias: <code>t</code>.</td></tr>
2009
+ <tr><td class="p-3 font-mono text-blue-400">subtitle</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Subheader. Alias: <code>s</code>.</td></tr>
2010
+ <tr><td class="p-3 font-mono text-blue-400">timeline</td><td class="p-3 font-mono text-xs">TimelineItem[]</td><td class="p-3">Ordered events. See TimelineItem below. Alias: <code>tl</code>.</td></tr>
2011
+ <tr><td class="p-3 font-mono text-blue-400">lineClass</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Extra CSS class on the vertical connector line.</td></tr>
2012
+ </tbody>
2013
+ </table>
2014
+ </div>
2015
+
2016
+ <h3 class="text-lg font-bold text-white mt-8 mb-4">TimelineItem (each event)</h3>
2017
+ <div class="overflow-x-auto border border-white/10 rounded-lg">
2018
+ <table class="w-full text-left text-sm text-gray-400">
2019
+ <thead class="bg-white/5 text-white font-bold">
2020
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2021
+ </thead>
2022
+ <tbody class="divide-y divide-white/5">
2023
+ <tr><td class="p-3 font-mono text-blue-400">date</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Time marker (e.g. "Q1 2024", "Jan 15", "Now").</td></tr>
2024
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Event title. Alias: <code>t</code>.</td></tr>
2025
+ <tr><td class="p-3 font-mono text-blue-400">description</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Details. Alias: <code>desc</code>, <code>d</code>.</td></tr>
2026
+ <tr><td class="p-3 font-mono text-blue-400">icon</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Phosphor icon. <code>ph-*</code> or short name.</td></tr>
2027
+ <tr><td class="p-3 font-mono text-blue-400">id</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Override for element control. Default: <code>s{N}-timeline-{i}</code>.</td></tr>
2025
2028
  </tbody>
2026
2029
  </table>
2027
2030
  </div>
2031
+ <p class="text-white/50 text-sm mt-2">Element ids: <code>s{N}-title</code>, <code>s{N}-subtitle</code>, <code>s{N}-timeline-0</code>, …</p>
2028
2032
  </div>
2029
2033
 
2030
2034
  <div class="my-8">
@@ -2036,43 +2040,41 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2036
2040
  <!-- REF: STEPS -->
2037
2041
  <div v-else-if="activeSection === 'ref-steps'">
2038
2042
  <h1>Steps Slide</h1>
2039
- <p class="lead">Used for tutorials, "how-to" guides, or process flows.</p>
2043
+ <p class="lead">Numbered steps for tutorials, how-to guides, or process flows. Responsive grid. SlideBase applies.</p>
2040
2044
 
2041
2045
  <div class="my-8">
2042
- <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
2046
+ <h2 class="text-xl font-bold text-white mb-4">Slide configuration</h2>
2043
2047
  <div class="overflow-x-auto border border-white/10 rounded-lg">
2044
2048
  <table class="w-full text-left text-sm text-gray-400">
2045
2049
  <thead class="bg-white/5 text-white font-bold">
2046
- <tr>
2047
- <th class="p-3 border-b border-white/10">Property</th>
2048
- <th class="p-3 border-b border-white/10">Type</th>
2049
- <th class="p-3 border-b border-white/10">Description</th>
2050
- </tr>
2050
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2051
2051
  </thead>
2052
2052
  <tbody class="divide-y divide-white/5">
2053
- <tr>
2054
- <td class="p-3 font-mono text-purple-400">type</td>
2055
- <td class="p-3 font-mono text-xs">"steps"</td>
2056
- <td class="p-3">Required.</td>
2057
- </tr>
2058
- <tr>
2059
- <td class="p-3 font-mono text-blue-400">title</td>
2060
- <td class="p-3 font-mono text-xs">string</td>
2061
- <td class="p-3">Process name.</td>
2062
- </tr>
2063
- <tr>
2064
- <td class="p-3 font-mono text-blue-400">subtitle</td>
2065
- <td class="p-3 font-mono text-xs">string?</td>
2066
- <td class="p-3">Optional.</td>
2067
- </tr>
2068
- <tr>
2069
- <td class="p-3 font-mono text-blue-400">steps</td>
2070
- <td class="p-3 font-mono text-xs">StepItem[]</td>
2071
- <td class="p-3">Array: <code>{ step, title, description?, icon?, id? }</code>. <code>step</code> is e.g. <code>"01"</code>.</td>
2072
- </tr>
2053
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"steps"</td><td class="p-3">Required.</td></tr>
2054
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Process or section header.</td></tr>
2055
+ <tr><td class="p-3 font-mono text-blue-400">subtitle</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Optional subheader.</td></tr>
2056
+ <tr><td class="p-3 font-mono text-blue-400">steps</td><td class="p-3 font-mono text-xs">StepItem[]</td><td class="p-3">Ordered steps. See StepItem below. Alias: <code>st</code>.</td></tr>
2057
+ </tbody>
2058
+ </table>
2059
+ </div>
2060
+
2061
+ <h3 class="text-lg font-bold text-white mt-8 mb-4">StepItem (each step)</h3>
2062
+ <div class="overflow-x-auto border border-white/10 rounded-lg">
2063
+ <table class="w-full text-left text-sm text-gray-400">
2064
+ <thead class="bg-white/5 text-white font-bold">
2065
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2066
+ </thead>
2067
+ <tbody class="divide-y divide-white/5">
2068
+ <tr><td class="p-3 font-mono text-blue-400">step</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Badge label: <code>"01"</code>, <code>"1"</code>, <code>"A"</code>, etc.</td></tr>
2069
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string</td><td class="p-3">Step title.</td></tr>
2070
+ <tr><td class="p-3 font-mono text-blue-400">description</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Body text.</td></tr>
2071
+ <tr><td class="p-3 font-mono text-blue-400">icon</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Phosphor icon; shown as watermark. <code>ph-*</code> or short name.</td></tr>
2072
+ <tr><td class="p-3 font-mono text-blue-400">class</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Extra CSS class on the step card.</td></tr>
2073
+ <tr><td class="p-3 font-mono text-blue-400">id</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Override for element control. Default: <code>s{N}-steps-{i}</code>.</td></tr>
2073
2074
  </tbody>
2074
2075
  </table>
2075
2076
  </div>
2077
+ <p class="text-white/50 text-sm mt-2">Element ids: <code>s{N}-header</code>, <code>s{N}-steps-0</code>, <code>s{N}-steps-1</code>, …</p>
2076
2078
  </div>
2077
2079
 
2078
2080
  <div class="my-8">
@@ -2084,187 +2086,61 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2084
2086
  <!-- REF: FLEX -->
2085
2087
  <div v-else-if="activeSection === 'ref-flex'">
2086
2088
  <h1>Flex Layout</h1>
2087
- <p class="lead">Flow-based layout for composing slides using semantic sizing. No coordinates
2088
- needed—perfect for LLM generation.</p>
2089
+ <p class="lead">Flow-based layout with semantic sizing (quarter, half, full, etc.). No coordinates—ideal for LLMs. SlideBase applies. Top-level and content children can have <code>size?: FlexSize</code>.</p>
2089
2090
 
2090
2091
  <div class="my-8">
2091
- <h2 class="text-xl font-bold text-white mb-4">Slide Options</h2>
2092
+ <h2 class="text-xl font-bold text-white mb-4">Slide options</h2>
2092
2093
  <div class="overflow-x-auto border border-white/10 rounded-lg">
2093
2094
  <table class="w-full text-left text-sm text-gray-400">
2094
2095
  <thead class="bg-white/5 text-white font-bold">
2095
- <tr>
2096
- <th class="p-3 border-b border-white/10">Property</th>
2097
- <th class="p-3 border-b border-white/10">Type</th>
2098
- <th class="p-3 border-b border-white/10">Description</th>
2099
- </tr>
2096
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2100
2097
  </thead>
2101
2098
  <tbody class="divide-y divide-white/5">
2102
- <tr>
2103
- <td class="p-3 font-mono text-purple-400">type</td>
2104
- <td class="p-3 font-mono text-xs">"flex"</td>
2105
- <td class="p-3">Required.</td>
2106
- </tr>
2107
- <tr>
2108
- <td class="p-3 font-mono text-blue-400">direction</td>
2109
- <td class="p-3 font-mono text-xs">"horizontal" | "vertical"</td>
2110
- <td class="p-3">Main flow direction. Default: "horizontal".</td>
2111
- </tr>
2112
- <tr>
2113
- <td class="p-3 font-mono text-blue-400">gap</td>
2114
- <td class="p-3 font-mono text-xs">SpacingToken</td>
2115
- <td class="p-3">Gap between elements. Default: "none".</td>
2116
- </tr>
2117
- <tr>
2118
- <td class="p-3 font-mono text-blue-400">padding</td>
2119
- <td class="p-3 font-mono text-xs">SpacingToken</td>
2120
- <td class="p-3">Container padding. Default: "none".</td>
2121
- </tr>
2122
- <tr>
2123
- <td class="p-3 font-mono text-blue-400">halign</td>
2124
- <td class="p-3 font-mono text-xs">"left" | "center" | "right"</td>
2125
- <td class="p-3">Horizontal alignment of the flex group. Default: "left".</td>
2126
- </tr>
2127
- <tr>
2128
- <td class="p-3 font-mono text-blue-400">valign</td>
2129
- <td class="p-3 font-mono text-xs">"top" | "center" | "bottom"</td>
2130
- <td class="p-3">Vertical alignment of the flex group. Default: "top".</td>
2131
- </tr>
2132
- <tr>
2133
- <td class="p-3 font-mono text-blue-400">elements</td>
2134
- <td class="p-3 font-mono text-xs">FlexElement[]</td>
2135
- <td class="p-3">Array of flex elements in flow order. Each can have <code>size</code> (FlexSize).</td>
2136
- </tr>
2099
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"flex"</td><td class="p-3">Required.</td></tr>
2100
+ <tr><td class="p-3 font-mono text-blue-400">direction</td><td class="p-3 font-mono text-xs">"horizontal" | "vertical"</td><td class="p-3">Main flow. Default: "horizontal".</td></tr>
2101
+ <tr><td class="p-3 font-mono text-blue-400">gap</td><td class="p-3 font-mono text-xs">SpacingToken</td><td class="p-3">none | xs | sm | md | lg | xl | 2xl. Default: "none".</td></tr>
2102
+ <tr><td class="p-3 font-mono text-blue-400">padding</td><td class="p-3 font-mono text-xs">SpacingToken</td><td class="p-3">Container padding. Default: "none".</td></tr>
2103
+ <tr><td class="p-3 font-mono text-blue-400">halign</td><td class="p-3 font-mono text-xs">left | center | right</td><td class="p-3">Default: "left".</td></tr>
2104
+ <tr><td class="p-3 font-mono text-blue-400">valign</td><td class="p-3 font-mono text-xs">top | center | bottom</td><td class="p-3">Default: "top".</td></tr>
2105
+ <tr><td class="p-3 font-mono text-blue-400">elements</td><td class="p-3 font-mono text-xs">FlexElement[]</td><td class="p-3">Flow order. Each: <code>type</code> + type-specific props + optional <code>size</code> (FlexSize).</td></tr>
2137
2106
  </tbody>
2138
2107
  </table>
2139
2108
  </div>
2140
2109
  </div>
2141
2110
 
2142
2111
  <div class="my-8">
2143
- <h2 class="text-xl font-bold text-white mb-4">Size Tokens</h2>
2144
- <p>Each element can have a <code>size</code> property to control how much space it occupies:
2145
- </p>
2146
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 my-6 not-prose">
2147
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>auto</code><br><span
2148
- class="text-xs text-white/40">flexible</span></div>
2149
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>quarter</code><br><span
2150
- class="text-xs text-white/40">25%</span></div>
2151
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>third</code><br><span
2152
- class="text-xs text-white/40">33%</span></div>
2153
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>half</code><br><span
2154
- class="text-xs text-white/40">50%</span></div>
2155
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>two-thirds</code><br><span
2156
- class="text-xs text-white/40">66%</span></div>
2157
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>three-quarters</code><br><span
2158
- class="text-xs text-white/40">75%</span></div>
2159
- <div class="p-4 bg-white/5 rounded-lg text-center"><code>full</code><br><span
2160
- class="text-xs text-white/40">100%</span></div>
2161
- </div>
2112
+ <h2 class="text-xl font-bold text-white mb-4">FlexSize (element width)</h2>
2113
+ <p>Optional <code>size</code> on elements: <code>auto</code> (flex) | <code>quarter</code> (25%) | <code>third</code> (33%) | <code>half</code> (50%) | <code>two-thirds</code> (66%) | <code>three-quarters</code> (75%) | <code>full</code> (100%).</p>
2162
2114
  </div>
2163
2115
 
2164
2116
  <div class="my-8">
2165
- <h2 class="text-xl font-bold text-white mb-4">Element Types</h2>
2117
+ <h2 class="text-xl font-bold text-white mb-4">Element types (top-level and in content)</h2>
2166
2118
  <div class="overflow-x-auto border border-white/10 rounded-lg">
2167
2119
  <table class="w-full text-left text-sm text-gray-400">
2168
2120
  <thead class="bg-white/5 text-white font-bold">
2169
- <tr>
2170
- <th class="p-3 border-b border-white/10">Type</th>
2171
- <th class="p-3 border-b border-white/10">Properties</th>
2172
- <th class="p-3 border-b border-white/10">Description</th>
2173
- </tr>
2121
+ <tr><th class="p-3 border-b border-white/10">type</th><th class="p-3 border-b border-white/10">Properties</th><th class="p-3 border-b border-white/10">Description</th></tr>
2174
2122
  </thead>
2175
2123
  <tbody class="divide-y divide-white/5">
2176
- <tr>
2177
- <td class="p-3 font-mono text-cyan-400">content</td>
2178
- <td class="p-3 font-mono text-xs">elements, valign, halign, gap, padding
2179
- </td>
2180
- <td class="p-3">Container that groups child elements vertically.</td>
2181
- </tr>
2182
- <tr>
2183
- <td class="p-3 font-mono text-cyan-400">image</td>
2184
- <td class="p-3 font-mono text-xs">src, alt?, fill?, fit?, rounded?</td>
2185
- <td class="p-3">Visual media element.</td>
2186
- </tr>
2187
- <tr>
2188
- <td class="p-3 font-mono text-cyan-400">title</td>
2189
- <td class="p-3 font-mono text-xs">text, size?, align?</td>
2190
- <td class="p-3">Large heading (lg | xl | 2xl | 3xl).</td>
2191
- </tr>
2192
- <tr>
2193
- <td class="p-3 font-mono text-cyan-400">text</td>
2194
- <td class="p-3 font-mono text-xs">text, align?, muted?</td>
2195
- <td class="p-3">Body paragraph text.</td>
2196
- </tr>
2197
- <tr>
2198
- <td class="p-3 font-mono text-cyan-400">bullets</td>
2199
- <td class="p-3 font-mono text-xs">items: string[]</td>
2200
- <td class="p-3">Unordered bullet list.</td>
2201
- </tr>
2202
- <tr>
2203
- <td class="p-3 font-mono text-cyan-400">ordered</td>
2204
- <td class="p-3 font-mono text-xs">items: string[]</td>
2205
- <td class="p-3">Numbered list.</td>
2206
- </tr>
2207
- <tr>
2208
- <td class="p-3 font-mono text-cyan-400">button</td>
2209
- <td class="p-3 font-mono text-xs">label, action?, variant?, fullWidth?</td>
2210
- <td class="p-3">CTA button (primary | secondary | outline | ghost).</td>
2211
- </tr>
2212
- <tr>
2213
- <td class="p-3 font-mono text-cyan-400">timeline</td>
2214
- <td class="p-3 font-mono text-xs">items: TimelineItem[], compact?</td>
2215
- <td class="p-3">Embedded timeline.</td>
2216
- </tr>
2217
- <tr>
2218
- <td class="p-3 font-mono text-cyan-400">stepper</td>
2219
- <td class="p-3 font-mono text-xs">items: StepItem[], compact?</td>
2220
- <td class="p-3">Embedded step process.</td>
2221
- </tr>
2222
- <tr>
2223
- <td class="p-3 font-mono text-cyan-400">spacer</td>
2224
- <td class="p-3 font-mono text-xs">size?: SpacingToken</td>
2225
- <td class="p-3">Adds visual spacing.</td>
2226
- </tr>
2124
+ <tr><td class="p-3 font-mono text-cyan-400">content</td><td class="p-3 font-mono text-xs">elements, valign?, halign?, gap?, padding?, size?</td><td class="p-3">Groups children vertically. Children: title, text, bullets, ordered, button, timeline, stepper, spacer (no image/video/nested content).</td></tr>
2125
+ <tr><td class="p-3 font-mono text-cyan-400">image</td><td class="p-3 font-mono text-xs">src, alt?, fill?, fit?, rounded?, href?, target?, class?, size?, id?</td><td class="p-3">Media. fill: edge-to-edge. fit: cover|contain. href+target: link. Rounded: none|sm|md|lg|xl|full.</td></tr>
2126
+ <tr><td class="p-3 font-mono text-cyan-400">video</td><td class="p-3 font-mono text-xs">src, poster?, autoplay?, loop?, muted?, controls?, fill?, fit?, rounded?, class?, size?, id?</td><td class="p-3">Video element. Same fill/fit/rounded as image.</td></tr>
2127
+ <tr><td class="p-3 font-mono text-cyan-400">title</td><td class="p-3 font-mono text-xs">text, size? (lg|xl|2xl|3xl), align?, id?</td><td class="p-3">Heading. align: left|center|right. Top-level only: optional FlexSize <code>size</code>.</td></tr>
2128
+ <tr><td class="p-3 font-mono text-cyan-400">text</td><td class="p-3 font-mono text-xs">text, align?, muted?, size?, id?</td><td class="p-3">Paragraph. muted: subtle style.</td></tr>
2129
+ <tr><td class="p-3 font-mono text-cyan-400">bullets</td><td class="p-3 font-mono text-xs">items: string[], size?, id?</td><td class="p-3">Unordered list.</td></tr>
2130
+ <tr><td class="p-3 font-mono text-cyan-400">ordered</td><td class="p-3 font-mono text-xs">items: string[], size?, id?</td><td class="p-3">Numbered list.</td></tr>
2131
+ <tr><td class="p-3 font-mono text-cyan-400">button</td><td class="p-3 font-mono text-xs">label, action?, actionType?, href?, gotoSlide?, target?, variant?, fullWidth?, size?, id?</td><td class="p-3">actionType: event|url|slide|download. url: href+target. slide: gotoSlide. variant: primary|secondary|outline|ghost.</td></tr>
2132
+ <tr><td class="p-3 font-mono text-cyan-400">timeline</td><td class="p-3 font-mono text-xs">items: TimelineItem[], compact?, size?, id?</td><td class="p-3">Embedded timeline. compact: tighter layout.</td></tr>
2133
+ <tr><td class="p-3 font-mono text-cyan-400">stepper</td><td class="p-3 font-mono text-xs">items: StepItem[], compact?, size?, id?</td><td class="p-3">Embedded steps.</td></tr>
2134
+ <tr><td class="p-3 font-mono text-cyan-400">spacer</td><td class="p-3 font-mono text-xs">size?: SpacingToken, id?</td><td class="p-3">Vertical gap. size: none|xs|sm|md|lg|xl|2xl. Default: md.</td></tr>
2227
2135
  </tbody>
2228
2136
  </table>
2229
2137
  </div>
2138
+ <p class="text-white/50 text-sm mt-2">SpacingToken: <code>none | xs | sm | md | lg | xl | 2xl</code>. Element ids: <code>s{N}-elements-{i}</code>, <code>s{N}-elements-{i}-elements-{j}</code> for content children.</p>
2230
2139
  </div>
2231
2140
 
2232
2141
  <div class="my-8">
2233
- <h2 class="text-xl font-bold text-white mb-4">Content Container</h2>
2234
- <p>Use <code>content</code> to group related elements with alignment control:</p>
2235
- <div class="overflow-x-auto border border-white/10 rounded-lg mt-6">
2236
- <table class="w-full text-left text-sm text-gray-400">
2237
- <thead class="bg-white/5 text-white font-bold">
2238
- <tr>
2239
- <th class="p-3 border-b border-white/10">Property</th>
2240
- <th class="p-3 border-b border-white/10">Values</th>
2241
- <th class="p-3 border-b border-white/10">Default</th>
2242
- </tr>
2243
- </thead>
2244
- <tbody class="divide-y divide-white/5">
2245
- <tr>
2246
- <td class="p-3 font-mono text-blue-400">valign</td>
2247
- <td class="p-3 font-mono text-xs">top | center | bottom</td>
2248
- <td class="p-3">center</td>
2249
- </tr>
2250
- <tr>
2251
- <td class="p-3 font-mono text-blue-400">halign</td>
2252
- <td class="p-3 font-mono text-xs">left | center | right</td>
2253
- <td class="p-3">left</td>
2254
- </tr>
2255
- <tr>
2256
- <td class="p-3 font-mono text-blue-400">gap</td>
2257
- <td class="p-3 font-mono text-xs">none | xs | sm | md | lg | xl | 2xl</td>
2258
- <td class="p-3">md</td>
2259
- </tr>
2260
- <tr>
2261
- <td class="p-3 font-mono text-blue-400">padding</td>
2262
- <td class="p-3 font-mono text-xs">none | xs | sm | md | lg | xl | 2xl</td>
2263
- <td class="p-3">lg</td>
2264
- </tr>
2265
- </tbody>
2266
- </table>
2267
- </div>
2142
+ <h2 class="text-xl font-bold text-white mb-4">Content container (valign, halign, gap, padding)</h2>
2143
+ <p>Defaults: valign <code>center</code>, halign <code>left</code>, gap <code>md</code>, padding <code>lg</code>.</p>
2268
2144
  </div>
2269
2145
 
2270
2146
  <div class="my-8">
@@ -2276,8 +2152,7 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2276
2152
  <!-- REF: CHART -->
2277
2153
  <div v-else-if="activeSection === 'ref-chart'">
2278
2154
  <h1>Chart Slide</h1>
2279
- <p class="lead">Visualize data extracted from CSV/Excel files. Perfect for LLM-generated reports
2280
- and dashboards.</p>
2155
+ <p class="lead">Data visualization with Chart.js. Types: <code>bar</code>, <code>line</code>, <code>pie</code>, <code>doughnut</code>. Requires <code>chart.js</code> as an optional peer. SlideBase applies.</p>
2281
2156
 
2282
2157
  <div class="my-8">
2283
2158
  <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
@@ -2499,31 +2374,10 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2499
2374
  "data": {
2500
2375
  "labels": ["Q1", "Q2", "Q3", "Q4"],
2501
2376
  "datasets": [
2502
- {
2503
- "label": "2023",
2504
- "values": [100, 120, 140, 160],
2505
- "color": "#6b7280"
2506
- },
2507
- {
2508
- "label": "2024",
2509
- "values": [120, 150, 180, 220],
2510
- "color": "c:p"
2511
- }
2377
+ { "label": "2023", "values": [100, 120, 140, 160], "color": "#6b7280" },
2378
+ { "label": "2024", "values": [120, 150, 180, 220], "color": "c:p" }
2512
2379
  ]
2513
- },
2514
- video: `{
2515
- "type": "statement",
2516
- "sizing": "container",
2517
- "meta": { "orbColor": "#ec4899" },
2518
- "background": {
2519
- "type": "video",
2520
- "src": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4",
2521
- "opacity": 0.4
2522
- },
2523
- "tag": "Cinematic",
2524
- "title": "Video Backgrounds",
2525
- "subtitle": "Immersive support."
2526
- }`
2380
+ }
2527
2381
  }' />
2528
2382
  </div>
2529
2383
 
@@ -2590,7 +2444,7 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2590
2444
  <!-- REF: VIDEO -->
2591
2445
  <div v-else-if="activeSection === 'ref-video'">
2592
2446
  <h1>Video Slide</h1>
2593
- <p class="lead">Full-screen video player with optional title overlay (shown on hover).</p>
2447
+ <p class="lead">Full-screen video. <code>video</code> (VideoProperties) is required. Optional <code>title</code> overlay at bottom-left (on hover). SlideBase applies.</p>
2594
2448
 
2595
2449
  <div class="my-8">
2596
2450
  <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
@@ -2659,8 +2513,7 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2659
2513
  <!-- REF: CUSTOM HTML -->
2660
2514
  <div v-else-if="activeSection === 'ref-custom'">
2661
2515
  <h1>Custom HTML Slide</h1>
2662
- <p class="lead">Full control with raw HTML content. Inject any HTML structure with custom
2663
- styling.</p>
2516
+ <p class="lead">Raw <code>html</code> and optional <code>css</code>. For iframes, D3, or brand-specific layouts. SlideBase applies. Sanitized: <code>&lt;script&gt;</code> and <code>on*</code> handlers removed.</p>
2664
2517
 
2665
2518
  <div class="my-8">
2666
2519
  <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
@@ -2737,99 +2590,109 @@ engine.<span class="text-yellow-400">closeSpeakerNotes</span>();</code></pre>
2737
2590
  <!-- REF: DIAGRAM -->
2738
2591
  <div v-else-if="activeSection === 'ref-diagram'">
2739
2592
  <h1>Diagram Slide</h1>
2740
- <p class="lead">Interactive node-based diagram using Vue Flow. Supports nodes, edges, and (in Studio) drag-and-drop and inline editing.</p>
2593
+ <p class="lead">Node-based diagram (Vue Flow). <code>nodes</code> and <code>edges</code> required. In Studio: drag-and-drop, connect, resize. SlideBase applies.</p>
2741
2594
 
2742
2595
  <div class="my-8">
2743
2596
  <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
2744
2597
  <div class="overflow-x-auto border border-white/10 rounded-lg">
2745
2598
  <table class="w-full text-left text-sm text-gray-400">
2746
2599
  <thead class="bg-white/5 text-white font-bold">
2747
- <tr>
2748
- <th class="p-3 border-b border-white/10">Property</th>
2749
- <th class="p-3 border-b border-white/10">Type</th>
2750
- <th class="p-3 border-b border-white/10">Description</th>
2751
- </tr>
2600
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2752
2601
  </thead>
2753
2602
  <tbody class="divide-y divide-white/5">
2754
- <tr>
2755
- <td class="p-3 font-mono text-purple-400">type</td>
2756
- <td class="p-3 font-mono text-xs">"diagram"</td>
2757
- <td class="p-3">Required.</td>
2758
- </tr>
2759
- <tr>
2760
- <td class="p-3 font-mono text-blue-400">nodes</td>
2761
- <td class="p-3 font-mono text-xs">object[]</td>
2762
- <td class="p-3">Vue Flow nodes: <code>id</code>, <code>type</code> (default/input), <code>position</code> <code>{x,y}</code>, <code>label</code>, <code>data</code> (e.g. shape, style).</td>
2763
- </tr>
2764
- <tr>
2765
- <td class="p-3 font-mono text-blue-400">edges</td>
2766
- <td class="p-3 font-mono text-xs">object[]</td>
2767
- <td class="p-3">Vue Flow edges: <code>id</code>, <code>source</code>, <code>target</code>, <code>sourceHandle</code>, <code>targetHandle</code> (optional).</td>
2768
- </tr>
2769
- <tr>
2770
- <td class="p-3 font-mono text-blue-400">config</td>
2771
- <td class="p-3 font-mono text-xs">object?</td>
2772
- <td class="p-3"><code>fitView</code> and other Vue Flow options.</td>
2773
- </tr>
2603
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"diagram"</td><td class="p-3">Required.</td></tr>
2604
+ <tr><td class="p-3 font-mono text-blue-400">title</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Optional header.</td></tr>
2605
+ <tr><td class="p-3 font-mono text-blue-400">nodes</td><td class="p-3 font-mono text-xs">object[]</td><td class="p-3">Vue Flow: <code>id</code>, <code>type</code> (default|input|...), <code>position: { x, y }</code>, <code>label</code>, <code>data?</code> (shape, style).</td></tr>
2606
+ <tr><td class="p-3 font-mono text-blue-400">edges</td><td class="p-3 font-mono text-xs">object[]</td><td class="p-3">Vue Flow: <code>id</code>, <code>source</code>, <code>target</code>, <code>sourceHandle?</code>, <code>targetHandle?</code>.</td></tr>
2607
+ <tr><td class="p-3 font-mono text-blue-400">config</td><td class="p-3 font-mono text-xs">object?</td><td class="p-3"><code>fitView?: boolean</code> and other Vue Flow options.</td></tr>
2774
2608
  </tbody>
2775
2609
  </table>
2776
2610
  </div>
2611
+ <p class="text-white/50 text-sm mt-2">Element control: <code>s{N}-nodes-{i}</code>, <code>s{N}-edges-{i}</code>. Studio: palette, drag, connect, resize.</p>
2777
2612
  </div>
2778
- <p class="text-white/60 text-sm">Element control: <code>s{N}-nodes-{i}</code>, <code>s{N}-edges-{i}</code>. With <code>studio: true</code>, diagrams are editable (add nodes via palette, drag, connect, resize).</p>
2779
2613
  </div>
2780
2614
 
2781
2615
  <!-- REF: FREE -->
2782
2616
  <div v-else-if="activeSection === 'ref-free'">
2783
2617
  <h1>Free / Composition Slide</h1>
2784
- <p class="lead">Absolutely positioned elements (text, image, box) for Remotion-style storytelling. Use <code>timelineTracks</code> to animate <code>x</code>, <code>y</code> (as translate), <code>opacity</code>, etc.</p>
2618
+ <p class="lead">Absolutely positioned elements for Remotion-style storytelling. Three types: <code>text</code>, <code>image</code>, <code>box</code>. Position and animation are driven by <code>slide.timelineTracks</code> (x, y as translate). SlideBase applies.</p>
2785
2619
 
2786
2620
  <div class="my-8">
2787
- <h2 class="text-xl font-bold text-white mb-4">Configuration</h2>
2621
+ <h2 class="text-xl font-bold text-white mb-4">Slide configuration</h2>
2788
2622
  <div class="overflow-x-auto border border-white/10 rounded-lg">
2789
2623
  <table class="w-full text-left text-sm text-gray-400">
2790
2624
  <thead class="bg-white/5 text-white font-bold">
2791
- <tr>
2792
- <th class="p-3 border-b border-white/10">Property</th>
2793
- <th class="p-3 border-b border-white/10">Type</th>
2794
- <th class="p-3 border-b border-white/10">Description</th>
2795
- </tr>
2625
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2796
2626
  </thead>
2797
2627
  <tbody class="divide-y divide-white/5">
2798
- <tr>
2799
- <td class="p-3 font-mono text-purple-400">type</td>
2800
- <td class="p-3 font-mono text-xs">"free"</td>
2801
- <td class="p-3">Required.</td>
2802
- </tr>
2803
- <tr>
2804
- <td class="p-3 font-mono text-blue-400">elements</td>
2805
- <td class="p-3 font-mono text-xs">FreeElement[]</td>
2806
- <td class="p-3">Each: <code>type</code> (<code>"text"</code>|<code>"image"</code>|<code>"box"</code>), <code>text?</code>, <code>src?</code>, <code>width?</code>, <code>height?</code>, <code>fontSize?</code>, <code>color?</code>, <code>fontWeight?</code>, <code>backgroundColor?</code> (box), <code>id?</code>.</td>
2807
- </tr>
2628
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"free"</td><td class="p-3">Required.</td></tr>
2629
+ <tr><td class="p-3 font-mono text-blue-400">elements</td><td class="p-3 font-mono text-xs">FreeElement[]</td><td class="p-3">Array of text, image, or box. See FreeElement below.</td></tr>
2808
2630
  </tbody>
2809
2631
  </table>
2810
2632
  </div>
2633
+
2634
+ <h3 class="text-lg font-bold text-white mt-8 mb-4">FreeElement (each item)</h3>
2635
+ <div class="overflow-x-auto border border-white/10 rounded-lg">
2636
+ <table class="w-full text-left text-sm text-gray-400">
2637
+ <thead class="bg-white/5 text-white font-bold">
2638
+ <tr><th class="p-3 border-b border-white/10">Property</th><th class="p-3 border-b border-white/10">Type</th><th class="p-3 border-b border-white/10">Description</th></tr>
2639
+ </thead>
2640
+ <tbody class="divide-y divide-white/5">
2641
+ <tr><td class="p-3 font-mono text-purple-400">type</td><td class="p-3 font-mono text-xs">"text" | "image" | "box"</td><td class="p-3">Required. <code>text</code>: string content. <code>image</code>: use <code>src</code>. <code>box</code>: colored block, use <code>backgroundColor</code>.</td></tr>
2642
+ <tr><td class="p-3 font-mono text-blue-400">text</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">For <code>type: "text"</code>. Rendered as block.</td></tr>
2643
+ <tr><td class="p-3 font-mono text-blue-400">src</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">For <code>type: "image"</code>. Image URL.</td></tr>
2644
+ <tr><td class="p-3 font-mono text-blue-400">width</td><td class="p-3 font-mono text-xs">number | string?</td><td class="p-3">CSS width. Number → px. String: e.g. <code>"50%"</code>, <code>"10rem"</code>.</td></tr>
2645
+ <tr><td class="p-3 font-mono text-blue-400">height</td><td class="p-3 font-mono text-xs">number | string?</td><td class="p-3">CSS height. Same as width.</td></tr>
2646
+ <tr><td class="p-3 font-mono text-blue-400">fontSize</td><td class="p-3 font-mono text-xs">number | string?</td><td class="p-3">For text. Number → px.</td></tr>
2647
+ <tr><td class="p-3 font-mono text-blue-400">color</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Text color. CSS value.</td></tr>
2648
+ <tr><td class="p-3 font-mono text-blue-400">fontWeight</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">e.g. <code>"bold"</code>, <code>"600"</code>.</td></tr>
2649
+ <tr><td class="p-3 font-mono text-blue-400">backgroundColor</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">For <code>type: "box"</code>. CSS color.</td></tr>
2650
+ <tr><td class="p-3 font-mono text-blue-400">id</td><td class="p-3 font-mono text-xs">string?</td><td class="p-3">Override for <code>timelineTracks</code> and <code>engine.element(id)</code>. Default: <code>s{N}-elements-{i}</code>.</td></tr>
2651
+ </tbody>
2652
+ </table>
2653
+ </div>
2654
+
2655
+ <h3 class="text-lg font-bold text-white mt-8 mb-4">Positioning and animation (timelineTracks)</h3>
2656
+ <p>Elements are placed at <code>left: 0; top: 0</code> by default. To move or animate them, set <code>slide.timelineTracks</code> on the slide (SlideBase). Keys are element ids: <code>s{N}-elements-0</code>, <code>s{N}-elements-1</code>, or the element’s <code>id</code>. Value: keyframes from progress string to state:</p>
2657
+ <ul class="list-disc list-inside text-white/70 my-4 space-y-1">
2658
+ <li><code>opacity</code> (0–1)</li>
2659
+ <li><code>x</code>, <code>y</code> (number, px) → applied as <code>translate(x, y)</code></li>
2660
+ <li><code>scale</code>, <code>rotate</code></li>
2661
+ <li><code>visible</code> (boolean)</li>
2662
+ </ul>
2663
+ <p class="text-white/60 text-sm">Keyframe keys: <code>"0"</code>, <code>"0.25"</code>, <code>"0.5"</code>, <code>"1"</code>, etc. Linear interpolation. Use <code>engine.seekTo(progress)</code> or <code>engine.playTimeline(duration)</code>.</p>
2664
+
2665
+ <h3 class="text-lg font-bold text-white mt-8 mb-4">Example</h3>
2666
+ <pre class="bg-[#0A0A0A] border border-white/10 rounded-xl p-5 overflow-x-auto mb-6 text-sm"><code>{
2667
+ <span class="text-blue-400">"type"</span>: <span class="text-green-400">"free"</span>,
2668
+ <span class="text-blue-400">"elements"</span>: [
2669
+ { <span class="text-blue-400">"type"</span>: <span class="text-green-400">"text"</span>, <span class="text-blue-400">"text"</span>: <span class="text-green-400">"Hello"</span>, <span class="text-blue-400">"fontSize"</span>: <span class="text-cyan-400">48</span> },
2670
+ { <span class="text-blue-400">"type"</span>: <span class="text-green-400">"box"</span>, <span class="text-blue-400">"width"</span>: <span class="text-cyan-400">200</span>, <span class="text-blue-400">"height"</span>: <span class="text-cyan-400">100</span>, <span class="text-blue-400">"backgroundColor"</span>: <span class="text-green-400">"#3b82f6"</span>, <span class="text-blue-400">"id"</span>: <span class="text-green-400">"myBox"</span> }
2671
+ ],
2672
+ <span class="text-blue-400">"timelineTracks"</span>: {
2673
+ <span class="text-green-400">"s0-elements-0"</span>: { <span class="text-green-400">"0"</span>: { <span class="text-blue-400">opacity</span>: <span class="text-cyan-400">0</span>, <span class="text-blue-400">y</span>: <span class="text-cyan-400">20</span> }, <span class="text-green-400">"0.5"</span>: { <span class="text-blue-400">opacity</span>: <span class="text-cyan-400">1</span>, <span class="text-blue-400">y</span>: <span class="text-cyan-400">0</span> } },
2674
+ <span class="text-green-400">"myBox"</span>: { <span class="text-green-400">"0"</span>: { <span class="text-blue-400">x</span>: <span class="text-cyan-400">-50</span>, <span class="text-blue-400">visible</span>: <span class="text-yellow-400">false</span> }, <span class="text-green-400">"0.5"</span>: { <span class="text-blue-400">x</span>: <span class="text-cyan-400">100</span>, <span class="text-blue-400">visible</span>: <span class="text-yellow-400">true</span> } }
2675
+ }
2676
+ }</code></pre>
2811
2677
  </div>
2812
- <p class="text-white/60 text-sm">Element ids: <code>s{N}-elements-0</code>, <code>s{N}-elements-1</code>, … (or custom <code>id</code> on each element). Position is driven by <code>slide.timelineTracks</code>; see <em>Timeline (keyframes)</em>.</p>
2813
2678
  </div>
2814
2679
 
2815
2680
  <!-- REF: AUTO -->
2816
2681
  <div v-else-if="activeSection === 'ref-auto'">
2817
2682
  <h1>Auto Strategy</h1>
2818
- <p class="lead">Smartly chooses the best layout based on the data structure provided. Useful for
2819
- AI agents or rapid prototyping.</p>
2683
+ <p class="lead">Picks a layout from the data shape. Use <code>type: "auto"</code>; the engine resolves to one of: Chart, Timeline, Steps, Features, Half, Statement. All SlideBase and layout-specific props are passed through to the chosen layout. Best for LLMs and rapid prototyping.</p>
2820
2684
 
2821
2685
  <div class="p-6 bg-blue-500/10 border border-blue-500/20 rounded-xl my-8">
2822
- <h3 class="text-blue-400 font-bold mb-2">How it works</h3>
2686
+ <h3 class="text-blue-400 font-bold mb-2">Resolution order (first match wins)</h3>
2823
2687
  <ul class="list-disc list-inside text-sm text-blue-200/80 space-y-1">
2824
- <li>If <code>chartType</code> + <code>data.datasets</code> exist ->
2825
- <strong>Chart</strong>
2826
- </li>
2827
- <li>If <code>timeline</code> array exists -> <strong>Timeline</strong></li>
2828
- <li>If <code>steps</code> array exists -> <strong>Steps</strong></li>
2829
- <li>If <code>features</code> array exists -> <strong>Features</strong></li>
2830
- <li>If <code>image</code> exists -> <strong>Half</strong></li>
2831
- <li>Otherwise -> <strong>Statement</strong></li>
2688
+ <li><code>chartType</code> and <code>data.datasets</code> <strong>Chart</strong></li>
2689
+ <li><code>timeline</code> (array) → <strong>Timeline</strong></li>
2690
+ <li><code>steps</code> (array) → <strong>Steps</strong></li>
2691
+ <li><code>features</code> (array) <strong>Features</strong></li>
2692
+ <li><code>image</code> or <code>video</code> <strong>Half</strong></li>
2693
+ <li>else <strong>Statement</strong> (<code>title</code>, <code>subtitle</code>)</li>
2832
2694
  </ul>
2695
+ <p class="text-blue-200/70 text-sm mt-3">Provide the fields required by the target layout (e.g. <code>features</code> must be FeatureItem[] if resolved to Features).</p>
2833
2696
  </div>
2834
2697
 
2835
2698
  <div class="my-8">
@@ -3206,6 +3069,7 @@ const navigation = [
3206
3069
  { id: 'element-control', label: 'Element Control' },
3207
3070
  { id: 'animations', label: 'Animations (reveal, presets, stagger)' },
3208
3071
  { id: 'timeline-keyframes', label: 'Timeline (keyframes)' },
3072
+ { id: 'template-tags', label: 'Template Tags & engine.data' },
3209
3073
  { id: 'sizing', label: 'Embedding' },
3210
3074
  { id: 'speaker-notes', label: 'Speaker Notes' }
3211
3075
  ]