@vibecuting/video-project-core 0.1.26 → 0.1.28

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.
Files changed (266) hide show
  1. package/package.json +4 -4
  2. package/src/base/BaseRemotionScene.tsx +4 -3
  3. package/src/core/index.test.ts +40 -0
  4. package/src/core/intro/_shared/intro-layout.test.ts +18 -0
  5. package/src/core/intro/_shared/intro-layout.ts +50 -0
  6. package/src/core/intro/cyberpunk-intro-holo/default-cyberpunk-intro-bumper-Horizontal.tsx +25 -0
  7. package/src/core/intro/cyberpunk-intro-holo/default-cyberpunk-intro-bumper-Landscape.tsx +25 -0
  8. package/src/core/intro/cyberpunk-intro-holo/default-cyberpunk-intro-bumper.stories.tsx +31 -0
  9. package/src/core/intro/cyberpunk-intro-holo/default-cyberpunk-intro-bumper.tsx +118 -0
  10. package/src/core/intro/cyberpunk-intro-holo/index.ts +11 -0
  11. package/src/core/intro/cyberpunk-intro-neon/default-cyberpunk-intro-bumper-Horizontal.tsx +24 -0
  12. package/src/core/intro/cyberpunk-intro-neon/default-cyberpunk-intro-bumper-Landscape.tsx +24 -0
  13. package/src/core/intro/cyberpunk-intro-neon/default-cyberpunk-intro-bumper.stories.tsx +30 -0
  14. package/src/core/intro/cyberpunk-intro-neon/default-cyberpunk-intro-bumper.tsx +108 -0
  15. package/src/core/intro/cyberpunk-intro-neon/index.ts +10 -0
  16. package/src/core/intro/default-cinematic-intro-bumper/default-cinematic-intro-bumper-Horizontal.tsx +24 -0
  17. package/src/core/intro/default-cinematic-intro-bumper/default-cinematic-intro-bumper-Landscape.tsx +24 -0
  18. package/src/core/intro/default-cinematic-intro-bumper/default-cinematic-intro-bumper.stories.tsx +29 -0
  19. package/src/core/intro/default-cinematic-intro-bumper/default-cinematic-intro-bumper.tsx +234 -0
  20. package/src/core/intro/default-cinematic-intro-bumper/index.ts +11 -0
  21. package/src/core/intro/default-festival-intro-bumper/default-festival-intro-bumper-Horizontal.tsx +24 -0
  22. package/src/core/intro/default-festival-intro-bumper/default-festival-intro-bumper-Landscape.tsx +24 -0
  23. package/src/core/intro/default-festival-intro-bumper/default-festival-intro-bumper.stories.tsx +29 -0
  24. package/src/core/intro/default-festival-intro-bumper/default-festival-intro-bumper.tsx +187 -0
  25. package/src/core/intro/default-festival-intro-bumper/index.ts +11 -0
  26. package/src/core/intro/default-intro-bumper/default-intro-bumper-Horizontal.tsx +24 -0
  27. package/src/core/intro/default-intro-bumper/default-intro-bumper-Landscape.tsx +24 -0
  28. package/src/core/intro/default-intro-bumper/default-intro-bumper.stories.tsx +41 -0
  29. package/src/core/intro/default-intro-bumper/default-intro-bumper.tsx +256 -0
  30. package/src/core/intro/default-intro-bumper/index.ts +11 -0
  31. package/src/core/intro/default-noir-intro-bumper/default-noir-intro-bumper-Horizontal.tsx +24 -0
  32. package/src/core/intro/default-noir-intro-bumper/default-noir-intro-bumper-Landscape.tsx +24 -0
  33. package/src/core/intro/default-noir-intro-bumper/default-noir-intro-bumper.stories.tsx +29 -0
  34. package/src/core/intro/default-noir-intro-bumper/default-noir-intro-bumper.tsx +122 -0
  35. package/src/core/intro/default-noir-intro-bumper/index.ts +11 -0
  36. package/src/core/intro/default-trailer-intro-bumper/default-trailer-intro-bumper-Horizontal.tsx +24 -0
  37. package/src/core/intro/default-trailer-intro-bumper/default-trailer-intro-bumper-Landscape.tsx +24 -0
  38. package/src/core/intro/default-trailer-intro-bumper/default-trailer-intro-bumper.stories.tsx +29 -0
  39. package/src/core/intro/default-trailer-intro-bumper/default-trailer-intro-bumper.tsx +181 -0
  40. package/src/core/intro/default-trailer-intro-bumper/index.ts +11 -0
  41. package/src/core/intro/documentary-intro-observation/default-documentary-intro-bumper-Horizontal.tsx +18 -0
  42. package/src/core/intro/documentary-intro-observation/default-documentary-intro-bumper-Landscape.tsx +18 -0
  43. package/src/core/intro/documentary-intro-observation/default-documentary-intro-bumper.stories.tsx +31 -0
  44. package/src/core/intro/documentary-intro-observation/default-documentary-intro-bumper.tsx +158 -0
  45. package/src/core/intro/documentary-intro-observation/index.ts +10 -0
  46. package/src/core/intro/family-intro-reunion/default-family-intro-bumper-Horizontal.tsx +18 -0
  47. package/src/core/intro/family-intro-reunion/default-family-intro-bumper-Landscape.tsx +18 -0
  48. package/src/core/intro/family-intro-reunion/default-family-intro-bumper.stories.tsx +43 -0
  49. package/src/core/intro/family-intro-reunion/default-family-intro-bumper.tsx +165 -0
  50. package/src/core/intro/family-intro-reunion/index.ts +10 -0
  51. package/src/core/intro/festival-intro-spotlight/default-festival-intro-bumper-Horizontal.tsx +1 -0
  52. package/src/core/intro/festival-intro-spotlight/default-festival-intro-bumper-Landscape.tsx +1 -0
  53. package/src/core/intro/festival-intro-spotlight/default-festival-intro-bumper.stories.tsx +30 -0
  54. package/src/core/intro/festival-intro-spotlight/default-festival-intro-bumper.tsx +105 -0
  55. package/src/core/intro/festival-intro-spotlight/index.ts +10 -0
  56. package/src/core/intro/index.test.ts +45 -0
  57. package/src/core/intro/index.ts +17 -0
  58. package/src/core/intro/noir-intro-city/default-noir-intro-bumper-Horizontal.tsx +24 -0
  59. package/src/core/intro/noir-intro-city/default-noir-intro-bumper-Landscape.tsx +24 -0
  60. package/src/core/intro/noir-intro-city/default-noir-intro-bumper.stories.tsx +31 -0
  61. package/src/core/intro/noir-intro-city/default-noir-intro-bumper.tsx +96 -0
  62. package/src/core/intro/noir-intro-city/index.ts +10 -0
  63. package/src/core/intro/noir-intro-deluxe/default-noir-intro-bumper-Horizontal.tsx +1 -0
  64. package/src/core/intro/noir-intro-deluxe/default-noir-intro-bumper-Landscape.tsx +1 -0
  65. package/src/core/intro/noir-intro-deluxe/default-noir-intro-bumper.stories.tsx +31 -0
  66. package/src/core/intro/noir-intro-deluxe/default-noir-intro-bumper.tsx +117 -0
  67. package/src/core/intro/noir-intro-deluxe/index.ts +10 -0
  68. package/src/core/intro/sci-fi-intro/default-sci-fi-intro-bumper-Horizontal.tsx +1 -0
  69. package/src/core/intro/sci-fi-intro/default-sci-fi-intro-bumper-Landscape.tsx +1 -0
  70. package/src/core/intro/sci-fi-intro/default-sci-fi-intro-bumper.stories.tsx +48 -0
  71. package/src/core/intro/sci-fi-intro/default-sci-fi-intro-bumper.tsx +105 -0
  72. package/src/core/intro/sci-fi-intro/index.ts +10 -0
  73. package/src/core/intro/thriller-intro-suspense/default-thriller-intro-bumper-Horizontal.tsx +18 -0
  74. package/src/core/intro/thriller-intro-suspense/default-thriller-intro-bumper-Landscape.tsx +18 -0
  75. package/src/core/intro/thriller-intro-suspense/default-thriller-intro-bumper.stories.tsx +31 -0
  76. package/src/core/intro/thriller-intro-suspense/default-thriller-intro-bumper.tsx +155 -0
  77. package/src/core/intro/thriller-intro-suspense/index.ts +10 -0
  78. package/src/core/intro/trailer-intro-premiere/default-trailer-intro-bumper-Horizontal.tsx +1 -0
  79. package/src/core/intro/trailer-intro-premiere/default-trailer-intro-bumper-Landscape.tsx +1 -0
  80. package/src/core/intro/trailer-intro-premiere/default-trailer-intro-bumper.stories.tsx +30 -0
  81. package/src/core/intro/trailer-intro-premiere/default-trailer-intro-bumper.tsx +104 -0
  82. package/src/core/intro/trailer-intro-premiere/index.ts +10 -0
  83. package/src/core/intro/travel-intro-journey/default-travel-intro-bumper-Horizontal.tsx +18 -0
  84. package/src/core/intro/travel-intro-journey/default-travel-intro-bumper-Landscape.tsx +18 -0
  85. package/src/core/intro/travel-intro-journey/default-travel-intro-bumper.stories.tsx +43 -0
  86. package/src/core/intro/travel-intro-journey/default-travel-intro-bumper.tsx +158 -0
  87. package/src/core/intro/travel-intro-journey/index.ts +10 -0
  88. package/src/core/intro/western-intro/default-western-intro-bumper-Horizontal.tsx +24 -0
  89. package/src/core/intro/western-intro/default-western-intro-bumper-Landscape.tsx +24 -0
  90. package/src/core/intro/western-intro/default-western-intro-bumper.stories.tsx +29 -0
  91. package/src/core/intro/western-intro/default-western-intro-bumper.tsx +146 -0
  92. package/src/core/intro/western-intro/index.ts +4 -0
  93. package/src/core/intro/western-intro-gangster/default-western-intro-bumper-Horizontal.tsx +25 -0
  94. package/src/core/intro/western-intro-gangster/default-western-intro-bumper-Landscape.tsx +25 -0
  95. package/src/core/intro/western-intro-gangster/default-western-intro-bumper.stories.tsx +31 -0
  96. package/src/core/intro/western-intro-gangster/default-western-intro-bumper.tsx +105 -0
  97. package/src/core/intro/western-intro-gangster/index.ts +11 -0
  98. package/src/core/outro/_shared/outro-layout.test.ts +32 -0
  99. package/src/core/outro/_shared/outro-layout.ts +72 -0
  100. package/src/core/outro/award-outro-celebration/default-award-outro-bumper-Horizontal.tsx +18 -0
  101. package/src/core/outro/award-outro-celebration/default-award-outro-bumper-Landscape.tsx +18 -0
  102. package/src/core/outro/award-outro-celebration/default-award-outro-bumper.stories.tsx +42 -0
  103. package/src/core/outro/award-outro-celebration/default-award-outro-bumper.tsx +152 -0
  104. package/src/core/outro/award-outro-celebration/index.ts +10 -0
  105. package/src/core/outro/blackout-outro-finale/default-blackout-outro-bumper-Horizontal.tsx +1 -0
  106. package/src/core/outro/blackout-outro-finale/default-blackout-outro-bumper-Landscape.tsx +1 -0
  107. package/src/core/outro/blackout-outro-finale/default-blackout-outro-bumper.stories.tsx +28 -0
  108. package/src/core/outro/blackout-outro-finale/default-blackout-outro-bumper.tsx +71 -0
  109. package/src/core/outro/blackout-outro-finale/index.ts +10 -0
  110. package/src/core/outro/credits-roll-outro-epic/default-credits-roll-outro-Horizontal.tsx +24 -0
  111. package/src/core/outro/credits-roll-outro-epic/default-credits-roll-outro-Landscape.tsx +24 -0
  112. package/src/core/outro/credits-roll-outro-epic/default-credits-roll-outro.stories.tsx +31 -0
  113. package/src/core/outro/credits-roll-outro-epic/default-credits-roll-outro.tsx +106 -0
  114. package/src/core/outro/credits-roll-outro-epic/index.ts +10 -0
  115. package/src/core/outro/credits-roll-outro-premium/default-credits-roll-outro-Horizontal.tsx +1 -0
  116. package/src/core/outro/credits-roll-outro-premium/default-credits-roll-outro-Landscape.tsx +1 -0
  117. package/src/core/outro/credits-roll-outro-premium/default-credits-roll-outro.stories.tsx +30 -0
  118. package/src/core/outro/credits-roll-outro-premium/default-credits-roll-outro.tsx +88 -0
  119. package/src/core/outro/credits-roll-outro-premium/index.ts +10 -0
  120. package/src/core/outro/credits-roll-outro-royal/default-credits-roll-outro-Horizontal.tsx +25 -0
  121. package/src/core/outro/credits-roll-outro-royal/default-credits-roll-outro-Landscape.tsx +25 -0
  122. package/src/core/outro/credits-roll-outro-royal/default-credits-roll-outro.stories.tsx +32 -0
  123. package/src/core/outro/credits-roll-outro-royal/default-credits-roll-outro.tsx +110 -0
  124. package/src/core/outro/credits-roll-outro-royal/index.ts +11 -0
  125. package/src/core/outro/default-blackout-outro-bumper/default-blackout-outro-bumper-Horizontal.tsx +22 -0
  126. package/src/core/outro/default-blackout-outro-bumper/default-blackout-outro-bumper-Landscape.tsx +22 -0
  127. package/src/core/outro/default-blackout-outro-bumper/default-blackout-outro-bumper.stories.tsx +48 -0
  128. package/src/core/outro/default-blackout-outro-bumper/default-blackout-outro-bumper.tsx +124 -0
  129. package/src/core/outro/default-blackout-outro-bumper/index.ts +11 -0
  130. package/src/core/outro/default-credits-roll-outro/default-credits-roll-outro-Horizontal.tsx +22 -0
  131. package/src/core/outro/default-credits-roll-outro/default-credits-roll-outro-Landscape.tsx +22 -0
  132. package/src/core/outro/default-credits-roll-outro/default-credits-roll-outro.stories.tsx +48 -0
  133. package/src/core/outro/default-credits-roll-outro/default-credits-roll-outro.tsx +208 -0
  134. package/src/core/outro/default-credits-roll-outro/index.ts +11 -0
  135. package/src/core/outro/default-epilogue-outro/default-epilogue-outro-Horizontal.tsx +22 -0
  136. package/src/core/outro/default-epilogue-outro/default-epilogue-outro-Landscape.tsx +22 -0
  137. package/src/core/outro/default-epilogue-outro/default-epilogue-outro.stories.tsx +48 -0
  138. package/src/core/outro/default-epilogue-outro/default-epilogue-outro.tsx +115 -0
  139. package/src/core/outro/default-epilogue-outro/index.ts +11 -0
  140. package/src/core/outro/default-outro-bumper/default-outro-bumper-Horizontal.tsx +22 -0
  141. package/src/core/outro/default-outro-bumper/default-outro-bumper-Landscape.tsx +22 -0
  142. package/src/core/outro/default-outro-bumper/default-outro-bumper.stories.tsx +48 -0
  143. package/src/core/outro/default-outro-bumper/default-outro-bumper.tsx +159 -0
  144. package/src/core/outro/default-outro-bumper/index.ts +11 -0
  145. package/src/core/outro/default-sunset-outro-bumper/default-sunset-outro-bumper-Horizontal.tsx +22 -0
  146. package/src/core/outro/default-sunset-outro-bumper/default-sunset-outro-bumper-Landscape.tsx +22 -0
  147. package/src/core/outro/default-sunset-outro-bumper/default-sunset-outro-bumper.stories.tsx +48 -0
  148. package/src/core/outro/default-sunset-outro-bumper/default-sunset-outro-bumper.tsx +183 -0
  149. package/src/core/outro/default-sunset-outro-bumper/index.ts +11 -0
  150. package/src/core/outro/festival-outro-encore/default-festival-outro-bumper-Horizontal.tsx +18 -0
  151. package/src/core/outro/festival-outro-encore/default-festival-outro-bumper-Landscape.tsx +18 -0
  152. package/src/core/outro/festival-outro-encore/default-festival-outro-bumper.stories.tsx +31 -0
  153. package/src/core/outro/festival-outro-encore/default-festival-outro-bumper.tsx +130 -0
  154. package/src/core/outro/festival-outro-encore/index.ts +10 -0
  155. package/src/core/outro/heist-outro/default-heist-outro-bumper-Horizontal.tsx +24 -0
  156. package/src/core/outro/heist-outro/default-heist-outro-bumper-Landscape.tsx +24 -0
  157. package/src/core/outro/heist-outro/default-heist-outro-bumper.stories.tsx +29 -0
  158. package/src/core/outro/heist-outro/default-heist-outro-bumper.tsx +160 -0
  159. package/src/core/outro/heist-outro/index.ts +4 -0
  160. package/src/core/outro/index.test.ts +88 -0
  161. package/src/core/outro/index.ts +73 -0
  162. package/src/core/outro/memoir-outro-reflection/default-memoir-outro-bumper-Horizontal.tsx +18 -0
  163. package/src/core/outro/memoir-outro-reflection/default-memoir-outro-bumper-Landscape.tsx +18 -0
  164. package/src/core/outro/memoir-outro-reflection/default-memoir-outro-bumper.stories.tsx +42 -0
  165. package/src/core/outro/memoir-outro-reflection/default-memoir-outro-bumper.tsx +158 -0
  166. package/src/core/outro/memoir-outro-reflection/index.ts +10 -0
  167. package/src/core/outro/romance-outro/default-romance-outro-bumper-Horizontal.tsx +1 -0
  168. package/src/core/outro/romance-outro/default-romance-outro-bumper-Landscape.tsx +1 -0
  169. package/src/core/outro/romance-outro/default-romance-outro-bumper.stories.tsx +48 -0
  170. package/src/core/outro/romance-outro/default-romance-outro-bumper.tsx +123 -0
  171. package/src/core/outro/romance-outro/index.ts +10 -0
  172. package/src/core/outro/sunset-outro-coda/default-sunset-outro-bumper-Horizontal.tsx +1 -0
  173. package/src/core/outro/sunset-outro-coda/default-sunset-outro-bumper-Landscape.tsx +1 -0
  174. package/src/core/outro/sunset-outro-coda/default-sunset-outro-bumper.stories.tsx +30 -0
  175. package/src/core/outro/sunset-outro-coda/default-sunset-outro-bumper.tsx +75 -0
  176. package/src/core/outro/sunset-outro-coda/index.ts +10 -0
  177. package/src/core/scene/2dscene/default-2d-scene-Horizontal.stories.tsx +1 -1
  178. package/src/core/scene/2dscene/default-2d-scene.stories.tsx +1 -1
  179. package/src/core/scene/3dscene/default-3d-scene-Horizontal.stories.tsx +1 -1
  180. package/src/core/scene/3dscene/default-3d-scene.stories.tsx +1 -1
  181. package/src/core/scene/index.ts +3 -0
  182. package/src/core/scene/photo/3dvr-photo/default-3dvr-photo-scene-Horizontal.stories.tsx +46 -0
  183. package/src/core/scene/photo/3dvr-photo/default-3dvr-photo-scene-Horizontal.tsx +20 -0
  184. package/src/core/scene/photo/3dvr-photo/default-3dvr-photo-scene-Landscape.tsx +20 -0
  185. package/src/core/scene/photo/3dvr-photo/default-3dvr-photo-scene.stories.tsx +46 -0
  186. package/src/core/scene/photo/3dvr-photo/default-3dvr-photo-scene.tsx +255 -0
  187. package/src/core/scene/photo/3dvr-photo/index.ts +3 -0
  188. package/src/core/scene/photo/default-live-photo-scene-Horizontal.stories.tsx +33 -0
  189. package/src/core/scene/photo/default-live-photo-scene-Horizontal.tsx +20 -0
  190. package/src/core/scene/photo/default-live-photo-scene-Landscape.tsx +20 -0
  191. package/src/core/scene/photo/default-live-photo-scene.stories.tsx +33 -0
  192. package/src/core/scene/photo/default-live-photo-scene.tsx +432 -0
  193. package/src/core/scene/photo/default-photo-strip-scene-Horizontal.tsx +20 -0
  194. package/src/core/scene/photo/default-photo-strip-scene-Landscape.tsx +20 -0
  195. package/src/core/scene/photo/default-photo-strip-scene.stories.tsx +38 -0
  196. package/src/core/scene/photo/default-photo-strip-scene.tsx +19 -0
  197. package/src/core/scene/photo/default-photo-wall-scene-Horizontal.tsx +20 -0
  198. package/src/core/scene/photo/default-photo-wall-scene-Landscape.tsx +20 -0
  199. package/src/core/scene/photo/default-photo-wall-scene.stories.tsx +38 -0
  200. package/src/core/scene/photo/default-photo-wall-scene.tsx +19 -0
  201. package/src/core/scene/photo/effects-photo/default-effects-photo-scene-Horizontal.stories.tsx +44 -0
  202. package/src/core/scene/photo/effects-photo/default-effects-photo-scene-Horizontal.tsx +20 -0
  203. package/src/core/scene/photo/effects-photo/default-effects-photo-scene-Landscape.tsx +20 -0
  204. package/src/core/scene/photo/effects-photo/default-effects-photo-scene.stories.tsx +44 -0
  205. package/src/core/scene/photo/effects-photo/default-effects-photo-scene.tsx +352 -0
  206. package/src/core/scene/photo/effects-photo/index.ts +3 -0
  207. package/src/core/scene/photo/index.ts +25 -0
  208. package/src/core/scene/photo/photo-storybook.test.tsx +112 -0
  209. package/src/core/scene/slide/_shared/index.ts +27 -0
  210. package/src/core/scene/slide/_shared/media-templates.test.ts +47 -0
  211. package/src/core/scene/slide/_shared/media-templates.tsx +324 -0
  212. package/src/core/scene/slide/default-slide-scene-Horizontal.animated.stories.tsx +1 -1
  213. package/src/core/scene/slide/default-slide-scene-Horizontal.stories.tsx +1 -1
  214. package/src/core/scene/slide/default-slide-scene.animated.stories.tsx +1 -1
  215. package/src/core/scene/slide/default-slide-scene.stories.tsx +1 -1
  216. package/src/core/scene/slide/index.test.ts +28 -0
  217. package/src/core/scene/slide/index.ts +14 -0
  218. package/src/core/scene/slide/person-intro/default-person-intro-duo-slide.tsx +19 -0
  219. package/src/core/scene/slide/person-intro/default-person-intro-group-slide.tsx +168 -0
  220. package/src/core/scene/slide/person-intro/default-person-intro-quad-slide.tsx +19 -0
  221. package/src/core/scene/slide/person-intro/default-person-intro-slide-Horizontal.animated.stories.tsx +47 -0
  222. package/src/core/scene/slide/person-intro/default-person-intro-slide-Horizontal.stories.tsx +46 -0
  223. package/src/core/scene/slide/person-intro/default-person-intro-slide-Horizontal.tsx +302 -0
  224. package/src/core/scene/slide/person-intro/default-person-intro-slide-Landscape.tsx +20 -0
  225. package/src/core/scene/slide/person-intro/default-person-intro-slide.animated.stories.tsx +126 -0
  226. package/src/core/scene/slide/person-intro/default-person-intro-slide.stories.tsx +119 -0
  227. package/src/core/scene/slide/person-intro/default-person-intro-slide.tsx +363 -0
  228. package/src/core/scene/slide/person-intro/default-person-intro-trio-slide.tsx +19 -0
  229. package/src/core/scene/slide/person-intro/index.ts +8 -0
  230. package/src/core/scene/slide/photo-album/default-photo-album-multi-slide.tsx +19 -0
  231. package/src/core/scene/slide/photo-album/default-photo-album-pair-slide.tsx +19 -0
  232. package/src/core/scene/slide/photo-album/default-photo-album-single-slide.tsx +19 -0
  233. package/src/core/scene/slide/photo-album/default-photo-album-slide-Horizontal.animated.stories.tsx +26 -0
  234. package/src/core/scene/slide/photo-album/default-photo-album-slide-Horizontal.stories.tsx +25 -0
  235. package/src/core/scene/slide/photo-album/default-photo-album-slide-Horizontal.tsx +20 -0
  236. package/src/core/scene/slide/photo-album/default-photo-album-slide-Landscape.tsx +20 -0
  237. package/src/core/scene/slide/photo-album/default-photo-album-slide.animated.stories.tsx +94 -0
  238. package/src/core/scene/slide/photo-album/default-photo-album-slide.stories.tsx +87 -0
  239. package/src/core/scene/slide/photo-album/default-photo-album-slide.tsx +414 -0
  240. package/src/core/scene/slide/photo-album/index.ts +7 -0
  241. package/src/core/scene/slide/video-showcase/default-video-showcase-multi-slide.tsx +195 -0
  242. package/src/core/scene/slide/video-showcase/default-video-showcase-slide-Horizontal.tsx +212 -0
  243. package/src/core/scene/slide/video-showcase/default-video-showcase-slide-Landscape.tsx +20 -0
  244. package/src/core/scene/slide/video-showcase/default-video-showcase-slide.animated.stories.tsx +78 -0
  245. package/src/core/scene/slide/video-showcase/default-video-showcase-slide.stories.tsx +74 -0
  246. package/src/core/scene/slide/video-showcase/default-video-showcase-slide.tsx +365 -0
  247. package/src/core/scene/slide/video-showcase/index.ts +5 -0
  248. package/src/core/scene/video/default-video-scene-Horizontal.stories.tsx +26 -0
  249. package/src/core/scene/video/default-video-scene-Horizontal.tsx +20 -0
  250. package/src/core/scene/video/default-video-scene-Landscape.tsx +20 -0
  251. package/src/core/scene/video/default-video-scene.stories.tsx +26 -0
  252. package/src/core/scene/video/default-video-scene.tsx +283 -0
  253. package/src/core/scene/video/default-video-split-scene-Horizontal.tsx +20 -0
  254. package/src/core/scene/video/default-video-split-scene-Landscape.tsx +20 -0
  255. package/src/core/scene/video/default-video-split-scene.stories.tsx +41 -0
  256. package/src/core/scene/video/default-video-split-scene.tsx +19 -0
  257. package/src/core/scene/video/default-video-wall-scene-Horizontal.tsx +20 -0
  258. package/src/core/scene/video/default-video-wall-scene-Landscape.tsx +20 -0
  259. package/src/core/scene/video/default-video-wall-scene.stories.tsx +40 -0
  260. package/src/core/scene/video/default-video-wall-scene.tsx +19 -0
  261. package/src/core/scene/video/index.ts +9 -0
  262. package/src/storybook/remotion-preview.tsx +112 -6
  263. package/src/core/intro/default-intro-bumper.stories.tsx +0 -19
  264. package/src/core/intro/default-intro-bumper.tsx +0 -218
  265. package/src/core/outro/default-outro-bumper.stories.tsx +0 -19
  266. package/src/core/outro/default-outro-bumper.tsx +0 -218
