dsh-drawai 0.4.2 → 0.4.3

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 (366) hide show
  1. package/README.md +4 -3
  2. package/lib/index.js +7777 -7719
  3. package/lib/motion/asset-pack.js +394 -394
  4. package/lib/motion/assets.js +291 -291
  5. package/lib/motion/demo-assets-lock.js +10 -10
  6. package/lib/motion/mgstyles/vendor/README.md +28 -28
  7. package/lib/motion/mgstyles/vendor/modules/d3/LICENSE +13 -13
  8. package/lib/motion/mgstyles/vendor/modules/d3/dist/d3.min.js +2 -2
  9. package/lib/motion/mgstyles/vendor/modules/opentype.js/LICENSE +20 -20
  10. package/lib/motion/mgstyles/vendor/modules/opentype.js/dist/opentype.mjs +14460 -14460
  11. package/lib/motion/mgstyles/vendor/modules/simplex-noise/LICENSE +21 -21
  12. package/lib/motion/mgstyles/vendor/modules/simplex-noise/dist/esm/simplex-noise.js +465 -465
  13. package/lib/motion/mgstyles/vendor/modules/topojson-client/LICENSE +13 -13
  14. package/lib/motion/mgstyles/vendor/modules/topojson-client/dist/topojson-client.min.js +2 -2
  15. package/lib/motion/render.js +179 -179
  16. package/lib/motion/shotcraft/upstream/SKILL.md +286 -286
  17. package/lib/motion/shotcraft/upstream/assets/lib/Caption.tsx +54 -54
  18. package/lib/motion/shotcraft/upstream/assets/lib/ClipCard.tsx +200 -200
  19. package/lib/motion/shotcraft/upstream/assets/lib/DigitRoll.tsx +45 -45
  20. package/lib/motion/shotcraft/upstream/assets/lib/FlashCut.tsx +20 -20
  21. package/lib/motion/shotcraft/upstream/assets/lib/FlatPanel.tsx +65 -65
  22. package/lib/motion/shotcraft/upstream/assets/lib/PageCam.tsx +151 -151
  23. package/lib/motion/shotcraft/upstream/assets/lib/VerticalTicker.tsx +129 -129
  24. package/lib/motion/shotcraft/upstream/assets/lib/helpers/camera.tsx +75 -75
  25. package/lib/motion/shotcraft/upstream/assets/lib/helpers/motion.ts +40 -40
  26. package/lib/motion/shotcraft/upstream/assets/lib/helpers/rand.ts +11 -11
  27. package/lib/motion/shotcraft/upstream/assets/lib/helpers/shake.ts +10 -10
  28. package/lib/motion/shotcraft/upstream/assets/scripts/build-readme-cover.mjs +49 -49
  29. package/lib/motion/shotcraft/upstream/assets/scripts/capture-template.mjs +210 -210
  30. package/lib/motion/shotcraft/upstream/assets/scripts/sfx-source.py +423 -423
  31. package/lib/motion/shotcraft/upstream/assets/scripts/smoke-render-demos.py +170 -170
  32. package/lib/motion/shotcraft/upstream/assets/scripts/test_sfx_source.py +157 -157
  33. package/lib/motion/shotcraft/upstream/demos/README.md +120 -120
  34. package/lib/motion/shotcraft/upstream/demos/_fixtures/Brand.tsx +112 -112
  35. package/lib/motion/shotcraft/upstream/demos/_fixtures/Fixtures.tsx +647 -647
  36. package/lib/motion/shotcraft/upstream/demos/_fixtures/Look.tsx +316 -316
  37. package/lib/motion/shotcraft/upstream/demos/_fixtures/Motion.tsx +82 -82
  38. package/lib/motion/shotcraft/upstream/demos/_fixtures/PageCam2D.tsx +115 -115
  39. package/lib/motion/shotcraft/upstream/demos/_fixtures/Polish.tsx +243 -243
  40. package/lib/motion/shotcraft/upstream/demos/_textures/live-layout.json +388 -388
  41. package/lib/motion/shotcraft/upstream/demos/camera/basic-3d-scene/Basic3DScene.tsx +250 -250
  42. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashImpactReal.tsx +305 -305
  43. package/lib/motion/shotcraft/upstream/demos/camera/crash-zoom-punch/CrashZoomReal.tsx +246 -246
  44. package/lib/motion/shotcraft/upstream/demos/camera/cursor-flyover/CursorFlyover.tsx +390 -390
  45. package/lib/motion/shotcraft/upstream/demos/camera/depth-layer-moves/MultiplaneReal.tsx +138 -138
  46. package/lib/motion/shotcraft/upstream/demos/camera/graze-face-tour/GrazeFaceTour.tsx +542 -542
  47. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/OverheadTabletopDrop.tsx +315 -315
  48. package/lib/motion/shotcraft/upstream/demos/camera/overhead-camera-moves/TiltReveal.tsx +299 -299
  49. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/DroneDiveLanding.tsx +173 -173
  50. package/lib/motion/shotcraft/upstream/demos/camera/space-camera-moves/ExplodedView.tsx +348 -348
  51. package/lib/motion/shotcraft/upstream/demos/camera/steep-tilt-glide/SteepTiltGlide.tsx +366 -366
  52. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/BulletTimeFreezeOrbit.tsx +279 -279
  53. package/lib/motion/shotcraft/upstream/demos/camera/tension-camera-moves/PullBackIsolation.tsx +184 -184
  54. package/lib/motion/shotcraft/upstream/demos/camera/terminal-3d/Terminal3D.tsx +390 -390
  55. package/lib/motion/shotcraft/upstream/demos/data/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +155 -155
  56. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/AxisRescaleShockV2.tsx +303 -303
  57. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/OscilloscopeStreamV2.tsx +290 -290
  58. package/lib/motion/shotcraft/upstream/demos/data/chart-live-moves/UnitDotSwarmRegroupV2.tsx +278 -278
  59. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/NeedleSweepSelftest.tsx +307 -307
  60. package/lib/motion/shotcraft/upstream/demos/data/gauge-readout-moves/TapeScrollFixedPointer.tsx +215 -215
  61. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/BrakeReticleLock.tsx +299 -299
  62. package/lib/motion/shotcraft/upstream/demos/data/scroll-brake-moves/ChangelogScrollBrake.tsx +232 -232
  63. package/lib/motion/shotcraft/upstream/demos/data/timeline-travel/TimelineTravel.tsx +290 -290
  64. package/lib/motion/shotcraft/upstream/demos/effects/assemble-then-type-flyin/AssembleThenTypeFlyin.tsx +273 -273
  65. package/lib/motion/shotcraft/upstream/demos/effects/aurora-bloom-bg-flip/AuroraBloomBgFlip.tsx +167 -167
  66. package/lib/motion/shotcraft/upstream/demos/effects/brand-frame-snap/BrandFrameSnap.tsx +536 -536
  67. package/lib/motion/shotcraft/upstream/demos/effects/fui-hud-moves/ReticleLockOn.tsx +164 -164
  68. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/FlylineArc.tsx +175 -175
  69. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/GlowOrbAmbient.tsx +197 -197
  70. package/lib/motion/shotcraft/upstream/demos/effects/glow-flyline-moves/OrbFlylineRelay.tsx +241 -241
  71. package/lib/motion/shotcraft/upstream/demos/effects/icon-performance-moves/AttentionBounce.tsx +279 -279
  72. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/AnimeImpact.tsx +230 -230
  73. package/lib/motion/shotcraft/upstream/demos/effects/impact-feedback/HitCounter.tsx +345 -345
  74. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SheenSweepRetry.tsx +275 -275
  75. package/lib/motion/shotcraft/upstream/demos/effects/light-play-moves/SpotlightSweepReveal.tsx +229 -229
  76. package/lib/motion/shotcraft/upstream/demos/effects/radial-ripple-phone-chips/RadialRipplePhoneChips.tsx +312 -312
  77. package/lib/motion/shotcraft/upstream/demos/effects/riso-print-hits/RisoMisregistrationHit.tsx +222 -222
  78. package/lib/motion/shotcraft/upstream/demos/effects/scan-bracket-sweep/ScanBracketSweep.tsx +295 -295
  79. package/lib/motion/shotcraft/upstream/demos/effects/scanline-annotate-focus/ScanlineAnnotateFocus.tsx +329 -329
  80. package/lib/motion/shotcraft/upstream/demos/effects/scanline-assemble-flyin/ScanlineAssembleFlyin.tsx +315 -315
  81. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ImpactBurstKit.tsx +264 -264
  82. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/KanadaPerspectiveSnap.tsx +260 -260
  83. package/lib/motion/shotcraft/upstream/demos/effects/slam-entrance-moves/ScoreSlam.tsx +263 -263
  84. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/CornerSpotlightReveal.tsx +123 -123
  85. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +187 -187
  86. package/lib/motion/shotcraft/upstream/demos/effects/spotlight-sweep-moves/SlideSpotlightPan.tsx +175 -175
  87. package/lib/motion/shotcraft/upstream/demos/interaction/autolayout-gap-dial/AutolayoutGapDial.tsx +305 -305
  88. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/DiagramCascadeBuild.tsx +350 -350
  89. package/lib/motion/shotcraft/upstream/demos/interaction/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +352 -352
  90. package/lib/motion/shotcraft/upstream/demos/interaction/chip-grid-single-select-blackout/ChipGridSingleSelectBlackout.tsx +218 -218
  91. package/lib/motion/shotcraft/upstream/demos/interaction/collab-cursor-moves/CursorCastEnsemble.tsx +297 -297
  92. package/lib/motion/shotcraft/upstream/demos/interaction/glass-pill-dictation-typing/GlassPillDictationTyping.tsx +157 -157
  93. package/lib/motion/shotcraft/upstream/demos/interaction/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +218 -218
  94. package/lib/motion/shotcraft/upstream/demos/interaction/picker-carousel-feature-cycle/PickerCarouselFeatureCycle.tsx +202 -202
  95. package/lib/motion/shotcraft/upstream/demos/interaction/segmented-thumb-hero/SegmentedThumbHero.tsx +265 -265
  96. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/PaletteThemeRipple.tsx +457 -457
  97. package/lib/motion/shotcraft/upstream/demos/interaction/theme-switch-moves/ThemeSweepToggle.tsx +446 -446
  98. package/lib/motion/shotcraft/upstream/demos/interaction/type-and-filter/TypeAndFilter.tsx +249 -249
  99. package/lib/motion/shotcraft/upstream/demos/interaction/voice-waveform-live/VoiceWaveformLive.tsx +278 -278
  100. package/lib/motion/shotcraft/upstream/demos/opening/crane-rise-reveal/CraneRiseReveal.tsx +332 -332
  101. package/lib/motion/shotcraft/upstream/demos/opening/dataviz-landscape-open/DatavizLandscapeOpen.tsx +358 -358
  102. package/lib/motion/shotcraft/upstream/demos/opening/fracture/Fracture.tsx +201 -201
  103. package/lib/motion/shotcraft/upstream/demos/opening/icon-field-colorize/IconFieldColorize.tsx +200 -200
  104. package/lib/motion/shotcraft/upstream/demos/opening/letterspace-materialize/LetterspaceMaterialize.tsx +208 -208
  105. package/lib/motion/shotcraft/upstream/demos/opening/magician-card-flourish/MagicianCardFlourish.tsx +341 -341
  106. package/lib/motion/shotcraft/upstream/demos/opening/orbit-ring-title-open/OrbitRingTitleOpen.tsx +389 -389
  107. package/lib/motion/shotcraft/upstream/demos/opening/spotlight-hero-card/SpotlightHeroCard.tsx +293 -293
  108. package/lib/motion/shotcraft/upstream/demos/opening/stroke-segment-build/StrokeSegmentBuild.tsx +183 -183
  109. package/lib/motion/shotcraft/upstream/demos/opening/text-as-mask/TextAsMask.tsx +245 -245
  110. package/lib/motion/shotcraft/upstream/demos/outro/grain-dissolve/GrainDissolve.tsx +222 -222
  111. package/lib/motion/shotcraft/upstream/demos/outro/logo-shrink-wordmark-lockup/LogoShrinkWordmarkLockup.tsx +223 -223
  112. package/lib/motion/shotcraft/upstream/demos/outro/neon-triple-marquee/NeonTripleMarquee.tsx +217 -217
  113. package/lib/motion/shotcraft/upstream/demos/outro/outro-group-photo-launch/OutroGroupPhotoLaunch.tsx +343 -343
  114. package/lib/motion/shotcraft/upstream/demos/outro/ui-strip-away-outro/UiStripAwayOutro.tsx +357 -357
  115. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/IconFlipBloomLogo.tsx +187 -187
  116. package/lib/motion/shotcraft/upstream/demos/outro/ui-to-brand-morph/InputMorphsIntoLogo.tsx +333 -333
  117. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-cut-moves/PaparazziFlash.tsx +274 -274
  118. package/lib/motion/shotcraft/upstream/demos/rhythm/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +270 -270
  119. package/lib/motion/shotcraft/upstream/demos/rhythm/panel-grid-moves/ComicPanelSplit.tsx +430 -430
  120. package/lib/motion/shotcraft/upstream/demos/rhythm/quad-split-parallel-scenes/QuadSplitParallelScenes.tsx +252 -252
  121. package/lib/motion/shotcraft/upstream/demos/rhythm/rhythm-interrupt-moves/JumpCutPunchIn.tsx +106 -106
  122. package/lib/motion/shotcraft/upstream/demos/rhythm/sakuga-timing-shift/SakugaTimingShift.tsx +288 -288
  123. package/lib/motion/shotcraft/upstream/demos/rhythm/speed-ramp-freeze/FreezeAnnotateReal.tsx +362 -362
  124. package/lib/motion/shotcraft/upstream/demos/rhythm/trailer-grammar-moves/TrailerBumper.tsx +168 -168
  125. package/lib/motion/shotcraft/upstream/demos/transition/bottom-push-stack-wipe/BottomPushStackWipe.tsx +310 -310
  126. package/lib/motion/shotcraft/upstream/demos/transition/card-flip-reveal/CardFlipReveal.tsx +261 -261
  127. package/lib/motion/shotcraft/upstream/demos/transition/card-flock-tumble/CardFlockTumble.tsx +459 -459
  128. package/lib/motion/shotcraft/upstream/demos/transition/circle-match-iris/CircleMatchIris.tsx +294 -294
  129. package/lib/motion/shotcraft/upstream/demos/transition/gradient-transition/GradientTransition.tsx +161 -161
  130. package/lib/motion/shotcraft/upstream/demos/transition/line-carry-transition/LineCarryTransition.tsx +248 -248
  131. package/lib/motion/shotcraft/upstream/demos/transition/mosaic-reframe/MosaicReframe.tsx +359 -359
  132. package/lib/motion/shotcraft/upstream/demos/transition/page-turn-transitions/BarnDoorSplit.tsx +227 -227
  133. package/lib/motion/shotcraft/upstream/demos/transition/print-texture-transitions/InkBleedReveal.tsx +162 -162
  134. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/PortalWipeV2.tsx +248 -248
  135. package/lib/motion/shotcraft/upstream/demos/transition/shot-transitions/WhipBrakeReal.tsx +186 -186
  136. package/lib/motion/shotcraft/upstream/demos/transition/tear-streak-transitions/GlitchDisplace.tsx +355 -355
  137. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/InvisibleCut.tsx +272 -272
  138. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/LightLeakBurn.tsx +262 -262
  139. package/lib/motion/shotcraft/upstream/demos/transition/transition-hidden-cut/VersusSlam.tsx +217 -217
  140. package/lib/motion/shotcraft/upstream/demos/transition/transition-travel/LetterformZoom.tsx +285 -285
  141. package/lib/motion/shotcraft/upstream/demos/transition/white-flash-logo-simplify-cut/WhiteFlashLogoSimplifyCut.tsx +205 -205
  142. package/lib/motion/shotcraft/upstream/demos/transition/wipe-transitions/BlindsSlice.tsx +178 -178
  143. package/lib/motion/shotcraft/upstream/demos/typography/blur-slide/BlurSlide.tsx +147 -147
  144. package/lib/motion/shotcraft/upstream/demos/typography/brace-expand/BraceExpand.tsx +143 -143
  145. package/lib/motion/shotcraft/upstream/demos/typography/brand-ink-open/BrandInkOpen.tsx +134 -134
  146. package/lib/motion/shotcraft/upstream/demos/typography/countdown-arc-scatter/CountdownArcScatter.tsx +217 -217
  147. package/lib/motion/shotcraft/upstream/demos/typography/flying-words/FlyingWords.tsx +198 -198
  148. package/lib/motion/shotcraft/upstream/demos/typography/glitch-cycle/GlitchCycle.tsx +221 -221
  149. package/lib/motion/shotcraft/upstream/demos/typography/gradient-word-sweep/GradientWordSweep.tsx +312 -312
  150. package/lib/motion/shotcraft/upstream/demos/typography/lead-word-zoom-assemble/LeadWordZoomAssemble.tsx +261 -261
  151. package/lib/motion/shotcraft/upstream/demos/typography/marker-underline-title/MarkerUnderlineTitle.tsx +121 -121
  152. package/lib/motion/shotcraft/upstream/demos/typography/outline-word-fill/OutlineWordFill.tsx +153 -153
  153. package/lib/motion/shotcraft/upstream/demos/typography/paper-title-card/PaperTitleCard.tsx +179 -179
  154. package/lib/motion/shotcraft/upstream/demos/typography/pill-chip-slot-cycle-handled/PillChipSlotCycleHandled.tsx +140 -140
  155. package/lib/motion/shotcraft/upstream/demos/typography/pill-slot-cycle/PillSlotCycle.tsx +309 -309
  156. package/lib/motion/shotcraft/upstream/demos/typography/text-column-converge/TextColumnConverge.tsx +191 -191
  157. package/lib/motion/shotcraft/upstream/demos/typography/title-demote-to-label/TitleDemoteToLabel.tsx +292 -292
  158. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/LetterformDriftAssembly.tsx +135 -135
  159. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/SplitTextStagger.tsx +124 -124
  160. package/lib/motion/shotcraft/upstream/demos/typography/type-assembly-moves/TextOnPath.tsx +255 -255
  161. package/lib/motion/shotcraft/upstream/demos/typography/type-entrance-moves/LetterDropPhysics.tsx +173 -173
  162. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/FontWeightPump.tsx +225 -225
  163. package/lib/motion/shotcraft/upstream/demos/typography/type-rhythm-sync/KaraokeFillSync.tsx +141 -141
  164. package/lib/motion/shotcraft/upstream/demos/typography/typewriter-moves/TypewriterErrorRetype.tsx +137 -137
  165. package/lib/motion/shotcraft/upstream/demos/typography/vertical-word-roll-blur-cycle/VerticalWordRollBlurCycle.tsx +147 -147
  166. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-filmstrip/WordRelayFilmstrip.tsx +409 -409
  167. package/lib/motion/shotcraft/upstream/demos/typography/word-relay-geometry/WordRelayGeometry.tsx +280 -280
  168. package/lib/motion/shotcraft/upstream/demos/ui-entrance/avatar-bracket-carousel/AvatarBracketCarousel.tsx +271 -271
  169. package/lib/motion/shotcraft/upstream/demos/ui-entrance/bezier-source-converge-merge/BezierSourceConvergeMerge.tsx +385 -385
  170. package/lib/motion/shotcraft/upstream/demos/ui-entrance/card-stack/CardStack.tsx +312 -312
  171. package/lib/motion/shotcraft/upstream/demos/ui-entrance/carousel-3d/Carousel3D.tsx +303 -303
  172. package/lib/motion/shotcraft/upstream/demos/ui-entrance/clipcard-looping/ClipCardLooping.tsx +77 -77
  173. package/lib/motion/shotcraft/upstream/demos/ui-entrance/cloner-depth-echo/ClonerDepthEcho.tsx +311 -311
  174. package/lib/motion/shotcraft/upstream/demos/ui-entrance/deck-deal-flyin/DeckDealFlyin.tsx +307 -307
  175. package/lib/motion/shotcraft/upstream/demos/ui-entrance/doc-park-left-pill-deal/DocParkLeftPillDeal.tsx +349 -349
  176. package/lib/motion/shotcraft/upstream/demos/ui-entrance/document-typewriter-reveal/DocumentTypewriterReveal.tsx +255 -255
  177. package/lib/motion/shotcraft/upstream/demos/ui-entrance/draw-svg-trace/DrawSvgTrace.tsx +244 -244
  178. package/lib/motion/shotcraft/upstream/demos/ui-entrance/element-body-moves/ContactShadowLift.tsx +217 -217
  179. package/lib/motion/shotcraft/upstream/demos/ui-entrance/integration-hub-map/IntegrationHubMap.tsx +652 -652
  180. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-reveal/ListReveal.tsx +153 -153
  181. package/lib/motion/shotcraft/upstream/demos/ui-entrance/list-stack-press/ListStackPress.tsx +238 -238
  182. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-forerun/NeonFrameForerun.tsx +324 -324
  183. package/lib/motion/shotcraft/upstream/demos/ui-entrance/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +354 -354
  184. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/PageWaterfallWall.tsx +101 -101
  185. package/lib/motion/shotcraft/upstream/demos/ui-entrance/page-waterfall-wall/VerticalTicker.tsx +129 -129
  186. package/lib/motion/shotcraft/upstream/demos/ui-entrance/product-card-progressive-assemble/ProductCardProgressiveAssemble.tsx +297 -297
  187. package/lib/motion/shotcraft/upstream/demos/ui-entrance/radial-wave/RadialWave.tsx +57 -57
  188. package/lib/motion/shotcraft/upstream/demos/ui-entrance/research-card-stack-scroll/ResearchCardStackScroll.tsx +155 -155
  189. package/lib/motion/shotcraft/upstream/demos/ui-entrance/row-embed/RowEmbed.tsx +175 -175
  190. package/lib/motion/shotcraft/upstream/demos/ui-entrance/value-stagger-gradient/ValueStaggerGradient.tsx +153 -153
  191. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/BentoLightUp.tsx +146 -146
  192. package/lib/motion/shotcraft/upstream/demos/ui-entrance/wall-reveal-moves/WireframeDrawOn.tsx +226 -226
  193. package/lib/motion/shotcraft/upstream/gallery/api/library.json +1 -1
  194. package/lib/motion/shotcraft/upstream/references/aesthetic-rules.md +193 -193
  195. package/lib/motion/shotcraft/upstream/references/final-review.md +121 -121
  196. package/lib/motion/shotcraft/upstream/references/guided-free-creation.md +199 -199
  197. package/lib/motion/shotcraft/upstream/references/jianying-export.md +183 -183
  198. package/lib/motion/shotcraft/upstream/references/music-beat-sync.md +257 -257
  199. package/lib/motion/shotcraft/upstream/references/pipeline.md +382 -382
  200. package/lib/motion/shotcraft/upstream/references/publish-upload-post.md +111 -111
  201. package/lib/motion/shotcraft/upstream/references/sequences/promo-energy-arc.md +50 -50
  202. package/lib/motion/shotcraft/upstream/references/sfx-sourcing.md +95 -95
  203. package/lib/motion/shotcraft/upstream/references/shots/camera/basic-3d-scene.md +41 -41
  204. package/lib/motion/shotcraft/upstream/references/shots/camera/crash-zoom-punch.md +52 -52
  205. package/lib/motion/shotcraft/upstream/references/shots/camera/cursor-flyover.md +39 -39
  206. package/lib/motion/shotcraft/upstream/references/shots/camera/depth-layer-moves.md +39 -39
  207. package/lib/motion/shotcraft/upstream/references/shots/camera/graze-face-tour.md +57 -57
  208. package/lib/motion/shotcraft/upstream/references/shots/camera/overhead-camera-moves.md +51 -51
  209. package/lib/motion/shotcraft/upstream/references/shots/camera/space-camera-moves.md +46 -46
  210. package/lib/motion/shotcraft/upstream/references/shots/camera/steep-tilt-glide.md +52 -52
  211. package/lib/motion/shotcraft/upstream/references/shots/camera/tension-camera-moves.md +43 -43
  212. package/lib/motion/shotcraft/upstream/references/shots/camera/terminal-3d.md +42 -42
  213. package/lib/motion/shotcraft/upstream/references/shots/data/before-after-slider-scrub.md +48 -48
  214. package/lib/motion/shotcraft/upstream/references/shots/data/chart-live-moves.md +52 -52
  215. package/lib/motion/shotcraft/upstream/references/shots/data/gauge-readout-moves.md +45 -45
  216. package/lib/motion/shotcraft/upstream/references/shots/data/scroll-brake-moves.md +46 -46
  217. package/lib/motion/shotcraft/upstream/references/shots/data/timeline-travel.md +44 -44
  218. package/lib/motion/shotcraft/upstream/references/shots/effects/assemble-then-type-flyin.md +63 -63
  219. package/lib/motion/shotcraft/upstream/references/shots/effects/aurora-bloom-bg-flip.md +54 -54
  220. package/lib/motion/shotcraft/upstream/references/shots/effects/brand-frame-snap.md +58 -58
  221. package/lib/motion/shotcraft/upstream/references/shots/effects/fui-hud-moves.md +35 -35
  222. package/lib/motion/shotcraft/upstream/references/shots/effects/glow-flyline-moves.md +53 -53
  223. package/lib/motion/shotcraft/upstream/references/shots/effects/icon-performance-moves.md +42 -42
  224. package/lib/motion/shotcraft/upstream/references/shots/effects/impact-feedback.md +50 -50
  225. package/lib/motion/shotcraft/upstream/references/shots/effects/light-play-moves.md +46 -46
  226. package/lib/motion/shotcraft/upstream/references/shots/effects/radial-ripple-phone-chips.md +56 -56
  227. package/lib/motion/shotcraft/upstream/references/shots/effects/riso-print-hits.md +49 -49
  228. package/lib/motion/shotcraft/upstream/references/shots/effects/scan-bracket-sweep.md +50 -50
  229. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-annotate-focus.md +53 -53
  230. package/lib/motion/shotcraft/upstream/references/shots/effects/scanline-assemble-flyin.md +53 -53
  231. package/lib/motion/shotcraft/upstream/references/shots/effects/slam-entrance-moves.md +55 -55
  232. package/lib/motion/shotcraft/upstream/references/shots/effects/spotlight-sweep-moves.md +52 -52
  233. package/lib/motion/shotcraft/upstream/references/shots/interaction/autolayout-gap-dial.md +60 -60
  234. package/lib/motion/shotcraft/upstream/references/shots/interaction/canvas-materialize-moves.md +57 -57
  235. package/lib/motion/shotcraft/upstream/references/shots/interaction/chip-grid-single-select-blackout.md +51 -51
  236. package/lib/motion/shotcraft/upstream/references/shots/interaction/collab-cursor-moves.md +41 -41
  237. package/lib/motion/shotcraft/upstream/references/shots/interaction/glass-pill-dictation-typing.md +53 -53
  238. package/lib/motion/shotcraft/upstream/references/shots/interaction/hashtag-to-pill-materialize.md +60 -60
  239. package/lib/motion/shotcraft/upstream/references/shots/interaction/picker-carousel-feature-cycle.md +55 -55
  240. package/lib/motion/shotcraft/upstream/references/shots/interaction/segmented-thumb-hero.md +57 -57
  241. package/lib/motion/shotcraft/upstream/references/shots/interaction/theme-switch-moves.md +47 -47
  242. package/lib/motion/shotcraft/upstream/references/shots/interaction/type-and-filter.md +37 -37
  243. package/lib/motion/shotcraft/upstream/references/shots/interaction/voice-waveform-live.md +54 -54
  244. package/lib/motion/shotcraft/upstream/references/shots/opening/brand-ink-open.md +36 -36
  245. package/lib/motion/shotcraft/upstream/references/shots/opening/crane-rise-reveal.md +56 -56
  246. package/lib/motion/shotcraft/upstream/references/shots/opening/dataviz-landscape-open.md +56 -56
  247. package/lib/motion/shotcraft/upstream/references/shots/opening/fracture.md +40 -40
  248. package/lib/motion/shotcraft/upstream/references/shots/opening/icon-field-colorize.md +60 -60
  249. package/lib/motion/shotcraft/upstream/references/shots/opening/letterspace-materialize.md +57 -57
  250. package/lib/motion/shotcraft/upstream/references/shots/opening/magician-card-flourish.md +73 -73
  251. package/lib/motion/shotcraft/upstream/references/shots/opening/orbit-ring-title-open.md +87 -87
  252. package/lib/motion/shotcraft/upstream/references/shots/opening/spotlight-hero-card.md +55 -55
  253. package/lib/motion/shotcraft/upstream/references/shots/opening/stroke-segment-build.md +50 -50
  254. package/lib/motion/shotcraft/upstream/references/shots/opening/text-as-mask.md +59 -59
  255. package/lib/motion/shotcraft/upstream/references/shots/outro/grain-dissolve.md +38 -38
  256. package/lib/motion/shotcraft/upstream/references/shots/outro/logo-shrink-wordmark-lockup.md +38 -38
  257. package/lib/motion/shotcraft/upstream/references/shots/outro/neon-triple-marquee.md +59 -59
  258. package/lib/motion/shotcraft/upstream/references/shots/outro/outro-group-photo-launch.md +39 -39
  259. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-strip-away-outro.md +61 -61
  260. package/lib/motion/shotcraft/upstream/references/shots/outro/ui-to-brand-morph.md +52 -52
  261. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-cut-moves.md +50 -50
  262. package/lib/motion/shotcraft/upstream/references/shots/rhythm/beat-step-list-theme-cycle.md +66 -66
  263. package/lib/motion/shotcraft/upstream/references/shots/rhythm/panel-grid-moves.md +43 -43
  264. package/lib/motion/shotcraft/upstream/references/shots/rhythm/quad-split-parallel-scenes.md +38 -38
  265. package/lib/motion/shotcraft/upstream/references/shots/rhythm/rhythm-interrupt-moves.md +38 -38
  266. package/lib/motion/shotcraft/upstream/references/shots/rhythm/sakuga-timing-shift.md +56 -56
  267. package/lib/motion/shotcraft/upstream/references/shots/rhythm/speed-ramp-freeze.md +44 -44
  268. package/lib/motion/shotcraft/upstream/references/shots/rhythm/trailer-grammar-moves.md +38 -38
  269. package/lib/motion/shotcraft/upstream/references/shots/transition/bottom-push-stack-wipe.md +63 -63
  270. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flip-reveal.md +57 -57
  271. package/lib/motion/shotcraft/upstream/references/shots/transition/card-flock-tumble.md +63 -63
  272. package/lib/motion/shotcraft/upstream/references/shots/transition/circle-match-iris.md +58 -58
  273. package/lib/motion/shotcraft/upstream/references/shots/transition/gradient-transition.md +45 -45
  274. package/lib/motion/shotcraft/upstream/references/shots/transition/line-carry-transition.md +55 -55
  275. package/lib/motion/shotcraft/upstream/references/shots/transition/mosaic-reframe.md +49 -49
  276. package/lib/motion/shotcraft/upstream/references/shots/transition/page-turn-transitions.md +42 -42
  277. package/lib/motion/shotcraft/upstream/references/shots/transition/print-texture-transitions.md +42 -42
  278. package/lib/motion/shotcraft/upstream/references/shots/transition/shot-transitions.md +45 -45
  279. package/lib/motion/shotcraft/upstream/references/shots/transition/tear-streak-transitions.md +48 -48
  280. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-hidden-cut.md +55 -55
  281. package/lib/motion/shotcraft/upstream/references/shots/transition/transition-travel.md +43 -43
  282. package/lib/motion/shotcraft/upstream/references/shots/transition/white-flash-logo-simplify-cut.md +41 -41
  283. package/lib/motion/shotcraft/upstream/references/shots/transition/wipe-transitions.md +42 -42
  284. package/lib/motion/shotcraft/upstream/references/shots/typography/blur-slide.md +59 -59
  285. package/lib/motion/shotcraft/upstream/references/shots/typography/brace-expand.md +55 -55
  286. package/lib/motion/shotcraft/upstream/references/shots/typography/countdown-arc-scatter.md +65 -65
  287. package/lib/motion/shotcraft/upstream/references/shots/typography/document-typewriter-reveal.md +42 -42
  288. package/lib/motion/shotcraft/upstream/references/shots/typography/flying-words.md +64 -64
  289. package/lib/motion/shotcraft/upstream/references/shots/typography/glitch-cycle.md +64 -64
  290. package/lib/motion/shotcraft/upstream/references/shots/typography/gradient-word-sweep.md +54 -54
  291. package/lib/motion/shotcraft/upstream/references/shots/typography/lead-word-zoom-assemble.md +91 -91
  292. package/lib/motion/shotcraft/upstream/references/shots/typography/marker-underline-title.md +51 -51
  293. package/lib/motion/shotcraft/upstream/references/shots/typography/outline-word-fill.md +66 -66
  294. package/lib/motion/shotcraft/upstream/references/shots/typography/paper-title-card.md +38 -38
  295. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-chip-slot-cycle-handled.md +66 -66
  296. package/lib/motion/shotcraft/upstream/references/shots/typography/pill-slot-cycle.md +58 -58
  297. package/lib/motion/shotcraft/upstream/references/shots/typography/text-column-converge.md +61 -61
  298. package/lib/motion/shotcraft/upstream/references/shots/typography/title-demote-to-label.md +64 -64
  299. package/lib/motion/shotcraft/upstream/references/shots/typography/type-assembly-moves.md +45 -45
  300. package/lib/motion/shotcraft/upstream/references/shots/typography/type-entrance-moves.md +41 -41
  301. package/lib/motion/shotcraft/upstream/references/shots/typography/type-rhythm-sync.md +51 -51
  302. package/lib/motion/shotcraft/upstream/references/shots/typography/typewriter-moves.md +42 -42
  303. package/lib/motion/shotcraft/upstream/references/shots/typography/vertical-word-roll-blur-cycle.md +63 -63
  304. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-filmstrip.md +57 -57
  305. package/lib/motion/shotcraft/upstream/references/shots/typography/word-relay-geometry.md +75 -75
  306. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/avatar-bracket-carousel.md +59 -59
  307. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/bezier-source-converge-merge.md +67 -67
  308. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/card-stack.md +60 -60
  309. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/carousel-3d.md +66 -66
  310. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/cloner-depth-echo.md +40 -40
  311. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/deck-deal-flyin.md +45 -45
  312. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/doc-park-left-pill-deal.md +62 -62
  313. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/draw-svg-trace.md +55 -55
  314. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/element-body-moves.md +37 -37
  315. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/integration-hub-map.md +55 -55
  316. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-reveal.md +50 -50
  317. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/list-stack-press.md +43 -43
  318. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-forerun.md +55 -55
  319. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/neon-frame-orbit-drop.md +51 -51
  320. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/page-waterfall-wall.md +51 -51
  321. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/product-card-progressive-assemble.md +56 -56
  322. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/radial-wave.md +49 -49
  323. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/research-card-stack-scroll.md +57 -57
  324. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/row-embed.md +36 -36
  325. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/value-stagger-gradient.md +64 -64
  326. package/lib/motion/shotcraft/upstream/references/shots/ui-entrance/wall-reveal-moves.md +47 -47
  327. package/lib/motion/shotcraft/upstream/references/sound-design.md +170 -170
  328. package/lib/motion/shotcraft/upstream/references/workbench.md +157 -157
  329. package/lib/motion/shotcraft/upstream/template/TEMPLATE.md +103 -103
  330. package/lib/motion/shotcraft/upstream/template/THEMES.md +44 -44
  331. package/lib/motion/shotcraft/upstream/template/package.json +20 -20
  332. package/lib/motion/shotcraft/upstream/template/remotion.config.ts +6 -6
  333. package/lib/motion/shotcraft/upstream/template/src/Root.tsx +17 -17
  334. package/lib/motion/shotcraft/upstream/template/src/aifl/Caption.tsx +65 -65
  335. package/lib/motion/shotcraft/upstream/template/src/aifl/DigitRoll.tsx +48 -48
  336. package/lib/motion/shotcraft/upstream/template/src/aifl/FlashCut.tsx +24 -24
  337. package/lib/motion/shotcraft/upstream/template/src/aifl/Main.tsx +192 -192
  338. package/lib/motion/shotcraft/upstream/template/src/aifl/PaperTitleCard.tsx +111 -111
  339. package/lib/motion/shotcraft/upstream/template/src/aifl/live/PageCam.tsx +150 -150
  340. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneDetail.tsx +158 -158
  341. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneFlyIn.tsx +468 -468
  342. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOpen.tsx +552 -552
  343. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneOutroLive.tsx +411 -411
  344. package/lib/motion/shotcraft/upstream/template/src/aifl/live/ScenePapers.tsx +200 -200
  345. package/lib/motion/shotcraft/upstream/template/src/aifl/live/SceneWbr.tsx +324 -324
  346. package/lib/motion/shotcraft/upstream/template/src/aifl/live-layout.json +388 -388
  347. package/lib/motion/shotcraft/upstream/template/src/index.ts +4 -4
  348. package/lib/motion/shotcraft/upstream/template/src/themes/ThemedFilm.tsx +7 -7
  349. package/lib/motion/shotcraft/upstream/template/src/themes/manifest.tsx +68 -68
  350. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.json +1 -1
  351. package/lib/motion/shotcraft/upstream/template/src/themes/palette-assets.ts +24 -24
  352. package/lib/motion/shotcraft/upstream/template/src/themes/palettes.json +74 -74
  353. package/lib/motion/shotcraft/upstream/template/src/themes/visual-theme.tsx +91 -91
  354. package/lib/motion/shotcraft/upstream/template/src/workbench.ts +213 -213
  355. package/lib/motion/shotcraft/upstream/template/tsconfig.json +15 -15
  356. package/lib/motion/style-frames.js +306 -306
  357. package/lib/motion/sync.js +214 -214
  358. package/lib/motion-project.js +105 -105
  359. package/lib/motion-render-worker.js +174 -174
  360. package/lib/routing/router.js +222 -222
  361. package/lib/routing/vendor/README.md +96 -96
  362. package/lib/routing/vendor/libavoid-routing.js +753 -753
  363. package/lib/routing/vendor/libavoid.min.js +59 -59
  364. package/lib/video-trace-pool.js +128 -128
  365. package/package.json +1 -1
  366. package/LICENSE +0 -4175
