@devinilabs/reelstack 1.2.0
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/LICENSE +128 -0
- package/README.md +125 -0
- package/cli/beats.js +124 -0
- package/cli/bootstrap.js +124 -0
- package/cli/capture.js +34 -0
- package/cli/direction.js +114 -0
- package/cli/icons.js +49 -0
- package/cli/index.js +101 -0
- package/cli/init.js +253 -0
- package/cli/license.js +168 -0
- package/cli/lint.js +865 -0
- package/cli/preview.js +59 -0
- package/cli/render.js +404 -0
- package/cli/scaffold.js +239 -0
- package/cli/smoke.js +76 -0
- package/cli/update.js +26 -0
- package/cli/utils.js +184 -0
- package/docs/buyers-guide.md +220 -0
- package/docs/design-discipline.md +130 -0
- package/docs/family-galleries/dark.md +95 -0
- package/docs/family-galleries/forbidden.md +78 -0
- package/docs/family-galleries/glass.md +98 -0
- package/docs/family-galleries/paper.md +82 -0
- package/docs/family-galleries/warm.md +86 -0
- package/docs/superpowers/plans/2026-05-09-reelstack-init-readiness-gate.md +1166 -0
- package/docs/superpowers/specs/2026-05-09-reelstack-init-readiness-gate-design.md +233 -0
- package/families/dark/components/DriftingSpotlights.tsx +59 -0
- package/families/dark/components/FilmGrain.tsx +44 -0
- package/families/dark/components/ForestCard.tsx +43 -0
- package/families/dark/components/GridBackground.tsx +29 -0
- package/families/dark/components/RadialVignette.tsx +21 -0
- package/families/dark/components/Scanlines.tsx +35 -0
- package/families/dark/components/SegmentOpacity.ts +37 -0
- package/families/dark/components/index.ts +13 -0
- package/families/dark/index.ts +31 -0
- package/families/dark/palette.ts +98 -0
- package/families/dark/presets/claudedispatch.ts +46 -0
- package/families/dark/presets/codedrop.ts +37 -0
- package/families/dark/presets/gpt55.ts +54 -0
- package/families/dark/presets/notebooklm.ts +50 -0
- package/families/dark/presets/resourcescta.ts +35 -0
- package/families/dark/presets/skills.ts +40 -0
- package/families/dark/presets/stitch.ts +46 -0
- package/families/dark/presets/stitch2.ts +43 -0
- package/families/dark/typography.ts +16 -0
- package/families/forbidden/components/ForbiddenCausticBlobs.tsx +52 -0
- package/families/forbidden/components/NewsprintTexture.tsx +28 -0
- package/families/forbidden/components/TintedShadow.tsx +36 -0
- package/families/forbidden/components/index.ts +38 -0
- package/families/forbidden/index.ts +17 -0
- package/families/forbidden/palette.ts +88 -0
- package/families/forbidden/presets/heretic.ts +44 -0
- package/families/forbidden/typography.ts +18 -0
- package/families/glass/components/BreakdownCard.tsx +158 -0
- package/families/glass/components/CausticBlobs.tsx +49 -0
- package/families/glass/components/Counter.tsx +72 -0
- package/families/glass/components/EyebrowPill.tsx +59 -0
- package/families/glass/components/FilmStrip.tsx +202 -0
- package/families/glass/components/FloatingGlyphs.tsx +78 -0
- package/families/glass/components/GlassCard.tsx +58 -0
- package/families/glass/components/GlassCardBezel.tsx +45 -0
- package/families/glass/components/HairlineGrid.tsx +30 -0
- package/families/glass/components/IridescentRing.tsx +114 -0
- package/families/glass/components/IridescentText.tsx +98 -0
- package/families/glass/components/LightBeam.tsx +46 -0
- package/families/glass/components/ParticleBurst.tsx +62 -0
- package/families/glass/components/SonarRings.tsx +81 -0
- package/families/glass/components/StaggeredWords.tsx +74 -0
- package/families/glass/components/index.ts +20 -0
- package/families/glass/index.ts +31 -0
- package/families/glass/palette.ts +93 -0
- package/families/glass/presets/claudewatch.ts +64 -0
- package/families/glass/presets/claudewatchcta.ts +43 -0
- package/families/glass/presets/graphify.ts +45 -0
- package/families/glass/presets/gstack.ts +48 -0
- package/families/glass/presets/jcode.ts +50 -0
- package/families/glass/presets/lilagents.ts +52 -0
- package/families/glass/presets/paperclip.ts +43 -0
- package/families/glass/typography.ts +15 -0
- package/families/index.ts +49 -0
- package/families/paper/components/CardSpring.tsx +42 -0
- package/families/paper/components/CreamGrid.tsx +26 -0
- package/families/paper/components/EditorialSerifText.tsx +51 -0
- package/families/paper/components/GreenAccentCard.tsx +10 -0
- package/families/paper/components/PaperShadow.tsx +30 -0
- package/families/paper/components/ScaleBlurText.tsx +40 -0
- package/families/paper/components/index.ts +11 -0
- package/families/paper/index.ts +23 -0
- package/families/paper/palette.ts +102 -0
- package/families/paper/presets/designreel.ts +32 -0
- package/families/paper/presets/devini3d.ts +45 -0
- package/families/paper/presets/justdrop.ts +39 -0
- package/families/paper/presets/opus.ts +48 -0
- package/families/paper/typography.ts +17 -0
- package/families/warm/components/AccentGlow.tsx +60 -0
- package/families/warm/components/BentoCell.tsx +56 -0
- package/families/warm/components/BentoGrid.tsx +30 -0
- package/families/warm/components/FilmGrain.tsx +36 -0
- package/families/warm/components/ScaleBlurCounter.tsx +71 -0
- package/families/warm/components/WarmSurface.tsx +35 -0
- package/families/warm/components/index.ts +11 -0
- package/families/warm/index.ts +19 -0
- package/families/warm/palette.ts +81 -0
- package/families/warm/presets/huashu.ts +49 -0
- package/families/warm/presets/mempalace.ts +51 -0
- package/families/warm/typography.ts +17 -0
- package/package.json +85 -0
- package/reference/dark/claudedispatch.tsx +2441 -0
- package/reference/dark/notebooklm.tsx +2316 -0
- package/reference/dark/stitch.tsx +3040 -0
- package/reference/forbidden/heretic.tsx +2636 -0
- package/reference/glass/claudewatch.tsx +3827 -0
- package/reference/glass/graphify.tsx +2418 -0
- package/reference/glass/paperclip.tsx +2218 -0
- package/reference/paper/designreel.tsx +883 -0
- package/reference/paper/justdrop.tsx +1898 -0
- package/reference/paper/opus.tsx +1770 -0
- package/reference/warm/huashu.tsx +3413 -0
- package/reference/warm/mempalace.tsx +2909 -0
- package/skill/SKILL.md +229 -0
- package/skill/commands/reelstack-beats.md +20 -0
- package/skill/commands/reelstack-capture.md +24 -0
- package/skill/commands/reelstack-critique.md +15 -0
- package/skill/commands/reelstack-dark.md +40 -0
- package/skill/commands/reelstack-direction.md +17 -0
- package/skill/commands/reelstack-forbidden.md +25 -0
- package/skill/commands/reelstack-glass.md +39 -0
- package/skill/commands/reelstack-icons.md +22 -0
- package/skill/commands/reelstack-init.md +17 -0
- package/skill/commands/reelstack-lint.md +22 -0
- package/skill/commands/reelstack-paper.md +36 -0
- package/skill/commands/reelstack-render.md +20 -0
- package/skill/commands/reelstack-warm.md +36 -0
- package/templates/dark/template.tsx +115 -0
- package/templates/forbidden/template.tsx +111 -0
- package/templates/glass/template.tsx +201 -0
- package/templates/paper/template.tsx +133 -0
- package/templates/warm/template.tsx +210 -0
- package/utils/ai-purple-blocklist.ts +13 -0
- package/utils/banned-fonts.ts +11 -0
- package/utils/cubic-bezier.ts +36 -0
- package/utils/easing.ts +84 -0
- package/utils/grid.ts +13 -0
- package/utils/render-presets.json +56 -0
- package/utils/safe-zones.tsx +57 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: claudedispatch (Dark Cinematic)
|
|
3
|
+
* Source: ClaudeDispatchReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* Hero-narrative reel with dark forest green card surfaces (#1a2e1f) for
|
|
6
|
+
* embedded UI screenshots. The family's strongest card stack treatment.
|
|
7
|
+
*/
|
|
8
|
+
export const preset = {
|
|
9
|
+
name: "claudedispatch",
|
|
10
|
+
family: "dark",
|
|
11
|
+
source: "ClaudeDispatchReel",
|
|
12
|
+
durationFrames: 2220,
|
|
13
|
+
fps: 30,
|
|
14
|
+
copy: {
|
|
15
|
+
hook: "99% of Claude users don't know this exists.",
|
|
16
|
+
sub: "AI as your dispatching system.",
|
|
17
|
+
cta: "Setup link below.",
|
|
18
|
+
},
|
|
19
|
+
accents: {
|
|
20
|
+
cardForest: "#1a2e1f",
|
|
21
|
+
cardForestLift: "#243a28",
|
|
22
|
+
danger: "#e25822",
|
|
23
|
+
safe: "#4fc46a",
|
|
24
|
+
},
|
|
25
|
+
beats: {
|
|
26
|
+
hook: 0,
|
|
27
|
+
secret: 246,
|
|
28
|
+
dispatching: 600,
|
|
29
|
+
workflow: 990,
|
|
30
|
+
cards: 1230,
|
|
31
|
+
setup: 1560,
|
|
32
|
+
cta: 1875,
|
|
33
|
+
end: 2055,
|
|
34
|
+
final: 2220,
|
|
35
|
+
},
|
|
36
|
+
primitives: [
|
|
37
|
+
"DriftingSpotlights",
|
|
38
|
+
"RadialVignette",
|
|
39
|
+
"SegmentOpacity",
|
|
40
|
+
"Crossfade",
|
|
41
|
+
"GridBackground",
|
|
42
|
+
"ForestCard", // preset-specific — dark green card surface
|
|
43
|
+
],
|
|
44
|
+
notes:
|
|
45
|
+
"ForestCard surfaces (#1a2e1f bg, #243a28 lifted) are the signature element. Use them whenever a UI screenshot or terminal block needs a frame.",
|
|
46
|
+
} as const;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: codedrop (Dark Cinematic)
|
|
3
|
+
* Source: CodeDropReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* Short-form 37s drop reel. First 20s designed as overlay-friendly blank
|
|
6
|
+
* space (user composes screen recordings on top). Final 17s is Claude pitch
|
|
7
|
+
* + CTA.
|
|
8
|
+
*/
|
|
9
|
+
export const preset = {
|
|
10
|
+
name: "codedrop",
|
|
11
|
+
family: "dark",
|
|
12
|
+
source: "CodeDropReel",
|
|
13
|
+
durationFrames: 1110,
|
|
14
|
+
fps: 30,
|
|
15
|
+
copy: {
|
|
16
|
+
hook: "Claude Code just dropped.",
|
|
17
|
+
cta: "For the full tutorial, hit my YouTube.",
|
|
18
|
+
},
|
|
19
|
+
accents: {
|
|
20
|
+
safe: "#4fc46a",
|
|
21
|
+
},
|
|
22
|
+
beats: {
|
|
23
|
+
overlayWindow: 0, // user composes screen rec here
|
|
24
|
+
clausePitch: 600, // Claude Code pitch begins
|
|
25
|
+
feature: 750,
|
|
26
|
+
cta: 930,
|
|
27
|
+
end: 1110,
|
|
28
|
+
},
|
|
29
|
+
primitives: [
|
|
30
|
+
"DriftingSpotlights",
|
|
31
|
+
"RadialVignette",
|
|
32
|
+
"SegmentOpacity",
|
|
33
|
+
"GridBackground",
|
|
34
|
+
],
|
|
35
|
+
notes:
|
|
36
|
+
"Frames 0–600 are intentionally minimal — buyer is expected to composite a screen recording over the top. Do not auto-fill the overlay window with motion graphics; that defeats the preset's purpose.",
|
|
37
|
+
} as const;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: gpt55 (Dark Cinematic)
|
|
3
|
+
* Source: GPT55Reel.tsx
|
|
4
|
+
*
|
|
5
|
+
* Benchmark-thesis reel. OpenAI green dominant. Competitive narrative
|
|
6
|
+
* tone — uses rival purple for "Claude" beats and YouTube red for CTA.
|
|
7
|
+
*/
|
|
8
|
+
export const preset = {
|
|
9
|
+
name: "gpt55",
|
|
10
|
+
family: "dark",
|
|
11
|
+
source: "GPT55Reel",
|
|
12
|
+
durationFrames: 2900,
|
|
13
|
+
fps: 30,
|
|
14
|
+
copy: {
|
|
15
|
+
hook: "GPT 5.5 just dropped. It's a half-step.",
|
|
16
|
+
sub: "Stop chasing benchmarks.",
|
|
17
|
+
cta: "Full thesis on YouTube.",
|
|
18
|
+
},
|
|
19
|
+
accents: {
|
|
20
|
+
openai: "#10a37f",
|
|
21
|
+
openaiSoft: "#1ac997",
|
|
22
|
+
openaiDeep: "#0a6e55",
|
|
23
|
+
rivalPurple: "#6466f1",
|
|
24
|
+
warnAmber: "#fcbb00",
|
|
25
|
+
red: "#ff3b46",
|
|
26
|
+
youtubeRed: "#FF0033",
|
|
27
|
+
},
|
|
28
|
+
beats: {
|
|
29
|
+
hook: 0,
|
|
30
|
+
drop: 180,
|
|
31
|
+
halfStep: 420,
|
|
32
|
+
benchmarks: 600,
|
|
33
|
+
skepticism: 930,
|
|
34
|
+
rivals: 1140,
|
|
35
|
+
ship: 1320,
|
|
36
|
+
workflow: 1560,
|
|
37
|
+
payoff: 1860,
|
|
38
|
+
thesis: 2190,
|
|
39
|
+
cta: 2490,
|
|
40
|
+
end: 2715,
|
|
41
|
+
final: 2900,
|
|
42
|
+
},
|
|
43
|
+
primitives: [
|
|
44
|
+
"DriftingSpotlights",
|
|
45
|
+
"RadialVignette",
|
|
46
|
+
"SegmentOpacity",
|
|
47
|
+
"Crossfade",
|
|
48
|
+
"GridBackground",
|
|
49
|
+
"BenchmarkScreenshot", // preset-specific
|
|
50
|
+
"ForestCard",
|
|
51
|
+
],
|
|
52
|
+
notes:
|
|
53
|
+
"Multi-brand reel: OpenAI green for GPT moments, rival purple for Claude moments, YouTube red exclusively for the CTA. Do not let any of these accents bleed into other scenes.",
|
|
54
|
+
} as const;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: notebooklm (Dark Cinematic)
|
|
3
|
+
* Source: NotebookLMReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* Product-integration narrative (Claude × NotebookLM). NotebookLM blue is
|
|
6
|
+
* the dominant accent. 11 scenes synced to voiceover rhythm.
|
|
7
|
+
*/
|
|
8
|
+
export const preset = {
|
|
9
|
+
name: "notebooklm",
|
|
10
|
+
family: "dark",
|
|
11
|
+
source: "NotebookLMReel",
|
|
12
|
+
durationFrames: 1680,
|
|
13
|
+
fps: 30,
|
|
14
|
+
copy: {
|
|
15
|
+
hook: "Gave Claude infinite memory for zero tokens.",
|
|
16
|
+
sub: "Connect Claude to NotebookLM.",
|
|
17
|
+
cta: "Setup walkthrough below.",
|
|
18
|
+
},
|
|
19
|
+
accents: {
|
|
20
|
+
notebookBlue: "#4F7DF3",
|
|
21
|
+
gold: "#F0C23A",
|
|
22
|
+
danger: "#E8483A",
|
|
23
|
+
success: "#3CCB7F",
|
|
24
|
+
},
|
|
25
|
+
beats: {
|
|
26
|
+
hook: 0,
|
|
27
|
+
memory: 108,
|
|
28
|
+
tokens: 216,
|
|
29
|
+
integration: 396,
|
|
30
|
+
nb: 570,
|
|
31
|
+
semanticSearch: 684,
|
|
32
|
+
wrapup: 864,
|
|
33
|
+
walkthrough: 1056,
|
|
34
|
+
install: 1254,
|
|
35
|
+
config: 1428,
|
|
36
|
+
cta: 1536,
|
|
37
|
+
end: 1677,
|
|
38
|
+
},
|
|
39
|
+
primitives: [
|
|
40
|
+
"DriftingSpotlights",
|
|
41
|
+
"RadialVignette",
|
|
42
|
+
"SegmentOpacity",
|
|
43
|
+
"Crossfade",
|
|
44
|
+
"GridBackground",
|
|
45
|
+
"GlowingUnderline", // preset-specific — animated text underline
|
|
46
|
+
"FilmGrain",
|
|
47
|
+
],
|
|
48
|
+
notes:
|
|
49
|
+
"NotebookLM blue (#4F7DF3) is the signature. Use the gold accent (#F0C23A) sparingly — only for the 'gave infinite memory' beat at frame 108.",
|
|
50
|
+
} as const;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: resourcescta (Dark Cinematic)
|
|
3
|
+
* Source: ResourcesCTAReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* 7-second standalone CTA reel. Used as a footer/outro on Dark Cinematic
|
|
6
|
+
* reels. Generic "Comment AI / Like, Subscribe, check resources" copy.
|
|
7
|
+
*/
|
|
8
|
+
export const preset = {
|
|
9
|
+
name: "resourcescta",
|
|
10
|
+
family: "dark",
|
|
11
|
+
source: "ResourcesCTAReel",
|
|
12
|
+
durationFrames: 210,
|
|
13
|
+
fps: 30,
|
|
14
|
+
copy: {
|
|
15
|
+
hook: "Comment AI for resources.",
|
|
16
|
+
sub: "Like, subscribe.",
|
|
17
|
+
},
|
|
18
|
+
accents: {
|
|
19
|
+
claude: "#D4663A",
|
|
20
|
+
},
|
|
21
|
+
beats: {
|
|
22
|
+
hook: 0,
|
|
23
|
+
button: 60,
|
|
24
|
+
cta: 120,
|
|
25
|
+
end: 210,
|
|
26
|
+
},
|
|
27
|
+
primitives: [
|
|
28
|
+
"DriftingSpotlights",
|
|
29
|
+
"SegmentOpacity",
|
|
30
|
+
"GridBackground",
|
|
31
|
+
"CtaButton",
|
|
32
|
+
],
|
|
33
|
+
notes:
|
|
34
|
+
"Designed to append after another Dark Cinematic reel. Frame budget is 7 seconds — keep motion floor at 3+ layers using concurrent (not sequenced) animations.",
|
|
35
|
+
} as const;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: skills (Dark Cinematic)
|
|
3
|
+
* Source: SkillsReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* Ecosystem-showcase reel. Category bento grid (UI Design, App Testing, SEO,
|
|
6
|
+
* Writing, Debugging, Deploy) + platforms (Claude Code, Codex, Desktop App,
|
|
7
|
+
* Any Editor). Lightweight motion compared to the rest of Dark Cinematic.
|
|
8
|
+
*/
|
|
9
|
+
export const preset = {
|
|
10
|
+
name: "skills",
|
|
11
|
+
family: "dark",
|
|
12
|
+
source: "SkillsReel",
|
|
13
|
+
durationFrames: 1260,
|
|
14
|
+
fps: 30,
|
|
15
|
+
copy: {
|
|
16
|
+
hook: "AI superpowers live in the skills, not the model.",
|
|
17
|
+
sub: "1000+ free Claude Code skills.",
|
|
18
|
+
cta: "Find one that fits below.",
|
|
19
|
+
},
|
|
20
|
+
accents: {},
|
|
21
|
+
beats: {
|
|
22
|
+
hook: 0,
|
|
23
|
+
thesis: 165,
|
|
24
|
+
categories: 330,
|
|
25
|
+
platforms: 525,
|
|
26
|
+
examples: 690,
|
|
27
|
+
install: 855,
|
|
28
|
+
cta: 1035,
|
|
29
|
+
end: 1260,
|
|
30
|
+
},
|
|
31
|
+
primitives: [
|
|
32
|
+
"DriftingSpotlights",
|
|
33
|
+
"RadialVignette",
|
|
34
|
+
"SegmentOpacity",
|
|
35
|
+
"GridBackground",
|
|
36
|
+
"BentoGrid", // preset-specific — category × platform matrix
|
|
37
|
+
],
|
|
38
|
+
notes:
|
|
39
|
+
"Bento grid is the signature. Each cell carries a category icon (no emojis — pull via /reelstack-icons logos:<brand>) and a platform label. Use staggered reveals with 4-frame offsets between cells.",
|
|
40
|
+
} as const;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: stitch (Dark Cinematic)
|
|
3
|
+
* Source: StitchReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* Cross-product workflow demo. Stitch rose accent + Gemini blue + Claude
|
|
6
|
+
* terracotta in the same reel — Dark Cinematic's multi-brand allowance is
|
|
7
|
+
* on full display.
|
|
8
|
+
*/
|
|
9
|
+
export const preset = {
|
|
10
|
+
name: "stitch",
|
|
11
|
+
family: "dark",
|
|
12
|
+
source: "StitchReel",
|
|
13
|
+
durationFrames: 2297,
|
|
14
|
+
fps: 30,
|
|
15
|
+
copy: {
|
|
16
|
+
hook: "Stitch connects your entire Claude workflow.",
|
|
17
|
+
sub: "AI agents as you. Unlocked.",
|
|
18
|
+
cta: "Free during beta.",
|
|
19
|
+
},
|
|
20
|
+
accents: {
|
|
21
|
+
stitch: "#ff4d9b",
|
|
22
|
+
gemini: "#4285f4",
|
|
23
|
+
safe: "#4fc46a",
|
|
24
|
+
},
|
|
25
|
+
beats: {
|
|
26
|
+
hook: 0,
|
|
27
|
+
nameDrop: 249,
|
|
28
|
+
workflow: 438,
|
|
29
|
+
agents: 678,
|
|
30
|
+
unlocked: 915,
|
|
31
|
+
demo: 1320,
|
|
32
|
+
palette: 1560,
|
|
33
|
+
cta: 2025,
|
|
34
|
+
end: 2297,
|
|
35
|
+
},
|
|
36
|
+
primitives: [
|
|
37
|
+
"DriftingSpotlights",
|
|
38
|
+
"RadialVignette",
|
|
39
|
+
"SegmentOpacity",
|
|
40
|
+
"Crossfade",
|
|
41
|
+
"GridBackground",
|
|
42
|
+
"PaletteChips", // preset-specific — palette legend on screen
|
|
43
|
+
],
|
|
44
|
+
notes:
|
|
45
|
+
"Stitch reel is the family's reference for multi-brand accent usage. Crossfades 0.45s in / 0.55s out. Palette chip legend appears in the demo scene as a credibility signal.",
|
|
46
|
+
} as const;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: stitch2 (Dark Cinematic)
|
|
3
|
+
* Source: Stitch2Reel.tsx
|
|
4
|
+
*
|
|
5
|
+
* 20-second teaser variant. Letterboxed hero video (2304×1440 landscape
|
|
6
|
+
* scaled to 1080×675), title fade + lift, with safe zones at 288px top /
|
|
7
|
+
* 422px bottom offset.
|
|
8
|
+
*/
|
|
9
|
+
export const preset = {
|
|
10
|
+
name: "stitch2",
|
|
11
|
+
family: "dark",
|
|
12
|
+
source: "Stitch2Reel",
|
|
13
|
+
durationFrames: 600,
|
|
14
|
+
fps: 30,
|
|
15
|
+
copy: {
|
|
16
|
+
hook: "Stitch.",
|
|
17
|
+
sub: "Workflow agents. Beta open.",
|
|
18
|
+
},
|
|
19
|
+
accents: {
|
|
20
|
+
stitch: "#ff4d9b",
|
|
21
|
+
},
|
|
22
|
+
beats: {
|
|
23
|
+
clipIn: 0,
|
|
24
|
+
titleIn: 90,
|
|
25
|
+
titleLift: 360,
|
|
26
|
+
cta: 510,
|
|
27
|
+
end: 600,
|
|
28
|
+
},
|
|
29
|
+
primitives: [
|
|
30
|
+
"DriftingSpotlights",
|
|
31
|
+
"RadialVignette",
|
|
32
|
+
"SegmentOpacity",
|
|
33
|
+
"OffthreadVideoLetterbox",
|
|
34
|
+
],
|
|
35
|
+
embeddedClip: {
|
|
36
|
+
path: "captures/stitch/hero.mp4",
|
|
37
|
+
sequenceStart: 0,
|
|
38
|
+
durationFrames: 600,
|
|
39
|
+
aspect: "letterbox",
|
|
40
|
+
},
|
|
41
|
+
notes:
|
|
42
|
+
"Use this preset when you have a clip and need a 20s teaser without composing a full motion-graphics narrative. Title lifts from baseline at frame 360.",
|
|
43
|
+
} as const;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Dark Cinematic typography scale. Geist Sans + Geist Mono only.
|
|
2
|
+
* Pulled from existing template usage (StitchReel / CodeDropReel hero 84);
|
|
3
|
+
* locks the implicit scale into named tokens. Text colors come from palette
|
|
4
|
+
* (fg / fgSoft / fgMuted) — never embed colors in typography tokens.
|
|
5
|
+
*/
|
|
6
|
+
export const typography = {
|
|
7
|
+
hero: { fontSize: 96, fontWeight: 700, letterSpacing: -2, lineHeight: 1.05, fontFamily: "Geist, system-ui" },
|
|
8
|
+
h1: { fontSize: 84, fontWeight: 700, letterSpacing: -1.5, lineHeight: 1.1, fontFamily: "Geist, system-ui" },
|
|
9
|
+
h2: { fontSize: 56, fontWeight: 700, letterSpacing: -1.5, lineHeight: 1.15, fontFamily: "Geist, system-ui" },
|
|
10
|
+
h3: { fontSize: 36, fontWeight: 600, letterSpacing: -1, lineHeight: 1.2, fontFamily: "Geist, system-ui" },
|
|
11
|
+
body: { fontSize: 24, fontWeight: 500, letterSpacing: -0.2, lineHeight: 1.5, fontFamily: "Geist, system-ui" },
|
|
12
|
+
caption: { fontSize: 18, fontWeight: 500, letterSpacing: 0.5, lineHeight: 1.4, fontFamily: "Geist, system-ui", textTransform: "uppercase" as const },
|
|
13
|
+
mono: { fontSize: 22, fontWeight: 500, letterSpacing: 0.3, lineHeight: 1.4, fontFamily: "Geist Mono, monospace" },
|
|
14
|
+
counter: { fontSize: 144, fontWeight: 700, letterSpacing: -2, lineHeight: 1, fontFamily: "Geist Mono, monospace" },
|
|
15
|
+
} as const;
|
|
16
|
+
export type Typography = typeof typography;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AbsoluteFill, useCurrentFrame } from "remotion";
|
|
3
|
+
import { palette, gradients } from "../palette";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ForbiddenCausticBlobs — animated radial gradients drifting on sine paths.
|
|
7
|
+
*
|
|
8
|
+
* Forbidden's signature background motion. Same shape as Glass's CausticBlobs
|
|
9
|
+
* but with two key differences:
|
|
10
|
+
* 1. Stops are ember/crimson/ultraviolet/plasma (NEVER gold — gold belongs
|
|
11
|
+
* to Glass).
|
|
12
|
+
* 2. mixBlendMode is `multiply` (not `screen`) so the blobs darken the
|
|
13
|
+
* cream-rose paper into deeper rose tones instead of brightening it.
|
|
14
|
+
*
|
|
15
|
+
* Frame-budget: cheap. 4 absolutely-positioned divs with CSS gradients only.
|
|
16
|
+
*/
|
|
17
|
+
export const ForbiddenCausticBlobs: React.FC<{
|
|
18
|
+
intensity?: number; // 0..1 — overall opacity multiplier
|
|
19
|
+
reduceMotion?: boolean;
|
|
20
|
+
}> = ({ intensity = 1, reduceMotion = false }) => {
|
|
21
|
+
const frame = useCurrentFrame();
|
|
22
|
+
const blobs = [
|
|
23
|
+
{ gradient: gradients.causticEmber, speedX: 0.0040, speedY: 0.0030, size: 1100 },
|
|
24
|
+
{ gradient: gradients.causticCrimson, speedX: 0.0033, speedY: 0.0042, size: 1100 },
|
|
25
|
+
{ gradient: gradients.causticUltraviolet, speedX: 0.0027, speedY: 0.0035, size: 1100 },
|
|
26
|
+
{ gradient: gradients.causticPlasma, speedX: 0.0046, speedY: 0.0024, size: 1100 },
|
|
27
|
+
];
|
|
28
|
+
return (
|
|
29
|
+
<AbsoluteFill style={{ background: palette.bg, opacity: intensity }}>
|
|
30
|
+
{blobs.map((b, i) => {
|
|
31
|
+
const cx = reduceMotion ? 0.5 : 0.5 + 0.35 * Math.sin(frame * b.speedX + i);
|
|
32
|
+
const cy = reduceMotion ? 0.5 : 0.5 + 0.30 * Math.cos(frame * b.speedY + i * 1.3);
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
key={i}
|
|
36
|
+
style={{
|
|
37
|
+
position: "absolute",
|
|
38
|
+
left: `${cx * 100 - 50}%`,
|
|
39
|
+
top: `${cy * 100 - 50}%`,
|
|
40
|
+
width: b.size,
|
|
41
|
+
height: b.size,
|
|
42
|
+
background: b.gradient,
|
|
43
|
+
filter: "blur(60px)",
|
|
44
|
+
mixBlendMode: "multiply",
|
|
45
|
+
pointerEvents: "none",
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
})}
|
|
50
|
+
</AbsoluteFill>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AbsoluteFill } from "remotion";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Brutalist Swiss Industrial newsprint texture — opt-in for Forbidden reels.
|
|
6
|
+
* Pure SVG turbulence for a halftone/grain effect on cream-rose paper.
|
|
7
|
+
* Inspired by leonxlnx/taste-skill-brutalist's Swiss Industrial Print mode.
|
|
8
|
+
*/
|
|
9
|
+
export const NewsprintTexture: React.FC<{
|
|
10
|
+
opacity?: number;
|
|
11
|
+
reduceMotion?: boolean;
|
|
12
|
+
}> = ({ opacity = 0.08, reduceMotion: _r = false }) => {
|
|
13
|
+
// Newsprint is texture-only; no motion to reduce. The reduceMotion prop is
|
|
14
|
+
// accepted for API consistency.
|
|
15
|
+
return (
|
|
16
|
+
<AbsoluteFill style={{ pointerEvents: "none", opacity, mixBlendMode: "multiply" }}>
|
|
17
|
+
<svg width="100%" height="100%">
|
|
18
|
+
<filter id="reelstack-newsprint">
|
|
19
|
+
<feTurbulence type="fractalNoise" baseFrequency="0.85" numOctaves="3" seed="2" />
|
|
20
|
+
<feColorMatrix
|
|
21
|
+
values="0 0 0 0 0.45 0 0 0 0 0.30 0 0 0 0 0.40 0 0 0 0.6 0"
|
|
22
|
+
/>
|
|
23
|
+
</filter>
|
|
24
|
+
<rect width="100%" height="100%" filter="url(#reelstack-newsprint)" />
|
|
25
|
+
</svg>
|
|
26
|
+
</AbsoluteFill>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import { palette } from "../palette";
|
|
3
|
+
|
|
4
|
+
type Depth = "soft" | "mid" | "deep";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* tintedShadow — helper that returns a `{ boxShadow }` style object using the
|
|
8
|
+
* Forbidden palette's rose-purple shadow stack (rgba(120,80,120,…)).
|
|
9
|
+
*
|
|
10
|
+
* Spread it into another component's style prop to inherit the family's
|
|
11
|
+
* tinted-shadow signature without wrapping in an extra div:
|
|
12
|
+
* <GlassCard style={{ ...tintedShadow("deep"), padding: 36 }}>...</GlassCard>
|
|
13
|
+
*/
|
|
14
|
+
export const tintedShadow = (depth: Depth = "mid"): CSSProperties => ({
|
|
15
|
+
boxShadow:
|
|
16
|
+
depth === "soft" ? palette.shadowSoft :
|
|
17
|
+
depth === "deep" ? palette.shadowDeep :
|
|
18
|
+
palette.shadowMid,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* TintedShadow — wrapper component that applies the matching Forbidden
|
|
23
|
+
* rose-purple shadow to its children. Use when JSX composition is cleaner
|
|
24
|
+
* than spreading the helper into an existing style prop.
|
|
25
|
+
*
|
|
26
|
+
* The Forbidden family's secret weapon: every shadow is rose-purple, never
|
|
27
|
+
* pure black. Pure-black shadows on cream-rose paper read as cheap and
|
|
28
|
+
* generic — the tinted variant reads as printed dye.
|
|
29
|
+
*/
|
|
30
|
+
export const TintedShadow: React.FC<{
|
|
31
|
+
depth?: Depth;
|
|
32
|
+
style?: CSSProperties;
|
|
33
|
+
children?: ReactNode;
|
|
34
|
+
}> = ({ depth = "mid", style, children }) => (
|
|
35
|
+
<div style={{ ...tintedShadow(depth), ...style }}>{children}</div>
|
|
36
|
+
);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forbidden — primitive components index.
|
|
3
|
+
*
|
|
4
|
+
* Forbidden inherits most primitives from Glass (they accept palette-agnostic
|
|
5
|
+
* props) and overrides only what truly differs:
|
|
6
|
+
* - ForbiddenCausticBlobs replaces Glass's CausticBlobs (multiply blend,
|
|
7
|
+
* ember/crimson/ultraviolet/plasma stops — never gold)
|
|
8
|
+
* - TintedShadow + tintedShadow() add the family's rose-purple shadow stack
|
|
9
|
+
*
|
|
10
|
+
* Scaffold templates import from here:
|
|
11
|
+
* import { CausticBlobs, GlassCard, TintedShadow, tintedShadow }
|
|
12
|
+
* from "@devinilabs/reelstack/families/forbidden/components";
|
|
13
|
+
*
|
|
14
|
+
* `CausticBlobs` is aliased to ForbiddenCausticBlobs so a buyer never has to
|
|
15
|
+
* remember which family's variant they're using — it's always the right one
|
|
16
|
+
* for the family they imported from.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Forbidden-specific
|
|
20
|
+
export { ForbiddenCausticBlobs } from "./ForbiddenCausticBlobs";
|
|
21
|
+
export { TintedShadow, tintedShadow } from "./TintedShadow";
|
|
22
|
+
|
|
23
|
+
// Inherited from Glass — these primitives are palette-agnostic.
|
|
24
|
+
export {
|
|
25
|
+
HairlineGrid,
|
|
26
|
+
GlassCard,
|
|
27
|
+
EyebrowPill,
|
|
28
|
+
StaggeredWords,
|
|
29
|
+
Counter,
|
|
30
|
+
SonarRings,
|
|
31
|
+
ParticleBurst,
|
|
32
|
+
FloatingGlyphs,
|
|
33
|
+
LightBeam,
|
|
34
|
+
} from "../../glass/components";
|
|
35
|
+
|
|
36
|
+
// Renamed: Forbidden's caustics replace Glass's at the family-canonical name.
|
|
37
|
+
export { ForbiddenCausticBlobs as CausticBlobs } from "./ForbiddenCausticBlobs";
|
|
38
|
+
export { NewsprintTexture } from "./NewsprintTexture";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forbidden — family index.
|
|
3
|
+
*/
|
|
4
|
+
export { palette, safeZones, gradients } from "./palette";
|
|
5
|
+
export type { ForbiddenPalette } from "./palette";
|
|
6
|
+
|
|
7
|
+
import { preset as heretic } from "./presets/heretic";
|
|
8
|
+
|
|
9
|
+
export const presets = {
|
|
10
|
+
heretic,
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export const family = {
|
|
14
|
+
name: "forbidden",
|
|
15
|
+
label: "Forbidden",
|
|
16
|
+
presets: Object.keys(presets) as Array<keyof typeof presets>,
|
|
17
|
+
} as const;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReelStack — Forbidden palette
|
|
3
|
+
*
|
|
4
|
+
* Verified against /Users/abhishekraj/my-video/src/HereticReel.tsx.
|
|
5
|
+
*
|
|
6
|
+
* Mood: forbidden, mysterious, slightly off-kilter. Desaturated palette
|
|
7
|
+
* suggests something declassified.
|
|
8
|
+
*
|
|
9
|
+
* Inherits primitives from Glass family but with rose-purple tinted shadows
|
|
10
|
+
* for the cream-rose paper background. NEVER use iridescent gold here —
|
|
11
|
+
* that hue belongs to Glass.
|
|
12
|
+
*/
|
|
13
|
+
export const palette = {
|
|
14
|
+
// Backgrounds — cream-rose paper
|
|
15
|
+
bg: "#F2EBE5",
|
|
16
|
+
bgWarm: "#EFE3DB",
|
|
17
|
+
bgCool: "#ECE6E8",
|
|
18
|
+
|
|
19
|
+
// Ink (slightly darker than Glass to read on rose-cream)
|
|
20
|
+
ink: "#0E0B12", // contrast 17.6:1 on bg #F2EBE5 — WCAG AAA
|
|
21
|
+
inkSoft: "#26222A", // contrast 13.0:1 on bg #F2EBE5 — WCAG AAA
|
|
22
|
+
inkMuted: "#5A5560", // contrast 6.8:1 on bg #F2EBE5 — WCAG AA
|
|
23
|
+
inkDim: "#8A848F", // contrast 3.5:1 on bg #F2EBE5 — WCAG AA-Large
|
|
24
|
+
|
|
25
|
+
// Forbidden accents — desaturated, mysterious
|
|
26
|
+
ember: "#D97757", // burning orange
|
|
27
|
+
crimson: "#C4506B", // deep rose / refusal
|
|
28
|
+
ultraviolet: "#6B5BD9", // nightshade / mechanism
|
|
29
|
+
plasma: "#A87FE8", // electric violet / stars
|
|
30
|
+
|
|
31
|
+
// Tinted shadows — the family's secret weapon. Never use pure black.
|
|
32
|
+
shadowSoft: "rgba(120, 80, 120, 0.10)",
|
|
33
|
+
shadowMid: "rgba(120, 80, 120, 0.18)",
|
|
34
|
+
shadowDeep: "rgba(120, 80, 120, 0.28)",
|
|
35
|
+
|
|
36
|
+
// Glass surface tokens (warmer than Glass family — rose-tinted whites)
|
|
37
|
+
glassFill: "rgba(255, 248, 245, 0.46)",
|
|
38
|
+
glassFillStrong: "rgba(255, 248, 245, 0.66)",
|
|
39
|
+
glassBorder: "rgba(255, 248, 245, 0.88)",
|
|
40
|
+
|
|
41
|
+
// Macro-window dots
|
|
42
|
+
macClose: "#FF5F57",
|
|
43
|
+
macMin: "#FEBC2E",
|
|
44
|
+
macMax: "#28C840",
|
|
45
|
+
} as const;
|
|
46
|
+
|
|
47
|
+
export const safeZones = {
|
|
48
|
+
top: 290,
|
|
49
|
+
bottom: 1500,
|
|
50
|
+
canvas: { width: 1080, height: 1920 },
|
|
51
|
+
} as const;
|
|
52
|
+
|
|
53
|
+
export const gradients = {
|
|
54
|
+
forbidden: `linear-gradient(135deg, ${palette.ember} 0%, ${palette.crimson} 33%, ${palette.ultraviolet} 66%, ${palette.plasma} 100%)`,
|
|
55
|
+
causticEmber: `radial-gradient(ellipse, ${palette.ember}55 0%, transparent 60%)`,
|
|
56
|
+
causticCrimson: `radial-gradient(ellipse, ${palette.crimson}55 0%, transparent 60%)`,
|
|
57
|
+
causticUltraviolet: `radial-gradient(ellipse, ${palette.ultraviolet}55 0%, transparent 60%)`,
|
|
58
|
+
causticPlasma: `radial-gradient(ellipse, ${palette.plasma}55 0%, transparent 60%)`,
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Hard-coded "allowed accents" list. The lint command checks every fill /
|
|
63
|
+
* stroke / background color in a Forbidden reel against this set. Note that
|
|
64
|
+
* ultraviolet (#6B5BD9) and plasma (#A87FE8) are family-specific overrides
|
|
65
|
+
* — they would otherwise be flagged by the AI-purple blocklist. Inside
|
|
66
|
+
* Forbidden they are allowed; nowhere else in ReelStack are they permitted.
|
|
67
|
+
*/
|
|
68
|
+
export const ALLOWED_ACCENTS = [
|
|
69
|
+
palette.ink,
|
|
70
|
+
palette.ember,
|
|
71
|
+
palette.crimson,
|
|
72
|
+
palette.ultraviolet,
|
|
73
|
+
palette.plasma,
|
|
74
|
+
] as const;
|
|
75
|
+
|
|
76
|
+
export type ForbiddenPalette = typeof palette;
|
|
77
|
+
|
|
78
|
+
/** Re-export grid units so consumers can pull them from the family entrypoint. */
|
|
79
|
+
export {
|
|
80
|
+
GRID,
|
|
81
|
+
GRID_2,
|
|
82
|
+
GRID_4,
|
|
83
|
+
GRID_6,
|
|
84
|
+
GRID_8,
|
|
85
|
+
GRID_12,
|
|
86
|
+
GRID_16,
|
|
87
|
+
GRID_24,
|
|
88
|
+
} from "../../utils/grid";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset: heretic (Forbidden)
|
|
3
|
+
* Source: HereticReel.tsx
|
|
4
|
+
*
|
|
5
|
+
* The reference (and only) preset for the Forbidden family. Cream-rose
|
|
6
|
+
* paper background, forbidden palette stops (ember, crimson, ultraviolet,
|
|
7
|
+
* plasma). Inherits Glass primitives but with rose-purple tinted shadows.
|
|
8
|
+
*/
|
|
9
|
+
export const preset = {
|
|
10
|
+
name: "heretic",
|
|
11
|
+
family: "forbidden",
|
|
12
|
+
source: "HereticReel",
|
|
13
|
+
durationFrames: 1639,
|
|
14
|
+
fps: 30,
|
|
15
|
+
copy: {
|
|
16
|
+
hook: "Strip the censorship right out of any open source AI.",
|
|
17
|
+
sub: "It's called Heretic.",
|
|
18
|
+
cta: "GitHub link below.",
|
|
19
|
+
},
|
|
20
|
+
accents: {},
|
|
21
|
+
beats: {
|
|
22
|
+
hook: 0,
|
|
23
|
+
declassified: 144,
|
|
24
|
+
method: 386,
|
|
25
|
+
naming: 716,
|
|
26
|
+
refusal: 961,
|
|
27
|
+
install: 1219,
|
|
28
|
+
cta: 1500,
|
|
29
|
+
end: 1639,
|
|
30
|
+
},
|
|
31
|
+
primitives: [
|
|
32
|
+
"CausticBlobs", // forbidden palette variant
|
|
33
|
+
"HairlineGrid",
|
|
34
|
+
"GlassCard", // tinted shadows (rose-purple) for cream bg
|
|
35
|
+
"EyebrowPill",
|
|
36
|
+
"StaggeredWords",
|
|
37
|
+
"SonarRings",
|
|
38
|
+
"ParticleBurst",
|
|
39
|
+
"FloatingGlyphs",
|
|
40
|
+
"TintedShadow", // preset-specific — rgba(120,80,120,…) shadow stack
|
|
41
|
+
],
|
|
42
|
+
notes:
|
|
43
|
+
"Caustic blobs use ember/crimson/ultraviolet/plasma stops — never gold (gold belongs to Glass). Tinted shadows are the family's secret weapon: every shadow uses rose-purple tint, never pure black.",
|
|
44
|
+
} as const;
|