Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ jobs:
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run ve:eval
- run: npm run ve:eval-presentation
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
### Tooling
- New `npm test` (node:test) covering the loader, extractors, and diagram layout; wired into CI alongside the expanded `ve:eval`.

### PresentationDeck engine + deck primitives
- **PresentationDeck engine + deck primitives** (`visual-explainer-mdx/presentation.tsx`, re-exported through `components.tsx`): an alternative to `SlideDeck` for presented, interactive decks. Fixed 1920×1080 stage scaled to fit (ResizeObserver + letterbox), collapsible slide rail (auto-collapse, hover expand, dot column), keyboard nav (arrows/Space/PageUp/PageDown/Home/End), 80px edge click zones, and a mono slide counter. Primitives: `PresentationSlide` (tone chrome via the existing `data-ve-tone` → `--ve-slide-*` mapping), `DrillCard`/`DrillChip`/`DrillSheet` (click-to-expand with corner-anchored expansion, Escape/X close, and a click-anywhere-to-close guard that ignores `button, a, input, select, textarea, [data-interactive]`), `LayerExplorer`, `LadderDiagram`/`FanoutDiagram` (grid-paper backdrops with opaque solid-over-grid fills), `PullQuote`, `Metric`/`StatRow`, `HairlineList`, `Stepper`, `CodePanel`, `MonoLabel`/`DisplayText`, `IconChip` + geometric icons, `ShineOverlay`/`trackShine`, and pure helpers `fitStage`/`shouldDismissDrillSheet`/`tint`/`solidTint`. Everything consumes `--ve-*` tokens (new root token: `--ve-deck-letterbox`); prefers-reduced-motion collapses all deck motion.
- **Presentation eval suite** (`evals/run-presentation.mjs`, `npm run ve:eval-presentation`, wired into CI): the engine's behavioral contract — click-anywhere-to-close guard matrix, keyboard-nav matrix, drill CTA contract (click/Enter/Space; primary solid vs secondary outline computed styles), LayerExplorer selection, reduced-motion, scale-to-fit geometry across viewports, letterboxing, rail collapse/expand widths, preset re-skin assertions, and an allowlist-based scan asserting the shipped module contains no color or font literals at all. Runs against the demo (`examples/visual-explainer-mdx/presentation-deck.tsx`) exported through the standard `ve:export` path.
- Unit tests for the pure deck logic (`visual-explainer-mdx/presentation-core.test.mjs`) and an `npm test` script (also runs the existing diagram-layout tests) now executed in CI.
- Docs: `docs/presentation-deck.md` (when to use PresentationDeck vs SlideDeck).

### Changed (presentation)
- Keyboard guard hardened: modifier chords (meta/ctrl/alt) are never intercepted, and focus inside `input`/`textarea`/`select`/`[contenteditable]` now owns every key (arrows, Space, Home/End) instead of only Space/Enter.
- Navigation (edge click zones + nav keys) is gated while a drill sheet is open — an edge click can no longer blow past an open sheet; Escape closes first.
- Light-tone slides flip the CTA ink like accent-tone slides do, fixing primary chips rendering ink-on-ink where `--ve-accent` remaps to the ink color. All three pinned by new falsifiable evals.
- `ve-verify` profile detection: artifacts carrying `data-ve-presentation` (fixed-stage decks that never scroll) classify as `page` instead of tripping the scroll-snap `slides` heuristics via bundled Tailwind utilities.
- Roster-sync guard (`scripts/ve-mdx/check.mjs`) now also collects PascalCase named re-exports from `components.tsx`.

## [0.7.0] - 2026-07-04

### Changed
Expand Down
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ objects with `id`, `family`, `severity`, `spec`, etc.). To add one:
3. Add it to the component list in `plugins/visual-explainer/SKILL.md`.
4. Run `npm run ve:check` to confirm export integrity holds.

## Presentation deck changes

The PresentationDeck engine (`visual-explainer-mdx/presentation.tsx` +
`presentation-core.ts`) is contract-pinned by two suites; run both after any
change there:

- `npm test` — unit tests for the pure logic (scale-to-fit math, the
click-anywhere-to-close guard, tint helpers).
- `npm run ve:eval-presentation` — the behavioral eval suite
(`evals/run-presentation.mjs`, a documented sibling of `evals/run.mjs`):
exports `examples/visual-explainer-mdx/presentation-deck.tsx` through the
standard `ve:export` path and replays the interaction, geometry, and
token-consumption contracts headlessly with Playwright. New engine behavior
should land with a new eval here (and verify it can fail by breaking the
behavior locally before trusting it).