@@ -1,389 +1,389 @@
1
- // orbit-ring-title-open — 环形卡阵标题开场
2
- // 八张 16:9 内容卡按 45° 均布在椭圆上匀速公转(卡身永不倾斜,纵深只由 sin(θ) 给出缩放、
3
- // z 序、景深与明暗),入场期卡内容冻结首帧、环撑开落定后统一开播;居中标题逐字解糊下沉落定,
4
- // 关键词全部到位那一刻荧光马克块自左横扫铺满(扫过处字色反白为墨),mono 副行随后浮出。
5
- //
6
- // 第二轮重设计(石墨夜 · 荧光笔):
7
- // - look = lime:石墨暗场 + 荧光黄绿。马克块从"黄色便利贴"变成一支荧光笔——暗场里唯一的高饱和色块,
8
- // 只给关键词「每一个动效」。八张卡全部换成暗色产品卡(深石墨底 + 发丝线 + 顶部内高光),
9
- // 卡内小动效统一用荧光绿做唯一强调,卡内字只做纹理(读的是标题)。
10
- // - 标题从 64px 单行改成两级:上行 64px 次级灰「让镜头卡替你想好」,下行 156px「每一个动效」做主角;
11
- // 马克块扫过时用两层裁切让字从白翻成墨色(反白在块的前沿同步发生,读作"被荧光笔划过")。
12
- // - 空间:椭圆轨道本身画成一圈极淡的发丝线(入场时描出来),卡的纵深除了 ±12% 缩放,
13
- // 远处(上方)的卡再压暗 + 轻微失焦,近处(下方)全亮全清——环有前后,标题在焦平面上。
14
- // 标题后垫一团暗色 scrim,保证卡从背后经过时标题始终压得住。
15
- // - 收尾:原版末段整行失焦退场做交棒;单镜头演示改为停在完整海报(HANDOFF_EXIT 开关保留退场逻辑)。
16
- //
17
- // 时间表(30fps,共 150f):
18
- // 0–24 环从 0.62 撑开到满径(snappy)+ 逐卡淡入;轨道发丝线 0–30 描出
19
- // 24 八张卡同时开播(冻结首帧 → 正常时间轴)
20
- // 10–40 上行逐字解糊下沉(错峰 1f)
21
- // 18–52 下行大字逐字解糊下沉(错峰 2f,更重更慢)
22
- // 50–64 荧光马克块横扫(弹簧,damping 20),扫过处字反白为墨
23
- // 60–76 副行(标志 + video-shotcraft + mono 代号)浮出
24
- // 76–150 hold:环持续匀速公转 + 整体极缓推近 2.5%;最后 2.5s 是一张完整海报
25
- import React from 'react';
26
- import { AbsoluteFill, Easing, Freeze, interpolate, useCurrentFrame, useVideoConfig } from 'remotion';
27
- import { EASE, FONT, ramp } from '../../_fixtures/Polish';
28
- import { LOOKS, Stage, alpha, springAt } from '../../_fixtures/Look';
29
- import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
30
-
31
- export const ORBIT_RING_TITLE_OPEN_DURATION = 150; // 5s @30fps
32
-
33
- const L = LOOKS.lime;
34
- const LIME = L.accent;
35
-
36
- // ---- 环 ----
37
- const RX = 720; // 椭圆长半轴
38
- const RY = 380; // 椭圆短半轴(RY/RX≈0.53 → 读作俯视的环,不是正圆转盘)
39
- const CW = 400; // 卡宽(16:9)
40
- const CH = 225;
41
- const N = 8;
42
- const ROT_SPEED = 0.3; // rad/s,正值 = 顺时针
43
- const RING_IN = 24; // f:从中心撑开到满径
44
- const RING_SCALE_FROM = 0.62;
45
- const PLAY_START = 24; // f:环撑开后卡内容才开播
46
- const DEPTH_SCALE = 0.12; // 近大远小幅度(底部近、顶部远)
47
-
48
- // ---- 标题 ----
49
- const LINE1 = '让镜头卡替你想好';
50
- const LINE2 = '每一个动效';
51
- const S1 = 64;
52
- const S2 = 156;
53
- const MARKER_AT = 50; // 下行末字视觉到位那一刻起扫
54
- // 副行 = video-shotcraft 标志 + 小写字标 + mono 产品代号(不写卡片数:会过时)
55
- const KICKER = 'SHOT RECIPE CARDS';
56
- const HANDOFF_EXIT = false; // true = 末段整行失焦淡出、环继续转着交棒下一镜(成片里接下一镜时打开)
57
- const EXIT_AT = 118;
58
-
59
- const SANS = `${FONT.sans.replace('Arial, sans-serif', '')}"PingFang SC", "Hiragino Sans GB", sans-serif`;
60
- const MONO = FONT.mono;
61
- const INK = L.ink;
62
- const DIM = '#8d937f';
63
-
64
- // ── 卡内占位内容(暗色产品卡,960×540 作画后整体缩到卡宽)──────────────────
65
- const F = (frame: number, a: number, b: number, ease = Easing.out(Easing.cubic)) =>
66
- interpolate(frame, [a, b], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: ease });
67
-
68
- const Pad: React.FC<{ children: React.ReactNode; bg?: string }> = ({ children, bg = L.surface }) => (
69
- <div style={{ position: 'absolute', inset: 0, background: bg, padding: 60, fontFamily: SANS, boxSizing: 'border-box' }}>{children}</div>
70
- );
71
-
72
- const T: React.FC<{ size: number; color?: string; weight?: number; mono?: boolean; style?: React.CSSProperties; children: React.ReactNode }> = ({
73
- size, color = INK, weight = 500, mono, style, children,
74
- }) => (
75
- <div style={{
76
- fontSize: size, color, fontWeight: weight, fontFamily: mono ? MONO : SANS,
77
- letterSpacing: mono ? 0 : size >= 40 ? '-0.035em' : '-0.01em', lineHeight: 1.2, whiteSpace: 'nowrap', ...style,
78
- }}>{children}</div>
79
- );
80
- const Caps: React.FC<{ children: React.ReactNode; color?: string }> = ({ children, color = DIM }) => (
81
- <div style={{ fontSize: 24, fontWeight: 650, letterSpacing: '0.16em', color }}>{children}</div>
82
- );
83
-
84
- /** 1 荧光笔扫读 */
85
- const TileSweep: React.FC = () => {
86
- const f = useCurrentFrame();
87
- const s = F(f, 14, 32, EASE.snappy);
88
- return (
89
- <Pad>
90
- <Caps>RELEASE NOTES · 4.2</Caps>
91
- <div style={{ position: 'relative', display: 'inline-block', marginTop: 40 }}>
92
- <div style={{ position: 'absolute', left: -12, right: -12, top: 4, bottom: 0, background: LIME, borderRadius: 4, transformOrigin: 'left center', transform: `scaleX(${s})` }} />
93
- <T size={58} weight={700} color={s > 0.6 ? L.onAccent : INK} style={{ position: 'relative' }}>Motion, considered.</T>
94
- </div>
95
- <T size={30} color={DIM} weight={450} style={{ marginTop: 34 }}>Every card ships with timing, easing</T>
96
- <T size={30} color={DIM} weight={450} style={{ marginTop: 8 }}>and a validated reference build.</T>
97
- </Pad>
98
- );
99
- };
100
-
101
- /** 2 指标 + sparkline 描线 */
102
- const SPARK = 'M8 118 L118 92 L228 104 L338 56 L448 68 L558 20 L632 34';
103
- const TileMetric: React.FC = () => {
104
- const f = useCurrentFrame();
105
- const draw = F(f, 10, 46, EASE.smooth);
106
- const val = 128 + Math.round(F(f, 8, 40, Easing.out(Easing.quad)) * 84);
107
- const chip = F(f, 34, 46);
108
- return (
109
- <Pad>
110
- <div style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
111
- <Caps>RENDERS / DAY</Caps>
112
- <div style={{ fontSize: 24, fontWeight: 650, color: L.onAccent, background: LIME, padding: '4px 12px', borderRadius: 999, opacity: chip, transform: `translateY(${(1 - chip) * 8}px)` }}>+18.4%</div>
113
- </div>
114
- <div style={{ fontSize: 140, fontWeight: 700, color: INK, letterSpacing: '-0.045em', fontVariantNumeric: 'tabular-nums', lineHeight: 1.1, fontFamily: SANS }}>{val}</div>
115
- <svg width={640} height={140} viewBox="0 0 640 140" style={{ marginTop: 8, overflow: 'visible' }}>
116
- <defs>
117
- <linearGradient id="orto-area" x1="0" y1="0" x2="0" y2="1">
118
- <stop offset="0" stopColor={LIME} stopOpacity={0.28} />
119
- <stop offset="1" stopColor={LIME} stopOpacity={0} />
120
- </linearGradient>
121
- </defs>
122
- <path d={`${SPARK} L632 140 L8 140 Z`} fill="url(#orto-area)" opacity={draw} />
123
- <path d={SPARK} fill="none" stroke="rgba(220,255,170,0.12)" strokeWidth={8} strokeLinecap="round" strokeLinejoin="round" />
124
- <path d={SPARK} fill="none" stroke={LIME} strokeWidth={8} strokeLinecap="round" strokeLinejoin="round" pathLength={1} strokeDasharray={1} strokeDashoffset={1 - draw} />
125
- </svg>
126
- </Pad>
127
- );
128
- };
129
-
130
- /** 3 竖向步骤清单逐条勾选 */
131
- const STEPS = ['Draft the storyboard', 'Pick shot cards', 'Tune easing curves', 'Render & review'];
132
- const TileSteps: React.FC = () => {
133
- const f = useCurrentFrame();
134
- return (
135
- <Pad bg={L.surface2}>
136
- <div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
137
- {STEPS.map((label, i) => {
138
- const on = F(f, 8 + i * 9, 22 + i * 9);
139
- const tick = F(f, 12 + i * 9, 22 + i * 9, EASE.overshoot);
140
- return (
141
- <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 26 }}>
142
- <div style={{
143
- width: 46, height: 46, borderRadius: 23, flex: 'none', boxSizing: 'border-box',
144
- background: on > 0.6 ? LIME : 'transparent', border: on > 0.6 ? 'none' : '3px solid rgba(220,255,170,0.18)',
145
- display: 'flex', alignItems: 'center', justifyContent: 'center',
146
- }}>
147
- <svg width={26} height={26} viewBox="0 0 24 24" style={{ transform: `scale(${tick})` }}>
148
- <path d="M5 12.5 L10 17 L19 7.5" fill="none" stroke={L.onAccent} strokeWidth={3.2} strokeLinecap="round" strokeLinejoin="round" />
149
- </svg>
150
- </div>
151
- <T size={38} weight={on > 0.6 ? 600 : 500} color={on > 0.6 ? INK : '#5f6556'}>{label}</T>
152
- </div>
153
- );
154
- })}
155
- </div>
156
- </Pad>
157
- );
158
- };
159
-
160
- /** 4 路线描线 + 落点钉针(暗网格地图底) */
161
- const ROUTE = 'M40 380 C 200 380 190 210 340 200 C 500 190 500 90 700 70';
162
- const TileRoute: React.FC = () => {
163
- const f = useCurrentFrame();
164
- const draw = F(f, 6, 42, EASE.smooth);
165
- const pin = springAt(f, 36, { damping: 12 });
166
- const tag = F(f, 42, 54);
167
- return (
168
- <Pad bg={L.surface2}>
169
- <div style={{ position: 'absolute', inset: 0, backgroundImage: 'linear-gradient(rgba(220,255,170,0.06) 2px, transparent 2px), linear-gradient(90deg, rgba(220,255,170,0.06) 2px, transparent 2px)', backgroundSize: '80px 80px' }} />
170
- <svg width={848} height={428} viewBox="0 0 848 428" style={{ position: 'relative', overflow: 'visible' }}>
171
- <path d={ROUTE} fill="none" stroke="rgba(220,255,170,0.14)" strokeWidth={10} strokeLinecap="round" />
172
- <path d={ROUTE} fill="none" stroke={LIME} strokeWidth={10} strokeLinecap="round" pathLength={1} strokeDasharray={1} strokeDashoffset={1 - draw} />
173
- <circle cx={40} cy={380} r={14} fill={L.surface2} stroke={LIME} strokeWidth={6} />
174
- <g transform={`translate(700 70) scale(${pin})`}>
175
- <circle r={36} fill={alpha(LIME, 0.2)} />
176
- <circle r={24} fill={LIME} />
177
- <circle r={9} fill={L.onAccent} />
178
- </g>
179
- </svg>
180
- <div style={{ position: 'absolute', left: 470, top: 64, padding: '10px 18px', borderRadius: 12, background: '#262a20', boxShadow: '0 0 0 2px rgba(220,255,170,0.1), 0 10px 24px rgba(0,0,0,0.4)', opacity: tag, transform: `translateY(${(1 - tag) * 10}px)` }}>
181
- <T size={28} weight={600}>ETA 12 min</T>
182
- </div>
183
- </Pad>
184
- );
185
- };
186
-
187
- /** 5 终端打字(打字是机械匀速语义,逐字线性揭示) */
188
- const TERM = [
189
- { t: '$ npx remotion render Open', c: '#e8ecdf' },
190
- { t: '✓ Bundled in 2.1s', c: LIME },
191
- { t: ' Rendering frames 0–149', c: '#8d937f' },
192
- { t: '✓ Done → out/open.mp4', c: LIME },
193
- ];
194
- const TileTerminal: React.FC = () => {
195
- const f = useCurrentFrame();
196
- return (
197
- <Pad bg="#0b0c09">
198
- <div style={{ display: 'flex', gap: 14, marginBottom: 34 }}>
199
- {[0.5, 0.3, 0.2].map((o, i) => <div key={i} style={{ width: 20, height: 20, borderRadius: 10, background: `rgba(220,255,170,${o})` }} />)}
200
- </div>
201
- <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
202
- <T size={30} mono color={LIME}>~/shotcraft</T>
203
- {TERM.map((row, i) => {
204
- const p = F(f, 8 + i * 11, 20 + i * 11, Easing.linear);
205
- const n = Math.round(row.t.length * p);
206
- return <T key={i} size={30} mono color={row.c} style={{ height: 37 }}>{row.t.slice(0, n)}</T>;
207
- })}
208
- </div>
209
- </Pad>
210
- );
211
- };
212
-
213
- /** 6 线稿描画(点阵纸底) */
214
- const SKETCH = ['M80 380 L768 380', 'M140 380 L200 90 L648 90 L708 380', 'M280 90 L280 380', 'M500 90 L500 380'];
215
- const TileSketch: React.FC = () => {
216
- const f = useCurrentFrame();
217
- return (
218
- <Pad>
219
- <div style={{ position: 'absolute', inset: 0, backgroundImage: 'radial-gradient(circle, rgba(220,255,170,0.14) 2px, transparent 2.5px)', backgroundSize: '40px 40px' }} />
220
- <svg width={848} height={428} viewBox="0 0 848 428" style={{ position: 'relative' }}>
221
- {SKETCH.map((d, i) => <path key={`g${i}`} d={d} fill="none" stroke="rgba(220,255,170,0.12)" strokeWidth={7} strokeLinecap="round" />)}
222
- {SKETCH.map((d, i) => {
223
- const p = F(f, 6 + i * 10, 24 + i * 10, EASE.smooth);
224
- return <path key={i} d={d} fill="none" stroke={i === 1 ? LIME : INK} strokeWidth={7} strokeLinecap="round" strokeLinejoin="round" pathLength={1} strokeDasharray={1} strokeDashoffset={1 - p} />;
225
- })}
226
- </svg>
227
- </Pad>
228
- );
229
- };
230
-
231
- /** 7 卡片缩成胶囊(主体让位) */
232
- const TileShrink: React.FC = () => {
233
- const f = useCurrentFrame();
234
- const p = F(f, 16, 44, EASE.smooth);
235
- const cont = F(f, 28, 50);
236
- return (
237
- <Pad bg={L.surface2}>
238
- <div style={{
239
- position: 'absolute', left: 60, top: 60, width: 840 - 690 * p, height: 420 - 342 * p, borderRadius: 16 + 30 * p,
240
- background: '#262a20', boxShadow: '0 0 0 2px rgba(220,255,170,0.08), 0 12px 28px rgba(0,0,0,0.35)', overflow: 'hidden',
241
- display: 'flex', alignItems: p > 0.6 ? 'center' : 'flex-start', justifyContent: p > 0.6 ? 'center' : 'flex-start',
242
- padding: p > 0.6 ? 0 : 40, boxSizing: 'border-box',
243
- }}>
244
- {p <= 0.6 ? (
245
- <div style={{ opacity: 1 - p / 0.6 }}>
246
- <Caps>WEEKLY SUMMARY</Caps>
247
- <T size={46} weight={700} style={{ marginTop: 18 }}>12 shots approved</T>
248
- <T size={28} color={DIM} weight={450} style={{ marginTop: 10 }}>3 pending review · 1 re-render</T>
249
- </div>
250
- ) : (
251
- <T size={30} weight={600} color={LIME} style={{ opacity: (p - 0.6) / 0.4 }}>Summary</T>
252
- )}
253
- </div>
254
- <div style={{ position: 'absolute', left: 260, top: 150, opacity: cont, transform: `translateX(${(1 - cont) * 24}px)` }}>
255
- <T size={48} weight={700}>Q3 launch plan</T>
256
- <T size={28} color={DIM} weight={450} style={{ marginTop: 14 }}>Owner · Studio team</T>
257
- <T size={28} color={DIM} weight={450} style={{ marginTop: 6 }}>Due Oct 18</T>
258
- </div>
259
- </Pad>
260
- );
261
- };
262
-
263
- /** 8 冲击字卡 */
264
- const TileImpact: React.FC = () => {
265
- const f = useCurrentFrame();
266
- const p = springAt(f, 8, { damping: 13, mass: 0.7 });
267
- return (
268
- <Pad bg="#0f110c">
269
- <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 22 }}>
270
- <div style={{ fontSize: 30, fontWeight: 650, color: LIME, letterSpacing: '0.4em', fontFamily: SANS }}>2026 · Q3</div>
271
- <div style={{ fontSize: 150, fontWeight: 850, letterSpacing: '-0.05em', color: INK, fontFamily: SANS, transform: `scale(${0.72 + p * 0.28})`, opacity: Math.min(1, p) }}>GO LIVE</div>
272
- </div>
273
- </Pad>
274
- );
275
- };
276
-
277
- const TILES: React.FC[] = [TileSweep, TileShrink, TileMetric, TileRoute, TileSteps, TileTerminal, TileSketch, TileImpact];
278
-
279
- // ── 标题逐字:位移只占前 1/3,解糊走满(同起不同终 = blur-slide 的手感)──
280
- const charStyle = (frame: number, at: number, size: number, dur: number): React.CSSProperties => {
281
- const pMain = ramp(frame, at, dur, EASE.out);
282
- const pTravel = ramp(frame, at, dur / 3, EASE.out);
283
- return {
284
- display: 'inline-block', whiteSpace: 'pre', transformOrigin: '50% 55%', opacity: pMain,
285
- filter: pMain < 1 ? `blur(${((1 - pMain) * (size / 6)).toFixed(2)}px)` : undefined,
286
- transform: `translateY(${((1 - pTravel) * size * 0.22).toFixed(2)}px)`,
287
- };
288
- };
289
-
290
- // ── 主体 ───────────────────────────────────────────────────────────────────
291
- export const OrbitRingTitleOpen: React.FC = () => {
292
- const frame = useCurrentFrame();
293
- const { fps } = useVideoConfig();
294
- const t = frame / fps;
295
-
296
- const ringIn = ramp(frame, 0, RING_IN, EASE.snappy);
297
- const ringScale = RING_SCALE_FROM + (1 - RING_SCALE_FROM) * ringIn;
298
- const rot = t * ROT_SPEED;
299
- const track = ramp(frame, 0, 30, EASE.out);
300
- const push = 1 + 0.025 * ramp(frame, 40, 110, EASE.smooth); // hold 段极缓推近
301
-
302
- const marker = Math.min(1.03, springAt(frame, MARKER_AT, { damping: 20, stiffness: 190 }));
303
- const kickerIn = ramp(frame, 60, 16, EASE.out);
304
- const exitQ = HANDOFF_EXIT ? ramp(frame, EXIT_AT, 10, EASE.exit) : 0;
305
- const titleExit: React.CSSProperties = { opacity: 1 - exitQ, filter: exitQ > 0.01 ? `blur(${(exitQ * 6.5).toFixed(2)}px)` : undefined };
306
-
307
- const l1 = Array.from(LINE1);
308
- const l2 = Array.from(LINE2);
309
- const line2 = (color: string) => l2.map((ch, j) => <span key={j} style={{ ...charStyle(frame, 18 + j * 2, S2, 32), color }}>{ch}</span>);
310
- // 马克块比字宽出左右各 0.14em:块前沿在字盒里的位置 = (m·(W+0.28em) − 0.14em) / W,W ≈ 5.05em
311
- const edge = Math.min(1, Math.max(0, (Math.min(1, marker) * 5.33 - 0.14) / 5.05));
312
- const clipR = ((1 - edge) * 100).toFixed(2);
313
- const clipL = (edge * 100).toFixed(2);
314
-
315
- return (
316
- <AbsoluteFill style={{ background: L.bg[1], fontFamily: SANS }}>
317
- <Stage look={L} keyLight={{ x: 0.5, y: 0.0 }} fill={null} intensity={0.5} vignette={0.62}>
318
- {/* 标题背后的暗 scrim:卡从背后经过时标题始终压得住 */}
319
- <div style={{ position: 'absolute', left: 360, top: 300, width: 1200, height: 480, background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${alpha('#050604', 0.75)} 0%, ${alpha('#050604', 0)} 70%)` }} />
320
- </Stage>
321
-
322
- <AbsoluteFill style={{ transform: `scale(${push})` }}>
323
- {/* 椭圆轨道发丝线:入场时描出来,给环一个看得见的几何 */}
324
- <svg width={1920} height={1080} style={{ position: 'absolute', inset: 0 }}>
325
- <ellipse cx={960} cy={540} rx={RX * ringScale} ry={RY * ringScale} fill="none" stroke={alpha(LIME, 0.16)} strokeWidth={1.5}
326
- pathLength={1} strokeDasharray="1" strokeDashoffset={1 - track} />
327
- </svg>
328
-
329
- {TILES.map((Comp, i) => {
330
- const theta = -Math.PI / 2 + (i * Math.PI * 2) / N + rot;
331
- const x = 960 + Math.cos(theta) * RX * ringScale;
332
- const y = 540 + Math.sin(theta) * RY * ringScale;
333
- const depth = Math.sin(theta); // +1 = 画面下方(近),−1 = 上方(远)
334
- const s = 1 + DEPTH_SCALE * depth;
335
- const op = ramp(frame, 2 + i * 1.5, 11, EASE.out);
336
- const grow = 0.9 + 0.1 * op;
337
- const far = Math.max(0, -depth); // 远处:压暗 + 轻微失焦
338
- const elev = 14 + 12 * depth;
339
- return (
340
- <div key={i} style={{
341
- position: 'absolute', left: x - (CW * s) / 2, top: y - (CH * s) / 2, width: CW * s, height: CH * s,
342
- borderRadius: 14, overflow: 'hidden', opacity: op, transform: `scale(${grow})`, zIndex: 10 + Math.round(depth * 5),
343
- boxShadow: `inset 0 1px 0 rgba(255,255,255,0.08), 0 0 0 1px ${L.line}, 0 ${(elev * 0.6).toFixed(1)}px ${(elev * 1.6).toFixed(1)}px rgba(0,0,0,${(0.45 + 0.2 * depth).toFixed(2)})`,
344
- filter: far > 0.05 ? `blur(${(far * 1.6).toFixed(2)}px)` : undefined,
345
- }}>
346
- {/* 卡内按 960×540 作画再整体缩到卡宽——内容组件不需要知道自己被缩小了 */}
347
- <div style={{ position: 'absolute', left: 0, top: 0, width: 960, height: 540, transform: `scale(${(CW * s) / 960})`, transformOrigin: 'top left' }}>
348
- <Freeze frame={Math.max(0, frame - PLAY_START)}>
349
- <Comp />
350
- </Freeze>
351
- </div>
352
- {/* 纵深明暗:远处压暗、近处带一点顶光 */}
353
- <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(180deg, rgba(255,255,255,${(0.04 * Math.max(0, depth)).toFixed(3)}) 0%, rgba(5,6,4,${(0.5 * far).toFixed(3)}) 100%), rgba(5,6,4,${(0.25 * far).toFixed(3)})` }} />
354
- </div>
355
- );
356
- })}
357
-
358
- {/* 卡与标题之间的暗 scrim(在卡之上、字之下):近处卡从标题背后经过时被压暗,字始终压得住 */}
359
- <div style={{ position: 'absolute', left: 260, top: 250, width: 1400, height: 560, zIndex: 25, background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${alpha('#060705', 0.82)} 0%, ${alpha('#060705', 0.55)} 45%, ${alpha('#060705', 0)} 72%)` }} />
360
-
361
- {/* 标题:上行次级灰、下行主角大字 + 荧光马克 */}
362
- <div style={{ position: 'absolute', left: 0, right: 0, top: 336, textAlign: 'center', zIndex: 30, ...titleExit }}>
363
- <div style={{ fontSize: S1, fontWeight: 500, letterSpacing: '0.02em', color: '#b7bdaa', whiteSpace: 'nowrap', lineHeight: 1 }}>
364
- {l1.map((ch, i) => <span key={i} style={charStyle(frame, 10 + i, S1, 27)}>{ch}</span>)}
365
- </div>
366
- <div style={{ marginTop: 34, display: 'inline-block', position: 'relative', fontSize: S2, fontWeight: 600, letterSpacing: '0.01em', lineHeight: 1.12, whiteSpace: 'nowrap' }}>
367
- {/* 马克块:自左横扫铺满(垫在字下) */}
368
- <span aria-hidden style={{
369
- position: 'absolute', left: '-0.14em', right: '-0.14em', top: '0.1em', bottom: '0.04em', background: LIME, borderRadius: 8,
370
- transformOrigin: 'left center', transform: `scaleX(${marker.toFixed(4)})`, boxShadow: marker > 0.02 ? `0 0 60px ${alpha(LIME, 0.28)}` : undefined,
371
- }} />
372
- {/* 两层字:块的前沿左边是墨色、右边是白色——扫过即反白 */}
373
- <span style={{ position: 'relative', display: 'inline-block', clipPath: `inset(-20% 0 -20% ${clipL}%)`, color: INK }}>{line2(INK)}</span>
374
- <span aria-hidden style={{ position: 'absolute', left: 0, top: 0, display: 'inline-block', clipPath: `inset(-20% ${clipR}% -20% 0)` }}>{line2(L.onAccent)}</span>
375
- </div>
376
- <div style={{
377
- marginTop: 40, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 16, whiteSpace: 'pre',
378
- opacity: kickerIn, transform: `translateY(${((1 - kickerIn) * 12).toFixed(2)}px)`,
379
- }}>
380
- <ShotcraftMark size={44} tone="dark" />
381
- <span style={{ fontFamily: BRAND.font, fontSize: 30, fontWeight: 700, letterSpacing: '0.03em', color: INK, lineHeight: 1 }}>{BRAND.name}</span>
382
- <span style={{ fontFamily: MONO, fontSize: 26, fontWeight: 600, color: DIM, lineHeight: 1 }}>·</span>
383
- <span style={{ fontFamily: MONO, fontSize: 26, fontWeight: 600, letterSpacing: '0.2em', marginRight: '-0.2em', color: DIM, lineHeight: 1 }}>{KICKER}</span>
384
- </div>
385
- </div>
386
- </AbsoluteFill>
387
- </AbsoluteFill>
388
- );
389
- };
1
+ // orbit-ring-title-open — 环形卡阵标题开场
2
+ // 八张 16:9 内容卡按 45° 均布在椭圆上匀速公转(卡身永不倾斜,纵深只由 sin(θ) 给出缩放、
3
+ // z 序、景深与明暗),入场期卡内容冻结首帧、环撑开落定后统一开播;居中标题逐字解糊下沉落定,
4
+ // 关键词全部到位那一刻荧光马克块自左横扫铺满(扫过处字色反白为墨),mono 副行随后浮出。
5
+ //
6
+ // 第二轮重设计(石墨夜 · 荧光笔):
7
+ // - look = lime:石墨暗场 + 荧光黄绿。马克块从"黄色便利贴"变成一支荧光笔——暗场里唯一的高饱和色块,
8
+ // 只给关键词「每一个动效」。八张卡全部换成暗色产品卡(深石墨底 + 发丝线 + 顶部内高光),
9
+ // 卡内小动效统一用荧光绿做唯一强调,卡内字只做纹理(读的是标题)。
10
+ // - 标题从 64px 单行改成两级:上行 64px 次级灰「让镜头卡替你想好」,下行 156px「每一个动效」做主角;
11
+ // 马克块扫过时用两层裁切让字从白翻成墨色(反白在块的前沿同步发生,读作"被荧光笔划过")。
12
+ // - 空间:椭圆轨道本身画成一圈极淡的发丝线(入场时描出来),卡的纵深除了 ±12% 缩放,
13
+ // 远处(上方)的卡再压暗 + 轻微失焦,近处(下方)全亮全清——环有前后,标题在焦平面上。
14
+ // 标题后垫一团暗色 scrim,保证卡从背后经过时标题始终压得住。
15
+ // - 收尾:原版末段整行失焦退场做交棒;单镜头演示改为停在完整海报(HANDOFF_EXIT 开关保留退场逻辑)。
16
+ //
17
+ // 时间表(30fps,共 150f):
18
+ // 0–24 环从 0.62 撑开到满径(snappy)+ 逐卡淡入;轨道发丝线 0–30 描出
19
+ // 24 八张卡同时开播(冻结首帧 → 正常时间轴)
20
+ // 10–40 上行逐字解糊下沉(错峰 1f)
21
+ // 18–52 下行大字逐字解糊下沉(错峰 2f,更重更慢)
22
+ // 50–64 荧光马克块横扫(弹簧,damping 20),扫过处字反白为墨
23
+ // 60–76 副行(标志 + video-shotcraft + mono 代号)浮出
24
+ // 76–150 hold:环持续匀速公转 + 整体极缓推近 2.5%;最后 2.5s 是一张完整海报
25
+ import React from 'react';
26
+ import { AbsoluteFill, Easing, Freeze, interpolate, useCurrentFrame, useVideoConfig } from 'remotion';
27
+ import { EASE, FONT, ramp } from '../../_fixtures/Polish';
28
+ import { LOOKS, Stage, alpha, springAt } from '../../_fixtures/Look';
29
+ import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
30
+
31
+ export const ORBIT_RING_TITLE_OPEN_DURATION = 150; // 5s @30fps
32
+
33
+ const L = LOOKS.lime;
34
+ const LIME = L.accent;
35
+
36
+ // ---- 环 ----
37
+ const RX = 720; // 椭圆长半轴
38
+ const RY = 380; // 椭圆短半轴(RY/RX≈0.53 → 读作俯视的环,不是正圆转盘)
39
+ const CW = 400; // 卡宽(16:9)
40
+ const CH = 225;
41
+ const N = 8;
42
+ const ROT_SPEED = 0.3; // rad/s,正值 = 顺时针
43
+ const RING_IN = 24; // f:从中心撑开到满径
44
+ const RING_SCALE_FROM = 0.62;
45
+ const PLAY_START = 24; // f:环撑开后卡内容才开播
46
+ const DEPTH_SCALE = 0.12; // 近大远小幅度(底部近、顶部远)
47
+
48
+ // ---- 标题 ----
49
+ const LINE1 = '让镜头卡替你想好';
50
+ const LINE2 = '每一个动效';
51
+ const S1 = 64;
52
+ const S2 = 156;
53
+ const MARKER_AT = 50; // 下行末字视觉到位那一刻起扫
54
+ // 副行 = video-shotcraft 标志 + 小写字标 + mono 产品代号(不写卡片数:会过时)
55
+ const KICKER = 'SHOT RECIPE CARDS';
56
+ const HANDOFF_EXIT = false; // true = 末段整行失焦淡出、环继续转着交棒下一镜(成片里接下一镜时打开)
57
+ const EXIT_AT = 118;
58
+
59
+ const SANS = `${FONT.sans.replace('Arial, sans-serif', '')}"PingFang SC", "Hiragino Sans GB", sans-serif`;
60
+ const MONO = FONT.mono;
61
+ const INK = L.ink;
62
+ const DIM = '#8d937f';
63
+
64
+ // ── 卡内占位内容(暗色产品卡,960×540 作画后整体缩到卡宽)──────────────────
65
+ const F = (frame: number, a: number, b: number, ease = Easing.out(Easing.cubic)) =>
66
+ interpolate(frame, [a, b], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: ease });
67
+
68
+ const Pad: React.FC<{ children: React.ReactNode; bg?: string }> = ({ children, bg = L.surface }) => (
69
+ <div style={{ position: 'absolute', inset: 0, background: bg, padding: 60, fontFamily: SANS, boxSizing: 'border-box' }}>{children}</div>
70
+ );
71
+
72
+ const T: React.FC<{ size: number; color?: string; weight?: number; mono?: boolean; style?: React.CSSProperties; children: React.ReactNode }> = ({
73
+ size, color = INK, weight = 500, mono, style, children,
74
+ }) => (
75
+ <div style={{
76
+ fontSize: size, color, fontWeight: weight, fontFamily: mono ? MONO : SANS,
77
+ letterSpacing: mono ? 0 : size >= 40 ? '-0.035em' : '-0.01em', lineHeight: 1.2, whiteSpace: 'nowrap', ...style,
78
+ }}>{children}</div>
79
+ );
80
+ const Caps: React.FC<{ children: React.ReactNode; color?: string }> = ({ children, color = DIM }) => (
81
+ <div style={{ fontSize: 24, fontWeight: 650, letterSpacing: '0.16em', color }}>{children}</div>
82
+ );
83
+
84
+ /** 1 荧光笔扫读 */
85
+ const TileSweep: React.FC = () => {
86
+ const f = useCurrentFrame();
87
+ const s = F(f, 14, 32, EASE.snappy);
88
+ return (
89
+ <Pad>
90
+ <Caps>RELEASE NOTES · 4.2</Caps>
91
+ <div style={{ position: 'relative', display: 'inline-block', marginTop: 40 }}>
92
+ <div style={{ position: 'absolute', left: -12, right: -12, top: 4, bottom: 0, background: LIME, borderRadius: 4, transformOrigin: 'left center', transform: `scaleX(${s})` }} />
93
+ <T size={58} weight={700} color={s > 0.6 ? L.onAccent : INK} style={{ position: 'relative' }}>Motion, considered.</T>
94
+ </div>
95
+ <T size={30} color={DIM} weight={450} style={{ marginTop: 34 }}>Every card ships with timing, easing</T>
96
+ <T size={30} color={DIM} weight={450} style={{ marginTop: 8 }}>and a validated reference build.</T>
97
+ </Pad>
98
+ );
99
+ };
100
+
101
+ /** 2 指标 + sparkline 描线 */
102
+ const SPARK = 'M8 118 L118 92 L228 104 L338 56 L448 68 L558 20 L632 34';
103
+ const TileMetric: React.FC = () => {
104
+ const f = useCurrentFrame();
105
+ const draw = F(f, 10, 46, EASE.smooth);
106
+ const val = 128 + Math.round(F(f, 8, 40, Easing.out(Easing.quad)) * 84);
107
+ const chip = F(f, 34, 46);
108
+ return (
109
+ <Pad>
110
+ <div style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
111
+ <Caps>RENDERS / DAY</Caps>
112
+ <div style={{ fontSize: 24, fontWeight: 650, color: L.onAccent, background: LIME, padding: '4px 12px', borderRadius: 999, opacity: chip, transform: `translateY(${(1 - chip) * 8}px)` }}>+18.4%</div>
113
+ </div>
114
+ <div style={{ fontSize: 140, fontWeight: 700, color: INK, letterSpacing: '-0.045em', fontVariantNumeric: 'tabular-nums', lineHeight: 1.1, fontFamily: SANS }}>{val}</div>
115
+ <svg width={640} height={140} viewBox="0 0 640 140" style={{ marginTop: 8, overflow: 'visible' }}>
116
+ <defs>
117
+ <linearGradient id="orto-area" x1="0" y1="0" x2="0" y2="1">
118
+ <stop offset="0" stopColor={LIME} stopOpacity={0.28} />
119
+ <stop offset="1" stopColor={LIME} stopOpacity={0} />
120
+ </linearGradient>
121
+ </defs>
122
+ <path d={`${SPARK} L632 140 L8 140 Z`} fill="url(#orto-area)" opacity={draw} />
123
+ <path d={SPARK} fill="none" stroke="rgba(220,255,170,0.12)" strokeWidth={8} strokeLinecap="round" strokeLinejoin="round" />
124
+ <path d={SPARK} fill="none" stroke={LIME} strokeWidth={8} strokeLinecap="round" strokeLinejoin="round" pathLength={1} strokeDasharray={1} strokeDashoffset={1 - draw} />
125
+ </svg>
126
+ </Pad>
127
+ );
128
+ };
129
+
130
+ /** 3 竖向步骤清单逐条勾选 */
131
+ const STEPS = ['Draft the storyboard', 'Pick shot cards', 'Tune easing curves', 'Render & review'];
132
+ const TileSteps: React.FC = () => {
133
+ const f = useCurrentFrame();
134
+ return (
135
+ <Pad bg={L.surface2}>
136
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
137
+ {STEPS.map((label, i) => {
138
+ const on = F(f, 8 + i * 9, 22 + i * 9);
139
+ const tick = F(f, 12 + i * 9, 22 + i * 9, EASE.overshoot);
140
+ return (
141
+ <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 26 }}>
142
+ <div style={{
143
+ width: 46, height: 46, borderRadius: 23, flex: 'none', boxSizing: 'border-box',
144
+ background: on > 0.6 ? LIME : 'transparent', border: on > 0.6 ? 'none' : '3px solid rgba(220,255,170,0.18)',
145
+ display: 'flex', alignItems: 'center', justifyContent: 'center',
146
+ }}>
147
+ <svg width={26} height={26} viewBox="0 0 24 24" style={{ transform: `scale(${tick})` }}>
148
+ <path d="M5 12.5 L10 17 L19 7.5" fill="none" stroke={L.onAccent} strokeWidth={3.2} strokeLinecap="round" strokeLinejoin="round" />
149
+ </svg>
150
+ </div>
151
+ <T size={38} weight={on > 0.6 ? 600 : 500} color={on > 0.6 ? INK : '#5f6556'}>{label}</T>
152
+ </div>
153
+ );
154
+ })}
155
+ </div>
156
+ </Pad>
157
+ );
158
+ };
159
+
160
+ /** 4 路线描线 + 落点钉针(暗网格地图底) */
161
+ const ROUTE = 'M40 380 C 200 380 190 210 340 200 C 500 190 500 90 700 70';
162
+ const TileRoute: React.FC = () => {
163
+ const f = useCurrentFrame();
164
+ const draw = F(f, 6, 42, EASE.smooth);
165
+ const pin = springAt(f, 36, { damping: 12 });
166
+ const tag = F(f, 42, 54);
167
+ return (
168
+ <Pad bg={L.surface2}>
169
+ <div style={{ position: 'absolute', inset: 0, backgroundImage: 'linear-gradient(rgba(220,255,170,0.06) 2px, transparent 2px), linear-gradient(90deg, rgba(220,255,170,0.06) 2px, transparent 2px)', backgroundSize: '80px 80px' }} />
170
+ <svg width={848} height={428} viewBox="0 0 848 428" style={{ position: 'relative', overflow: 'visible' }}>
171
+ <path d={ROUTE} fill="none" stroke="rgba(220,255,170,0.14)" strokeWidth={10} strokeLinecap="round" />
172
+ <path d={ROUTE} fill="none" stroke={LIME} strokeWidth={10} strokeLinecap="round" pathLength={1} strokeDasharray={1} strokeDashoffset={1 - draw} />
173
+ <circle cx={40} cy={380} r={14} fill={L.surface2} stroke={LIME} strokeWidth={6} />
174
+ <g transform={`translate(700 70) scale(${pin})`}>
175
+ <circle r={36} fill={alpha(LIME, 0.2)} />
176
+ <circle r={24} fill={LIME} />
177
+ <circle r={9} fill={L.onAccent} />
178
+ </g>
179
+ </svg>
180
+ <div style={{ position: 'absolute', left: 470, top: 64, padding: '10px 18px', borderRadius: 12, background: '#262a20', boxShadow: '0 0 0 2px rgba(220,255,170,0.1), 0 10px 24px rgba(0,0,0,0.4)', opacity: tag, transform: `translateY(${(1 - tag) * 10}px)` }}>
181
+ <T size={28} weight={600}>ETA 12 min</T>
182
+ </div>
183
+ </Pad>
184
+ );
185
+ };
186
+
187
+ /** 5 终端打字(打字是机械匀速语义,逐字线性揭示) */
188
+ const TERM = [
189
+ { t: '$ npx remotion render Open', c: '#e8ecdf' },
190
+ { t: '✓ Bundled in 2.1s', c: LIME },
191
+ { t: ' Rendering frames 0–149', c: '#8d937f' },
192
+ { t: '✓ Done → out/open.mp4', c: LIME },
193
+ ];
194
+ const TileTerminal: React.FC = () => {
195
+ const f = useCurrentFrame();
196
+ return (
197
+ <Pad bg="#0b0c09">
198
+ <div style={{ display: 'flex', gap: 14, marginBottom: 34 }}>
199
+ {[0.5, 0.3, 0.2].map((o, i) => <div key={i} style={{ width: 20, height: 20, borderRadius: 10, background: `rgba(220,255,170,${o})` }} />)}
200
+ </div>
201
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
202
+ <T size={30} mono color={LIME}>~/shotcraft</T>
203
+ {TERM.map((row, i) => {
204
+ const p = F(f, 8 + i * 11, 20 + i * 11, Easing.linear);
205
+ const n = Math.round(row.t.length * p);
206
+ return <T key={i} size={30} mono color={row.c} style={{ height: 37 }}>{row.t.slice(0, n)}</T>;
207
+ })}
208
+ </div>
209
+ </Pad>
210
+ );
211
+ };
212
+
213
+ /** 6 线稿描画(点阵纸底) */
214
+ const SKETCH = ['M80 380 L768 380', 'M140 380 L200 90 L648 90 L708 380', 'M280 90 L280 380', 'M500 90 L500 380'];
215
+ const TileSketch: React.FC = () => {
216
+ const f = useCurrentFrame();
217
+ return (
218
+ <Pad>
219
+ <div style={{ position: 'absolute', inset: 0, backgroundImage: 'radial-gradient(circle, rgba(220,255,170,0.14) 2px, transparent 2.5px)', backgroundSize: '40px 40px' }} />
220
+ <svg width={848} height={428} viewBox="0 0 848 428" style={{ position: 'relative' }}>
221
+ {SKETCH.map((d, i) => <path key={`g${i}`} d={d} fill="none" stroke="rgba(220,255,170,0.12)" strokeWidth={7} strokeLinecap="round" />)}
222
+ {SKETCH.map((d, i) => {
223
+ const p = F(f, 6 + i * 10, 24 + i * 10, EASE.smooth);
224
+ return <path key={i} d={d} fill="none" stroke={i === 1 ? LIME : INK} strokeWidth={7} strokeLinecap="round" strokeLinejoin="round" pathLength={1} strokeDasharray={1} strokeDashoffset={1 - p} />;
225
+ })}
226
+ </svg>
227
+ </Pad>
228
+ );
229
+ };
230
+
231
+ /** 7 卡片缩成胶囊(主体让位) */
232
+ const TileShrink: React.FC = () => {
233
+ const f = useCurrentFrame();
234
+ const p = F(f, 16, 44, EASE.smooth);
235
+ const cont = F(f, 28, 50);
236
+ return (
237
+ <Pad bg={L.surface2}>
238
+ <div style={{
239
+ position: 'absolute', left: 60, top: 60, width: 840 - 690 * p, height: 420 - 342 * p, borderRadius: 16 + 30 * p,
240
+ background: '#262a20', boxShadow: '0 0 0 2px rgba(220,255,170,0.08), 0 12px 28px rgba(0,0,0,0.35)', overflow: 'hidden',
241
+ display: 'flex', alignItems: p > 0.6 ? 'center' : 'flex-start', justifyContent: p > 0.6 ? 'center' : 'flex-start',
242
+ padding: p > 0.6 ? 0 : 40, boxSizing: 'border-box',
243
+ }}>
244
+ {p <= 0.6 ? (
245
+ <div style={{ opacity: 1 - p / 0.6 }}>
246
+ <Caps>WEEKLY SUMMARY</Caps>
247
+ <T size={46} weight={700} style={{ marginTop: 18 }}>12 shots approved</T>
248
+ <T size={28} color={DIM} weight={450} style={{ marginTop: 10 }}>3 pending review · 1 re-render</T>
249
+ </div>
250
+ ) : (
251
+ <T size={30} weight={600} color={LIME} style={{ opacity: (p - 0.6) / 0.4 }}>Summary</T>
252
+ )}
253
+ </div>
254
+ <div style={{ position: 'absolute', left: 260, top: 150, opacity: cont, transform: `translateX(${(1 - cont) * 24}px)` }}>
255
+ <T size={48} weight={700}>Q3 launch plan</T>
256
+ <T size={28} color={DIM} weight={450} style={{ marginTop: 14 }}>Owner · Studio team</T>
257
+ <T size={28} color={DIM} weight={450} style={{ marginTop: 6 }}>Due Oct 18</T>
258
+ </div>
259
+ </Pad>
260
+ );
261
+ };
262
+
263
+ /** 8 冲击字卡 */
264
+ const TileImpact: React.FC = () => {
265
+ const f = useCurrentFrame();
266
+ const p = springAt(f, 8, { damping: 13, mass: 0.7 });
267
+ return (
268
+ <Pad bg="#0f110c">
269
+ <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 22 }}>
270
+ <div style={{ fontSize: 30, fontWeight: 650, color: LIME, letterSpacing: '0.4em', fontFamily: SANS }}>2026 · Q3</div>
271
+ <div style={{ fontSize: 150, fontWeight: 850, letterSpacing: '-0.05em', color: INK, fontFamily: SANS, transform: `scale(${0.72 + p * 0.28})`, opacity: Math.min(1, p) }}>GO LIVE</div>
272
+ </div>
273
+ </Pad>
274
+ );
275
+ };
276
+
277
+ const TILES: React.FC[] = [TileSweep, TileShrink, TileMetric, TileRoute, TileSteps, TileTerminal, TileSketch, TileImpact];
278
+
279
+ // ── 标题逐字:位移只占前 1/3,解糊走满(同起不同终 = blur-slide 的手感)──
280
+ const charStyle = (frame: number, at: number, size: number, dur: number): React.CSSProperties => {
281
+ const pMain = ramp(frame, at, dur, EASE.out);
282
+ const pTravel = ramp(frame, at, dur / 3, EASE.out);
283
+ return {
284
+ display: 'inline-block', whiteSpace: 'pre', transformOrigin: '50% 55%', opacity: pMain,
285
+ filter: pMain < 1 ? `blur(${((1 - pMain) * (size / 6)).toFixed(2)}px)` : undefined,
286
+ transform: `translateY(${((1 - pTravel) * size * 0.22).toFixed(2)}px)`,
287
+ };
288
+ };
289
+
290
+ // ── 主体 ───────────────────────────────────────────────────────────────────
291
+ export const OrbitRingTitleOpen: React.FC = () => {
292
+ const frame = useCurrentFrame();
293
+ const { fps } = useVideoConfig();
294
+ const t = frame / fps;
295
+
296
+ const ringIn = ramp(frame, 0, RING_IN, EASE.snappy);
297
+ const ringScale = RING_SCALE_FROM + (1 - RING_SCALE_FROM) * ringIn;
298
+ const rot = t * ROT_SPEED;
299
+ const track = ramp(frame, 0, 30, EASE.out);
300
+ const push = 1 + 0.025 * ramp(frame, 40, 110, EASE.smooth); // hold 段极缓推近
301
+
302
+ const marker = Math.min(1.03, springAt(frame, MARKER_AT, { damping: 20, stiffness: 190 }));
303
+ const kickerIn = ramp(frame, 60, 16, EASE.out);
304
+ const exitQ = HANDOFF_EXIT ? ramp(frame, EXIT_AT, 10, EASE.exit) : 0;
305
+ const titleExit: React.CSSProperties = { opacity: 1 - exitQ, filter: exitQ > 0.01 ? `blur(${(exitQ * 6.5).toFixed(2)}px)` : undefined };
306
+
307
+ const l1 = Array.from(LINE1);
308
+ const l2 = Array.from(LINE2);
309
+ const line2 = (color: string) => l2.map((ch, j) => <span key={j} style={{ ...charStyle(frame, 18 + j * 2, S2, 32), color }}>{ch}</span>);
310
+ // 马克块比字宽出左右各 0.14em:块前沿在字盒里的位置 = (m·(W+0.28em) − 0.14em) / W,W ≈ 5.05em
311
+ const edge = Math.min(1, Math.max(0, (Math.min(1, marker) * 5.33 - 0.14) / 5.05));
312
+ const clipR = ((1 - edge) * 100).toFixed(2);
313
+ const clipL = (edge * 100).toFixed(2);
314
+
315
+ return (
316
+ <AbsoluteFill style={{ background: L.bg[1], fontFamily: SANS }}>
317
+ <Stage look={L} keyLight={{ x: 0.5, y: 0.0 }} fill={null} intensity={0.5} vignette={0.62}>
318
+ {/* 标题背后的暗 scrim:卡从背后经过时标题始终压得住 */}
319
+ <div style={{ position: 'absolute', left: 360, top: 300, width: 1200, height: 480, background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${alpha('#050604', 0.75)} 0%, ${alpha('#050604', 0)} 70%)` }} />
320
+ </Stage>
321
+
322
+ <AbsoluteFill style={{ transform: `scale(${push})` }}>
323
+ {/* 椭圆轨道发丝线:入场时描出来,给环一个看得见的几何 */}
324
+ <svg width={1920} height={1080} style={{ position: 'absolute', inset: 0 }}>
325
+ <ellipse cx={960} cy={540} rx={RX * ringScale} ry={RY * ringScale} fill="none" stroke={alpha(LIME, 0.16)} strokeWidth={1.5}
326
+ pathLength={1} strokeDasharray="1" strokeDashoffset={1 - track} />
327
+ </svg>
328
+
329
+ {TILES.map((Comp, i) => {
330
+ const theta = -Math.PI / 2 + (i * Math.PI * 2) / N + rot;
331
+ const x = 960 + Math.cos(theta) * RX * ringScale;
332
+ const y = 540 + Math.sin(theta) * RY * ringScale;
333
+ const depth = Math.sin(theta); // +1 = 画面下方(近),−1 = 上方(远)
334
+ const s = 1 + DEPTH_SCALE * depth;
335
+ const op = ramp(frame, 2 + i * 1.5, 11, EASE.out);
336
+ const grow = 0.9 + 0.1 * op;
337
+ const far = Math.max(0, -depth); // 远处:压暗 + 轻微失焦
338
+ const elev = 14 + 12 * depth;
339
+ return (
340
+ <div key={i} style={{
341
+ position: 'absolute', left: x - (CW * s) / 2, top: y - (CH * s) / 2, width: CW * s, height: CH * s,
342
+ borderRadius: 14, overflow: 'hidden', opacity: op, transform: `scale(${grow})`, zIndex: 10 + Math.round(depth * 5),
343
+ boxShadow: `inset 0 1px 0 rgba(255,255,255,0.08), 0 0 0 1px ${L.line}, 0 ${(elev * 0.6).toFixed(1)}px ${(elev * 1.6).toFixed(1)}px rgba(0,0,0,${(0.45 + 0.2 * depth).toFixed(2)})`,
344
+ filter: far > 0.05 ? `blur(${(far * 1.6).toFixed(2)}px)` : undefined,
345
+ }}>
346
+ {/* 卡内按 960×540 作画再整体缩到卡宽——内容组件不需要知道自己被缩小了 */}
347
+ <div style={{ position: 'absolute', left: 0, top: 0, width: 960, height: 540, transform: `scale(${(CW * s) / 960})`, transformOrigin: 'top left' }}>
348
+ <Freeze frame={Math.max(0, frame - PLAY_START)}>
349
+ <Comp />
350
+ </Freeze>
351
+ </div>
352
+ {/* 纵深明暗:远处压暗、近处带一点顶光 */}
353
+ <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(180deg, rgba(255,255,255,${(0.04 * Math.max(0, depth)).toFixed(3)}) 0%, rgba(5,6,4,${(0.5 * far).toFixed(3)}) 100%), rgba(5,6,4,${(0.25 * far).toFixed(3)})` }} />
354
+ </div>
355
+ );
356
+ })}
357
+
358
+ {/* 卡与标题之间的暗 scrim(在卡之上、字之下):近处卡从标题背后经过时被压暗,字始终压得住 */}
359
+ <div style={{ position: 'absolute', left: 260, top: 250, width: 1400, height: 560, zIndex: 25, background: `radial-gradient(ellipse 50% 50% at 50% 50%, ${alpha('#060705', 0.82)} 0%, ${alpha('#060705', 0.55)} 45%, ${alpha('#060705', 0)} 72%)` }} />
360
+
361
+ {/* 标题:上行次级灰、下行主角大字 + 荧光马克 */}
362
+ <div style={{ position: 'absolute', left: 0, right: 0, top: 336, textAlign: 'center', zIndex: 30, ...titleExit }}>
363
+ <div style={{ fontSize: S1, fontWeight: 500, letterSpacing: '0.02em', color: '#b7bdaa', whiteSpace: 'nowrap', lineHeight: 1 }}>
364
+ {l1.map((ch, i) => <span key={i} style={charStyle(frame, 10 + i, S1, 27)}>{ch}</span>)}
365
+ </div>
366
+ <div style={{ marginTop: 34, display: 'inline-block', position: 'relative', fontSize: S2, fontWeight: 600, letterSpacing: '0.01em', lineHeight: 1.12, whiteSpace: 'nowrap' }}>
367
+ {/* 马克块:自左横扫铺满(垫在字下) */}
368
+ <span aria-hidden style={{
369
+ position: 'absolute', left: '-0.14em', right: '-0.14em', top: '0.1em', bottom: '0.04em', background: LIME, borderRadius: 8,
370
+ transformOrigin: 'left center', transform: `scaleX(${marker.toFixed(4)})`, boxShadow: marker > 0.02 ? `0 0 60px ${alpha(LIME, 0.28)}` : undefined,
371
+ }} />
372
+ {/* 两层字:块的前沿左边是墨色、右边是白色——扫过即反白 */}
373
+ <span style={{ position: 'relative', display: 'inline-block', clipPath: `inset(-20% 0 -20% ${clipL}%)`, color: INK }}>{line2(INK)}</span>
374
+ <span aria-hidden style={{ position: 'absolute', left: 0, top: 0, display: 'inline-block', clipPath: `inset(-20% ${clipR}% -20% 0)` }}>{line2(L.onAccent)}</span>
375
+ </div>
376
+ <div style={{
377
+ marginTop: 40, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 16, whiteSpace: 'pre',
378
+ opacity: kickerIn, transform: `translateY(${((1 - kickerIn) * 12).toFixed(2)}px)`,
379
+ }}>
380
+ <ShotcraftMark size={44} tone="dark" />
381
+ <span style={{ fontFamily: BRAND.font, fontSize: 30, fontWeight: 700, letterSpacing: '0.03em', color: INK, lineHeight: 1 }}>{BRAND.name}</span>
382
+ <span style={{ fontFamily: MONO, fontSize: 26, fontWeight: 600, color: DIM, lineHeight: 1 }}>·</span>
383
+ <span style={{ fontFamily: MONO, fontSize: 26, fontWeight: 600, letterSpacing: '0.2em', marginRight: '-0.2em', color: DIM, lineHeight: 1 }}>{KICKER}</span>
384
+ </div>
385
+ </div>
386
+ </AbsoluteFill>
387
+ </AbsoluteFill>
388
+ );
389
+ };