@@ -0,0 +1,31 @@
1
+ import { DefaultWesternIntroBumperGangsterHorizontal } from './default-western-intro-bumper-Horizontal'
2
+ import { DefaultWesternIntroBumperGangsterLandscape } from './default-western-intro-bumper-Landscape'
3
+
4
+ const args = {
5
+ kicker: 'Frontier Crime',
6
+ title: 'The Last Outlaw',
7
+ subtitle: 'A wanted-poster dossier with evidence-board framing and a tougher western tone.',
8
+ creditLine: 'A Vibecuting Original',
9
+ footer: 'Opening Sequence',
10
+ accent: '#1f130d',
11
+ secondaryAccent: '#6b3f1d',
12
+ }
13
+
14
+ const meta = {
15
+ title: 'core/intro/western-intro-gangster/DefaultWesternIntroBumperGangsterLandscape',
16
+ component: DefaultWesternIntroBumperGangsterLandscape,
17
+ args,
18
+ }
19
+
20
+ export default meta
21
+
22
+ export const Default = {}
23
+ export const Animated = { parameters: { scenePreviewMode: 'animation' } }
24
+ export const Horizontal = {
25
+ render: (storyArgs: typeof args) => <DefaultWesternIntroBumperGangsterHorizontal {...storyArgs} />,
26
+ parameters: { scenePreviewAspectRatio: '9:16' },
27
+ }
28
+ export const HorizontalAnimated = {
29
+ render: (storyArgs: typeof args) => <DefaultWesternIntroBumperGangsterHorizontal {...storyArgs} />,
30
+ parameters: { scenePreviewMode: 'animation', scenePreviewAspectRatio: '9:16' },
31
+ }
@@ -0,0 +1,105 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ import { VideoComponent, defineComponentProjectComponentMetadata } from '@vibecuting/component-project-helper'
4
+
5
+ import { BaseRemotionScene, type BaseRemotionSceneProps, useRemotionSceneRuntime } from '../../../base'
6
+ import { useSceneMotion } from '../../../base'
7
+ import { getIntroBodyMaxWidth, getIntroLineClamp, getIntroPanelMinHeight, getIntroPanelPadding } from '../_shared/intro-layout'
8
+
9
+ export interface DefaultWesternIntroBumperGangsterProps extends BaseRemotionSceneProps {
10
+ title: string
11
+ subtitle?: string
12
+ kicker?: string
13
+ creditLine?: string
14
+ footer?: string
15
+ accent?: string
16
+ secondaryAccent?: string
17
+ textColor?: string
18
+ children?: ReactNode
19
+ }
20
+
21
+ export const componentMetadata = defineComponentProjectComponentMetadata({
22
+ name: 'DefaultWesternIntroBumperGangster',
23
+ description: 'Gangster western intro with a wanted poster and evidence board layout, tuned for portrait previews',
24
+ sourceFile: 'src/core/intro/western-intro-gangster/default-western-intro-bumper.tsx',
25
+ aspectRatio: '16:9',
26
+ sceneType: 'intro',
27
+ tags: ['intro', 'bumper', 'western', 'gangster', 'dust'],
28
+ propsTypeName: 'DefaultWesternIntroBumperGangsterProps',
29
+ })
30
+
31
+ export function DefaultWesternIntroBumperGangster({
32
+ id,
33
+ name,
34
+ title,
35
+ subtitle,
36
+ kicker,
37
+ creditLine,
38
+ footer,
39
+ accent,
40
+ secondaryAccent,
41
+ textColor,
42
+ children,
43
+ }: DefaultWesternIntroBumperGangsterProps) {
44
+ const runtime = useRemotionSceneRuntime()
45
+ const motion = useSceneMotion()
46
+ const portrait = runtime.height > runtime.width
47
+
48
+ return (
49
+ <BaseRemotionScene
50
+ id={id}
51
+ name={name}
52
+ style={{
53
+ background: portrait
54
+ ? 'linear-gradient(180deg, #2b1d14 0%, #130d09 40%, #020617 100%)'
55
+ : `radial-gradient(circle at 50% 24%, ${secondaryAccent ?? '#6b3f1d'} 0%, ${accent ?? '#1f130d'} 42%, #020617 100%)`,
56
+ color: textColor ?? '#fff7ed',
57
+ display: 'grid',
58
+ placeItems: 'center',
59
+ padding: Math.round(runtime.height * 0.07),
60
+ }}
61
+ >
62
+ <section style={{ width: '100%', height: '100%', display: 'grid', gridTemplateColumns: portrait ? '1fr' : 'minmax(0, 0.84fr) minmax(280px, 1.16fr)', gap: portrait ? 18 : 24, alignItems: 'stretch', minWidth: 0, minHeight: 0, overflow: 'hidden' }}>
63
+ <div style={{ display: 'grid', gap: 12, textAlign: portrait ? 'center' : 'left', minWidth: 0, alignContent: 'center' }}>
64
+ <p style={{ margin: 0, fontSize: Math.round(runtime.height * 0.017), letterSpacing: '0.3em', textTransform: 'uppercase', opacity: 0.66 }}>
65
+ {kicker ?? 'Dust and Smoke'}
66
+ </p>
67
+ <h1 style={{ margin: 0, fontSize: portrait ? Math.round(runtime.height * 0.078) : Math.round(runtime.height * 0.072), lineHeight: 0.9, letterSpacing: '-0.08em', textTransform: 'uppercase', transform: motion.isAnimation ? `translate3d(0, ${(1 - motion.progress) * 8}px, 0)` : 'none' }}>
68
+ {title}
69
+ </h1>
70
+ {subtitle ? <p style={{ margin: 0, maxWidth: getIntroBodyMaxWidth(runtime.width, portrait, 0.42, 1, { min: 240, max: 680 }), fontSize: Math.round(runtime.height * 0.023), lineHeight: 1.55, opacity: 0.82, ...getIntroLineClamp(portrait ? 4 : 3) }}>{subtitle}</p> : null}
71
+ <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: portrait ? 'center' : 'flex-start', gap: 10 }}>
72
+ {creditLine ? <span style={{ fontSize: Math.round(runtime.height * 0.015), letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.72 }}>{creditLine}</span> : null}
73
+ {footer ? <span style={{ fontSize: Math.round(runtime.height * 0.015), letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.52 }}>{footer}</span> : null}
74
+ </div>
75
+ </div>
76
+
77
+ <div style={{ display: 'grid', gap: 12, alignContent: 'center', minWidth: 0 }}>
78
+ <div style={{ width: '100%', minWidth: 0, border: '1px solid rgba(255,247,237,0.14)', background: 'linear-gradient(180deg, rgba(255,247,237,0.06) 0%, rgba(15,23,42,0.2) 38%, rgba(2,6,23,0.96) 100%)', padding: getIntroPanelPadding(runtime.height, portrait, 0.008, 0.007, { min: 12, max: 18 }), display: 'grid', gap: 12, overflow: 'hidden', minHeight: getIntroPanelMinHeight(runtime.height, portrait, 0.3, 0.22, { min: 220, max: 340 }) }}>
79
+ <div style={{ display: 'grid', gridTemplateColumns: portrait ? '1fr' : 'minmax(0, 1fr) minmax(0, 0.82fr)', gap: 12, minWidth: 0 }}>
80
+ <div style={{ display: 'grid', gap: 10, minWidth: 0 }}>
81
+ <div style={{ fontSize: Math.round(runtime.height * 0.017), letterSpacing: '0.24em', textTransform: 'uppercase', opacity: 0.58 }}>Wanted and Wired</div>
82
+ <div style={{ fontSize: Math.round(runtime.height * 0.029), fontWeight: 800, letterSpacing: '-0.06em' }}>No one rides alone</div>
83
+ <div style={{ border: '1px solid rgba(255,247,237,0.1)', padding: '12px 14px', background: 'rgba(0,0,0,0.16)', display: 'grid', gap: 8 }}>
84
+ <span style={{ fontSize: Math.round(runtime.height * 0.014), letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.56 }}>Case File</span>
85
+ <span style={{ fontSize: Math.round(runtime.height * 0.02), ...getIntroLineClamp(2) }}>Split-screen dossier with a wanted poster on the right and records on the left.</span>
86
+ </div>
87
+ </div>
88
+ <div style={{ border: '1px solid rgba(255,247,237,0.12)', background: 'rgba(0,0,0,0.18)', padding: 14, display: 'grid', gap: 10, alignContent: 'start', minHeight: portrait ? 120 : 0 }}>
89
+ {['Alias', 'Territory', 'Reward'].map((label, index) => (
90
+ <div key={label} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, fontSize: Math.round(runtime.height * 0.018), opacity: 0.82, minWidth: 0 }}>
91
+ <span style={{ letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.56 }}>{label}</span>
92
+ <span style={getIntroLineClamp(1)}>{index === 0 ? 'Unknown' : index === 1 ? 'Borderline' : 'High'}</span>
93
+ </div>
94
+ ))}
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ </section>
100
+ {children ? <div style={{ position: 'absolute', inset: 'auto 0 8%', display: 'grid', placeItems: 'center' }}>{children}</div> : null}
101
+ </BaseRemotionScene>
102
+ )
103
+ }
104
+
105
+ VideoComponent(componentMetadata)(DefaultWesternIntroBumperGangster)
@@ -0,0 +1,11 @@
1
+ export { DefaultWesternIntroBumperGangster } from './default-western-intro-bumper'
2
+ export { componentMetadata } from './default-western-intro-bumper'
3
+ export {
4
+ DefaultWesternIntroBumperGangsterLandscape,
5
+ componentMetadata as DefaultWesternIntroBumperGangsterLandscapeMetadata,
6
+ } from './default-western-intro-bumper-Landscape'
7
+ export {
8
+ DefaultWesternIntroBumperGangsterHorizontal,
9
+ componentMetadata as DefaultWesternIntroBumperGangsterHorizontalMetadata,
10
+ } from './default-western-intro-bumper-Horizontal'
11
+
@@ -0,0 +1,32 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import {
4
+ getOutroBodyMaxWidth,
5
+ getOutroLineClamp,
6
+ getOutroPanelMinHeight,
7
+ getOutroTypographyScale,
8
+ resolveOutroLayout,
9
+ } from './outro-layout'
10
+
11
+ describe('outro layout helpers', () => {
12
+ it('keeps portrait constraints tighter than landscape ones', () => {
13
+ const landscape = resolveOutroLayout(undefined, 1920, 1080)
14
+ const portrait = resolveOutroLayout(undefined, 1080, 1920)
15
+
16
+ expect(landscape).toBe('landscape')
17
+ expect(portrait).toBe('horizontal')
18
+
19
+ expect(getOutroBodyMaxWidth(1080, landscape, 0.34, 0.24, { min: 240, max: 860 })).toBeGreaterThan(
20
+ getOutroBodyMaxWidth(1080, portrait, 0.34, 0.24, { min: 240, max: 860 }),
21
+ )
22
+
23
+ expect(getOutroPanelMinHeight(1920, portrait, 0.24, 0.28, { min: 220, max: 320 })).toBeLessThanOrEqual(320)
24
+ expect(getOutroPanelMinHeight(1920, landscape, 0.24, 0.28, { min: 220, max: 320 })).toBeLessThanOrEqual(320)
25
+
26
+ expect(getOutroTypographyScale(1080, landscape).titleFontSize).toBeGreaterThan(0)
27
+ expect(getOutroLineClamp(3)).toMatchObject({
28
+ display: '-webkit-box',
29
+ WebkitLineClamp: 3,
30
+ })
31
+ })
32
+ })
@@ -0,0 +1,72 @@
1
+ export type OutroLayout = 'landscape' | 'horizontal'
2
+
3
+ export function resolveOutroLayout(
4
+ layout: OutroLayout | undefined,
5
+ width: number,
6
+ height: number,
7
+ ): OutroLayout {
8
+ if (layout) {
9
+ return layout
10
+ }
11
+
12
+ return height > width ? 'horizontal' : 'landscape'
13
+ }
14
+
15
+ export function getOutroTypographyScale(height: number, layout: OutroLayout) {
16
+ const isHorizontal = layout === 'horizontal'
17
+
18
+ return {
19
+ titleFontSize: Math.round(height * (isHorizontal ? 0.074 : 0.068)),
20
+ noteFontSize: Math.round(height * 0.023),
21
+ kickerFontSize: Math.round(height * 0.018),
22
+ footerFontSize: Math.round(height * 0.016),
23
+ }
24
+ }
25
+
26
+ export function getOutroBodyMaxWidth(
27
+ width: number,
28
+ layout: OutroLayout,
29
+ landscapeRatio: number,
30
+ horizontalRatio: number,
31
+ options?: { min?: number; max?: number },
32
+ ) {
33
+ const isHorizontal = layout === 'horizontal'
34
+ const ratio = isHorizontal ? horizontalRatio : landscapeRatio
35
+ const minimum = options?.min ?? 240
36
+ const maximum = options?.max ?? 720
37
+
38
+ return Math.min(Math.max(Math.round(width * ratio), minimum), maximum)
39
+ }
40
+
41
+ export function getOutroPanelPadding(height: number, layout: OutroLayout, landscapeRatio: number, horizontalRatio: number) {
42
+ const isHorizontal = layout === 'horizontal'
43
+ return Math.round(height * (isHorizontal ? horizontalRatio : landscapeRatio))
44
+ }
45
+
46
+ export function getOutroPanelMinHeight(
47
+ height: number,
48
+ layout: OutroLayout,
49
+ landscapeRatio: number,
50
+ horizontalRatio: number,
51
+ options?: { min?: number; max?: number },
52
+ ) {
53
+ const isHorizontal = layout === 'horizontal'
54
+ const ratio = isHorizontal ? horizontalRatio : landscapeRatio
55
+ const minimum = options?.min ?? 120
56
+ const maximum = options?.max ?? 360
57
+
58
+ return Math.min(Math.max(Math.round(height * ratio), minimum), maximum)
59
+ }
60
+
61
+ export function getOutroBodyGridTemplate(layout: OutroLayout, portraitTemplate: string, landscapeTemplate: string) {
62
+ return layout === 'horizontal' ? portraitTemplate : landscapeTemplate
63
+ }
64
+
65
+ export function getOutroLineClamp(lines: number) {
66
+ return {
67
+ display: '-webkit-box',
68
+ WebkitLineClamp: lines,
69
+ WebkitBoxOrient: 'vertical' as const,
70
+ overflow: 'hidden',
71
+ }
72
+ }
@@ -0,0 +1,18 @@
1
+ import type { ComponentProps } from 'react'
2
+
3
+ import { VideoComponent, defineComponentProjectComponentMetadata } from '@vibecuting/component-project-helper'
4
+
5
+ import { DefaultAwardOutroBumper, componentMetadata as baseComponentMetadata } from './default-award-outro-bumper'
6
+
7
+ export const componentMetadata = defineComponentProjectComponentMetadata({
8
+ ...baseComponentMetadata,
9
+ name: 'DefaultAwardOutroBumperHorizontal',
10
+ aspectRatio: '9:16',
11
+ sourceFile: 'src/core/outro/award-outro-celebration/default-award-outro-bumper-Horizontal.tsx',
12
+ })
13
+
14
+ export const DefaultAwardOutroBumperHorizontal = VideoComponent(componentMetadata)(
15
+ function DefaultAwardOutroBumperHorizontal(props: ComponentProps<typeof DefaultAwardOutroBumper>) {
16
+ return <DefaultAwardOutroBumper {...props} />
17
+ },
18
+ )
@@ -0,0 +1,18 @@
1
+ import type { ComponentProps } from 'react'
2
+
3
+ import { VideoComponent, defineComponentProjectComponentMetadata } from '@vibecuting/component-project-helper'
4
+
5
+ import { DefaultAwardOutroBumper, componentMetadata as baseComponentMetadata } from './default-award-outro-bumper'
6
+
7
+ export const componentMetadata = defineComponentProjectComponentMetadata({
8
+ ...baseComponentMetadata,
9
+ name: 'DefaultAwardOutroBumperLandscape',
10
+ aspectRatio: '16:9',
11
+ sourceFile: 'src/core/outro/award-outro-celebration/default-award-outro-bumper-Landscape.tsx',
12
+ })
13
+
14
+ export const DefaultAwardOutroBumperLandscape = VideoComponent(componentMetadata)(
15
+ function DefaultAwardOutroBumperLandscape(props: ComponentProps<typeof DefaultAwardOutroBumper>) {
16
+ return <DefaultAwardOutroBumper {...props} />
17
+ },
18
+ )
@@ -0,0 +1,42 @@
1
+ import { DefaultAwardOutroBumperHorizontal } from './default-award-outro-bumper-Horizontal'
2
+ import { DefaultAwardOutroBumperLandscape } from './default-award-outro-bumper-Landscape'
3
+
4
+ const posterImageSrc = `data:image/svg+xml;utf8,${encodeURIComponent(`
5
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="900" viewBox="0 0 1200 900">
6
+ <rect width="1200" height="900" fill="#111827"/>
7
+ <circle cx="600" cy="360" r="180" fill="#f59e0b" fill-opacity="0.45"/>
8
+ <rect x="470" y="180" width="260" height="360" rx="24" fill="#f8fafc" fill-opacity="0.12"/>
9
+ <text x="120" y="720" fill="#fef3c7" font-size="92" font-family="Arial, sans-serif" letter-spacing="8">AWARD</text>
10
+ </svg>
11
+ `)}`;
12
+
13
+ const args = {
14
+ kicker: 'Awards Season',
15
+ title: 'And the Winner Is',
16
+ note: 'A trophy-rail finale with poster framing, winner highlights, and a formal award-show finish.',
17
+ creditLine: 'A Vibecuting Original',
18
+ footer: 'End Credits',
19
+ accent: '#111827',
20
+ secondaryAccent: '#f59e0b',
21
+ posterImageSrc,
22
+ posterImageAlt: 'Award celebration image',
23
+ }
24
+
25
+ const meta = {
26
+ title: 'core/outro/award-outro-celebration/DefaultAwardOutroBumperLandscape',
27
+ component: DefaultAwardOutroBumperLandscape,
28
+ args,
29
+ }
30
+
31
+ export default meta
32
+
33
+ export const Default = { parameters: { scenePreviewAspectRatio: '16:9' } }
34
+ export const Animated = { parameters: { scenePreviewAspectRatio: '16:9', scenePreviewMode: 'animation' } }
35
+ export const Horizontal = {
36
+ render: (storyArgs: typeof args) => <DefaultAwardOutroBumperHorizontal {...storyArgs} />,
37
+ parameters: { scenePreviewAspectRatio: '9:16' },
38
+ }
39
+ export const HorizontalAnimated = {
40
+ render: (storyArgs: typeof args) => <DefaultAwardOutroBumperHorizontal {...storyArgs} />,
41
+ parameters: { scenePreviewAspectRatio: '9:16', scenePreviewMode: 'animation' },
42
+ }
@@ -0,0 +1,152 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ import { VideoComponent, defineComponentProjectComponentMetadata } from '@vibecuting/component-project-helper'
4
+
5
+ import { BaseRemotionScene, type BaseRemotionSceneProps, useRemotionSceneRuntime } from '../../../base'
6
+ import { useSceneMotion } from '../../../base'
7
+ import { getOutroTypographyScale, resolveOutroLayout, type OutroLayout } from '../_shared/outro-layout'
8
+
9
+ export interface DefaultAwardOutroBumperProps extends BaseRemotionSceneProps {
10
+ title: string
11
+ note?: string
12
+ kicker?: string
13
+ creditLine?: string
14
+ footer?: string
15
+ accent?: string
16
+ secondaryAccent?: string
17
+ textColor?: string
18
+ layout?: OutroLayout
19
+ posterImageSrc?: string
20
+ posterImageAlt?: string
21
+ children?: ReactNode
22
+ }
23
+
24
+ export const componentMetadata = defineComponentProjectComponentMetadata({
25
+ name: 'DefaultAwardOutroBumper',
26
+ description: 'Award-show outro with a trophy rail and celebratory poster frame',
27
+ sourceFile: 'src/core/outro/award-outro-celebration/default-award-outro-bumper.tsx',
28
+ aspectRatio: '16:9',
29
+ sceneType: 'outro',
30
+ tags: ['outro', 'bumper', 'award', 'celebration'],
31
+ propsTypeName: 'DefaultAwardOutroBumperProps',
32
+ })
33
+
34
+ export function DefaultAwardOutroBumper({
35
+ id,
36
+ name,
37
+ title,
38
+ note,
39
+ kicker,
40
+ creditLine,
41
+ footer,
42
+ accent,
43
+ secondaryAccent,
44
+ textColor,
45
+ layout,
46
+ posterImageSrc,
47
+ posterImageAlt,
48
+ children,
49
+ }: DefaultAwardOutroBumperProps) {
50
+ const runtime = useRemotionSceneRuntime()
51
+ const motion = useSceneMotion()
52
+ const resolvedLayout = resolveOutroLayout(layout, runtime.width, runtime.height)
53
+ const isHorizontal = resolvedLayout === 'horizontal'
54
+ const portrait = isHorizontal
55
+ const { titleFontSize, noteFontSize, kickerFontSize, footerFontSize } = getOutroTypographyScale(runtime.height, resolvedLayout)
56
+
57
+ return (
58
+ <BaseRemotionScene
59
+ id={id}
60
+ name={name}
61
+ style={{
62
+ background: isHorizontal
63
+ ? `radial-gradient(circle at 50% 18%, ${secondaryAccent ?? '#f59e0b'} 0%, ${accent ?? '#111827'} 42%, #020617 100%)`
64
+ : `linear-gradient(180deg, ${accent ?? '#111827'} 0%, #0f172a 44%, #020617 100%)`,
65
+ color: textColor ?? '#f8fafc',
66
+ display: 'grid',
67
+ placeItems: 'center',
68
+ padding: Math.round(runtime.height * (portrait ? 0.06 : 0.07)),
69
+ overflow: 'hidden',
70
+ }}
71
+ >
72
+ <section
73
+ style={{
74
+ position: 'relative',
75
+ zIndex: 1,
76
+ width: '100%',
77
+ height: '100%',
78
+ display: 'grid',
79
+ gridTemplateColumns: portrait ? '1fr' : 'minmax(0, 0.92fr) minmax(300px, 1.08fr)',
80
+ gap: portrait ? 16 : 24,
81
+ alignItems: 'stretch',
82
+ minWidth: 0,
83
+ minHeight: 0,
84
+ }}
85
+ >
86
+ <div style={{ display: 'grid', gap: 12, alignContent: 'center', textAlign: portrait ? 'center' : 'left', minWidth: 0 }}>
87
+ <p style={{ margin: 0, fontSize: kickerFontSize, letterSpacing: '0.34em', textTransform: 'uppercase', opacity: 0.64 }}>
88
+ {kicker ?? 'Awards Season'}
89
+ </p>
90
+ <h1
91
+ style={{
92
+ margin: 0,
93
+ fontSize: titleFontSize,
94
+ lineHeight: 0.92,
95
+ letterSpacing: '-0.08em',
96
+ textTransform: 'uppercase',
97
+ transform: motion.isAnimation ? `translate3d(0, ${(1 - motion.progress) * 10}px, 0)` : 'none',
98
+ }}
99
+ >
100
+ {title}
101
+ </h1>
102
+ {note ? <p style={{ margin: 0, maxWidth: portrait ? '100%' : Math.round(runtime.width * 0.42), fontSize: noteFontSize, lineHeight: 1.55, opacity: 0.82 }}>{note}</p> : null}
103
+ <div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: portrait ? 'center' : 'flex-start', gap: 10 }}>
104
+ {creditLine ? <span style={{ fontSize: footerFontSize, letterSpacing: '0.22em', textTransform: 'uppercase', opacity: 0.8 }}>{creditLine}</span> : null}
105
+ {footer ? <span style={{ fontSize: footerFontSize, letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.54 }}>{footer}</span> : null}
106
+ </div>
107
+ </div>
108
+
109
+ <div style={{ display: 'grid', gap: 12, alignContent: 'center', minWidth: 0 }}>
110
+ <div style={{ border: '1px solid rgba(248,250,252,0.14)', background: 'linear-gradient(180deg, rgba(255,255,255,0.06), rgba(245,158,11,0.1) 44%, rgba(15,23,42,0.18))', padding: portrait ? 14 : 18, display: 'grid', gap: 12, overflow: 'hidden' }}>
111
+ <div style={{ display: 'grid', gridTemplateColumns: portrait ? '1fr' : posterImageSrc ? 'minmax(0, 0.74fr) minmax(0, 1.26fr)' : '1fr', gap: 12 }}>
112
+ {posterImageSrc ? (
113
+ <div style={{ minHeight: portrait ? 158 : 170, border: '1px solid rgba(248,250,252,0.12)', overflow: 'hidden', background: 'rgba(2,6,23,0.18)' }}>
114
+ <img src={posterImageSrc} alt={posterImageAlt ?? title} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
115
+ </div>
116
+ ) : null}
117
+ <div style={{ display: 'grid', gap: 10, alignContent: 'center' }}>
118
+ <div style={{ fontSize: footerFontSize, letterSpacing: '0.3em', textTransform: 'uppercase', opacity: 0.56 }}>
119
+ Trophy Cards
120
+ </div>
121
+ {[
122
+ ['Best Picture', 'Vibecuting Studio'],
123
+ ['Best Edit', 'Motion Team'],
124
+ ['Best Sound', 'Editorial Crew'],
125
+ ].map(([label, value], index) => (
126
+ <div
127
+ key={label}
128
+ style={{
129
+ display: 'flex',
130
+ justifyContent: 'space-between',
131
+ gap: 12,
132
+ fontSize: Math.round(runtime.height * (portrait ? 0.017 : 0.02)),
133
+ border: '1px solid rgba(248,250,252,0.1)',
134
+ padding: '10px 12px',
135
+ background: index === 1 ? 'rgba(245,158,11,0.14)' : 'rgba(0,0,0,0.14)',
136
+ }}
137
+ >
138
+ <span style={{ opacity: 0.56, textTransform: 'uppercase', letterSpacing: '0.18em' }}>{label}</span>
139
+ <span>{value}</span>
140
+ </div>
141
+ ))}
142
+ </div>
143
+ </div>
144
+ </div>
145
+ {children ? <div>{children}</div> : null}
146
+ </div>
147
+ </section>
148
+ </BaseRemotionScene>
149
+ )
150
+ }
151
+
152
+ VideoComponent(componentMetadata)(DefaultAwardOutroBumper)
@@ -0,0 +1,10 @@
1
+ export { DefaultAwardOutroBumper } from './default-award-outro-bumper'
2
+ export { componentMetadata } from './default-award-outro-bumper'
3
+ export {
4
+ DefaultAwardOutroBumperLandscape,
5
+ componentMetadata as DefaultAwardOutroBumperLandscapeMetadata,
6
+ } from './default-award-outro-bumper-Landscape'
7
+ export {
8
+ DefaultAwardOutroBumperHorizontal,
9
+ componentMetadata as DefaultAwardOutroBumperHorizontalMetadata,
10
+ } from './default-award-outro-bumper-Horizontal'
@@ -0,0 +1 @@
1
+ export { DefaultBlackoutOutroBumperFinale as DefaultBlackoutOutroBumperFinaleHorizontal, componentMetadata } from './default-blackout-outro-bumper'
@@ -0,0 +1 @@
1
+ export { DefaultBlackoutOutroBumperFinale as DefaultBlackoutOutroBumperFinaleLandscape, componentMetadata } from './default-blackout-outro-bumper'
@@ -0,0 +1,28 @@
1
+ import { DefaultBlackoutOutroBumperFinaleHorizontal } from './default-blackout-outro-bumper-Horizontal'
2
+ import { DefaultBlackoutOutroBumperFinaleLandscape } from './default-blackout-outro-bumper-Landscape'
3
+
4
+ const args = {
5
+ kicker: 'Finale',
6
+ title: 'The End',
7
+ note: 'A hard-black outro card for thriller endings, prestige drama, and stark finales.',
8
+ creditLine: 'A Vibecuting Original',
9
+ footer: 'End Credits',
10
+ }
11
+
12
+ const meta = {
13
+ title: 'core/outro/blackout-outro-finale/DefaultBlackoutOutroBumperFinale',
14
+ component: DefaultBlackoutOutroBumperFinaleLandscape,
15
+ args,
16
+ }
17
+
18
+ export default meta
19
+ export const Landscape = { parameters: { scenePreviewAspectRatio: '16:9' } }
20
+ export const LandscapeAnimated = { parameters: { scenePreviewAspectRatio: '16:9', scenePreviewMode: 'animation' } }
21
+ export const Horizontal = {
22
+ render: (storyArgs: typeof args) => <DefaultBlackoutOutroBumperFinaleHorizontal {...storyArgs} />,
23
+ parameters: { scenePreviewAspectRatio: '9:16' },
24
+ }
25
+ export const HorizontalAnimated = {
26
+ render: (storyArgs: typeof args) => <DefaultBlackoutOutroBumperFinaleHorizontal {...storyArgs} />,
27
+ parameters: { scenePreviewAspectRatio: '9:16', scenePreviewMode: 'animation' },
28
+ }
@@ -0,0 +1,71 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ import { VideoComponent, defineComponentProjectComponentMetadata } from '@vibecuting/component-project-helper'
4
+
5
+ import { BaseRemotionScene, type BaseRemotionSceneProps, useRemotionSceneRuntime } from '../../../base'
6
+ import { useSceneMotion } from '../../../base'
7
+
8
+ export interface DefaultBlackoutOutroBumperFinaleProps extends BaseRemotionSceneProps {
9
+ title: string
10
+ note?: string
11
+ kicker?: string
12
+ creditLine?: string
13
+ footer?: string
14
+ accent?: string
15
+ secondaryAccent?: string
16
+ textColor?: string
17
+ children?: ReactNode
18
+ }
19
+
20
+ export const componentMetadata = defineComponentProjectComponentMetadata({
21
+ name: 'DefaultBlackoutOutroBumperFinale',
22
+ description: 'Blackout finale outro bumper',
23
+ sourceFile: 'src/core/outro/blackout-outro-finale/default-blackout-outro-bumper.tsx',
24
+ aspectRatio: '16:9',
25
+ sceneType: 'outro',
26
+ tags: ['outro', 'bumper', 'blackout', 'minimal', 'finale'],
27
+ propsTypeName: 'DefaultBlackoutOutroBumperFinaleProps',
28
+ })
29
+
30
+ export function DefaultBlackoutOutroBumperFinale({
31
+ id,
32
+ name,
33
+ title,
34
+ note,
35
+ kicker,
36
+ creditLine,
37
+ footer,
38
+ textColor,
39
+ }: DefaultBlackoutOutroBumperFinaleProps) {
40
+ const runtime = useRemotionSceneRuntime()
41
+ const motion = useSceneMotion()
42
+ const portrait = runtime.height > runtime.width
43
+
44
+ return (
45
+ <BaseRemotionScene
46
+ id={id}
47
+ name={name}
48
+ style={{
49
+ background: '#000000',
50
+ color: textColor ?? '#f8fafc',
51
+ display: 'grid',
52
+ placeItems: 'center',
53
+ padding: Math.round(runtime.height * 0.07),
54
+ }}
55
+ >
56
+ <section style={{ width: '100%', height: '100%', display: 'grid', alignContent: 'center', justifyItems: 'center', gap: 14, textAlign: 'center', minWidth: 0, minHeight: 0 }}>
57
+ <p style={{ margin: 0, fontSize: Math.round(runtime.height * 0.017), letterSpacing: '0.34em', textTransform: 'uppercase', opacity: 0.56 }}>
58
+ {kicker ?? 'Fade to Black'}
59
+ </p>
60
+ <h1 style={{ margin: 0, fontSize: portrait ? Math.round(runtime.height * 0.078) : Math.round(runtime.height * 0.072), lineHeight: 0.92, letterSpacing: '-0.08em', textTransform: 'uppercase', transform: motion.isAnimation ? `translate3d(0, ${(1 - motion.progress) * 8}px, 0)` : 'none' }}>
61
+ {title}
62
+ </h1>
63
+ {note ? <p style={{ margin: 0, maxWidth: Math.round(runtime.width * 0.52), fontSize: Math.round(runtime.height * 0.023), lineHeight: 1.56, opacity: 0.8 }}>{note}</p> : null}
64
+ {creditLine ? <p style={{ margin: 0, fontSize: Math.round(runtime.height * 0.015), letterSpacing: '0.22em', textTransform: 'uppercase', opacity: 0.72 }}>{creditLine}</p> : null}
65
+ {footer ? <p style={{ margin: 0, fontSize: Math.round(runtime.height * 0.015), letterSpacing: '0.2em', textTransform: 'uppercase', opacity: 0.52 }}>{footer}</p> : null}
66
+ </section>
67
+ </BaseRemotionScene>
68
+ )
69
+ }
70
+
71
+ VideoComponent(componentMetadata)(DefaultBlackoutOutroBumperFinale)
@@ -0,0 +1,10 @@
1
+ export { DefaultBlackoutOutroBumperFinale } from './default-blackout-outro-bumper'
2
+ export { componentMetadata } from './default-blackout-outro-bumper'
3
+ export {
4
+ DefaultBlackoutOutroBumperFinaleLandscape,
5
+ componentMetadata as DefaultBlackoutOutroBumperFinaleLandscapeMetadata,
6
+ } from './default-blackout-outro-bumper-Landscape'
7
+ export {
8
+ DefaultBlackoutOutroBumperFinaleHorizontal,
9
+ componentMetadata as DefaultBlackoutOutroBumperFinaleHorizontalMetadata,
10
+ } from './default-blackout-outro-bumper-Horizontal'
@@ -0,0 +1,24 @@
1
+ import type { ComponentProps } from 'react'
2
+
3
+ import { VideoComponent, type ScenePluginMetadata } from '@vibecuting/component-project-helper'
4
+
5
+ import { DefaultCreditsRollOutroEpic, componentMetadata as baseComponentMetadata } from './default-credits-roll-outro'
6
+
7
+ export const componentMetadata: ScenePluginMetadata = {
8
+ ...baseComponentMetadata,
9
+ resourceKind: 'scene',
10
+ pluginKey: 'core.outro.credits-roll-epic',
11
+ sceneFamily: 'custom',
12
+ rootLayout: 'absolute-fill',
13
+ name: 'DefaultCreditsRollOutroEpicHorizontal',
14
+ description: 'Epic credits-roll outro bumper (Portrait 9:16 variant)',
15
+ sourceFile: 'src/core/outro/credits-roll-outro-epic/default-credits-roll-outro-Horizontal.tsx',
16
+ aspectRatio: '9:16',
17
+ tags: Array.from(new Set([...(baseComponentMetadata.tags ?? []), 'horizontal'])),
18
+ }
19
+
20
+ export const DefaultCreditsRollOutroEpicHorizontal = VideoComponent(componentMetadata)(function DefaultCreditsRollOutroEpicHorizontal(
21
+ props: ComponentProps<typeof DefaultCreditsRollOutroEpic>,
22
+ ) {
23
+ return <DefaultCreditsRollOutroEpic {...props} />
24
+ })