@aivorynet/slaide 1.0.0
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.
- package/CHANGELOG.md +26 -0
- package/LICENSE +201 -0
- package/README.md +87 -0
- package/bin/slaide.js +25 -0
- package/dist/assets.d.ts +10 -0
- package/dist/assets.js +54 -0
- package/dist/assets.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +433 -0
- package/dist/cli.js.map +1 -0
- package/dist/compare/index.d.ts +24 -0
- package/dist/compare/index.js +246 -0
- package/dist/compare/index.js.map +1 -0
- package/dist/compare/ssim.d.ts +2 -0
- package/dist/compare/ssim.js +46 -0
- package/dist/compare/ssim.js.map +1 -0
- package/dist/compiler/chrome.d.ts +7 -0
- package/dist/compiler/chrome.js +94 -0
- package/dist/compiler/chrome.js.map +1 -0
- package/dist/compiler/compile.d.ts +2 -0
- package/dist/compiler/compile.js +432 -0
- package/dist/compiler/compile.js.map +1 -0
- package/dist/compiler/markdown.d.ts +26 -0
- package/dist/compiler/markdown.js +439 -0
- package/dist/compiler/markdown.js.map +1 -0
- package/dist/compiler/tokens.d.ts +13 -0
- package/dist/compiler/tokens.js +127 -0
- package/dist/compiler/tokens.js.map +1 -0
- package/dist/container.d.ts +47 -0
- package/dist/container.js +309 -0
- package/dist/container.js.map +1 -0
- package/dist/engine-entry.d.ts +1 -0
- package/dist/engine-entry.js +71 -0
- package/dist/engine-entry.js.map +1 -0
- package/dist/export-keynote/keynote.d.ts +10 -0
- package/dist/export-keynote/keynote.js +58 -0
- package/dist/export-keynote/keynote.js.map +1 -0
- package/dist/export-pptx/embed-fonts.d.ts +5 -0
- package/dist/export-pptx/embed-fonts.js +159 -0
- package/dist/export-pptx/embed-fonts.js.map +1 -0
- package/dist/export-pptx/inject-anim.d.ts +28 -0
- package/dist/export-pptx/inject-anim.js +150 -0
- package/dist/export-pptx/inject-anim.js.map +1 -0
- package/dist/export-pptx/pptx.d.ts +10 -0
- package/dist/export-pptx/pptx.js +425 -0
- package/dist/export-pptx/pptx.js.map +1 -0
- package/dist/export-pptx/transitions.d.ts +16 -0
- package/dist/export-pptx/transitions.js +82 -0
- package/dist/export-pptx/transitions.js.map +1 -0
- package/dist/import/emit.d.ts +5 -0
- package/dist/import/emit.js +274 -0
- package/dist/import/emit.js.map +1 -0
- package/dist/import/index.d.ts +21 -0
- package/dist/import/index.js +192 -0
- package/dist/import/index.js.map +1 -0
- package/dist/import/pptx.d.ts +117 -0
- package/dist/import/pptx.js +1043 -0
- package/dist/import/pptx.js.map +1 -0
- package/dist/import/raster-com.d.ts +27 -0
- package/dist/import/raster-com.js +113 -0
- package/dist/import/raster-com.js.map +1 -0
- package/dist/import/raster-extension.d.ts +35 -0
- package/dist/import/raster-extension.js +27 -0
- package/dist/import/raster-extension.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +174 -0
- package/dist/index.js.map +1 -0
- package/dist/install/detect.d.ts +17 -0
- package/dist/install/detect.js +82 -0
- package/dist/install/detect.js.map +1 -0
- package/dist/install/index.d.ts +20 -0
- package/dist/install/index.js +126 -0
- package/dist/install/index.js.map +1 -0
- package/dist/install/registry.d.ts +33 -0
- package/dist/install/registry.js +169 -0
- package/dist/install/registry.js.map +1 -0
- package/dist/install/skills.d.ts +17 -0
- package/dist/install/skills.js +72 -0
- package/dist/install/skills.js.map +1 -0
- package/dist/master-io.d.ts +7 -0
- package/dist/master-io.js +55 -0
- package/dist/master-io.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +114 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/optimize/export-optimize.d.ts +21 -0
- package/dist/optimize/export-optimize.js +167 -0
- package/dist/optimize/export-optimize.js.map +1 -0
- package/dist/parser/frontmatter.d.ts +8 -0
- package/dist/parser/frontmatter.js +45 -0
- package/dist/parser/frontmatter.js.map +1 -0
- package/dist/parser/parse.d.ts +2 -0
- package/dist/parser/parse.js +184 -0
- package/dist/parser/parse.js.map +1 -0
- package/dist/render/anim.d.ts +50 -0
- package/dist/render/anim.js +213 -0
- package/dist/render/anim.js.map +1 -0
- package/dist/render/charts.d.ts +3 -0
- package/dist/render/charts.js +171 -0
- package/dist/render/charts.js.map +1 -0
- package/dist/render/css.d.ts +3 -0
- package/dist/render/css.js +183 -0
- package/dist/render/css.js.map +1 -0
- package/dist/render/echarts-lib.generated.d.ts +1 -0
- package/dist/render/echarts-lib.generated.js +7 -0
- package/dist/render/echarts-lib.generated.js.map +1 -0
- package/dist/render/html.d.ts +5 -0
- package/dist/render/html.js +186 -0
- package/dist/render/html.js.map +1 -0
- package/dist/render/inject.d.ts +12 -0
- package/dist/render/inject.js +19 -0
- package/dist/render/inject.js.map +1 -0
- package/dist/render/mermaid-lib.generated.d.ts +1 -0
- package/dist/render/mermaid-lib.generated.js +7 -0
- package/dist/render/mermaid-lib.generated.js.map +1 -0
- package/dist/render/runtime.d.ts +1 -0
- package/dist/render/runtime.js +393 -0
- package/dist/render/runtime.js.map +1 -0
- package/dist/render-pdf/pdf.d.ts +9 -0
- package/dist/render-pdf/pdf.js +53 -0
- package/dist/render-pdf/pdf.js.map +1 -0
- package/dist/render-png/montage.d.ts +14 -0
- package/dist/render-png/montage.js +75 -0
- package/dist/render-png/montage.js.map +1 -0
- package/dist/render-png/shoot.d.ts +25 -0
- package/dist/render-png/shoot.js +79 -0
- package/dist/render-png/shoot.js.map +1 -0
- package/dist/scaffold.d.ts +9 -0
- package/dist/scaffold.js +36 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/types.d.ts +212 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.js +28 -0
- package/dist/util.js.map +1 -0
- package/package.json +66 -0
- package/skills/slaide/SKILL.md +64 -0
- package/skills/slaide/agents/openai.yaml +12 -0
- package/skills/slaide/examples/branded-deck.slaide +198 -0
- package/skills/slaide/examples/branded-theme.slaide.yaml +187 -0
- package/skills/slaide/examples/sample.slaide +98 -0
- package/skills/slaide/reference.md +177 -0
- package/skills/slaide/themes.md +171 -0
- package/themes/aurora.slaide.yaml +136 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
master: ./vela.slaide.yaml
|
|
3
|
+
title: Vela
|
|
4
|
+
company: Vela, Inc.
|
|
5
|
+
date: "2026"
|
|
6
|
+
author: Vela team
|
|
7
|
+
~transition: fade
|
|
8
|
+
---
|
|
9
|
+
layout: cover
|
|
10
|
+
---
|
|
11
|
+
:: brand ::
|
|
12
|
+
```svg
|
|
13
|
+
<svg width="150" height="42" viewBox="0 0 120 40"><text x="0" y="31" font-family="Open Sans, Inter, sans-serif" font-size="30" font-weight="800" letter-spacing="2" fill="currentColor">VELA</text></svg>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
:: title ::
|
|
17
|
+
[Smart Route]{.grad}
|
|
18
|
+
|
|
19
|
+
:: sub ::
|
|
20
|
+
The spot market for AI compute
|
|
21
|
+
|
|
22
|
+
:: diagram ::
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
layout: team
|
|
27
|
+
chrome: header
|
|
28
|
+
---
|
|
29
|
+
:: title ::
|
|
30
|
+
[Hi!]{.teal} We are
|
|
31
|
+
|
|
32
|
+
:: lname ::
|
|
33
|
+
{.round anchor:"24% 22% 18% 32%"}
|
|
34
|
+
[Alex]{.blue}<br>Rivera
|
|
35
|
+
|
|
36
|
+
:: lbio ::
|
|
37
|
+
Built developer tooling and inference platforms for a decade. Shipped APIs used by thousands of teams.
|
|
38
|
+
|
|
39
|
+
Background across the full stack, from kernels to billing.
|
|
40
|
+
|
|
41
|
+
:: rname ::
|
|
42
|
+
{.round anchor:"73.5% 22% 18% 32%"}
|
|
43
|
+
[Sam]{.teal}<br>Chen
|
|
44
|
+
|
|
45
|
+
:: rbio ::
|
|
46
|
+
Software engineer and product lead. Specializes in user experience and turning messy infra into simple products.
|
|
47
|
+
|
|
48
|
+
M.Sc. in distributed systems.
|
|
49
|
+
|
|
50
|
+
:: logos ::
|
|
51
|
+
**We worked with** {.logo height=30px} {.logo height=30px} {.logo height=30px} {.logo height=30px} {.logo height=30px} {.logo height=30px}
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
layout: content-aside
|
|
55
|
+
footer: "We want to be **the router for compute**"
|
|
56
|
+
---
|
|
57
|
+
:: title ::
|
|
58
|
+
We offer: [Developer Tooling In The Age of AI]{.purple}
|
|
59
|
+
|
|
60
|
+
:: body ::
|
|
61
|
+
| Product | Traction | Status |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| **Route** — smart inference | [2,000+]{.blue.lg} teams | Paying customers |
|
|
64
|
+
| **Forge** — spot brokering | [300+]{.green.lg} clusters | Paid pilots |
|
|
65
|
+
| **Atlas** — capacity float | [18,000+]{.purple.lg} GPUs | Paying customers |
|
|
66
|
+
|
|
67
|
+
:: aside ::
|
|
68
|
+
We test the market and improve the offering. So far, all organic growth.
|
|
69
|
+
|
|
70
|
+
**Zero ad spend.**
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
layout: statement
|
|
74
|
+
footer: "Everyone is building supply. **Nobody is routing demand.**"
|
|
75
|
+
---
|
|
76
|
+
:: title ::
|
|
77
|
+
$765 billion in GPUs. [½ sit idle.]{.blue}
|
|
78
|
+
|
|
79
|
+
:: s1 ::
|
|
80
|
+
[40-80%]{.grad-purple.huge}
|
|
81
|
+
|
|
82
|
+
### Capacity Idle
|
|
83
|
+
|
|
84
|
+
[Inference workloads dip to 15–30% off-peak. A rack of GPUs costs $4M. At 40% utilization, half that investment earns nothing.]{.sm .muted}
|
|
85
|
+
|
|
86
|
+
:: s2 ::
|
|
87
|
+
[10x]{.grad-teal.huge}
|
|
88
|
+
|
|
89
|
+
### Price Spread
|
|
90
|
+
|
|
91
|
+
[Same GPU, same hour: $1.49 to $10.00. Up to 14.5× on spot.]{.sm .muted}
|
|
92
|
+
|
|
93
|
+
:: s3 ::
|
|
94
|
+
[60+]{.grad-blue.huge}
|
|
95
|
+
|
|
96
|
+
### Providers
|
|
97
|
+
|
|
98
|
+
[Tracked and growing. No aggregated spot market exists yet.]{.sm .muted}
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
layout: two-col
|
|
102
|
+
footer: "We take a cut of the spread. **Everybody wins.**"
|
|
103
|
+
---
|
|
104
|
+
:: title ::
|
|
105
|
+
Route the [tokens.]{.orange} Or rent the [GPU.]{.orange}
|
|
106
|
+
|
|
107
|
+
:: left ::
|
|
108
|
+
**Smart inference routing**
|
|
109
|
+
|
|
110
|
+
Drop-in OpenAI-compatible API. **Change one line of code.** Every request scored and routed to the cheapest healthy provider, with auto-failover.
|
|
111
|
+
|
|
112
|
+
**GPU spot brokering**
|
|
113
|
+
|
|
114
|
+
We find and provision the **cheapest spot GPU** for your model. Same scoring, same reliability layer, automatic migration. Up to **80%+ discount**.
|
|
115
|
+
|
|
116
|
+
:: right ::
|
|
117
|
+
| GPU | Pool | $/hr | Trend |
|
|
118
|
+
|---|---|---|---|
|
|
119
|
+
| **B300** · 2100 GB | bolt | **$2.99** | ▲ 20% |
|
|
120
|
+
| **B200** · 1440 GB | bolt | **$2.44** | ▲ 13% |
|
|
121
|
+
| **H200** · 1128 GB | drift | **$0.60** | ▼ 5% |
|
|
122
|
+
| **A100** · 640 GB | bolt | **$0.71** | ▲ 10% |
|
|
123
|
+
| **H100** · 640 GB | bolt | **$1.30** | ▲ 23% |
|
|
124
|
+
| **L40S** · 384 GB | bolt | **$0.55** | ▲ 37% |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
layout: two-col
|
|
128
|
+
footer: "One line of code. **Every provider.**"
|
|
129
|
+
---
|
|
130
|
+
:: title ::
|
|
131
|
+
How [Smart Route]{.grad} works
|
|
132
|
+
|
|
133
|
+
:: left ::
|
|
134
|
+
```mermaid
|
|
135
|
+
flowchart TD
|
|
136
|
+
C([Your app]) -->|OpenAI-compatible API| R{Smart Route}
|
|
137
|
+
R -->|cheapest healthy| A[Provider A]
|
|
138
|
+
R -->|auto-failover| B[Provider B]
|
|
139
|
+
R -->|spot broker| S[(Spot GPU pool)]
|
|
140
|
+
A --> O([Cheapest healthy token])
|
|
141
|
+
B --> O
|
|
142
|
+
S --> O
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
:: right ::
|
|
146
|
+
**Drop-in.** Change one line of code. Every request is scored on **price and health**, then routed to the cheapest healthy provider.
|
|
147
|
+
|
|
148
|
+
**Resilient.** Automatic failover and live migration across **60+ providers** — no lock-in, no babysitting.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
layout: title-content
|
|
152
|
+
footer: "Same GPU, same hour — **up to 10× apart.**"
|
|
153
|
+
---
|
|
154
|
+
:: title ::
|
|
155
|
+
Spot price by GPU [($/hr)]{.muted}
|
|
156
|
+
|
|
157
|
+
:: body ::
|
|
158
|
+
```echart
|
|
159
|
+
{
|
|
160
|
+
"grid": { "left": 64, "right": 28, "top": 28, "bottom": 48 },
|
|
161
|
+
"xAxis": { "type": "category", "data": ["L40S", "H200", "A100", "H100", "B200", "B300"] },
|
|
162
|
+
"yAxis": { "type": "value" },
|
|
163
|
+
"series": [
|
|
164
|
+
{
|
|
165
|
+
"type": "bar",
|
|
166
|
+
"data": [0.55, 0.60, 0.71, 1.30, 2.44, 2.99],
|
|
167
|
+
"barWidth": "52%",
|
|
168
|
+
"itemStyle": { "borderRadius": [10, 10, 0, 0] }
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
layout: media-split
|
|
176
|
+
footer: "Everyone is building supply."
|
|
177
|
+
---
|
|
178
|
+
:: media ::
|
|
179
|
+

|
|
180
|
+
|
|
181
|
+
:: copy ::
|
|
182
|
+
## $765B in racks — [half of it idle.]{.blue}
|
|
183
|
+
|
|
184
|
+
The world is racing to build compute. We make the idle half **earn its keep.**
|
|
185
|
+
|
|
186
|
+
[Photo by Taylor Vick on Unsplash]{.sm .muted}
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
layout: closing
|
|
190
|
+
---
|
|
191
|
+
:: card ::
|
|
192
|
+
```svg
|
|
193
|
+
<svg width="160" height="46" viewBox="0 0 120 40"><text x="0" y="31" font-family="Open Sans, Inter, sans-serif" font-size="30" font-weight="800" letter-spacing="2" fill="currentColor">VELA</text></svg>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### The router for AI compute
|
|
197
|
+
|
|
198
|
+
**Vela, Inc.** · hello@vela.dev · vela.dev
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://getslaide.com/schema/v1.json
|
|
2
|
+
schema: slaide/1
|
|
3
|
+
name: vela
|
|
4
|
+
description: A dark pitch-deck theme — Open Sans, navy ground, multi-accent gradient highlights.
|
|
5
|
+
|
|
6
|
+
canvas: { aspect: "16:9", width: 1920, height: 1080 }
|
|
7
|
+
|
|
8
|
+
fonts:
|
|
9
|
+
sans: { family: "Open Sans", provider: google, weights: [300, 400, 600, 700] }
|
|
10
|
+
display: { family: "Open Sans", provider: google, weights: [800] }
|
|
11
|
+
mono: { family: "IBM Plex Mono", provider: google, weights: [400, 600] }
|
|
12
|
+
|
|
13
|
+
typeScale:
|
|
14
|
+
base: "24px"
|
|
15
|
+
ratio: 1.2
|
|
16
|
+
steps:
|
|
17
|
+
stat: "110px"
|
|
18
|
+
hero: "80px"
|
|
19
|
+
h1: "72px"
|
|
20
|
+
h2: "44px"
|
|
21
|
+
h3: "36px"
|
|
22
|
+
h4: "28px"
|
|
23
|
+
body: "24px"
|
|
24
|
+
caption: "22px"
|
|
25
|
+
small: "18px"
|
|
26
|
+
|
|
27
|
+
colors:
|
|
28
|
+
palette:
|
|
29
|
+
navy: "#0B1220"
|
|
30
|
+
panel: "#121A2B"
|
|
31
|
+
ink: "#050810"
|
|
32
|
+
white: "#F8FAFC"
|
|
33
|
+
muted: "#8B93A7"
|
|
34
|
+
blue: "#5B8CFF"
|
|
35
|
+
purple: "#A855F7"
|
|
36
|
+
teal: "#2DD4BF"
|
|
37
|
+
green: "#34D399"
|
|
38
|
+
orange: "#FB923C"
|
|
39
|
+
pink: "#EC4899"
|
|
40
|
+
roles:
|
|
41
|
+
background: "{palette.navy}"
|
|
42
|
+
surface: "{palette.panel}"
|
|
43
|
+
text: "{palette.white}"
|
|
44
|
+
heading: "{palette.white}"
|
|
45
|
+
accent: "{palette.blue}"
|
|
46
|
+
link: "{palette.blue}"
|
|
47
|
+
muted: "{palette.muted}"
|
|
48
|
+
|
|
49
|
+
gradients:
|
|
50
|
+
brand: "linear-gradient(100deg, #5B8CFF 0%, #A855F7 50%, #2DD4BF 100%)"
|
|
51
|
+
purple: "linear-gradient(120deg, #A855F7, #EC4899)"
|
|
52
|
+
teal: "linear-gradient(120deg, #2DD4BF, #5B8CFF)"
|
|
53
|
+
blue: "linear-gradient(120deg, #5B8CFF, #818CF8)"
|
|
54
|
+
|
|
55
|
+
tokens:
|
|
56
|
+
"--slide-padding": "120px"
|
|
57
|
+
"--chrome-pad": "120px"
|
|
58
|
+
"--chrome-top": "44px"
|
|
59
|
+
"--chrome-bottom": "44px"
|
|
60
|
+
"--chrome-size": "22px"
|
|
61
|
+
"--chrome-foot-size": "40px"
|
|
62
|
+
"--chrome-page-size": "22px"
|
|
63
|
+
"--logo-h": "34px"
|
|
64
|
+
# ordered colour cycle for ```echart data series (falls back to a default palette)
|
|
65
|
+
"--chart-colors": "#5B8CFF, #A855F7, #2DD4BF, #34D399, #FB923C, #EC4899"
|
|
66
|
+
|
|
67
|
+
backgrounds:
|
|
68
|
+
navy: { type: solid, color: "{palette.navy}" }
|
|
69
|
+
team: { type: gradient, stops: ["#0B1220 0%", "#0B1220 50%", "#05070D 50%", "#05070D 100%"], angle: 90 }
|
|
70
|
+
paper: { type: solid, color: "#EEEFF1" }
|
|
71
|
+
|
|
72
|
+
variants:
|
|
73
|
+
light:
|
|
74
|
+
roles: { background: "#EEEFF1", surface: "#FFFFFF", text: "#0B1220", heading: "#0B1220", muted: "#5A6072" }
|
|
75
|
+
|
|
76
|
+
transitions: { default: fade, duration: 420 }
|
|
77
|
+
|
|
78
|
+
chrome:
|
|
79
|
+
header: { right: "{{date}} | © {{company}}" }
|
|
80
|
+
footer: { left: "{{footer}}", right: "{{pagePadded}} / {{totalPadded}}" }
|
|
81
|
+
logoPos: top-left
|
|
82
|
+
logo: '<svg viewBox="0 0 120 40"><text x="0" y="31" font-family="Open Sans, Inter, sans-serif" font-size="30" font-weight="800" letter-spacing="2" fill="currentColor">VELA</text></svg>'
|
|
83
|
+
|
|
84
|
+
layouts:
|
|
85
|
+
cover:
|
|
86
|
+
background: navy
|
|
87
|
+
chrome: header
|
|
88
|
+
logo: false
|
|
89
|
+
align: start
|
|
90
|
+
areas: [". diagram", "brand diagram", "title diagram", "sub diagram"]
|
|
91
|
+
rows: "1fr auto auto auto"
|
|
92
|
+
cols: "1.1fr 0.9fr"
|
|
93
|
+
gap: "0.3em 3em"
|
|
94
|
+
slots:
|
|
95
|
+
brand: { type: body, style: { align: left } }
|
|
96
|
+
title: { type: title, style: { font: display, size: hero, weight: "800", leading: "0.98", maxw: "7ch" } }
|
|
97
|
+
sub: { type: subtitle, style: { size: "32px", color: white, weight: "400" } }
|
|
98
|
+
diagram: { type: image, style: { valign: center } }
|
|
99
|
+
|
|
100
|
+
statement:
|
|
101
|
+
background: navy
|
|
102
|
+
align: center
|
|
103
|
+
areas: ["title title title", "s1 s2 s3"]
|
|
104
|
+
rows: "auto 1fr"
|
|
105
|
+
cols: "1fr 1fr 1fr"
|
|
106
|
+
gap: "1.4em"
|
|
107
|
+
slots:
|
|
108
|
+
title: { type: title, style: { size: "80px", weight: "800" } }
|
|
109
|
+
s1: { type: body, style: { align: center, valign: center } }
|
|
110
|
+
s2: { type: body, style: { align: center, valign: center } }
|
|
111
|
+
s3: { type: body, style: { align: center, valign: center } }
|
|
112
|
+
|
|
113
|
+
title-content:
|
|
114
|
+
background: navy
|
|
115
|
+
areas: ["title", "body"]
|
|
116
|
+
rows: "auto 1fr"
|
|
117
|
+
slots:
|
|
118
|
+
title: { type: title, style: { size: h1, weight: "800" } }
|
|
119
|
+
body: { type: body }
|
|
120
|
+
|
|
121
|
+
content-aside:
|
|
122
|
+
background: navy
|
|
123
|
+
areas: ["title title", "body aside"]
|
|
124
|
+
rows: "auto 1fr"
|
|
125
|
+
cols: "1.45fr 1fr"
|
|
126
|
+
gap: "3em"
|
|
127
|
+
slots:
|
|
128
|
+
title: { type: title, style: { size: h1, weight: "800" } }
|
|
129
|
+
body: { type: body }
|
|
130
|
+
aside: { type: body, style: { color: muted, size: caption } }
|
|
131
|
+
|
|
132
|
+
two-col:
|
|
133
|
+
background: navy
|
|
134
|
+
areas: ["title title", "left right"]
|
|
135
|
+
rows: "auto 1fr"
|
|
136
|
+
cols: "1fr 1fr"
|
|
137
|
+
gap: "3em"
|
|
138
|
+
slots:
|
|
139
|
+
title: { type: title, style: { size: h1, weight: "800" } }
|
|
140
|
+
left: { type: body }
|
|
141
|
+
right: { type: body }
|
|
142
|
+
|
|
143
|
+
team:
|
|
144
|
+
background: team
|
|
145
|
+
areas:
|
|
146
|
+
- "title title"
|
|
147
|
+
- "lname rname"
|
|
148
|
+
- "lbio rbio"
|
|
149
|
+
- "logos logos"
|
|
150
|
+
rows: "auto 400px 1fr auto"
|
|
151
|
+
cols: "1fr 1fr"
|
|
152
|
+
gap: "0.2em 2.4em"
|
|
153
|
+
slots:
|
|
154
|
+
title: { type: title, style: { size: "54px", weight: "800" } }
|
|
155
|
+
lname: { type: title, style: { size: "72px", weight: "800", leading: "0.95", valign: center } }
|
|
156
|
+
lbio: { type: body, style: { size: "28px", color: muted, valign: top } }
|
|
157
|
+
rname: { type: title, style: { size: "72px", weight: "800", leading: "0.95", valign: center } }
|
|
158
|
+
rbio: { type: body, style: { size: "28px", color: muted, valign: top } }
|
|
159
|
+
logos: { type: body, style: { valign: bottom } }
|
|
160
|
+
|
|
161
|
+
closing:
|
|
162
|
+
chrome: false
|
|
163
|
+
background: paper
|
|
164
|
+
align: center
|
|
165
|
+
areas: ["card"]
|
|
166
|
+
rows: "1fr"
|
|
167
|
+
cols: "1fr"
|
|
168
|
+
slots:
|
|
169
|
+
card: { type: body, style: { box: ink, color: white, align: center, valign: center, justify: center, maxw: "60%" } }
|
|
170
|
+
|
|
171
|
+
section:
|
|
172
|
+
background: navy
|
|
173
|
+
align: center
|
|
174
|
+
areas: ["title"]
|
|
175
|
+
rows: "1fr"
|
|
176
|
+
slots:
|
|
177
|
+
title: { type: title, style: { size: hero, weight: "800", align: center } }
|
|
178
|
+
|
|
179
|
+
media-split:
|
|
180
|
+
background: navy
|
|
181
|
+
areas: ["media copy"]
|
|
182
|
+
rows: "1fr"
|
|
183
|
+
cols: "1.25fr 1fr"
|
|
184
|
+
gap: "3.4em"
|
|
185
|
+
slots:
|
|
186
|
+
media: { type: media }
|
|
187
|
+
copy: { type: body, style: { valign: center } }
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
master: ../themes/aurora.slaide.yaml
|
|
3
|
+
title: slaide — Q3 Roadmap
|
|
4
|
+
author: The slaide team
|
|
5
|
+
~transition: slide-left
|
|
6
|
+
---
|
|
7
|
+
layout: cover
|
|
8
|
+
transition: fade
|
|
9
|
+
---
|
|
10
|
+
:: title ::
|
|
11
|
+
slaide
|
|
12
|
+
|
|
13
|
+
:: subtitle ::
|
|
14
|
+
slides that AI can actually write — and humans love to watch
|
|
15
|
+
|
|
16
|
+
??? Open warm. The whole pitch: plain text in, beautiful deck out.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
layout: title-content
|
|
20
|
+
---
|
|
21
|
+
## Why a new language
|
|
22
|
+
|
|
23
|
+
- PowerPoint's `.pptx` is a zip of namespaced XML — **bulky and overloaded** >>>
|
|
24
|
+
- Markdown is what language models write most reliably >>>
|
|
25
|
+
- A forgiving parser means **no broken decks** >>>
|
|
26
|
+
- One small header defines the entire visual system >>>
|
|
27
|
+
|
|
28
|
+
??? Land the contrast: OOXML vs. a single readable file.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
layout: two-cols
|
|
32
|
+
---
|
|
33
|
+
:: title ::
|
|
34
|
+
## Input vs. output
|
|
35
|
+
|
|
36
|
+
:: left ::
|
|
37
|
+
**You write this**
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
---
|
|
41
|
+
layout: image-right
|
|
42
|
+
---
|
|
43
|
+
## The pipeline
|
|
44
|
+
1. Parse
|
|
45
|
+
2. Compile
|
|
46
|
+
3. Render
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
:: right ::
|
|
50
|
+
**Your audience sees**
|
|
51
|
+
|
|
52
|
+
> A typographic, animated, full-bleed presentation — on the web or as a crisp PDF.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
layout: image-right
|
|
56
|
+
morph: hero
|
|
57
|
+
---
|
|
58
|
+
:: title ::
|
|
59
|
+
## The pipeline
|
|
60
|
+
|
|
61
|
+
:: body ::
|
|
62
|
+
1. **Parse** the deck + master >>>
|
|
63
|
+
2. **Compile** to a portable IR >>>
|
|
64
|
+
3. **Validate** against the schema >>>
|
|
65
|
+
4. **Render** to web or PDF >>>
|
|
66
|
+
|
|
67
|
+
:: image ::
|
|
68
|
+
{#hero}
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
layout: image-left
|
|
72
|
+
transition: morph
|
|
73
|
+
---
|
|
74
|
+
:: title ::
|
|
75
|
+
## One IR, many renderers
|
|
76
|
+
|
|
77
|
+
:: image ::
|
|
78
|
+
{#hero}
|
|
79
|
+
|
|
80
|
+
:: body ::
|
|
81
|
+
The compiled **deck.ir.json** is the durable asset.
|
|
82
|
+
|
|
83
|
+
Web and PDF are just *consumers* of it — so they can never drift apart.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
layout: quote
|
|
87
|
+
variant: light
|
|
88
|
+
transition: zoom
|
|
89
|
+
---
|
|
90
|
+
:: quote ::
|
|
91
|
+
> "The best format is the one your tools can write flawlessly **and** your audience never thinks about."
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
layout: section
|
|
95
|
+
transition: zoom
|
|
96
|
+
---
|
|
97
|
+
:: title ::
|
|
98
|
+
Let's build.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# slaide language specification (v1)
|
|
2
|
+
|
|
3
|
+
A **deck** is one UTF-8 `.slaide` file: a deck *headmatter* block + one or more slides. Styling lives in a separate reusable **master** (`*.slaide.yaml`, see [themes.md](themes.md)). Write plain Markdown; reference layouts / colours / fonts / classes **by name** from the master. Reach for explicit positioning (`anchor`, `valign`) only when a layout can't express it.
|
|
4
|
+
|
|
5
|
+
## 1. File structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
--- ← deck HEADMATTER (deck-wide config)
|
|
9
|
+
master: ./theme.slaide.yaml
|
|
10
|
+
title: My Talk
|
|
11
|
+
company: Acme, Inc. ← any scalar key → {{placeholder}}
|
|
12
|
+
~transition: slide-left ← `~` cascades this default to later slides
|
|
13
|
+
---
|
|
14
|
+
layout: cover ← per-slide FRONTMATTER
|
|
15
|
+
footer: Hello world
|
|
16
|
+
---
|
|
17
|
+
:: title :: ← route Markdown into slot "title"
|
|
18
|
+
My Talk
|
|
19
|
+
--- ← slide separator
|
|
20
|
+
## A content slide ← no frontmatter; body → main slot
|
|
21
|
+
- point one >>> ← `>>>` reveals as a build step
|
|
22
|
+
??? Speaker note (hidden from the audience).
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- A line that is exactly `---` separates slides. The **first** config block is headmatter; after a separator, a block is **frontmatter** *iff* it is `key:`-only **and** closed by another `---` before the body — else it's body. (A body first line that merely contains a colon, `We offer: Tooling`, stays body. To force body: an empty frontmatter `---`/`---`, or escape the line `\Name: Acme`.) Malformed config → `bad-config` warning.
|
|
26
|
+
- **Code fences are sigil-safe:** inside ``` / `~~~` everything is literal — sigils (`---`, `:: name ::`, `??? …`, `>>>`), spans, and `![img]` show verbatim, so a deck can show its own source. Outside fences, escape one line with a leading `\`.
|
|
27
|
+
- **Packaging:** the editable form is a folder (deck + master + `assets/`). `slaide pack` zips it into one `.slaidec`; `unpack` reverses. Same language, read transparently; archive is deterministic.
|
|
28
|
+
|
|
29
|
+
## 2. Headmatter keys
|
|
30
|
+
|
|
31
|
+
| Key | Meaning |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `master` | Path to the master (relative to the deck). Omit → bundled default theme. |
|
|
34
|
+
| `title`, `author`, `date`, `company`, … | Metadata. **Any** scalar key here → a `{{placeholder}}` (§7). |
|
|
35
|
+
| `~<key>` | Set a **cascading default** from here onward (e.g. `~transition: fade`). |
|
|
36
|
+
| `progress` | `true`/`false` — web position bar + counter (default `true`; web only, never PDF). |
|
|
37
|
+
|
|
38
|
+
## 3. Per-slide frontmatter keys
|
|
39
|
+
|
|
40
|
+
| Key | Values | Meaning |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `layout` | a master layout name | Which grid to use. |
|
|
43
|
+
| `transition` | `none`,`fade`,`slide-left/right/up/down`,`zoom`,`morph` | Transition **into** this slide. |
|
|
44
|
+
| `background` | a master background name | Override the layout's background. |
|
|
45
|
+
| `variant` | a master variant name | Scoped token overrides (e.g. a light section). |
|
|
46
|
+
| `morph` | an id | Participate in a shared-element morph. |
|
|
47
|
+
| `footer` | inline Markdown | Per-slide footer; also `{{footer}}`. |
|
|
48
|
+
| `chrome` | `both`,`header`,`footer`,`none`,`false` | Header/footer visibility this slide. |
|
|
49
|
+
| `logo` | `false` | Hide the corner logo this slide. |
|
|
50
|
+
| *any other scalar* | — | Available as a `{{placeholder}}`. |
|
|
51
|
+
|
|
52
|
+
**Cascade vs scope:** a bare key (`transition: zoom`) is this-slide-only; a `~`-prefixed key cascades to this slide and every later one until overridden (also valid in headmatter).
|
|
53
|
+
|
|
54
|
+
## 4. Slide body
|
|
55
|
+
|
|
56
|
+
- **Regions:** `:: name ::` on its own line routes following Markdown into slot `name`. Text before any marker → the main slot (`body`, else the first slot).
|
|
57
|
+
- **Markdown:** standard CommonMark — headings, lists, **bold**, *italic*, `code`, fences, > quotes, links, tables, images. (A single newline is a space; blank line = new paragraph.)
|
|
58
|
+
- **Builds `>>>`:** end an item/block with `>>>` to reveal it; steps auto-number in order, same step = simultaneous. PDF shows all.
|
|
59
|
+
- **Notes `??? …`:** a `???` line (until a blank line) is a speaker note — presenter overlay only, hidden from audience and PDF.
|
|
60
|
+
|
|
61
|
+
### 4.1 Inline styled spans — `[text]{.class …}`
|
|
62
|
+
|
|
63
|
+
Wrap inline text with one or more chainable dot-classes:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
[Smart Inference]{.grad} [40-80%]{.grad-purple .huge} [300+]{.green .lg} [caption]{.sm .muted}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Class | Effect |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `.<color>` | text colour — any `palette` key or `roles` name (`.blue`, `.accent`, `.muted`), or a raw hex/CSS colour as an escape hatch (`.#3366ff`, `.tomato`) — palette names preferred |
|
|
72
|
+
| `.grad` / `.grad-<name>` | fill text with the `brand` / a named gradient |
|
|
73
|
+
| `.xs .sm .md .lg .xl .xxl .huge` | font size (type-scale steps small→…→stat) |
|
|
74
|
+
| `.bold` / `.muted` | weight 800 / muted colour |
|
|
75
|
+
|
|
76
|
+
An unknown class warns (`unknown-class`/`unknown-gradient`) — it never silently degrades. Resolved against the master (see [themes.md](themes.md#marks--utility-classes)).
|
|
77
|
+
|
|
78
|
+
### 4.2 Images — `{ … }`
|
|
79
|
+
|
|
80
|
+
Local paths are inlined (portable single file). The `{…}` brace mixes, any order:
|
|
81
|
+
|
|
82
|
+
| Token | Meaning |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `#id` | morph target — same id on the next slide morphs into it (`transition: morph`) |
|
|
85
|
+
| `.class` | `.round` (circular), `.cover` (fill+crop), `.shadow` |
|
|
86
|
+
| `width=170px` / `height=…` | explicit size (bare `key=value`, units ok, unquoted) |
|
|
87
|
+
| `anchor: "x% y% w% h%"` | absolute placement in the slot (quoted) |
|
|
88
|
+
|
|
89
|
+
Example: `{.round width=170px}`
|
|
90
|
+
|
|
91
|
+
### 4.3 Video, audio, embeds
|
|
92
|
+
|
|
93
|
+
Image syntax + a media extension: `{ poster=cover.jpg }` → `<video controls>` (add `.autoplay` for muted looping bg); `` → `<audio>`. In PDF, video → its `poster` (always supply one), audio omitted. Local media inlined up to ~6 MB. For dynamic content (never run in the doc): ` ```embed ` (one URL → sandboxed iframe) and ` ```widget ` (inline HTML/JS → `sandbox="allow-scripts"` srcdoc, theme tokens injected). Both degrade to a static note in PDF.
|
|
94
|
+
|
|
95
|
+
### 4.4 Inline SVG — ` ```svg `
|
|
96
|
+
|
|
97
|
+
A fence tagged `svg` renders as a **vector** (inherits theme colour via `currentColor`). **Give it explicit `width`/`height`** — a zero-intrinsic-size SVG in a centered slot collapses and vanishes silently.
|
|
98
|
+
|
|
99
|
+
### 4.5 Charts — ` ```mermaid ` / ` ```echart `
|
|
100
|
+
|
|
101
|
+
Both render to **theme-coloured inline SVG** (web/PDF/PNG/PPTX); `slaide build` bakes them to static SVG with no engine left in the file.
|
|
102
|
+
- ` ```mermaid ` — diagrams (flowchart, sequence, state, ER, gantt). Match shape to slot: `flowchart TD` tall, `LR` wide.
|
|
103
|
+
- ` ```echart ` — ECharts `option` as JSON/YAML; best for data viz. Validated (bad option → `bad-chart` + code-block fallback). Series colours from the master `--chart-colors`.
|
|
104
|
+
|
|
105
|
+
**Put a chart in a slot with height (a `1fr` row, not `auto`)** or it collapses to a default aspect.
|
|
106
|
+
|
|
107
|
+
```echart
|
|
108
|
+
{ "xAxis": { "type": "category", "data": ["A","B","C"] },
|
|
109
|
+
"yAxis": { "type": "value" },
|
|
110
|
+
"series": [{ "type": "bar", "data": [5,9,7] }] }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 4.6 Tables
|
|
114
|
+
|
|
115
|
+
GFM pipe tables, styled by the master; use `[cell]{.class}` spans for emphasis.
|
|
116
|
+
|
|
117
|
+
## 5. Layers
|
|
118
|
+
|
|
119
|
+
Each slide composites **background → content → chrome** by paint order. Backgrounds come from the master (per layout or per slide); content flows through the layout's named slots; chrome sits on top.
|
|
120
|
+
|
|
121
|
+
## 6. Chrome
|
|
122
|
+
|
|
123
|
+
Defined in the master `chrome:` block (see [themes.md](themes.md#chrome)): header/footer are three-cell bands (`left`/`center`/`right`) with `{{placeholders}}`; a corner `logo` (inline SVG) sits in a chosen corner. Page numbers = `{{page}}`/`{{total}}` in a band. Per-slide `footer:`/`chrome:`/`logo:` override.
|
|
124
|
+
|
|
125
|
+
## 7. Placeholders — `{{ … }}`
|
|
126
|
+
|
|
127
|
+
Resolved at compile time in chrome bands and master text. Built-ins + every scalar headmatter/frontmatter key:
|
|
128
|
+
|
|
129
|
+
| Placeholder | Value |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `{{page}}` / `{{total}}` | 1-based index / count |
|
|
132
|
+
| `{{pagePadded}}` / `{{totalPadded}}` | zero-padded (`05` / `08`) |
|
|
133
|
+
| `{{date}}` | `date:`, else today |
|
|
134
|
+
| `{{title}}` / `{{author}}` / `{{slideTitle}}` | from headmatter / the slide's first heading |
|
|
135
|
+
| `{{footer}}` / `{{<anyKey>}}` | the slide's `footer:` / any scalar key (`{{company}}`) |
|
|
136
|
+
|
|
137
|
+
Unknown names → empty (with a warning).
|
|
138
|
+
|
|
139
|
+
## 8. Reserved sigils (cheat sheet)
|
|
140
|
+
|
|
141
|
+
| Token | Where | Meaning |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `---` | line | slide separator / config fence (outside code fences) |
|
|
144
|
+
| `:: name ::` | line | slot marker |
|
|
145
|
+
| `>>>` | line end | build step |
|
|
146
|
+
| `???` | line start | speaker note |
|
|
147
|
+
| `~key:` | frontmatter | cascading default |
|
|
148
|
+
| `[t]{.c}` | inline | styled span |
|
|
149
|
+
| `{#id .c k=v anchor:"…"}` | after image | attributes |
|
|
150
|
+
| `{{name}}` | chrome/master | placeholder |
|
|
151
|
+
| ` ```svg ` / ` ```embed ` / ` ```widget ` | fence | vector / sandboxed iframe |
|
|
152
|
+
| ` ```mermaid ` / ` ```echart ` | fence | chart → inline SVG |
|
|
153
|
+
| `\` (leading) | before a sigil | escape to literal |
|
|
154
|
+
|
|
155
|
+
## 9. Minimal example
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
---
|
|
159
|
+
master: ./aurora.slaide.yaml
|
|
160
|
+
title: Hello
|
|
161
|
+
---
|
|
162
|
+
layout: cover
|
|
163
|
+
---
|
|
164
|
+
:: title ::
|
|
165
|
+
[Hello, world]{.grad}
|
|
166
|
+
:: subtitle ::
|
|
167
|
+
written in slaide
|
|
168
|
+
---
|
|
169
|
+
layout: title-content
|
|
170
|
+
footer: A first deck
|
|
171
|
+
---
|
|
172
|
+
## Why it's nice
|
|
173
|
+
- Plain text in >>>
|
|
174
|
+
- Beautiful out >>>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
See [themes.md](themes.md) to author a master.
|