docs(skills): text corrections from prompt-guide validation

Documentation-only updates surfaced by the prompt-guide validation
campaign. The behavior fixes from the same campaign are in a separate
PR (pipeline fixes); Tier 3 block bugs are tracked in #2107.

- hyperframes-core SKILL.md: new "First-pass lint gotchas" subsection —
  the root composition element must carry data-start="0"
  (root_composition_missing_data_start), and initial states belong in
  gsap.fromTo, never a CSS transform paired with a GSAP tween on the
  same property (gsap_css_transform_conflict). Both were guaranteed
  first-build lint failures for agents writing compositions cold.
- media-use SKILL.md: "Weak local-model defaults" row corrected — local
  Kokoro TTS is the free default with HeyGen as the paid upsell (was
  described backwards), and bg-removal runs via the hyperframes CLI.
- docs/concepts/compositions.mdx: document that data-composition-src
  paths resolve relative to the project root, not the referencing file.
- gsap-transforms-and-perf.md: runtime-created SVG (createElementNS)
  has no reliable center pivot — draw geometry at local (0,0) inside a
  positioning <g> so scale/rotation pivot on the shape's middle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-07-09 22:21:10 -07:00
co-authored by Claude Fable 5
parent dda09c8d64
commit e7a6cb0da6
4 changed files with 12 additions and 2 deletions
+2
View File
@@ -37,6 +37,8 @@ You can embed one composition inside another in two ways: loading from an extern
<Tab title="External file"> <Tab title="External file">
Reference another HTML file with `data-composition-src`. The framework automatically fetches the file, extracts the `<template>` content, mounts it, executes scripts, and registers the timeline. Reference another HTML file with `data-composition-src`. The framework automatically fetches the file, extracts the `<template>` content, mounts it, executes scripts, and registers the timeline.
`data-composition-src` paths resolve relative to the **project root**, not the referencing file — a nested composition one level deep still writes `compositions/foo.html`, never `../compositions/foo.html`.
```html index.html ```html index.html
<div <div
id="el-5" id="el-5"
+2 -2
View File
@@ -22,7 +22,7 @@
"files": 1 "files": 1
}, },
"hyperframes-animation": { "hyperframes-animation": {
"hash": "16ecdf00cf5cebf1", "hash": "1c58fa2ea614e477",
"files": 99 "files": 99
}, },
"hyperframes-cli": { "hyperframes-cli": {
@@ -30,7 +30,7 @@
"files": 7 "files": 7
}, },
"hyperframes-core": { "hyperframes-core": {
"hash": "511a6283a5dbd7ea", "hash": "73e6f4cad4701e6d",
"files": 14 "files": 14
}, },
"hyperframes-creative": { "hyperframes-creative": {
@@ -54,6 +54,7 @@ Animate any custom property. Works for color, length, number — anything CSS wi
- `svgOrigin` sets transform origin in the SVG's global coordinate space (not the element's local box). **Do not** combine `svgOrigin` with `transformOrigin` on the same element — pick one. - `svgOrigin` sets transform origin in the SVG's global coordinate space (not the element's local box). **Do not** combine `svgOrigin` with `transformOrigin` on the same element — pick one.
- Animate SVG transform attributes via the same alias names (`x`, `y`, `rotation`) — GSAP handles the SVG-specific quirks. - Animate SVG transform attributes via the same alias names (`x`, `y`, `rotation`) — GSAP handles the SVG-specific quirks.
- **Runtime-created SVG (`createElementNS`) has no reliable center pivot.** GSAP can't resolve `transformOrigin`/`svgOrigin` to the geometric center of an element built at runtime, so `scale`/`rotation` pivot on the SVG's `(0,0)` origin instead of the shape's middle. Fix: draw the animated geometry centered at local `(0,0)` and place it with a wrapping `<g transform="translate(x,y)">` — the group positions it, the tween scales/rotates it about its own center.
## Performance Rules ## Performance Rules
+7
View File
@@ -49,6 +49,13 @@ The standalone root needs an explicit **sized box** (`width`/`height` in px), an
Each composition registers **exactly one** `gsap.timeline({ paused: true })` at `window.__timelines["<id>"]` (key = root `data-composition-id`), built **synchronously** at page load. Render duration = root `data-duration`, not timeline length. Don't manually nest sub-timelines into the host. Full contract (incl. non-GSAP runtimes) → `references/determinism-rules.md` + `hyperframes-animation/adapters/`. Each composition registers **exactly one** `gsap.timeline({ paused: true })` at `window.__timelines["<id>"]` (key = root `data-composition-id`), built **synchronously** at page load. Render duration = root `data-duration`, not timeline length. Don't manually nest sub-timelines into the host. Full contract (incl. non-GSAP runtimes) → `references/determinism-rules.md` + `hyperframes-animation/adapters/`.
### First-pass lint gotchas (a guaranteed first build failure)
Two rules that `lint` **does** catch, but only after the fact — write them right the first time:
- The **root** composition element must carry `data-start="0"` (alongside `data-composition-id`/`data-width`/`data-height`); omitting it fails `lint` with `root_composition_missing_data_start`.
- Never pair a CSS initial `transform` with a GSAP tween on the **same** property — the CSS value and the tween's start fight and `lint` rejects it with `gsap_css_transform_conflict`. Set the initial state inside the tween with `gsap.fromTo(el, { x: -40 }, { x: 0 })` instead of a CSS `transform: translateX(-40px)`.
### Non-negotiable rules (silent bugs `lint`/`validate`/`inspect` won't catch) ### Non-negotiable rules (silent bugs `lint`/`validate`/`inspect` won't catch)
Surfaced here; full rationale in the linked reference. Do not violate: Surfaced here; full rationale in the linked reference. Do not violate: