···22222323__Objective:__ Parse markdown documents into a rich `Slide` struct.
24242525-| Task | Description | Key Crates |
2626-| ---------------------- | --------------------------------------------------------------- | -------------------- |
2727-| __✓ Parser Core__ | Split files on `---` separators. | `pulldown-cmark`[^4] |
2828-| | Detect title blocks, lists, and code fences. | |
2929-| | Represent as `Vec<Slide>`. | |
3030-| __✓ Slide Model__ | Define structs: `Slide`, `Block`, `TextSpan`, `CodeBlock`, etc. | Internal |
3131-| __✓ Metadata Parsing__ | Optional front matter (YAML/TOML) for theme, author, etc. | `serde_yml`[^5] |
3232-| __Error & Validation__ | Provide friendly parser errors with file/line info. | `thiserror`[^6] |
3333-| __✓ Basic CLI UX__ | `slides present file.md` runs full TUI. | `clap` |
3434-| | `slides print` renders to stdout with width constraint. | |
2525+| Task | Description | Key Crates |
2626+| ----------------------- | --------------------------------------------------------------- | -------------------- |
2727+| __✓ Parser Core__ | Split files on `---` separators. | `pulldown-cmark`[^4] |
2828+| | Detect title blocks, lists, and code fences. | |
2929+| | Represent as `Vec<Slide>`. | |
3030+| __✓ Slide Model__ | Define structs: `Slide`, `Block`, `TextSpan`, `CodeBlock`, etc. | Internal |
3131+| __✓ Metadata Parsing__ | Optional front matter (YAML/TOML) for theme, author, etc. | `serde_yml`[^5] |
3232+| __Error & Validation__ | Provide friendly parser errors with file/line info. | `thiserror`[^6] |
3333+| __✓ Basic CLI UX__ | `lantern present file.md` runs full TUI. | `clap` |
3434+| | `lantern print` renders to stdout with width constraint. | |
35353636## Rendering & Navigation
3737···4444| __✓ Status Bar__ | Display slide count, filename, clock, and theme name. | `ratatui` |
4545| __✓ Color Styling__ | Apply consistent color palette via `owo-colors`. Define traits like `ThemeColor`. | `owo-colors` |
4646| __✓ Unicode Headings__ | Use Unicode block symbols (▉▓▒░▌) for h1-h6 instead of markdown `#` syntax. | Unicode constants |
4747-| __Configurable Themes__ | Base16 YAML theme system with 10 prebuilt themes. Add user theme loading from config directory and CLI `--theme-file` flag. | `serde_yml`, `serde`, `dirs` |
4747+| __Configurable Themes__ | Base16 YAML theme system with 10 prebuilt themes. | `serde_yml`, `serde` |
4848+| | Add user theme loading from config directory and CLI `--theme-file` flag. | `dirs` |
48494950---
5051···6061| | Render syntax-highlighted text with color spans mapped to `owo-colors`. | |
6162| __✓ Theming__ | Map terminal theme choice to Syntect theme (e.g., `"OneDark"`, `"Monokai"`). | `syntect` |
6263| __✓ Performance__ | Lazy-load themes and syntaxes; use `OnceLock` for caching. | `std::sync::OnceLock` |
6363-| __✓ Mode__ | Render to ANSI-colored plain text output (for `slides print`). | `owo-colors` |
6464+| __✓ Mode__ | Render to ANSI-colored plain text output (for `lantern print`). | `owo-colors` |
64656566## Presenter
6667···78797980__Objective:__ Add richness and visual polish to text and layout.
80818181-| Task | Description | Key Crates |
8282-| -------------------- | ------------------------------------------------------------ | ----------------------------- |
8383-| __Tables & Lists__ | Render GitHub-style tables, bullets, and task lists. | `pulldown-cmark`, `ratatui` |
8484-| __Admonitions__ | Highlighted boxes with icons | `owo-colors`, internal glyphs |
8585-| __Horizontal Rules__ | Use box-drawing (`─`, `═`) and shading (`░`, `▓`). | Unicode constants |
8686-| __Generators__ | `slides init` scaffolds an example deck with code and notes. | `include_str!`, `fs` |
8282+| Task | Description | Key Crates |
8383+| -------------------- | ------------------------------------------------------------- | ----------------------------- |
8484+| __Tables & Lists__ | Render GitHub-style tables, bullets, and task lists. | `pulldown-cmark`, `ratatui` |
8585+| __Admonitions__ | Highlighted boxes with icons | `owo-colors`, internal glyphs |
8686+| __Horizontal Rules__ | Use box-drawing (`─`, `═`) and shading (`░`, `▓`). | Unicode constants |
8787+| __Generators__ | `lantern init` scaffolds an example deck with code and notes. | `include_str!`, `fs` |
87888889## RC
8990···113114| __Canvas → Pixmap__ | Implement a `FrameRasterizer` that turns a `Frame` + layout into an RGBA pixmap (background, panes, etc). | `tiny-skia` |
114115| __Text Rendering__ | Render slide titles/body text via glyph rasterization and simple layout (left/center, line wrapping). | `ab_glyph` |
115116| __Terminal Snapshot Mode__ | Convert `TerminalBuffer` into a rendered terminal "window" (frame, tabs, padding, cursor). | `tiny-skia`, `ab_glyph` |
116116-| __Slide Screenshot CLI__ | `slides export-image deck.md --slide 5 --output slide-5.png` (PNG by default, optional SVG/WebP). | `clap`, `image` |
117117+| __Slide Screenshot CLI__ | `lantern export-image deck.md --slide 5 --output slide-5.png` (PNG by default, optional SVG/WebP). | `clap`, `image` |
117118| __Batch Export__ | `--all` / `--range 3..7` to dump multiple slides, naming convention like `deck-003.png`. | `image` |
118119| __Deterministic Layout Test__ | Golden tests comparing generated PNGs against fixtures for regression in layout and text. | `image`, integration test harness |
119120···126127| __Timeline Scheduling__ | Extend `Event` to carry timestamps or durations; implement `Scheduler` to emit frames at target FPS. | internal `timeline` module | |
127128| __Frame Capture Loop__ | Drive the same layout/rasterizer used for images at N FPS, yielding a sequence of RGBA frames. | `tiny-skia`, `image` | |
128129| __FFmpeg Binding Layer__ | Wrap `ffmpeg-next` to open an encoder, configure codec/container, and accept raw frames. | `ffmpeg-next` | |
129129-| __Video Export CLI__ | `slides export-video deck.md --output demo.mp4 --fps 30 --duration 120s` (or auto-duration from events). | `clap`, internal encoder | |
130130+| __Video Export CLI__ | `lantern export-video deck.md --output demo.mp4 --fps 30 --duration 120s` (or auto-duration from events). | `clap`, internal encoder | |
130131| __GIF / WebM Variants__ | Add `--format gif | webm` mapping to appropriate ffmpeg muxer/codec presets. | `ffmpeg-next`[^7] |
131132| __Typing & Cursor Effects__ | Represent typing, deletes, cursor blinks as timeline events, so video export matches live presentation feel. | internal `timeline`, terminal core | |
132133| __Audio-less Simplification__ | Keep V1 video export silent (no audio tracks) for simpler ffmpeg integration and smaller binaries. | `ffmpeg-next` | |
···140141| -------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------- |
141142| __Portrait Layout Engine__ | Implement 9:16 aspect ratio layout with vertical constraints (1080x1920, 720x1280). | internal `layout` module |
142143| __Mobile-Optimized Text__ | Larger font sizes, reduced content density, and simplified layouts for mobile readability. | `ab_glyph`, `tiny-skia` |
143143-| __Vertical Export CLI__ | `slides export-vertical deck.md --output reel.mp4` with preset dimensions for each platform. | `clap`, internal encoder |
144144+| __Vertical Export CLI__ | `lantern export-vertical deck.md --output reel.mp4` with preset dimensions for each platform. | `clap`, internal encoder |
144145| __Platform Presets__ | Built-in presets: `instagram-reel`, `tiktok`, `youtube-shorts` with optimal resolution/duration. | internal preset registry |
145146| __Content Adaptation__ | Auto-scale or warn when horizontal content doesn't fit portrait orientation. | internal `layout` module |
146147| __Safe Zones__ | Respect platform UI overlays (captions, profile pics) with configurable safe zones. | internal `layout` module |
···152153153154| Task | Description | Key Crates |
154155| ------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------- |
155155-| __Export Subcommands__ | Add `slides export-image` and `slides export-video` commands with shared flags (theme, range). | `clap` |
156156+| __Export Subcommands__ | Add `lantern export-image` and `lantern export-video` commands with shared flags (theme, range). | `clap` |
156157| __Frontmatter Controls__ | Support per-deck/per-slide frontmatter: `fps`, `default_duration`, `transition`, `record: true`. | `pulldown-cmark-frontmatter` |
157158| __Deterministic Seeds__ | Add `--seed` for any animations (typing jitter, cursor blink timing) to keep exports repeatable. | internal `timeline` |
158159| __Preset Profiles__ | Presets like `social-card`, `doc-screenshot`, `talk-demo` mapping to resolution + theme. | internal profile registry |
+2-4
core/src/theme.rs
···129129130130/// Color theme abstraction for slides with semantic roles for consistent theming across the application.
131131///
132132-/// Stores RGB colors that can be converted to both owo-colors Style (for terminal output)
133133-/// and ratatui Color (for TUI rendering) via Into implementations.
134134-#[derive(Debug, Clone)]
132132+/// Stores RGB colors that can be converted to both owo-colors Style (for terminal output) and ratatui Color (for TUI rendering).
133133+#[derive(Debug, Clone, Copy)]
135134pub struct ThemeColors {
136135 pub heading: Color,
137136 pub heading_bold: bool,
···652651 assert!(theme.link(&"Test").to_string().contains("Test"));
653652 assert!(theme.inline_code_bg(&"Test").to_string().contains("Test"));
654653655655- // UI colors don't need style methods, just verify they exist
656654 let _ = theme.ui_border;
657655 let _ = theme.ui_title;
658656 let _ = theme.ui_text;