stagecraft 0.1.0 → 0.2.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.
package/AGENT.md CHANGED
@@ -2,18 +2,104 @@
2
2
 
3
3
  You're not filling a template. You're directing a scene.
4
4
 
5
- If your slide is fewer than three lines, it's probably boring. The components below are anchors, not cages. Take them apart. Add particles, typewriters, glitch transitions, SVG. The Web Animations API is your friend.
5
+ **Reach for custom JS first. Reach for the component catalog when a pattern truly fits.** The 50 components below are sugar around one tiny primitive — they are anchors, never cages. Take them apart. Write raw `render(el)` and `init(el)` functions. Use the Web Animations API. Use SVG. Use Canvas. Animation is the language of your deck — not a checkbox.
6
6
 
7
- ## 1. The rule
7
+ If your slide reads like a filled-in form, you wasted the moment.
8
8
 
9
- - A deck is a collection of `.js` files registered via `Stage.register({...})`.
10
- - Each slide owns its DOM, its animation, its lifecycle.
11
- - The engine handles navigation, the storyboard, and transitions.
12
- - If you copy-paste a component call and don't customize it, you've wasted the opportunity.
9
+ ## 1. What a slide actually is
13
10
 
14
- ## 2. The toolbox (Layer-2 components)
11
+ There is exactly one foundational API:
15
12
 
16
- Components have spare defaults on purpose. Adding animation is opt-in.
13
+ ```js
14
+ Stage.register({
15
+ section, title,
16
+ render(el) { /* set up DOM */ },
17
+ init(el)? { /* run animation, return cleanup */ },
18
+ replay(el)? { /* re-run on R */ },
19
+ steps?, onStep? { /* internal step navigation */ }
20
+ });
21
+ ```
22
+
23
+ That's the whole contract. Everything else — every factory you'll see below — is sugar around this primitive.
24
+
25
+ ### A 100% custom slide (the canonical form)
26
+
27
+ ```js
28
+ Stage.register({
29
+ section: 2,
30
+ title: '02 · Custom motion',
31
+ render(el) {
32
+ el.innerHTML = `
33
+ <h1 style="font-size: clamp(3rem, 9vw, 8rem); font-weight: 600;
34
+ letter-spacing: -0.025em; text-align: center;">
35
+ Write <span class="accent">whatever HTML</span> you want.
36
+ </h1>
37
+ <svg id="field" viewBox="0 0 800 200"
38
+ style="width:min(800px,80vw); height:200px; margin-top:2rem;"></svg>
39
+ `;
40
+ },
41
+ init(el) {
42
+ // Whatever JS animation you want. Web Animations API, RAF, intervals.
43
+ const svg = el.querySelector('#field');
44
+ const id = setInterval(() => {
45
+ const x = Math.random() * 800;
46
+ Stage.emitParticle(svg, x, 200, x + (Math.random() - 0.5) * 200, -20, 2400);
47
+ }, 220);
48
+ return () => clearInterval(id); // cleanup when slide leaves
49
+ }
50
+ }, {
51
+ notes: 'Take this as proof: the catalog is optional. The full power lives here.'
52
+ });
53
+ ```
54
+
55
+ That's a complete, finished slide. No factory required. You can do anything CSS, SVG, Canvas, the Web Animations API, and JS can do — which is everything.
56
+
57
+ ### A factory call (sugar for common shapes)
58
+
59
+ ```js
60
+ Stage.register(Stage.KineticText({
61
+ lines: [
62
+ { text: 'Sometimes', color: 'fg' },
63
+ { text: 'a list of lines', color: 'dim' },
64
+ { text: 'is enough.', color: 'accent' }
65
+ ]
66
+ }));
67
+ ```
68
+
69
+ Both forms coexist. Both accept a second `meta` arg for speaker notes (`{ notes: '...' }`).
70
+
71
+ ## 2. When to write custom vs. reach for a factory
72
+
73
+ **Write a fully custom slide when:**
74
+ - The animation IS the message (token streams, particle fields, terminal logs)
75
+ - You're combining motion patterns no factory covers
76
+ - The slide is the centerpiece of a section — it deserves the time
77
+ - You can see the slide in your head and the catalog can't reproduce it
78
+
79
+ **Extend a factory's `init` when:**
80
+ - The shape fits (a bulleted list, a quote, a stat grid) but you want extra motion on top
81
+ - Get a factory, then call `Object.assign(slide, { init(el) { … } })` or write a wrapping registration
82
+
83
+ **Reach for the factory plain when:**
84
+ - It is genuinely the right pattern — list, comparison, divider — and motion sugar via `reveal: 'staggered' | 'per-click'` is enough
85
+
86
+ A healthy deck: roughly **20–30% bespoke from scratch**, **40% factory + customized init**, **30–40% plain factories**. If your bespoke share is 0%, the deck has gone flat. Add a centerpiece.
87
+
88
+ ## 3. The cookbook (start here for bespoke inspiration)
89
+
90
+ Five real bespoke slides ship in `examples/` — they are not abstract demos, they are slides from a production deck. Read them before writing your own bespoke:
91
+
92
+ - `examples/token-stream.js` — interleaved word-fill across a split panel with particle emit
93
+ - `examples/orchestration-graph.js` — SVG hex-graph, particles flowing from satellites to center
94
+ - `examples/terminal-log.js` — streaming colored log lines + a "human realization" reveal arc
95
+ - `examples/whoami.js` — terminal prompt cycling through identity strings
96
+ - `examples/closing-card.js` — QR + dedication + underline + presenter names
97
+
98
+ These show you the bar. Don't copy them — take the *technique* (the interleaved queue, the SVG particle pattern, the streaming type) and apply it to your own content.
99
+
100
+ ## 4. The toolbox (Layer-2 components — reference)
101
+
102
+ Components have spare defaults on purpose. Adding animation is opt-in. Treat this whole section as a *reference* — scan when you need an anchor, ignore otherwise.
17
103
 
