rikiki-deck 0.3.1 → 0.4.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/README.md +2 -0
- package/bin/lib/inline.mjs +231 -0
- package/bin/lib/starter.mjs +83 -0
- package/bin/rikiki.mjs +150 -0
- package/dist/deck-badge.js +1 -1
- package/dist/deck-callout.js +1 -1
- package/dist/deck-card.js +1 -1
- package/dist/deck-code.js +1 -1
- package/dist/deck-cover.js +2 -2
- package/dist/deck-feature-cards.js +1 -1
- package/dist/deck-feature.js +1 -1
- package/dist/deck-grid.js +1 -1
- package/dist/deck-kicker.js +1 -1
- package/dist/deck-md.js +1 -1
- package/dist/deck-mermaid.js +3 -3
- package/dist/deck-metric.js +1 -1
- package/dist/deck-notes.js +1 -1
- package/dist/deck-overview.js +7 -3
- package/dist/deck-photo.js +1 -1
- package/dist/deck-presenter.js +25 -17
- package/dist/deck-punch.js +1 -1
- package/dist/deck-root.js +11 -6
- package/dist/deck-section.js +2 -2
- package/dist/deck-shortcut.js +1 -1
- package/dist/deck-split.js +1 -1
- package/dist/deck-stack.js +1 -1
- package/dist/deck-stat.js +2 -2
- package/dist/deck-step-list.js +1 -1
- package/dist/deck-takeaway.js +2 -2
- package/dist/deck-tier-list.js +1 -1
- package/dist/index.js +28 -23
- package/dist/plugins/shiki.d.ts +0 -2
- package/dist/runtime/deck-root.d.ts +23 -0
- package/dist/shared-styles.js +1 -1
- package/dist/shiki.js +1 -1
- package/dist/standalone.js +130 -68
- package/dist/vendor/lit.js +3 -0
- package/dist/vendor/marked.js +46 -0
- package/dist/vendor/mermaid.min.js +2024 -0
- package/dist/vendor/shiki.js +57 -0
- package/docs/llms/rikiki-reference.md +718 -0
- package/llms.txt +50 -0
- package/package.json +21 -7
- package/themes/rikiki.css +10 -4
- package/themes/siliceum.css +10 -4
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A tiny **Lit Web Components** framework for technical presentations. Drop a folder anywhere, open `index.html`, give the talk. No build step on the consumer side · the framework itself is built from TypeScript, but the output is plain ES modules you import directly.
|
|
4
4
|
|
|
5
|
+
This documentation tracks rikiki v0.4.0.
|
|
6
|
+
|
|
5
7
|
## TL;DR
|
|
6
8
|
|
|
7
9
|
```sh
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// ════════════════════════════════════════════════════════════════
|
|
2
|
+
// Shared single-file inliner · turns a rikiki deck HTML into one
|
|
3
|
+
// self-contained file with ZERO external references (JS, CSS, fonts and
|
|
4
|
+
// images inlined). JS bundling + per-deck curation (tree-shaking unused
|
|
5
|
+
// components) is delegated to rolldown · CSS / font / image inlining is
|
|
6
|
+
// plain Node string work, bundler-agnostic.
|
|
7
|
+
//
|
|
8
|
+
// Used by both `rikiki bundle <deck.html>` and `rikiki init --standalone`.
|
|
9
|
+
// ════════════════════════════════════════════════════════════════
|
|
10
|
+
|
|
11
|
+
import { rolldown } from 'rolldown';
|
|
12
|
+
import { readFileSync, existsSync, writeFileSync, rmSync, mkdtempSync } from 'node:fs';
|
|
13
|
+
import { resolve, dirname, join } from 'node:path';
|
|
14
|
+
import { tmpdir } from 'node:os';
|
|
15
|
+
|
|
16
|
+
// A literal `</script>` inside the bundled JS (deck-presenter builds popup HTML
|
|
17
|
+
// at runtime) would close the inline <script> early · the backslash is a no-op
|
|
18
|
+
// for JS string semantics but hides the tag from the HTML parser.
|
|
19
|
+
const escapeScript = (js) => js.replace(/<\/script>/gi, '<\\/script>');
|
|
20
|
+
|
|
21
|
+
const isExternal = (url) => /^(https?:)?\/\//i.test(url) || url.startsWith('//');
|
|
22
|
+
|
|
23
|
+
const MIME = {
|
|
24
|
+
woff2: 'font/woff2', woff: 'font/woff', ttf: 'font/ttf', otf: 'font/otf',
|
|
25
|
+
svg: 'image/svg+xml', png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg',
|
|
26
|
+
gif: 'image/gif', webp: 'image/webp', avif: 'image/avif',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Read a local file as a `data:<mime>;base64,…` URI. */
|
|
30
|
+
function dataUri(absPath) {
|
|
31
|
+
const ext = absPath.split('.').pop().toLowerCase();
|
|
32
|
+
const mime = MIME[ext] || 'application/octet-stream';
|
|
33
|
+
return `data:${mime};base64,${readFileSync(absPath).toString('base64')}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Resolve a deck reference to an absolute path · rikiki package assets
|
|
37
|
+
* (dist/, themes/, tokens.css) resolve against pkgRoot when not found next to
|
|
38
|
+
* the deck, so a deck may use whichever path style it likes. */
|
|
39
|
+
function resolveRef(ref, baseDir, pkgRoot) {
|
|
40
|
+
const clean = ref.replace(/^\//, '').replace(/.*?rikiki\//, '');
|
|
41
|
+
const candidates = [
|
|
42
|
+
resolve(baseDir, ref),
|
|
43
|
+
/(?:^|\/)(dist|themes)\/|tokens\.css$/.test(ref) ? resolve(pkgRoot, clean) : null,
|
|
44
|
+
].filter(Boolean);
|
|
45
|
+
return candidates.find(existsSync) ?? candidates[0];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Bundle a JS entry file to one ESM string (lazy imports folded in). */
|
|
49
|
+
async function bundleEntry(absEntry, { minify = true } = {}) {
|
|
50
|
+
const bundle = await rolldown({ input: absEntry, logLevel: 'silent' });
|
|
51
|
+
const { output } = await bundle.generate({ format: 'esm', codeSplitting: false, minify });
|
|
52
|
+
await bundle.close?.();
|
|
53
|
+
return output[0].code.trimEnd();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Bundle a snippet of module JS (with imports) by staging it in a temp dir. */
|
|
57
|
+
async function bundleInlineModule(code, resolveDir, pkgRoot, opts) {
|
|
58
|
+
const dir = mkdtempSync(join(tmpdir(), 'rikiki-inline-'));
|
|
59
|
+
const entry = join(dir, 'entry.mjs');
|
|
60
|
+
try {
|
|
61
|
+
// Rewrite relative imports to absolute so they resolve from the original
|
|
62
|
+
// location rather than the temp dir · rikiki paths (./dist/…) fall back to
|
|
63
|
+
// the package root via resolveRef, so a deck anywhere can reference them.
|
|
64
|
+
const fixed = code.replace(/(from\s+|import\s*\(\s*)(['"])(\.[^'"]+)\2/g,
|
|
65
|
+
(_m, kw, q, p) => `${kw}${q}${resolveRef(p, resolveDir, pkgRoot)}${q}`);
|
|
66
|
+
writeFileSync(entry, fixed);
|
|
67
|
+
return await bundleEntry(entry, opts);
|
|
68
|
+
} finally {
|
|
69
|
+
rmSync(dir, { recursive: true, force: true });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Scan the deck for the <deck-*> components it actually uses · so the bundle
|
|
74
|
+
* carries only those (+ deck-root, + forced includes), not all 28 elements. */
|
|
75
|
+
function scanComponents(html, pkgRoot, include = []) {
|
|
76
|
+
const tags = new Set(['deck-root', ...include]);
|
|
77
|
+
for (const m of html.matchAll(/<(deck-[a-z0-9-]+)[\s/>]/gi)) tags.add(m[1].toLowerCase());
|
|
78
|
+
return [...tags].filter((t) => existsSync(resolve(pkgRoot, 'dist', `${t}.js`)));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Build the curated component bundle · one side-effect import per used tag. */
|
|
82
|
+
async function curatedBundle(html, pkgRoot, { include, minify }) {
|
|
83
|
+
const comps = scanComponents(html, pkgRoot, include);
|
|
84
|
+
const entry = comps.map((t) => `import ${JSON.stringify(resolve(pkgRoot, 'dist', `${t}.js`))};`).join('\n');
|
|
85
|
+
return bundleInlineModule(entry, pkgRoot, pkgRoot, { minify });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const minifyCssText = (css) => css
|
|
89
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // comments
|
|
90
|
+
.replace(/\s+/g, ' ') // collapse whitespace
|
|
91
|
+
.replace(/\s*([{}:;,>])\s*/g, '$1') // around punctuation
|
|
92
|
+
.replace(/;}/g, '}')
|
|
93
|
+
.trim();
|
|
94
|
+
|
|
95
|
+
/** Inline one CSS file: follow local @imports, drop external ones, turn local
|
|
96
|
+
* url(...) assets (woff2, images, …) into data URIs. */
|
|
97
|
+
function inlineCss(absCssPath, { noFonts } = {}, seen = new Set()) {
|
|
98
|
+
if (seen.has(absCssPath) || !existsSync(absCssPath)) return '';
|
|
99
|
+
seen.add(absCssPath);
|
|
100
|
+
const dir = dirname(absCssPath);
|
|
101
|
+
let css = readFileSync(absCssPath, 'utf8');
|
|
102
|
+
|
|
103
|
+
// @import · inline local ones recursively, strip external (CSP-proof).
|
|
104
|
+
css = css.replace(/@import\s+url\(\s*['"]?([^'")]+)['"]?\s*\)\s*;?/g, (_m, href) => {
|
|
105
|
+
if (isExternal(href)) return ''; // e.g. Google Fonts
|
|
106
|
+
return inlineCss(resolve(dir, href), { noFonts }, seen);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// url(...) assets · inline local files as data URIs, blank external ones.
|
|
110
|
+
css = css.replace(/url\(\s*['"]?([^'")]+)['"]?\s*\)/g, (m, ref) => {
|
|
111
|
+
if (ref.startsWith('data:') || ref.startsWith('#')) return m;
|
|
112
|
+
if (isExternal(ref)) return 'none'; // no external fetch
|
|
113
|
+
if (noFonts && /\.(woff2?|ttf|otf|eot)(\?.*)?$/i.test(ref)) return 'none';
|
|
114
|
+
const assetPath = resolve(dir, ref.split(/[?#]/)[0]);
|
|
115
|
+
if (!existsSync(assetPath)) return m;
|
|
116
|
+
return `url(${dataUri(assetPath)})`;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return css;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const attr = (tag, name) => (tag.match(new RegExp(`\\b${name}=["']([^"']*)["']`, 'i')) || [])[1];
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Inline a deck HTML into a self-contained string.
|
|
126
|
+
* baseDir/pkgRoot · resolution roots (deck dir / rikiki package)
|
|
127
|
+
* cure/all/include · component tree-shaking (default cured; --all keeps all)
|
|
128
|
+
* minifyJs/minifyCss/minifyHtml · default: JS minified, HTML+CSS readable
|
|
129
|
+
* noFonts · drop fonts instead of inlining them
|
|
130
|
+
*/
|
|
131
|
+
export async function inlineDeck({
|
|
132
|
+
html, baseDir, pkgRoot,
|
|
133
|
+
cure = true, all = false, include = [],
|
|
134
|
+
minifyJs = true, minifyCss = false, minifyHtml = false,
|
|
135
|
+
noFonts = false,
|
|
136
|
+
}) {
|
|
137
|
+
let out = html;
|
|
138
|
+
|
|
139
|
+
// Precompute the curated component bundle from the original markup (before we
|
|
140
|
+
// inline big <script> blocks the tag scan must not see).
|
|
141
|
+
const curated = (cure && !all) ? await curatedBundle(html, pkgRoot, { include, minify: minifyJs }) : null;
|
|
142
|
+
|
|
143
|
+
// ── Asset passes run BEFORE script bundling · their regexes must never see
|
|
144
|
+
// the inlined JS (which contains <img>/style= in string literals). ──────
|
|
145
|
+
|
|
146
|
+
// a. <img src="*.svg"> · replace with the inline <svg> markup (stylable).
|
|
147
|
+
out = out.replace(/<img\b[^>]*>/gi, (tag) => {
|
|
148
|
+
const src = attr(tag, 'src');
|
|
149
|
+
if (!src || isExternal(src) || src.startsWith('data:') || !/\.svg$/i.test(src)) return tag;
|
|
150
|
+
const abs = resolveRef(src, baseDir, pkgRoot);
|
|
151
|
+
if (!existsSync(abs)) return tag;
|
|
152
|
+
let svg = readFileSync(abs, 'utf8')
|
|
153
|
+
.replace(/<\?xml[\s\S]*?\?>/i, '').replace(/<!DOCTYPE[\s\S]*?>/i, '').trim();
|
|
154
|
+
const cls = attr(tag, 'class'), id = attr(tag, 'id'), sty = attr(tag, 'style');
|
|
155
|
+
const extra = (cls ? ` class="${cls}"` : '') + (id ? ` id="${id}"` : '') + (sty ? ` style="${sty}"` : '');
|
|
156
|
+
return extra ? svg.replace(/<svg\b/, `<svg${extra}`) : svg;
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// b. any image-bearing attribute (img/deck-photo src, deck-cover brand-src,
|
|
160
|
+
// video poster, …) pointing at a local image → base64 data URI.
|
|
161
|
+
out = out.replace(/\b(src|brand-src|poster|data-src)=(["'])([^"']+)\2/gi, (m, name, q, ref) => {
|
|
162
|
+
if (ref.startsWith('data:') || isExternal(ref)) return m;
|
|
163
|
+
if (!/\.(png|jpe?g|gif|webp|avif|svg)$/i.test(ref)) return m; // only images, never JS
|
|
164
|
+
const abs = resolveRef(ref, baseDir, pkgRoot);
|
|
165
|
+
return existsSync(abs) ? `${name}=${q}${dataUri(abs)}${q}` : m;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// c. inline style="… url(local) …" → base64.
|
|
169
|
+
out = out.replace(/\bstyle=(["'])([\s\S]*?)\1/gi, (m, q, body) => {
|
|
170
|
+
if (!/url\(/i.test(body)) return m;
|
|
171
|
+
const fixed = body.replace(/url\(\s*['"]?([^'")]+)['"]?\s*\)/gi, (um, ref) => {
|
|
172
|
+
if (ref.startsWith('data:') || ref.startsWith('#') || isExternal(ref)) return um;
|
|
173
|
+
const abs = resolve(baseDir, ref.split(/[?#]/)[0]);
|
|
174
|
+
return existsSync(abs) ? `url(${dataUri(abs)})` : um;
|
|
175
|
+
});
|
|
176
|
+
return `style=${q}${fixed}${q}`;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// 1. <link rel="stylesheet" href="..."> → inline <style>
|
|
180
|
+
out = out.replace(/<link\b[^>]*\brel=["']stylesheet["'][^>]*>/gi, (tag) => {
|
|
181
|
+
const href = attr(tag, 'href');
|
|
182
|
+
if (!href || isExternal(href)) return ''; // drop external sheets
|
|
183
|
+
let css = inlineCss(resolveRef(href, baseDir, pkgRoot), { noFonts });
|
|
184
|
+
if (minifyCss) css = minifyCssText(css);
|
|
185
|
+
return `<style>\n${css}\n</style>`;
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// 2. inline <script type="module">…</script> WITH imports → bundle.
|
|
189
|
+
out = await replaceAsync(out, /<script\b[^>]*\btype=["']module["'][^>]*>([\s\S]*?)<\/script>/gi,
|
|
190
|
+
async (full, body) => {
|
|
191
|
+
if (!/\bimport\b/.test(body)) return full;
|
|
192
|
+
const code = await bundleInlineModule(body, baseDir, pkgRoot, { minify: minifyJs });
|
|
193
|
+
return `<script type="module">\n${escapeScript(code)}\n</script>`;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// 3. <script src="..."> → inline. The rikiki barrel (dist/index.js) is swapped
|
|
197
|
+
// for the curated bundle; other module scripts bundle as-is; classic
|
|
198
|
+
// scripts (mermaid UMD) are inlined verbatim.
|
|
199
|
+
out = await replaceAsync(out, /<script\b([^>]*)\bsrc=["']([^"']+)["']([^>]*)><\/script>/gi,
|
|
200
|
+
async (full, pre, src, post) => {
|
|
201
|
+
if (isExternal(src)) return full;
|
|
202
|
+
const abs = resolveRef(src, baseDir, pkgRoot);
|
|
203
|
+
const isModule = /type=["']module["']/.test(pre + post);
|
|
204
|
+
const isBarrel = abs === resolve(pkgRoot, 'dist', 'index.js');
|
|
205
|
+
const code = curated && isBarrel ? curated
|
|
206
|
+
: isModule ? await bundleEntry(abs, { minify: minifyJs })
|
|
207
|
+
: readFileSync(abs, 'utf8');
|
|
208
|
+
// Tag the inlined framework bundle so the presenter can re-inject it into
|
|
209
|
+
// its preview iframes (no external index.js to <script src> in one file).
|
|
210
|
+
const attrs = isModule ? ' type="module" data-rikiki-bundle' : '';
|
|
211
|
+
return `<script${attrs}>\n${escapeScript(code)}\n</script>`;
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Optional · collapse blank lines / trailing spaces (safe, conservative).
|
|
215
|
+
if (minifyHtml) out = out.replace(/[ \t]+$/gm, '').replace(/\n{2,}/g, '\n');
|
|
216
|
+
|
|
217
|
+
return out;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** async String.replace · awaits each replacement in order. */
|
|
221
|
+
async function replaceAsync(str, regex, fn) {
|
|
222
|
+
const parts = [];
|
|
223
|
+
let last = 0;
|
|
224
|
+
for (const m of str.matchAll(regex)) {
|
|
225
|
+
parts.push(str.slice(last, m.index));
|
|
226
|
+
parts.push(await fn(...m, m.index, m.input));
|
|
227
|
+
last = m.index + m[0].length;
|
|
228
|
+
}
|
|
229
|
+
parts.push(str.slice(last));
|
|
230
|
+
return parts.join('');
|
|
231
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// ════════════════════════════════════════════════════════════════
|
|
2
|
+
// Starter deck template for `rikiki init`. Returns plain deck HTML whose
|
|
3
|
+
// refs (tokens.css / themes / dist) resolve against the rikiki package
|
|
4
|
+
// root · the inliner then folds everything into one self-contained file.
|
|
5
|
+
// ════════════════════════════════════════════════════════════════
|
|
6
|
+
|
|
7
|
+
const esc = (s) => String(s).replace(/[&<>"]/g, (c) =>
|
|
8
|
+
({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]));
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {object} o
|
|
12
|
+
* @param {string} o.title deck title (cover + <title>)
|
|
13
|
+
* @param {'rikiki'|'siliceum'} o.theme
|
|
14
|
+
* @param {boolean} o.withMermaid include + preload the mermaid runtime
|
|
15
|
+
* @param {boolean} o.withShiki include + activate the Shiki highlighter
|
|
16
|
+
*/
|
|
17
|
+
export function starterHtml({ title = 'My deck', theme = 'rikiki', withMermaid = false, withShiki = false } = {}) {
|
|
18
|
+
const themeHref = theme === 'siliceum' ? 'themes/siliceum.css' : 'tokens.css';
|
|
19
|
+
|
|
20
|
+
// Heavy plugins · injected as refs the inliner folds in. mermaid's UMD sets
|
|
21
|
+
// window.mermaid (deck-mermaid then skips its network load); the shiki module
|
|
22
|
+
// exposes the vendored highlighter as a global and activates it.
|
|
23
|
+
const mermaidTag = withMermaid
|
|
24
|
+
? '<script src="dist/vendor/mermaid.min.js"></script>\n'
|
|
25
|
+
: '';
|
|
26
|
+
const shikiTag = withShiki
|
|
27
|
+
? `<script type="module">
|
|
28
|
+
import { createHighlighter } from './dist/vendor/shiki.js';
|
|
29
|
+
globalThis.__rikikiShiki = createHighlighter;
|
|
30
|
+
import { installShiki } from './dist/shiki.js';
|
|
31
|
+
await installShiki();
|
|
32
|
+
</script>\n`
|
|
33
|
+
: '';
|
|
34
|
+
|
|
35
|
+
const mermaidSlide = withMermaid
|
|
36
|
+
? `
|
|
37
|
+
<deck-feature eyebrow="Diagram">
|
|
38
|
+
<h1 slot="title">A <span class="accent">diagram</span></h1>
|
|
39
|
+
<deck-mermaid>graph LR
|
|
40
|
+
Idea --> Draft --> Share</deck-mermaid>
|
|
41
|
+
</deck-feature>
|
|
42
|
+
`
|
|
43
|
+
: '';
|
|
44
|
+
|
|
45
|
+
return `<!doctype html>
|
|
46
|
+
<html lang="en">
|
|
47
|
+
<head>
|
|
48
|
+
<meta charset="UTF-8">
|
|
49
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
50
|
+
<title>${esc(title)}</title>
|
|
51
|
+
<link rel="stylesheet" href="${themeHref}">
|
|
52
|
+
${mermaidTag}${shikiTag}<script type="module" src="dist/index.js"></script>
|
|
53
|
+
</head>
|
|
54
|
+
<body>
|
|
55
|
+
|
|
56
|
+
<deck-root>
|
|
57
|
+
|
|
58
|
+
<deck-cover brand="rikiki" speaker="Your name" duration="~10 min" audience="Your audience">
|
|
59
|
+
<h1>${esc(title)} <span class="accent">deck</span></h1>
|
|
60
|
+
<p class="sub">A self-contained, shareable slide deck.</p>
|
|
61
|
+
</deck-cover>
|
|
62
|
+
|
|
63
|
+
<deck-feature eyebrow="Start here">
|
|
64
|
+
<h1 slot="title">Edit <span class="accent">this file</span></h1>
|
|
65
|
+
<deck-md>
|
|
66
|
+
This whole deck is **one HTML file** with zero external links.
|
|
67
|
+
|
|
68
|
+
- open it anywhere, offline
|
|
69
|
+
- each \`<deck-*>\` element is a slide
|
|
70
|
+
- press **?** for keyboard shortcuts
|
|
71
|
+
</deck-md>
|
|
72
|
+
</deck-feature>
|
|
73
|
+
${mermaidSlide}
|
|
74
|
+
<deck-takeaway>
|
|
75
|
+
<h1>Ship it</h1>
|
|
76
|
+
<p>One file. No network. Share it.</p>
|
|
77
|
+
</deck-takeaway>
|
|
78
|
+
|
|
79
|
+
</deck-root>
|
|
80
|
+
</body>
|
|
81
|
+
</html>
|
|
82
|
+
`;
|
|
83
|
+
}
|
package/bin/rikiki.mjs
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ════════════════════════════════════════════════════════════════
|
|
3
|
+
// rikiki CLI
|
|
4
|
+
//
|
|
5
|
+
// rikiki init --standalone [name.html] [--title "…"] [--theme rikiki|siliceum]
|
|
6
|
+
// [--with-mermaid] [--with-shiki] [--no-fonts]
|
|
7
|
+
// rikiki bundle <deck.html> [out.html|-] [--no-fonts]
|
|
8
|
+
//
|
|
9
|
+
// `init --standalone` generates a self-contained, share-anywhere deck with no
|
|
10
|
+
// external links. `bundle` folds an existing deck into the same single file.
|
|
11
|
+
// Both use the rolldown-powered inliner in lib/inline.mjs.
|
|
12
|
+
// ════════════════════════════════════════════════════════════════
|
|
13
|
+
|
|
14
|
+
import { parseArgs } from 'node:util';
|
|
15
|
+
import { readFileSync, writeFileSync, existsSync, statSync } from 'node:fs';
|
|
16
|
+
import { resolve, dirname, basename, join } from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
import { inlineDeck } from './lib/inline.mjs';
|
|
19
|
+
import { starterHtml } from './lib/starter.mjs';
|
|
20
|
+
|
|
21
|
+
const PKG_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
22
|
+
|
|
23
|
+
const HELP = `rikiki · self-contained slide decks
|
|
24
|
+
|
|
25
|
+
rikiki init --standalone [name.html] [options] generate a new single-file deck
|
|
26
|
+
rikiki bundle <deck.html> [out.html|-] [options] fold an existing deck into one file
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
--title "…" deck title (init)
|
|
30
|
+
--theme rikiki|siliceum theme · siliceum inlines its local fonts (default: rikiki)
|
|
31
|
+
--with-mermaid inline the mermaid runtime (+~3 MB)
|
|
32
|
+
--with-shiki inline the Shiki highlighter (+~9 MB)
|
|
33
|
+
--no-fonts drop fonts instead of inlining them (smaller, system fonts)
|
|
34
|
+
--all bundle every component (skip the used-only curation)
|
|
35
|
+
--include a,b force-include components used only from JS
|
|
36
|
+
--minify-css minify the inlined CSS (default: readable)
|
|
37
|
+
--minify-html collapse blank lines in the HTML (default: readable)
|
|
38
|
+
--no-minify-js keep the framework JS readable (default: minified)
|
|
39
|
+
-h, --help show this help
|
|
40
|
+
|
|
41
|
+
Output is one HTML file with zero external references · open it offline.
|
|
42
|
+
The bundle is curated to the components the deck uses; HTML and CSS stay
|
|
43
|
+
readable so you can keep editing the file. Images are inlined as base64 and
|
|
44
|
+
SVGs as inline markup.`;
|
|
45
|
+
|
|
46
|
+
/** Shared inlining options derived from the parsed flags. */
|
|
47
|
+
const inlineOpts = (v) => ({
|
|
48
|
+
all: v.all,
|
|
49
|
+
include: v.include ? v.include.split(',').map((s) => s.trim()).filter(Boolean) : [],
|
|
50
|
+
minifyCss: v['minify-css'],
|
|
51
|
+
minifyHtml: v['minify-html'],
|
|
52
|
+
minifyJs: !v['no-minify-js'],
|
|
53
|
+
noFonts: v['no-fonts'],
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const SHARED_OPTIONS = {
|
|
57
|
+
all: { type: 'boolean', default: false },
|
|
58
|
+
include: { type: 'string' },
|
|
59
|
+
'minify-css': { type: 'boolean', default: false },
|
|
60
|
+
'minify-html': { type: 'boolean', default: false },
|
|
61
|
+
'no-minify-js': { type: 'boolean', default: false },
|
|
62
|
+
'no-fonts': { type: 'boolean', default: false },
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Warn if anything external slipped through. */
|
|
66
|
+
function warnExternal(html) {
|
|
67
|
+
const hits = [...html.matchAll(/\b(?:https?:)?\/\/[^\s"')]+/g)]
|
|
68
|
+
.map((m) => m[0])
|
|
69
|
+
.filter((u) => !u.startsWith('//W') && /cdn|googleapis|gstatic|unpkg|jsdelivr|esm\.sh|fonts\./.test(u));
|
|
70
|
+
if (hits.length) {
|
|
71
|
+
console.error('rikiki · WARNING · external references remain:');
|
|
72
|
+
[...new Set(hits)].slice(0, 5).forEach((u) => console.error(' · ' + u));
|
|
73
|
+
}
|
|
74
|
+
return hits.length === 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function writeOut(html, outputPath) {
|
|
78
|
+
if (outputPath === '-') { process.stdout.write(html); return; }
|
|
79
|
+
writeFileSync(outputPath, html);
|
|
80
|
+
const kb = (Buffer.byteLength(html) / 1024).toFixed(0);
|
|
81
|
+
console.error(`rikiki · wrote ${outputPath} · ${kb} KB`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function cmdInit(argv) {
|
|
85
|
+
const { values, positionals } = parseArgs({
|
|
86
|
+
args: argv,
|
|
87
|
+
allowPositionals: true,
|
|
88
|
+
options: {
|
|
89
|
+
standalone: { type: 'boolean', default: false },
|
|
90
|
+
title: { type: 'string' },
|
|
91
|
+
theme: { type: 'string', default: 'rikiki' },
|
|
92
|
+
'with-mermaid': { type: 'boolean', default: false },
|
|
93
|
+
'with-shiki': { type: 'boolean', default: false },
|
|
94
|
+
...SHARED_OPTIONS,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// `init` only produces standalone single-file decks for now · accept the flag
|
|
99
|
+
// explicitly but don't require it (the whole point is the self-contained file).
|
|
100
|
+
if (!values.standalone) {
|
|
101
|
+
console.error('rikiki · init currently generates standalone single-file decks · assuming --standalone');
|
|
102
|
+
}
|
|
103
|
+
const theme = values.theme === 'siliceum' ? 'siliceum' : 'rikiki';
|
|
104
|
+
const name = positionals[0] || 'slides.html';
|
|
105
|
+
const outputPath = name === '-' ? '-' : resolve(process.cwd(), name.endsWith('.html') ? name : name + '.html');
|
|
106
|
+
const title = values.title || basename(name, '.html').replace(/[-_]/g, ' ') || 'My deck';
|
|
107
|
+
|
|
108
|
+
const html = starterHtml({
|
|
109
|
+
title, theme,
|
|
110
|
+
withMermaid: values['with-mermaid'],
|
|
111
|
+
withShiki: values['with-shiki'],
|
|
112
|
+
});
|
|
113
|
+
const inlined = await inlineDeck({ html, baseDir: PKG_ROOT, pkgRoot: PKG_ROOT, ...inlineOpts(values) });
|
|
114
|
+
writeOut(inlined, outputPath);
|
|
115
|
+
if (outputPath !== '-') warnExternal(inlined);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function cmdBundle(argv) {
|
|
119
|
+
const { values, positionals } = parseArgs({
|
|
120
|
+
args: argv,
|
|
121
|
+
allowPositionals: true,
|
|
122
|
+
options: { ...SHARED_OPTIONS },
|
|
123
|
+
});
|
|
124
|
+
const input = positionals[0];
|
|
125
|
+
if (!input) { console.error('rikiki bundle · missing <deck.html>\n\n' + HELP); process.exit(1); }
|
|
126
|
+
const inputPath = resolve(process.cwd(), input);
|
|
127
|
+
if (!existsSync(inputPath) || !statSync(inputPath).isFile()) {
|
|
128
|
+
console.error('rikiki bundle · input not found: ' + inputPath); process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const outArg = positionals[1];
|
|
131
|
+
const outputPath = outArg === '-' ? '-'
|
|
132
|
+
: outArg ? resolve(process.cwd(), outArg)
|
|
133
|
+
: join(dirname(inputPath), basename(inputPath, '.html') + '.bundle.html');
|
|
134
|
+
|
|
135
|
+
const html = readFileSync(inputPath, 'utf8');
|
|
136
|
+
const inlined = await inlineDeck({ html, baseDir: dirname(inputPath), pkgRoot: PKG_ROOT, ...inlineOpts(values) });
|
|
137
|
+
writeOut(inlined, outputPath);
|
|
138
|
+
if (outputPath !== '-') warnExternal(inlined);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const [cmd, ...rest] = process.argv.slice(2);
|
|
142
|
+
try {
|
|
143
|
+
if (cmd === 'init') await cmdInit(rest);
|
|
144
|
+
else if (cmd === 'bundle') await cmdBundle(rest);
|
|
145
|
+
else if (!cmd || cmd === '-h' || cmd === '--help' || cmd === 'help') { console.log(HELP); }
|
|
146
|
+
else { console.error('rikiki · unknown command: ' + cmd + '\n\n' + HELP); process.exit(1); }
|
|
147
|
+
} catch (e) {
|
|
148
|
+
console.error('rikiki · error · ' + (e && e.stack || e));
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
package/dist/deck-badge.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var g=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var b=(d,a,s,t)=>{for(var r=t>1?void 0:t?k(a,s):a,i=d.length-1,o;i>=0;i--)(o=d[i])&&(r=(t?o(a,s,r):o(r))||r);return t&&r&&g(a,s,r),r};import{LitElement as c,html as n,css as v}from"
|
|
1
|
+
var g=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var b=(d,a,s,t)=>{for(var r=t>1?void 0:t?k(a,s):a,i=d.length-1,o;i>=0;i--)(o=d[i])&&(r=(t?o(a,s,r):o(r))||r);return t&&r&&g(a,s,r),r};import{LitElement as c,html as n,css as v}from"./vendor/lit.js";import{customElement as p,property as u}from"./vendor/lit.js";var e=class extends c{render(){return n`<slot></slot>`}};e.styles=v`:host{display:inline-block;padding:var(--deck-badge-padding-y,var(--rik-space-1)) var(--deck-badge-padding-x,var(--rik-space-3));margin-bottom:var(--rik-space-2);font:700 var(--rik-font-size-xs)/1.2 var(--rik-font-sans);letter-spacing:0.1em;text-transform:uppercase;border-radius:var(--deck-badge-radius,var(--rik-radius-pill));background:var(--deck-badge-bg,var(--rik-surface-tint));color:var(--deck-badge-fg,var(--rik-text-default--faint));border:1px solid var(--deck-badge-border,var(--rik-border-default))}:host([type="bad"]){--deck-badge-bg:var(--rik-status-danger__bg);--deck-badge-fg:var(--rik-status-danger);--deck-badge-border:var(--rik-status-danger__border)}:host([type="ok"]){--deck-badge-bg:var(--rik-status-success__bg);--deck-badge-fg:var(--rik-status-success);--deck-badge-border:var(--rik-status-success__border)}:host([type="info"]){--deck-badge-bg:var(--rik-status-info__bg--strong);--deck-badge-fg:var(--rik-status-info__text);--deck-badge-border:var(--rik-status-info__border)}:host([type="warn"]){--deck-badge-bg:var(--rik-status-warn__bg);--deck-badge-fg:var(--rik-status-warn);--deck-badge-border:var(--rik-status-warn__border)}`,b([u({type:String})],e.prototype,"type",2),e=b([p("deck-badge")],e);export{e as DeckBadge};
|
package/dist/deck-callout.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var l=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var d=(i,t,a,o)=>{for(var r=o>1?void 0:o?k(t,a):t,s=i.length-1,c;s>=0;s--)(c=i[s])&&(r=(o?c(t,a,r):c(r))||r);return o&&r&&l(t,a,r),r};import{LitElement as u,html as v,css as p}from"
|
|
1
|
+
var l=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var d=(i,t,a,o)=>{for(var r=o>1?void 0:o?k(t,a):t,s=i.length-1,c;s>=0;s--)(c=i[s])&&(r=(o?c(t,a,r):c(r))||r);return o&&r&&l(t,a,r),r};import{LitElement as u,html as v,css as p}from"./vendor/lit.js";import{customElement as g,property as f}from"./vendor/lit.js";var n={info:'<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>',warn:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',danger:'<circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/>',ok:'<path d="M20 6 9 17l-5-5"/>'},e=class extends u{render(){let t=this.type??"info",a=n[t]??n.info;return v`<div class="icon-box"> <svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" .innerHTML="${a}"></svg> </div> <div class="content"><slot></slot></div>`}};e.styles=p`:host{display:flex;gap:var(--rik-space-3);padding:var(--deck-callout-padding-y,var(--rik-space-3)) var(--deck-callout-padding-x,var(--rik-space-4));border-radius:var(--deck-callout-radius,var(--rik-radius-md));background:var(--deck-callout-bg,var(--rik-status-info__bg--mid));border:1px solid var(--deck-callout-border,var(--rik-status-info__border));box-shadow:var(--rik-elevation-2);align-items:center;color:var(--rik-text-default--muted);font-family:var(--rik-font-sans);font-size:var(--rik-font-size-body);line-height:1.55}:host([type="info"]){--deck-callout-bg:var(--rik-status-info__bg--mid);--deck-callout-border:var(--rik-status-info__border);--deck-callout-stroke:var(--rik-accent)}:host([type="warn"]){--deck-callout-bg:var(--rik-status-warn__bg);--deck-callout-border:var(--rik-status-warn__border);--deck-callout-stroke:var(--rik-status-warn)}:host([type="danger"]){--deck-callout-bg:var(--rik-status-danger__bg);--deck-callout-border:var(--rik-status-danger__border);--deck-callout-stroke:var(--rik-status-danger)}:host([type="ok"]){--deck-callout-bg:var(--rik-status-success__bg);--deck-callout-border:var(--rik-status-success__border);--deck-callout-stroke:var(--rik-status-success)}.icon-box{flex-shrink:0;width:var(--rik-icon-2xl);height:var(--rik-icon-2xl);display:inline-flex;align-items:center;justify-content:center;border-radius:50%;background:var(--rik-surface-tint)}.icon-box svg{width:var(--rik-icon-lg);height:var(--rik-icon-lg);stroke:var(--deck-callout-stroke,var(--rik-accent));stroke-width:2.2}.content{flex:1}::slotted(p){margin:0}::slotted(strong){color:var(--rik-text-default);font-weight:700}::slotted(code){font-family:var(--rik-font-mono);font-size:var(--rik-font-size-mono-sm);background:var(--rik-surface-tint);padding:2px 6px;border-radius:var(--rik-radius-sm);color:var(--rik-text-default)}`,d([f({type:String})],e.prototype,"type",2),e=d([g("deck-callout")],e);export{e as DeckCallout};
|
package/dist/deck-card.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var l=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var o=(d,a,s,t)=>{for(var e=t>1?void 0:t?k(a,s):a,c=d.length-1,i;c>=0;c--)(i=d[c])&&(e=(t?i(a,s,e):i(e))||e);return t&&e&&l(a,s,e),e};import{LitElement as v,html as g,css as b}from"
|
|
1
|
+
var l=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var o=(d,a,s,t)=>{for(var e=t>1?void 0:t?k(a,s):a,c=d.length-1,i;c>=0;c--)(i=d[c])&&(e=(t?i(a,s,e):i(e))||e);return t&&e&&l(a,s,e),e};import{LitElement as v,html as g,css as b}from"./vendor/lit.js";import{customElement as p,property as n}from"./vendor/lit.js";var r=class extends v{constructor(){super(...arguments);this.center=!1;this.compact=!1}render(){return g`<slot></slot>`}};r.styles=b`:host{display:flex;flex-direction:column;gap:var(--deck-card-gap,var(--rik-space-2));background:var(--deck-card-bg,var(--rik-surface-raised--strong));border:1px solid var(--deck-card-border,var(--rik-border-default));border-radius:var(--deck-card-radius,var(--rik-radius-lg));padding:var(--deck-card-padding-y,var(--rik-space-3)) var(--deck-card-padding-x,var(--rik-space-4));box-shadow:var(--deck-card-shadow,var(--rik-elevation-2));min-height:0;font-family:var(--rik-font-sans);color:var(--deck-card-text,var(--rik-text-default--muted))}:host([color="yellow"]){background:var(--deck-card-bg,var(--rik-status-info__bg));border:4px solid var(--deck-card-border,var(--rik-status-info__border))}:host([color="orange"]){background:var(--deck-card-bg,var(--rik-status-warn__bg));border:4px solid var(--deck-card-border,var(--rik-status-warn__border))}:host([color="green"]){background:var(--deck-card-bg,var(--rik-status-success__bg));border:4px solid var(--deck-card-border,var(--rik-status-success__border))}:host([color="red"]){background:var(--deck-card-bg,var(--rik-status-danger__bg));border:4px solid var(--deck-card-border,var(--rik-status-danger__border))}::slotted(h3){font-family:var(--rik-font-display,var(--rik-font-sans));font-size:var(--rik-font-size-h2);font-weight:700;color:var(--deck-card-title-color,var(--rik-text-default));letter-spacing:-0.01em;line-height:1.25;margin:0}::slotted(p){font-size:var(--rik-font-size-body);line-height:1.55;margin:0}::slotted(strong){color:var(--rik-text-default);font-weight:700}:host([center]){text-align:center;align-items:center}:host([compact]){padding:var(--rik-space-2) var(--rik-space-3)}`,o([n({type:String})],r.prototype,"color",2),o([n({type:Boolean})],r.prototype,"center",2),o([n({type:Boolean})],r.prototype,"compact",2),r=o([p("deck-card")],r);export{r as DeckCard};
|
package/dist/deck-code.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var m=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var l=(d,n,e,s)=>{for(var r=s>1?void 0:s?h(n,e):n,a=d.length-1,i;a>=0;a--)(i=d[a])&&(r=(s?i(n,e,r):i(r))||r);return s&&r&&m(n,e,r),r};import{LitElement as v,html as u,css as y}from"
|
|
1
|
+
var m=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var l=(d,n,e,s)=>{for(var r=s>1?void 0:s?h(n,e):n,a=d.length-1,i;a>=0;a--)(i=d[a])&&(r=(s?i(n,e,r):i(r))||r);return s&&r&&m(n,e,r),r};import{LitElement as v,html as u,css as y}from"./vendor/lit.js";import{customElement as f,property as g,state as k}from"./vendor/lit.js";function _(d,n){let e=d.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),s=[],r=(t,c)=>{let p="P"+s.length+"E";return s.push('<span class="'+t+'">'+c+"</span>"),p};return n==="html"||n==="xml"||n==="svg"?(e=e.replace(/(<!--[\s\S]*?-->)/g,t=>r("cmt",t)),e=e.replace(/(<!doctype[^&]*>)/gi,t=>r("cmt",t)),e=e.replace(/("[^"]*"|'[^']*')/g,t=>r("str",t)),e=e.replace(/(<\/?)([a-zA-Z][a-zA-Z0-9:-]*)/g,(t,c,p)=>c+r("kw",p)),e=e.replace(/\b([a-zA-Z][a-zA-Z0-9-]*)(?==)/g,t=>r("prop",t))):n==="css"||n==="scss"||n==="less"?(e=e.replace(/(\/\*[\s\S]*?\*\/)/g,t=>r("cmt",t)),e=e.replace(/("[^"]*"|'[^']*')/g,t=>r("str",t)),e=e.replace(/([a-zA-Z-]+)(?=\s*:)/g,t=>r("prop",t)),e=e.replace(/(#[0-9a-fA-F]{3,8})\b/g,t=>r("num",t)),e=e.replace(/\b(\d+(?:\.\d+)?)(px|rem|em|%|vh|vw|vmin|vmax|s|ms|deg)?/g,(t,c,p)=>r("num",c+(p??"")))):(e=e.replace(/(\/\/[^\n]*)/g,t=>r("cmt",t)),e=e.replace(/(['"`])((?:\\.|(?!\1)[^\\])*)\1/g,t=>r("str",t)),e=e.replace(/\b(const|let|var|function|return|if|else|for|while|class|extends|new|export|import|from|as|await|async|of|in|typeof|instanceof|true|false|null|undefined)\b/g,t=>r("kw",t)),e=e.replace(/\b(\d+(?:\.\d+)?)\b/g,t=>r("num",t))),e=e.replace(/P(\d+)E/g,(t,c)=>s[+c]??""),e}var o=class extends v{constructor(){super(...arguments);this.lang="";this.hero=!1;this.nested=!1;this._html="";this._groups=null}connectedCallback(){super.connectedCallback(),this._highlight();try{this._groups=JSON.parse(this.getAttribute("step-groups")??"null")}catch{this._groups=null}}_highlight(){let s=(this.textContent??"").split(`
|
|
2
2
|
`);for(;s.length&&!s[0].trim();)s.shift();for(;s.length&&!s[s.length-1].trim();)s.pop();let r=s.filter(i=>i.trim().length>0).reduce((i,t)=>Math.min(i,t.match(/^ */)?.[0].length??0),1/0),a=r===1/0?s:s.map(i=>i.slice(r));this._html=a.map((i,t)=>'<span class="line" data-line="'+(t+1)+'">'+_(i||" ",this.lang)+"</span>").join("")}applyStep(e){if(!this._groups)return;let s=this.shadowRoot?.querySelectorAll(".line");if(s)if(e===0)s.forEach(r=>r.classList.remove("dim","lit"));else{let r=this._groups[Math.min(e-1,this._groups.length-1)]??[];s.forEach(a=>{let i=parseInt(a.dataset.line??"0",10);a.classList.toggle("lit",r.includes(i)),a.classList.toggle("dim",!r.includes(i))})}}render(){return u`<pre><code .innerHTML="${this._html}"></code></pre>`}};o.styles=y`:host{display:block;background:var(--deck-code-bg,var(--rik-code__bg));border:1px solid var(--deck-code-border,var(--rik-code__border));border-radius:var(--deck-code-radius,var(--rik-radius-md));padding:var(--deck-code-padding-y,var(--rik-space-3)) var(--deck-code-padding-x,var(--rik-space-4));font-family:var(--rik-font-mono);font-size:var(--rik-font-size-mono);line-height:1.7;color:var(--deck-code-text,var(--rik-code__text));box-shadow:var(--rik-elevation-2);overflow:auto;white-space:pre}:host([hero]){display:flex;align-items:safe center;padding:var(--deck-code-padding-y,var(--rik-space-4)) var(--deck-code-padding-x,var(--rik-space-5))}:host([nested]){box-shadow:none;border-radius:var(--rik-radius-sm);padding:var(--deck-code-padding-y,var(--rik-space-2)) var(--deck-code-padding-x,var(--rik-space-3))}pre{margin:0;font:inherit;color:inherit}code{display:block;width:100%;font:inherit;color:inherit}.line{transition:opacity 0.25s ease;display:block}.line.dim{opacity:0.25}.line.lit{opacity:1}.kw{color:var(--deck-code-syntax-kw,var(--rik-code__syntax-keyword))}.fn{color:var(--deck-code-syntax-fn,var(--rik-code__syntax-function))}.str{color:var(--deck-code-syntax-str,var(--rik-code__syntax-string))}.num{color:var(--deck-code-syntax-num,var(--rik-code__syntax-number))}.cmt{color:var(--deck-code-syntax-cmt,var(--rik-code__syntax-comment));font-style:italic}.ty{color:var(--deck-code-syntax-ty,var(--rik-code__syntax-type))}.prop{color:var(--deck-code-syntax-prop,var(--rik-code__syntax-property))}`,l([g({type:String})],o.prototype,"lang",2),l([g({type:Boolean,reflect:!0})],o.prototype,"hero",2),l([g({type:Boolean,reflect:!0})],o.prototype,"nested",2),l([g({type:String,attribute:"step-groups"})],o.prototype,"stepGroups",2),l([k()],o.prototype,"_html",2),o=l([f("deck-code")],o);export{o as DeckCode};
|
package/dist/deck-cover.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var g=Object.defineProperty;var
|
|
1
|
+
var g=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var e=(c,n,s,o)=>{for(var i=o>1?void 0:o?f(n,s):n,d=c.length-1,a;d>=0;d--)(a=c[d])&&(i=(o?a(n,s,i):a(i))||i);return o&&i&&g(n,s,i),i};import{LitElement as u,html as l,css as h}from"./vendor/lit.js";import{customElement as x,property as r}from"./vendor/lit.js";import{css as p}from"./vendor/lit.js";var v=p`:host{display:none;position:absolute;inset:0;padding:var(--rik-slide-padding-y) var(--rik-slide-padding-x);flex-direction:column;overflow:hidden;background:var(--rik-surface-page);font-family:var(--rik-font-sans);color:var(--rik-text-default)}:host([active]){display:flex}`,b=p`h1{font-size:var(--rik-font-size-h1);font-weight:700;color:var(--rik-text-default);letter-spacing:-0.022em;line-height:1.15;margin-bottom:var(--rik-space-4);padding-bottom:var(--rik-space-2);border-bottom:3px solid var(--rik-accent);display:inline-block;align-self:flex-start;flex:0 0 auto}h1 .accent{color:var(--rik-accent)}::slotted(p),p{font-size:var(--rik-font-size-body);line-height:1.65;color:var(--rik-text-default--muted);margin:0}::slotted(strong),strong{color:var(--rik-text-default);font-weight:700}::slotted(code),code{font-family:var(--rik-font-mono);font-size:var(--rik-font-size-mono-sm);background:rgba(0,0,0,0.06);padding:2px 6px;border-radius:var(--rik-radius-sm);color:var(--rik-text-default)}`,k=p`.lbl{display:inline-block;padding:var(--deck-eyebrow-padding-y,4px) var(--deck-eyebrow-padding-x,12px);background:var(--deck-eyebrow-bg,var(--rik-accent));color:var(--deck-eyebrow-color,var(--rik-accent__on,var(--rik-surface-inverse)));border-radius:var(--deck-eyebrow-radius,var(--rik-radius-pill));font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.1em;text-transform:uppercase;margin-bottom:var(--rik-space-1);align-self:flex-start}.lead{font-size:var(--rik-font-size-lead);color:var(--rik-text-default--faint);line-height:1.5;margin-bottom:var(--rik-space-4);max-width:75ch;flex:0 0 auto}.kicker{font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--rik-text-default--faint);margin-bottom:var(--rik-space-3);display:block}.kicker.on-dark{color:rgba(255,255,255,0.35)}.caption{font-size:var(--rik-font-size-sm);color:var(--rik-text-default--faint);line-height:1.55}.caption.on-dark{color:rgba(255,255,255,0.5)}.col-label{font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--rik-text-default--faint);margin-bottom:var(--rik-space-2)}`,m=[v,b,k];var t=class extends u{render(){let n=(this.brand??"").split("\xB7").map(a=>a.trim()).filter(Boolean),s=n[0]??"",o=n.slice(1).join(" \xB7 "),i=[this.speaker&&{l:this.speakerLabel??"Pr\xE9sent\xE9 par",v:this.speaker},this.company&&{l:this.companyLabel??"Entreprise",v:this.company},this.duration&&{l:this.durationLabel??"Dur\xE9e",v:this.duration},this.audience&&{l:this.audienceLabel??"Audience",v:this.audience},this.runtime&&{l:this.runtimeLabel??"Runtime",v:this.runtime}].filter(a=>!!a),d=!!this.brandSrc;return l`<div class="brand" part="brand"> ${d?l`<span class="brand-tile"><img src="${this.brandSrc}" alt="${s}"></span>`:""}
|
|
2
2
|
${s?l`<span class="brand-name">${s}</span>`:""}
|
|
3
3
|
${o?l`<span class="brand-context">${o}</span>`:""}
|
|
4
4
|
</div>
|
|
@@ -7,4 +7,4 @@ var g=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var e=(c,n,s,o
|
|
|
7
7
|
<div class="meta-item"><strong>${a.l}</strong><span>${a.v}</span></div>
|
|
8
8
|
`)}
|
|
9
9
|
</div>`:""}
|
|
10
|
-
`}};t.styles=[...m,h`:host{background:var(--deck-cover-bg,var(--rik-surface-inverse));justify-content:center;color:var(--deck-cover-text,var(--rik-text-inverse))}.brand{display:inline-flex;align-items:center;gap:var(--rik-space-3);margin-bottom:var(--rik-space-5);align-self:flex-start}.brand-tile{width:
|
|
10
|
+
`}};t.styles=[...m,h`:host{background:var(--deck-cover-bg,var(--rik-surface-inverse));justify-content:center;color:var(--deck-cover-text,var(--rik-text-inverse))}.brand{display:inline-flex;align-items:center;gap:var(--rik-space-3);margin-bottom:var(--rik-space-5);align-self:flex-start}.brand-tile{width:2.5rem;height:2.5rem;display:inline-flex;align-items:center;justify-content:center}.brand-tile img{width:100%;height:100%;display:block}.brand-name{font-family:var(--rik-font-display,inherit);font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.2em;text-transform:uppercase;color:var(--deck-cover-soft,var(--rik-text-inverse--muted))}.brand-context{font-size:var(--rik-font-size-xs);font-weight:700;color:var(--deck-cover-muted,var(--rik-text-inverse--faint));letter-spacing:0.2em;text-transform:uppercase;padding-left:var(--rik-space-3);border-left:1px solid var(--deck-cover-border,var(--rik-border-inverse))}::slotted(h1){font-size:clamp(3.6rem,9cqw,8.5rem);font-weight:900;color:var(--deck-cover-text,var(--rik-text-inverse));line-height:1.02;letter-spacing:-0.035em;margin-bottom:var(--rik-space-4);border:none;padding:0}::slotted(.sub){font-size:var(--rik-font-size-h2);color:var(--deck-cover-muted,var(--rik-text-inverse--faint));margin-bottom:var(--rik-space-6);max-width:60ch;line-height:1.45;display:block}.meta{display:flex;gap:var(--rik-space-6);border-top:1px solid var(--deck-cover-border,var(--rik-border-inverse));padding-top:var(--rik-space-4)}.meta-item strong{display:block;font-size:var(--rik-font-size-xs);letter-spacing:0.12em;text-transform:uppercase;color:var(--deck-cover-faint,var(--rik-text-inverse--ghost));margin-bottom:6px;font-weight:700}.meta-item span{color:var(--deck-cover-text,var(--rik-text-inverse));font-size:var(--rik-font-size-body);font-weight:600}`],e([r({type:String})],t.prototype,"brand",2),e([r({type:String,attribute:"brand-src"})],t.prototype,"brandSrc",2),e([r({type:String})],t.prototype,"speaker",2),e([r({type:String})],t.prototype,"company",2),e([r({type:String})],t.prototype,"duration",2),e([r({type:String})],t.prototype,"audience",2),e([r({type:String})],t.prototype,"runtime",2),e([r({type:String,attribute:"speaker-label"})],t.prototype,"speakerLabel",2),e([r({type:String,attribute:"company-label"})],t.prototype,"companyLabel",2),e([r({type:String,attribute:"duration-label"})],t.prototype,"durationLabel",2),e([r({type:String,attribute:"audience-label"})],t.prototype,"audienceLabel",2),e([r({type:String,attribute:"runtime-label"})],t.prototype,"runtimeLabel",2),t=e([x("deck-cover")],t);export{t as DeckCover};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var n=(o,t,i,a)=>{for(var e=a>1?void 0:a?v(t,i):t,l=o.length-1,s;l>=0;l--)(s=o[l])&&(e=(a?s(t,i,e):s(e))||e);return a&&e&&p(t,i,e),e};import{LitElement as x,html as f,css as h}from"
|
|
1
|
+
var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var n=(o,t,i,a)=>{for(var e=a>1?void 0:a?v(t,i):t,l=o.length-1,s;l>=0;l--)(s=o[l])&&(e=(a?s(t,i,e):s(e))||e);return a&&e&&p(t,i,e),e};import{LitElement as x,html as f,css as h}from"./vendor/lit.js";import{customElement as u,property as b}from"./vendor/lit.js";import{css as d}from"./vendor/lit.js";var m=d`:host{display:none;position:absolute;inset:0;padding:var(--rik-slide-padding-y) var(--rik-slide-padding-x);flex-direction:column;overflow:hidden;background:var(--rik-surface-page);font-family:var(--rik-font-sans);color:var(--rik-text-default)}:host([active]){display:flex}`,k=d`h1{font-size:var(--rik-font-size-h1);font-weight:700;color:var(--rik-text-default);letter-spacing:-0.022em;line-height:1.15;margin-bottom:var(--rik-space-4);padding-bottom:var(--rik-space-2);border-bottom:3px solid var(--rik-accent);display:inline-block;align-self:flex-start;flex:0 0 auto}h1 .accent{color:var(--rik-accent)}::slotted(p),p{font-size:var(--rik-font-size-body);line-height:1.65;color:var(--rik-text-default--muted);margin:0}::slotted(strong),strong{color:var(--rik-text-default);font-weight:700}::slotted(code),code{font-family:var(--rik-font-mono);font-size:var(--rik-font-size-mono-sm);background:rgba(0,0,0,0.06);padding:2px 6px;border-radius:var(--rik-radius-sm);color:var(--rik-text-default)}`,g=d`.lbl{display:inline-block;padding:var(--deck-eyebrow-padding-y,4px) var(--deck-eyebrow-padding-x,12px);background:var(--deck-eyebrow-bg,var(--rik-accent));color:var(--deck-eyebrow-color,var(--rik-accent__on,var(--rik-surface-inverse)));border-radius:var(--deck-eyebrow-radius,var(--rik-radius-pill));font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.1em;text-transform:uppercase;margin-bottom:var(--rik-space-1);align-self:flex-start}.lead{font-size:var(--rik-font-size-lead);color:var(--rik-text-default--faint);line-height:1.5;margin-bottom:var(--rik-space-4);max-width:75ch;flex:0 0 auto}.kicker{font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--rik-text-default--faint);margin-bottom:var(--rik-space-3);display:block}.kicker.on-dark{color:rgba(255,255,255,0.35)}.caption{font-size:var(--rik-font-size-sm);color:var(--rik-text-default--faint);line-height:1.55}.caption.on-dark{color:rgba(255,255,255,0.5)}.col-label{font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--rik-text-default--faint);margin-bottom:var(--rik-space-2)}`,c=[m,k,g];var r=class extends x{render(){return f`${this.eyebrow?f`<span class="lbl">${this.eyebrow}</span>`:""}
|
|
2
2
|
<slot name="title"></slot>
|
|
3
3
|
<slot name="lead"></slot>
|
|
4
4
|
<div class="hero" part="hero"><slot></slot></div>
|
package/dist/deck-feature.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var p=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var n=(a,r,i,o)=>{for(var e=o>1?void 0:o?k(r,i):r,s=a.length-1,l;s>=0;s--)(l=a[s])&&(e=(o?l(r,i,e):l(e))||e);return o&&e&&p(r,i,e),e};import{LitElement as x,html as f,css as b}from"
|
|
1
|
+
var p=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var n=(a,r,i,o)=>{for(var e=o>1?void 0:o?k(r,i):r,s=a.length-1,l;s>=0;s--)(l=a[s])&&(e=(o?l(r,i,e):l(e))||e);return o&&e&&p(r,i,e),e};import{LitElement as x,html as f,css as b}from"./vendor/lit.js";import{customElement as h,property as u}from"./vendor/lit.js";import{css as d}from"./vendor/lit.js";var m=d`:host{display:none;position:absolute;inset:0;padding:var(--rik-slide-padding-y) var(--rik-slide-padding-x);flex-direction:column;overflow:hidden;background:var(--rik-surface-page);font-family:var(--rik-font-sans);color:var(--rik-text-default)}:host([active]){display:flex}`,v=d`h1{font-size:var(--rik-font-size-h1);font-weight:700;color:var(--rik-text-default);letter-spacing:-0.022em;line-height:1.15;margin-bottom:var(--rik-space-4);padding-bottom:var(--rik-space-2);border-bottom:3px solid var(--rik-accent);display:inline-block;align-self:flex-start;flex:0 0 auto}h1 .accent{color:var(--rik-accent)}::slotted(p),p{font-size:var(--rik-font-size-body);line-height:1.65;color:var(--rik-text-default--muted);margin:0}::slotted(strong),strong{color:var(--rik-text-default);font-weight:700}::slotted(code),code{font-family:var(--rik-font-mono);font-size:var(--rik-font-size-mono-sm);background:rgba(0,0,0,0.06);padding:2px 6px;border-radius:var(--rik-radius-sm);color:var(--rik-text-default)}`,g=d`.lbl{display:inline-block;padding:var(--deck-eyebrow-padding-y,4px) var(--deck-eyebrow-padding-x,12px);background:var(--deck-eyebrow-bg,var(--rik-accent));color:var(--deck-eyebrow-color,var(--rik-accent__on,var(--rik-surface-inverse)));border-radius:var(--deck-eyebrow-radius,var(--rik-radius-pill));font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.1em;text-transform:uppercase;margin-bottom:var(--rik-space-1);align-self:flex-start}.lead{font-size:var(--rik-font-size-lead);color:var(--rik-text-default--faint);line-height:1.5;margin-bottom:var(--rik-space-4);max-width:75ch;flex:0 0 auto}.kicker{font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.14em;text-transform:uppercase;color:var(--rik-text-default--faint);margin-bottom:var(--rik-space-3);display:block}.kicker.on-dark{color:rgba(255,255,255,0.35)}.caption{font-size:var(--rik-font-size-sm);color:var(--rik-text-default--faint);line-height:1.55}.caption.on-dark{color:rgba(255,255,255,0.5)}.col-label{font-size:var(--rik-font-size-xs);font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--rik-text-default--faint);margin-bottom:var(--rik-space-2)}`,c=[m,v,g];var t=class extends x{render(){return f`${this.eyebrow?f`<span class="lbl">${this.eyebrow}</span>`:""}
|
|
2
2
|
<slot name="title"></slot>
|
|
3
3
|
<slot name="lead"></slot>
|
|
4
4
|
<div class="body" part="body"><slot></slot></div>
|
package/dist/deck-grid.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var f=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var n=(r,t,a,e)=>{for(var i=e>1?void 0:e?h(t,a):t,g=r.length-1,l;g>=0;g--)(l=r[g])&&(i=(e?l(t,a,i):l(i))||i);return e&&i&&f(t,a,i),i};import{LitElement as y,html as d,css as u}from"
|
|
1
|
+
var f=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var n=(r,t,a,e)=>{for(var i=e>1?void 0:e?h(t,a):t,g=r.length-1,l;g>=0;g--)(l=r[g])&&(i=(e?l(t,a,i):l(i))||i);return e&&i&&f(t,a,i),i};import{LitElement as y,html as d,css as u}from"./vendor/lit.js";import{customElement as m,property as o}from"./vendor/lit.js";var p={start:"start",center:"center",end:"end",stretch:"stretch"};function c(r){if(!r)return null;let t=parseInt(r,10);return!Number.isNaN(t)&&String(t)===r.trim()&&t>=1&&t<=12?`repeat(${t}, minmax(0, 1fr))`:r}function _(r){if(!r)return null;let t=parseInt(r,10);return!Number.isNaN(t)&&t>=1&&t<=6?`var(--rik-space-${t})`:r}var s=class extends y{updated(){let t=c(this.cols),a=c(this.rows),e=_(this.gap);t&&this.style.setProperty("--_cols",t),a&&this.style.setProperty("--_rows",a),e&&this.style.setProperty("--_gap",e),this.align&&this.style.setProperty("--_align",p[this.align]??this.align),this.justify&&this.style.setProperty("--_justify",p[this.justify]??this.justify)}render(){return d`<slot></slot>`}};s.styles=u`:host{display:grid;grid-template-columns:var(--_cols,1fr);grid-template-rows:var(--_rows,auto);gap:var(--_gap,var(--deck-grid-gap,var(--rik-space-3)));align-items:var(--_align,stretch);justify-items:var(--_justify,stretch);min-width:0;min-height:0}:host([fill]){flex:1 1 auto;height:100%}`,n([o({type:String})],s.prototype,"cols",2),n([o({type:String})],s.prototype,"rows",2),n([o({type:String})],s.prototype,"gap",2),n([o({type:String})],s.prototype,"align",2),n([o({type:String})],s.prototype,"justify",2),s=n([m("deck-grid")],s);export{s as DeckGrid};
|
package/dist/deck-kicker.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LitElement as e,html as t,css as o}from"
|
|
1
|
+
import{LitElement as e,html as t,css as o}from"./vendor/lit.js";var r=class extends e{static{this.styles=o`:host{display:block;font:700 var(--deck-kicker-font-size,var(--rik-font-size-xs))/1.2 var(--rik-font-sans);letter-spacing:var(--deck-kicker-tracking,0.14em);text-transform:uppercase;color:var(--deck-kicker-color,var(--rik-text-default--faint));margin-bottom:var(--deck-kicker-margin,var(--rik-space-2))}:host([on-dark]){color:var(--deck-kicker-on-dark-color,var(--rik-text-inverse--faint))}`}render(){return t`<slot></slot>`}};customElements.define("deck-kicker",r);export{r as DeckKicker};
|