luckiest-co 1.0.24 → 1.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +2 -1
- package/commands/finish.md +4 -5
- package/commands/next.md +53 -0
- package/package.json +1 -1
- package/skills/luckiest-ad-creative/CHANGELOG.md +3 -0
- package/skills/luckiest-ad-creative/SKILL.md +4 -2
- package/skills/luckiest-copywriting-humanize/ATTRIBUTION.md +32 -0
- package/skills/luckiest-copywriting-humanize/CHANGELOG.md +30 -0
- package/skills/luckiest-copywriting-humanize/SKILL.md +82 -0
- package/skills/luckiest-copywriting-humanize/references/detection.md +40 -0
- package/skills/luckiest-copywriting-humanize/references/patterns.md +320 -0
- package/skills/luckiest-design-website/CHANGELOG.md +3 -0
- package/skills/luckiest-design-website/SKILL.md +3 -2
- package/skills/luckiest-finish/SKILL.md +4 -5
- package/skills/luckiest-image/CHANGELOG.md +3 -0
- package/skills/luckiest-image/SKILL.md +4 -2
- package/skills/luckiest-launch/CHANGELOG.md +3 -0
- package/skills/luckiest-launch/SKILL.md +3 -3
- package/skills/luckiest-next/SKILL.md +54 -0
- package/skills/luckiest-prompt-rewrite/CHANGELOG.md +3 -0
- package/skills/luckiest-prompt-rewrite/SKILL.md +4 -2
- package/skills/luckiest-social/CHANGELOG.md +3 -0
- package/skills/luckiest-social/SKILL.md +4 -2
- package/skills/luckiest-video/CHANGELOG.md +3 -0
- package/skills/luckiest-video/SKILL.md +4 -2
- package/skills/luckiest-video-studio/CHANGELOG.md +8 -0
- package/skills/luckiest-video-studio/SKILL.md +7 -3
- package/skills/luckiest-video-studio-cards/CHANGELOG.md +3 -0
- package/skills/luckiest-video-studio-cards/SKILL.md +4 -2
- package/skills/luckiest-video-studio-composition/ATTRIBUTION.md +22 -0
- package/skills/luckiest-video-studio-composition/CHANGELOG.md +30 -0
- package/skills/luckiest-video-studio-composition/LICENSE-iart +21 -0
- package/skills/luckiest-video-studio-composition/SKILL.md +212 -0
- package/skills/luckiest-video-studio-composition/references/grids-and-ratios.md +124 -0
- package/skills/luckiest-video-studio-composition/references/twenty-rules.md +47 -0
- package/skills/luckiest-video-studio-composition/scripts/frame_check.py +102 -0
- package/skills/luckiest-video-studio-recreate/CHANGELOG.md +3 -0
- package/skills/luckiest-video-studio-recreate/SKILL.md +5 -3
- package/skills/luckiest-video-studio-reel/CHANGELOG.md +3 -0
- package/skills/luckiest-video-studio-reel/SKILL.md +4 -2
- package/skills/luckiest-video-studio-talk/CHANGELOG.md +3 -0
- package/skills/luckiest-video-studio-talk/SKILL.md +4 -2
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog — luckiest-video-studio
|
|
2
2
|
|
|
3
|
+
## 1.6.0 (2026-10-03)
|
|
4
|
+
- New `luckiest-video-studio-composition` sub-skill: focal placement (thirds, phi
|
|
5
|
+
grid, golden spiral and triangles), white-space budgets, platform safe areas,
|
|
6
|
+
and the 20 photo composition rules adapted to video.
|
|
7
|
+
- Step 3 reads it for each scene's hold frame. Step 4 runs
|
|
8
|
+
`luckiest-video-studio-composition --review` (writes `qa/composition-review.md`)
|
|
9
|
+
before the motion review.
|
|
10
|
+
|
|
3
11
|
## 1.5.1 (2026-10-02)
|
|
4
12
|
- Step 2 routes narrated videos of 30 seconds or more to the new
|
|
5
13
|
`luckiest-video-studio-script` sub-skill, whose lines become scenes.
|
|
@@ -4,7 +4,7 @@ description: "Make product launch videos, product demos with motion design betwe
|
|
|
4
4
|
license: See ATTRIBUTION.md
|
|
5
5
|
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
|
|
6
6
|
metadata:
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.6.0"
|
|
8
8
|
listing_id: luckiest-video-studio
|
|
9
9
|
author: luckiest
|
|
10
10
|
---
|
|
@@ -25,7 +25,7 @@ further if `upToDate: true`. Never block on this check; if the tool is unavailab
|
|
|
25
25
|
proceed.
|
|
26
26
|
|
|
27
27
|
When the skill's work is done, call the Luckiest MCP `report_usage` tool once with
|
|
28
|
-
`{ listing_id: "luckiest-video-studio", skill_version: "1.
|
|
28
|
+
`{ listing_id: "luckiest-video-studio", skill_version: "1.6.0", matched: true, success: <true if the skill completed, false otherwise> }`.
|
|
29
29
|
Metadata only, never prompt text. Never block on it; if the tool is unavailable,
|
|
30
30
|
skip silently.
|
|
31
31
|
|
|
@@ -178,7 +178,8 @@ length.
|
|
|
178
178
|
`hyperframes-keyframes`, `hyperframes-creative`, `hyperframes-cli`, then
|
|
179
179
|
[references/step-3-compose.md](references/step-3-compose.md),
|
|
180
180
|
[references/audio.md](references/audio.md), and the `luckiest-video-studio-motion`
|
|
181
|
-
sub-skill for easing, duration, origin, and transitions.
|
|
181
|
+
sub-skill for easing, duration, origin, and transitions. Read the `luckiest-video-studio-composition` sub-skill for
|
|
182
|
+
focal placement, grids, and white space at each scene's hold frame. Do not enter the `hyperframes` intent
|
|
182
183
|
interview or its generic launch-video workflow; this skill owns the story.
|
|
183
184
|
|
|
184
185
|
Build each motion and logo scene as its own sub-composition. For demo scenes,
|
|
@@ -206,6 +207,9 @@ node <skill-dir>/scripts/qa.mjs crossfade <output-dir>/composition # full-fra
|
|
|
206
207
|
node <skill-dir>/scripts/qa.mjs motion <output-dir>/composition # ease-in entrances, scale 0 cards, short linear moves
|
|
207
208
|
```
|
|
208
209
|
|
|
210
|
+
Then run `luckiest-video-studio-composition --review` on the run. It writes
|
|
211
|
+
`qa/composition-review.md` with a verdict per scene. Fix every scene it blocks.
|
|
212
|
+
|
|
209
213
|
Then run `luckiest-video-studio-motion --review` on the run. It writes
|
|
210
214
|
`qa/motion-review.md` with a verdict per scene. Fix and re-render every scene it
|
|
211
215
|
blocks before the judge.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog: luckiest-video-studio-cards
|
|
2
2
|
|
|
3
|
+
## 1.0.1 (2026-10-03)
|
|
4
|
+
- Points at `luckiest-video-studio-composition` (when installed) for focal point, grid, white space, and safe areas.
|
|
5
|
+
|
|
3
6
|
## 1.0.0 (2026-09-30)
|
|
4
7
|
- New sub-skill: 406 cards in the paper-collage and aurora-glass packs, a
|
|
5
8
|
blueprint, two scene templates, and registry and new-pack scripts.
|
|
@@ -14,7 +14,7 @@ user-invocable: false
|
|
|
14
14
|
license: MIT. See ATTRIBUTION.md
|
|
15
15
|
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
|
|
16
16
|
metadata:
|
|
17
|
-
version: "1.0.
|
|
17
|
+
version: "1.0.1"
|
|
18
18
|
listing_id: luckiest-video-studio-cards
|
|
19
19
|
author: luckiest
|
|
20
20
|
---
|
|
@@ -32,7 +32,7 @@ On activation, call the Luckiest MCP `check_updates` tool with
|
|
|
32
32
|
`upToDate: false`, surface the `notice` once and continue. Never block on it.
|
|
33
33
|
|
|
34
34
|
When done, call `report_usage` once with
|
|
35
|
-
`{ listing_id: "luckiest-video-studio-cards", skill_version: "1.0.
|
|
35
|
+
`{ listing_id: "luckiest-video-studio-cards", skill_version: "1.0.1", matched: true, success: <true|false> }`.
|
|
36
36
|
Metadata only. Skip silently if unavailable.
|
|
37
37
|
|
|
38
38
|
## Standing rules
|
|
@@ -82,6 +82,8 @@ loaded from `composition/assets/fonts/` when the files are there.
|
|
|
82
82
|
|
|
83
83
|
## Step 3: Place
|
|
84
84
|
|
|
85
|
+
Read `luckiest-video-studio-composition` for the card's focal point, grid, and white space at its hold frame.
|
|
86
|
+
|
|
85
87
|
- **tier1:** copy the branded card to `composition/compositions/<scene-id>.html`
|
|
86
88
|
(its `tokens.css` link, `cards/<pack-id>/tokens.css`, is already relative to
|
|
87
89
|
`composition/`, so it resolves in Studio and in the render), fill every
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Attribution
|
|
2
|
+
|
|
3
|
+
`luckiest-video-studio-composition` is a Luckiest sub-skill of `luckiest-video-studio`.
|
|
4
|
+
|
|
5
|
+
| Source | License | What this sub-skill uses | License file |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| **shot-composition** by iart.ai (`iart-ai/motion-design-skills`, https://github.com/iart-ai/motion-design-skills/tree/main/skills/shot-composition) | MIT, Copyright (c) 2026 iart.ai | Grid math and worked tables, rule-of-thirds placement, hierarchy order, negative space, depth layers and parallax speeds, safe-area table, camera-move values, and the anti-pattern framing | `LICENSE-iart` |
|
|
8
|
+
| **20 rules of photo composition** (SlideShare deck, https://www.slideshare.net/slideshow/20-rules-of-photo-composition/248755645) | Not stated | The list of 20 rule names only. Explanations, video adaptations, and tests are original | n/a |
|
|
9
|
+
|
|
10
|
+
## Changes in this edition
|
|
11
|
+
|
|
12
|
+
- Refocused from general motion design to hold frames in `luckiest-video-studio`
|
|
13
|
+
runs (HyperFrames and GSAP).
|
|
14
|
+
- Added the golden ratio: phi grid, golden spiral, golden triangles, phi type
|
|
15
|
+
scale, with pixel tables per aspect.
|
|
16
|
+
- Added white-space budgets per scene type and the 20 rules with pass/fail tests.
|
|
17
|
+
- Added `--review` mode and rendered-still checks (squint, thumbnail, overlay).
|
|
18
|
+
- Removed cross-references to iart skills not installed here
|
|
19
|
+
(`animation-principles`, `motion-art-direction`, `gsap-web`, `remotion-video`,
|
|
20
|
+
`after-effects`). Easing and timing defer to `luckiest-video-studio-motion`.
|
|
21
|
+
- Replaced CSS scroll, pointer, and Three.js parallax code with GSAP. Dropped the
|
|
22
|
+
orbit and dolly-zoom recipes.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog — luckiest-video-studio-composition
|
|
2
|
+
|
|
3
|
+
## 1.1.0 — 2026-10-03
|
|
4
|
+
- Description widened so it triggers for generated images, product photos,
|
|
5
|
+
mockups, thumbnails, ads, and launch videos, not only video-studio scenes.
|
|
6
|
+
- Image, ad creative, AI video, social, launch, website design, and prompt
|
|
7
|
+
rewrite skills now point here when it is installed.
|
|
8
|
+
|
|
9
|
+
## 1.0.0 — 2026-10-03
|
|
10
|
+
- New sub-skill of luckiest-video-studio, based on iart.ai `shot-composition` (MIT).
|
|
11
|
+
- Placement systems: rule of thirds, phi grid, golden spiral, golden triangles,
|
|
12
|
+
centered symmetry, with pixel anchors for 16:9, 9:16, 1:1, 4:5.
|
|
13
|
+
- White-space budgets per scene type. Focal spacing at least 1.5x supporting spacing.
|
|
14
|
+
- `references/twenty-rules.md`: the 20 photo composition rules adapted to video,
|
|
15
|
+
each with a pass/fail test, mapped to motion-skill scene purposes.
|
|
16
|
+
- `--review` writes `qa/composition-review.md` with Approve or Block per scene.
|
|
17
|
+
- Rendered-still checks: squint blur, 160px thumbnail, anchor overlay.
|
|
18
|
+
- Network hook: after `--review`, offer to share the worst frame and its fix with
|
|
19
|
+
the tribe for a second eye.
|
|
20
|
+
- `scripts/frame_check.py` (Pillow): draws thirds, phi, golden triangle, and
|
|
21
|
+
safe-area overlays, writes squint and 160px thumbnail stills, and scores the
|
|
22
|
+
focal point against each anchor system (exit 1 when off by more than 3%).
|
|
23
|
+
- 9:16 safe areas corrected from 13/19/6/6% to 15/35/11/18%, with per-platform
|
|
24
|
+
pixels for TikTok, Reels, and Shorts. Source: postplanify.com and brandeal.ai
|
|
25
|
+
safe-zone guides, checked 2026-10-03.
|
|
26
|
+
- Trend pass: not run. `/newsjack` and `/luckiest-trends` were skipped for this
|
|
27
|
+
build. Safe-area percentages carry a re-check note instead.
|
|
28
|
+
- Thumbnail: description routes to `checklist` (matched "rule"). Real keyword
|
|
29
|
+
match but loose. A composition or grid scene would fit better; that is a
|
|
30
|
+
separate `/luckiest-micrographic` task.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 iart.ai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: luckiest-video-studio-composition
|
|
3
|
+
description: >-
|
|
4
|
+
Frame composition for video scenes, generated images, product photos, mockups,
|
|
5
|
+
thumbnails, ads, and launch videos. Places the focal point, sets the grid, and
|
|
6
|
+
reserves white space using the rule of thirds, golden ratio (phi grid, golden
|
|
7
|
+
spiral, golden triangles), 12 column and 8px grids, platform safe areas, and the
|
|
8
|
+
20 classic photo composition rules (leading lines, rule of odds, rule of space,
|
|
9
|
+
frame within a frame, and more). Also reviews frames and stills against those
|
|
10
|
+
rules. Used by luckiest-video-studio while composing, and by image, video, ad,
|
|
11
|
+
social, and prompt skills before they frame a shot. Trigger on "the frame feels
|
|
12
|
+
cluttered", "where should this go", "where should the subject go", "frame this",
|
|
13
|
+
"compose this shot", "use the rule of thirds", "golden
|
|
14
|
+
ratio layout", "more white space", "review the composition", "adapt this to 9:16", or "/luckiest-video-studio-composition". For easing
|
|
15
|
+
and transitions use luckiest-video-studio-motion. For building the whole video
|
|
16
|
+
use luckiest-video-studio.
|
|
17
|
+
argument-hint: "[run-dir] [--review] [--scene <id>] [--aspect 16:9|9:16|1:1|4:5]"
|
|
18
|
+
user-invocable: true
|
|
19
|
+
license: MIT. See ATTRIBUTION.md
|
|
20
|
+
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
|
|
21
|
+
metadata:
|
|
22
|
+
version: "1.1.0"
|
|
23
|
+
listing_id: luckiest-video-studio-composition
|
|
24
|
+
author: luckiest
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# Composition for video frames
|
|
28
|
+
|
|
29
|
+
Decides where things sit in the frame and how much empty space surrounds them.
|
|
30
|
+
Every scene is judged at its **hold frame**, the frame where motion has settled
|
|
31
|
+
and the viewer reads it. Motion between holds belongs to
|
|
32
|
+
`luckiest-video-studio-motion`.
|
|
33
|
+
|
|
34
|
+
## Staying current
|
|
35
|
+
|
|
36
|
+
On activation, call the Luckiest MCP `check_updates` tool with
|
|
37
|
+
`{ listingId: "luckiest-video-studio-composition", installedSemver: "1.1.0" }`. If
|
|
38
|
+
`upToDate: false`, surface the `notice` once and continue. Never block on it.
|
|
39
|
+
|
|
40
|
+
When done, call `report_usage` once with
|
|
41
|
+
`{ listing_id: "luckiest-video-studio-composition", skill_version: "1.1.0", matched: true, success: <true|false> }`.
|
|
42
|
+
Metadata only, never prompt text. Skip silently if unavailable.
|
|
43
|
+
|
|
44
|
+
## Modes
|
|
45
|
+
|
|
46
|
+
| Mode | Use when | Output |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| Build (default) | Composing or fixing a scene | A composition plan per scene, then code that follows it |
|
|
49
|
+
| `--review` | After `npx hyperframes check` passes, before `luckiest-video-studio-motion --review` | `<run-dir>/qa/composition-review.md` |
|
|
50
|
+
| `--aspect` | Adapting a master to another aspect | Restack plan for that aspect |
|
|
51
|
+
|
|
52
|
+
## 1. Pick one placement system per scene
|
|
53
|
+
|
|
54
|
+
Pick before placing anything. Mixing systems in one frame makes alignment drift.
|
|
55
|
+
|
|
56
|
+
| System | Use when | Anchor points (fraction of W and H) |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| **Rule of thirds** | Default. One subject plus supporting text | 0.333 / 0.667 |
|
|
59
|
+
| **Phi grid** (golden ratio) | Premium, editorial, calm. A subject that needs more breathing room on one side | 0.382 / 0.618 |
|
|
60
|
+
| **Golden spiral** | One hero object with a detail to land on (a phone screen, a logo mark) | Spiral eye at ~0.618 / 0.618 from the open corner |
|
|
61
|
+
| **Golden triangles** | Diagonal products, angled UI, a strong slant in the shot | Main diagonal plus perpendiculars from the other two corners |
|
|
62
|
+
| **Centered symmetry** | Logo reveals, single-word statements, end cards, deliberate stillness | 0.5 / 0.5, mirrored weight |
|
|
63
|
+
|
|
64
|
+
Phi and thirds differ by about 5% of the frame (on 1920px: 640 vs 733). Use phi
|
|
65
|
+
when the extra room on the open side matters. Do not claim a frame "uses the
|
|
66
|
+
golden spiral" unless the subject's detail actually lands on the spiral eye.
|
|
67
|
+
|
|
68
|
+
Formulas and pixel tables for every aspect are in
|
|
69
|
+
[references/grids-and-ratios.md](references/grids-and-ratios.md). Load it when
|
|
70
|
+
placing exact coordinates.
|
|
71
|
+
|
|
72
|
+
## 2. Set the grid
|
|
73
|
+
|
|
74
|
+
- 12 columns for 16:9 and 1:1, 6 columns for 9:16.
|
|
75
|
+
- 8px base unit. Spacing from 8, 16, 24, 32, 48, 64, 96, 128. Type sizes on the
|
|
76
|
+
same scale.
|
|
77
|
+
- Every element edge lands on a column edge or a baseline. A 3px misalignment
|
|
78
|
+
reads as a mistake at 1080p.
|
|
79
|
+
|
|
80
|
+
## 3. Reserve white space before placing content
|
|
81
|
+
|
|
82
|
+
White space is assigned, not left over. Set these budgets first, then fit
|
|
83
|
+
content into what remains.
|
|
84
|
+
|
|
85
|
+
| Scene type | Minimum empty area of the safe frame |
|
|
86
|
+
|---|---|
|
|
87
|
+
| Logo, statement, end card | 60% |
|
|
88
|
+
| Hero product with headline | 40% |
|
|
89
|
+
| Stat or data card | 30% |
|
|
90
|
+
| Dense explainer (diagram, UI walkthrough) | 20% |
|
|
91
|
+
|
|
92
|
+
- Space around the focal point is at least 1.5x the space between supporting
|
|
93
|
+
elements. Equal gaps everywhere make the frame read as a list, not a hierarchy.
|
|
94
|
+
- Related items sit closer to each other than to anything else (proximity).
|
|
95
|
+
- When a frame feels cluttered, remove an element before shrinking anything.
|
|
96
|
+
|
|
97
|
+
## 4. Rank the hierarchy
|
|
98
|
+
|
|
99
|
+
One primary focal point per hold frame. Rank every element by
|
|
100
|
+
**size > contrast > color > position**. Secondaries must lose on at least two of
|
|
101
|
+
those four. Test it with the squint check in section 7.
|
|
102
|
+
|
|
103
|
+
## 5. Apply the 20 composition rules
|
|
104
|
+
|
|
105
|
+
The full rule set, each adapted to motion graphics with a pass/fail test, is in
|
|
106
|
+
[references/twenty-rules.md](references/twenty-rules.md). Load it in Build mode
|
|
107
|
+
when a scene's placement is still undecided, and always in `--review`.
|
|
108
|
+
|
|
109
|
+
Rules that most often decide a video frame:
|
|
110
|
+
|
|
111
|
+
- **Rule of space / lead room.** A subject that moves or faces a direction gets
|
|
112
|
+
open space on that side. A speaker looking right sits on the left third.
|
|
113
|
+
- **Leading lines and diagonals.** UI edges, arrows, and gradients point at the
|
|
114
|
+
focal point, never off-frame.
|
|
115
|
+
- **Rule of odds.** Groups of 3 or 5 cards, icons, or logos read as designed.
|
|
116
|
+
Groups of 2 or 4 invite comparison. Use even numbers only when comparing.
|
|
117
|
+
- **Frame within a frame.** Device bezels, cards, and masks frame the subject.
|
|
118
|
+
One frame level per scene.
|
|
119
|
+
- **Left to right.** New content enters and progresses left to right (reverse
|
|
120
|
+
for RTL scripts). Reverse direction only to mean "back" or "against".
|
|
121
|
+
- **Balance.** A large element on one side is balanced by a smaller, higher
|
|
122
|
+
contrast element or by deliberate empty space on the other.
|
|
123
|
+
|
|
124
|
+
## 6. Safe areas and aspects
|
|
125
|
+
|
|
126
|
+
Critical content (text, logos, faces, CTAs) stays inside title-safe. On 9:16,
|
|
127
|
+
platform UI covers the top 15%, the bottom 35%, and the right 18%, with TikTok's
|
|
128
|
+
action rail reaching 28% in from the right from mid-frame down. Per-platform
|
|
129
|
+
pixels are in the grids reference. Use one platform's row when the video targets
|
|
130
|
+
only that platform.
|
|
131
|
+
|
|
132
|
+
To adapt across aspects, master in 16:9 with the focal point near the vertical
|
|
133
|
+
center band. For 9:16, restack side-by-side elements vertically, enlarge type
|
|
134
|
+
15-25%, and move the focal point up toward 0.4 H. Never make vertical by cropping
|
|
135
|
+
the master.
|
|
136
|
+
|
|
137
|
+
## 7. Checks that catch what reading the code misses
|
|
138
|
+
|
|
139
|
+
Run these on a rendered still of each hold frame
|
|
140
|
+
(`npx hyperframes render --frame <t>` or a screenshot of the preview), then:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
python3 <skill-dir>/scripts/frame_check.py still.png --focal <x>,<y> [--aspect 9:16]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
It writes `still.overlay.png` (thirds cyan, phi gold, golden triangles magenta,
|
|
147
|
+
safe area red, focal point white), `still.squint.png`, and `still.thumb.png`, and
|
|
148
|
+
prints the focal point's distance to each anchor system. It exits 1 when the focal
|
|
149
|
+
point is not within 3% of any anchor. Ignore that failure for scenes planned as
|
|
150
|
+
centered symmetry.
|
|
151
|
+
|
|
152
|
+
Read all three images:
|
|
153
|
+
|
|
154
|
+
1. **Squint.** The brightest or largest blob must be the intended focal point.
|
|
155
|
+
2. **Thumbnail.** The focal point and the headline must still read at 160px.
|
|
156
|
+
3. **Overlay.** The focal point sits on its planned anchor, and text, logos, and
|
|
157
|
+
faces stay inside the red safe area.
|
|
158
|
+
4. **Empty area.** Estimate the empty share of the safe area against the budget
|
|
159
|
+
in section 3.
|
|
160
|
+
|
|
161
|
+
The script needs Pillow. If it is missing, ask before running
|
|
162
|
+
`pip install pillow`. If the user declines, do the checks by eye on the still
|
|
163
|
+
and say which checks were done by eye.
|
|
164
|
+
|
|
165
|
+
## 8. Composition plan (Build mode output)
|
|
166
|
+
|
|
167
|
+
Per scene, write into the scene's entry in `storyboard.json` or alongside it:
|
|
168
|
+
|
|
169
|
+
- Placement system and the anchor the focal point sits on, in px.
|
|
170
|
+
- Grid: columns, margin, gutter, base unit.
|
|
171
|
+
- White-space budget and the scene type it came from.
|
|
172
|
+
- Hierarchy rank of every element.
|
|
173
|
+
- Which of the 20 rules the scene leans on (one to three, named).
|
|
174
|
+
- Safe areas and restack plan for each target aspect.
|
|
175
|
+
|
|
176
|
+
## 9. Review mode
|
|
177
|
+
|
|
178
|
+
`--review` reads `storyboard.json` and the composition files, renders or
|
|
179
|
+
screenshots each hold frame, runs section 7, and checks each scene against the
|
|
180
|
+
20 rules. Write `<run-dir>/qa/composition-review.md`:
|
|
181
|
+
|
|
182
|
+
| Scene | System | Focal on anchor | White space vs budget | Rules broken | Fix | Verdict |
|
|
183
|
+
|---|---|---|---|---|---|---|
|
|
184
|
+
|
|
185
|
+
Verdict is **Approve** or **Block**. Block when the focal point is ambiguous,
|
|
186
|
+
critical content leaves title-safe, the white-space budget is missed by more
|
|
187
|
+
than 10 points, or a scene breaks a rule without a stated reason. A broken rule
|
|
188
|
+
with a stated reason in the plan ("centered for stillness") passes.
|
|
189
|
+
|
|
190
|
+
After writing the review, offer once to share the worst-scoring frame and its
|
|
191
|
+
fix with the user's Luckiest tribe for a second eye. Never post automatically.
|
|
192
|
+
|
|
193
|
+
## Anti-patterns
|
|
194
|
+
|
|
195
|
+
| Symptom | Fix |
|
|
196
|
+
|---|---|
|
|
197
|
+
| Everything centered on one vertical axis | Move the primary to a thirds or phi anchor. Keep center only for symmetry scenes |
|
|
198
|
+
| Two elements tie for attention | Shrink or desaturate one until it loses on two of the four hierarchy factors |
|
|
199
|
+
| Frame filled edge to edge | Cut an element, then meet the white-space budget |
|
|
200
|
+
| Subject faces or moves into the near edge | Flip placement so lead room is on the facing side |
|
|
201
|
+
| Vertical made by cropping | Restack per section 6 |
|
|
202
|
+
| Different placement systems in one frame | One system per scene |
|
|
203
|
+
| Hold frame different from what was planned | Plan the hold frame, not the first or last frame |
|
|
204
|
+
|
|
205
|
+
## Reference files
|
|
206
|
+
|
|
207
|
+
- [references/grids-and-ratios.md](references/grids-and-ratios.md): thirds, phi,
|
|
208
|
+
spiral, and triangle math with pixel tables per aspect, grid math, safe areas,
|
|
209
|
+
depth layers, and camera moves in GSAP. Load when placing coordinates.
|
|
210
|
+
- [references/twenty-rules.md](references/twenty-rules.md): the 20 photo
|
|
211
|
+
composition rules adapted to video frames, each with a pass/fail test. Load for
|
|
212
|
+
undecided placement and for every review.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Grids, ratios, safe areas, and camera framing
|
|
2
|
+
|
|
3
|
+
Load this when placing exact coordinates. Pixel values are rounded to the
|
|
4
|
+
nearest pixel. Adapted from iart.ai `shot-composition/references/camera-and-grids.md`
|
|
5
|
+
(MIT), with phi and triangle math added and code moved to GSAP.
|
|
6
|
+
|
|
7
|
+
## Anchor points per aspect
|
|
8
|
+
|
|
9
|
+
Thirds lines at `W/3, 2W/3` and `H/3, 2H/3`. Phi lines at `0.382 W, 0.618 W`
|
|
10
|
+
and `0.382 H, 0.618 H`.
|
|
11
|
+
|
|
12
|
+
| Frame | Thirds x | Thirds y | Phi x | Phi y |
|
|
13
|
+
|---|---|---|---|---|
|
|
14
|
+
| 1920x1080 (16:9) | 640 / 1280 | 360 / 720 | 733 / 1187 | 413 / 667 |
|
|
15
|
+
| 1080x1920 (9:16) | 360 / 720 | 640 / 1280 | 413 / 667 | 733 / 1187 |
|
|
16
|
+
| 1080x1080 (1:1) | 360 / 720 | 360 / 720 | 413 / 667 | 413 / 667 |
|
|
17
|
+
| 1080x1350 (4:5) | 360 / 720 | 450 / 900 | 413 / 667 | 516 / 834 |
|
|
18
|
+
|
|
19
|
+
Power points are the four intersections of each set.
|
|
20
|
+
|
|
21
|
+
## Golden triangles
|
|
22
|
+
|
|
23
|
+
Draw one corner-to-corner diagonal, then a perpendicular to it from each of the
|
|
24
|
+
other two corners. The two feet of those perpendiculars are the anchors.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
t1 = W² / (W² + H²) foot from the corner at (W, 0), on the diagonal (0,0)→(W,H)
|
|
28
|
+
t2 = H² / (W² + H²) foot from the corner at (0, H)
|
|
29
|
+
anchor = (t * W, t * H)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Frame | Anchor A | Anchor B |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| 1920x1080 | (1459, 820) | (462, 260) |
|
|
35
|
+
| 1080x1920 | (260, 462) | (820, 1459) |
|
|
36
|
+
| 1080x1080 | (540, 540) | (540, 540) |
|
|
37
|
+
|
|
38
|
+
On 1:1 both anchors collapse to the center. Use thirds or phi on square frames instead.
|
|
39
|
+
Mirror the diagonal to suit the direction of the subject's slant.
|
|
40
|
+
|
|
41
|
+
## Golden spiral
|
|
42
|
+
|
|
43
|
+
The spiral is built from a golden rectangle (1:1.618). Video frames are not golden
|
|
44
|
+
rectangles, so the spiral is an approximation on 16:9 and 9:16. Its tight end
|
|
45
|
+
lands near the phi intersection on the side where the spiral closes. Place the
|
|
46
|
+
detail (screen, logo mark, face) there and let the larger subject sweep along the
|
|
47
|
+
outer arc. Rotate or flip the spiral to match where the detail is.
|
|
48
|
+
|
|
49
|
+
## Golden ratio beyond placement
|
|
50
|
+
|
|
51
|
+
- Split a frame into a 61.8 / 38.2 content and empty zone for calm hero scenes.
|
|
52
|
+
- Type scale by phi: 16, 26, 42, 68, 110. It has bigger jumps than an 8px scale,
|
|
53
|
+
so use it for statement scenes and the 8px scale for dense scenes.
|
|
54
|
+
- A card at 1:1.618 reads as more considered than an arbitrary rectangle.
|
|
55
|
+
|
|
56
|
+
## Grid math
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
content_width = frame_width - 2 * margin
|
|
60
|
+
column_width = (content_width - (cols - 1) * gutter) / cols
|
|
61
|
+
column_x(i) = margin + i * (column_width + gutter) // 0-indexed
|
|
62
|
+
span_width(n) = n * column_width + (n - 1) * gutter
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Frame | margin | gutter | cols | content | column | 4-col span |
|
|
66
|
+
|---|---|---|---|---|---|---|
|
|
67
|
+
| 1920x1080 | 100 | 24 | 12 | 1720 | 121.3 | 557.3 |
|
|
68
|
+
| 1080x1080 | 64 | 16 | 12 | 952 | 64.7 | 306.6 |
|
|
69
|
+
| 1080x1920 | 48 | 16 | 6 | 984 | 150.7 | 650.6 |
|
|
70
|
+
|
|
71
|
+
Spacing values are 4, 8, 16, 24, 32, 48, 64, 96, 128.
|
|
72
|
+
|
|
73
|
+
## Safe areas
|
|
74
|
+
|
|
75
|
+
| Aspect | Top | Bottom | Left | Right | Reason |
|
|
76
|
+
|---|---|---|---|---|---|
|
|
77
|
+
| 16:9 (1920x1080) | 5% (54) | 5% (54) | 5% (96) | 5% (96) | Web and video. Use 10% for broadcast |
|
|
78
|
+
| 9:16 (1080x1920) | 15% (288) | 35% (672) | 11% (120) | 18% (192) | Strictest of TikTok, Reels, and Shorts combined (see below) |
|
|
79
|
+
| 1:1 (1080x1080) | 7% (76) | 7% (76) | 7% (76) | 7% (76) | Symmetric feed crop |
|
|
80
|
+
| 4:5 (1080x1350) | 8% (108) | 8% (108) | 6% (65) | 6% (65) | Taller feed crop |
|
|
81
|
+
|
|
82
|
+
9:16 per platform, in px on 1080x1920 (checked 2026-10-03):
|
|
83
|
+
|
|
84
|
+
| Platform | Top | Bottom | Left | Right |
|
|
85
|
+
|---|---|---|---|---|
|
|
86
|
+
| TikTok | 240 | 660 | 120 | 120, and 300 from y=840 down for the action rail |
|
|
87
|
+
| Instagram Reels | 269 | 672 | 65 | 65 |
|
|
88
|
+
| YouTube Shorts | 288 | 672 | 48 | 192 |
|
|
89
|
+
|
|
90
|
+
Sources: postplanify.com/blog/social-media-safe-zones-2026-complete-guide,
|
|
91
|
+
brandeal.ai/en/blog/tiktok-safe-zone-guide. The combined row above takes the
|
|
92
|
+
largest value per side. When a video targets one platform, use that platform's
|
|
93
|
+
row for more room. Platform UI changes, so re-check this table when it is more
|
|
94
|
+
than six months old.
|
|
95
|
+
|
|
96
|
+
## Depth layers
|
|
97
|
+
|
|
98
|
+
| Depth | Role | Parallax speed | Contrast |
|
|
99
|
+
|---|---|---|---|
|
|
100
|
+
| Background | Ambient | 0.1-0.3x | Low, often blurred or desaturated |
|
|
101
|
+
| Midground | Supporting | 0.5-0.7x | Mid |
|
|
102
|
+
| Foreground | Primary, the thing the eye follows | 1.0-1.5x | Sharp. Props crossing the subject blur 2-4px |
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
// GSAP parallax pan, one timeline, distinct speeds per layer
|
|
106
|
+
const dist = 300;
|
|
107
|
+
tl.to(".bg", { x: -dist * 0.2, duration: 1.6, ease: "power2.inOut" }, 0)
|
|
108
|
+
.to(".mid", { x: -dist * 0.6, duration: 1.6, ease: "power2.inOut" }, 0)
|
|
109
|
+
.to(".fg", { x: -dist * 1.2, duration: 1.6, ease: "power2.inOut" }, 0);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Camera moves
|
|
113
|
+
|
|
114
|
+
One move per beat. Combining push, pan, and rotate reads as chaos.
|
|
115
|
+
|
|
116
|
+
| Move | Values | Ease | Use |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| Push-in | scale 1.0 → 1.12 over 1.6s, origin on the focal point | `power2.inOut` | Focus, intimacy |
|
|
119
|
+
| Pull-out | scale 1.15 → 1.0 over 1.8s, origin centered | `power2.inOut` | Reveal context |
|
|
120
|
+
| Pan | x 0 → -300 over 1.5s | `power2.inOut` | Reveal space. Keep the subject a third from the trailing edge so it leads |
|
|
121
|
+
| Whip-pan | out: x 0 → -120% over 0.28s, `power3.in`. In: 120% → 0 over 0.28s, `power3.out`, overlapped | see values | Energetic scene change |
|
|
122
|
+
|
|
123
|
+
Set `transformOrigin` to the focal point's anchor for pushes, so the subject stays
|
|
124
|
+
on its thirds or phi point while the frame grows around it.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# The 20 composition rules, adapted for video frames
|
|
2
|
+
|
|
3
|
+
The rule list follows the deck "20 rules of photo composition"
|
|
4
|
+
(https://www.slideshare.net/slideshow/20-rules-of-photo-composition/248755645,
|
|
5
|
+
fetched 2026-10-03). The explanations, video adaptations, and tests are written
|
|
6
|
+
for this skill.
|
|
7
|
+
|
|
8
|
+
Rules conflict on purpose (fill the frame vs negative space, thirds vs centered).
|
|
9
|
+
Each scene picks the rules that serve its purpose and states any rule it breaks.
|
|
10
|
+
|
|
11
|
+
| # | Rule | Video adaptation | Pass test |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| 1 | **Rule of thirds** | Focal point on a thirds line or power point. The default for product and speaker shots | Focal point within 3% of a thirds line |
|
|
14
|
+
| 2 | **Centered composition and symmetry** | Logo reveals, single statements, end cards. Symmetry reads as still and formal | Mirrored weight within ~10%. Center chosen on purpose, not by default |
|
|
15
|
+
| 3 | **Foreground interest and depth** | A blurred foreground prop or UI chip in front of the subject adds depth. Pair it with parallax | At least two depth layers moving at different speeds when the scene moves |
|
|
16
|
+
| 4 | **Frame within the frame** | Device bezels, cards, masks, and window chrome enclose the subject | One frame level. The inner frame does not touch the outer frame edge |
|
|
17
|
+
| 5 | **Leading lines** | UI edges, arrows, connector lines, and gradient directions point at the focal point | Every strong line ends at or points to the focal point, not off-frame |
|
|
18
|
+
| 6 | **Diagonals and triangles** | Tilted devices and angled cards add energy. Three elements arranged in a triangle feel stable | Diagonals run toward the focal point. Triangle groups have a clear apex |
|
|
19
|
+
| 7 | **Patterns and textures** | Repeated cards, grids of logos, and background textures give rhythm. Break the pattern once to mark the focal item | The focal item breaks the pattern by color, scale, or position |
|
|
20
|
+
| 8 | **Rule of odds** | Show 3 or 5 items. Odd groups give the eye a center item to rest on | Item count is odd, or even on purpose for a comparison |
|
|
21
|
+
| 9 | **Fill the frame** | Close crops on a UI detail or product surface for emphasis beats | The subject takes over ~70% of the frame. No unrelated element enters |
|
|
22
|
+
| 10 | **Leave negative space** | Empty area around the subject signals premium and gives text and motion room | Meets the white-space budget in SKILL.md section 3 |
|
|
23
|
+
| 11 | **Simplicity and minimalism** | One idea per hold frame. Cut decoration that does not support the beat | Removing any element would lose meaning |
|
|
24
|
+
| 12 | **Isolate the subject** | Separate the subject with blur, a darkened background, a spotlight gradient, or a solid field | The squint check finds the subject first |
|
|
25
|
+
| 13 | **Change your point of view** | Vary the virtual camera: top-down, low angle, 3D tilt on a device. Avoid every scene being flat front-on | Consecutive scenes do not repeat the same angle and scale |
|
|
26
|
+
| 14 | **Look for particular color** | One accent color marks the focal point. Everything else stays neutral | The accent color appears on the focal element and nowhere competing |
|
|
27
|
+
| 15 | **Rule of space** | Lead room. Open space goes in the direction the subject faces, points, or moves | The space ahead of the subject is wider than the space behind it |
|
|
28
|
+
| 16 | **Left to right rule** | Progress, timelines, and entering content flow left to right for LTR viewers. Reverse only to mean back or against | Direction matches meaning. Flip for RTL scripts |
|
|
29
|
+
| 17 | **Balance elements in the scene** | Offset a heavy element with a smaller, higher contrast one or with empty space on the opposite side | The frame does not feel like it tips toward one side when squinted |
|
|
30
|
+
| 18 | **Juxtaposition** | Place contrasting items side by side (before and after, old and new, problem and fix) to tell a story in one frame | The two items share size and alignment so only the difference reads |
|
|
31
|
+
| 19 | **Golden triangles** | Diagonal compositions place subjects on the triangle anchors (see grids-and-ratios.md) | Subject within 3% of a triangle anchor. Main lines follow the diagonal |
|
|
32
|
+
| 20 | **Golden ratio** | Phi grid at 0.382 and 0.618, golden spiral for one hero with a detail, 61.8/38.2 splits | Focal point within 3% of a phi line, or the spiral eye on the detail |
|
|
33
|
+
|
|
34
|
+
## Choosing rules by scene purpose
|
|
35
|
+
|
|
36
|
+
Scene purposes match `luckiest-video-studio-motion`.
|
|
37
|
+
|
|
38
|
+
| Purpose | Lean on |
|
|
39
|
+
|---|---|
|
|
40
|
+
| Reveal | 3, 4, 12 |
|
|
41
|
+
| Emphasis | 9, 12, 14 |
|
|
42
|
+
| Bridge | 5, 15, 16 |
|
|
43
|
+
| Explain | 1, 7, 8, 16 |
|
|
44
|
+
| Cause | 6, 18 |
|
|
45
|
+
| Rhythm | 7, 8, 13 |
|
|
46
|
+
| Delight | 19, 20, 13 |
|
|
47
|
+
| Logo or end card | 2, 10, 11 |
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Composition checks on a rendered hold-frame still.
|
|
3
|
+
|
|
4
|
+
Writes next to the still:
|
|
5
|
+
<name>.overlay.png thirds (cyan), phi (gold), golden triangles (magenta), safe area (red)
|
|
6
|
+
<name>.squint.png blurred copy, the brightest/largest blob should be the focal point
|
|
7
|
+
<name>.thumb.png 160px wide copy, focal point and headline must still read
|
|
8
|
+
With --focal X,Y, prints the distance to the nearest thirds/phi line and triangle anchor
|
|
9
|
+
as a fraction of the frame, and PASS when within 3%.
|
|
10
|
+
|
|
11
|
+
Usage: frame_check.py still.png [--aspect 16:9|9:16|1:1|4:5] [--focal 1280,360]
|
|
12
|
+
Needs Pillow (pip install pillow).
|
|
13
|
+
"""
|
|
14
|
+
import argparse
|
|
15
|
+
import sys
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from PIL import Image, ImageDraw, ImageFilter
|
|
19
|
+
|
|
20
|
+
# top, bottom, left, right as fractions, from references/grids-and-ratios.md
|
|
21
|
+
SAFE = {"16:9": (.05, .05, .05, .05), "9:16": (.15, .35, .11, .18),
|
|
22
|
+
"1:1": (.07, .07, .07, .07), "4:5": (.08, .08, .06, .06)}
|
|
23
|
+
THIRDS = (1 / 3, 2 / 3)
|
|
24
|
+
PHI = (0.382, 0.618)
|
|
25
|
+
TOL = 0.03
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def guess_aspect(w, h):
|
|
29
|
+
r = w / h
|
|
30
|
+
def ratio(k):
|
|
31
|
+
x, y = map(int, k.split(":"))
|
|
32
|
+
return x / y
|
|
33
|
+
return min(SAFE, key=lambda k: abs(r - ratio(k)))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def triangle_anchors(w, h):
|
|
37
|
+
d = w * w + h * h
|
|
38
|
+
t1, t2 = w * w / d, h * h / d
|
|
39
|
+
pts = [(t1 * w, t1 * h), (t2 * w, t2 * h)]
|
|
40
|
+
return pts + [(w - x, y) for x, y in pts] # mirrored diagonal
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def focal_report(fx, fy, w, h):
|
|
44
|
+
lines = []
|
|
45
|
+
for name, fr in (("thirds", THIRDS), ("phi", PHI)):
|
|
46
|
+
dx = min(abs(fx / w - f) for f in fr)
|
|
47
|
+
dy = min(abs(fy / h - f) for f in fr)
|
|
48
|
+
d = min(dx, dy)
|
|
49
|
+
lines.append((name, d, d <= TOL))
|
|
50
|
+
d = min(max(abs(fx - ax) / w, abs(fy - ay) / h) for ax, ay in triangle_anchors(w, h))
|
|
51
|
+
lines.append(("triangle", d, d <= TOL))
|
|
52
|
+
return lines
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def main():
|
|
56
|
+
ap = argparse.ArgumentParser()
|
|
57
|
+
ap.add_argument("still")
|
|
58
|
+
ap.add_argument("--aspect", choices=SAFE)
|
|
59
|
+
ap.add_argument("--focal")
|
|
60
|
+
a = ap.parse_args()
|
|
61
|
+
|
|
62
|
+
src = Path(a.still)
|
|
63
|
+
im = Image.open(src).convert("RGB")
|
|
64
|
+
w, h = im.size
|
|
65
|
+
aspect = a.aspect or guess_aspect(w, h)
|
|
66
|
+
stroke = max(2, w // 640)
|
|
67
|
+
|
|
68
|
+
ov = im.copy()
|
|
69
|
+
dr = ImageDraw.Draw(ov)
|
|
70
|
+
for fr, color in ((THIRDS, (0, 220, 255)), (PHI, (255, 190, 0))):
|
|
71
|
+
for f in fr:
|
|
72
|
+
dr.line([(f * w, 0), (f * w, h)], fill=color, width=stroke)
|
|
73
|
+
dr.line([(0, f * h), (w, f * h)], fill=color, width=stroke)
|
|
74
|
+
dr.line([(0, 0), (w, h)], fill=(255, 0, 200), width=stroke)
|
|
75
|
+
dr.line([(w, 0), (0, h)], fill=(255, 0, 200), width=stroke)
|
|
76
|
+
for ax, ay in triangle_anchors(w, h):
|
|
77
|
+
r = stroke * 4
|
|
78
|
+
dr.ellipse([ax - r, ay - r, ax + r, ay + r], outline=(255, 0, 200), width=stroke)
|
|
79
|
+
t, b, l, r_ = SAFE[aspect]
|
|
80
|
+
dr.rectangle([l * w, t * h, w - r_ * w, h - b * h], outline=(255, 40, 40), width=stroke)
|
|
81
|
+
if a.focal:
|
|
82
|
+
fx, fy = map(float, a.focal.split(","))
|
|
83
|
+
rr = stroke * 6
|
|
84
|
+
dr.ellipse([fx - rr, fy - rr, fx + rr, fy + rr], outline=(255, 255, 255), width=stroke * 2)
|
|
85
|
+
|
|
86
|
+
stem = src.with_suffix("")
|
|
87
|
+
ov.save(f"{stem}.overlay.png")
|
|
88
|
+
im.filter(ImageFilter.GaussianBlur(radius=max(8, w // 160))).save(f"{stem}.squint.png")
|
|
89
|
+
im.resize((160, max(1, round(160 * h / w))), Image.LANCZOS).save(f"{stem}.thumb.png")
|
|
90
|
+
print(f"{w}x{h} aspect {aspect}: wrote overlay, squint, thumb next to {src.name}")
|
|
91
|
+
|
|
92
|
+
if a.focal:
|
|
93
|
+
ok = False
|
|
94
|
+
for name, d, passed in focal_report(fx, fy, w, h):
|
|
95
|
+
ok |= passed
|
|
96
|
+
print(f" {name:8} {d:.1%} from nearest {'PASS' if passed else 'off'}")
|
|
97
|
+
print("focal:", "PASS" if ok else "FAIL (not within 3% of any anchor system)")
|
|
98
|
+
sys.exit(0 if ok else 1)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
main()
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog — luckiest-video-studio-recreate
|
|
2
2
|
|
|
3
|
+
## 1.0.1 — 2026-10-03
|
|
4
|
+
- Points at `luckiest-video-studio-composition` (when installed) for focal point, grid, white space, and safe areas.
|
|
5
|
+
|
|
3
6
|
## 1.0.0 — 2026-10-01
|
|
4
7
|
- New sub-skill: URL or mp4 to a per-shot prompt list (`prompts.md`,
|
|
5
8
|
`prompts.json`), AI generation through the creative MCP with a cost check
|