18
104
  ### Stage.KineticText — multi-line staggered reveal (workhorse, ~50% of slides)
19
105
  ```js
@@ -635,7 +721,7 @@ Stage.register(Stage.Marquee({
635
721
  }));
636
722
  ```
637
723
 
638
- ## 3. The toolbox (Layer-1 primitives)
724
+ ## 5. The toolbox (Layer-1 primitives)
639
725
 
640
726
  Available globally as `Stage.<name>`. Use them in any slide's `init()` to build bespoke motion.
641
727
 
@@ -649,19 +735,7 @@ Available globally as `Stage.<name>`. Use them in any slide's `init()` to build
649
735
  | `sessionElapsedClock` | `({start}) → {el, stop}` | Live MM:SS clock element. |
650
736
  | `assignStageKeys` | `(root)` | Auto-assigns `data-stage-key` for edit-mode pins (engine calls this). |
651
737
 
652
- ## 4. The cookbook
653
-
654
- When you need motion that the components don't cover, **read these first** — they're the ceiling, not the floor. All in `examples/`:
655
-
656
- - `examples/token-stream.js` — interleaved word-fill across a split panel, particle emit.
657
- - `examples/orchestration-graph.js` — SVG hex-graph with particles flowing from satellites to center.
658
- - `examples/terminal-log.js` — streaming colored log lines with a human realization reveal.
659
- - `examples/whoami.js` — terminal prompt cycling through identity strings.
660
- - `examples/closing-card.js` — QR + dedication + underline.
661
-
662
- Don't copy them verbatim. Take the technique (the interleaved queue, the SVG particle pattern, the streaming type) and apply it to your own content.
663
-
664
- ## 5. The step model
738
+ ## 6. The step model
665
739
 
666
740
  A slide may declare `steps: N`. The engine:
667
741
 