## Adding a preset

Presets are semantic-token layers in `visual-explainer-mdx/global.css`,
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Video formats (9:16 reel, 16:9 long-form) render to MP4 through Hyperframes; sam
- **ve-verify** (`scripts/verify/`): a 200+ check deterministic design-quality gate — static scans, real-browser measurement (390px overflow, WCAG contrast in both themes, Mermaid render), and small blind LLM rubric passes. Exit codes and JSON reports make it usable as a CI gate. Its own eval suite of seeded-violation fixtures proves each check fires.
- **Tiered agent docs**: SKILL.md is a ~2.5k-token bootstrap plus one ~300-token card per use case (`cards/`). A covered flow reads about 3,100 tokens instead of 62,000. Deep references load only on escalation.
- **17 shared components** (`visual-explainer-mdx/components.tsx`): DiagramCanvas with computed layout and CSS-only mobile linearization, build-time Shiki CodeBlock, DiffBlock, TerminalBlock, JsonTree, an interactive Quiz, MermaidBlock with zoom/pan chrome, decks, posters, and more. Strict-export integrity checks catch bad edge ids and undefined components at build time.
- **PresentationDeck** (`visual-explainer-mdx/presentation.tsx`): a second deck engine for presented (not scrolled) decks — a fixed 1920×1080 stage scaled to fit any screen, collapsible slide rail, keyboard nav, and drill-down primitives (click-to-expand cards/sheets with a click-anywhere-to-close guard, ladder/fanout diagrams, metrics, steppers). Fully `--ve-*` token-driven so every preset skins it; its behavioral contract is pinned by a headless eval suite (`npm run ve:eval-presentation`). See [docs/presentation-deck.md](docs/presentation-deck.md) for when to use it vs `SlideDeck`.
- **`/explain-diff`**: a literate diff mode (background → intuition → walkthrough → quiz), adapted from Geoffrey Litt's prompt pattern.
- **Model-matrix eval harness** (`evals/model-matrix/`): the same briefs across Kimi, GLM, DeepSeek, Claude, and Codex, scored on deterministic compliance plus a blind screenshot judge. Point it at your own model in about ten minutes.
- **One-command team sharing**: `share.sh` deploys to Vercel (zero setup, public) or sharehtml on Cloudflare (stable update-in-place URLs, team SSO via Cloudflare Access, comments). See `docs/TEAM-SHARING.md`.
Expand Down Expand Up @@ -112,6 +113,7 @@ For private team sharing setup, see [`docs/TEAM-SHARING.md`](docs/TEAM-SHARING.m

- [Features](docs/features.md): the full capability reference, including all output modes, aesthetics, and how generation works.
- [Design systems](docs/design-systems.md): the external design-system registry format, resolution order, `ve:learn` token learning, and the agent-assisted refinement flow.
- [PresentationDeck vs SlideDeck](docs/presentation-deck.md): which deck engine to reach for, the drill-down primitives, and the eval-pinned behavioral contract.
- [Team sharing](docs/TEAM-SHARING.md): one-command deploys to Vercel or a team-gated Cloudflare space.
- [Skill docs](plugins/visual-explainer/SKILL.md): what an agent actually reads, plus the per-use-case [cards](plugins/visual-explainer/cards/).
- [Verifier](plugins/visual-explainer/scripts/verify/): the deterministic design-quality gate and its [eval suite](evals/).
Expand Down
Binary file added docs/img/examples/presentation-deck.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions docs/presentation-deck.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# PresentationDeck vs SlideDeck

Artifacture ships two deck engines. They solve different problems; neither
replaces the other.

| | `SlideDeck` / `Slide` | `PresentationDeck` / `PresentationSlide` |
|-|-|-|
| Mental model | A scrolling document of slide-sized sections | A fixed 1920×1080 stage a presenter drives |
| Layout | Responsive; content reflows per viewport | Designed once at stage size; scaled to fit, letterboxed |
| Navigation | Scroll / scroll-snap (vertical or horizontal) | Keyboard (arrows, Space, PageUp/Down, Home/End), edge click zones, slide rail |
| Interactivity | Static content, optional review tools | Drill-down cards and sheets, layer explorers, progressive disclosure |
| Reading mode | Self-serve: send the link, reader scrolls | Presented: one slide at a time, details on demand |
| Verifier profile | `slides` (scroll-snap contract) | `page` (fixed stage never scrolls) |
| Best for | Handouts, recaps, docs-as-slides, PDF-ish exports | Exec/architecture walkthroughs, demos, talks with Q&A drill-downs |

## When to use which

Use **SlideDeck** when the artifact is read without you in the room. It
behaves like a document: responsive, printable, scannable top to bottom.

Use **PresentationDeck** when a human presents the artifact. The fixed stage
guarantees your layout survives any projector or window size (the engine
scales `min(w/1920, h/1080)` and letterboxes the rest), and the drill-down
primitives let you keep slides sparse while holding detail one click away —
the deck is the appendix.

Both are exported the same way (`npm run ve:export -- <src> --out <out>`)
and both consume the `--ve-*` preset tokens, so the same preset skins either.

## PresentationDeck quick start

```tsx
import { PresentationDeck, PresentationSlide, DrillCard, StatRow } from 'visual-explainer-mdx/components';

export default function Deck() {
return (
<PresentationDeck title="Q3 Architecture" eyebrow="Platform review" preset="paper-ink">
<PresentationSlide kicker="01 · Context" title="Where we are" shortTitle="Context" tone="dark">
<StatRow stats={[{ value: '3', label: 'Services' }, { value: '2', label: 'Regions' }]} />
</PresentationSlide>
<PresentationSlide kicker="02 · Plan" title="Where we go" shortTitle="Plan" tone="accent">
<DrillCard drillId="detail" title="The migration" body="Click for the full sequence.">
Detail content shown in an expanding sheet.
</DrillCard>
</PresentationSlide>
</PresentationDeck>
);
}
```

Notes:

- **Slide metadata comes from the deck's direct children.** The rail and
tone-matched chrome read `shortTitle`/`tone` off each child element. If you
wrap `PresentationSlide` in your own component (e.g. to hold drill state),
pass `shortTitle` and `tone` at the usage site and forward them.
- **Tones** reuse `Slide`'s contract: `dark` (the preset's base surface),
`light` (`--ve-bg-alt`, opposite polarity), `accent` (`--ve-accent` surface;
CTAs automatically flip to the tone's ink color).
- **Stage size** defaults to 1920×1080; override with
`stageWidth`/`stageHeight`. All font sizes inside slides are stage-space
pixels — the scale transform handles the rest.

## Primitives

- **Drill-downs** — `DrillCard` (click-to-expand card), `DrillChip`
(CTA trigger: `variant="primary"` solid fill / `"secondary"` outline),
`DrillSheet` (the expanding surface: closes on Escape, the X, or any click
that isn't on `button, a, input, select, textarea, [data-interactive]`,
with `transform-origin` controlled by `origin` for corner-anchored
expansion), `LayerExplorer` (card list + detail panel).
- **Diagrams** — `LadderDiagram` (ascending staircase on grid paper; card
fills are always opaque so grid lines never bleed through),
`FanoutDiagram` (one source, N outputs).
- **Composition** — `StatRow`/`Metric`, `PullQuote`, `Stepper`,
`HairlineList`, `CodePanel`, `MonoLabel`, `DisplayText`, `IconChip` + the
geometric icon set, `ShineOverlay`/`trackShine` (pointer-follow shine).
- **Helpers** — `fitStage` (scale-to-fit math), `shouldDismissDrillSheet`
(the dismiss guard), `tint`/`solidTint` (hex tinting; for token-driven
fills use the `.ve-pres-solid` opaque-layer idiom instead).

## Behavioral contract (evals)

The engine's behavior is pinned by `evals/run-presentation.mjs`
(`npm run ve:eval-presentation`, runs in CI): the click-anywhere-to-close
guard matrix, keyboard-nav matrix, drill CTA contract (click + Enter + Space;
primary vs secondary computed styles), reduced-motion, scale-to-fit geometry
across viewports, rail collapse/expand widths, and preset re-skinning with a
an allowlist-based scan proving the module ships zero color/font literals. Unit tests for the pure logic live in
`visual-explainer-mdx/presentation-core.test.mjs` (`npm test`). Change the
engine, run both.
Loading
Loading