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,217 +1,217 @@
1
- // neon-triple-marquee —— 三行对向霓虹跑马灯 recap(clickup-30 61–64.5s 的手法)
2
- //
3
- // 第二轮重设计(夜里的灯牌墙 · 斜拍 + 湿地面反光):
4
- // - look = custom「neon」:蓝黑砖墙 + 三色灯管(冰青 / 洋红 / 钠灯琥珀)。不再是平铺的彩色描边字,
5
- // 而是一面真实的霓虹灯牌墙:机位斜拍(墙面 rotateY −17°→−9° 极缓摇近,透视让词流有纵深),
6
- // 墙下是一条湿地面,亮着的那行在地上投出倒影与色光池。
7
- // - 灯管三层:暗态玻璃管(同色、低亮、常亮——三行结构永远在)→ 通电彩色管体 + 双层辉光 → 近白热芯;
8
- // 亮行的光同时溢到身后砖墙上(砖缝被照出来),这是"灯在墙上"而不是"字在屏上"。
9
- // - 字体换成粗体窄体(Avenir Next Condensed Heavy),三连词 FRAME / CRAFT / SHIP(video-shotcraft 的
10
- // "取景 → 刻镜头 → 交片",取自品牌短句 Frame motion. Craft the shot.,recap 用);
11
- // 词距按 canvas 实测宽度排,分隔用空心菱形 ◇。
12
- // - 轮唱:周期 42f、相位差 14f,一亮俩暗;每次点亮先打 2 帧点火闪烁(真霓虹的启辉),再余弦软包络。
13
- // 开场三行按 0/5/10f 依次点火闪烁上电;尾段 124f 起自上而下逐行"断电"(闪两下熄灭),
14
- // 落到只剩暗态玻璃管的熄灯海报(墙仍可见),不淡到死黑。
15
- //
16
- // 时间表(30fps,共 150f):
17
- // 0–18 上电:三行依次点火闪烁(0/5/10f 起),暗态玻璃管亮起
18
- // 18–124 轮唱:42f 周期、14f 相位差,奇偶行反向匀速滚动(marquee 豁免 linear)
19
- // 124–142 断电:自上而下每行错峰 6f 闪两下熄灭
20
- // 142–150 熄灯 hold:暗态灯管 + 墙面余光
21
- import React from 'react';
22
- import { AbsoluteFill, useCurrentFrame } from 'remotion';
23
- import { EASE, Grain, Vignette, ramp, mix } from '../../_fixtures/Polish';
24
- import { alpha } from '../../_fixtures/Look';
25
-
26
- export const NEON_TRIPLE_MARQUEE_DURATION = 150;
27
-
28
- const FONT = '"Avenir Next Condensed", "DIN Condensed", "Arial Narrow", Impact, sans-serif';
29
- const WEIGHT = 800;
30
- const SIZE = 286;
31
- const GAP = SIZE * 0.36;
32
- const PLANE_W = 2900; // 墙面宽(透视斜拍时两侧不露边)
33
- const FLOOR_Y = 900; // 墙脚 / 地面线(墙面坐标)
34
- const ROW_Y = [28, 318, 608];
35
-
36
- const WALL = '#0a0b14';
37
- // 砖墙纹理:两行错缝砖(SVG 小图平铺),砖缝极淡——被灯光照到才看得见
38
- const BRICK = `url("data:image/svg+xml;utf8,${encodeURIComponent(
39
- "<svg xmlns='http://www.w3.org/2000/svg' width='300' height='120'>" +
40
- "<rect width='300' height='120' fill='none'/>" +
41
- "<g stroke='rgba(255,255,255,0.04)' stroke-width='3'>" +
42
- "<line x1='0' y1='1.5' x2='300' y2='1.5'/><line x1='0' y1='61.5' x2='300' y2='61.5'/>" +
43
- "<line x1='1.5' y1='0' x2='1.5' y2='60'/><line x1='151.5' y1='0' x2='151.5' y2='60'/>" +
44
- "<line x1='76.5' y1='60' x2='76.5' y2='120'/><line x1='226.5' y1='60' x2='226.5' y2='120'/></g></svg>",
45
- )}")`;
46
-
47
- // 实测文本宽度(同字体同字号,确定性);无 DOM 时退回估宽
48
- const widthCache = new Map<string, number>();
49
- const measure = (text: string) => {
50
- const hit = widthCache.get(text);
51
- if (hit !== undefined) return hit;
52
- let w = text.length * SIZE * 0.6;
53
- if (typeof document !== 'undefined') {
54
- const ctx = document.createElement('canvas').getContext('2d');
55
- if (ctx) {
56
- ctx.font = `${WEIGHT} ${SIZE}px ${FONT}`;
57
- w = ctx.measureText(text).width + text.length * SIZE * 0.02; // letterSpacing 0.02em
58
- }
59
- }
60
- widthCache.set(text, w);
61
- return w;
62
- };
63
-
64
- type Row = { word: string; color: string; core: string; dir: 1 | -1; speed: number };
65
- const ROWS: Row[] = [
66
- { word: 'FRAME', color: '#38d9ff', core: '#e9fbff', dir: 1, speed: 9 },
67
- { word: 'CRAFT', color: '#ff3d9a', core: '#ffe6f3', dir: -1, speed: 11 },
68
- { word: 'SHIP', color: '#ffae34', core: '#fff3dc', dir: 1, speed: 9 },
69
- ];
70
-
71
- // 点火闪烁序列(确定性):0/1 门,6 帧后恒 1
72
- const IGNITE = [0, 1, 0.15, 0, 0.9, 0.6];
73
- const ignite = (f: number, at: number) => {
74
- const k = Math.floor(f - at);
75
- if (k < 0) return 0;
76
- return k < IGNITE.length ? IGNITE[k] : 1;
77
- };
78
- // 断电序列:闪两下熄灭
79
- const KILL = [1, 0.2, 0.85, 0.1, 0.5, 0];
80
- const kill = (f: number, at: number) => {
81
- const k = Math.floor(f - at);
82
- if (k < 0) return 1;
83
- return k < KILL.length ? KILL[k] : 0;
84
- };
85
-
86
- const PERIOD = 42;
87
- const SLOT = PERIOD / 3; // 每行 14f
88
- // 轮唱亮度:每行在自己的 14f 槽里点亮——前 2 帧启辉闪烁、3f 升满、平台、最后 4f ease-in 熄灭并与下一行
89
- // 重叠 2f 交接(任意时刻总有一行在亮,"一亮俩暗"不出现全暗空拍)
90
- const pulse = (f: number, i: number) => {
91
- if (f < 18) return 0;
92
- const ph = ((((f - 18) - i * SLOT) % PERIOD) + PERIOD) % PERIOD;
93
- const len = SLOT + 2;
94
- if (ph >= len) return 0;
95
- const fl = ph < 1 ? 0.6 : ph < 2 ? 0.25 : 1; // 启辉
96
- const up = ramp(ph, 1, 3, EASE.out);
97
- const down = 1 - ramp(ph, len - 5, 5, EASE.exit);
98
- return Math.max(up * down, 0) * fl;
99
- };
100
-
101
- const MarqueeRow: React.FC<{ row: Row; f: number; y: number; lit: number; glass: number; cheap?: boolean }> = ({ row, f, y, lit, glass, cheap }) => {
102
- const wordW = measure(row.word);
103
- const dotW = SIZE * 0.42;
104
- const unitW = wordW + GAP + dotW + GAP;
105
- const copies = Math.ceil(PLANE_W / unitW) + 3;
106
- const raw = (f * row.speed) % unitW;
107
- const offset = row.dir === 1 ? -unitW * 1.5 + raw : -unitW * 0.5 - raw;
108
- const base: React.CSSProperties = {
109
- position: 'absolute', top: y, left: 0, width: PLANE_W, height: SIZE * 1.05,
110
- transform: `translateX(${offset.toFixed(2)}px)`,
111
- fontFamily: FONT, fontWeight: WEIGHT, fontSize: SIZE, letterSpacing: '0.02em', lineHeight: 1, color: 'transparent',
112
- };
113
- // 分隔:空心菱形(边框色 / 粗细与同层灯管一致,字本身只描边不填色)
114
- const text = (sep: string, bw: number) => Array.from({ length: copies }).map((_, i) => (
115
- <span key={i} style={{ position: 'absolute', left: i * unitW, top: 0, whiteSpace: 'nowrap' }}>
116
- {row.word}
117
- <span style={{
118
- position: 'absolute', left: wordW + GAP + dotW * 0.2, top: SIZE * 0.34, width: dotW * 0.6, height: dotW * 0.6,
119
- transform: 'rotate(45deg)', boxSizing: 'border-box', border: `${bw.toFixed(2)}px solid ${sep}`, borderRadius: 6,
120
- }} />
121
- </span>
122
- ));
123
- const tube = 6 + lit * 4;
124
- const core = 2 + lit * 1.8;
125
- return (
126
- <>
127
- {/* 暗态玻璃管:同色低亮,三行结构永远在 */}
128
- <div style={{ ...base, WebkitTextStroke: `6px ${alpha(row.color, 0.3 * glass)}` }}>{text(alpha(row.color, 0.3 * glass), 6)}</div>
129
- {lit > 0.02 && (
130
- <>
131
- {/* 通电管体 + 双层辉光 */}
132
- <div style={{
133
- ...base, WebkitTextStroke: `${tube.toFixed(2)}px ${row.color}`, opacity: Math.min(1, lit * 1.1),
134
- filter: cheap ? undefined : `drop-shadow(0 0 ${(3 + lit * 6).toFixed(1)}px ${row.color}) drop-shadow(0 0 ${(14 + lit * 22).toFixed(1)}px ${row.color}) drop-shadow(0 0 ${(40 + lit * 50).toFixed(1)}px ${alpha(row.color, 0.9)})`,
135
- }}>{text(row.color, tube)}</div>
136
- {/* 热芯:近白细线,只在通电时亮——"霓虹"而不是"彩色描边"的关键 */}
137
- <div style={{ ...base, WebkitTextStroke: `${core.toFixed(2)}px ${row.core}`, opacity: Math.min(1, lit * 1.3), filter: cheap ? undefined : `drop-shadow(0 0 2px ${alpha(row.core, 0.9)})` }}>
138
- {text(row.core, core)}
139
- </div>
140
- </>
141
- )}
142
- </>
143
- );
144
- };
145
-
146
- export const NeonTripleMarquee: React.FC = () => {
147
- const f = useCurrentFrame();
148
-
149
- // 每行供电:上电点火 × 断电
150
- const power = ROWS.map((_, i) => ignite(f, i * 5) * kill(f, 124 + i * 6));
151
- // 暗态玻璃:上电后常亮,断电后仍留 0.6(熄灯海报:灯管看得见)
152
- const glass = ROWS.map((_, i) => Math.max(ignite(f, i * 5), f >= 124 ? 1 : 0) * (1 - 0.25 * ramp(f, 124 + i * 6 + 4, 8, EASE.out)));
153
- // 亮度:开场上电时全行点火亮一下(0.7)→ 轮唱
154
- const lit = ROWS.map((_, i) => {
155
- const boot = f < 18 ? 0.7 * ignite(f, i * 5) * (1 - ramp(f, 12, 6, EASE.out)) : 0;
156
- const killFlash = f >= 124 ? 0.55 * kill(f, 124 + i * 6) * (f < 124 + i * 6 ? 0 : 1) : 0;
157
- return Math.max(boot, pulse(f, i) * power[i], killFlash);
158
- });
159
-
160
- // 机位:墙面斜拍,rotateY −17° → −9° 极缓摇近(smooth),整体轻推
161
- const cam = ramp(f, 0, 150, EASE.smooth);
162
- const rotY = mix(-17, -9, cam);
163
- const scale = mix(1.0, 1.05, cam);
164
-
165
- return (
166
- <AbsoluteFill style={{ background: '#05050a', overflow: 'hidden' }}>
167
- <div style={{ position: 'absolute', inset: 0, perspective: 1700, perspectiveOrigin: '50% 45%' }}>
168
- <div style={{
169
- position: 'absolute', left: (1920 - PLANE_W) / 2, top: 40, width: PLANE_W, height: 1200,
170
- transform: `rotateY(${rotY.toFixed(3)}deg) scale(${scale.toFixed(4)})`, transformOrigin: '50% 40%',
171
- }}>
172
- {/* 砖墙:底色 + 极淡砖缝(被灯光照到才看得见) */}
173
- <div style={{
174
- position: 'absolute', left: 0, top: -40, width: PLANE_W, height: FLOOR_Y + 40, background: WALL,
175
- backgroundImage: BRICK, backgroundSize: '300px 120px',
176
- }} />
177
- {/* 墙面溢光:每行身后一条同色柔光带,随亮度呼吸(screen 叠在砖墙上) */}
178
- {ROWS.map((r, i) => (
179
- <div key={`spill${i}`} style={{
180
- position: 'absolute', left: 0, right: 0, top: ROW_Y[i] - 200, height: SIZE + 400, mixBlendMode: 'screen',
181
- background: `radial-gradient(ellipse 50% 44% at 50% 50%, ${alpha(r.color, 0.6)} 0%, ${alpha(r.color, 0.12)} 45%, ${alpha(r.color, 0)} 72%)`,
182
- opacity: 0.05 * glass[i] + lit[i] * 0.55,
183
- }} />
184
- ))}
185
- {ROWS.map((r, i) => (
186
- <MarqueeRow key={r.word} row={r} f={f} y={ROW_Y[i]} lit={lit[i]} glass={glass[i]} />
187
- ))}
188
- {/* 湿地面:墙脚以下一条深色反光面,倒影只取最下一行(翻转、虚化、渐隐) */}
189
- <div style={{ position: 'absolute', left: 0, top: FLOOR_Y, width: PLANE_W, height: 300, background: 'linear-gradient(180deg, #08080e 0%, #040407 100%)' }} />
190
- <div style={{
191
- position: 'absolute', left: 0, top: FLOOR_Y, width: PLANE_W, height: 300, overflow: 'hidden',
192
- WebkitMaskImage: 'linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 70%)',
193
- maskImage: 'linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 70%)',
194
- filter: 'blur(3px)',
195
- }}>
196
- {/* 镜像:墙面 y_w 处的点映到地面下 (FLOOR_Y − y_w);内层 600 高、绕自身中心翻转 → 行放在 y_w − 300 */}
197
- <div style={{ position: 'absolute', left: 0, top: 0, width: PLANE_W, height: 600, transform: 'scaleY(-1)', transformOrigin: '50% 50%' }}>
198
- <MarqueeRow row={ROWS[2]} f={f} y={ROW_Y[2] - 300} lit={lit[2]} glass={glass[2]} cheap />
199
- </div>
200
- </div>
201
- {/* 地面色光池:每行的光落在地上(远行更弱) */}
202
- {ROWS.map((r, i) => (
203
- <div key={`pool${i}`} style={{
204
- position: 'absolute', left: 0, right: 0, top: FLOOR_Y - 40, height: 220, mixBlendMode: 'screen',
205
- background: `radial-gradient(ellipse 46% 40% at 50% 30%, ${alpha(r.color, 0.55)} 0%, ${alpha(r.color, 0)} 70%)`,
206
- opacity: lit[i] * [0.18, 0.28, 0.5][i],
207
- }} />
208
- ))}
209
- {/* 墙脚接缝:一条发丝高光,把墙和地分开 */}
210
- <div style={{ position: 'absolute', left: 0, top: FLOOR_Y, width: PLANE_W, height: 2, background: 'rgba(255,255,255,0.06)' }} />
211
- </div>
212
- </div>
213
- <Vignette strength={0.62} inner={0.36} color="#020205" />
214
- <Grain opacity={0.08} blend="soft-light" />
215
- </AbsoluteFill>
216
- );
217
- };
1
+ // neon-triple-marquee —— 三行对向霓虹跑马灯 recap(clickup-30 61–64.5s 的手法)
2
+ //
3
+ // 第二轮重设计(夜里的灯牌墙 · 斜拍 + 湿地面反光):
4
+ // - look = custom「neon」:蓝黑砖墙 + 三色灯管(冰青 / 洋红 / 钠灯琥珀)。不再是平铺的彩色描边字,
5
+ // 而是一面真实的霓虹灯牌墙:机位斜拍(墙面 rotateY −17°→−9° 极缓摇近,透视让词流有纵深),
6
+ // 墙下是一条湿地面,亮着的那行在地上投出倒影与色光池。
7
+ // - 灯管三层:暗态玻璃管(同色、低亮、常亮——三行结构永远在)→ 通电彩色管体 + 双层辉光 → 近白热芯;
8
+ // 亮行的光同时溢到身后砖墙上(砖缝被照出来),这是"灯在墙上"而不是"字在屏上"。
9
+ // - 字体换成粗体窄体(Avenir Next Condensed Heavy),三连词 FRAME / CRAFT / SHIP(video-shotcraft 的
10
+ // "取景 → 刻镜头 → 交片",取自品牌短句 Frame motion. Craft the shot.,recap 用);
11
+ // 词距按 canvas 实测宽度排,分隔用空心菱形 ◇。
12
+ // - 轮唱:周期 42f、相位差 14f,一亮俩暗;每次点亮先打 2 帧点火闪烁(真霓虹的启辉),再余弦软包络。
13
+ // 开场三行按 0/5/10f 依次点火闪烁上电;尾段 124f 起自上而下逐行"断电"(闪两下熄灭),
14
+ // 落到只剩暗态玻璃管的熄灯海报(墙仍可见),不淡到死黑。
15
+ //
16
+ // 时间表(30fps,共 150f):
17
+ // 0–18 上电:三行依次点火闪烁(0/5/10f 起),暗态玻璃管亮起
18
+ // 18–124 轮唱:42f 周期、14f 相位差,奇偶行反向匀速滚动(marquee 豁免 linear)
19
+ // 124–142 断电:自上而下每行错峰 6f 闪两下熄灭
20
+ // 142–150 熄灯 hold:暗态灯管 + 墙面余光
21
+ import React from 'react';
22
+ import { AbsoluteFill, useCurrentFrame } from 'remotion';
23
+ import { EASE, Grain, Vignette, ramp, mix } from '../../_fixtures/Polish';
24
+ import { alpha } from '../../_fixtures/Look';
25
+
26
+ export const NEON_TRIPLE_MARQUEE_DURATION = 150;
27
+
28
+ const FONT = '"Avenir Next Condensed", "DIN Condensed", "Arial Narrow", Impact, sans-serif';
29
+ const WEIGHT = 800;
30
+ const SIZE = 286;
31
+ const GAP = SIZE * 0.36;
32
+ const PLANE_W = 2900; // 墙面宽(透视斜拍时两侧不露边)
33
+ const FLOOR_Y = 900; // 墙脚 / 地面线(墙面坐标)
34
+ const ROW_Y = [28, 318, 608];
35
+
36
+ const WALL = '#0a0b14';
37
+ // 砖墙纹理:两行错缝砖(SVG 小图平铺),砖缝极淡——被灯光照到才看得见
38
+ const BRICK = `url("data:image/svg+xml;utf8,${encodeURIComponent(
39
+ "<svg xmlns='http://www.w3.org/2000/svg' width='300' height='120'>" +
40
+ "<rect width='300' height='120' fill='none'/>" +
41
+ "<g stroke='rgba(255,255,255,0.04)' stroke-width='3'>" +
42
+ "<line x1='0' y1='1.5' x2='300' y2='1.5'/><line x1='0' y1='61.5' x2='300' y2='61.5'/>" +
43
+ "<line x1='1.5' y1='0' x2='1.5' y2='60'/><line x1='151.5' y1='0' x2='151.5' y2='60'/>" +
44
+ "<line x1='76.5' y1='60' x2='76.5' y2='120'/><line x1='226.5' y1='60' x2='226.5' y2='120'/></g></svg>",
45
+ )}")`;
46
+
47
+ // 实测文本宽度(同字体同字号,确定性);无 DOM 时退回估宽
48
+ const widthCache = new Map<string, number>();
49
+ const measure = (text: string) => {
50
+ const hit = widthCache.get(text);
51
+ if (hit !== undefined) return hit;
52
+ let w = text.length * SIZE * 0.6;
53
+ if (typeof document !== 'undefined') {
54
+ const ctx = document.createElement('canvas').getContext('2d');
55
+ if (ctx) {
56
+ ctx.font = `${WEIGHT} ${SIZE}px ${FONT}`;
57
+ w = ctx.measureText(text).width + text.length * SIZE * 0.02; // letterSpacing 0.02em
58
+ }
59
+ }
60
+ widthCache.set(text, w);
61
+ return w;
62
+ };
63
+
64
+ type Row = { word: string; color: string; core: string; dir: 1 | -1; speed: number };
65
+ const ROWS: Row[] = [
66
+ { word: 'FRAME', color: '#38d9ff', core: '#e9fbff', dir: 1, speed: 9 },
67
+ { word: 'CRAFT', color: '#ff3d9a', core: '#ffe6f3', dir: -1, speed: 11 },
68
+ { word: 'SHIP', color: '#ffae34', core: '#fff3dc', dir: 1, speed: 9 },
69
+ ];
70
+
71
+ // 点火闪烁序列(确定性):0/1 门,6 帧后恒 1
72
+ const IGNITE = [0, 1, 0.15, 0, 0.9, 0.6];
73
+ const ignite = (f: number, at: number) => {
74
+ const k = Math.floor(f - at);
75
+ if (k < 0) return 0;
76
+ return k < IGNITE.length ? IGNITE[k] : 1;
77
+ };
78
+ // 断电序列:闪两下熄灭
79
+ const KILL = [1, 0.2, 0.85, 0.1, 0.5, 0];
80
+ const kill = (f: number, at: number) => {
81
+ const k = Math.floor(f - at);
82
+ if (k < 0) return 1;
83
+ return k < KILL.length ? KILL[k] : 0;
84
+ };
85
+
86
+ const PERIOD = 42;
87
+ const SLOT = PERIOD / 3; // 每行 14f
88
+ // 轮唱亮度:每行在自己的 14f 槽里点亮——前 2 帧启辉闪烁、3f 升满、平台、最后 4f ease-in 熄灭并与下一行
89
+ // 重叠 2f 交接(任意时刻总有一行在亮,"一亮俩暗"不出现全暗空拍)
90
+ const pulse = (f: number, i: number) => {
91
+ if (f < 18) return 0;
92
+ const ph = ((((f - 18) - i * SLOT) % PERIOD) + PERIOD) % PERIOD;
93
+ const len = SLOT + 2;
94
+ if (ph >= len) return 0;
95
+ const fl = ph < 1 ? 0.6 : ph < 2 ? 0.25 : 1; // 启辉
96
+ const up = ramp(ph, 1, 3, EASE.out);
97
+ const down = 1 - ramp(ph, len - 5, 5, EASE.exit);
98
+ return Math.max(up * down, 0) * fl;
99
+ };
100
+
101
+ const MarqueeRow: React.FC<{ row: Row; f: number; y: number; lit: number; glass: number; cheap?: boolean }> = ({ row, f, y, lit, glass, cheap }) => {
102
+ const wordW = measure(row.word);
103
+ const dotW = SIZE * 0.42;
104
+ const unitW = wordW + GAP + dotW + GAP;
105
+ const copies = Math.ceil(PLANE_W / unitW) + 3;
106
+ const raw = (f * row.speed) % unitW;
107
+ const offset = row.dir === 1 ? -unitW * 1.5 + raw : -unitW * 0.5 - raw;
108
+ const base: React.CSSProperties = {
109
+ position: 'absolute', top: y, left: 0, width: PLANE_W, height: SIZE * 1.05,
110
+ transform: `translateX(${offset.toFixed(2)}px)`,
111
+ fontFamily: FONT, fontWeight: WEIGHT, fontSize: SIZE, letterSpacing: '0.02em', lineHeight: 1, color: 'transparent',
112
+ };
113
+ // 分隔:空心菱形(边框色 / 粗细与同层灯管一致,字本身只描边不填色)
114
+ const text = (sep: string, bw: number) => Array.from({ length: copies }).map((_, i) => (
115
+ <span key={i} style={{ position: 'absolute', left: i * unitW, top: 0, whiteSpace: 'nowrap' }}>
116
+ {row.word}
117
+ <span style={{
118
+ position: 'absolute', left: wordW + GAP + dotW * 0.2, top: SIZE * 0.34, width: dotW * 0.6, height: dotW * 0.6,
119
+ transform: 'rotate(45deg)', boxSizing: 'border-box', border: `${bw.toFixed(2)}px solid ${sep}`, borderRadius: 6,
120
+ }} />
121
+ </span>
122
+ ));
123
+ const tube = 6 + lit * 4;
124
+ const core = 2 + lit * 1.8;
125
+ return (
126
+ <>
127
+ {/* 暗态玻璃管:同色低亮,三行结构永远在 */}
128
+ <div style={{ ...base, WebkitTextStroke: `6px ${alpha(row.color, 0.3 * glass)}` }}>{text(alpha(row.color, 0.3 * glass), 6)}</div>
129
+ {lit > 0.02 && (
130
+ <>
131
+ {/* 通电管体 + 双层辉光 */}
132
+ <div style={{
133
+ ...base, WebkitTextStroke: `${tube.toFixed(2)}px ${row.color}`, opacity: Math.min(1, lit * 1.1),
134
+ filter: cheap ? undefined : `drop-shadow(0 0 ${(3 + lit * 6).toFixed(1)}px ${row.color}) drop-shadow(0 0 ${(14 + lit * 22).toFixed(1)}px ${row.color}) drop-shadow(0 0 ${(40 + lit * 50).toFixed(1)}px ${alpha(row.color, 0.9)})`,
135
+ }}>{text(row.color, tube)}</div>
136
+ {/* 热芯:近白细线,只在通电时亮——"霓虹"而不是"彩色描边"的关键 */}
137
+ <div style={{ ...base, WebkitTextStroke: `${core.toFixed(2)}px ${row.core}`, opacity: Math.min(1, lit * 1.3), filter: cheap ? undefined : `drop-shadow(0 0 2px ${alpha(row.core, 0.9)})` }}>
138
+ {text(row.core, core)}
139
+ </div>
140
+ </>
141
+ )}
142
+ </>
143
+ );
144
+ };
145
+
146
+ export const NeonTripleMarquee: React.FC = () => {
147
+ const f = useCurrentFrame();
148
+
149
+ // 每行供电:上电点火 × 断电
150
+ const power = ROWS.map((_, i) => ignite(f, i * 5) * kill(f, 124 + i * 6));
151
+ // 暗态玻璃:上电后常亮,断电后仍留 0.6(熄灯海报:灯管看得见)
152
+ const glass = ROWS.map((_, i) => Math.max(ignite(f, i * 5), f >= 124 ? 1 : 0) * (1 - 0.25 * ramp(f, 124 + i * 6 + 4, 8, EASE.out)));
153
+ // 亮度:开场上电时全行点火亮一下(0.7)→ 轮唱
154
+ const lit = ROWS.map((_, i) => {
155
+ const boot = f < 18 ? 0.7 * ignite(f, i * 5) * (1 - ramp(f, 12, 6, EASE.out)) : 0;
156
+ const killFlash = f >= 124 ? 0.55 * kill(f, 124 + i * 6) * (f < 124 + i * 6 ? 0 : 1) : 0;
157
+ return Math.max(boot, pulse(f, i) * power[i], killFlash);
158
+ });
159
+
160
+ // 机位:墙面斜拍,rotateY −17° → −9° 极缓摇近(smooth),整体轻推
161
+ const cam = ramp(f, 0, 150, EASE.smooth);
162
+ const rotY = mix(-17, -9, cam);
163
+ const scale = mix(1.0, 1.05, cam);
164
+
165
+ return (
166
+ <AbsoluteFill style={{ background: '#05050a', overflow: 'hidden' }}>
167
+ <div style={{ position: 'absolute', inset: 0, perspective: 1700, perspectiveOrigin: '50% 45%' }}>
168
+ <div style={{
169
+ position: 'absolute', left: (1920 - PLANE_W) / 2, top: 40, width: PLANE_W, height: 1200,
170
+ transform: `rotateY(${rotY.toFixed(3)}deg) scale(${scale.toFixed(4)})`, transformOrigin: '50% 40%',
171
+ }}>
172
+ {/* 砖墙:底色 + 极淡砖缝(被灯光照到才看得见) */}
173
+ <div style={{
174
+ position: 'absolute', left: 0, top: -40, width: PLANE_W, height: FLOOR_Y + 40, background: WALL,
175
+ backgroundImage: BRICK, backgroundSize: '300px 120px',
176
+ }} />
177
+ {/* 墙面溢光:每行身后一条同色柔光带,随亮度呼吸(screen 叠在砖墙上) */}
178
+ {ROWS.map((r, i) => (
179
+ <div key={`spill${i}`} style={{
180
+ position: 'absolute', left: 0, right: 0, top: ROW_Y[i] - 200, height: SIZE + 400, mixBlendMode: 'screen',
181
+ background: `radial-gradient(ellipse 50% 44% at 50% 50%, ${alpha(r.color, 0.6)} 0%, ${alpha(r.color, 0.12)} 45%, ${alpha(r.color, 0)} 72%)`,
182
+ opacity: 0.05 * glass[i] + lit[i] * 0.55,
183
+ }} />
184
+ ))}
185
+ {ROWS.map((r, i) => (
186
+ <MarqueeRow key={r.word} row={r} f={f} y={ROW_Y[i]} lit={lit[i]} glass={glass[i]} />
187
+ ))}
188
+ {/* 湿地面:墙脚以下一条深色反光面,倒影只取最下一行(翻转、虚化、渐隐) */}
189
+ <div style={{ position: 'absolute', left: 0, top: FLOOR_Y, width: PLANE_W, height: 300, background: 'linear-gradient(180deg, #08080e 0%, #040407 100%)' }} />
190
+ <div style={{
191
+ position: 'absolute', left: 0, top: FLOOR_Y, width: PLANE_W, height: 300, overflow: 'hidden',
192
+ WebkitMaskImage: 'linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 70%)',
193
+ maskImage: 'linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 70%)',
194
+ filter: 'blur(3px)',
195
+ }}>
196
+ {/* 镜像:墙面 y_w 处的点映到地面下 (FLOOR_Y − y_w);内层 600 高、绕自身中心翻转 → 行放在 y_w − 300 */}
197
+ <div style={{ position: 'absolute', left: 0, top: 0, width: PLANE_W, height: 600, transform: 'scaleY(-1)', transformOrigin: '50% 50%' }}>
198
+ <MarqueeRow row={ROWS[2]} f={f} y={ROW_Y[2] - 300} lit={lit[2]} glass={glass[2]} cheap />
199
+ </div>
200
+ </div>
201
+ {/* 地面色光池:每行的光落在地上(远行更弱) */}
202
+ {ROWS.map((r, i) => (
203
+ <div key={`pool${i}`} style={{
204
+ position: 'absolute', left: 0, right: 0, top: FLOOR_Y - 40, height: 220, mixBlendMode: 'screen',
205
+ background: `radial-gradient(ellipse 46% 40% at 50% 30%, ${alpha(r.color, 0.55)} 0%, ${alpha(r.color, 0)} 70%)`,
206
+ opacity: lit[i] * [0.18, 0.28, 0.5][i],
207
+ }} />
208
+ ))}
209
+ {/* 墙脚接缝:一条发丝高光,把墙和地分开 */}
210
+ <div style={{ position: 'absolute', left: 0, top: FLOOR_Y, width: PLANE_W, height: 2, background: 'rgba(255,255,255,0.06)' }} />
211
+ </div>
212
+ </div>
213
+ <Vignette strength={0.62} inner={0.36} color="#020205" />
214
+ <Grain opacity={0.08} blend="soft-light" />
215
+ </AbsoluteFill>
216
+ );
217
+ };