rikiki-deck 0.5.0 → 0.7.1

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 (151) hide show
  1. package/.claude/skills/rikiki-debug/SKILL.md +65 -0
  2. package/.claude/skills/rikiki-deck/SKILL.md +366 -0
  3. package/.claude/skills/rikiki-theme/SKILL.md +70 -0
  4. package/README.md +101 -38
  5. package/bin/lib/assemble.mjs +154 -0
  6. package/bin/lib/box-geometry.mjs +66 -0
  7. package/bin/lib/browser.mjs +279 -0
  8. package/bin/lib/check.mjs +992 -0
  9. package/bin/lib/cli-error.mjs +26 -0
  10. package/bin/lib/diff.mjs +275 -0
  11. package/bin/lib/export-pdf.mjs +42 -0
  12. package/bin/lib/graph-hit.mjs +86 -0
  13. package/bin/lib/inline.mjs +71 -8
  14. package/bin/lib/prune-icons.mjs +81 -0
  15. package/bin/lib/render.mjs +195 -0
  16. package/bin/lib/scan-external.mjs +126 -0
  17. package/bin/lib/starter.mjs +27 -14
  18. package/bin/lib/visual.mjs +120 -0
  19. package/bin/rikiki.mjs +410 -30
  20. package/dist/annotation-marks.js +1 -0
  21. package/dist/application/deep-link.d.ts +29 -0
  22. package/dist/application/keymap.d.ts +40 -0
  23. package/dist/application/mouse-nav.d.ts +12 -0
  24. package/dist/atoms/deck-code-highlighter.d.ts +6 -0
  25. package/dist/atoms/deck-code.d.ts +14 -0
  26. package/dist/atoms/deck-punch.d.ts +6 -0
  27. package/dist/atoms/deck-source.d.ts +12 -0
  28. package/dist/bar-segments.js +1 -0
  29. package/dist/browser-location.js +1 -0
  30. package/dist/cards-syntax.js +6 -0
  31. package/dist/click-stages.js +1 -1
  32. package/dist/contrast.js +1 -0
  33. package/dist/deck-agenda.js +6 -0
  34. package/dist/deck-annotate.js +18 -0
  35. package/dist/deck-bar.js +19 -0
  36. package/dist/deck-bento.js +4 -0
  37. package/dist/deck-callout.js +1 -1
  38. package/dist/deck-cell.js +1 -0
  39. package/dist/deck-checklist.js +1 -0
  40. package/dist/deck-code-highlighter.js +1 -0
  41. package/dist/deck-code.js +2 -2
  42. package/dist/deck-cover.js +6 -6
  43. package/dist/deck-csv.js +15 -0
  44. package/dist/deck-feature-cards.js +2 -2
  45. package/dist/deck-feature.js +2 -2
  46. package/dist/deck-figure.js +8 -0
  47. package/dist/deck-fit.js +1 -0
  48. package/dist/deck-flow.js +7 -0
  49. package/dist/deck-graph.js +25 -0
  50. package/dist/deck-grid.js +1 -1
  51. package/dist/deck-icon.js +1 -0
  52. package/dist/deck-kpi-grid.js +4 -0
  53. package/dist/deck-link.js +1 -0
  54. package/dist/deck-md.js +8 -3
  55. package/dist/deck-mermaid.js +15 -3
  56. package/dist/deck-outline.js +1 -0
  57. package/dist/deck-overview.js +15 -2
  58. package/dist/deck-persona.js +6 -0
  59. package/dist/deck-photo.js +1 -1
  60. package/dist/deck-point.js +1 -0
  61. package/dist/deck-presenter.js +85 -16
  62. package/dist/deck-pull.js +1 -0
  63. package/dist/deck-punch.js +1 -1
  64. package/dist/deck-quote.js +6 -0
  65. package/dist/deck-root.js +17 -13
  66. package/dist/deck-section.js +2 -2
  67. package/dist/deck-source.js +2 -0
  68. package/dist/deck-split.js +5 -3
  69. package/dist/deck-stat.js +2 -2
  70. package/dist/deck-step-list.js +4 -2
  71. package/dist/deck-table.js +1 -0
  72. package/dist/deck-takeaway.js +2 -2
  73. package/dist/deck-timeline.js +5 -0
  74. package/dist/deck-transition.js +3 -3
  75. package/dist/deck-versus.js +9 -0
  76. package/dist/deep-link.js +1 -0
  77. package/dist/domain/deck-link.d.ts +21 -0
  78. package/dist/domain/deck-outline.d.ts +50 -0
  79. package/dist/domain/navigation.d.ts +25 -0
  80. package/dist/domain/viewport.d.ts +42 -0
  81. package/dist/escape-html.js +1 -0
  82. package/dist/extras/deck-agenda.d.ts +25 -0
  83. package/dist/extras/deck-annotate.d.ts +108 -0
  84. package/dist/extras/deck-bar.d.ts +32 -0
  85. package/dist/extras/deck-checklist.d.ts +20 -0
  86. package/dist/extras/deck-figure.d.ts +26 -0
  87. package/dist/extras/deck-flow.d.ts +41 -0
  88. package/dist/extras/deck-graph.d.ts +92 -0
  89. package/dist/extras/deck-icon.d.ts +20 -0
  90. package/dist/extras/deck-kpi-grid.d.ts +26 -0
  91. package/dist/extras/deck-persona.d.ts +31 -0
  92. package/dist/extras/deck-pull.d.ts +13 -0
  93. package/dist/extras/deck-quote.d.ts +28 -0
  94. package/dist/extras/deck-table.d.ts +26 -0
  95. package/dist/extras/deck-timeline.d.ts +31 -0
  96. package/dist/extras/deck-versus.d.ts +18 -0
  97. package/dist/extras/signature.d.ts +2 -0
  98. package/dist/fit-controller.js +1 -0
  99. package/dist/graph-layout.js +1 -0
  100. package/dist/grid-tracks.js +1 -0
  101. package/dist/icon-set.js +1 -0
  102. package/dist/index.d.ts +9 -0
  103. package/dist/index.js +92 -49
  104. package/dist/infrastructure/browser-location.d.ts +3 -0
  105. package/dist/keymap.js +1 -0
  106. package/dist/layouts/deck-bento.d.ts +38 -0
  107. package/dist/layouts/deck-cover.d.ts +6 -0
  108. package/dist/layouts/deck-feature.d.ts +7 -0
  109. package/dist/layouts/deck-split.d.ts +12 -0
  110. package/dist/layouts/deck-takeaway.d.ts +7 -0
  111. package/dist/molecules/deck-callout.d.ts +2 -0
  112. package/dist/molecules/deck-cell.d.ts +19 -0
  113. package/dist/molecules/deck-csv.d.ts +38 -0
  114. package/dist/molecules/deck-fit.d.ts +14 -0
  115. package/dist/molecules/deck-md.d.ts +3 -0
  116. package/dist/molecules/deck-point.d.ts +22 -0
  117. package/dist/molecules/deck-stat.d.ts +2 -0
  118. package/dist/molecules/deck-step-list.d.ts +8 -0
  119. package/dist/mouse-nav.js +1 -0
  120. package/dist/navigation.js +1 -0
  121. package/dist/parse-csv.js +3 -0
  122. package/dist/plugins/click-stages.d.ts +5 -0
  123. package/dist/plugins/shiki.d.ts +2 -2
  124. package/dist/runtime/deck-root.d.ts +179 -2
  125. package/dist/shared/annotation-marks.d.ts +60 -0
  126. package/dist/shared/bar-segments.d.ts +28 -0
  127. package/dist/shared/cards-syntax.d.ts +31 -0
  128. package/dist/shared/contrast.d.ts +52 -0
  129. package/dist/shared/escape-html.d.ts +3 -0
  130. package/dist/shared/fit-controller.d.ts +27 -0
  131. package/dist/shared/graph-layout.d.ts +35 -0
  132. package/dist/shared/grid-tracks.d.ts +17 -0
  133. package/dist/shared/icon-set.d.ts +6 -0
  134. package/dist/shared/parse-csv.d.ts +9 -0
  135. package/dist/shared/slide-fill.d.ts +8 -0
  136. package/dist/shared-styles.js +1 -1
  137. package/dist/shiki.js +1 -1
  138. package/dist/signature.js +1 -0
  139. package/dist/slide-fill.js +1 -0
  140. package/dist/standalone.js +223 -98
  141. package/dist/vendor/THIRD-PARTY-NOTICES.txt +4347 -0
  142. package/dist/vendor/inventory.json +3029 -0
  143. package/dist/vendor/lit.js +62 -2
  144. package/dist/vendor/shiki.js +1 -57
  145. package/dist/viewport.js +1 -0
  146. package/docs/llms/rikiki-reference.md +1048 -72
  147. package/docs/llms/rikiki-workflow.md +536 -0
  148. package/llms.txt +42 -13
  149. package/package.json +25 -8
  150. package/themes/rikiki.css +176 -50
  151. package/themes/siliceum.css +176 -54
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: rikiki-debug
3
+ description: Use when a rikiki deck renders or behaves wrong — slides unstyled or tiny, letterbox bands clash, content overflows or won't reflow, click-stages/reveals don't fire, navigation dead, livereload silent, or a bundled single-file deck breaks. Triggers on "rikiki not rendering", "deck broken", "slides unstyled", "reveals don't work", "debug a deck".
4
+ ---
5
+
6
+ # Debugging a rikiki deck
7
+
8
+ Work from the symptom. Most breakage is load order, a wrong selector/token, or
9
+ the rendering model — not the engine. `docs/llms/rikiki-reference.md` is the
10
+ source of truth for tags, attributes, and tokens.
11
+
12
+ ## First checks (do these before anything)
13
+
14
+ - **Console + network.** A `Failed to load resource` on `dist/index.js` or the
15
+ theme means a wrong relative path — the deck never upgrades. Fix the two paths
16
+ in the `<head>` first.
17
+ - **Load order.** Theme `<link>` must come **before** `dist/index.js`. Reversed,
18
+ components upgrade with no tokens and render unstyled.
19
+ - **Upgrade.** In the console, `customElements.get('deck-root')` must be defined
20
+ and `document.querySelector('deck-root > [active]')` must match one slide.
21
+
22
+ ## Symptom → cause
23
+
24
+ | Symptom | Likely cause |
25
+ |---|---|
26
+ | Whole deck unstyled / browser-default fonts | theme `<link>` missing or after `index.js`; or a non-rikiki page consuming theme CSS without the engine |
27
+ | Slides tiny / letterboxed on mobile | working as designed — zoom-to-fit canvas (1920×1080) scaled to fit. Want reflow? add `fluid` on `<deck-root>` |
28
+ | Letterbox bands clash with a slide | slide background isn't opaque or uses a gradient/image; bands match only an opaque `background-color` |
29
+ | Content overflows the slide | authored past the logical canvas; use `cqw/cqh` and `--rik-*` sizing, not fixed px |
30
+ | Content missing or in the wrong place / a title/lead doesn't show | wrong or missing `slot=` name — each layout names its slots (e.g. `deck-split` uses `left`/`right` or `a`/`b`/`c`, not arbitrary names). Check the layout's slots in the reference |
31
+ | Arrows don't jump between chapters / `↑↓` does nothing | 2D navigation is opt-in: add `nav="2d"` on `<deck-root>` (needs `<deck-section>` chapters). Without it arrows are linear — by design |
32
+ | One slide's `<style>` leaks deck-wide | the `<style>` lacks `scoped` — without it a light-DOM `<style>` is a global stylesheet |
33
+ | Reveals / click-stages don't fire | `installClickStages()` not called, or wrong attribute (`data-click`, `data-anim=…` — check the reference's exact values). On a deck created **dynamically after** `installClickStages()`, register per instance: `deckRoot.use(clickStagesPlugin())` |
34
+ | `customElements.define` "already used" crash from a plugin | a plugin (or custom code) did a **value** import from a per-component dist file (`dist/deck-code.js`, `dist/deck-root.js`) which re-bundles + re-defines the element. Import types with `import type`, and reach shared state via `customElements.get(...)` or the re-exports from `dist/index.js` |
35
+ | Steps don't advance | missing `steps="N"` + `[data-step-block]`, or `deck-code[step-groups]` JSON malformed |
36
+ | Navigation dead | `mouse-nav="none"`, focus trapped in an input, or an overlay (`?`/`O`) open |
37
+ | Zoom does nothing / "ça zoom pas" | Slide zoom is on by default in the fixed canvas: Ctrl/⌘+wheel, pinch, or `+`/`-`/`0` magnify the slide (drag/wheel to pan, any nav resets). If it does nothing: the deck is in `fluid` mode (no fixed layout to magnify · use the fixed canvas), `no-zoom` is set, or an overlay (`?`/`O`) is open. For reflowing bigger text instead of magnification, use `fluid` + `cqw/cqh` |
38
+ | Embedded deck breaks the host page | an older runtime — 0.5.0+ scopes globals to full-page decks; upgrade the package |
39
+ | Livereload silent | `?live` missing from the URL, or the static server doesn't see file changes |
40
+ | Bundled single-file deck unstyled | `rikiki bundle` resolves a plain relative ref against the deck's own dir; the `rikiki/(dist\|themes\|tokens.css)` convention is what triggers the package-root fallback. A deck pointing outside its dir (`../../dist/index.js`) won't inline — repoint at `rikiki/…`-style paths. See reference §9 |
41
+ | A `deck-graph` node sits outside its canvas | `check` reports `GRAPH_NODE_OUT_OF_BOUNDS` (error) · move the node inward with `at`, shorten its note, or constrain it with `width` / `--deck-node-size` |
42
+ | Two `deck-graph` nodes are painted on top of each other | `check` reports `GRAPH_NODE_OVERLAPS_NODE` (error) · move one with `at`, or narrow both with `width` / `--deck-node-size` |
43
+ | A `deck-graph` arrow or line passes under an unrelated node | `check` reports `GRAPH_EDGE_CROSSES_NODE` (warning) · move the obstructing node or split the route into a clear path; an orthogonal route (`route="ortho"` on `deck-edge`) is preferable when available |
44
+
45
+ ## Measure first
46
+
47
+ `npx rikiki check <deck>.html --json` before reading anything. It names the
48
+ runtime that never loaded, the file that did not arrive, the misspelled element
49
+ that renders as nothing, and the content the slide clips away · each with the
50
+ element path, inside the Shadow DOM when that is where it is. Most of the table
51
+ above is answered by that one command.
52
+
53
+ ## Isolate
54
+
55
+ Reproduce against a known-good deck: `npx rikiki init probe.html` writes one,
56
+ with its runtime, in a directory of its own. If that deck works and yours
57
+ doesn't, the fault is in your markup — diff its `<head>` and its slide tags
58
+ against the reference.
59
+
60
+ ## Rules
61
+
62
+ - Don't patch a symptom with hardcoded px or `!important` — find the wrong
63
+ token, path, or attribute.
64
+ - Only trust tags/attributes/tokens listed in the reference; a silent no-op is
65
+ usually an invented name.
@@ -0,0 +1,366 @@
1
+ ---
2
+ name: rikiki-deck
3
+ description: Use when writing, composing or fixing a slide deck with rikiki — turning a brief into slides, choosing a composition, writing speaker notes, adding reveals, checking a deck and delivering it as HTML, a single file or a PDF. Triggers on "rikiki deck", "create a slide deck", "make slides", "presentation deck", "fais des slides", "une présentation".
4
+ ---
5
+
6
+ # Writing a deck with rikiki
7
+
8
+ A deck is plain HTML: a theme stylesheet, then `dist/index.js`, then a
9
+ `<deck-root>` wrapping `deck-*` elements. Nothing compiles. You edit the file,
10
+ a browser renders it, and two commands let you see and measure what you wrote.
11
+
12
+ Work in this order. Skipping to step 4 is how a deck ends up correct and
13
+ useless.
14
+
15
+ ```
16
+ 1 contract → 2 plan → 3 composition → 4 write → 5 independent review → 6 fix → 7 deliver
17
+ ```
18
+
19
+ Full guide, with the nine recipes and their verified HTML:
20
+ `node_modules/rikiki-deck/docs/llms/rikiki-workflow.md`.
21
+ Every tag, attribute and token: `rikiki-reference.md` beside it.
22
+
23
+ ## The agent workflow
24
+
25
+ Treat deck writing as a small editorial pipeline, not one long generation.
26
+ Use separate passes when agents are available:
27
+
28
+ 1. **Planner** turns the brief into a contract, a fact ledger and a slide plan.
29
+ 2. **Writer** turns that plan into HTML and notes without adding claims.
30
+ 3. **Content critic** checks the story, claims, sources, titles and notes without
31
+ editing the deck.
32
+ 4. **Visual critic** renders every slide and reveal state, reads the images and
33
+ reports hierarchy, density, balance and legibility without editing the deck.
34
+ 5. **Integrator** applies only accepted findings, then runs the complete check
35
+ and render pass again.
36
+
37
+ The planner's artifacts are the handoff between agents. Keep them in a
38
+ temporary working directory, with one row per slide containing `id`, question,
39
+ claim, evidence, composition, source and note purpose. The fact ledger lists
40
+ every number, quote, date and external asset with its source or `TODO`; the
41
+ writer may use only entries in that ledger. If there is one agent, simulate the
42
+ same boundaries by saving each artifact before starting the next pass. Never
43
+ ask the writer to approve its own deck in the same instruction.
44
+
45
+ Critics return findings keyed by slide id and severity (`blocker`, `fix`, or
46
+ `choice`). The integrator fixes blockers first, then fixes, and leaves choices
47
+ for the user when they change the argument or tone. Re-run the critics after a
48
+ structural change, not only after changing CSS.
49
+
50
+ The working guide contains copyable boundaries for these five prompts and the
51
+ expected status markers. Use them when delegating; do not collapse the writer
52
+ and critic into one pass to save a turn.
53
+
54
+ ## 1 · The contract, before any HTML
55
+
56
+ Eight lines. They decide everything after them.
57
+
58
+ ```
59
+ Audience · Decision · Duration · Language · Context · Theme · Sources · Missing
60
+ Tone: sober unless asked otherwise · gifs only on explicit request
61
+ ```
62
+
63
+ - **Ask for what is missing.** If you cannot ask, write the assumption into the
64
+ deck where it will be seen and fixed, not into your own head.
65
+ - **Never invent a number, a quotation or a source.** Not a rounded figure, not
66
+ a plausible date. A gap marked `TODO` gets filled before the talk; an invented
67
+ figure gets presented.
68
+ - **Duration is words, not slides.** Speech runs at 100 to 130 words a minute
69
+ for technical content, so twenty minutes is roughly 2,400 spoken words. Those
70
+ words live in `<deck-notes>`. Nine thin slides fill ten minutes, whatever the
71
+ plan says.
72
+
73
+ ## 2 · The plan · three columns, not a table of contents
74
+
75
+ A list of subjects is not a plan. What makes a deck hold together is that each
76
+ slide answers a question the previous one opened. Write three columns:
77
+
78
+ ```
79
+ # Question the room is asking here → What this slide answers → With what
80
+ 2 "Why should I care?" Recopying costs 40 min two-column comparison
81
+ 3 "So what would work instead?" A slide is an HTML element the code itself
82
+ 5 "Does that actually hold?" Valid code, broken slide screenshot + marks
83
+ ```
84
+
85
+ Two rules make it mechanical:
86
+
87
+ - **A slide answering no open question is cut or moved.** This is the single
88
+ most useful check. It removes the "while we're at it" slides that a subject
89
+ list always grows.
90
+ - **A question still open at the end needs a slide.** If nothing answers "what
91
+ do I do Monday", the deck has no ending.
92
+
93
+ ### The shape underneath
94
+
95
+ Two structures cover almost every technical talk. Pick one, name it, keep it.
96
+
97
+ - **Situation, complication, question, answer.** State the shared ground, then
98
+ what disrupts it, then the question that follows, then your answer with its
99
+ support. Barbara Minto's structure, from the consulting world, and the one
100
+ that carries a recommendation best.
101
+ - **What is, what could be.** Alternate the present state and the possible one,
102
+ each return to "what is" buying the next claim, tightening until the last
103
+ slide only names the action.
104
+
105
+ For a tooling or migration talk, problem then solution then results works; for a
106
+ learning or migration story, the journey shape does.
107
+
108
+ ### The title test, before writing any body
109
+
110
+ Read the slide titles in sequence, aloud. They must form a text that stands on
111
+ its own · that is the deck's argument. Any title that reads as a subject
112
+ ("The architecture") rather than a claim breaks the chain, and any title you
113
+ could move elsewhere without loss means the order is not a story.
114
+
115
+ `rikiki render` writes the titles into its manifest, so the test can be run on
116
+ a deck already written. Run it on the plan first; it costs nothing there.
117
+
118
+ Freeze the plan before writing HTML. Each row is complete only when it names the
119
+ audience's question, the slide's answer, the evidence that earns the answer,
120
+ the source for each factual item, and what the speaker will add in the notes.
121
+ A topic, a component name, or a decorative idea is not evidence.
122
+
123
+ ## 3 · Composition
124
+
125
+ ### The rule the research supports
126
+
127
+ The title is a **full sentence stating what the slide argues**, eight to
128
+ fourteen words. The body is its **evidence**: a figure, a diagram, a number, a
129
+ comparison. Not a bullet list restating the title.
130
+
131
+ This is assertion-evidence, and it is here because it was measured: against the
132
+ usual topic headline over bullets, audiences understood and remembered more,
133
+ with fewer misconceptions and lower cognitive load. It is Mayer's multimedia
134
+ principles at slide scale.
135
+
136
+ Two consequences:
137
+
138
+ - **A bullet list read aloud is worse than no slide.** The room reads and
139
+ listens to the same words at once, and pays for it.
140
+ - **Cutting is a design act.** Removing what does not serve the claim improves
141
+ comprehension by itself.
142
+
143
+ `deck-cover` and `deck-section` are exempt: a chapter title is a boundary.
144
+
145
+ ### Graphic composition, in seven decisions
146
+
147
+ What separates a slide that reads at ten metres from one that does not. The
148
+ first four are the ones that carry; spend effort there.
149
+
150
+ | Decision | The rule | The failure it prevents |
151
+ |---|---|---|
152
+ | **Hierarchy** | Two type sizes, and the gap between them *is* the design. A statement size and a reading size, nothing between. But the title is not free: a headline that wraps to two lines eats a third of the canvas, and everything under it then looks small. Prefer a title that fits one line. | A title at 1.5× reads as bold body text · the single commonest reason a deck looks flat. Its opposite: a three-line headline over one small box. |
153
+ | **Mass** | One filled area at most. Everything else sits on the page ground. | Two masses and the eye picks the wrong one. |
154
+ | **Text density** | The strongest measurable predictor of how a room judges a slide. When in doubt, remove a sentence. | A wall of text: nobody reads it, they wait for you to say it. |
155
+ | **Balance** | One alignment axis for the whole slide. Left-align by default; centre only when a single block is the whole slide. | Content massed in the top fifth with a dead half below · fix it with `spread`, not with more content. |
156
+ | **Colour** | The accent is a **mark**, not a surface: a rule, a stroke, a number, a word. Real emphasis on a light theme is the inverse surface. | An accent-tinted panel that is invisible on one of the two shipped themes. |
157
+ | **Whitespace** | Empty space is a choice, not a defect. It is what makes the one loud thing loud. But a lone callout on an otherwise empty slide is not restraint, it is a slide with nothing on it: either the claim deserves real evidence, or it belongs in the notes of the slide before. | Filling the space because it is there · and its opposite, a slide carrying one small box. |
158
+ | **Structure** | A device must encode information: number a list only when it is a sequence, label a block only when the label adds something. | Numbered markers on three unordered items, eyebrows above everything. |
159
+
160
+ ### The density floor
161
+
162
+ A content slide carries at least one of: a figure, an image, three comparable
163
+ items, a diagram, or code. A headline over one sentence is not a slide · it is
164
+ a sentence that belongs in the notes of the slide before it.
165
+
166
+ `rikiki check` measures this on the pixels and reports `SLIDE_TOP_HEAVY` when
167
+ the ink sits in the top of the canvas with a dead band under it. It reports the
168
+ imbalance, never the amount of empty space: space that the composition uses is
169
+ left alone.
170
+
171
+ ### Emphasis, icons, and the occasional gif
172
+
173
+ Flat prose on a slide reads as flat prose in the room. Three cheap tools:
174
+
175
+ - **Bold for the word that carries the claim**, italic for the aside or the term
176
+ you are introducing. One or two per slide · past that nothing stands out.
177
+ - **`deck-icon`** (opt-in, 24 drawn glyphs) beside a status, a step or a
178
+ verdict. It gives a shape to what would otherwise be another line of text.
179
+ Give it a `label` when it carries meaning, leave it off when it decorates.
180
+ **Gifs are asked for, never offered.** Add one only when the person writing the
181
+ deck asks for it in so many words. No gif by default, none "because the slide
182
+ felt dry", none in a deck whose tone was never discussed. A steering committee
183
+ and a Friday internal talk do not want the same thing, and guessing wrong is
184
+ worse than a sober slide.
185
+
186
+ When asked: place one between two dense passages, or right after the hardest
187
+ slide. One per talk, maybe two. It works because it is rare, and never on a
188
+ slide that already has something to say.
189
+
190
+ **Where the file comes from matters as much as the file.** Tenor and Giphy both
191
+ require an API key, and their catalogue is largely clips from films and shows:
192
+ fine for a Friday internal talk, a risk for a recorded conference. Without a key
193
+ in the environment, use a source whose licence is explicit · Wikimedia Commons
194
+ has one on every file · or draw the animation yourself in the deck's own
195
+ colours. Either way, credit it on the slide: author, licence, source, one line.
196
+
197
+ The file must live next to the deck. A gif left on a remote URL breaks the
198
+ single-file promise, and `rikiki bundle` exits non-zero for it. Downloaded, it
199
+ inlines as base64 like any image (a 400 KB gif costs 400 KB there) and exports
200
+ to PDF as its first frame. Say so when you use one.
201
+
202
+ ### Show the mechanism, do not describe it
203
+
204
+ A technical audience reads a diagram faster than a sentence about the same
205
+ thing. Three habits separate a deck that argues from one that recites:
206
+
207
+ - **A boxed sentence is not evidence.** A `deck-callout` carrying two lines of
208
+ prose is the claim restated in a frame. Either the slide has something to
209
+ show, or the sentence belongs in the notes of the slide before it.
210
+ - **Show your own artefacts.** A screenshot of the broken thing, the real
211
+ report, the actual output. `deck-annotate` puts numbered marks on an image
212
+ and reveals them one per step · one photograph of a defect beats a paragraph
213
+ describing it.
214
+ - **Draw the flow.** A pipeline, a fan-out, a set of layers: `deck-graph` with
215
+ positioned nodes says in one look what three bullets say badly. Reserve
216
+ `deck-flow` for what is genuinely a sequence · one source with three outputs
217
+ is a fan-out, and numbering it is a lie about the content. If an edge's
218
+ straight line would pass under a node it does not connect, add
219
+ `route="ortho"` on that `deck-edge` rather than repositioning nodes around
220
+ it.
221
+
222
+ ### Choosing the element
223
+
224
+ Pick from what the slide has to say, not from the tag you remember. Reach for
225
+ the opt-in components when they fit · one `<script type="module">` each, after
226
+ the core bundle.
227
+
228
+ | The slide says | Reach for |
229
+ |---|---|
230
+ | A claim and its proof | `deck-feature` + `deck-callout` / `deck-code` |
231
+ | Two options, before and after | `deck-split` with two `deck-card` |
232
+ | One figure that carries the slide | `deck-stat` (`num` + a `claim` slot) |
233
+ | Several figures as one family | `deck-kpi-grid` + `deck-kpi` (opt-in) |
234
+ | An ordered process | `deck-flow` + `deck-flow-step` (opt-in) |
235
+ | How the parts sit together | `deck-graph` + `deck-node` / `deck-edge` (opt-in) |
236
+ | A screenshot, diagram or chart with a caption and a source | `deck-figure` (opt-in) |
237
+ | What works and what does not | `deck-checklist` + `deck-check` (opt-in) |
238
+ | A trajectory in time | `deck-timeline` + `deck-milestone` (opt-in) |
239
+ | Code, explained | `deck-code lang="…" hero` |
240
+ | The close | `deck-takeaway` |
241
+
242
+ `deck-mermaid` renders a diagram from text, but a hand-placed `deck-graph`
243
+ reads better for anything you can position yourself.
244
+
245
+ ## 4 · Writing
246
+
247
+ ```sh
248
+ npx rikiki init talk.html --title "…" --theme rikiki # or siliceum
249
+ ```
250
+
251
+ Then edit the HTML. Three rules that save a rewrite:
252
+
253
+ - **Give every slide a stable `id`.** It is how `render` selects it, how
254
+ `check` names it, and how you edit one slide later without touching the rest.
255
+ - **An attribute a component does not read is dropped in silence.** `deck-stat`
256
+ takes `num` and its words as content; `label="…"` on it loses the label with
257
+ no error. `check` reports these.
258
+ - **Slotted content only renders if a slot takes it.** A `deck-card slot="a"`
259
+ inside the wrong parent leaves a blank slide.
260
+
261
+ ## The presentation mode · what the speaker gets
262
+
263
+ Press **P** and rikiki opens a second window: the current slide, the next one as
264
+ a preview, a running timer, and the `<deck-notes>` of the slide on screen. With
265
+ a second display it sends the slides fullscreen to the projector and keeps this
266
+ view on the speaker's screen. Both windows stay in sync through
267
+ `BroadcastChannel`.
268
+
269
+ Design for that window from the start:
270
+
271
+ - **The notes are the script, not a summary.** Write what you would say. The
272
+ slide already carries what is projected; repeating it there wastes the one
273
+ surface the speaker actually reads.
274
+ - **Put in the notes what must not be projected**: the source of a figure, the
275
+ method behind it, the answer to the question you expect, the sentence you
276
+ would add if asked, what to say if a demo fails.
277
+ - **The notes are what `check` measures for length.** A deck whose cover says
278
+ `duration="20 min"` and whose notes carry two minutes of speech gets a
279
+ warning. Either the notes are thin, or the slot is shorter than announced.
280
+ - **`<deck-notes>` never appears on the slide** and is not counted in what the
281
+ room sees. It is the only place where being long is free.
282
+
283
+ ### Reveals, when the slide would otherwise be a wall
284
+
285
+ ```html
286
+ <deck-feature steps="2">
287
+ <h1 slot="title">Two things happen, in order</h1>
288
+ <p data-step-block="1">The first.</p>
289
+ <p data-step-block="2">The second.</p>
290
+ </deck-feature>
291
+ ```
292
+
293
+ Use a reveal when the order is the message: the speaker comments each state
294
+ before the next appears. Do not use it to fit more on one slide · that is a
295
+ split, not a reveal. Render them with `--steps`, or you are judging the emptiest
296
+ state of the deck.
297
+
298
+ ## 5 · Independent review
299
+
300
+ Review in two passes with different questions. The content pass reads the
301
+ contract, plan, titles and notes without looking at the implementation first:
302
+
303
+ - Does each slide answer a question opened by the previous slide?
304
+ - Do the titles form a coherent argument when read aloud?
305
+ - Does every number, quote, date and asset have a source or an explicit `TODO`?
306
+ - Is the note speech rather than projected copy, and does its length fit the
307
+ announced duration?
308
+
309
+ The visual pass starts from rendered images, including every reveal state. Look
310
+ for one focal point, a readable title, evidence that occupies the right amount
311
+ of space, a stable alignment axis, and an image or diagram that can be read at
312
+ the intended distance. Record the slide id and the concrete change needed;
313
+ do not rewrite the deck while reviewing it.
314
+
315
+ The two critics return findings keyed by slide id and severity (`blocker`,
316
+ `fix`, or `choice`). Apply blockers first, then fixes. Leave choices for the
317
+ user when they change the argument or tone. A structural correction triggers
318
+ both review passes again.
319
+
320
+ ## 6 · Fixing, in this order
321
+
322
+ Stop at the first that works. The early moves keep the deck's shape.
323
+
324
+ 1. **Cut the repetition.** The title already says it.
325
+ 2. **Shorten.** Sentences to clauses, clauses to words.
326
+ 3. **Move detail into `<deck-notes>`.** Still said, no longer projected.
327
+ 4. **Split the slide.** Two slides with one idea each beat one with two.
328
+ 5. **Change the composition.** A list that will not fit is often a comparison,
329
+ a flow, or a single number.
330
+ 6. **Adjust the type,** last, and within the readable floor.
331
+
332
+ A request about one slide changes that slide. Keep the ids stable, leave the
333
+ others byte for byte, and re-run `check` on the whole deck afterwards.
334
+
335
+ ## 7 · Look, measure, deliver
336
+
337
+ ```sh
338
+ npx rikiki check talk.html # 0 clean · 1 defects · 2 could not look
339
+ npx rikiki render talk.html --steps # one picture per state + a manifest
340
+ npx rikiki bundle talk.html # one file, opens offline (needs rolldown)
341
+ npx rikiki export talk.html # PDF, one page per slide (needs playwright)
342
+ ```
343
+
344
+ **Do both.** `check` measures what is objective: content clipped away, an
345
+ element that renders as nothing, a missing file, text too small for a room, an
346
+ attribute being ignored, a deck shorter than it claims. It does not judge
347
+ whether the slide is any good. So read the pictures too · a green report on an
348
+ ugly slide is still an ugly slide.
349
+
350
+ Read what the report says it did **not** check: your wording, your figures, your
351
+ argument, accessibility. Silence there is not approval.
352
+
353
+ ## Before saying it is done
354
+
355
+ - [ ] Every figure in the deck comes from the brief, and nothing else does.
356
+ - [ ] The plan and fact ledger exist, and the writer stayed inside the ledger.
357
+ - [ ] The titles, read in sequence, form a text that holds together.
358
+ - [ ] Each slide answers a question an earlier slide opened.
359
+ - [ ] Each content slide's title is a sentence that states its message.
360
+ - [ ] No slide is a headline over a single sentence.
361
+ - [ ] Notes are written as speech, and their length matches the announced slot.
362
+ - [ ] `rikiki check` exits 0.
363
+ - [ ] You looked at the rendered pictures, including revealed states.
364
+ - [ ] A separate content pass and visual pass reviewed the final structure.
365
+ - [ ] Structural changes triggered another full review, not only a local check.
366
+ - [ ] What you did not verify is said out loud.
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: rikiki-theme
3
+ description: Use when creating, customizing, or debugging a rikiki theme — defining a new color/typography look, overriding design tokens, porting an existing brand into a deck, or fixing a theme where colors/fonts don't apply. Triggers on "rikiki theme", "new theme", "custom theme", "theme tokens", "rebrand a deck".
4
+ ---
5
+
6
+ # Authoring rikiki themes
7
+
8
+ A rikiki theme is one CSS file. Most of it is `--rik-*` custom properties at
9
+ `:root`, but **the rules below `:root` are load-bearing** — the reset,
10
+ `::selection`, the `html/body` binding, and slotted-element styles
11
+ (`deck-cover > h1`, `.lead`, `table.dense`, …) paint the page and slide content.
12
+ Components read only the **semantic** tokens, so re-theming never touches
13
+ component code — you swap one `<link>`.
14
+
15
+ `docs/llms/rikiki-reference.md` lists every semantic token. It is the source of
16
+ truth — do not invent token names.
17
+
18
+ ## Start from a copy
19
+
20
+ **Copy the entire `themes/siliceum.css` (the cleanest example) — not just its
21
+ `:root`** — and change values. A `:root`-only theme renders bodies and slide
22
+ titles unstyled because the painting rules sit below `:root`. Keep the layering:
23
+
24
+ 1. **Palette (private).** `--rik-palette-*` raw brand colors (`paper-50`,
25
+ `ink-900`, `accent-500`…). Only this layer holds hex values. Nothing outside
26
+ the theme reads these.
27
+ 2. **Semantic (public).** The names components consume, mapped onto the palette.
28
+ These names match `themes/rikiki.css` **1:1** — keep every one, change only
29
+ the value. The full set is large; the families below are representative, not
30
+ exhaustive — copy the whole `:root` from `themes/rikiki.css` and re-point
31
+ values rather than hand-listing: `--rik-surface-*` (page/raised/inverse),
32
+ `--rik-text-*` (default/inverse/`--faint`), `--rik-accent` (+`--soft`),
33
+ `--rik-status-*` (success/danger/warn/info, each `bg`/`border`/`text`),
34
+ `--rik-interactive-*`, `--rik-border-*`, `--rik-link-*`, `--rik-focus-*`,
35
+ `--rik-selection-*`, `--rik-decor-*`, `--rik-elevation-*`, `--rik-code-*`
36
+ (syntax surface), `--rik-font-*`, `--rik-font-size-*`, `--rik-space-*`,
37
+ `--rik-radius-*`, `--rik-icon-*`, `--rik-opacity-*`, `--rik-motion-*`,
38
+ `--rik-z-*`.
39
+
40
+ Keep the `@media (prefers-reduced-motion: reduce)` block too — it zeroes the
41
+ `--rik-motion-*` durations and neutralizes the spring ease.
42
+
43
+ ## Fonts
44
+
45
+ Declare `@font-face` (or import a `*-fonts.css`, like `siliceum-fonts.css`) and
46
+ point `--rik-font-sans` / `--rik-font-mono` / `--rik-font-display` at them. The
47
+ default theme pulls Unbounded + Inter + Space Mono from Google Fonts; self-host
48
+ for offline decks.
49
+
50
+ ## Rules
51
+
52
+ - Define the **full** semantic set. A missing token falls back to nothing and
53
+ breaks a component silently — diff your `:root` against `themes/rikiki.css`
54
+ (e.g. `comm -23` of the two token lists must be empty).
55
+ - Put hex only in the palette layer; semantic tokens reference it via `var(...)`.
56
+ Two sanctioned exceptions, as in both shipped themes: `--rik-code__*` (the
57
+ syntax surface) holds raw hex, and alpha tints use `rgba(...)` literals.
58
+ - For a **dark** theme, keep the inverse surfaces (`--rik-palette-night-*`)
59
+ *darker* than the dark page so cover/section/takeaway stay a distinct layer.
60
+ - Don't restyle components in the theme. Per-component tweaks are `--deck-*-…`
61
+ tokens set on that host, not in the theme file.
62
+ - Keep `--rik-*` lowercase; match WCAG contrast (the default theme documents the
63
+ link-contrast caveat inline — read it before lowering contrast).
64
+
65
+ ## Verify
66
+
67
+ Load a deck (`npx rikiki init probe.html` writes one) with your theme `<link>`. Click
68
+ through covers, sections, callouts, code, and a `deck-takeaway` (it uses
69
+ `--rik-surface-inverse` + `--rik-accent`). Every surface, text tone, accent and
70
+ status color must be intentional — no browser-default black or unstyled blocks.