brand-lock-extractor
Extract a production-ready brand-lock.md from a brand's existing assets. Point it at a website URL, a brand book PDF, screenshots, or a written description and…
Render a structured storyboard (storyboard.md, shots.json, text-overlays.json, brand-lock.snapshot.md) into a single-file HTML preview that is shareable, printable, and offline. Use when the user wants to share a storyboard, export for review, hand off to an editor, or print a
$ npx -y skills add whystrohm/shotkit --skill storyboard-html-preview --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/storyboard-html-previewContext preview
The summary Claude sees to decide when to auto-load this skill.
Render a structured storyboard (storyboard.md, shots.json, text-overlays.json, brand-lock.snapshot.md) into a single-file HTML preview that is shareable, printable, and offline. Use when the user wants to share a storyboard, export for review, hand off to an editor, or print a
name: storyboard-html-preview description: Render a structured storyboard (storyboard.md, shots.json, text-overlays.json, brand-lock.snapshot.md) into a single-file HTML preview that is shareable, printable, and offline. Use when the user wants to share a storyboard, export for review, hand off to an editor, or print a hard copy. Triggers on "preview the storyboard", "share this", "export to HTML", "print version", or after a storyboard-architect run. Produces one self-contained .html file with no build or server.
You are turning structured storyboard files into a single shareable HTML document. The output is what an editor, stakeholder, or client opens in a browser without thinking about it.
The constraint is non-negotiable: **single file, no build step, no server, works offline.** Any time the output requires "run this build command" or "host this somewhere," the skill has failed.
Trigger when the user:
One file: `preview.html`. Self-contained. Inline CSS. No JavaScript dependencies (vanilla JS only, embedded). No external font files (uses system stack with brand-font fallbacks). No external images (placeholder slots; if generated images exist, embed as base64 OR reference relative paths).
output/ ├── run.json # input, for the run id and date ├── storyboard.md # input ├── shots.json # input ├── text-overlays.json # input ├── brand-lock.snapshot.md # input ├── frames/round-N/ # input, if generation has happened ├── critiques/round-N/ # input, for the verdict badges └── preview.html # ← what this skill produces
If the user has generated frames, the HTML references them via relative paths so the file works when the whole `output/` folder is shared. Resolve a shot's frame in this order:
1. An entry in `shot.assets.generated` marked `accepted: true` 2. The newest entry in `shot.assets.generated` 3. `frames/round-{highest}/{shot_id}.{png,jpg,jpeg,webp}` 4. `generated/{shot_id}.{ext}`, the pre-3.0.0 flat layout
Data first, convention second. Reading the path convention first meant the page showed whatever file happened to sit there, accepted or rejected, first draft or fifth re-roll.
If no frames exist yet, the HTML uses styled placeholder cards with the shot spec, still useful for review and handoff.
Required:
Optional:
Validate before rendering, and stop if it fails:
python tools/validate_shots.py output/
From `brand-lock.snapshot.md`, extract:
The HTML preview should *feel* like the brand without going overboard. Quiet branding, not loud.
Use `templates/preview.html.tpl` as the structural template. Read it before generating.
The HTML structure:
<!DOCTYPE html>
<html>
<head>
<meta>
<title>{project title}</title>
<style>
/* All CSS inline. ~200 lines. Brand-aware. */
/* Print stylesheet included. */
</style>
</head>
<body>
<header>
<!-- Project title, duration, aspect, generated timestamp -->
</header>
<section class="brief">
<!-- Brief summary if storyboard.md provides one -->
</section>
<section class="series-lock">
<!-- Character / environment / lighting / color grade -->
</section>
<section class="shots">
<!-- One card per shot -->
<article class="shot" id="shot_01">
<div class="shot-frame">
<!-- generated image OR styled placeholder -->
</div>
<div class="shot-meta">
<!-- timestamp, framing, angle, motion -->
</div>
<div class="shot-subject">
<!-- subject description -->
</div>
<div class="shot-text-overlay">
<!-- if on_screen_text exists, show overlay content with timing -->
</div>
<div class="shot-rationale">
<!-- rationale text -->
</div>
</article>
<!-- ... -->
</section>
<footer>
<!-- audit trail: brand-lock snapshot reference, timestamp -->
</footer>
<script>
/* Vanilla JS only. Optional: keyboard nav, jump-to-shot, expand/collapse. */
</script>
</body>
</html>Resolve each shot's frame by the order in "What you produce" above, then reference it by a path relative to the output root:
<img src="frames/round-2/shot_01.png" alt="shot_01: hook" loading="lazy" />
This works when the whole output folder is zipped and shared.
For hard-copy print (a single file with no folder structure), the skill can offer to inline frames as base64. Ask the user which they prefer if frames are present.
If a shot's `assets.generated` entry carries a `sha256` and the file no longer matches it, render the frame but say so on the page. That mismatch means the frame changed after it was recorded, which is exactly the case where a preview quietly showing the new file is worse than one that flags it.
If no frames exist, render styled placeholder cards showing the framing, subject, and shot spec. These are still useful for stakeholder review at the storyboard stage.
**Template flag convention.** When composin
The pre-production system we use to ship hundreds of videos a month. Open-sourced.
Extract a production-ready brand-lock.md from a brand's existing assets. Point it at a website URL, a brand book PDF, screenshots, or a written description and…
Turn a creative brief into a production-grade storyboard with shot specs, timing, on-screen text, and per-shot rationale. Use when the user describes a video…
Critique a generated image against its source storyboard shot and prompt, producing revision notes. Use when the user has generated an image and wants feedback…
Generate model-specific prompts from shots.json. Outputs copy-paste-ready prompts for stills (Midjourney, Flux, Ideogram, GPT Image, Nano Banana, Seedream) and…