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,329 +1,329 @@
1
- // scanline-annotate-focus — 扫描分析取景标注:一条扫描线自上而下匀速掠过一张已存在的品牌官网,
2
- // 扫过哪个区块的下缘,哪块就被一组取景角标"收拢对准",随后贴一枚机器标签把它命名;顶部状态行实时计数。
3
- //
4
- // 第二轮重设计(暖沙官网 × 钴蓝机器视线):
5
- // - look = sand(米色 · 赤陶)。被分析的是 video-shotcraft 的官网:镜刻标志 + 字标、大号粗黑体 H1「Your product, in motion.」、
6
- // 一支样片(陶器品牌 Tide Vase 的发布片封面,手绘感陶瓶)、赤陶色 CTA、四色色板——页面本身就是一张好看的品牌页。
7
- // - 两套颜色严格分工:赤陶 = 品牌(页面内容),钴蓝 = 机器(扫描线 / 角标 / 标签 / 状态行)。
8
- // 标签照设计工具的选中标签惯例做成钴蓝底白字小签,32px 等宽字,任何底上都读得清。
9
- // - 页面放进一扇有两层软阴影的浏览器窗(1560×840),状态行在窗外上方;全程 1.000→1.035 极缓推镜。
10
- // - 扫描线严格匀速(机器的视线,不加缓动):3px 钴蓝光芯 + 身后 140px 渐隐的"已读"淡蓝余晖与点阵;
11
- // 窗框两侧各一枚随线滑动的游标,左侧读出当前 Y 坐标。
12
- // - 取景框:四个 L 角从外扩 76px 处按弹簧(damping 15,一次可见过冲)收拢到 bbox,臂长晚 3f 收一档(跟随);
13
- // 对准瞬间框内钴蓝对焦闪;标签 5f 后从左擦出、文字逐字打出(机器在写)。
14
- //
15
- // 时间表(30fps,共 150f):
16
- // 0–6 页面已在场(它本来就存在),状态行亮起 READING
17
- // 6–80 扫描线匀速 −20→860(74f);越过 bbox 下缘即触发(≥4f 最小间隔):
18
- // LOGO ~19f · NAV ~23f · H1 ~47f · CTA ~66f · HERO ~70f · PALETTE ~75f
19
- // ft+0–14 角标弹簧收拢;ft+5–14 标签擦出 + 打字
20
- // 80–88 扫描线淡出;状态行切 BRAND READ · 6 SIGNALS(钴蓝)
21
- // 88–150 hold:全部标注就位,极缓推镜让画面活着,尾帧是一张完整海报
22
- import React from 'react';
23
- import { AbsoluteFill, useCurrentFrame } from 'remotion';
24
- import { EASE, FONT, ramp, softShadow } from '../../_fixtures/Polish';
25
- import { LOOKS, Stage, alpha, springAt } from '../../_fixtures/Look';
26
- import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
27
-
28
- export const SCANLINE_ANNOTATE_FOCUS_DURATION = 150;
29
-
30
- const L = LOOKS.sand;
31
- const MACHINE = '#2b4fd8'; // 机器色(钴蓝):扫描线 / 角标 / 标签 / 状态行专用,页面内容不用
32
- const TERRA = L.accent; // 品牌色(赤陶):只在页面内容里出现
33
- const MONO = FONT.mono;
34
-
35
- // 浏览器窗(帧坐标)
36
- const WX = 180;
37
- const WY = 168;
38
- const WW = 1560;
39
- const WH = 840;
40
- const CHROME = 52;
41
-
42
- // 扫描线(页面坐标,窗内 y):严格匀速
43
- const SCAN0 = 6;
44
- const SCAN1 = 80;
45
- const Y0 = -20;
46
- const Y1 = 860;
47
- const scanY = (f: number) => Y0 + (Y1 - Y0) * Math.min(1, Math.max(0, (f - SCAN0) / (SCAN1 - SCAN0)));
48
- const frameAtY = (y: number) => SCAN0 + ((y - Y0) / (Y1 - Y0)) * (SCAN1 - SCAN0);
49
-
50
- // ───────────── 分析目标(页面坐标;tag = 标签相对 bbox 的放置) ─────────────
51
- type Tag = 'right' | 'above' | 'below' | 'belowRight';
52
- type Target = { key: string; x: number; y: number; w: number; h: number; head: string; detail: string; tag: Tag; ft: number };
53
- const TARGETS: Target[] = (() => {
54
- const ts: Target[] = [
55
- { key: 'logo', x: 48, y: 64, w: 344, h: 66, head: 'LOGO', detail: 'Frame Chisel', tag: 'right', ft: 0 },
56
- { key: 'nav', x: 1000, y: 64, w: 512, h: 66, head: 'NAV', detail: '4 items', tag: 'belowRight', ft: 0 },
57
- { key: 'h1', x: 48, y: 222, w: 722, h: 262, head: 'H1', detail: 'Grotesk 850 · −4%', tag: 'above', ft: 0 },
58
- { key: 'cta', x: 48, y: 632, w: 408, h: 88, head: 'CTA', detail: '#C4552D', tag: 'right', ft: 0 },
59
- { key: 'hero', x: 892, y: 216, w: 620, h: 532, head: 'HERO', detail: 'Sample film', tag: 'below', ft: 0 },
60
- { key: 'palette', x: 48, y: 756, w: 220, h: 66, head: 'PALETTE', detail: '4 swatches', tag: 'right', ft: 0 },
61
- ];
62
- // 触发 = 扫描线越过 bbox 下缘的那一帧;按下缘排序后钳制最小间隔 4f(两块同高的不会同帧弹)
63
- let prev = -99;
64
- for (const t of [...ts].sort((a, b) => a.y + a.h - (b.y + b.h))) {
65
- t.ft = Math.max(frameAtY(t.y + t.h), prev + 4);
66
- prev = t.ft;
67
- }
68
- return ts;
69
- })();
70
- const LAST_FIRE = Math.max(...TARGETS.map((t) => t.ft));
71
-
72
- // ───────────── 页面内容:video-shotcraft 官网(产品图位放一支样片封面:陶器品牌的发布片) ─────────────
73
- const Vase: React.FC = () => (
74
- <svg width={620} height={580} viewBox="0 0 620 580" style={{ position: 'absolute', left: 0, top: 0 }}>
75
- <defs>
76
- <linearGradient id="haf-vase" x1="0" x2="1" y1="0" y2="0">
77
- <stop offset="0" stopColor="#7d3418" />
78
- <stop offset="0.3" stopColor="#c45a31" />
79
- <stop offset="0.46" stopColor="#e9925f" />
80
- <stop offset="0.62" stopColor="#c2552c" />
81
- <stop offset="1" stopColor="#6e2c13" />
82
- </linearGradient>
83
- <linearGradient id="haf-bowl" x1="0" x2="1" y1="0" y2="0">
84
- <stop offset="0" stopColor="#a99a83" />
85
- <stop offset="0.4" stopColor="#f3ece1" />
86
- <stop offset="0.7" stopColor="#ddd1bf" />
87
- <stop offset="1" stopColor="#8f8069" />
88
- </linearGradient>
89
- <radialGradient id="haf-shadow" cx="0.5" cy="0.5" r="0.5">
90
- <stop offset="0" stopColor="#5a3a1c" stopOpacity="0.38" />
91
- <stop offset="1" stopColor="#5a3a1c" stopOpacity="0" />
92
- </radialGradient>
93
- <clipPath id="haf-clip"><path d="M228 118 C226 150 214 168 196 196 C150 262 142 336 168 398 C186 444 214 466 268 468 C322 466 350 444 368 398 C394 336 386 262 340 196 C322 168 310 150 308 118 Z" /></clipPath>
94
- <linearGradient id="haf-glaze" x1="0" x2="0" y1="0" y2="1">
95
- <stop offset="0" stopColor="#fff" stopOpacity="0.18" />
96
- <stop offset="0.25" stopColor="#fff" stopOpacity="0" />
97
- </linearGradient>
98
- </defs>
99
- {/* 接触影 */}
100
- <ellipse cx={268} cy={470} rx={150} ry={22} fill="url(#haf-shadow)" />
101
- <ellipse cx={452} cy={478} rx={98} ry={15} fill="url(#haf-shadow)" />
102
- {/* 陶瓶:窄口 · 鼓腹 · 收足 */}
103
- <path
104
- d="M228 118 C226 150 214 168 196 196 C150 262 142 336 168 398 C186 444 214 466 268 468 C322 466 350 444 368 398 C394 336 386 262 340 196 C322 168 310 150 308 118 Z"
105
- fill="url(#haf-vase)"
106
- />
107
- <path
108
- d="M228 118 C226 150 214 168 196 196 C150 262 142 336 168 398 C186 444 214 466 268 468 C322 466 350 444 368 398 C394 336 386 262 340 196 C322 168 310 150 308 118 Z"
109
- fill="url(#haf-glaze)"
110
- />
111
- <ellipse cx={268} cy={118} rx={40} ry={9} fill="#5e260f" />
112
- <ellipse cx={268} cy={116} rx={40} ry={8} fill="none" stroke="#e7a073" strokeWidth={2} opacity={0.7} />
113
- {/* 拉坯留下的轮纹:几道极淡的横向弧线,手作感 */}
114
- <g clipPath="url(#haf-clip)">
115
- {[176, 222, 270, 320, 370, 420].map((y, i) => (
116
- <path key={i} d={`M60 ${y} Q268 ${y + 14} 476 ${y}`} fill="none" stroke="#3e1608" strokeWidth={1.6} opacity={0.09} />
117
- ))}
118
- </g>
119
- {/* 釉面流挂的一道亮痕 */}
120
- <path d="M232 210 C214 262 206 330 222 400" fill="none" stroke="#ffd2b0" strokeWidth={6} strokeLinecap="round" opacity={0.28} />
121
- {/* 骨白小碗 */}
122
- <path d="M362 402 C366 452 404 478 452 478 C500 478 538 452 542 402 Z" fill="url(#haf-bowl)" />
123
- <ellipse cx={452} cy={402} rx={90} ry={14} fill="#efe6d8" />
124
- <ellipse cx={452} cy={404} rx={78} ry={9} fill="#cdbfa9" />
125
- </svg>
126
- );
127
-
128
- const Page: React.FC = () => (
129
- <div style={{ position: 'absolute', inset: 0, background: '#f8f2e9', fontFamily: FONT.sans, color: L.ink }}>
130
- {/* 浏览器顶栏 */}
131
- <div style={{ position: 'absolute', left: 0, top: 0, width: WW, height: CHROME, background: '#efe7db', borderBottom: `1px solid ${L.line}` }}>
132
- {[0, 1, 2].map((i) => (
133
- <div key={i} style={{ position: 'absolute', left: 24 + i * 22, top: 20, width: 12, height: 12, borderRadius: 6, background: alpha(L.ink, 0.16) }} />
134
- ))}
135
- <div style={{ position: 'absolute', left: WW / 2 - 260, top: 11, width: 520, height: 30, borderRadius: 8, background: alpha('#ffffff', 0.7), border: `1px solid ${L.line}`, font: `500 18px ${MONO}`, color: L.ink3, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
136
- {BRAND.repo}
137
- </div>
138
- </div>
139
- {/* logo:镜刻标志 + video-shotcraft 字标(标志 svg 四周有 16/128 留白,左移 7px 让可见框对齐 64) */}
140
- <div style={{ position: 'absolute', left: 57, top: 70, display: 'flex', alignItems: 'center', gap: 12 }}>
141
- <ShotcraftMark size={56} tone="light" />
142
- <div style={{ font: `700 34px ${BRAND.font}`, letterSpacing: '0.01em', color: BRAND.ink, whiteSpace: 'nowrap' }}>{BRAND.name}</div>
143
- </div>
144
- {/* 导航 */}
145
- <div style={{ position: 'absolute', right: 64, top: 84, display: 'flex', gap: 46, font: `550 28px ${FONT.sans}`, color: L.ink2, letterSpacing: '-0.01em' }}>
146
- <span>Recipes</span>
147
- <span>Gallery</span>
148
- <span>Docs</span>
149
- <span style={{ color: L.ink }}>GitHub</span>
150
- </div>
151
- {/* H1 */}
152
- <div style={{ position: 'absolute', left: 60, top: 236, font: `850 120px ${FONT.sans}`, letterSpacing: '-0.045em', lineHeight: 1, whiteSpace: 'nowrap' }}>
153
- Your product,
154
- <br />
155
- in <span style={{ color: TERRA }}>motion.</span>
156
- </div>
157
- {/* 正文 */}
158
- <div style={{ position: 'absolute', left: 64, top: 512, width: 700, font: `450 34px ${FONT.sans}`, lineHeight: 1.36, color: L.ink2, letterSpacing: '-0.012em' }}>
159
- Cinematic product videos, crafted by your agent. From screenshot to showreel.
160
- </div>
161
- {/* CTA */}
162
- <div style={{ position: 'absolute', left: 64, top: 644, height: 64, padding: '0 34px', borderRadius: 32, background: TERRA, color: L.onAccent, display: 'flex', alignItems: 'center', gap: 14, font: `650 30px ${FONT.sans}`, letterSpacing: '-0.01em', boxShadow: `0 10px 24px -10px ${alpha('#7a2a10', 0.55)}, inset 0 1px 0 rgba(255,255,255,0.25)` }}>
163
- Render a launch film <span style={{ fontWeight: 500 }}>→</span>
164
- </div>
165
- {/* 釉色板 */}
166
- <div style={{ position: 'absolute', left: 64, top: 768, display: 'flex', alignItems: 'center', gap: 12 }}>
167
- {['#ebe5da', '#5d6c4f', TERRA, '#d6c3a5'].map((c, i) => (
168
- <div key={i} style={{ width: 42, height: 42, borderRadius: 21, background: `radial-gradient(circle at 35% 30%, ${alpha('#ffffff', 0.45)}, ${alpha('#ffffff', 0)} 55%), ${c}`, boxShadow: `inset 0 0 0 1px ${alpha(L.ink, 0.12)}` }} />
169
- ))}
170
- </div>
171
- {/* 产品图卡 */}
172
- <div style={{ position: 'absolute', left: 900, top: 224, width: 604, height: 516, borderRadius: 22, overflow: 'hidden', background: 'linear-gradient(180deg, #ecdcc7 0%, #e2cbae 62%, #d4b896 62.2%, #cdb08c 100%)' }}>
173
- <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 60% 55% at 70% 18%, rgba(255,248,236,0.75) 0%, rgba(255,248,236,0) 70%)' }} />
174
- <div style={{ position: 'absolute', left: -8, top: -24 }}>
175
- <Vase />
176
- </div>
177
- <div style={{ position: 'absolute', left: 28, bottom: 26, padding: '10px 18px', borderRadius: 14, background: alpha('#fbf6ef', 0.86), font: `600 24px ${FONT.sans}`, color: L.ink, letterSpacing: '-0.01em' }}>
178
- ▶ Tide Vase launch film <span style={{ color: L.ink3, fontWeight: 500 }}>· 0:30</span>
179
- </div>
180
- </div>
181
- </div>
182
- );
183
-
184
- // ───────────── 取景框 + 标签 ─────────────
185
- const Bracket: React.FC<{ t: Target; frame: number }> = ({ t, frame }) => {
186
- const f = frame - t.ft;
187
- if (f < 0) return null;
188
- const s = springAt(frame, t.ft, { damping: 15, stiffness: 210 }); // 0→1(过冲 ~1.06)
189
- const pad = 76 * (1 - s); // 外扩 76px → 0(过冲时略收进 bbox)
190
- const op = Math.min(1, f / 3);
191
- const arm = 40 - 14 * ramp(frame, t.ft + 3, 12, EASE.out); // 臂长晚一拍收一档
192
- const flash = ramp(frame, t.ft + 3, 3, EASE.out) * (1 - ramp(frame, t.ft + 6, 12, EASE.out));
193
- const x = t.x - pad;
194
- const y = t.y - pad;
195
- const w = t.w + pad * 2;
196
- const h = t.h + pad * 2;
197
- const d = [
198
- `M${x} ${y + arm}V${y}H${x + arm}`,
199
- `M${x + w - arm} ${y}H${x + w}V${y + arm}`,
200
- `M${x + w} ${y + h - arm}V${y + h}H${x + w - arm}`,
201
- `M${x + arm} ${y + h}H${x}V${y + h - arm}`,
202
- ].join('');
203
- return (
204
- <>
205
- <div style={{ position: 'absolute', left: t.x, top: t.y, width: t.w, height: t.h, borderRadius: 6, background: alpha(MACHINE, 0.075 * flash), boxShadow: `inset 0 0 0 2px ${alpha(MACHINE, 0.4 * flash)}` }} />
206
- <svg width={WW} height={WH} style={{ position: 'absolute', left: 0, top: 0, overflow: 'visible', opacity: op }}>
207
- <path d={d} fill="none" stroke={MACHINE} strokeWidth={3.5} strokeLinecap="round" strokeLinejoin="round" />
208
- </svg>
209
- </>
210
- );
211
- };
212
-
213
- const TAG_H = 50;
214
- const CHAR_W = 0.6 * 32; // 32px 等宽字步进
215
- const tagWidth = (t: Target) => Math.round((t.head.length + 3 + t.detail.length) * CHAR_W + 34);
216
-
217
- const Label: React.FC<{ t: Target; frame: number }> = ({ t, frame }) => {
218
- const s0 = t.ft + 5;
219
- if (frame < s0) return null;
220
- const rise = ramp(frame, s0, 12, EASE.out);
221
- const pop = ramp(frame, s0, 4, EASE.out);
222
- const full = `${t.head} · ${t.detail}`;
223
- const typedF = Math.min(full.length, (frame - s0) * 2.2 + 1); // 机器在写:~2 字/帧
224
- const typed = Math.floor(typedF);
225
- const w = tagWidth(t); // 定位用的最终宽度
226
- const wNow = Math.min(w, typedF * CHAR_W + 34); // 签条随字长出来(右缘略领先于字)
227
- const typing = typed < full.length;
228
- let x = t.x;
229
- let y = t.y;
230
- if (t.tag === 'right') { x = t.x + t.w + 16; y = t.y + (t.h - TAG_H) / 2; }
231
- if (t.tag === 'above') { x = t.x; y = t.y - TAG_H - 10; }
232
- if (t.tag === 'below') { x = t.x; y = t.y + t.h + 12; }
233
- if (t.tag === 'belowRight') { x = t.x + t.w - w; y = t.y + t.h + 10; }
234
- const head = full.slice(0, Math.min(typed, t.head.length));
235
- const rest = typed > t.head.length ? full.slice(t.head.length, typed) : '';
236
- return (
237
- <div style={{
238
- position: 'absolute', left: t.tag === 'belowRight' ? x + w - wNow : x, top: y, width: wNow, height: TAG_H, borderRadius: 10, background: MACHINE,
239
- boxShadow: `0 10px 22px -10px ${alpha('#0c1a5a', 0.55)}, inset 0 1px 0 rgba(255,255,255,0.22)`,
240
- opacity: pop, overflow: 'hidden',
241
- transform: `translateY(${((1 - rise) * 8).toFixed(2)}px)`,
242
- display: 'flex', alignItems: 'center', paddingLeft: 17, boxSizing: 'border-box',
243
- font: `600 32px ${MONO}`, letterSpacing: 0, whiteSpace: 'pre', color: '#ffffff',
244
- }}>
245
- <span style={{ fontWeight: 750 }}>{head}</span>
246
- <span style={{ color: 'rgba(255,255,255,0.78)', fontWeight: 500 }}>{rest}</span>
247
- {typing && <span style={{ display: 'inline-block', width: 14, height: 30, marginLeft: 2, background: 'rgba(255,255,255,0.85)' }} />}
248
- </div>
249
- );
250
- };
251
-
252
- export const ScanlineAnnotateFocus: React.FC = () => {
253
- const frame = useCurrentFrame();
254
- const ly = scanY(frame);
255
- const lineOn = ramp(frame, SCAN0 - 4, 5, EASE.out) * (1 - ramp(frame, SCAN1, 8, EASE.exit));
256
- const fired = TARGETS.filter((t) => frame >= t.ft).length;
257
- const done = ramp(frame, LAST_FIRE + 8, 8, EASE.out);
258
- const push = 1 + 0.035 * ramp(frame, 0, SCANLINE_ANNOTATE_FOCUS_DURATION, EASE.swift); // 极缓推镜
259
- const statusIn = ramp(frame, 0, 10, EASE.out);
260
- const scanProg = Math.min(1, Math.max(0, (frame - SCAN0) / (SCAN1 - SCAN0)));
261
-
262
- return (
263
- <AbsoluteFill>
264
- <Stage look={L} keyLight={{ x: 0.3, y: 0.05 }} fill={{ x: 0.9, y: 0.95 }} vignette={0.2} />
265
- <div style={{ position: 'absolute', inset: 0, transform: `scale(${push.toFixed(5)})`, transformOrigin: '50% 54%' }}>
266
- {/* ── 状态行(窗外上方)── */}
267
- <div style={{ position: 'absolute', left: WX, top: 84, width: WW, height: 48, opacity: statusIn, font: `600 30px ${MONO}`, color: L.ink, display: 'flex', alignItems: 'center' }}>
268
- <div style={{ width: 14, height: 14, borderRadius: 7, marginRight: 16, background: done > 0.5 ? MACHINE : alpha(MACHINE, 0.45 + 0.55 * (0.5 + 0.5 * Math.sin(frame / 3))), boxShadow: `0 0 0 6px ${alpha(MACHINE, 0.12)}` }} />
269
- <span style={{ color: done > 0.5 ? MACHINE : L.ink, letterSpacing: '0.06em' }}>{done > 0.5 ? 'BRAND READ' : 'READING'}</span>
270
- <span style={{ color: L.ink3, marginLeft: 18, fontWeight: 500 }}>{BRAND.name}</span>
271
- <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 20 }}>
272
- <div style={{ width: 220, height: 6, borderRadius: 3, background: alpha(L.ink, 0.1), overflow: 'hidden' }}>
273
- <div style={{ width: `${(scanProg * 100).toFixed(2)}%`, height: '100%', background: MACHINE, borderRadius: 3 }} />
274
- </div>
275
- <span style={{ fontVariantNumeric: 'tabular-nums', letterSpacing: '0.04em' }}>
276
- <span style={{ color: L.ink3, fontWeight: 500 }}>SIGNALS </span>
277
- <span style={{ color: fired === TARGETS.length ? MACHINE : L.ink }}>{String(fired).padStart(2, '0')}</span>
278
- <span style={{ color: L.ink3 }}> / {String(TARGETS.length).padStart(2, '0')}</span>
279
- </span>
280
- </div>
281
- </div>
282
-
283
- {/* ── 浏览器窗:页面 + 扫描余晖(裁进窗内)── */}
284
- <div style={{ position: 'absolute', left: WX, top: WY, width: WW, height: WH, borderRadius: 20, overflow: 'hidden', boxShadow: `${softShadow(30, { color: L.shadow, strength: 1.1 })}, 0 0 0 1px ${alpha(L.ink, 0.08)}` }}>
285
- <Page />
286
- {/* 已读余晖:扫描线身后 140px 的淡蓝洗色 + 点阵(机器"读过"的痕迹) */}
287
- {lineOn > 0.01 && (
288
- <>
289
- <div style={{
290
- position: 'absolute', left: 0, width: WW, top: ly - 140, height: 140, opacity: lineOn,
291
- background: `linear-gradient(180deg, ${alpha(MACHINE, 0)} 0%, ${alpha(MACHINE, 0.05)} 60%, ${alpha(MACHINE, 0.13)} 100%)`,
292
- }} />
293
- <div style={{
294
- position: 'absolute', left: 0, width: WW, top: ly - 90, height: 90, opacity: lineOn * 0.8,
295
- backgroundImage: `radial-gradient(circle, ${alpha(MACHINE, 0.55)} 1.3px, transparent 1.9px)`, backgroundSize: '18px 18px', backgroundPosition: '0 0',
296
- WebkitMaskImage: 'linear-gradient(180deg, transparent, #000)', maskImage: 'linear-gradient(180deg, transparent, #000)',
297
- }} />
298
- <div style={{
299
- position: 'absolute', left: 0, width: WW, top: ly - 1.5, height: 3, opacity: lineOn, background: MACHINE,
300
- boxShadow: `0 0 10px ${alpha(MACHINE, 0.55)}, 0 0 28px ${alpha(MACHINE, 0.3)}`,
301
- }} />
302
- </>
303
- )}
304
- </div>
305
-
306
- {/* ── 窗框两侧游标:随线滑动,左侧读出 Y ── */}
307
- {lineOn > 0.01 && (
308
- <div style={{ opacity: lineOn }}>
309
- <svg width={22} height={26} viewBox="0 0 22 26" style={{ position: 'absolute', left: WX - 30, top: WY + ly - 13 }}>
310
- <path d="M2 2 L20 13 L2 24 Z" fill={MACHINE} />
311
- </svg>
312
- <svg width={22} height={26} viewBox="0 0 22 26" style={{ position: 'absolute', left: WX + WW + 8, top: WY + ly - 13 }}>
313
- <path d="M20 2 L2 13 L20 24 Z" fill={MACHINE} />
314
- </svg>
315
- <div style={{ position: 'absolute', left: WX - 150, top: WY + ly - 14, width: 112, textAlign: 'right', font: `600 22px ${MONO}`, color: MACHINE, fontVariantNumeric: 'tabular-nums' }}>
316
- Y {String(Math.max(0, Math.round(ly))).padStart(4, '0')}
317
- </div>
318
- </div>
319
- )}
320
-
321
- {/* ── 取景框与标签(页面坐标,叠在窗上;不裁切,标签可略出框)── */}
322
- <div style={{ position: 'absolute', left: WX, top: WY, width: WW, height: WH }}>
323
- {TARGETS.map((t) => <Bracket key={t.key} t={t} frame={frame} />)}
324
- {TARGETS.map((t) => <Label key={t.key} t={t} frame={frame} />)}
325
- </div>
326
- </div>
327
- </AbsoluteFill>
328
- );
329
- };
1
+ // scanline-annotate-focus — 扫描分析取景标注:一条扫描线自上而下匀速掠过一张已存在的品牌官网,
2
+ // 扫过哪个区块的下缘,哪块就被一组取景角标"收拢对准",随后贴一枚机器标签把它命名;顶部状态行实时计数。
3
+ //
4
+ // 第二轮重设计(暖沙官网 × 钴蓝机器视线):
5
+ // - look = sand(米色 · 赤陶)。被分析的是 video-shotcraft 的官网:镜刻标志 + 字标、大号粗黑体 H1「Your product, in motion.」、
6
+ // 一支样片(陶器品牌 Tide Vase 的发布片封面,手绘感陶瓶)、赤陶色 CTA、四色色板——页面本身就是一张好看的品牌页。
7
+ // - 两套颜色严格分工:赤陶 = 品牌(页面内容),钴蓝 = 机器(扫描线 / 角标 / 标签 / 状态行)。
8
+ // 标签照设计工具的选中标签惯例做成钴蓝底白字小签,32px 等宽字,任何底上都读得清。
9
+ // - 页面放进一扇有两层软阴影的浏览器窗(1560×840),状态行在窗外上方;全程 1.000→1.035 极缓推镜。
10
+ // - 扫描线严格匀速(机器的视线,不加缓动):3px 钴蓝光芯 + 身后 140px 渐隐的"已读"淡蓝余晖与点阵;
11
+ // 窗框两侧各一枚随线滑动的游标,左侧读出当前 Y 坐标。
12
+ // - 取景框:四个 L 角从外扩 76px 处按弹簧(damping 15,一次可见过冲)收拢到 bbox,臂长晚 3f 收一档(跟随);
13
+ // 对准瞬间框内钴蓝对焦闪;标签 5f 后从左擦出、文字逐字打出(机器在写)。
14
+ //
15
+ // 时间表(30fps,共 150f):
16
+ // 0–6 页面已在场(它本来就存在),状态行亮起 READING
17
+ // 6–80 扫描线匀速 −20→860(74f);越过 bbox 下缘即触发(≥4f 最小间隔):
18
+ // LOGO ~19f · NAV ~23f · H1 ~47f · CTA ~66f · HERO ~70f · PALETTE ~75f
19
+ // ft+0–14 角标弹簧收拢;ft+5–14 标签擦出 + 打字
20
+ // 80–88 扫描线淡出;状态行切 BRAND READ · 6 SIGNALS(钴蓝)
21
+ // 88–150 hold:全部标注就位,极缓推镜让画面活着,尾帧是一张完整海报
22
+ import React from 'react';
23
+ import { AbsoluteFill, useCurrentFrame } from 'remotion';
24
+ import { EASE, FONT, ramp, softShadow } from '../../_fixtures/Polish';
25
+ import { LOOKS, Stage, alpha, springAt } from '../../_fixtures/Look';
26
+ import { BRAND, ShotcraftMark } from '../../_fixtures/Brand';
27
+
28
+ export const SCANLINE_ANNOTATE_FOCUS_DURATION = 150;
29
+
30
+ const L = LOOKS.sand;
31
+ const MACHINE = '#2b4fd8'; // 机器色(钴蓝):扫描线 / 角标 / 标签 / 状态行专用,页面内容不用
32
+ const TERRA = L.accent; // 品牌色(赤陶):只在页面内容里出现
33
+ const MONO = FONT.mono;
34
+
35
+ // 浏览器窗(帧坐标)
36
+ const WX = 180;
37
+ const WY = 168;
38
+ const WW = 1560;
39
+ const WH = 840;
40
+ const CHROME = 52;
41
+
42
+ // 扫描线(页面坐标,窗内 y):严格匀速
43
+ const SCAN0 = 6;
44
+ const SCAN1 = 80;
45
+ const Y0 = -20;
46
+ const Y1 = 860;
47
+ const scanY = (f: number) => Y0 + (Y1 - Y0) * Math.min(1, Math.max(0, (f - SCAN0) / (SCAN1 - SCAN0)));
48
+ const frameAtY = (y: number) => SCAN0 + ((y - Y0) / (Y1 - Y0)) * (SCAN1 - SCAN0);
49
+
50
+ // ───────────── 分析目标(页面坐标;tag = 标签相对 bbox 的放置) ─────────────
51
+ type Tag = 'right' | 'above' | 'below' | 'belowRight';
52
+ type Target = { key: string; x: number; y: number; w: number; h: number; head: string; detail: string; tag: Tag; ft: number };
53
+ const TARGETS: Target[] = (() => {
54
+ const ts: Target[] = [
55
+ { key: 'logo', x: 48, y: 64, w: 344, h: 66, head: 'LOGO', detail: 'Frame Chisel', tag: 'right', ft: 0 },
56
+ { key: 'nav', x: 1000, y: 64, w: 512, h: 66, head: 'NAV', detail: '4 items', tag: 'belowRight', ft: 0 },
57
+ { key: 'h1', x: 48, y: 222, w: 722, h: 262, head: 'H1', detail: 'Grotesk 850 · −4%', tag: 'above', ft: 0 },
58
+ { key: 'cta', x: 48, y: 632, w: 408, h: 88, head: 'CTA', detail: '#C4552D', tag: 'right', ft: 0 },
59
+ { key: 'hero', x: 892, y: 216, w: 620, h: 532, head: 'HERO', detail: 'Sample film', tag: 'below', ft: 0 },
60
+ { key: 'palette', x: 48, y: 756, w: 220, h: 66, head: 'PALETTE', detail: '4 swatches', tag: 'right', ft: 0 },
61
+ ];
62
+ // 触发 = 扫描线越过 bbox 下缘的那一帧;按下缘排序后钳制最小间隔 4f(两块同高的不会同帧弹)
63
+ let prev = -99;
64
+ for (const t of [...ts].sort((a, b) => a.y + a.h - (b.y + b.h))) {
65
+ t.ft = Math.max(frameAtY(t.y + t.h), prev + 4);
66
+ prev = t.ft;
67
+ }
68
+ return ts;
69
+ })();
70
+ const LAST_FIRE = Math.max(...TARGETS.map((t) => t.ft));
71
+
72
+ // ───────────── 页面内容:video-shotcraft 官网(产品图位放一支样片封面:陶器品牌的发布片) ─────────────
73
+ const Vase: React.FC = () => (
74
+ <svg width={620} height={580} viewBox="0 0 620 580" style={{ position: 'absolute', left: 0, top: 0 }}>
75
+ <defs>
76
+ <linearGradient id="haf-vase" x1="0" x2="1" y1="0" y2="0">
77
+ <stop offset="0" stopColor="#7d3418" />
78
+ <stop offset="0.3" stopColor="#c45a31" />
79
+ <stop offset="0.46" stopColor="#e9925f" />
80
+ <stop offset="0.62" stopColor="#c2552c" />
81
+ <stop offset="1" stopColor="#6e2c13" />
82
+ </linearGradient>
83
+ <linearGradient id="haf-bowl" x1="0" x2="1" y1="0" y2="0">
84
+ <stop offset="0" stopColor="#a99a83" />
85
+ <stop offset="0.4" stopColor="#f3ece1" />
86
+ <stop offset="0.7" stopColor="#ddd1bf" />
87
+ <stop offset="1" stopColor="#8f8069" />
88
+ </linearGradient>
89
+ <radialGradient id="haf-shadow" cx="0.5" cy="0.5" r="0.5">
90
+ <stop offset="0" stopColor="#5a3a1c" stopOpacity="0.38" />
91
+ <stop offset="1" stopColor="#5a3a1c" stopOpacity="0" />
92
+ </radialGradient>
93
+ <clipPath id="haf-clip"><path d="M228 118 C226 150 214 168 196 196 C150 262 142 336 168 398 C186 444 214 466 268 468 C322 466 350 444 368 398 C394 336 386 262 340 196 C322 168 310 150 308 118 Z" /></clipPath>
94
+ <linearGradient id="haf-glaze" x1="0" x2="0" y1="0" y2="1">
95
+ <stop offset="0" stopColor="#fff" stopOpacity="0.18" />
96
+ <stop offset="0.25" stopColor="#fff" stopOpacity="0" />
97
+ </linearGradient>
98
+ </defs>
99
+ {/* 接触影 */}
100
+ <ellipse cx={268} cy={470} rx={150} ry={22} fill="url(#haf-shadow)" />
101
+ <ellipse cx={452} cy={478} rx={98} ry={15} fill="url(#haf-shadow)" />
102
+ {/* 陶瓶:窄口 · 鼓腹 · 收足 */}
103
+ <path
104
+ d="M228 118 C226 150 214 168 196 196 C150 262 142 336 168 398 C186 444 214 466 268 468 C322 466 350 444 368 398 C394 336 386 262 340 196 C322 168 310 150 308 118 Z"
105
+ fill="url(#haf-vase)"
106
+ />
107
+ <path
108
+ d="M228 118 C226 150 214 168 196 196 C150 262 142 336 168 398 C186 444 214 466 268 468 C322 466 350 444 368 398 C394 336 386 262 340 196 C322 168 310 150 308 118 Z"
109
+ fill="url(#haf-glaze)"
110
+ />
111
+ <ellipse cx={268} cy={118} rx={40} ry={9} fill="#5e260f" />
112
+ <ellipse cx={268} cy={116} rx={40} ry={8} fill="none" stroke="#e7a073" strokeWidth={2} opacity={0.7} />
113
+ {/* 拉坯留下的轮纹:几道极淡的横向弧线,手作感 */}
114
+ <g clipPath="url(#haf-clip)">
115
+ {[176, 222, 270, 320, 370, 420].map((y, i) => (
116
+ <path key={i} d={`M60 ${y} Q268 ${y + 14} 476 ${y}`} fill="none" stroke="#3e1608" strokeWidth={1.6} opacity={0.09} />
117
+ ))}
118
+ </g>
119
+ {/* 釉面流挂的一道亮痕 */}
120
+ <path d="M232 210 C214 262 206 330 222 400" fill="none" stroke="#ffd2b0" strokeWidth={6} strokeLinecap="round" opacity={0.28} />
121
+ {/* 骨白小碗 */}
122
+ <path d="M362 402 C366 452 404 478 452 478 C500 478 538 452 542 402 Z" fill="url(#haf-bowl)" />
123
+ <ellipse cx={452} cy={402} rx={90} ry={14} fill="#efe6d8" />
124
+ <ellipse cx={452} cy={404} rx={78} ry={9} fill="#cdbfa9" />
125
+ </svg>
126
+ );
127
+
128
+ const Page: React.FC = () => (
129
+ <div style={{ position: 'absolute', inset: 0, background: '#f8f2e9', fontFamily: FONT.sans, color: L.ink }}>
130
+ {/* 浏览器顶栏 */}
131
+ <div style={{ position: 'absolute', left: 0, top: 0, width: WW, height: CHROME, background: '#efe7db', borderBottom: `1px solid ${L.line}` }}>
132
+ {[0, 1, 2].map((i) => (
133
+ <div key={i} style={{ position: 'absolute', left: 24 + i * 22, top: 20, width: 12, height: 12, borderRadius: 6, background: alpha(L.ink, 0.16) }} />
134
+ ))}
135
+ <div style={{ position: 'absolute', left: WW / 2 - 260, top: 11, width: 520, height: 30, borderRadius: 8, background: alpha('#ffffff', 0.7), border: `1px solid ${L.line}`, font: `500 18px ${MONO}`, color: L.ink3, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
136
+ {BRAND.repo}
137
+ </div>
138
+ </div>
139
+ {/* logo:镜刻标志 + video-shotcraft 字标(标志 svg 四周有 16/128 留白,左移 7px 让可见框对齐 64) */}
140
+ <div style={{ position: 'absolute', left: 57, top: 70, display: 'flex', alignItems: 'center', gap: 12 }}>
141
+ <ShotcraftMark size={56} tone="light" />
142
+ <div style={{ font: `700 34px ${BRAND.font}`, letterSpacing: '0.01em', color: BRAND.ink, whiteSpace: 'nowrap' }}>{BRAND.name}</div>
143
+ </div>
144
+ {/* 导航 */}
145
+ <div style={{ position: 'absolute', right: 64, top: 84, display: 'flex', gap: 46, font: `550 28px ${FONT.sans}`, color: L.ink2, letterSpacing: '-0.01em' }}>
146
+ <span>Recipes</span>
147
+ <span>Gallery</span>
148
+ <span>Docs</span>
149
+ <span style={{ color: L.ink }}>GitHub</span>
150
+ </div>
151
+ {/* H1 */}
152
+ <div style={{ position: 'absolute', left: 60, top: 236, font: `850 120px ${FONT.sans}`, letterSpacing: '-0.045em', lineHeight: 1, whiteSpace: 'nowrap' }}>
153
+ Your product,
154
+ <br />
155
+ in <span style={{ color: TERRA }}>motion.</span>
156
+ </div>
157
+ {/* 正文 */}
158
+ <div style={{ position: 'absolute', left: 64, top: 512, width: 700, font: `450 34px ${FONT.sans}`, lineHeight: 1.36, color: L.ink2, letterSpacing: '-0.012em' }}>
159
+ Cinematic product videos, crafted by your agent. From screenshot to showreel.
160
+ </div>
161
+ {/* CTA */}
162
+ <div style={{ position: 'absolute', left: 64, top: 644, height: 64, padding: '0 34px', borderRadius: 32, background: TERRA, color: L.onAccent, display: 'flex', alignItems: 'center', gap: 14, font: `650 30px ${FONT.sans}`, letterSpacing: '-0.01em', boxShadow: `0 10px 24px -10px ${alpha('#7a2a10', 0.55)}, inset 0 1px 0 rgba(255,255,255,0.25)` }}>
163
+ Render a launch film <span style={{ fontWeight: 500 }}>→</span>
164
+ </div>
165
+ {/* 釉色板 */}
166
+ <div style={{ position: 'absolute', left: 64, top: 768, display: 'flex', alignItems: 'center', gap: 12 }}>
167
+ {['#ebe5da', '#5d6c4f', TERRA, '#d6c3a5'].map((c, i) => (
168
+ <div key={i} style={{ width: 42, height: 42, borderRadius: 21, background: `radial-gradient(circle at 35% 30%, ${alpha('#ffffff', 0.45)}, ${alpha('#ffffff', 0)} 55%), ${c}`, boxShadow: `inset 0 0 0 1px ${alpha(L.ink, 0.12)}` }} />
169
+ ))}
170
+ </div>
171
+ {/* 产品图卡 */}
172
+ <div style={{ position: 'absolute', left: 900, top: 224, width: 604, height: 516, borderRadius: 22, overflow: 'hidden', background: 'linear-gradient(180deg, #ecdcc7 0%, #e2cbae 62%, #d4b896 62.2%, #cdb08c 100%)' }}>
173
+ <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 60% 55% at 70% 18%, rgba(255,248,236,0.75) 0%, rgba(255,248,236,0) 70%)' }} />
174
+ <div style={{ position: 'absolute', left: -8, top: -24 }}>
175
+ <Vase />
176
+ </div>
177
+ <div style={{ position: 'absolute', left: 28, bottom: 26, padding: '10px 18px', borderRadius: 14, background: alpha('#fbf6ef', 0.86), font: `600 24px ${FONT.sans}`, color: L.ink, letterSpacing: '-0.01em' }}>
178
+ ▶ Tide Vase launch film <span style={{ color: L.ink3, fontWeight: 500 }}>· 0:30</span>
179
+ </div>
180
+ </div>
181
+ </div>
182
+ );
183
+
184
+ // ───────────── 取景框 + 标签 ─────────────
185
+ const Bracket: React.FC<{ t: Target; frame: number }> = ({ t, frame }) => {
186
+ const f = frame - t.ft;
187
+ if (f < 0) return null;
188
+ const s = springAt(frame, t.ft, { damping: 15, stiffness: 210 }); // 0→1(过冲 ~1.06)
189
+ const pad = 76 * (1 - s); // 外扩 76px → 0(过冲时略收进 bbox)
190
+ const op = Math.min(1, f / 3);
191
+ const arm = 40 - 14 * ramp(frame, t.ft + 3, 12, EASE.out); // 臂长晚一拍收一档
192
+ const flash = ramp(frame, t.ft + 3, 3, EASE.out) * (1 - ramp(frame, t.ft + 6, 12, EASE.out));
193
+ const x = t.x - pad;
194
+ const y = t.y - pad;
195
+ const w = t.w + pad * 2;
196
+ const h = t.h + pad * 2;
197
+ const d = [
198
+ `M${x} ${y + arm}V${y}H${x + arm}`,
199
+ `M${x + w - arm} ${y}H${x + w}V${y + arm}`,
200
+ `M${x + w} ${y + h - arm}V${y + h}H${x + w - arm}`,
201
+ `M${x + arm} ${y + h}H${x}V${y + h - arm}`,
202
+ ].join('');
203
+ return (
204
+ <>
205
+ <div style={{ position: 'absolute', left: t.x, top: t.y, width: t.w, height: t.h, borderRadius: 6, background: alpha(MACHINE, 0.075 * flash), boxShadow: `inset 0 0 0 2px ${alpha(MACHINE, 0.4 * flash)}` }} />
206
+ <svg width={WW} height={WH} style={{ position: 'absolute', left: 0, top: 0, overflow: 'visible', opacity: op }}>
207
+ <path d={d} fill="none" stroke={MACHINE} strokeWidth={3.5} strokeLinecap="round" strokeLinejoin="round" />
208
+ </svg>
209
+ </>
210
+ );
211
+ };
212
+
213
+ const TAG_H = 50;
214
+ const CHAR_W = 0.6 * 32; // 32px 等宽字步进
215
+ const tagWidth = (t: Target) => Math.round((t.head.length + 3 + t.detail.length) * CHAR_W + 34);
216
+
217
+ const Label: React.FC<{ t: Target; frame: number }> = ({ t, frame }) => {
218
+ const s0 = t.ft + 5;
219
+ if (frame < s0) return null;
220
+ const rise = ramp(frame, s0, 12, EASE.out);
221
+ const pop = ramp(frame, s0, 4, EASE.out);
222
+ const full = `${t.head} · ${t.detail}`;
223
+ const typedF = Math.min(full.length, (frame - s0) * 2.2 + 1); // 机器在写:~2 字/帧
224
+ const typed = Math.floor(typedF);
225
+ const w = tagWidth(t); // 定位用的最终宽度
226
+ const wNow = Math.min(w, typedF * CHAR_W + 34); // 签条随字长出来(右缘略领先于字)
227
+ const typing = typed < full.length;
228
+ let x = t.x;
229
+ let y = t.y;
230
+ if (t.tag === 'right') { x = t.x + t.w + 16; y = t.y + (t.h - TAG_H) / 2; }
231
+ if (t.tag === 'above') { x = t.x; y = t.y - TAG_H - 10; }
232
+ if (t.tag === 'below') { x = t.x; y = t.y + t.h + 12; }
233
+ if (t.tag === 'belowRight') { x = t.x + t.w - w; y = t.y + t.h + 10; }
234
+ const head = full.slice(0, Math.min(typed, t.head.length));
235
+ const rest = typed > t.head.length ? full.slice(t.head.length, typed) : '';
236
+ return (
237
+ <div style={{
238
+ position: 'absolute', left: t.tag === 'belowRight' ? x + w - wNow : x, top: y, width: wNow, height: TAG_H, borderRadius: 10, background: MACHINE,
239
+ boxShadow: `0 10px 22px -10px ${alpha('#0c1a5a', 0.55)}, inset 0 1px 0 rgba(255,255,255,0.22)`,
240
+ opacity: pop, overflow: 'hidden',
241
+ transform: `translateY(${((1 - rise) * 8).toFixed(2)}px)`,
242
+ display: 'flex', alignItems: 'center', paddingLeft: 17, boxSizing: 'border-box',
243
+ font: `600 32px ${MONO}`, letterSpacing: 0, whiteSpace: 'pre', color: '#ffffff',
244
+ }}>
245
+ <span style={{ fontWeight: 750 }}>{head}</span>
246
+ <span style={{ color: 'rgba(255,255,255,0.78)', fontWeight: 500 }}>{rest}</span>
247
+ {typing && <span style={{ display: 'inline-block', width: 14, height: 30, marginLeft: 2, background: 'rgba(255,255,255,0.85)' }} />}
248
+ </div>
249
+ );
250
+ };
251
+
252
+ export const ScanlineAnnotateFocus: React.FC = () => {
253
+ const frame = useCurrentFrame();
254
+ const ly = scanY(frame);
255
+ const lineOn = ramp(frame, SCAN0 - 4, 5, EASE.out) * (1 - ramp(frame, SCAN1, 8, EASE.exit));
256
+ const fired = TARGETS.filter((t) => frame >= t.ft).length;
257
+ const done = ramp(frame, LAST_FIRE + 8, 8, EASE.out);
258
+ const push = 1 + 0.035 * ramp(frame, 0, SCANLINE_ANNOTATE_FOCUS_DURATION, EASE.swift); // 极缓推镜
259
+ const statusIn = ramp(frame, 0, 10, EASE.out);
260
+ const scanProg = Math.min(1, Math.max(0, (frame - SCAN0) / (SCAN1 - SCAN0)));
261
+
262
+ return (
263
+ <AbsoluteFill>
264
+ <Stage look={L} keyLight={{ x: 0.3, y: 0.05 }} fill={{ x: 0.9, y: 0.95 }} vignette={0.2} />
265
+ <div style={{ position: 'absolute', inset: 0, transform: `scale(${push.toFixed(5)})`, transformOrigin: '50% 54%' }}>
266
+ {/* ── 状态行(窗外上方)── */}
267
+ <div style={{ position: 'absolute', left: WX, top: 84, width: WW, height: 48, opacity: statusIn, font: `600 30px ${MONO}`, color: L.ink, display: 'flex', alignItems: 'center' }}>
268
+ <div style={{ width: 14, height: 14, borderRadius: 7, marginRight: 16, background: done > 0.5 ? MACHINE : alpha(MACHINE, 0.45 + 0.55 * (0.5 + 0.5 * Math.sin(frame / 3))), boxShadow: `0 0 0 6px ${alpha(MACHINE, 0.12)}` }} />
269
+ <span style={{ color: done > 0.5 ? MACHINE : L.ink, letterSpacing: '0.06em' }}>{done > 0.5 ? 'BRAND READ' : 'READING'}</span>
270
+ <span style={{ color: L.ink3, marginLeft: 18, fontWeight: 500 }}>{BRAND.name}</span>
271
+ <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 20 }}>
272
+ <div style={{ width: 220, height: 6, borderRadius: 3, background: alpha(L.ink, 0.1), overflow: 'hidden' }}>
273
+ <div style={{ width: `${(scanProg * 100).toFixed(2)}%`, height: '100%', background: MACHINE, borderRadius: 3 }} />
274
+ </div>
275
+ <span style={{ fontVariantNumeric: 'tabular-nums', letterSpacing: '0.04em' }}>
276
+ <span style={{ color: L.ink3, fontWeight: 500 }}>SIGNALS </span>
277
+ <span style={{ color: fired === TARGETS.length ? MACHINE : L.ink }}>{String(fired).padStart(2, '0')}</span>
278
+ <span style={{ color: L.ink3 }}> / {String(TARGETS.length).padStart(2, '0')}</span>
279
+ </span>
280
+ </div>
281
+ </div>
282
+
283
+ {/* ── 浏览器窗:页面 + 扫描余晖(裁进窗内)── */}
284
+ <div style={{ position: 'absolute', left: WX, top: WY, width: WW, height: WH, borderRadius: 20, overflow: 'hidden', boxShadow: `${softShadow(30, { color: L.shadow, strength: 1.1 })}, 0 0 0 1px ${alpha(L.ink, 0.08)}` }}>
285
+ <Page />
286
+ {/* 已读余晖:扫描线身后 140px 的淡蓝洗色 + 点阵(机器"读过"的痕迹) */}
287
+ {lineOn > 0.01 && (
288
+ <>
289
+ <div style={{
290
+ position: 'absolute', left: 0, width: WW, top: ly - 140, height: 140, opacity: lineOn,
291
+ background: `linear-gradient(180deg, ${alpha(MACHINE, 0)} 0%, ${alpha(MACHINE, 0.05)} 60%, ${alpha(MACHINE, 0.13)} 100%)`,
292
+ }} />
293
+ <div style={{
294
+ position: 'absolute', left: 0, width: WW, top: ly - 90, height: 90, opacity: lineOn * 0.8,
295
+ backgroundImage: `radial-gradient(circle, ${alpha(MACHINE, 0.55)} 1.3px, transparent 1.9px)`, backgroundSize: '18px 18px', backgroundPosition: '0 0',
296
+ WebkitMaskImage: 'linear-gradient(180deg, transparent, #000)', maskImage: 'linear-gradient(180deg, transparent, #000)',
297
+ }} />
298
+ <div style={{
299
+ position: 'absolute', left: 0, width: WW, top: ly - 1.5, height: 3, opacity: lineOn, background: MACHINE,
300
+ boxShadow: `0 0 10px ${alpha(MACHINE, 0.55)}, 0 0 28px ${alpha(MACHINE, 0.3)}`,
301
+ }} />
302
+ </>
303
+ )}
304
+ </div>
305
+
306
+ {/* ── 窗框两侧游标:随线滑动,左侧读出 Y ── */}
307
+ {lineOn > 0.01 && (
308
+ <div style={{ opacity: lineOn }}>
309
+ <svg width={22} height={26} viewBox="0 0 22 26" style={{ position: 'absolute', left: WX - 30, top: WY + ly - 13 }}>
310
+ <path d="M2 2 L20 13 L2 24 Z" fill={MACHINE} />
311
+ </svg>
312
+ <svg width={22} height={26} viewBox="0 0 22 26" style={{ position: 'absolute', left: WX + WW + 8, top: WY + ly - 13 }}>
313
+ <path d="M20 2 L2 13 L20 24 Z" fill={MACHINE} />
314
+ </svg>
315
+ <div style={{ position: 'absolute', left: WX - 150, top: WY + ly - 14, width: 112, textAlign: 'right', font: `600 22px ${MONO}`, color: MACHINE, fontVariantNumeric: 'tabular-nums' }}>
316
+ Y {String(Math.max(0, Math.round(ly))).padStart(4, '0')}
317
+ </div>
318
+ </div>
319
+ )}
320
+
321
+ {/* ── 取景框与标签(页面坐标,叠在窗上;不裁切,标签可略出框)── */}
322
+ <div style={{ position: 'absolute', left: WX, top: WY, width: WW, height: WH }}>
323
+ {TARGETS.map((t) => <Bracket key={t.key} t={t} frame={frame} />)}
324
+ {TARGETS.map((t) => <Label key={t.key} t={t} frame={frame} />)}
325
+ </div>
326
+ </div>
327
+ </AbsoluteFill>
328
+ );
329
+ };