mr-md 1.0.4 → 2.0.0-beta

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.
Files changed (58) hide show
  1. package/README.md +10 -5
  2. package/dist/builder.d.ts +6 -20
  3. package/dist/builder.d.ts.map +1 -1
  4. package/dist/builder.js +38 -97
  5. package/dist/cli/dev.d.ts +2 -0
  6. package/dist/cli/dev.d.ts.map +1 -0
  7. package/dist/cli/dev.js +92 -0
  8. package/dist/cli/generate.d.ts +2 -0
  9. package/dist/cli/generate.d.ts.map +1 -0
  10. package/dist/cli/generate.js +171 -0
  11. package/dist/cli/init.d.ts +2 -0
  12. package/dist/cli/init.d.ts.map +1 -0
  13. package/dist/cli/init.js +89 -0
  14. package/dist/cli.d.ts +3 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +27 -0
  17. package/dist/client/app.js +282 -107
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/renderer/blocks.d.ts.map +1 -1
  22. package/dist/renderer/blocks.js +88 -16
  23. package/dist/renderer/html-neo.d.ts +7 -0
  24. package/dist/renderer/html-neo.d.ts.map +1 -0
  25. package/dist/renderer/html-neo.js +173 -0
  26. package/dist/renderer/html.d.ts.map +1 -1
  27. package/dist/renderer/html.js +36 -7
  28. package/dist/renderer/index-neo.d.ts +4 -0
  29. package/dist/renderer/index-neo.d.ts.map +1 -0
  30. package/dist/renderer/index-neo.js +469 -0
  31. package/dist/renderer/index.d.ts +1 -2
  32. package/dist/renderer/index.d.ts.map +1 -1
  33. package/dist/renderer/index.js +29 -379
  34. package/dist/renderer/markdown.d.ts +1 -1
  35. package/dist/renderer/markdown.d.ts.map +1 -1
  36. package/dist/renderer/markdown.js +3 -3
  37. package/dist/renderer/utils.d.ts +1 -1
  38. package/dist/renderer/utils.d.ts.map +1 -1
  39. package/dist/renderer/utils.js +41 -34
  40. package/dist/styles/theme-neo.css +1369 -0
  41. package/dist/styles/theme.css +412 -127
  42. package/dist/types.d.ts +8 -10
  43. package/dist/types.d.ts.map +1 -1
  44. package/package.json +8 -7
  45. package/src/builder.ts +49 -125
  46. package/src/cli/dev.ts +102 -0
  47. package/src/cli/generate.ts +191 -0
  48. package/src/cli/init.ts +97 -0
  49. package/src/cli.ts +29 -0
  50. package/src/client/app.js +282 -107
  51. package/src/index.ts +1 -1
  52. package/src/renderer/blocks.ts +89 -15
  53. package/src/renderer/html.ts +36 -7
  54. package/src/renderer/index.ts +30 -394
  55. package/src/renderer/markdown.ts +3 -2
  56. package/src/renderer/utils.ts +43 -36
  57. package/src/styles/theme.css +412 -127
  58. package/src/types.ts +8 -12
