dsh-drawai 0.4.2 → 0.4.4

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 (379) hide show
  1. package/README.md +7 -5
  2. package/lib/client.js +142 -16
  3. package/lib/index.js +7945 -7719
  4. package/lib/motion/asset-pack.js +394 -394
  5. package/lib/motion/assets.js +291 -291
  6. package/lib/motion/demo-assets-lock.js +10 -10
  7. package/lib/motion/mgstyles/briefs/23-ink-wash.md +147 -0
  8. package/lib/motion/mgstyles/catalog.d/23-ink-wash.json +28 -0
  9. package/lib/motion/mgstyles/catalog.json +127 -14
  10. package/lib/motion/mgstyles/upstream/demos/23-ink-wash/brush.js +149 -0
  11. package/lib/motion/mgstyles/upstream/demos/23-ink-wash/film.js +202 -0
  12. package/lib/motion/mgstyles/upstream/manifest.json +28 -3
  13. package/lib/motion/mgstyles/upstream/prompts/23-ink-wash.md +59 -0
  14. package/lib/motion/mgstyles/vendor/README.md +28 -28
  15. package/lib/motion/mgstyles/vendor/modules/d3/LICENSE +13 -13
  16. package/lib/motion/mgstyles/vendor/modules/d3/dist/d3.min.js +2 -2
  17. package/lib/motion/mgstyles/vendor/modules/opentype.js/LICENSE +20 -20
  18. package/lib/motion/mgstyles/vendor/modules/opentype.js/dist/opentype.mjs +14460 -14460
  19. package/lib/motion/mgstyles/vendor/modules/simplex-noise/LICENSE +21 -21
  20. package/lib/motion/mgstyles/vendor/modules/simplex-noise/dist/esm/simplex-noise.js +465 -465
  21. package/lib/motion/mgstyles/vendor/modules/topojson-client/LICENSE +13 -13
  22. package/lib/motion/mgstyles/vendor/modules/topojson-client/dist/topojson-client.min.js +2 -2
  23. package/lib/motion/project.js +5 -1
  24. package/lib/motion/qa.js +116 -6
  25. package/lib/motion/render.js +179 -179
  26. package/lib/motion/scene-kit.js +1 -1
  27. package/lib/motion/shotcraft/upstream/SKILL.md +286 -286
  28. package/lib/motion/shotcraft/upstream/assets/lib/Caption.tsx +54 -54
  29. package/lib/motion/shotcraft/upstream/assets/lib/ClipCard.tsx +200 -200
  30. package/lib/motion/shotcraft/upstream/assets/lib/DigitRoll.tsx +45 -45
  31. package/lib/motion/shotcraft/upstream/assets/lib/FlashCut.tsx +20 -20
  32. package/lib/motion/shotcraft/upstream/assets/lib/FlatPanel.tsx +65 -65
  33. package/lib/motion/shotcraft/upstream/assets/lib/PageCam.tsx +151 -151
  34. package/lib/motion/shotcraft/upstream/assets/lib/VerticalTicker.tsx +129 -129
  35. package/lib/motion/shotcraft/upstream/assets/lib/helpers/camera.tsx +75 -75
  36. package/lib/motion/shotcraft/upstream/assets/lib/helpers/motion.ts +40 -40
  37. package/lib/motion/shotcraft/upstream/assets/lib/helpers/rand.ts +11 -11
  38. package/lib/motion/shotcraft/upstream/assets/lib/helpers/shake.ts +10 -10
  39. package/lib/motion/shotcraft/upstream/assets/scripts/build-readme-cover.mjs +49 -49
  40. package/lib/motion/shotcraft/upstream/assets/scripts/capture-template.mjs +210 -210
  41. package/lib/motion/shotcraft/upstream/assets/scripts/sfx-source.py +423 -423
  42. package/lib/motion/shotcraft/upstream/assets/scripts/smoke-render-demos.py +170 -170
  43. package/lib/motion/shotcraft/upstream/assets/scripts/test_sfx_source.py +157 -157
  44. package/lib/motion/shotcraft/upstream/demos/README.md +120 -120
  45. package/lib/motion/shotcraft/upstream/demos/_fixtures/Brand.tsx +112 -112
  46. package/lib/motion/shotcraft/upstream/demos/_fixtures/Fixtures.tsx +647 -647
  47. package/lib/motion/shotcraft/upstream/demos/_fixtures/Look.tsx +316 -316
  48. package/lib/motion/shotcraft/upstream/demos/_fixtures/Motion.tsx +82 -82
  49. package/lib/motion/shotcraft/upstream/demos/_fixtures/PageCam2D.tsx +115 -115
  50. package/lib/motion/shotcraft/upstream/demos/_fixtures/Polish.tsx +243 -243
  51. package/lib/motion/shotcraft/upstream/demos/_textures/live-layout.json +388 -388
  52. package/lib/motion/shotcraft/upstream/demos/camera/basic-3d-scene/Basic3DScene.tsx +250 -250
  53. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashImpactReal.tsx +305 -305
  54. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashZoomReal.tsx +246 -246
  55. package/lib/motion/shotcraft/upstream/demos/camera/cursor-flyover/CursorFlyover.tsx +390 -390
  56. package/lib/motion/shotcraft/upstream/demos/camera/depth-layer-moves/MultiplaneReal.tsx +138 -138
  57. package/lib/motion/shotcraft/upstream/demos/camera/graze-face-tour/GrazeFaceTour.tsx +542 -542
  58. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx +315 -315
  59. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/TiltReveal.tsx +299 -299
  60. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/DroneDiveLanding.tsx +173 -173
  61. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/ExplodedView.tsx +348 -348
  62. package/lib/motion/shotcraft/upstream/demos/camera/steep-tilt-glide/SteepTiltGlide.tsx +366 -366
  63. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/BulletTimeFreezeOrbit.tsx +279 -279
  64. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/PullBackIsolation.tsx +184 -184
  65. package/lib/motion/shotcraft/upstream/demos/camera/terminal-3d/Terminal3D.tsx +390 -390
  66. package/lib/motion/shotcraft/upstream/demos/data/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +155 -155
  67. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/AxisRescaleShockV2.tsx +303 -303
  68. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/OscilloscopeStreamV2.tsx +290 -290
  69. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/UnitDotSwarmRegroupV2.tsx +278 -278
  70. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/NeedleSweepSelftest.tsx +307 -307
  71. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/TapeScrollFixedPointer.tsx +215 -215
  72. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/BrakeReticleLock.tsx +299 -299
  73. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/ChangelogScrollBrake.tsx +232 -232
  74. package/lib/motion/shotcraft/upstream/demos/data/timeline-travel/TimelineTravel.tsx +290 -290
  75. package/lib/motion/shotcraft/upstream/demos/effects/assemble-then-type-flyin/AssembleThenTypeFlyin.tsx +273 -273
  76. package/lib/motion/shotcraft/upstream/demos/effects/aurora-bloom-bg-flip/AuroraBloomBgFlip.tsx +167 -167
  77. package/lib/motion/shotcraft/upstream/demos/effects/brand-frame-snap/BrandFrameSnap.tsx +536 -536
  78. package/lib/motion/shotcraft/upstream/demos/effects/fui-hud-moves/ReticleLockOn.tsx +164 -164
  79. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/FlylineArc.tsx +175 -175
  80. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/GlowOrbAmbient.tsx +197 -197
  81. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/OrbFlylineRelay.tsx +241 -241
  82. package/lib/motion/shotcraft/upstream/demos/effects/icon-performance-moves/AttentionBounce.tsx +279 -279
  83. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/AnimeImpact.tsx +230 -230
  84. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/HitCounter.tsx +345 -345
  85. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SheenSweepRetry.tsx +275 -275
  86. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SpotlightSweepReveal.tsx +229 -229
  87. package/lib/motion/shotcraft/upstream/demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx +312 -312
  88. package/lib/motion/shotcraft/upstream/demos/effects/riso-print-hits/RisoMisregistrationHit.tsx +222 -222
  89. package/lib/motion/shotcraft/upstream/demos/effects/scan-bracket-sweep/ScanBracketSweep.tsx +295 -295
  90. package/lib/motion/shotcraft/upstream/demos/effects/scanline-annotate-focus/ScanlineAnnotateFocus.tsx +329 -329
  91. package/lib/motion/shotcraft/upstream/demos/effects/scanline-assemble-flyin/ScanlineAssembleFlyin.tsx +315 -315
  92. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ImpactBurstKit.tsx +264 -264
  93. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/KanadaPerspectiveSnap.tsx +260 -260
  94. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ScoreSlam.tsx +263 -263
  95. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/CornerSpotlightReveal.tsx +123 -123
  96. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +187 -187
  97. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/SlideSpotlightPan.tsx +175 -175
  98. package/lib/motion/shotcraft/upstream/demos/interaction/autolayout-gap-dial/AutolayoutGapDial.tsx +305 -305
  99. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/DiagramCascadeBuild.tsx +350 -350
  100. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +352 -352
  101. package/lib/motion/shotcraft/upstream/demos/interaction/chip-grid-single-select-blackout/ChipGridSingleSelectBlackout.tsx +218 -218
  102. package/lib/motion/shotcraft/upstream/demos/interaction/collab-cursor-moves/CursorCastEnsemble.tsx +297 -297
  103. package/lib/motion/shotcraft/upstream/demos/interaction/glass-pill-dictation-typing/GlassPillDictationTyping.tsx +157 -157
  104. package/lib/motion/shotcraft/upstream/demos/interaction/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +218 -218
  105. package/lib/motion/shotcraft/upstream/demos/interaction/picker-carousel-feature-cycle/PickerCarouselFeatureCycle.tsx +202 -202
  106. package/lib/motion/shotcraft/upstream/demos/interaction/segmented-thumb-hero/SegmentedThumbHero.tsx +265 -265
  107. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/PaletteThemeRipple.tsx +457 -457
  108. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/ThemeSweepToggle.tsx +446 -446
  109. package/lib/motion/shotcraft/upstream/demos/interaction/type-and-filter/TypeAndFilter.tsx +249 -249
  110. package/lib/motion/shotcraft/upstream/demos/interaction/voice-waveform-live/VoiceWaveformLive.tsx +278 -278
  111. package/lib/motion/shotcraft/upstream/demos/opening/crane-rise-reveal/CraneRiseReveal.tsx +332 -332
  112. package/lib/motion/shotcraft/upstream/demos/opening/dataviz-landscape-open/DatavizLandscapeOpen.tsx +358 -358
  113. package/lib/motion/shotcraft/upstream/demos/opening/fracture/Fracture.tsx +201 -201
  114. package/lib/motion/shotcraft/upstream/demos/opening/icon-field-colorize/IconFieldColorize.tsx +200 -200
  115. package/lib/motion/shotcraft/upstream/demos/opening/letterspace-materialize/LetterspaceMaterialize.tsx +208 -208
  116. package/lib/motion/shotcraft/upstream/demos/opening/magician-card-flourish/MagicianCardFlourish.tsx +341 -341
  117. package/lib/motion/shotcraft/upstream/demos/opening/orbit-ring-title-open/OrbitRingTitleOpen.tsx +389 -389
  118. package/lib/motion/shotcraft/upstream/demos/opening/spotlight-hero-card/SpotlightHeroCard.tsx +293 -293
  119. package/lib/motion/shotcraft/upstream/demos/opening/stroke-segment-build/StrokeSegmentBuild.tsx +183 -183
  120. package/lib/motion/shotcraft/upstream/demos/opening/text-as-mask/TextAsMask.tsx +245 -245
  121. package/lib/motion/shotcraft/upstream/demos/outro/grain-dissolve/GrainDissolve.tsx +222 -222
  122. package/lib/motion/shotcraft/upstream/demos/outro/logo-shrink-wordmark-lockup/LogoShrinkWordmarkLockup.tsx +223 -223
  123. package/lib/motion/shotcraft/upstream/demos/outro/neon-triple-marquee/NeonTripleMarquee.tsx +217 -217
  124. package/lib/motion/shotcraft/upstream/demos/outro/outro-group-photo-launch/OutroGroupPhotoLaunch.tsx +343 -343
  125. package/lib/motion/shotcraft/upstream/demos/outro/ui-strip-away-outro/UiStripAwayOutro.tsx +357 -357
  126. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/IconFlipBloomLogo.tsx +187 -187
  127. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/InputMorphsIntoLogo.tsx +333 -333
  128. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-cut-moves/PaparazziFlash.tsx +274 -274
  129. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +270 -270
  130. package/lib/motion/shotcraft/upstream/demos/rhythm/panel-grid-moves/ComicPanelSplit.tsx +430 -430
  131. package/lib/motion/shotcraft/upstream/demos/rhythm/quad-split-parallel-scenes/QuadSplitParallelScenes.tsx +252 -252
  132. package/lib/motion/shotcraft/upstream/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx +106 -106
  133. package/lib/motion/shotcraft/upstream/demos/rhythm/sakuga-timing-shift/SakugaTimingShift.tsx +288 -288
  134. package/lib/motion/shotcraft/upstream/demos/rhythm/speed-ramp-freeze/FreezeAnnotateReal.tsx +362 -362
  135. package/lib/motion/shotcraft/upstream/demos/rhythm/trailer-grammar-moves/TrailerBumper.tsx +168 -168
  136. package/lib/motion/shotcraft/upstream/demos/transition/bottom-push-stack-wipe/BottomPushStackWipe.tsx +310 -310
  137. package/lib/motion/shotcraft/upstream/demos/transition/card-flip-reveal/CardFlipReveal.tsx +261 -261
  138. package/lib/motion/shotcraft/upstream/demos/transition/card-flock-tumble/CardFlockTumble.tsx +459 -459
  139. package/lib/motion/shotcraft/upstream/demos/transition/circle-match-iris/CircleMatchIris.tsx +294 -294
  140. package/lib/motion/shotcraft/upstream/demos/transition/gradient-transition/GradientTransition.tsx +161 -161
  141. package/lib/motion/shotcraft/upstream/demos/transition/line-carry-transition/LineCarryTransition.tsx +248 -248
  142. package/lib/motion/shotcraft/upstream/demos/transition/mosaic-reframe/MosaicReframe.tsx +359 -359
  143. package/lib/motion/shotcraft/upstream/demos/transition/page-turn-transitions/BarnDoorSplit.tsx +227 -227
  144. package/lib/motion/shotcraft/upstream/demos/transition/print-texture-transitions/InkBleedReveal.tsx +162 -162
  145. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/PortalWipeV2.tsx +248 -248
  146. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/WhipBrakeReal.tsx +186 -186
  147. package/lib/motion/shotcraft/upstream/demos/transition/tear-streak-transitions/GlitchDisplace.tsx +355 -355
  148. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/InvisibleCut.tsx +272 -272
  149. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/LightLeakBurn.tsx +262 -262
  150. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/VersusSlam.tsx +217 -217
  151. package/lib/motion/shotcraft/upstream/demos/transition/transition-travel/LetterformZoom.tsx +285 -285
  152. package/lib/motion/shotcraft/upstream/demos/transition/white-flash-logo-simplify-cut/WhiteFlashLogoSimplifyCut.tsx +205 -205
  153. package/lib/motion/shotcraft/upstream/demos/transition/wipe-transitions/BlindsSlice.tsx +178 -178
  154. package/lib/motion/shotcraft/upstream/demos/typography/blur-slide/BlurSlide.tsx +147 -147
  155. package/lib/motion/shotcraft/upstream/demos/typography/brace-expand/BraceExpand.tsx +143 -143
  156. package/lib/motion/shotcraft/upstream/demos/typography/brand-ink-open/BrandInkOpen.tsx +134 -134
  157. package/lib/motion/shotcraft/upstream/demos/typography/countdown-arc-scatter/CountdownArcScatter.tsx +217 -217
  158. package/lib/motion/shotcraft/upstream/demos/typography/flying-words/FlyingWords.tsx +198 -198
  159. package/lib/motion/shotcraft/upstream/demos/typography/glitch-cycle/GlitchCycle.tsx +221 -221
  160. package/lib/motion/shotcraft/upstream/demos/typography/gradient-word-sweep/GradientWordSweep.tsx +312 -312
  161. package/lib/motion/shotcraft/upstream/demos/typography/lead-word-zoom-assemble/LeadWordZoomAssemble.tsx +261 -261
  162. package/lib/motion/shotcraft/upstream/demos/typography/marker-underline-title/MarkerUnderlineTitle.tsx +121 -121
  163. package/lib/motion/shotcraft/upstream/demos/typography/outline-word-fill/OutlineWordFill.tsx +153 -153
  164. package/lib/motion/shotcraft/upstream/demos/typography/paper-title-card/PaperTitleCard.tsx +179 -179
  165. package/lib/motion/shotcraft/upstream/demos/typography/pill-chip-slot-cycle-handled/PillChipSlotCycleHandled.tsx +140 -140
  166. package/lib/motion/shotcraft/upstream/demos/typography/pill-slot-cycle/PillSlotCycle.tsx +309 -309
  167. package/lib/motion/shotcraft/upstream/demos/typography/text-column-converge/TextColumnConverge.tsx +191 -191
  168. package/lib/motion/shotcraft/upstream/demos/typography/title-demote-to-label/TitleDemoteToLabel.tsx +292 -292
  169. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/LetterformDriftAssembly.tsx +135 -135
  170. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/SplitTextStagger.tsx +124 -124
  171. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/TextOnPath.tsx +255 -255
  172. package/lib/motion/shotcraft/upstream/demos/typography/type-entrance-moves/LetterDropPhysics.tsx +173 -173
  173. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/FontWeightPump.tsx +225 -225
  174. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/KaraokeFillSync.tsx +141 -141
  175. package/lib/motion/shotcraft/upstream/demos/typography/typewriter-moves/TypewriterErrorRetype.tsx +137 -137
  176. package/lib/motion/shotcraft/upstream/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx +147 -147
  177. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-filmstrip/WordRelayFilmstrip.tsx +409 -409
  178. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-geometry/WordRelayGeometry.tsx +280 -280
  179. package/lib/motion/shotcraft/upstream/demos/ui-entrance/avatar-bracket-carousel/AvatarBracketCarousel.tsx +271 -271
  180. package/lib/motion/shotcraft/upstream/demos/ui-entrance/bezier-source-converge-merge/BezierSourceConvergeMerge.tsx +385 -385
  181. package/lib/motion/shotcraft/upstream/demos/ui-entrance/card-stack/CardStack.tsx +312 -312
  182. package/lib/motion/shotcraft/upstream/demos/ui-entrance/carousel-3d/Carousel3D.tsx +303 -303
  183. package/lib/motion/shotcraft/upstream/demos/ui-entrance/clipcard-looping/ClipCardLooping.tsx +77 -77
  184. package/lib/motion/shotcraft/upstream/demos/ui-entrance/cloner-depth-echo/ClonerDepthEcho.tsx +311 -311
  185. package/lib/motion/shotcraft/upstream/demos/ui-entrance/deck-deal-flyin/DeckDealFlyin.tsx +307 -307
  186. package/lib/motion/shotcraft/upstream/demos/ui-entrance/doc-park-left-pill-deal/DocParkLeftPillDeal.tsx +349 -349
  187. package/lib/motion/shotcraft/upstream/demos/ui-entrance/document-typewriter-reveal/DocumentTypewriterReveal.tsx +255 -255
  188. package/lib/motion/shotcraft/upstream/demos/ui-entrance/draw-svg-trace/DrawSvgTrace.tsx +244 -244
  189. package/lib/motion/shotcraft/upstream/demos/ui-entrance/element-body-moves/ContactShadowLift.tsx +217 -217
  190. package/lib/motion/shotcraft/upstream/demos/ui-entrance/integration-hub-map/IntegrationHubMap.tsx +652 -652
  191. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-reveal/ListReveal.tsx +153 -153
  192. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-stack-press/ListStackPress.tsx +238 -238
  193. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx +324 -324
  194. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +354 -354
  195. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/PageWaterfallWall.tsx +101 -101
  196. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/VerticalTicker.tsx +129 -129
  197. package/lib/motion/shotcraft/upstream/demos/ui-entrance/product-card-progressive-assemble/ProductCardProgressiveAssemble.tsx +297 -297
  198. package/lib/motion/shotcraft/upstream/demos/ui-entrance/radial-wave/RadialWave.tsx +57 -57
  199. package/lib/motion/shotcraft/upstream/demos/ui-entrance/research-card-stack-scroll/ResearchCardStackScroll.tsx +155 -155
  200. package/lib/motion/shotcraft/upstream/demos/ui-entrance/row-embed/RowEmbed.tsx +175 -175
  201. package/lib/motion/shotcraft/upstream/demos/ui-entrance/value-stagger-gradient/ValueStaggerGradient.tsx +153 -153
  202. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/BentoLightUp.tsx +146 -146
  203. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/WireframeDrawOn.tsx +226 -226
  204. package/lib/motion/shotcraft/upstream/gallery/api/library.json +1 -1
  205. package/lib/motion/shotcraft/upstream/references/aesthetic-rules.md +193 -193
  206. package/lib/motion/shotcraft/upstream/references/final-review.md +121 -121
  207. package/lib/motion/shotcraft/upstream/references/guided-free-creation.md +199 -199
  208. package/lib/motion/shotcraft/upstream/references/jianying-export.md +183 -183
  209. package/lib/motion/shotcraft/upstream/references/music-beat-sync.md +257 -257
  210. package/lib/motion/shotcraft/upstream/references/pipeline.md +382 -382
  211. package/lib/motion/shotcraft/upstream/references/publish-upload-post.md +111 -111
  212. package/lib/motion/shotcraft/upstream/references/sequences/promo-energy-arc.md +50 -50
  213. package/lib/motion/shotcraft/upstream/references/sfx-sourcing.md +95 -95
  214. package/lib/motion/shotcraft/upstream/references/shots/camera/basic-3d-scene.md +41 -41
  215. package/lib/motion/shotcraft/upstream/references/shots/camera/crash-zoom-punch.md +52 -52
  216. package/lib/motion/shotcraft/upstream/references/shots/camera/cursor-flyover.md +39 -39
  217. package/lib/motion/shotcraft/upstream/references/shots/camera/depth-layer-moves.md +39 -39
  218. package/lib/motion/shotcraft/upstream/references/shots/camera/graze-face-tour.md +57 -57
  219. package/lib/motion/shotcraft/upstream/references/shots/camera/overhead-camera-moves.md +51 -51
  220. package/lib/motion/shotcraft/upstream/references/shots/camera/space-camera-moves.md +46 -46
  221. package/lib/motion/shotcraft/upstream/references/shots/camera/steep-tilt-glide.md +52 -52
  222. package/lib/motion/shotcraft/upstream/references/shots/camera/tension-camera-moves.md +43 -43
  223. package/lib/motion/shotcraft/upstream/references/shots/camera/terminal-3d.md +42 -42
  224. package/lib/motion/shotcraft/upstream/references/shots/data/before-after-slider-scrub.md +48 -48
  225. package/lib/motion/shotcraft/upstream/references/shots/data/chart-live-moves.md +52 -52
  226. package/lib/motion/shotcraft/upstream/references/shots/data/gauge-readout-moves.md +45 -45
  227. package/lib/motion/shotcraft/upstream/references/shots/data/scroll-brake-moves.md +46 -46
  228. package/lib/motion/shotcraft/upstream/references/shots/data/timeline-travel.md +44 -44
  229. package/lib/motion/shotcraft/upstream/references/shots/effects/assemble-then-type-flyin.md +63 -63
  230. package/lib/motion/shotcraft/upstream/references/shots/effects/aurora-bloom-bg-flip.md +54 -54
  231. package/lib/motion/shotcraft/upstream/references/shots/effects/brand-frame-snap.md +58 -58
  232. package/lib/motion/shotcraft/upstream/references/shots/effects/fui-hud-moves.md +35 -35
  233. package/lib/motion/shotcraft/upstream/references/shots/effects/glow-flyline-moves.md +53 -53
  234. package/lib/motion/shotcraft/upstream/references/shots/effects/icon-performance-moves.md +42 -42
  235. package/lib/motion/shotcraft/upstream/references/shots/effects/impact-feedback.md +50 -50
  236. package/lib/motion/shotcraft/upstream/references/shots/effects/light-play-moves.md +46 -46
  237. package/lib/motion/shotcraft/upstream/references/shots/effects/radial-ripple-phone-chips.md +56 -56
  238. package/lib/motion/shotcraft/upstream/references/shots/effects/riso-print-hits.md +49 -49
  239. package/lib/motion/shotcraft/upstream/references/shots/effects/scan-bracket-sweep.md +50 -50
  240. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-annotate-focus.md +53 -53
  241. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-assemble-flyin.md +53 -53
  242. package/lib/motion/shotcraft/upstream/references/shots/effects/slam-entrance-moves.md +55 -55
  243. package/lib/motion/shotcraft/upstream/references/shots/effects/spotlight-sweep-moves.md +52 -52
  244. package/lib/motion/shotcraft/upstream/references/shots/interaction/autolayout-gap-dial.md +60 -60
  245. package/lib/motion/shotcraft/upstream/references/shots/interaction/canvas-materialize-moves.md +57 -57
  246. package/lib/motion/shotcraft/upstream/references/shots/interaction/chip-grid-single-select-blackout.md +51 -51
  247. package/lib/motion/shotcraft/upstream/references/shots/interaction/collab-cursor-moves.md +41 -41
  248. package/lib/motion/shotcraft/upstream/references/shots/interaction/glass-pill-dictation-typing.md +53 -53
  249. package/lib/motion/shotcraft/upstream/references/shots/interaction/hashtag-to-pill-materialize.md +60 -60
  250. package/lib/motion/shotcraft/upstream/references/shots/interaction/picker-carousel-feature-cycle.md +55 -55
  251. package/lib/motion/shotcraft/upstream/references/shots/interaction/segmented-thumb-hero.md +57 -57
  252. package/lib/motion/shotcraft/upstream/references/shots/interaction/theme-switch-moves.md +47 -47
  253. package/lib/motion/shotcraft/upstream/references/shots/interaction/type-and-filter.md +37 -37
  254. package/lib/motion/shotcraft/upstream/references/shots/interaction/voice-waveform-live.md +54 -54
  255. package/lib/motion/shotcraft/upstream/references/shots/opening/brand-ink-open.md +36 -36
  256. package/lib/motion/shotcraft/upstream/references/shots/opening/crane-rise-reveal.md +56 -56
  257. package/lib/motion/shotcraft/upstream/references/shots/opening/dataviz-landscape-open.md +56 -56
  258. package/lib/motion/shotcraft/upstream/references/shots/opening/fracture.md +40 -40
  259. package/lib/motion/shotcraft/upstream/references/shots/opening/icon-field-colorize.md +60 -60
  260. package/lib/motion/shotcraft/upstream/references/shots/opening/letterspace-materialize.md +57 -57
  261. package/lib/motion/shotcraft/upstream/references/shots/opening/magician-card-flourish.md +73 -73
  262. package/lib/motion/shotcraft/upstream/references/shots/opening/orbit-ring-title-open.md +87 -87
  263. package/lib/motion/shotcraft/upstream/references/shots/opening/spotlight-hero-card.md +55 -55
  264. package/lib/motion/shotcraft/upstream/references/shots/opening/stroke-segment-build.md +50 -50
  265. package/lib/motion/shotcraft/upstream/references/shots/opening/text-as-mask.md +59 -59
  266. package/lib/motion/shotcraft/upstream/references/shots/outro/grain-dissolve.md +38 -38
  267. package/lib/motion/shotcraft/upstream/references/shots/outro/logo-shrink-wordmark-lockup.md +38 -38
  268. package/lib/motion/shotcraft/upstream/references/shots/outro/neon-triple-marquee.md +59 -59
  269. package/lib/motion/shotcraft/upstream/references/shots/outro/outro-group-photo-launch.md +39 -39
  270. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-strip-away-outro.md +61 -61
  271. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-to-brand-morph.md +52 -52
  272. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-cut-moves.md +50 -50
  273. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-step-list-theme-cycle.md +66 -66
  274. package/lib/motion/shotcraft/upstream/references/shots/rhythm/panel-grid-moves.md +43 -43
  275. package/lib/motion/shotcraft/upstream/references/shots/rhythm/quad-split-parallel-scenes.md +38 -38
  276. package/lib/motion/shotcraft/upstream/references/shots/rhythm/rhythm-interrupt-moves.md +38 -38
  277. package/lib/motion/shotcraft/upstream/references/shots/rhythm/sakuga-timing-shift.md +56 -56
  278. package/lib/motion/shotcraft/upstream/references/shots/rhythm/speed-ramp-freeze.md +44 -44
  279. package/lib/motion/shotcraft/upstream/references/shots/rhythm/trailer-grammar-moves.md +38 -38
  280. package/lib/motion/shotcraft/upstream/references/shots/transition/bottom-push-stack-wipe.md +63 -63
  281. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flip-reveal.md +57 -57
  282. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flock-tumble.md +63 -63
  283. package/lib/motion/shotcraft/upstream/references/shots/transition/circle-match-iris.md +58 -58
  284. package/lib/motion/shotcraft/upstream/references/shots/transition/gradient-transition.md +45 -45
  285. package/lib/motion/shotcraft/upstream/references/shots/transition/line-carry-transition.md +55 -55
  286. package/lib/motion/shotcraft/upstream/references/shots/transition/mosaic-reframe.md +49 -49
  287. package/lib/motion/shotcraft/upstream/references/shots/transition/page-turn-transitions.md +42 -42
  288. package/lib/motion/shotcraft/upstream/references/shots/transition/print-texture-transitions.md +42 -42
  289. package/lib/motion/shotcraft/upstream/references/shots/transition/shot-transitions.md +45 -45
  290. package/lib/motion/shotcraft/upstream/references/shots/transition/tear-streak-transitions.md +48 -48
  291. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-hidden-cut.md +55 -55
  292. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-travel.md +43 -43
  293. package/lib/motion/shotcraft/upstream/references/shots/transition/white-flash-logo-simplify-cut.md +41 -41
  294. package/lib/motion/shotcraft/upstream/references/shots/transition/wipe-transitions.md +42 -42
  295. package/lib/motion/shotcraft/upstream/references/shots/typography/blur-slide.md +59 -59
  296. package/lib/motion/shotcraft/upstream/references/shots/typography/brace-expand.md +55 -55
  297. package/lib/motion/shotcraft/upstream/references/shots/typography/countdown-arc-scatter.md +65 -65
  298. package/lib/motion/shotcraft/upstream/references/shots/typography/document-typewriter-reveal.md +42 -42
  299. package/lib/motion/shotcraft/upstream/references/shots/typography/flying-words.md +64 -64
  300. package/lib/motion/shotcraft/upstream/references/shots/typography/glitch-cycle.md +64 -64
  301. package/lib/motion/shotcraft/upstream/references/shots/typography/gradient-word-sweep.md +54 -54
  302. package/lib/motion/shotcraft/upstream/references/shots/typography/lead-word-zoom-assemble.md +91 -91
  303. package/lib/motion/shotcraft/upstream/references/shots/typography/marker-underline-title.md +51 -51
  304. package/lib/motion/shotcraft/upstream/references/shots/typography/outline-word-fill.md +66 -66
  305. package/lib/motion/shotcraft/upstream/references/shots/typography/paper-title-card.md +38 -38
  306. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-chip-slot-cycle-handled.md +66 -66
  307. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-slot-cycle.md +58 -58
  308. package/lib/motion/shotcraft/upstream/references/shots/typography/text-column-converge.md +61 -61
  309. package/lib/motion/shotcraft/upstream/references/shots/typography/title-demote-to-label.md +64 -64
  310. package/lib/motion/shotcraft/upstream/references/shots/typography/type-assembly-moves.md +45 -45
  311. package/lib/motion/shotcraft/upstream/references/shots/typography/type-entrance-moves.md +41 -41
  312. package/lib/motion/shotcraft/upstream/references/shots/typography/type-rhythm-sync.md +51 -51
  313. package/lib/motion/shotcraft/upstream/references/shots/typography/typewriter-moves.md +42 -42
  314. package/lib/motion/shotcraft/upstream/references/shots/typography/vertical-word-roll-blur-cycle.md +63 -63
  315. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-filmstrip.md +57 -57
  316. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-geometry.md +75 -75
  317. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/avatar-bracket-carousel.md +59 -59
  318. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/bezier-source-converge-merge.md +67 -67
  319. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/card-stack.md +60 -60
  320. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/carousel-3d.md +66 -66
  321. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/cloner-depth-echo.md +40 -40
  322. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/deck-deal-flyin.md +45 -45
  323. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/doc-park-left-pill-deal.md +62 -62
  324. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/draw-svg-trace.md +55 -55
  325. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/element-body-moves.md +37 -37
  326. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/integration-hub-map.md +55 -55
  327. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-reveal.md +50 -50
  328. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-stack-press.md +43 -43
  329. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-forerun.md +55 -55
  330. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-orbit-drop.md +51 -51
  331. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/page-waterfall-wall.md +51 -51
  332. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/product-card-progressive-assemble.md +56 -56
  333. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/radial-wave.md +49 -49
  334. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/research-card-stack-scroll.md +57 -57
  335. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/row-embed.md +36 -36
  336. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/value-stagger-gradient.md +64 -64
  337. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/wall-reveal-moves.md +47 -47
  338. package/lib/motion/shotcraft/upstream/references/sound-design.md +170 -170
  339. package/lib/motion/shotcraft/upstream/references/workbench.md +157 -157
  340. package/lib/motion/shotcraft/upstream/template/TEMPLATE.md +103 -103
  341. package/lib/motion/shotcraft/upstream/template/THEMES.md +44 -44
  342. package/lib/motion/shotcraft/upstream/template/package.json +20 -20
  343. package/lib/motion/shotcraft/upstream/template/remotion.config.ts +6 -6
  344. package/lib/motion/shotcraft/upstream/template/src/Root.tsx +17 -17
  345. package/lib/motion/shotcraft/upstream/template/src/aifl/Caption.tsx +65 -65
  346. package/lib/motion/shotcraft/upstream/template/src/aifl/DigitRoll.tsx +48 -48
  347. package/lib/motion/shotcraft/upstream/template/src/aifl/FlashCut.tsx +24 -24
  348. package/lib/motion/shotcraft/upstream/template/src/aifl/Main.tsx +192 -192
  349. package/lib/motion/shotcraft/upstream/template/src/aifl/PaperTitleCard.tsx +111 -111
  350. package/lib/motion/shotcraft/upstream/template/src/aifl/live/PageCam.tsx +150 -150
  351. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneDetail.tsx +158 -158
  352. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneFlyIn.tsx +468 -468
  353. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOpen.tsx +552 -552
  354. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOutroLive.tsx +411 -411
  355. package/lib/motion/shotcraft/upstream/template/src/aifl/live/ScenePapers.tsx +200 -200
  356. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneWbr.tsx +324 -324
  357. package/lib/motion/shotcraft/upstream/template/src/aifl/live-layout.json +388 -388
  358. package/lib/motion/shotcraft/upstream/template/src/index.ts +4 -4
  359. package/lib/motion/shotcraft/upstream/template/src/themes/ThemedFilm.tsx +7 -7
  360. package/lib/motion/shotcraft/upstream/template/src/themes/manifest.tsx +68 -68
  361. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.json +1 -1
  362. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.ts +24 -24
  363. package/lib/motion/shotcraft/upstream/template/src/themes/palettes.json +74 -74
  364. package/lib/motion/shotcraft/upstream/template/src/themes/visual-theme.tsx +91 -91
  365. package/lib/motion/shotcraft/upstream/template/src/workbench.ts +213 -213
  366. package/lib/motion/shotcraft/upstream/template/tsconfig.json +15 -15
  367. package/lib/motion/style-frames.js +306 -306
  368. package/lib/motion/sync.js +214 -214
  369. package/lib/motion-library.js +1 -1
  370. package/lib/motion-project.js +105 -105
  371. package/lib/motion-render-worker.js +174 -174
  372. package/lib/routing/router.js +222 -222
  373. package/lib/routing/vendor/README.md +96 -96
  374. package/lib/routing/vendor/libavoid-routing.js +753 -753
  375. package/lib/routing/vendor/libavoid.min.js +59 -59
  376. package/lib/svg-export.js +1344 -0
  377. package/lib/video-trace-pool.js +128 -128
  378. package/package.json +3 -2
  379. package/LICENSE +0 -4175