@@ -688,7 +762,7 @@ Stage.register({
688
762
 
689
763
  For trivial cases use `Stage.revealByDataStep`. For anything richer (glow transitions, particle emit, typewriter on each step) write `onStep` yourself — that's the point.
690
764
 
691
- ## 6. The transition library
765
+ ## 7. The transition library
692
766
 
693
767
  In `stagecraft.config.js`, the `transition` on each slide controls how it enters:
694
768
 
@@ -715,7 +789,7 @@ Built-in (14):
715
789
 
716
790
  Themes override visuals. Unknown → falls back to `fade`.
717
791
 
718
- ## 7. Edit mode (you-might-not-see-it, but: it exists)
792
+ ## 8. Edit mode (you-might-not-see-it, but: it exists)
719
793
 
720
794
  When the human runs `npx stagecraft serve`, they get a browser-based editor that writes back to source. They might leave notes in slides:
721
795
 
@@ -733,19 +807,6 @@ When they say "process my notes":
733
807
 
734
808
  Notes don't get a "resolved" state. Deleting them is how you mark them done.
735
809
 
736
- ## 8. When to register a custom slide vs. use a component
737
-
738
- Use a component when:
739
- - It's truly a list of bullets / a comparison / a section divider — boring is fine for these.
740
- - The visual you want is achievable with one component + minor styling.
741
-
742
- Write a custom slide (just `Stage.register({section, title, render, init, ...})`) when:
743
- - The animation is core to the message (token-stream, orchestration graph, terminal log).
744
- - You're combining motion patterns no component covers.
745
- - The slide is the centerpiece of a section — it deserves the attention.
746
-
747
- The split should be roughly: ~40% workhorse components (KineticText, SectionCard, Quote, BigNumber), ~30% structural (ImageText, Bento, Compare, Pillars, Timeline), ~15% chart/diagram for data-heavy moments (BarChart, Matrix2x2, Pyramid, Funnel, Venn, ProcessFlow, Cycle), ~15% bespoke. If the bespoke share goes below 10%, the deck has gone flat.
748
-
749
810
  ## 9. The full component catalog at a glance
750
811
 
751
812
  | Family | Components |
package/CHANGELOG.md ADDED
@@ -0,0 +1,54 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 — 2026-05-23
4
+
5
+ ### Themes
6
+ - Added **Shopware** theme — fifth official theme, sourced from the Meteor design system (`@shopware-ag/meteor-tokens` v1.4.0). Light, Inter, brand-blue `#0870ff`, semantic palette piped through. Full overrides for all 50 components and all transitions.
7
+ - Polished **Paper**, **Neon**, and **Brand** themes with per-family component overrides (each had been mostly inheriting Phosphor before — now they have distinct visual personalities).
8
+ - **Theme picker** in the storyboard toolbar lets you switch live across all 5 themes.
9
+ - Demo loads all 5 themes' CSS so switching is instant (no reload). Production starter loads a single theme bundle and reloads on switch.
10
+
11
+ ### Editor
12
+ - New **'E' keypress** toggles edit-mode affordances on/off without disconnecting the dev server — present cleanly even with the server running.
13
+ - New **Speaker notes** field (`Stage.register(slide, {notes: '…'})`) with 🎙 button per storyboard tile. AST-aware roundtrip preserves all other slide fields.
14
+ - New **CRUD** in storyboard: ➕ add slide (with template choice), 🗑 delete slide.
15
+ - New **Process notes** button copies a ready-made agent prompt to the clipboard.
16
+ - New **Pin markers** on annotated elements during edit mode (yellow pulsing dots, hover for note text).
17
+ - Element click for inline editing changed from double-click to single click.
18
+
19
+ ### Presenter view
20
+ - Press **P** to open a second window with the presenter view: current slide, next-slide thumbnail, speaker notes, elapsed timer, wall clock. Multi-monitor via `BroadcastChannel` sync. Laptop sees notes, beamer sees clean slide.
21
+
22
+ ### Components (50 total)
23
+ - Phase 3 added: ImageText, FullImage, Quote, BigNumber, Stats, Bento, Pillars, Timeline, Pyramid, Cycle, Funnel, Matrix2x2, BarChart, Progress, ProcessFlow, Venn, KPI, DonutChart, LineChart, Gauge, SparkLine, Heatmap, Roadmap, SWOT, CodeBlock, CodeDiff, Pricing, Testimonial, TeamGrid, Agenda, Checklist, Steps, CTA, Callout, Tip, BeforeAfter, Statement, QandA, Manifesto, Punchline, Definition, ImageGrid, Spotlight, Marquee.
24
+
25
+ ### Transitions (15 total)
26
+ - Added zoom-in, zoom-out, flip (3D rotateY), iris (clip-path), shutter, push, typewriter, shatter.
27
+ - Hover-to-play-once preview in the picker.
28
+
29
+ ### Tooling
30
+ - **Bundle script** (`npm run build`): concatenates everything into `dist/stagecraft.bundle.{js,css}` + per-theme CSS bundles.
31
+ - **PDF export** (`npx stagecraft export pdf`): renders deck to PDF via Playwright + pdf-lib (optional deps).
32
+ - **Visual regression** harness (`tests/visual/run.js`): Playwright snapshots with optional pixelmatch diffing.
33
+ - **GitHub Pages CI**: `npm run build` + `scripts/deploy-build.js` produce a `deploy/` directory; `.github/workflows/deploy-pages.yml` ships it on every push to main.
34
+ - **Verify CI**: `.github/workflows/verify.yml` runs `npm run verify` (AST tests), syntax-checks every JS file, builds bundles, and assembles the deploy directory on every PR.
35
+
36
+ ### Accessibility
37
+ - `prefers-reduced-motion: reduce` shortcuts the typewriter, particles, and stagger animations to their final state.
38
+
39
+ ### Bug fixes
40
+ - CodeBlock/CodeDiff: removed redundant `<pre>` wrapper that was preserving template-string whitespace as huge inter-line gaps.
41
+ - Venn diagram: geometry now expressed in SVG viewBox units; labels converted to container-% on render, so they align with the circles regardless of container aspect ratio.
42
+ - Heatmap: x-labels wrapped in a `.hm-x-row` grid container so they run horizontally instead of stacking.
43
+ - Drag-to-reorder in storyboard: the synthetic click after drop no longer closes the storyboard.
44
+ - Click-to-advance no longer fires in edit mode (previously prevented inline editing on the first click of any potential double-click).
45
+ - Storyboard state persists across the file-watcher reload after a drag-drop reorder.
46
+ - 'cut' transition now has a picker-only preview animation (was invisible before).
47
+
48
+ ## 0.1.0 — 2026-05-22
49
+
50
+ Initial release.
51
+
52
+ - Engine, primitives, 6 core components, 4 themes, 5 cookbook examples.
53
+ - Edit mode with slide-level notes, element-pin notes, transition picker, inline text editing.
54
+ - Dev server with WebSocket + AST roundtrip.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Stagecraft
2
2
 
3
- **Cinematic, agent-authored presentations in a single HTML file.**
3
+ **Cinematic, agent-authored presentations. No build step.**
4
4
 
5
5
  ▶ **[Live demo](https://noegel.io/stagecraft/)** — the deck about Stagecraft, built with Stagecraft. Auto-deployed from `main` via GitHub Pages.
6
6
 
7
- A small JavaScript library for building animated slide decks that live in a single HTML file. Designed so an LLM can generate a deck that doesn't look like an LLM generated it.
7
+ A small JavaScript library for animated slide decks. Source is plain JS files loaded by `<script>` tags — no bundler, no framework, opens directly in any browser. Designed so an LLM can generate a deck that doesn't look like an LLM generated it.
8
8
 
9
9
  ## Why
10
10
 
package/package.json CHANGED
@@ -1,12 +1,21 @@
1
1
  {
2
2
  "name": "stagecraft",
3
- "version": "0.1.0",
4
- "description": "Cinematic, agent-authored presentations in a single HTML file.",
3
+ "version": "0.2.1",
4
+ "description": "Cinematic, agent-authored presentations. No build step.",
5
5
  "type": "module",
6
6
  "main": "src/engine.js",
7
7
  "bin": {
8
8
  "stagecraft": "bin/cli.js"
9
9
  },
10
+ "homepage": "https://noegel.io/stagecraft/",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/dnoegel/stagecraft.git"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/dnoegel/stagecraft/issues"
17
+ },
18
+ "author": "Daniel Nögel",
10
19
  "files": [
11
20
  "src",
12
21
  "themes",
@@ -15,7 +24,9 @@
15
24
  "bin",
16
25
  "starter",
17
26
  "AGENT.md",
18
- "README.md"
27
+ "README.md",
28
+ "LICENSE",
29
+ "CHANGELOG.md"
19
30
  ],
20
31
  "scripts": {
21
32
  "serve": "node bin/serve.js",
@@ -25,7 +36,8 @@
25
36
  "build": "node scripts/bundle.js",
26
37
  "test:visual": "node tests/visual/run.js",
27
38
  "test:visual:update": "node tests/visual/run.js --update-baseline",
28
- "export": "node bin/export.js"
39
+ "export": "node bin/export.js",
40
+ "prepublishOnly": "npm run build"
29
41
  },
30
42
  "dependencies": {
31
43
  "@babel/generator": "^7.24.0",
@@ -36,6 +48,17 @@
36
48
  "mime-types": "^2.1.35",
37
49
  "ws": "^8.16.0"
38
50
  },
39
- "keywords": ["slides", "presentation", "reveal", "agent", "llm"],
40
- "license": "MIT"
51
+ "keywords": [
52
+ "slides",
53
+ "presentation",
54
+ "agent",
55
+ "llm",
56
+ "stagecraft",
57
+ "deck",
58
+ "keynote"
59
+ ],
60
+ "license": "MIT",
61
+ "engines": {
62
+ "node": ">=18"
63
+ }
41
64
  }