@@ -0,0 +1,469 @@
1
+ import { escAttr, escHtml, renderBlock } from "./blocks.js";
2
+ import { renderPage } from "./html.js";
3
+ // ─── Main render function ─────────────────────────────────────────────────────
4
+ export function render(lesson, opts = {}) {
5
+ const bodyItems = [];
6
+ const structuredNavItems = [];
7
+ lesson.blocks.forEach((block, idx) => {
8
+ const { html, navItems } = renderBlock(block, idx, opts);
9
+ bodyItems.push(html);
10
+ if (navItems) {
11
+ structuredNavItems.push(...navItems);
12
+ }
13
+ });
14
+ return renderPage(lesson, structuredNavItems, bodyItems.join("\n"), opts);
15
+ }
16
+ // ─── Chapter Rendering ────────────────────────────────────────────────────────
17
+ export function renderChapter(chapter, opts = {}) {
18
+ const theme = opts.theme ?? "auto";
19
+ const schemeAttr = `data-theme="${theme}"`;
20
+ const preset = opts.preset ?? {};
21
+ const layout = preset.layout ?? "lesson";
22
+ const density = preset.density ?? "comfortable";
23
+ const tone = preset.tone ?? "scholarly";
24
+ const palette = opts.palette ?? "ink";
25
+ const navHtml = chapter.lessons
26
+ .map((l) => `<a href="${escAttr(l.meta.slug)}.html" class="bk-nav-item bk-nav-chapter">${escHtml(l.meta.title)}</a>`)
27
+ .join("\n");
28
+ const timelineHtml = `
29
+ <div class="bk-chapter-path-wrapper" style="margin-top: 3rem;">
30
+ <div class="bk-chapter-path">
31
+ ${chapter.lessons
32
+ .map((lesson, idx) => `
33
+ <a href="${escAttr(lesson.meta.slug)}.html" class="bk-lesson-card bk-status-${lesson.meta.status ?? "unread"}">
34
+ <div class="bk-lesson-number">${String(idx + 1).padStart(2, "0")}</div>
35
+ <div class="bk-lesson-content">
36
+ <h3 class="bk-lesson-title" style="view-transition-name: title-${escAttr(lesson.meta.slug)}">${escHtml(lesson.meta.title)}</h3>
37
+ ${lesson.meta.description ? `<p class="bk-lesson-desc">${escHtml(lesson.meta.description)}</p>` : ""}
38
+ </div>
39
+ <div class="bk-lesson-footer">
40
+ <span class="bk-lesson-action">${lesson.meta.status === "read" ? "Read again" : "Start Lesson"} <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14m-7-7 7 7-7 7"/></svg></span>
41
+ </div>
42
+ </a>
43
+ ${idx < chapter.lessons.length - 1 ? `
44
+ <div class="bk-path-connector ${chapter.lessons[idx + 1].meta.status === "read" ? "bk-connector-read" : "bk-connector-unread"}">
45
+ <div class="bk-connector-line"></div>
46
+ <div class="bk-connector-arrow">
47
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>
48
+ </div>
49
+ </div>` : `
50
+ <div class="bk-path-connector ${lesson.meta.status === "read" ? "bk-connector-read" : "bk-connector-unread"}">
51
+ <div class="bk-connector-line"></div>
52
+ <div class="bk-connector-arrow">
53
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>
54
+ </div>
55
+ </div>
56
+ <a href="${chapter.meta.nextSlug ? escAttr(chapter.meta.nextSlug) + '.html' : '#'}" class="bk-path-terminal bk-terminal-next">
57
+ <span class="bk-terminal-text">${chapter.meta.nextTitle ? `Next: ${escHtml(chapter.meta.nextTitle)}` : 'Next Chapter'}</span>
58
+ <div class="bk-terminal-icon">
59
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
60
+ </div>
61
+ </a>
62
+ `}
63
+ `)
64
+ .join("")}
65
+ </div>
66
+ </div>
67
+ <script>
68
+ if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
69
+ const observer = new IntersectionObserver(
70
+ (entries) => {
71
+ for (const entry of entries) {
72
+ if (entry.isIntersecting) {
73
+ entry.target.classList.add('js-visible');
74
+ entry.target.classList.remove('js-hidden');
75
+ observer.unobserve(entry.target);
76
+ }
77
+ }
78
+ },
79
+ { threshold: 0.1 }
80
+ );
81
+ document.querySelectorAll('.bk-lesson-card, .bk-path-connector, .bk-path-terminal').forEach((el) => {
82
+ el.classList.add('js-hidden');
83
+ observer.observe(el);
84
+ });
85
+ }
86
+ </script>`;
87
+ const chapterStyles = `
88
+ .bk-chapter-path-wrapper {
89
+ position: relative;
90
+ width: 100%;
91
+ padding: 1rem 0 4rem 0;
92
+ z-index: 1;
93
+ }
94
+
95
+ .bk-chapter-path {
96
+ display: flex;
97
+ flex-direction: column;
98
+ align-items: center;
99
+ position: relative;
100
+ max-width: 700px;
101
+ margin: 0 auto;
102
+ }
103
+
104
+ .bk-path-terminal {
105
+ display: flex;
106
+ align-items: center;
107
+ gap: 1rem;
108
+ padding: 1.25rem 2.5rem;
109
+ background: var(--paper);
110
+ border: 2px solid var(--ink);
111
+ border-radius: 0;
112
+ color: var(--ink);
113
+ font-family: var(--font-display);
114
+ font-weight: 700;
115
+ font-size: 1.2rem;
116
+ box-shadow: 4px 4px 0px 0px var(--ink);
117
+ z-index: 2;
118
+ position: relative;
119
+ transition: all 0.15s ease-out;
120
+ }
121
+
122
+ .bk-terminal-next {
123
+ color: var(--accent);
124
+ border-color: var(--accent);
125
+ background: var(--paper);
126
+ box-shadow: 4px 4px 0px 0px var(--accent);
127
+ text-decoration: none !important;
128
+ cursor: pointer;
129
+ }
130
+
131
+ .bk-terminal-next:hover {
132
+ transform: translate(-2px, -2px);
133
+ background: var(--accent);
134
+ color: var(--paper);
135
+ box-shadow: 6px 6px 0px 0px var(--ink);
136
+ }
137
+
138
+ .bk-terminal-icon {
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ }
143
+
144
+ .bk-lesson-card {
145
+ width: 100%;
146
+ background: var(--paper);
147
+ border: 2px solid var(--ink);
148
+ border-radius: 0;
149
+ padding: 2.5rem;
150
+ display: flex;
151
+ flex-direction: column;
152
+ text-decoration: none !important;
153
+ color: inherit;
154
+ position: relative;
155
+ transition: all 0.15s ease-out;
156
+ box-shadow: 6px 6px 0px 0px var(--ink);
157
+ overflow: hidden;
158
+ }
159
+
160
+ .bk-lesson-card:hover {
161
+ transform: translate(-2px, -2px);
162
+ border-color: var(--accent);
163
+ box-shadow: 8px 8px 0px 0px var(--accent);
164
+ }
165
+
166
+ /* Subtle glow effect behind card on hover */
167
+ .bk-lesson-card::after {
168
+ content: '';
169
+ position: absolute;
170
+ inset: 0;
171
+ border-radius: 0;
172
+ box-shadow: inset 0 0 0 2px var(--accent);
173
+ opacity: 0;
174
+ transition: opacity 0.15s ease;
175
+ pointer-events: none;
176
+ }
177
+ .bk-lesson-card:hover::after {
178
+ opacity: 0.1;
179
+ }
180
+
181
+ .bk-lesson-number {
182
+ position: absolute;
183
+ top: -1.5rem;
184
+ right: 1.5rem;
185
+ font-family: var(--font-display);
186
+ font-size: 8rem;
187
+ font-weight: 800;
188
+ color: var(--line-strong);
189
+ opacity: 0.05;
190
+ line-height: 1;
191
+ transition: all 0.4s ease;
192
+ letter-spacing: -0.05em;
193
+ pointer-events: none;
194
+ z-index: 0;
195
+ }
196
+
197
+ .bk-lesson-card:hover .bk-lesson-number {
198
+ color: var(--accent);
199
+ opacity: 0.1;
200
+ transform: translateY(8px);
201
+ }
202
+
203
+ .bk-lesson-content {
204
+ position: relative;
205
+ z-index: 1;
206
+ display: flex;
207
+ flex-direction: column;
208
+ gap: 0.75rem;
209
+ }
210
+
211
+ .bk-lesson-title {
212
+ font-family: var(--font-display);
213
+ font-size: 1.6rem;
214
+ font-weight: 600;
215
+ color: var(--ink);
216
+ margin: 0;
217
+ line-height: 1.3;
218
+ transition: color 0.3s ease;
219
+ padding-right: 4rem;
220
+ }
221
+
222
+ .bk-lesson-card:hover .bk-lesson-title {
223
+ color: var(--accent);
224
+ }
225
+
226
+ .bk-lesson-desc {
227
+ color: var(--muted);
228
+ line-height: 1.6;
229
+ font-size: 1.1rem;
230
+ margin: 0;
231
+ max-width: 90%;
232
+ }
233
+
234
+ .bk-lesson-footer {
235
+ margin-top: 2rem;
236
+ padding-top: 1.5rem;
237
+ border-top: 1px solid var(--line);
238
+ display: flex;
239
+ align-items: center;
240
+ position: relative;
241
+ z-index: 1;
242
+ transition: border-color 0.3s ease;
243
+ }
244
+
245
+ .bk-lesson-card:hover .bk-lesson-footer {
246
+ border-color: color-mix(in srgb, var(--accent) 20%, transparent);
247
+ }
248
+
249
+ .bk-lesson-action {
250
+ font-weight: 600;
251
+ color: var(--accent);
252
+ display: inline-flex;
253
+ align-items: center;
254
+ gap: 0.5rem;
255
+ font-size: 1.05rem;
256
+ transition: gap 0.3s cubic-bezier(0.16, 1, 0.3, 1);
257
+ }
258
+
259
+ .bk-lesson-card:hover .bk-lesson-action {
260
+ gap: 0.8rem;
261
+ }
262
+
263
+ /* Status variants */
264
+ .bk-status-unread {
265
+ opacity: 0.85;
266
+ }
267
+ .bk-status-unread .bk-lesson-title {
268
+ color: color-mix(in srgb, var(--ink) 80%, transparent);
269
+ }
270
+ .bk-status-unread .bk-lesson-desc {
271
+ color: color-mix(in srgb, var(--muted) 80%, transparent);
272
+ }
273
+ .bk-status-unread .bk-lesson-action {
274
+ color: var(--muted);
275
+ }
276
+ .bk-status-unread:hover .bk-lesson-title {
277
+ color: var(--ink);
278
+ }
279
+ .bk-status-unread:hover .bk-lesson-action {
280
+ color: var(--accent);
281
+ }
282
+
283
+ /* Path Connector */
284
+ .bk-path-connector {
285
+ display: flex;
286
+ flex-direction: column;
287
+ align-items: center;
288
+ padding: 0.5rem 0;
289
+ }
290
+
291
+ .bk-connector-line {
292
+ width: 2px;
293
+ height: 40px;
294
+ background: var(--line-strong);
295
+ border-radius: 2px;
296
+ }
297
+
298
+ .bk-connector-arrow {
299
+ color: var(--line-strong);
300
+ margin-top: -6px;
301
+ background: var(--paper);
302
+ border-radius: 50%;
303
+ padding: 4px;
304
+ }
305
+
306
+ .bk-connector-read .bk-connector-line {
307
+ background: var(--accent);
308
+ }
309
+ .bk-connector-read .bk-connector-arrow {
310
+ color: var(--accent);
311
+ }
312
+
313
+ .bk-connector-unread {
314
+ opacity: 0.4;
315
+ }
316
+ .bk-connector-unread .bk-connector-line {
317
+ background: repeating-linear-gradient(to bottom, var(--line-strong) 0, var(--line-strong) 6px, transparent 6px, transparent 12px);
318
+ }
319
+
320
+ /* Scroll-driven animations */
321
+ @media (prefers-reduced-motion: no-preference) {
322
+ @supports ((animation-timeline: view()) and (animation-range: entry)) {
323
+ .bk-lesson-card, .bk-path-connector, .bk-path-terminal {
324
+ animation: slide-fade-in both cubic-bezier(0.16, 1, 0.3, 1);
325
+ animation-timeline: view(block);
326
+ animation-range: entry 5% cover 15%;
327
+ }
328
+ @keyframes slide-fade-in {
329
+ 0% { opacity: 0; transform: translateY(40px) scale(0.98); }
330
+ 100% { opacity: 1; transform: translateY(0) scale(1); }
331
+ }
332
+ }
333
+ }
334
+
335
+ /* Fallback animation */
336
+ .bk-lesson-card.js-hidden, .bk-path-connector.js-hidden, .bk-path-terminal.js-hidden {
337
+ opacity: 0;
338
+ transform: translateY(30px) scale(0.98);
339
+ }
340
+ .bk-lesson-card.js-visible, .bk-path-connector.js-visible, .bk-path-terminal.js-visible {
341
+ opacity: 1;
342
+ transform: translateY(0) scale(1);
343
+ transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1), transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
344
+ }
345
+
346
+ /* Dark theme specific adjustments */
347
+ :root[data-theme="dark"] .bk-path-terminal {
348
+ background: var(--panel);
349
+ }
350
+ :root[data-theme="dark"] .bk-terminal-next {
351
+ background: color-mix(in srgb, var(--accent) 15%, var(--panel));
352
+ }
353
+ :root[data-theme="dark"] .bk-terminal-next:hover {
354
+ background: var(--accent);
355
+ color: var(--panel);
356
+ }
357
+ :root[data-theme="dark"] .bk-lesson-card {
358
+ background: var(--panel);
359
+ box-shadow: 0 4px 20px rgba(0,0,0,0.2);
360
+ }
361
+ :root[data-theme="dark"] .bk-status-unread {
362
+ background: color-mix(in srgb, var(--panel) 50%, transparent);
363
+ }
364
+ :root[data-theme="dark"] .bk-status-unread:hover {
365
+ background: var(--panel);
366
+ }
367
+ :root[data-theme="dark"] .bk-connector-arrow {
368
+ background: var(--panel);
369
+ }
370
+
371
+ @media (max-width: 600px) {
372
+ .bk-lesson-card {
373
+ padding: 1.5rem;
374
+ }
375
+ .bk-lesson-number {
376
+ font-size: 5rem;
377
+ top: -0.5rem;
378
+ right: 1rem;
379
+ }
380
+ .bk-lesson-title {
381
+ padding-right: 0;
382
+ }
383
+ }
384
+ `;
385
+ return `<!DOCTYPE html>
386
+ <html lang="en" data-palette="${palette}" ${schemeAttr}>
387
+ <head>
388
+ <meta charset="UTF-8">
389
+ <meta name="viewport" content="width=device-width, initial-scale=1">
390
+ <title>${escHtml(chapter.meta.title)}</title>
391
+ ${chapter.meta.description ? `<meta name="description" content="${escHtml(chapter.meta.description)}">` : ""}
392
+ <link rel="preconnect" href="https://fonts.googleapis.com">
393
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
394
+ <link href="https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Syne:wght@600;700;800&display=swap" rel="stylesheet">
395
+ ${opts.head ?? ""}
396
+ <link rel="stylesheet" href="assets/theme.css">
397
+ <style>
398
+ ${opts.font ? `:root { --font-sans: ${opts.font}, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }` : ""}
399
+ ${chapterStyles}
400
+ </style>
401
+ </head>
402
+ <body class="bk-layout-${layout} bk-density-${density} bk-tone-${tone}">
403
+ <div class="bk-shell">
404
+ <aside class="bk-sidebar">
405
+ <div class="bk-sidebar-inner">
406
+ <div class="bk-sidebar-header">
407
+ <div style="margin-top: 8px;"></div>
408
+ <div class="bk-sidebar-title">${escHtml(chapter.meta.title)}</div>
409
+ </div>
410
+ <nav class="bk-nav">${navHtml}</nav>
411
+ <div class="bk-sidebar-footer">
412
+ <button class="bk-icon-btn bk-settings-button" id="bk-settings-button" type="button" aria-expanded="false" aria-controls="bk-theme-panel" title="Display settings">
413
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
414
+ <span class="bk-sr-only">Display settings</span>
415
+ </button>
416
+ <div class="bk-theme-panel" id="bk-theme-panel" aria-label="Display settings" hidden>
417
+ <div class="bk-theme-row">
418
+ <span>Theme</span>
419
+ <div class="bk-segmented-control" id="bk-theme-icons">
420
+ <button type="button" class="bk-segment-btn ${theme === "light" ? "active" : ""}" data-theme="light" title="Light" aria-label="Light theme">
421
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
422
+ </button>
423
+ <button type="button" class="bk-segment-btn ${theme === "auto" ? "active" : (!theme ? "active" : "")}" data-theme="auto" title="System" aria-label="System theme">
424
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line></svg>
425
+ </button>
426
+ <button type="button" class="bk-segment-btn ${theme === "dark" ? "active" : ""}" data-theme="dark" title="Dark" aria-label="Dark theme">
427
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
428
+ </button>
429
+ </div>
430
+ </div>
431
+ <div class="bk-theme-row">
432
+ <span>Palette</span>
433
+ <div class="bk-segmented-control" id="bk-palette-icons">
434
+ <button type="button" class="bk-segment-btn ${palette === "ink" ? "active" : ""}" data-palette="ink" title="Ink" aria-label="Ink palette">
435
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z"></path></svg>
436
+ </button>
437
+ <button type="button" class="bk-segment-btn ${palette === "field" ? "active" : ""}" data-palette="field" title="Field" aria-label="Field palette">
438
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z"></path><path d="M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 12"></path></svg>
439
+ </button>
440
+ <button type="button" class="bk-segment-btn ${palette === "ember" ? "active" : ""}" data-palette="ember" title="Ember" aria-label="Ember palette">
441
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 14.5A2.5 2.5 0 0011 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 11-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 002.5 2.5z"></path></svg>
442
+ </button>
443
+ </div>
444
+ </div>
445
+ </div>
446
+ </div>
447
+ </div>
448
+ </aside>
449
+ <button class="bk-sidebar-collapse-floating" id="bk-sidebar-collapse" aria-label="Collapse sidebar">
450
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 18l-6-6 6-6"/></svg>
451
+ </button>
452
+ <main class="bk-main">
453
+ <button class="bk-sidebar-expand" id="bk-sidebar-expand" type="button" aria-label="Expand sidebar">
454
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
455
+ </button>
456
+ <article class="bk-content" style="max-width: 1000px; margin: 0 auto;">
457
+ <header class="bk-hero" style="border-bottom: none;">
458
+ <p class="bk-eyebrow">Chapter</p>
459
+ <h1>${escHtml(chapter.meta.title)}</h1>
460
+ ${chapter.meta.description ? `<p class="bk-deck">${escHtml(chapter.meta.description)}</p>` : ""}
461
+ </header>
462
+ ${timelineHtml}
463
+ </article>
464
+ </main>
465
+ </div>
466
+ <script src="assets/app.js"></script>
467
+ </body>
468
+ </html>`;
469
+ }
@@ -1,5 +1,4 @@
1
- import type { BuildOptions, Chapter, Course, Lesson } from "../types.js";
1
+ import type { BuildOptions, Chapter, Lesson } from "../types.js";
2
2
  export declare function render(lesson: Lesson, opts?: BuildOptions): string;
3
3
  export declare function renderChapter(chapter: Chapter, opts?: BuildOptions): string;
4
- export declare function renderCourse(course: Course, opts?: BuildOptions): string;
5
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOzE,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CAatE;AAID,wBAAgB,aAAa,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,YAAiB,GACrB,MAAM,CAqXR;AAID,wBAAgB,YAAY,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,YAAiB,GACrB,MAAM,CAqXR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOjE,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CAatE;AAID,wBAAgB,aAAa,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,YAAiB,GACrB,MAAM,CAqYR"}