@@ -1,310 +1,310 @@
1
- // bottom-push-stack-wipe —— slack-promo 22–27s
2
- // 换章手法不变:新章连底色整屏从底边向上推入,把旧章刚性顶出画外(两层同速同缓动),连推三章,
3
- // 每章一种饱和底色,内容钉死在各自色底坐标系里随底色走;上缘接缝阴影是"顶出"的物理接触证据。
4
- //
5
- // 第二轮重设计(设计决定)
6
- // - look = custom「瑞士海报」:第 0 章近黑开场,三章是三块拉满的饱和色板——钴蓝 / 朱橙 / 酸柠,
7
- // 色相彼此拉开 120° 级,换章一眼读作"换了个世界"。产品是 video-shotcraft,一章一个卖点(一句话出片 / 踩点剪辑 / 自动交付)。
8
- // - 版式:左栏 120px 安全边距起排,眉题(章号 + 名称)→ 116px 超粗两行标题 → 40px 说明;
9
- // 右栏一张为镜头设计的大字 UI 卡(和 agent 对话 / 踩点时间线 / 交付流水线),字号 ≥ 30px;色板本身左上受光、右下压暗,
10
- // 卡片投带色相的两层软阴影(同一光向),平面海报里也有前后景。
11
- // - 推入:26f 重 ease-out(快进慢停的"哐"),整摞按速度做纵向方向性模糊;新章上缘 2px 受光边 +
12
- // 压在旧章上的 56px 接触影。推入窗口内章内元素全部静止(钉死),标题在落定前 ~8f 才从线下升起,
13
- // UI 卡的小动作(打字中 → 消息出现 / 说话声波 / 自动化逐步打勾)都放在 hold 里,避开推入。
14
- //
15
- // 时间表(30fps,170f)
16
- // 0–22 第 0 章:近黑底「Meet video-shotcraft.」已在画面,标题 0f 起逐行升起,2–20f 落定
17
- // 22–48 推入 01 钴蓝(26f 重 ease-out,~34f 已到 95%)→ 34f 标题升起 → 36–48f 第三条消息"打字中"→ 48f 弹入
18
- // 48–66 hold(读)
19
- // 66–92 推入 02 朱橙 → 78f 标题 → 声波与计时全程在跳,82f 起第二个镜头亮环
20
- // 92–110 hold
21
- // 110–136 推入 03 酸柠(深色字)→ 122f 标题 → 126/134/142f 三个步骤依次打勾(弹簧)
22
- // 142–170 hold 28f:极缓推近 1.5%,尾帧是完整的章节海报
23
- import React from 'react';
24
- import { AbsoluteFill, useCurrentFrame } from 'remotion';
25
- import { EASE, FONT, Grain, SpeedBlur, bezier, mix, ramp, softShadow, velocity } from '../../_fixtures/Polish';
26
- import { TextReveal, alpha, springAt, type } from '../../_fixtures/Look';
27
- import { BRAND, PITCH, ShotcraftMark, ShotcraftWordmark } from '../../_fixtures/Brand';
28
-
29
- const H = 1080;
30
-
31
- export const BOTTOM_PUSH_STACK_WIPE_DURATION = 170;
32
-
33
- const PUSH_STARTS = [22, 66, 110];
34
- const PUSH_DUR = 26;
35
- const heavyEaseOut = bezier(0.12, 0.9, 0.2, 1); // 快进慢停(md 钉死的推入曲线)
36
-
37
- type Chapter = {
38
- num: string; name: string; title: string; sub: string;
39
- hi: string; base: string; lo: string; shade: string; ink: string; ink2: string;
40
- };
41
- const CHAPTERS: Chapter[] = [
42
- {
43
- num: '00', name: 'Agent skill', title: `Meet\n${BRAND.name}.`, sub: PITCH.en.taglines[1],
44
- hi: '#1c1c1e', base: '#141415', lo: '#0c0c0d', shade: '#000000', ink: '#f4f2ee', ink2: 'rgba(244,242,238,0.62)',
45
- },
46
- {
47
- num: '01', name: 'Prompt', title: 'One prompt.\nOne film.', sub: 'Describe the promo. Your agent storyboards every shot.',
48
- hi: '#4565ff', base: '#2d4cff', lo: '#1c37e0', shade: '#0a1670', ink: '#ffffff', ink2: 'rgba(255,255,255,0.78)',
49
- },
50
- {
51
- num: '02', name: 'Rhythm', title: 'Cut on\nthe beat.', sub: 'Every shot lands on the music, frame for frame.',
52
- hi: '#ff6a3d', base: '#ff4d1f', lo: '#e83c10', shade: '#6e1600', ink: '#ffffff', ink2: 'rgba(255,255,255,0.8)',
53
- },
54
- {
55
- num: '03', name: 'Delivery', title: 'Delivery,\nautomated.', sub: 'Render, export and publish the moment the cut locks.',
56
- hi: '#dcfb5e', base: '#cdf23a', lo: '#b8dc22', shade: '#3c4a00', ink: '#121407', ink2: 'rgba(18,20,7,0.68)',
57
- },
58
- ];
59
-
60
- const pushP = (f: number, i: number) => ramp(f, PUSH_STARTS[i], PUSH_DUR, heavyEaseOut);
61
- const stackY = (f: number) => PUSH_STARTS.reduce((s, _, i) => s + pushP(f, i), 0) * H;
62
- // 每章"落定"帧(标题起升的参照);第 0 章 = 0
63
- const landAt = (i: number) => (i === 0 ? -10 : PUSH_STARTS[i - 1] + 12);
64
-
65
- const SANS = FONT.sans;
66
-
67
- // ───────────── UI 卡(为镜头设计:少元素、大字、强对比) ─────────────
68
- const Avatar: React.FC<{ c: string; t: string; size?: number; ring?: number; ringColor?: string; mark?: boolean }> = ({ c, t, size = 64, ring = 0, ringColor = '#fff', mark = false }) => (
69
- <div style={{
70
- width: size, height: size, borderRadius: size / 2, flex: 'none', background: c, color: '#fff',
71
- display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: SANS, fontWeight: 700,
72
- fontSize: size * 0.38, letterSpacing: '-0.01em',
73
- boxShadow: ring > 0 ? `0 0 0 ${4 + 6 * ring}px ${alpha(ringColor, 0.25 + 0.5 * ring)}` : undefined,
74
- }}>{mark ? <ShotcraftMark size={size * 0.62} tone="dark" /> : t}</div>
75
- );
76
-
77
- const ChannelCard: React.FC<{ frame: number }> = ({ frame }) => {
78
- const t0 = PUSH_STARTS[0] + 14; // 打字中提示(推入已到 95%)
79
- const typing = frame >= t0 && frame < t0 + 12;
80
- const msg = springAt(frame, t0 + 12, { damping: 18, stiffness: 200 });
81
- const msgs = [
82
- { c: '#7c5cff', t: 'MK', name: 'Maya', time: '9:41', text: 'Cut a 30s launch film for our app.', mark: false },
83
- { c: BRAND.ink, t: '', name: 'Shotcraft', time: '9:42', text: 'Storyboard ready: 12 shots, on beat.', mark: true },
84
- ];
85
- return (
86
- <div style={{ width: 760, padding: '40px 44px 44px', fontFamily: SANS, color: '#0e1020' }}>
87
- <div style={{ display: 'flex', alignItems: 'baseline', gap: 16, paddingBottom: 28, borderBottom: '2px solid rgba(14,16,32,0.08)' }}>
88
- <div style={{ ...type(44, 800), color: '#0e1020' }}># launch-film</div>
89
- <div style={{ marginLeft: 'auto', fontSize: 28, fontWeight: 500, color: '#7a7f99' }}>3 members</div>
90
- </div>
91
- {msgs.map((m, k) => (
92
- <div key={k} style={{ display: 'flex', gap: 22, marginTop: 32 }}>
93
- <Avatar c={m.c} t={m.t} mark={m.mark} />
94
- <div>
95
- <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
96
- <span style={{ fontSize: 32, fontWeight: 750, letterSpacing: '-0.015em' }}>{m.name}</span>
97
- <span style={{ fontSize: 24, color: '#9a9fb5', fontVariantNumeric: 'tabular-nums' }}>{m.time}</span>
98
- </div>
99
- <div style={{ fontSize: 32, fontWeight: 450, color: '#3a3f58', marginTop: 6, lineHeight: 1.25 }}>{m.text}</div>
100
- </div>
101
- </div>
102
- ))}
103
- {/* 第三条:打字中 → 消息弹入 */}
104
- <div style={{ position: 'relative', height: 132, marginTop: 32 }}>
105
- {typing && (
106
- <div style={{ position: 'absolute', left: 86, top: 20, display: 'flex', gap: 10, alignItems: 'center', padding: '18px 24px', borderRadius: 24, background: '#eef0fb' }}>
107
- {[0, 1, 2].map((d) => (
108
- <div key={d} style={{ width: 13, height: 13, borderRadius: 7, background: '#2d4cff', opacity: 0.35 + 0.65 * (0.5 + 0.5 * Math.sin((frame - t0) * 0.7 - d * 1.1)) }} />
109
- ))}
110
- </div>
111
- )}
112
- {frame >= t0 + 12 && (
113
- <div style={{ display: 'flex', gap: 22, opacity: Math.min(1, msg * 1.5), transform: `translateY(${((1 - msg) * 26).toFixed(2)}px)` }}>
114
- <Avatar c="#ff7a1a" t="IR" />
115
- <div>
116
- <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
117
- <span style={{ fontSize: 32, fontWeight: 750, letterSpacing: '-0.015em' }}>Ines</span>
118
- <span style={{ fontSize: 24, color: '#9a9fb5' }}>9:44</span>
119
- </div>
120
- <div style={{ display: 'flex', gap: 12, marginTop: 10 }}>
121
- <div style={{ fontSize: 32, fontWeight: 700, color: '#2d4cff', padding: '8px 22px', borderRadius: 999, background: '#e8ecff' }}>Render it ↗</div>
122
- </div>
123
- </div>
124
- </div>
125
- )}
126
- </div>
127
- </div>
128
- );
129
- };
130
-
131
- const HuddleCard: React.FC<{ frame: number }> = ({ frame }) => {
132
- const t = frame - PUSH_STARTS[1];
133
- const people = [
134
- { c: '#7c5cff', t: '01', name: 'Hook' },
135
- { c: '#00a37a', t: '02', name: 'Zoom' },
136
- { c: '#ff9f1c', t: '03', name: 'Whip' },
137
- { c: '#3a86ff', t: '04', name: 'Sting' },
138
- ];
139
- // 当前镜头:前段 01 Hook,82f 起交给 02 Zoom(环 6f 交叉,踩在拍点上换镜)
140
- const handoff = ramp(frame, PUSH_STARTS[1] + 16, 8, EASE.smooth);
141
- const speak = [1 - handoff, handoff, 0, 0];
142
- const secs = 12 + Math.floor(Math.max(0, t) / 30);
143
- return (
144
- <div style={{ width: 760, padding: '40px 44px 44px', fontFamily: SANS, color: '#f6f3ef' }}>
145
- <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
146
- <div style={{ width: 16, height: 16, borderRadius: 8, background: '#3ddc84', boxShadow: '0 0 0 6px rgba(61,220,132,0.18)' }} />
147
- <div style={{ ...type(40, 800) }}>Beat sync · 128 BPM</div>
148
- <div style={{ marginLeft: 'auto', fontSize: 32, fontWeight: 600, color: 'rgba(246,243,239,0.6)', fontFamily: FONT.mono }}>
149
- {String(Math.floor(secs / 60)).padStart(2, '0')}:{String(secs % 60).padStart(2, '0')}
150
- </div>
151
- </div>
152
- <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 52 }}>
153
- {people.map((p, k) => (
154
- <div key={k} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 18 }}>
155
- <Avatar c={p.c} t={p.t} size={124} ring={speak[k] * (0.75 + 0.25 * Math.sin(frame * 0.5))} ringColor="#3ddc84" />
156
- <div style={{ fontSize: 30, fontWeight: 600, color: speak[k] > 0.5 ? '#ffffff' : 'rgba(246,243,239,0.6)' }}>{p.name}</div>
157
- </div>
158
- ))}
159
- </div>
160
- {/* 声波:确定性正弦叠加 */}
161
- <div style={{ display: 'flex', alignItems: 'center', gap: 7, height: 96, marginTop: 44 }}>
162
- {Array.from({ length: 44 }, (_, j) => {
163
- const a = 0.5 + 0.5 * Math.sin(frame * 0.42 + j * 0.62) * Math.sin(frame * 0.17 + j * 0.23);
164
- const env = Math.sin((j / 43) * Math.PI);
165
- return <div key={j} style={{ flex: 1, height: `${(12 + 84 * a * env).toFixed(1)}%`, borderRadius: 4, background: j % 9 === 4 ? '#ff6a3d' : 'rgba(246,243,239,0.82)' }} />;
166
- })}
167
- </div>
168
- <div style={{ display: 'flex', gap: 18, marginTop: 40 }}>
169
- <div style={{ flex: 1, height: 76, borderRadius: 38, background: 'rgba(255,255,255,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 30, fontWeight: 650 }}>Preview</div>
170
- <div style={{ width: 210, height: 76, borderRadius: 38, background: '#ff4d1f', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 30, fontWeight: 700 }}>Render</div>
171
- </div>
172
- </div>
173
- );
174
- };
175
-
176
- const WorkflowCard: React.FC<{ frame: number }> = ({ frame }) => {
177
- const steps = ['Render 1080p master', 'Export JianYing draft', 'Post to the gallery'];
178
- const at = [PUSH_STARTS[2] + 16, PUSH_STARTS[2] + 24, PUSH_STARTS[2] + 32];
179
- return (
180
- <div style={{ width: 760, padding: '40px 44px 48px', fontFamily: SANS, color: '#121407' }}>
181
- <div style={{ fontSize: 26, fontWeight: 700, letterSpacing: '0.12em', color: '#7b8064', textTransform: 'uppercase' }}>Trigger</div>
182
- <div style={{ ...type(44, 800), marginTop: 12 }}>When the cut locks</div>
183
- <div style={{ position: 'relative', marginTop: 36 }}>
184
- {/* 竖向连接线:随打勾向下"灌注" */}
185
- <div style={{ position: 'absolute', left: 31, top: 56, height: 224, width: 3, background: 'rgba(18,20,7,0.1)' }} />
186
- <div style={{
187
- position: 'absolute', left: 31, top: 56, width: 3, background: '#121407',
188
- height: (ramp(frame, at[0], at[2] - at[0], EASE.swift) * (112 * 2)).toFixed(2) + 'px',
189
- }} />
190
- {steps.map((s, k) => {
191
- const c = springAt(frame, at[k], { damping: 14, stiffness: 240 });
192
- const on = frame >= at[k];
193
- return (
194
- <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 28, height: 112, position: 'relative' }}>
195
- <div style={{
196
- width: 64, height: 64, borderRadius: 32, flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center',
197
- background: on ? '#121407' : '#f3f5e6', boxShadow: on ? 'none' : 'inset 0 0 0 3px rgba(18,20,7,0.14)',
198
- transform: `scale(${on ? mix(0.6, 1, c).toFixed(4) : 1})`,
199
- }}>
200
- {on && (
201
- <svg width={30} height={30} viewBox="0 0 30 30">
202
- <path d="M7 15.5 L13 21 L23.5 9.5" fill="none" stroke="#cdf23a" strokeWidth={4.2} strokeLinecap="round" strokeLinejoin="round"
203
- strokeDasharray={28} strokeDashoffset={(28 * (1 - Math.min(1, c))).toFixed(2)} />
204
- </svg>
205
- )}
206
- </div>
207
- <div style={{ fontSize: 36, fontWeight: 650, letterSpacing: '-0.015em', color: on ? '#121407' : '#8d927a' }}>{s}</div>
208
- <div style={{ marginLeft: 'auto', fontSize: 26, fontWeight: 600, color: '#8d927a', opacity: on ? Math.min(1, c) : 0, fontFamily: FONT.mono }}>
209
- {['38s', '2.4s', '0.6s'][k]}
210
- </div>
211
- </div>
212
- );
213
- })}
214
- </div>
215
- </div>
216
- );
217
- };
218
-
219
- // ───────────── 章节 ─────────────
220
- const ChapterScene: React.FC<{ i: number; frame: number }> = ({ i, frame }) => {
221
- const c = CHAPTERS[i];
222
- const land = landAt(i);
223
- const dark = i === 0;
224
- const cardBg = i === 2 ? 'linear-gradient(180deg, #1d1411 0%, #140d0b 100%)' : 'linear-gradient(180deg, #ffffff 0%, #fafaf7 100%)';
225
- return (
226
- <AbsoluteFill style={{ background: `linear-gradient(176deg, ${c.hi} 0%, ${c.base} 44%, ${c.lo} 100%)`, overflow: 'hidden', fontFamily: SANS }}>
227
- {/* 受光:左上柔光斑 + 右下压暗(同一光向,和卡片阴影一致) */}
228
- <AbsoluteFill style={{
229
- background: `radial-gradient(ellipse 62% 70% at 18% 6%, rgba(255,255,255,${dark ? 0.06 : 0.2}) 0%, rgba(255,255,255,0) 70%), ` +
230
- `radial-gradient(ellipse 70% 70% at 100% 100%, ${alpha(c.shade, dark ? 0.5 : 0.3)} 0%, ${alpha(c.shade, 0)} 70%)`,
231
- }} />
232
- {/* 左栏:眉题 / 标题 / 说明 */}
233
- <div style={{ position: 'absolute', left: 120, top: 150, display: 'flex', alignItems: 'center', gap: 20 }}>
234
- <div style={{
235
- height: 48, padding: '0 18px', borderRadius: 24, display: 'flex', alignItems: 'center',
236
- boxShadow: `inset 0 0 0 2px ${alpha(c.ink, 0.5)}`, color: c.ink, fontFamily: FONT.mono, fontSize: 26, fontWeight: 700,
237
- }}>{c.num}</div>
238
- <div style={{ ...type(30, 700, { caps: true }), color: c.ink, letterSpacing: '0.14em' }}>{c.name}</div>
239
- </div>
240
- <div style={{ position: 'absolute', left: 116, top: 268, ...type(i === 0 ? 168 : 116, 850), color: c.ink, letterSpacing: '-0.038em', lineHeight: 0.98 }}>
241
- <TextReveal text={c.title} by="line" variant="rise" start={land} each={18} gap={5} />
242
- </div>
243
- <div style={{
244
- position: 'absolute', left: 120, top: i === 0 ? 640 : 560, width: 620, ...type(40, 500), lineHeight: 1.28, color: c.ink2,
245
- opacity: ramp(frame, land + 8, 14, EASE.out), transform: `translateY(${((1 - ramp(frame, land + 8, 16, EASE.snappy)) * 18).toFixed(2)}px)`,
246
- }}>{c.sub}</div>
247
- {/* 页脚:品牌 + 章节刻度(章内绝对坐标) */}
248
- <div style={{ position: 'absolute', left: 120, bottom: 96, display: 'flex', alignItems: 'center', gap: 14 }}>
249
- <ShotcraftWordmark size={28} markScale={1.4} gap={14} tone={i === 3 ? 'light' : 'dark'} color={c.ink} />
250
- <div style={{ display: 'flex', gap: 10, marginLeft: 30 }}>
251
- {[1, 2, 3].map((k) => (
252
- <div key={k} style={{ width: k === i ? 64 : 28, height: 8, borderRadius: 4, background: c.ink, opacity: k === i ? 0.95 : 0.28 }} />
253
- ))}
254
- </div>
255
- </div>
256
-
257
- {/* 右栏 UI 卡(钉在章内坐标) */}
258
- {i > 0 && (
259
- <div style={{
260
- position: 'absolute', right: 120, top: '50%', transform: 'translateY(-50%)', borderRadius: 36, overflow: 'hidden',
261
- background: cardBg,
262
- boxShadow: `inset 0 1px 0 rgba(255,255,255,${i === 2 ? 0.1 : 0.9}), ${softShadow(48, { color: c.shade, strength: 1.6 })}`,
263
- }}>
264
- {i === 1 && <ChannelCard frame={frame} />}
265
- {i === 2 && <HuddleCard frame={frame} />}
266
- {i === 3 && <WorkflowCard frame={frame} />}
267
- </div>
268
- )}
269
- </AbsoluteFill>
270
- );
271
- };
272
-
273
- export const BottomPushStackWipe: React.FC = () => {
274
- const frame = useCurrentFrame();
275
- const progress = PUSH_STARTS.map((_, i) => pushP(frame, i));
276
- const vy = -velocity(stackY, frame);
277
- const settle = 1 + 0.015 * ramp(frame, 142, 28, EASE.smooth); // 尾段极缓推近
278
- return (
279
- <AbsoluteFill style={{ overflow: 'hidden', background: CHAPTERS[0].base }}>
280
- <AbsoluteFill style={{ transform: `scale(${settle.toFixed(4)})` }}>
281
- <SpeedBlur vx={0} vy={vy} amount={0.1} max={22}>
282
- {CHAPTERS.map((_, i) => {
283
- const pushedIn = i === 0 ? 1 : progress[i - 1];
284
- const pushedOut = i < CHAPTERS.length - 1 ? progress[i] : 0;
285
- const y = (1 - pushedIn) * H - pushedOut * H;
286
- if (y <= -H || y >= H) return null;
287
- const moving = pushedIn < 1;
288
- return (
289
- <AbsoluteFill key={i} style={{ transform: `translateY(${y.toFixed(2)}px)` }}>
290
- <ChapterScene i={i} frame={frame} />
291
- {i > 0 && moving && (
292
- <>
293
- {/* 接缝:压在旧章上的接触影(近实远虚) */}
294
- <div style={{
295
- position: 'absolute', top: -56, left: 0, right: 0, height: 56,
296
- background: `linear-gradient(to top, ${alpha(CHAPTERS[i].shade, 0.42)}, ${alpha(CHAPTERS[i].shade, 0.12)} 40%, ${alpha(CHAPTERS[i].shade, 0)})`,
297
- }} />
298
- {/* 新章上缘 2px 受光边:色板是一块有厚度的整料 */}
299
- <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 2, background: 'rgba(255,255,255,0.45)' }} />
300
- </>
301
- )}
302
- </AbsoluteFill>
303
- );
304
- })}
305
- </SpeedBlur>
306
- </AbsoluteFill>
307
- <Grain opacity={0.06} blend="overlay" />
308
- </AbsoluteFill>
309
- );
310
- };
1
+ // bottom-push-stack-wipe —— slack-promo 22–27s
2
+ // 换章手法不变:新章连底色整屏从底边向上推入,把旧章刚性顶出画外(两层同速同缓动),连推三章,
3
+ // 每章一种饱和底色,内容钉死在各自色底坐标系里随底色走;上缘接缝阴影是"顶出"的物理接触证据。
4
+ //
5
+ // 第二轮重设计(设计决定)
6
+ // - look = custom「瑞士海报」:第 0 章近黑开场,三章是三块拉满的饱和色板——钴蓝 / 朱橙 / 酸柠,
7
+ // 色相彼此拉开 120° 级,换章一眼读作"换了个世界"。产品是 video-shotcraft,一章一个卖点(一句话出片 / 踩点剪辑 / 自动交付)。
8
+ // - 版式:左栏 120px 安全边距起排,眉题(章号 + 名称)→ 116px 超粗两行标题 → 40px 说明;
9
+ // 右栏一张为镜头设计的大字 UI 卡(和 agent 对话 / 踩点时间线 / 交付流水线),字号 ≥ 30px;色板本身左上受光、右下压暗,
10
+ // 卡片投带色相的两层软阴影(同一光向),平面海报里也有前后景。
11
+ // - 推入:26f 重 ease-out(快进慢停的"哐"),整摞按速度做纵向方向性模糊;新章上缘 2px 受光边 +
12
+ // 压在旧章上的 56px 接触影。推入窗口内章内元素全部静止(钉死),标题在落定前 ~8f 才从线下升起,
13
+ // UI 卡的小动作(打字中 → 消息出现 / 说话声波 / 自动化逐步打勾)都放在 hold 里,避开推入。
14
+ //
15
+ // 时间表(30fps,170f)
16
+ // 0–22 第 0 章:近黑底「Meet video-shotcraft.」已在画面,标题 0f 起逐行升起,2–20f 落定
17
+ // 22–48 推入 01 钴蓝(26f 重 ease-out,~34f 已到 95%)→ 34f 标题升起 → 36–48f 第三条消息"打字中"→ 48f 弹入
18
+ // 48–66 hold(读)
19
+ // 66–92 推入 02 朱橙 → 78f 标题 → 声波与计时全程在跳,82f 起第二个镜头亮环
20
+ // 92–110 hold
21
+ // 110–136 推入 03 酸柠(深色字)→ 122f 标题 → 126/134/142f 三个步骤依次打勾(弹簧)
22
+ // 142–170 hold 28f:极缓推近 1.5%,尾帧是完整的章节海报
23
+ import React from 'react';
24
+ import { AbsoluteFill, useCurrentFrame } from 'remotion';
25
+ import { EASE, FONT, Grain, SpeedBlur, bezier, mix, ramp, softShadow, velocity } from '../../_fixtures/Polish';
26
+ import { TextReveal, alpha, springAt, type } from '../../_fixtures/Look';
27
+ import { BRAND, PITCH, ShotcraftMark, ShotcraftWordmark } from '../../_fixtures/Brand';
28
+
29
+ const H = 1080;
30
+
31
+ export const BOTTOM_PUSH_STACK_WIPE_DURATION = 170;
32
+
33
+ const PUSH_STARTS = [22, 66, 110];
34
+ const PUSH_DUR = 26;
35
+ const heavyEaseOut = bezier(0.12, 0.9, 0.2, 1); // 快进慢停(md 钉死的推入曲线)
36
+
37
+ type Chapter = {
38
+ num: string; name: string; title: string; sub: string;
39
+ hi: string; base: string; lo: string; shade: string; ink: string; ink2: string;
40
+ };
41
+ const CHAPTERS: Chapter[] = [
42
+ {
43
+ num: '00', name: 'Agent skill', title: `Meet\n${BRAND.name}.`, sub: PITCH.en.taglines[1],
44
+ hi: '#1c1c1e', base: '#141415', lo: '#0c0c0d', shade: '#000000', ink: '#f4f2ee', ink2: 'rgba(244,242,238,0.62)',
45
+ },
46
+ {
47
+ num: '01', name: 'Prompt', title: 'One prompt.\nOne film.', sub: 'Describe the promo. Your agent storyboards every shot.',
48
+ hi: '#4565ff', base: '#2d4cff', lo: '#1c37e0', shade: '#0a1670', ink: '#ffffff', ink2: 'rgba(255,255,255,0.78)',
49
+ },
50
+ {
51
+ num: '02', name: 'Rhythm', title: 'Cut on\nthe beat.', sub: 'Every shot lands on the music, frame for frame.',
52
+ hi: '#ff6a3d', base: '#ff4d1f', lo: '#e83c10', shade: '#6e1600', ink: '#ffffff', ink2: 'rgba(255,255,255,0.8)',
53
+ },
54
+ {
55
+ num: '03', name: 'Delivery', title: 'Delivery,\nautomated.', sub: 'Render, export and publish the moment the cut locks.',
56
+ hi: '#dcfb5e', base: '#cdf23a', lo: '#b8dc22', shade: '#3c4a00', ink: '#121407', ink2: 'rgba(18,20,7,0.68)',
57
+ },
58
+ ];
59
+
60
+ const pushP = (f: number, i: number) => ramp(f, PUSH_STARTS[i], PUSH_DUR, heavyEaseOut);
61
+ const stackY = (f: number) => PUSH_STARTS.reduce((s, _, i) => s + pushP(f, i), 0) * H;
62
+ // 每章"落定"帧(标题起升的参照);第 0 章 = 0
63
+ const landAt = (i: number) => (i === 0 ? -10 : PUSH_STARTS[i - 1] + 12);
64
+
65
+ const SANS = FONT.sans;
66
+
67
+ // ───────────── UI 卡(为镜头设计:少元素、大字、强对比) ─────────────
68
+ const Avatar: React.FC<{ c: string; t: string; size?: number; ring?: number; ringColor?: string; mark?: boolean }> = ({ c, t, size = 64, ring = 0, ringColor = '#fff', mark = false }) => (
69
+ <div style={{
70
+ width: size, height: size, borderRadius: size / 2, flex: 'none', background: c, color: '#fff',
71
+ display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: SANS, fontWeight: 700,
72
+ fontSize: size * 0.38, letterSpacing: '-0.01em',
73
+ boxShadow: ring > 0 ? `0 0 0 ${4 + 6 * ring}px ${alpha(ringColor, 0.25 + 0.5 * ring)}` : undefined,
74
+ }}>{mark ? <ShotcraftMark size={size * 0.62} tone="dark" /> : t}</div>
75
+ );
76
+
77
+ const ChannelCard: React.FC<{ frame: number }> = ({ frame }) => {
78
+ const t0 = PUSH_STARTS[0] + 14; // 打字中提示(推入已到 95%)
79
+ const typing = frame >= t0 && frame < t0 + 12;
80
+ const msg = springAt(frame, t0 + 12, { damping: 18, stiffness: 200 });
81
+ const msgs = [
82
+ { c: '#7c5cff', t: 'MK', name: 'Maya', time: '9:41', text: 'Cut a 30s launch film for our app.', mark: false },
83
+ { c: BRAND.ink, t: '', name: 'Shotcraft', time: '9:42', text: 'Storyboard ready: 12 shots, on beat.', mark: true },
84
+ ];
85
+ return (
86
+ <div style={{ width: 760, padding: '40px 44px 44px', fontFamily: SANS, color: '#0e1020' }}>
87
+ <div style={{ display: 'flex', alignItems: 'baseline', gap: 16, paddingBottom: 28, borderBottom: '2px solid rgba(14,16,32,0.08)' }}>
88
+ <div style={{ ...type(44, 800), color: '#0e1020' }}># launch-film</div>
89
+ <div style={{ marginLeft: 'auto', fontSize: 28, fontWeight: 500, color: '#7a7f99' }}>3 members</div>
90
+ </div>
91
+ {msgs.map((m, k) => (
92
+ <div key={k} style={{ display: 'flex', gap: 22, marginTop: 32 }}>
93
+ <Avatar c={m.c} t={m.t} mark={m.mark} />
94
+ <div>
95
+ <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
96
+ <span style={{ fontSize: 32, fontWeight: 750, letterSpacing: '-0.015em' }}>{m.name}</span>
97
+ <span style={{ fontSize: 24, color: '#9a9fb5', fontVariantNumeric: 'tabular-nums' }}>{m.time}</span>
98
+ </div>
99
+ <div style={{ fontSize: 32, fontWeight: 450, color: '#3a3f58', marginTop: 6, lineHeight: 1.25 }}>{m.text}</div>
100
+ </div>
101
+ </div>
102
+ ))}
103
+ {/* 第三条:打字中 → 消息弹入 */}
104
+ <div style={{ position: 'relative', height: 132, marginTop: 32 }}>
105
+ {typing && (
106
+ <div style={{ position: 'absolute', left: 86, top: 20, display: 'flex', gap: 10, alignItems: 'center', padding: '18px 24px', borderRadius: 24, background: '#eef0fb' }}>
107
+ {[0, 1, 2].map((d) => (
108
+ <div key={d} style={{ width: 13, height: 13, borderRadius: 7, background: '#2d4cff', opacity: 0.35 + 0.65 * (0.5 + 0.5 * Math.sin((frame - t0) * 0.7 - d * 1.1)) }} />
109
+ ))}
110
+ </div>
111
+ )}
112
+ {frame >= t0 + 12 && (
113
+ <div style={{ display: 'flex', gap: 22, opacity: Math.min(1, msg * 1.5), transform: `translateY(${((1 - msg) * 26).toFixed(2)}px)` }}>
114
+ <Avatar c="#ff7a1a" t="IR" />
115
+ <div>
116
+ <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
117
+ <span style={{ fontSize: 32, fontWeight: 750, letterSpacing: '-0.015em' }}>Ines</span>
118
+ <span style={{ fontSize: 24, color: '#9a9fb5' }}>9:44</span>
119
+ </div>
120
+ <div style={{ display: 'flex', gap: 12, marginTop: 10 }}>
121
+ <div style={{ fontSize: 32, fontWeight: 700, color: '#2d4cff', padding: '8px 22px', borderRadius: 999, background: '#e8ecff' }}>Render it ↗</div>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ )}
126
+ </div>
127
+ </div>
128
+ );
129
+ };
130
+
131
+ const HuddleCard: React.FC<{ frame: number }> = ({ frame }) => {
132
+ const t = frame - PUSH_STARTS[1];
133
+ const people = [
134
+ { c: '#7c5cff', t: '01', name: 'Hook' },
135
+ { c: '#00a37a', t: '02', name: 'Zoom' },
136
+ { c: '#ff9f1c', t: '03', name: 'Whip' },
137
+ { c: '#3a86ff', t: '04', name: 'Sting' },
138
+ ];
139
+ // 当前镜头:前段 01 Hook,82f 起交给 02 Zoom(环 6f 交叉,踩在拍点上换镜)
140
+ const handoff = ramp(frame, PUSH_STARTS[1] + 16, 8, EASE.smooth);
141
+ const speak = [1 - handoff, handoff, 0, 0];
142
+ const secs = 12 + Math.floor(Math.max(0, t) / 30);
143
+ return (
144
+ <div style={{ width: 760, padding: '40px 44px 44px', fontFamily: SANS, color: '#f6f3ef' }}>
145
+ <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
146
+ <div style={{ width: 16, height: 16, borderRadius: 8, background: '#3ddc84', boxShadow: '0 0 0 6px rgba(61,220,132,0.18)' }} />
147
+ <div style={{ ...type(40, 800) }}>Beat sync · 128 BPM</div>
148
+ <div style={{ marginLeft: 'auto', fontSize: 32, fontWeight: 600, color: 'rgba(246,243,239,0.6)', fontFamily: FONT.mono }}>
149
+ {String(Math.floor(secs / 60)).padStart(2, '0')}:{String(secs % 60).padStart(2, '0')}
150
+ </div>
151
+ </div>
152
+ <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 52 }}>
153
+ {people.map((p, k) => (
154
+ <div key={k} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 18 }}>
155
+ <Avatar c={p.c} t={p.t} size={124} ring={speak[k] * (0.75 + 0.25 * Math.sin(frame * 0.5))} ringColor="#3ddc84" />
156
+ <div style={{ fontSize: 30, fontWeight: 600, color: speak[k] > 0.5 ? '#ffffff' : 'rgba(246,243,239,0.6)' }}>{p.name}</div>
157
+ </div>
158
+ ))}
159
+ </div>
160
+ {/* 声波:确定性正弦叠加 */}
161
+ <div style={{ display: 'flex', alignItems: 'center', gap: 7, height: 96, marginTop: 44 }}>
162
+ {Array.from({ length: 44 }, (_, j) => {
163
+ const a = 0.5 + 0.5 * Math.sin(frame * 0.42 + j * 0.62) * Math.sin(frame * 0.17 + j * 0.23);
164
+ const env = Math.sin((j / 43) * Math.PI);
165
+ return <div key={j} style={{ flex: 1, height: `${(12 + 84 * a * env).toFixed(1)}%`, borderRadius: 4, background: j % 9 === 4 ? '#ff6a3d' : 'rgba(246,243,239,0.82)' }} />;
166
+ })}
167
+ </div>
168
+ <div style={{ display: 'flex', gap: 18, marginTop: 40 }}>
169
+ <div style={{ flex: 1, height: 76, borderRadius: 38, background: 'rgba(255,255,255,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 30, fontWeight: 650 }}>Preview</div>
170
+ <div style={{ width: 210, height: 76, borderRadius: 38, background: '#ff4d1f', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 30, fontWeight: 700 }}>Render</div>
171
+ </div>
172
+ </div>
173
+ );
174
+ };
175
+
176
+ const WorkflowCard: React.FC<{ frame: number }> = ({ frame }) => {
177
+ const steps = ['Render 1080p master', 'Export JianYing draft', 'Post to the gallery'];
178
+ const at = [PUSH_STARTS[2] + 16, PUSH_STARTS[2] + 24, PUSH_STARTS[2] + 32];
179
+ return (
180
+ <div style={{ width: 760, padding: '40px 44px 48px', fontFamily: SANS, color: '#121407' }}>
181
+ <div style={{ fontSize: 26, fontWeight: 700, letterSpacing: '0.12em', color: '#7b8064', textTransform: 'uppercase' }}>Trigger</div>
182
+ <div style={{ ...type(44, 800), marginTop: 12 }}>When the cut locks</div>
183
+ <div style={{ position: 'relative', marginTop: 36 }}>
184
+ {/* 竖向连接线:随打勾向下"灌注" */}
185
+ <div style={{ position: 'absolute', left: 31, top: 56, height: 224, width: 3, background: 'rgba(18,20,7,0.1)' }} />
186
+ <div style={{
187
+ position: 'absolute', left: 31, top: 56, width: 3, background: '#121407',
188
+ height: (ramp(frame, at[0], at[2] - at[0], EASE.swift) * (112 * 2)).toFixed(2) + 'px',
189
+ }} />
190
+ {steps.map((s, k) => {
191
+ const c = springAt(frame, at[k], { damping: 14, stiffness: 240 });
192
+ const on = frame >= at[k];
193
+ return (
194
+ <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 28, height: 112, position: 'relative' }}>
195
+ <div style={{
196
+ width: 64, height: 64, borderRadius: 32, flex: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center',
197
+ background: on ? '#121407' : '#f3f5e6', boxShadow: on ? 'none' : 'inset 0 0 0 3px rgba(18,20,7,0.14)',
198
+ transform: `scale(${on ? mix(0.6, 1, c).toFixed(4) : 1})`,
199
+ }}>
200
+ {on && (
201
+ <svg width={30} height={30} viewBox="0 0 30 30">
202
+ <path d="M7 15.5 L13 21 L23.5 9.5" fill="none" stroke="#cdf23a" strokeWidth={4.2} strokeLinecap="round" strokeLinejoin="round"
203
+ strokeDasharray={28} strokeDashoffset={(28 * (1 - Math.min(1, c))).toFixed(2)} />
204
+ </svg>
205
+ )}
206
+ </div>
207
+ <div style={{ fontSize: 36, fontWeight: 650, letterSpacing: '-0.015em', color: on ? '#121407' : '#8d927a' }}>{s}</div>
208
+ <div style={{ marginLeft: 'auto', fontSize: 26, fontWeight: 600, color: '#8d927a', opacity: on ? Math.min(1, c) : 0, fontFamily: FONT.mono }}>
209
+ {['38s', '2.4s', '0.6s'][k]}
210
+ </div>
211
+ </div>
212
+ );
213
+ })}
214
+ </div>
215
+ </div>
216
+ );
217
+ };
218
+
219
+ // ───────────── 章节 ─────────────
220
+ const ChapterScene: React.FC<{ i: number; frame: number }> = ({ i, frame }) => {
221
+ const c = CHAPTERS[i];
222
+ const land = landAt(i);
223
+ const dark = i === 0;
224
+ const cardBg = i === 2 ? 'linear-gradient(180deg, #1d1411 0%, #140d0b 100%)' : 'linear-gradient(180deg, #ffffff 0%, #fafaf7 100%)';
225
+ return (
226
+ <AbsoluteFill style={{ background: `linear-gradient(176deg, ${c.hi} 0%, ${c.base} 44%, ${c.lo} 100%)`, overflow: 'hidden', fontFamily: SANS }}>
227
+ {/* 受光:左上柔光斑 + 右下压暗(同一光向,和卡片阴影一致) */}
228
+ <AbsoluteFill style={{
229
+ background: `radial-gradient(ellipse 62% 70% at 18% 6%, rgba(255,255,255,${dark ? 0.06 : 0.2}) 0%, rgba(255,255,255,0) 70%), ` +
230
+ `radial-gradient(ellipse 70% 70% at 100% 100%, ${alpha(c.shade, dark ? 0.5 : 0.3)} 0%, ${alpha(c.shade, 0)} 70%)`,
231
+ }} />
232
+ {/* 左栏:眉题 / 标题 / 说明 */}
233
+ <div style={{ position: 'absolute', left: 120, top: 150, display: 'flex', alignItems: 'center', gap: 20 }}>
234
+ <div style={{
235
+ height: 48, padding: '0 18px', borderRadius: 24, display: 'flex', alignItems: 'center',
236
+ boxShadow: `inset 0 0 0 2px ${alpha(c.ink, 0.5)}`, color: c.ink, fontFamily: FONT.mono, fontSize: 26, fontWeight: 700,
237
+ }}>{c.num}</div>
238
+ <div style={{ ...type(30, 700, { caps: true }), color: c.ink, letterSpacing: '0.14em' }}>{c.name}</div>
239
+ </div>
240
+ <div style={{ position: 'absolute', left: 116, top: 268, ...type(i === 0 ? 168 : 116, 850), color: c.ink, letterSpacing: '-0.038em', lineHeight: 0.98 }}>
241
+ <TextReveal text={c.title} by="line" variant="rise" start={land} each={18} gap={5} />
242
+ </div>
243
+ <div style={{
244
+ position: 'absolute', left: 120, top: i === 0 ? 640 : 560, width: 620, ...type(40, 500), lineHeight: 1.28, color: c.ink2,
245
+ opacity: ramp(frame, land + 8, 14, EASE.out), transform: `translateY(${((1 - ramp(frame, land + 8, 16, EASE.snappy)) * 18).toFixed(2)}px)`,
246
+ }}>{c.sub}</div>
247
+ {/* 页脚:品牌 + 章节刻度(章内绝对坐标) */}
248
+ <div style={{ position: 'absolute', left: 120, bottom: 96, display: 'flex', alignItems: 'center', gap: 14 }}>
249
+ <ShotcraftWordmark size={28} markScale={1.4} gap={14} tone={i === 3 ? 'light' : 'dark'} color={c.ink} />
250
+ <div style={{ display: 'flex', gap: 10, marginLeft: 30 }}>
251
+ {[1, 2, 3].map((k) => (
252
+ <div key={k} style={{ width: k === i ? 64 : 28, height: 8, borderRadius: 4, background: c.ink, opacity: k === i ? 0.95 : 0.28 }} />
253
+ ))}
254
+ </div>
255
+ </div>
256
+
257
+ {/* 右栏 UI 卡(钉在章内坐标) */}
258
+ {i > 0 && (
259
+ <div style={{
260
+ position: 'absolute', right: 120, top: '50%', transform: 'translateY(-50%)', borderRadius: 36, overflow: 'hidden',
261
+ background: cardBg,
262
+ boxShadow: `inset 0 1px 0 rgba(255,255,255,${i === 2 ? 0.1 : 0.9}), ${softShadow(48, { color: c.shade, strength: 1.6 })}`,
263
+ }}>
264
+ {i === 1 && <ChannelCard frame={frame} />}
265
+ {i === 2 && <HuddleCard frame={frame} />}
266
+ {i === 3 && <WorkflowCard frame={frame} />}
267
+ </div>
268
+ )}
269
+ </AbsoluteFill>
270
+ );
271
+ };
272
+
273
+ export const BottomPushStackWipe: React.FC = () => {
274
+ const frame = useCurrentFrame();
275
+ const progress = PUSH_STARTS.map((_, i) => pushP(frame, i));
276
+ const vy = -velocity(stackY, frame);
277
+ const settle = 1 + 0.015 * ramp(frame, 142, 28, EASE.smooth); // 尾段极缓推近
278
+ return (
279
+ <AbsoluteFill style={{ overflow: 'hidden', background: CHAPTERS[0].base }}>
280
+ <AbsoluteFill style={{ transform: `scale(${settle.toFixed(4)})` }}>
281
+ <SpeedBlur vx={0} vy={vy} amount={0.1} max={22}>
282
+ {CHAPTERS.map((_, i) => {
283
+ const pushedIn = i === 0 ? 1 : progress[i - 1];
284
+ const pushedOut = i < CHAPTERS.length - 1 ? progress[i] : 0;
285
+ const y = (1 - pushedIn) * H - pushedOut * H;
286
+ if (y <= -H || y >= H) return null;
287
+ const moving = pushedIn < 1;
288
+ return (
289
+ <AbsoluteFill key={i} style={{ transform: `translateY(${y.toFixed(2)}px)` }}>
290
+ <ChapterScene i={i} frame={frame} />
291
+ {i > 0 && moving && (
292
+ <>
293
+ {/* 接缝:压在旧章上的接触影(近实远虚) */}
294
+ <div style={{
295
+ position: 'absolute', top: -56, left: 0, right: 0, height: 56,
296
+ background: `linear-gradient(to top, ${alpha(CHAPTERS[i].shade, 0.42)}, ${alpha(CHAPTERS[i].shade, 0.12)} 40%, ${alpha(CHAPTERS[i].shade, 0)})`,
297
+ }} />
298
+ {/* 新章上缘 2px 受光边:色板是一块有厚度的整料 */}
299
+ <div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 2, background: 'rgba(255,255,255,0.45)' }} />
300
+ </>
301
+ )}
302
+ </AbsoluteFill>
303
+ );
304
+ })}
305
+ </SpeedBlur>
306
+ </AbsoluteFill>
307
+ <Grain opacity={0.06} blend="overlay" />
308
+ </AbsoluteFill>
309
+ );
310
+ };