chore(skill): drop visual-vocabulary.md + use published npx hyperframes

- Delete `references/visual-vocabulary.md` and scrub the four call
  sites that referenced it. The 6-axis lookup framing it introduced
  contradicted the rest of the skill's "design from the brand, not
  from a table" stance.
- Replace all `npx tsx packages/cli/src/cli.ts <cmd>` invocations
  with `npx hyperframes <cmd>` in step-0-capture.md, step-5-build.md,
  step-6-validate.md, and beat-builder-guide.md. The capture- and
  snapshot-pipeline improvements that previously required the local
  CLI now ship in the published CLI via the stack's PRs #987 and
  #988, so once the stack lands the published CLI is the right
  invocation for the skill prose.
- Remove the now-contradictory "ALWAYS use the local CLI — never
  npx hyperframes" warnings in step-0-capture.md and step-6-validate.md.
This commit is contained in:
ukimsanov
2026-05-21 11:08:51 -07:00
parent a1ffb6e7bf
commit 051c9c9de4
8 changed files with 16 additions and 181 deletions
+1 -2
View File
@@ -95,7 +95,7 @@ Write DESIGN.md — a brand cheat sheet covering the visual identity: colors, ty
## Step 2: Strategy & Messaging
**Read:** [references/step-2-brief.md](references/step-2-brief.md), [references/visual-vocabulary.md](references/visual-vocabulary.md), [references/capabilities.md](references/capabilities.md) (scan the Table of Contents — deep-dive sections only as needed)
**Read:** [references/step-2-brief.md](references/step-2-brief.md), [references/capabilities.md](references/capabilities.md) (scan the Table of Contents — deep-dive sections only as needed)
Align with the user on **what the video must communicate** before talking visuals or assets. Parse the user's prompt — they probably already gave you the video type and style. Ask only what's missing: the ONE thing this video must say, the narrative arc, and the audience.
@@ -184,7 +184,6 @@ Beat count is not in this table intentionally — it should come from the storyb
| [step-1-design.md](references/step-1-design.md) | Step 1 — write DESIGN.md brand cheat sheet (6 sections, 250-350 lines) |
| [step-2-brief.md](references/step-2-brief.md) | Step 2 — align on message, narrative arc, audience with user |
| [capabilities.md](references/capabilities.md) | Steps 2 & 5 — full inventory of what HyperFrames can do (24 sections). Scan the TOC during the brief, deep-dive specific sections during build |
| [visual-vocabulary.md](references/visual-vocabulary.md) | Step 2 & 3 — translate subjective terms to concrete techniques. Composable building blocks, not rigid presets |
| [step-3-storyboard.md](references/step-3-storyboard.md) | Step 3 — storyboard + script (combined) with user review gate |
| [step-4-vo.md](references/step-4-vo.md) | Step 4 — TTS provider choice, generation, timing |
| [step-5-build.md](references/step-5-build.md) | Step 5 — build index.html + compositions |
@@ -95,7 +95,7 @@ Fix ALL errors. Zero errors required.
## Step 4: Snapshot and verify
```bash
npx tsx packages/cli/src/cli.ts snapshot . --frames 3
npx hyperframes snapshot . --frames 3
```
**READ the contact sheet** (`snapshots/contact-sheet.jpg`). For each frame:
@@ -13,11 +13,10 @@ If the user provides the key or already has one set, proceed. If they skip it, p
Create a project directory for your video if it doesn't exist yet, then capture the website into a `capture/` subfolder within it:
```bash
# ⚠ ALWAYS use the local CLI — never `npx hyperframes capture`:
npx tsx packages/cli/src/cli.ts capture <URL> -o <project-dir>/capture
npx hyperframes capture <URL> -o <project-dir>/capture
```
Example: `npx tsx packages/cli/src/cli.ts capture https://stripe.com -o videos/stripe-launch/capture`
Example: `npx hyperframes capture https://stripe.com -o videos/stripe-launch/capture`
Keeping the capture artifacts (`screenshots/`, `assets/`, `extracted/`, `AGENTS.md`, `CLAUDE.md`) in a dedicated `capture/` subfolder keeps them isolated from the later build files (`SCRIPT.md`, `STORYBOARD.md`, `DESIGN.md`, `compositions/`, `index.html`, `narration.wav`, `transcript.json`, `renders/`, `snapshots/`), which all live at `<project-dir>/` root.
@@ -35,7 +35,7 @@ Ask the user to describe what they want — or react to concrete framings that d
Do NOT present a labeled menu of styles with pre-filled descriptions ("Cinematic = dark + glow + Apple keynote energy"). Those descriptions become the brief even when they don't match the brand. "Cinematic" for a wellness brand should look completely different from "cinematic" for a security tool — but a label with a baked-in description collapses that distinction.
Instead, ask them across the six axes from [visual-vocabulary.md](visual-vocabulary.md) — framed as approachable questions, not a form:
Instead, ask them approachable open-ended questions:
> "A few questions to get the direction right:
>
@@ -44,7 +44,7 @@ Instead, ask them across the six axes from [visual-vocabulary.md](visual-vocabul
> - **Narration:** Should a voice guide viewers through the video, or let the visuals carry it?
> - **Anything specific?** Any moments, techniques, or references you're drawn to? Or say 'surprise me' and I'll work from what I found in the capture."
Their answers modify the brand-derived baseline you built in Step 1. Don't override the brand with their words — let the brand and their direction converge. See [visual-vocabulary.md](visual-vocabulary.md) for how to handle conflicts.
Their answers modify the brand-derived baseline you built in Step 1. When the user's words conflict with the brand, don't blindly override — let the brand and their direction converge. If the conflict is sharp (user says "dark cinematic" for a brand whose entire identity is white-and-pastel light), surface it and ask before resolving.
### Question 3: What's the ONE thing this video must communicate?
@@ -118,7 +118,7 @@ With that minimum in hand, still write an ambitious storyboard. "Surprise me" me
### Specific direction
Map their words to visual-vocabulary.md dimensions. If they say something vague ("make it really cool"), push back gently:
If they say something vague ("make it really cool"), push back gently:
> "I want to make sure I nail what you're imagining. When you say 'cool' — do you mean: dramatic/cinematic(slow reveals and dark atmosphere)? Or high-energy (fast cuts and bold motion)? Or something else entirely?"
@@ -157,7 +157,7 @@ Lock all of these before moving to Step 3. The first three are the strategic fra
3. **Audience** — who's watching, where they're watching. (Required.)
4. **Video type** — social ad / product demo / launch teaser / brand reel / feature announcement / etc. Infer from prompt.
5. **Duration** — infer from type if not stated (demo: 30-45s, social: 15-20s, teaser: 15-25s).
6. **Style direction**map their words to visual-vocabulary dimensions.
6. **Style direction**pace / mood / specifics — from the user's words, layered onto the brand baseline from Step 1.
7. **Specific requests** — any scenes/effects/beats they explicitly asked for.
8. **Narration** — yes / no / minimal.
9. **Format** — landscape unless specified otherwise.
@@ -61,8 +61,7 @@ Beat 3: composed kanban (4 cards-as-divs per column) + counter chip on In-Progre
**Re-read these files before writing:**
- **DESIGN.md** — your color palette, font rules, components, Do's/Don'ts. Every visual must be grounded in this brand identity. If it says "white backgrounds with purple accent" — plan light scenes, not dark moody ones.
- **[visual-vocabulary.md](visual-vocabulary.md)** — translate the user's style direction into concrete dimension values (pacing, density, transitions, mood, motion, audio). Note any per-beat overrides the user requested.
- **Asset discovery — use the contact sheets.** View `capture/assets/contact-sheet-*.jpg` and `capture/assets/svgs/contact-sheet-*.jpg`. Each grid cell is labeled with the filename. This is how you browse what's available without opening 50 individual files. When you find an asset that earns its place as a brand accent, note the filename from the label and reference it as `capture/assets/<filename>`. If an asset looks promising but you need to check resolution or detail, THEN open the individual file. Also read `capture/extracted/asset-descriptions.md` for one-line summaries. **Understand what each asset IS before using it.** Product screenshots show what the product does — useful for understanding the brand, but **compose the UI from divs/CSS in your beats rather than pasting the screenshot** (see Per-Beat Direction below). The strongest captured assets for video accents are usually the brand logo (SVG), the hero illustration, and gradient/texture backgrounds. **Never use contact sheets or scroll screenshots in the video** — contact sheets have grid labels and headers baked in, scroll screenshots are raw browser captures. Both are for AI to BROWSE and understand the site, not to place in compositions.
- **Asset discovery — use the contact sheets.** View `capture/assets/contact-sheet-*.jpg` and `capture/assets/svgs/contact-sheet-*.jpg`. Each grid cell is labeled with the filename. This is how you browse what's available without opening 50 individual files. When you find an asset that earns its place in a beat, note the filename from the label and reference it as `capture/assets/<filename>`. If an asset looks promising but you need to check resolution or detail, THEN open the individual file. Also read `capture/extracted/asset-descriptions.md` for one-line summaries. **Never use contact sheets or scroll screenshots in the video** — contact sheets have grid labels and headers baked in, scroll screenshots are raw browser captures. Both are for AI to BROWSE and understand the site, not to place in compositions.
- **[techniques.md](../../hyperframes/references/techniques.md)** — 20 visual techniques with code patterns. Pick for beats, these are starting points to adapt, not templates to copy.
- **[text-effects.md](../../hyperframes/references/text-effects.md)** — 24 named text animation effects bundled in the repo. Read the catalog now and assign a specific effect ID to every headline, label, and copy element in every beat — not generic "fades in" descriptions.
@@ -302,7 +302,7 @@ FIRST: Read skills/website-to-hyperframes/references/beat-builder-guide.md end t
It has your full workflow, all rules, easing vocabulary, and file references.
Follow its workflow exactly:
build → lint (`npx hyperframes lint .`)
→ snapshot (`npx tsx packages/cli/src/cli.ts snapshot . --frames 3`)
→ snapshot (`npx hyperframes snapshot . --frames 3`)
→ view contact sheet AND read snapshots/descriptions.md
→ fix issues
@@ -70,17 +70,15 @@ After lint and validate pass, capture snapshot frames to SEE your own output. **
Scale snapshot count to the video — not a fixed number. Formula: `max(beats × 3, ceil(duration_seconds / 2))`. A 3-beat 10s video: max(9, 5) = 9 frames. An 8-beat 60s video: max(24, 30) = 30 frames. Aim for at least 3 frames per beat: entrance, hold, and near-exit.
**⚠ NEVER use `npx hyperframes snapshot`.** The published CLI (0.6.6) is missing critical fixes: sub-comps load before capturing, local-time seek for last beats, Gemini vision descriptions. Always use the local CLI below or all beats after the first may appear black and descriptions.md won't be generated.
```bash
# The local CLI auto-loads .env from the current working directory, so a
# .env file in <project-dir> with GEMINI_API_KEY=... is enough — no explicit
# export needed. If you've set GEMINI_API_KEY directly in your shell env that
# also works.
npx tsx packages/cli/src/cli.ts snapshot <project-dir> --frames <N>
# The CLI auto-loads .env from the current working directory, so a
# .env file in <project-dir> with GEMINI_API_KEY=... is enough — no
# explicit `export` needed. If you've set GEMINI_API_KEY in your shell
# environment, that works too.
npx hyperframes snapshot <project-dir> --frames <N>
# Pass a custom question to Gemini instead of the default prompt:
npx tsx packages/cli/src/cli.ts snapshot <project-dir> --frames <N> \
npx hyperframes snapshot <project-dir> --frames <N> \
--describe "Is the brand logo visible in every beat? Is any beat showing a black or blank frame?"
```
@@ -1,160 +0,0 @@
# Visual Vocabulary
A vocabulary for talking about how a video looks and moves, organized along six independent axes. **The agent's job is to derive a value for each axis from the brand,** then treat the user's words as _modifiers_ on that brand-derived baseline.
The older version of this file had a "user says X → fill these 6 dimensions" lookup table. That table is gone. The failure mode it produced — "energetic wellness app" and "energetic fintech tool" rendering with the same 6-dimension recipe because both triggered the same user-word match — was the whole problem this skill is trying to solve.
The new flow:
1. **Read DESIGN.md and the captured site.** What cues does this brand give for each of the six axes? Each axis below lists what brand evidence suggests each value.
2. **Derive a baseline.** Write down what this _specific brand_ suggests for each axis, in one phrase per axis. This is the brand-native interpretation.
3. **Apply user modifiers.** If the user said "cinematic" or "fast" or "playful," treat that as a push on the baseline — not a replacement. "Cinematic" pushes toward slow pacing and dramatic transitions on top of what the brand already suggested; it doesn't override the brand.
4. **Resolve conflicts toward the brand.** If the user's word and the brand's evidence disagree strongly, raise it. Don't silently flatten the brand to fit the word.
---
## The Six Axes
Each axis below has values, and for each value, **brand cues that suggest it**. Read brand evidence first; the values are what you derive, not what you start with.
### 1. Pacing — how fast things move and change
| Value | Animation durations | Brand cues that suggest this value |
| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Slow** | 1.53s per move | Hero text dominates the homepage at large scale, copy uses long sentences and full paragraphs, whitespace is generous in the captured layout, serif or thin-weight sans typography, scroll animations on the site are fade-based and unhurried, brand language is mature ("decades of," "the standard for," "founded in") |
| **Moderate** | 0.81.5s per move | Standard product-marketing layout — hero plus three columns plus testimonials, sans-serif body type, content is sectioned but not dense, copy is professional but not formal, scroll animations exist but aren't dramatic |
| **Fast** | 0.30.6s per move | Dense feature grids, multi-column comparison tables, video/gif assets autoplay in the hero, second-person urgent copy ("crush your goals," "ship faster"), social-media-first iconography, brand voice is energetic or consumer-facing |
| **Arc (varies)** | Slow→build→peak→resolve | The site itself has narrative pacing — a long-scroll story, sequential reveals, a "this is the problem / here's the solution / here's the proof" structure. Most launch and announcement videos benefit from arc pacing regardless of brand. |
### 2. Density — how much shares the frame
| Value | Focus | Brand cues that suggest this value |
| ------------ | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Sparse** | One element dominates, generous breathing room | Homepage is hero-then-scroll with one element per viewport, design uses architectural negative space, type carries the work without supporting imagery, brand is confident/restrained (luxury, mature B2B, art) |
| **Balanced** | Primary plus 23 supporting | Standard marketing layout — hero with one secondary image, feature sections with icon + headline + body, professional but not minimal |
| **Rich** | Multiple elements share attention | Dashboard or product-tour-heavy site, feature comparison grids, sites with charts/data visualizations as primary content, sites with dense pricing tables, consumer apps showing many screenshots simultaneously |
### 3. Transitions — how scenes change
| Value | What happens | Brand cues that suggest this value |
| ------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Dramatic** | GPU shader effects, ~0.50.8s | Brand has high-stakes positioning (security, finance, dramatic reveals), homepage already uses dramatic transitions or shader effects, brand language uses words like "introducing," "finally," "the future of," brand has theatrical confidence |
| **Smooth** | CSS-based fades, slides, blurs, ~0.30.6s | Most brands. The professional default. Brand reads as competent and current without theatrical aspiration. |
| **Energetic** | Whip pans, fast zooms, ~0.20.4s | Consumer apps, social-first brands, brands targeting younger demographics, gaming, fast-moving consumer goods, brand voice uses imperatives and exclamation |
| **Hard cut** | Instant switches | Editorial brands, news, brands with confident type-driven identity, anything where rhythm/cadence is the design feature |
**A note on dramatic transitions:** Even when the brand suggests dramatic, the storyboard should not use shader transitions on every scene change. One to two shader moments in a video is the ceiling. Beyond that the effects flatten each other.
### 4. Mood — visual atmosphere
| Value | Characteristics | Brand cues that suggest this value |
| --------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Dark** | Deep backgrounds, glow accents, light from darkness | Captured site uses dark theme as default, primary background is near-black or deep neutral, single saturated accent against the dark, brand operates in technical/dramatic/luxury space |
| **Light** | Bright backgrounds, brand colors as accents | Captured site is white-or-near-white background, structure comes from borders and shadows not from color, brand is consumer-facing, friendly, or corporate-clean |
| **Vibrant** | Multiple saturated colors, gradient backgrounds | Brand uses multiple primary colors (not one accent), captured site uses gradient or aurora effects, brand voice is celebratory or energetic, consumer or creative product |
| **Atmospheric** | Dark base with gradient depth, color temperature shifts | Captured site uses dark base + colored gradients, brand has cinematic positioning, AI/computational brands often land here |
**Critical:** This axis comes more from the brand than any other. A dark-themed site gets dark mood; a white corporate site gets light mood. Don't override mood from a user word — if the user wants "cinematic" for a bright consumer brand, light-cinematic is a real thing (think Apple keynotes pre-2018) and you should reach for it rather than flipping the brand dark.
### 5. Motion language — how elements move
| Value | Easing flavor | Brand cues that suggest this value |
| -------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Cinematic** | Slow drifts, parallax, Ken Burns | Brand has theatrical or premium positioning, captured site uses parallax or scroll-driven storytelling, brand pace is unhurried |
| **Dynamic** | Bounce, overshoot, elastic | Consumer-facing brand, playful or energetic voice, captured site has bouncy micro-interactions, brand targets younger or general-consumer audience |
| **Elegant** | Smooth precise reveals without overshoot | Editorial or premium brand with restraint, captured site has clean fades and considered transitions, brand voice is confident without being theatrical |
| **Restrained** | Controlled, grid-aligned, no overshoot | Technical product, dev tool, data-focused, captured site is minimal-decoration / function-first, brand voice is direct and unornamented |
### 6. Audio — how sound supports the visual
This axis has the least brand evidence to draw from (captured sites don't have soundtracks), so it leans more on user direction and video type. But there are still brand cues:
| Value | Voice / music / SFX character | Brand cues that suggest this value |
| ------------ | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| **Ambient** | Calm voice, sustained pads, sparse SFX | Brand voice in copy is measured and unhurried, brand operates in considered/premium space |
| **Punchy** | Confident upbeat voice, rhythmic music, impact SFX | Consumer brand, energetic voice in copy, urgency language, social-first |
| **Minimal** | Silence and texture, voice carries everything, almost no SFX | Editorial brand, restraint-heavy identity, brand whose homepage uses no decorative motion |
| **Dramatic** | Slow voice with pauses, tension pads, deliberate silence | High-stakes brand positioning, theatrical voice in copy ("we believe," "the future demands") |
---
## How user words modify the baseline
After deriving a baseline from the brand, **read what the user actually said** and apply it as a modifier. Some user words map cleanly to single-axis pushes; some are vibe words that touch several axes; some only modify one part of the video.
The user word is a _direction of push_, not a replacement for the brand-derived value.
### Common user words and what they push
These are pushes, not recipes. They modify whatever baseline you derived from the brand — they don't replace it.
- **"Cinematic"** — pushes pacing slower (or toward arc), transitions toward dramatic for hero moments only, motion toward cinematic. Does _not_ automatically push mood toward dark — a cinematic light video is real (premium hotels, fashion, architecture).
- **"High-energy"** — pushes pacing faster, transitions toward energetic, motion toward dynamic, audio toward punchy. Does _not_ automatically push mood toward vibrant — a dark high-energy video is real (action movies, gaming launches).
- **"Minimal" / "clean"** — pushes density toward sparse, transitions toward smooth, motion toward elegant or restrained. Does _not_ automatically push mood toward light — minimal-dark is a major aesthetic (Bang & Olufsen, Aesop, most luxury).
- **"Professional"** — usually means "don't do anything weird." Mostly a no-op push that confirms the baseline; sometimes pulls dynamic or punchy axes slightly toward elegant or ambient.
- **"Playful" / "fun"** — pushes motion toward dynamic, transitions toward energetic, audio toward punchy. Does _not_ automatically push pacing to fast — playful-slow is a real thing (children's books, charm-forward brands).
- **"Premium" / "luxury"** — pushes pacing slower, density sparser, motion toward cinematic or elegant. Does _not_ automatically push mood toward dark — premium-light is the dominant aesthetic of most actual luxury brands today.
- **"Technical" / "developer"** — pushes motion toward restrained, density toward balanced or rich, audio toward minimal. Mood follows the brand — most dev tools are dark but not all.
Notice that every entry above includes what the word _doesn't_ do. That's deliberate — the previous file mapped each word onto all six axes simultaneously, which is what produced the homogeneity.
### When the user word and the brand conflict
If the user says "cinematic" and the brand is a brightly-colored playful consumer app, you have a conflict. Three options:
1. **Trust the brand and the word together.** Cinematic-playful is a real aesthetic (think Wes Anderson) — slow pacing, sparse density, but vibrant mood and elegant-with-personality motion. Borrow the dimensions that _can_ coexist; don't flatten one for the other.
2. **Ask.** "You said cinematic — I want to check, because your brand is bright and playful. Are you imagining slow dramatic reveals (which would mean leaning away from your brand's energy) or something more like Wes Anderson's pacing applied to your existing palette?"
3. **Default to brand if you can't ask.** When a video has to ship and the user isn't available, the brand-derived baseline is the safer choice — the user can always say "make it more cinematic" on review, but a video that contradicts the brand is harder to come back from.
---
## Lazy Defaults to Question
When you find yourself reaching for any of these as automatic responses, pause and ask whether it's coming from the brand or from a pattern-match:
- "Cinematic" → automatic dark mood + slow pace + dramatic transitions, regardless of what the brand actually looks like
- "Technical" → automatic dark mode + terminal font + restrained motion, regardless of what the dev tool's actual brand is
- "Premium" → automatic slow + sparse + dark, regardless of whether the brand is actually a light-premium or vibrant-premium aesthetic
- "Launch" → automatic dramatic transitions on every scene because "this is a big announcement"
- "Social ad" → automatic fast pacing + punchy audio + hard cuts, even when the brand's social presence is actually slow and editorial
If you catch yourself doing one of these, the fix is to go back to the brand evidence and re-derive. The user word should modify what the brand suggests — not replace it.
---
## Per-beat overrides
The baseline you derive applies to the whole video by default. The storyboard can override a single axis on a single beat — "this beat is faster" or "the transition into beat 4 is dramatic." These overrides should appear in the storyboard's notes, with a one-sentence reason rooted in this beat's purpose, not in a style preset.
Example override note:
> "Beat 4 — transition override to dramatic shader. Reason: this is the product-reveal beat and the brand's homepage has a similar dramatic moment on first scroll. The shader is doing what the brand already does at this moment in its own story."
The reason is the load-bearing part. "Use dramatic shader on beat 4" with no reason is style-by-fiat; the version with a reason is style-by-derivation.
---
## A worked example
Captured brand: a wellness app with light cream backgrounds, lowercase humanist serif type, soft pastel accents, first-person copy ("we believe in small daily rituals"), no urgency language, slow scroll-driven photography of hands.
User direction: "I want it high-energy for TikTok."
**Brand-derived baseline:**
- Pacing: slow (cream + serif + slow scroll photography + unhurried copy)
- Density: sparse (architectural negative space on site)
- Transitions: smooth (no dramatic transitions on the captured site)
- Mood: light (cream backgrounds are the brand's signature)
- Motion: elegant or cinematic (slow drifts on the captured site)
- Audio: ambient (unhurried copy voice)
**User modifier:** "high-energy for TikTok" pushes pacing faster, transitions toward energetic, motion toward dynamic, audio toward punchy.
**Conflict resolution:** the user's push is in direct conflict with the brand. Three options as above:
1. Borrow what can coexist — keep light mood and sparse density (brand-true), but accelerate pacing slightly and add motion personality. Result: a faster wellness video that still feels like a wellness video, not a fitness video.
2. Ask: "Your brand is paced slowly — for TikTok, do you want me to push it faster than your brand normally moves, or keep the calm pacing but design for vertical and short attention?"
3. If you can't ask: write the brand-true version and flag the tension in the Creative Direction Summary so the user can respond on review.
The wrong move is to read "high-energy" and produce a fast, punchy, vibrant video — which is what the old recipe table would have produced, and which would not be a video of this wellness brand. It would be a generic high-energy TikTok with a wellness logo pasted on.