@mova-ui/react 0.4.7 → 0.4.8
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.
- package/dist/index.js +2555 -449
- package/dist/styles.css +1 -1
- package/dist/ui/cards/calendar-day-card.d.ts +6 -0
- package/dist/ui/cards/day-trading-order-ticket.d.ts +4 -2
- package/dist/ui/cards/imessage-chat.d.ts +3 -1
- package/dist/ui/cards/liquid-glass-sheet.d.ts +3 -1
- package/dist/ui/cards/voice-assistant-card.d.ts +3 -1
- package/package.json +3 -2
- package/registry/1.json +1 -1
- package/registry/10.json +1 -1
- package/registry/11.json +1 -1
- package/registry/12.json +1 -1
- package/registry/13.json +1 -1
- package/registry/14.json +1 -1
- package/registry/15.json +1 -1
- package/registry/16.json +1 -1
- package/registry/17.json +1 -1
- package/registry/18.json +1 -1
- package/registry/19.json +1 -1
- package/registry/2.json +1 -1
- package/registry/20.json +1 -1
- package/registry/21.json +1 -1
- package/registry/22.json +1 -1
- package/registry/23.json +1 -1
- package/registry/24.json +1 -1
- package/registry/25.json +1 -1
- package/registry/26.json +1 -1
- package/registry/27.json +1 -1
- package/registry/28.json +1 -1
- package/registry/29.json +1 -1
- package/registry/3.json +1 -1
- package/registry/30.json +1 -1
- package/registry/31.json +1 -1
- package/registry/32.json +1 -1
- package/registry/33.json +1 -1
- package/registry/34.json +1 -1
- package/registry/35.json +1 -1
- package/registry/36.json +1 -1
- package/registry/37.json +1 -1
- package/registry/4.json +1 -1
- package/registry/5.json +1 -1
- package/registry/6.json +1 -1
- package/registry/7.json +1 -1
- package/registry/8.json +1 -1
- package/registry/9.json +1 -1
- package/registry/ab-segmented-tabs.json +1 -1
- package/registry/accordion-blind.json +1 -1
- package/registry/accordion-loader.json +1 -1
- package/registry/ai-approval-card.json +1 -1
- package/registry/ai-code-block.json +1 -1
- package/registry/ai-context-meter.json +1 -1
- package/registry/ai-fine-tune-card.json +1 -1
- package/registry/ai-prompt-bar.json +1 -1
- package/registry/ai-sidebar-nav.json +1 -1
- package/registry/ai-sources.json +1 -1
- package/registry/ai-suggestions.json +1 -1
- package/registry/ai-task-list.json +1 -1
- package/registry/ai-tool-call.json +1 -1
- package/registry/analyzing-image.json +1 -1
- package/registry/animated-sidebar.json +1 -1
- package/registry/animated-tags.json +1 -1
- package/registry/app-icon-load.json +1 -1
- package/registry/apple-breathe.json +1 -1
- package/registry/apple-equalizer.json +1 -1
- package/registry/apple-icon-morph.json +1 -1
- package/registry/apple-pulse-dots.json +1 -1
- package/registry/apple-scale-pulse.json +1 -1
- package/registry/apple-sound-wave.json +1 -1
- package/registry/apple-text-reveal.json +1 -1
- package/registry/apple-unlock.json +1 -1
- package/registry/arc-tracer.json +1 -1
- package/registry/balance-bar-chart-card.json +3 -5
- package/registry/bar-cascade.json +1 -1
- package/registry/bar-sweep.json +1 -1
- package/registry/blur-text.json +1 -1
- package/registry/blur-up-char.json +1 -1
- package/registry/blur-up-word.json +1 -1
- package/registry/bobbing-dots.json +1 -1
- package/registry/bookmark-corner-peel.json +1 -1
- package/registry/bookmark-save-pill.json +1 -1
- package/registry/bookmark-toggle.json +1 -1
- package/registry/border-trail-loading.json +1 -1
- package/registry/bounce-dots.json +1 -1
- package/registry/bounce-in-char.json +1 -1
- package/registry/bouncing-bars.json +1 -1
- package/registry/bouncing-dots.json +1 -1
- package/registry/bouncing-lines.json +1 -1
- package/registry/bouncing-square.json +1 -1
- package/registry/breathe-ring.json +1 -1
- package/registry/breathing-glow.json +1 -1
- package/registry/breathing-square.json +1 -1
- package/registry/btn-1.json +1 -1
- package/registry/btn-10.json +1 -1
- package/registry/btn-11.json +1 -1
- package/registry/btn-12.json +1 -1
- package/registry/btn-13.json +1 -1
- package/registry/btn-14.json +1 -1
- package/registry/btn-15.json +1 -1
- package/registry/btn-16.json +1 -1
- package/registry/btn-17.json +1 -1
- package/registry/btn-18.json +1 -1
- package/registry/btn-19.json +1 -1
- package/registry/btn-2.json +1 -1
- package/registry/btn-20.json +1 -1
- package/registry/btn-21.json +1 -1
- package/registry/btn-22.json +1 -1
- package/registry/btn-23.json +1 -1
- package/registry/btn-24.json +1 -1
- package/registry/btn-25.json +1 -1
- package/registry/btn-26.json +1 -1
- package/registry/btn-27.json +1 -1
- package/registry/btn-28.json +1 -1
- package/registry/btn-29.json +1 -1
- package/registry/btn-3.json +1 -1
- package/registry/btn-30.json +1 -1
- package/registry/btn-31.json +1 -1
- package/registry/btn-32.json +1 -1
- package/registry/btn-33.json +1 -1
- package/registry/btn-34.json +1 -1
- package/registry/btn-35.json +1 -1
- package/registry/btn-36.json +1 -1
- package/registry/btn-37.json +1 -1
- package/registry/btn-4.json +1 -1
- package/registry/btn-5.json +1 -1
- package/registry/btn-6.json +1 -1
- package/registry/btn-7.json +1 -1
- package/registry/btn-8.json +1 -1
- package/registry/btn-9.json +1 -1
- package/registry/button-slide-arrow.json +1 -1
- package/registry/cacheable-bandwidth-cost.json +1 -1
- package/registry/calendar-day-card.json +4 -5
- package/registry/card-arc-5.json +1 -1
- package/registry/card-arc-7.json +1 -1
- package/registry/card-carousel-mono.json +1 -1
- package/registry/card-carousel.json +1 -1
- package/registry/card-cascade-stagger.json +1 -1
- package/registry/card-corner-fan.json +1 -1
- package/registry/card-cover-flow-mono.json +1 -1
- package/registry/card-cover-flow.json +1 -1
- package/registry/card-deck-cascade.json +1 -1
- package/registry/card-glance-preview.json +1 -1
- package/registry/card-hover.json +1 -1
- package/registry/card-linear-spread.json +1 -1
- package/registry/card-long-arc-5.json +1 -1
- package/registry/card-scatter-spread.json +1 -1
- package/registry/card-stack-peel.json +1 -1
- package/registry/card-stamp-arc.json +1 -1
- package/registry/card-time-machine-mono.json +1 -1
- package/registry/card-time-machine.json +1 -1
- package/registry/card-wheel-fan.json +1 -1
- package/registry/category-select.json +1 -1
- package/registry/character-stagger.json +1 -1
- package/registry/checkbox-draw.json +1 -1
- package/registry/checkmark-draw.json +1 -1
- package/registry/circle-toggle.json +1 -1
- package/registry/circuit-trace-draw.json +1 -1
- package/registry/circular-bars.json +1 -1
- package/registry/circular-create-button.json +1 -1
- package/registry/classic-spinner.json +1 -1
- package/registry/classic-toggle.json +1 -1
- package/registry/clock-spinner.json +1 -1
- package/registry/comet-spinner.json +1 -1
- package/registry/compass-needle-deflect.json +1 -1
- package/registry/concentric-pulse.json +1 -1
- package/registry/concentric-ring.json +1 -1
- package/registry/concentric-squares.json +1 -1
- package/registry/context-menu.json +1 -1
- package/registry/conveyor-loop.json +1 -1
- package/registry/credit-score-barcode-meter.json +1 -1
- package/registry/cross-spinner.json +1 -1
- package/registry/cube-flip-spring.json +1 -1
- package/registry/cursor-trail.json +1 -1
- package/registry/dash-ring.json +1 -1
- package/registry/dashed-spiral.json +1 -1
- package/registry/date-position-selector.json +1 -1
- package/registry/day-trading-order-ticket.json +3 -5
- package/registry/dia-text-reveal.json +1 -1
- package/registry/diamond-grid.json +1 -1
- package/registry/diamond-rotate-spring.json +1 -1
- package/registry/dislike-toggle.json +1 -1
- package/registry/dither-book.json +1 -1
- package/registry/domino-cascade.json +1 -1
- package/registry/dot-spinner.json +1 -1
- package/registry/dots-ring.json +1 -1
- package/registry/double-bounce-toggle.json +1 -1
- package/registry/double-ring.json +1 -1
- package/registry/download-icons.json +1 -1
- package/registry/drop-dot.json +1 -1
- package/registry/drop-in-char.json +1 -1
- package/registry/droplet-squish.json +1 -1
- package/registry/dual-arc.json +1 -1
- package/registry/dual-magnet-dipole.json +1 -1
- package/registry/dynamic-island.json +1 -1
- package/registry/elastic-bars.json +1 -1
- package/registry/elastic-square.json +1 -1
- package/registry/elastic-tag-snap.json +1 -1
- package/registry/error-shake.json +1 -1
- package/registry/expanding-cross.json +1 -1
- package/registry/expanding-icon-tabs.json +1 -1
- package/registry/face-id-scan.json +1 -1
- package/registry/fade-arc.json +1 -1
- package/registry/fade-dots.json +1 -1
- package/registry/fade-down.json +1 -1
- package/registry/fade-in-char.json +1 -1
- package/registry/fade-in-text.json +1 -1
- package/registry/fade-in-word.json +1 -1
- package/registry/fade-in.json +1 -1
- package/registry/fade-up.json +1 -1
- package/registry/file-upload-dropzone.json +1 -1
- package/registry/filter-tag-pill.json +1 -1
- package/registry/flip-square.json +1 -1
- package/registry/flip-x-char.json +1 -1
- package/registry/flip-y-char.json +1 -1
- package/registry/float-char.json +1 -1
- package/registry/float-word.json +1 -1
- package/registry/floating-diamonds.json +1 -1
- package/registry/floating-label-input.json +1 -1
- package/registry/fluid-bars.json +1 -1
- package/registry/fluid-diamond.json +1 -1
- package/registry/fluid-dot-orbit.json +1 -1
- package/registry/fluid-skeleton.json +1 -1
- package/registry/focus-blur.json +1 -1
- package/registry/form-submit-button.json +1 -1
- package/registry/french-doors-3d.json +1 -1
- package/registry/gear-tooth-step.json +1 -1
- package/registry/gears.json +1 -1
- package/registry/gelatin-wobble.json +1 -1
- package/registry/geometric-iris-shutter.json +1 -1
- package/registry/glassmorphic-card.json +1 -1
- package/registry/glow-button.json +1 -1
- package/registry/glow-text.json +1 -1
- package/registry/gooey-popover.json +1 -1
- package/registry/gradient-arc.json +1 -1
- package/registry/gradient-shimmer.json +1 -1
- package/registry/grid-dots.json +1 -1
- package/registry/haptic-ring.json +1 -1
- package/registry/heartbeat.json +1 -1
- package/registry/hex-lattice-draw.json +1 -1
- package/registry/hexagon-spinner.json +1 -1
- package/registry/hourglass.json +1 -1
- package/registry/hover-lift-char.json +1 -1
- package/registry/hover-lift-word.json +1 -1
- package/registry/hover-link-card.json +1 -1
- package/registry/hover-scale-char.json +1 -1
- package/registry/hover-scale-word.json +1 -1
- package/registry/imessage-chat.json +2 -2
- package/registry/inertia-skid-stop.json +1 -1
- package/registry/infinity-path.json +1 -1
- package/registry/input-focus-glow.json +1 -1
- package/registry/inset-action-button.json +1 -1
- package/registry/inset-button.json +1 -1
- package/registry/intersecting-rings.json +1 -1
- package/registry/ios-spinner.json +1 -1
- package/registry/kinetic-metronome-tick.json +1 -1
- package/registry/kinetic-tension-capsule.json +1 -1
- package/registry/light-dark-morph.json +1 -1
- package/registry/like-toggle.json +1 -1
- package/registry/line-spinner.json +1 -1
- package/registry/liquid-dots.json +1 -1
- package/registry/liquid-glass-sheet.json +3 -5
- package/registry/mac-terminal.json +1 -1
- package/registry/magnetic-button.json +1 -1
- package/registry/magnetic-disks.json +1 -1
- package/registry/magnetic-dots.json +1 -1
- package/registry/magnetic-slide-btn.json +1 -1
- package/registry/manifest.json +658 -665
- package/registry/matrix-grid-loader.json +1 -1
- package/registry/minimal-triangle.json +1 -1
- package/registry/modular-tile-snap.json +1 -1
- package/registry/mono-activity-blue.json +1 -1
- package/registry/mono-activity-green.json +1 -1
- package/registry/mono-activity-purple.json +1 -1
- package/registry/mono-heatmap.json +1 -1
- package/registry/mono-rounded-area.json +1 -1
- package/registry/mono-rounded-bar.json +1 -1
- package/registry/mono-rounded-bubble.json +1 -1
- package/registry/mono-rounded-bullet.json +1 -1
- package/registry/mono-rounded-candlestick.json +1 -1
- package/registry/mono-rounded-composed.json +1 -1
- package/registry/mono-rounded-donut.json +1 -1
- package/registry/mono-rounded-funnel.json +1 -1
- package/registry/mono-rounded-gauge-arc.json +1 -1
- package/registry/mono-rounded-heatmap.json +1 -1
- package/registry/mono-rounded-kpi.json +1 -1
- package/registry/mono-rounded-line.json +1 -1
- package/registry/mono-rounded-meter.json +1 -1
- package/registry/mono-rounded-polar.json +1 -1
- package/registry/mono-rounded-pyramid.json +1 -1
- package/registry/mono-rounded-radar.json +1 -1
- package/registry/mono-rounded-radial-gauge.json +1 -1
- package/registry/mono-rounded-radial-group.json +1 -1
- package/registry/mono-rounded-range.json +1 -1
- package/registry/mono-rounded-sankey.json +1 -1
- package/registry/mono-rounded-scatter.json +1 -1
- package/registry/mono-rounded-sparkline.json +1 -1
- package/registry/mono-rounded-stacked-bar.json +1 -1
- package/registry/mono-rounded-step.json +1 -1
- package/registry/mono-rounded-stream.json +1 -1
- package/registry/mono-rounded-treemap.json +1 -1
- package/registry/mono-rounded-waterfall.json +1 -1
- package/registry/mono-stock.json +1 -1
- package/registry/morph-action-pill.json +1 -1
- package/registry/morph-dot-ring.json +1 -1
- package/registry/morph-loader.json +1 -1
- package/registry/morph-toggle.json +1 -1
- package/registry/morphing-bars.json +1 -1
- package/registry/morphing-infinity.json +1 -1
- package/registry/morphing-ring.json +1 -1
- package/registry/morphing-shape.json +1 -1
- package/registry/mouse-follow.json +1 -1
- package/registry/multi-select-chips.json +1 -1
- package/registry/multi-tab-bar.json +1 -1
- package/registry/neon-sign-draw.json +1 -1
- package/registry/nested-orbital-gimbal.json +1 -1
- package/registry/network-telemetry-matrix.json +1 -1
- package/registry/newtons-cradle.json +1 -1
- package/registry/noise-decibel-level.json +1 -1
- package/registry/obsidian-liquid-wave.json +1 -1
- package/registry/offset-rings.json +1 -1
- package/registry/orbiting-circles.json +1 -1
- package/registry/orbiting-dot.json +1 -1
- package/registry/origami-envelope-unfold.json +1 -1
- package/registry/origami-shape.json +1 -1
- package/registry/otp-input.json +1 -1
- package/registry/overview-bar-scrubber-card.json +1 -1
- package/registry/page-transition.json +1 -1
- package/registry/page-turn-curl.json +1 -1
- package/registry/password-toggle.json +1 -1
- package/registry/pendulum-bubble-level.json +1 -1
- package/registry/pendulum.json +1 -1
- package/registry/perspective-flip-stage.json +1 -1
- package/registry/perspective-flip.json +1 -1
- package/registry/perspective-layout-switcher.json +1 -1
- package/registry/physics-dock.json +1 -1
- package/registry/pill-tabs.json +1 -1
- package/registry/plus-minus-toggle.json +1 -1
- package/registry/presets.json +1 -1
- package/registry/prism-block-stack.json +1 -1
- package/registry/progress-indicator-piano.json +1 -1
- package/registry/progress-indicator.json +1 -1
- package/registry/progress-stepper.json +1 -1
- package/registry/pulsating-dots.json +1 -1
- package/registry/pulse-char.json +1 -1
- package/registry/pulse-dot.json +1 -1
- package/registry/pulse-dots.json +1 -1
- package/registry/pulse-square.json +1 -1
- package/registry/pulse-word.json +1 -1
- package/registry/pulse.json +1 -1
- package/registry/pumping-heart.json +1 -1
- package/registry/pyramid-block-build.json +1 -1
- package/registry/radar-sweep.json +1 -1
- package/registry/radial-iris-mask.json +1 -1
- package/registry/radial-spinner.json +1 -1
- package/registry/radio-scale.json +1 -1
- package/registry/range-slider.json +1 -1
- package/registry/receipt-tape-print.json +1 -1
- package/registry/rectangle-toggle.json +1 -1
- package/registry/repost-toggle.json +1 -1
- package/registry/reveal-text.json +1 -1
- package/registry/ribbon-banner-slide.json +1 -1
- package/registry/ring-sweep.json +1 -1
- package/registry/ripple-effect.json +1 -1
- package/registry/rise-up-word.json +1 -1
- package/registry/roller-blind-drop.json +1 -1
- package/registry/rolling-tumble.json +1 -1
- package/registry/rotate-in-char.json +1 -1
- package/registry/rotating-cross.json +1 -1
- package/registry/rotating-louvers.json +1 -1
- package/registry/rotating-triangle.json +1 -1
- package/registry/rudder-issue-board.json +1 -1
- package/registry/sales-analytics-dual-bars.json +1 -1
- package/registry/sales-overview-radial-dashboard.json +1 -1
- package/registry/sales-target-segmented-arc.json +1 -1
- package/registry/scale-in-char.json +1 -1
- package/registry/scale-in-text.json +1 -1
- package/registry/scale-in-word.json +1 -1
- package/registry/scale-in.json +1 -1
- package/registry/scramble-text.json +1 -1
- package/registry/scroll-canvas-unroll.json +1 -1
- package/registry/scroll-reveal.json +1 -1
- package/registry/search-expand.json +1 -1
- package/registry/segmented-arc-meter.json +1 -1
- package/registry/segmented-link-stretch.json +1 -1
- package/registry/segmented-step-bar.json +1 -1
- package/registry/segmented-stepper-dots.json +1 -1
- package/registry/select-dropdown.json +1 -1
- package/registry/server-performance-step-bars.json +1 -1
- package/registry/shape-shift-grid.json +1 -1
- package/registry/shimmer-line.json +1 -1
- package/registry/shimmer-text.json +1 -1
- package/registry/shutter-slide.json +1 -1
- package/registry/shutter-step-slices.json +1 -1
- package/registry/siri-wave.json +1 -1
- package/registry/skeleton-loader.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/skew-x-char.json +1 -1
- package/registry/slide-down-char.json +1 -1
- package/registry/slide-down-word.json +1 -1
- package/registry/slide-left-char.json +1 -1
- package/registry/slide-left.json +1 -1
- package/registry/slide-right-char.json +1 -1
- package/registry/slide-right.json +1 -1
- package/registry/slide-up-char.json +1 -1
- package/registry/slide-up-text.json +1 -1
- package/registry/slide-up-word.json +1 -1
- package/registry/sliding-bars.json +1 -1
- package/registry/slinky-coil.json +1 -1
- package/registry/smart-card-dispenser.json +1 -1
- package/registry/smooth-dot-shift.json +1 -1
- package/registry/smooth-ring.json +1 -1
- package/registry/smooth-rounded-square.json +1 -1
- package/registry/solid-switch.json +1 -1
- package/registry/spatial-door-portal.json +1 -1
- package/registry/spinning-squares.json +1 -1
- package/registry/spiral-spinner.json +1 -1
- package/registry/split-gate-reveal.json +1 -1
- package/registry/spotlight.json +1 -1
- package/registry/spring-bars.json +1 -1
- package/registry/spring-dot-matrix.json +1 -1
- package/registry/spring-hexagon.json +1 -1
- package/registry/spring-ring-expand.json +1 -1
- package/registry/spring-text-pop.json +1 -1
- package/registry/spring-text.json +1 -1
- package/registry/square-accordion.json +1 -1
- package/registry/square-grid.json +1 -1
- package/registry/square-snake.json +1 -1
- package/registry/square-spinner.json +1 -1
- package/registry/squash-sphere.json +1 -1
- package/registry/stacked-bar-pulse.json +1 -1
- package/registry/stagger-text.json +1 -1
- package/registry/staggered-glass-curtain.json +1 -1
- package/registry/sticky-note-peel.json +1 -1
- package/registry/sticky-reveal.json +1 -1
- package/registry/stretch-x-char.json +1 -1
- package/registry/stretch-y-char.json +1 -1
- package/registry/stroke-waveform.json +1 -1
- package/registry/submenu-flyout.json +1 -1
- package/registry/success-check.json +1 -1
- package/registry/sudden-brake.json +1 -1
- package/registry/swapping-dots.json +1 -1
- package/registry/swing-word.json +1 -1
- package/registry/swirling-spinner.json +1 -1
- package/registry/symmetric-wave.json +1 -1
- package/registry/terminal-loader.json +1 -1
- package/registry/text-blink.json +1 -1
- package/registry/text-dots.json +1 -1
- package/registry/text-morph.json +1 -1
- package/registry/text-reveal.json +1 -1
- package/registry/text-shimmer-wave.json +1 -1
- package/registry/text-shimmer.json +1 -1
- package/registry/textarea-auto-grow.json +1 -1
- package/registry/theme-toggle.json +1 -1
- package/registry/tilt-card.json +1 -1
- package/registry/timer-preparation-segmented.json +1 -1
- package/registry/tracking-in-text.json +1 -1
- package/registry/tracking-out-text.json +1 -1
- package/registry/trailing-dots.json +1 -1
- package/registry/triple-dot-spinner.json +1 -1
- package/registry/twin-orbit.json +1 -1
- package/registry/typewriter-text.json +1 -1
- package/registry/typing-indicator.json +1 -1
- package/registry/typing.json +1 -1
- package/registry/use-mouse-position.json +1 -1
- package/registry/use-reduced-motion.json +1 -1
- package/registry/use-scroll-progress.json +1 -1
- package/registry/use-stagger.json +1 -1
- package/registry/use-web-haptics.json +1 -1
- package/registry/users-growth-pill-progress.json +1 -1
- package/registry/utils.json +1 -1
- package/registry/vertical-wheel-counter.json +1 -1
- package/registry/views-hourly-wave-chart.json +1 -1
- package/registry/voice-assistant-card.json +3 -3
- package/registry/wandering-cube.json +1 -1
- package/registry/wandering-eyes.json +1 -1
- package/registry/watch-spinner.json +1 -1
- package/registry/wave-dots.json +1 -1
- package/registry/wave-physics-loader.json +1 -1
- package/registry/wave-reveal.json +1 -1
- package/registry/waveform-loader.json +1 -1
- package/registry/word-reveal.json +1 -1
- package/registry/zig-zag-pulse.json +1 -1
- package/registry/zoom-in-text.json +1 -1
- package/registry/zoom-in.json +1 -1
- package/registry/zoom-out-text.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4135,7 +4135,7 @@ function AnimatedSidebar({
|
|
|
4135
4135
|
"data-open": isSectionOpen,
|
|
4136
4136
|
id: sectionId,
|
|
4137
4137
|
children: /* @__PURE__ */ jsx12("div", { className: "mova-sidebar__section-content-inner", children: /* @__PURE__ */ jsx12("ul", { className: "mova-sidebar__list", children: SIDEBAR_ITEMS.map((item) => {
|
|
4138
|
-
const
|
|
4138
|
+
const Icon3 = item.icon;
|
|
4139
4139
|
const isActive = activeItem === item.id;
|
|
4140
4140
|
return /* @__PURE__ */ jsx12("li", { children: /* @__PURE__ */ jsxs12(
|
|
4141
4141
|
"button",
|
|
@@ -4148,7 +4148,7 @@ function AnimatedSidebar({
|
|
|
4148
4148
|
tabIndex: isSectionOpen ? 0 : -1,
|
|
4149
4149
|
type: "button",
|
|
4150
4150
|
children: [
|
|
4151
|
-
/* @__PURE__ */ jsx12("span", { className: "mova-sidebar__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx12(
|
|
4151
|
+
/* @__PURE__ */ jsx12("span", { className: "mova-sidebar__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx12(Icon3, { size: 17, strokeWidth: 1.8 }) }),
|
|
4152
4152
|
/* @__PURE__ */ jsxs12("span", { className: "mova-sidebar__item-copy", children: [
|
|
4153
4153
|
/* @__PURE__ */ jsx12("span", { className: "mova-sidebar__item-label", children: item.label }),
|
|
4154
4154
|
/* @__PURE__ */ jsx12("span", { className: "mova-sidebar__item-meta", children: item.meta })
|
|
@@ -4174,163 +4174,619 @@ function AnimatedSidebar({
|
|
|
4174
4174
|
|
|
4175
4175
|
// .generated/ui/cards/balance-bar-chart-card.tsx
|
|
4176
4176
|
import * as React from "react";
|
|
4177
|
-
import {
|
|
4178
|
-
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4177
|
+
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4179
4178
|
var periodsDefault = [
|
|
4180
|
-
{ id: "week", label: "Week", balance: 12480.5, change: "+8.2%", detail: "
|
|
4181
|
-
{ id: "month", label: "Month", balance: 12480.5, change: "+12.
|
|
4182
|
-
{ id: "year", label: "Year", balance: 12480.5, change: "+
|
|
4179
|
+
{ id: "week", label: "Week", balance: 12480.5, change: "+8.2%", detail: "+$940.20 this week", points: ["M", "T", "W", "T", "F", "S", "S"].map((label, i) => ({ label, value: [96, 142, 88, 210, 175, 120, 109][i] })) },
|
|
4180
|
+
{ id: "month", label: "Month", balance: 12480.5, change: "+12.4%", detail: "+$4,220.60 this month", points: ["1", "5", "10", "15", "20", "25", "30"].map((label, i) => ({ label, value: [420, 610, 380, 720, 560, 890, 640][i] })) },
|
|
4181
|
+
{ id: "year", label: "Year", balance: 12480.5, change: "+18.6%", detail: "+$32,520.00 this year", points: ["Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"].map((label, i) => ({ label, value: [3120, 4210, 3680, 5020, 4460, 5890, 6140][i] })) }
|
|
4183
4182
|
];
|
|
4183
|
+
var useLayoutEffect6 = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
|
|
4184
|
+
function SoftText({ text, className = "" }) {
|
|
4185
|
+
const element = React.useRef(null);
|
|
4186
|
+
const initial = React.useRef(text);
|
|
4187
|
+
useLayoutEffect6(() => {
|
|
4188
|
+
const el = element.current;
|
|
4189
|
+
if (!el) return;
|
|
4190
|
+
const previous = el.dataset.text ?? initial.current;
|
|
4191
|
+
if (previous === text) return;
|
|
4192
|
+
el.dataset.text = text;
|
|
4193
|
+
const width = el.getBoundingClientRect().width;
|
|
4194
|
+
const old = document.createElement("span");
|
|
4195
|
+
old.className = "mbc-soft-old";
|
|
4196
|
+
old.setAttribute("aria-hidden", "true");
|
|
4197
|
+
old.textContent = previous;
|
|
4198
|
+
const next = document.createElement("span");
|
|
4199
|
+
next.className = "mbc-soft-new";
|
|
4200
|
+
next.textContent = text;
|
|
4201
|
+
el.classList.remove("is-swapping");
|
|
4202
|
+
el.replaceChildren(old, next);
|
|
4203
|
+
const nextWidth = next.getBoundingClientRect().width;
|
|
4204
|
+
el.style.width = `${width}px`;
|
|
4205
|
+
void el.offsetWidth;
|
|
4206
|
+
el.classList.add("is-swapping");
|
|
4207
|
+
el.style.width = `${nextWidth}px`;
|
|
4208
|
+
const computed = getComputedStyle(el);
|
|
4209
|
+
const duration = Math.max(parseFloat(computed.getPropertyValue("--mbc-text-dur")) || 0, parseFloat(computed.getPropertyValue("--mbc-text-resize-dur")) || 0);
|
|
4210
|
+
const timer = window.setTimeout(() => {
|
|
4211
|
+
el.classList.remove("is-swapping");
|
|
4212
|
+
el.style.removeProperty("width");
|
|
4213
|
+
el.textContent = text;
|
|
4214
|
+
}, duration + 40);
|
|
4215
|
+
return () => window.clearTimeout(timer);
|
|
4216
|
+
}, [text]);
|
|
4217
|
+
return /* @__PURE__ */ jsx13("span", { ref: element, className: `mbc-soft ${className}`, children: initial.current });
|
|
4218
|
+
}
|
|
4184
4219
|
function BalanceBarChartCard({ periods = periodsDefault, defaultPeriod = "week", currency = "USD", locale = "en-US", onPeriodChange, theme = "light", className = "", style } = {}) {
|
|
4185
4220
|
const [selected, setSelected] = React.useState(defaultPeriod);
|
|
4186
4221
|
const [active, setActive] = React.useState(null);
|
|
4222
|
+
const root = React.useRef(null);
|
|
4223
|
+
const chart = React.useRef(null);
|
|
4224
|
+
const tooltip = React.useRef(null);
|
|
4225
|
+
const tooltipText = React.useRef(null);
|
|
4226
|
+
const tabs = React.useRef(null);
|
|
4227
|
+
const pill = React.useRef(null);
|
|
4228
|
+
const measuredPill = React.useRef(false);
|
|
4229
|
+
const lastTooltip = React.useRef("");
|
|
4230
|
+
const tipId = React.useId();
|
|
4231
|
+
const chartId = React.useId();
|
|
4187
4232
|
const period = periods.find((item) => item.id === selected) ?? periods[0];
|
|
4188
|
-
const
|
|
4233
|
+
const periodIndex = period ? periods.indexOf(period) : -1;
|
|
4234
|
+
const money2 = new Intl.NumberFormat(locale, { style: "currency", currency });
|
|
4235
|
+
const pointMoney = new Intl.NumberFormat(locale, { style: "currency", currency, minimumFractionDigits: 0, maximumFractionDigits: 2 });
|
|
4236
|
+
const amountParts = money2.formatToParts(period?.balance ?? 0);
|
|
4189
4237
|
const max = Math.max(1, ...period?.points.map((point) => Math.abs(point.value)) ?? []);
|
|
4190
|
-
const tipId = React.useId();
|
|
4191
4238
|
const signed = period?.points.some((point) => point.value < 0) ?? false;
|
|
4192
4239
|
const negativeChange = period?.change.trim().startsWith("-");
|
|
4193
|
-
|
|
4240
|
+
const detail = /^(.*?)(\$[\d,.]+)(\s+this\s+)(.+)$/.exec(period?.detail ?? "");
|
|
4241
|
+
if (active !== null && period?.points[active]) lastTooltip.current = pointMoney.format(period.points[active].value);
|
|
4242
|
+
useLayoutEffect6(() => {
|
|
4243
|
+
const tip = tooltip.current;
|
|
4244
|
+
if (!tip) return;
|
|
4245
|
+
const trigger = chart.current?.querySelectorAll(".mbc-column")[active ?? -1];
|
|
4246
|
+
if (active === null || !trigger || !chart.current || !tooltipText.current) {
|
|
4247
|
+
tip.dataset.show = "false";
|
|
4248
|
+
tip.setAttribute("aria-hidden", "true");
|
|
4249
|
+
return;
|
|
4250
|
+
}
|
|
4251
|
+
const showing = tip.dataset.show === "true";
|
|
4252
|
+
const computed = getComputedStyle(tip);
|
|
4253
|
+
const width = Math.ceil(tooltipText.current.scrollWidth + parseFloat(computed.paddingLeft) + parseFloat(computed.paddingRight));
|
|
4254
|
+
const groupRect = chart.current.getBoundingClientRect();
|
|
4255
|
+
const rect = trigger.getBoundingClientRect();
|
|
4256
|
+
const x = Math.max(0, Math.min(rect.left - groupRect.left + rect.width / 2 - width / 2, groupRect.width - width));
|
|
4257
|
+
if (!showing) tip.style.transition = "none";
|
|
4258
|
+
tip.style.width = `${width}px`;
|
|
4259
|
+
tip.style.setProperty("--mbc-tip-x", `${x}px`);
|
|
4260
|
+
if (!showing) {
|
|
4261
|
+
void tip.offsetWidth;
|
|
4262
|
+
tip.style.transition = "";
|
|
4263
|
+
}
|
|
4264
|
+
tip.dataset.show = "true";
|
|
4265
|
+
tip.setAttribute("aria-hidden", "false");
|
|
4266
|
+
}, [active, period, currency, locale]);
|
|
4267
|
+
const movePill = React.useCallback((animate) => {
|
|
4268
|
+
const tab = tabs.current?.querySelector('[role=tab][aria-selected="true"]');
|
|
4269
|
+
const el = pill.current;
|
|
4270
|
+
if (!tab || !el) return;
|
|
4271
|
+
if (!animate) el.style.transition = "none";
|
|
4272
|
+
el.style.transform = `translateX(${tab.offsetLeft}px)`;
|
|
4273
|
+
el.style.width = `${tab.offsetWidth}px`;
|
|
4274
|
+
if (!animate) {
|
|
4275
|
+
void el.offsetWidth;
|
|
4276
|
+
el.style.transition = "";
|
|
4277
|
+
}
|
|
4278
|
+
}, []);
|
|
4279
|
+
useLayoutEffect6(() => {
|
|
4280
|
+
movePill(measuredPill.current);
|
|
4281
|
+
measuredPill.current = true;
|
|
4282
|
+
}, [movePill, periodIndex, periods]);
|
|
4283
|
+
useLayoutEffect6(() => {
|
|
4284
|
+
const resize = () => movePill(false);
|
|
4285
|
+
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(resize) : void 0;
|
|
4286
|
+
if (tabs.current) observer?.observe(tabs.current);
|
|
4287
|
+
window.addEventListener("resize", resize);
|
|
4288
|
+
let cancelled = false;
|
|
4289
|
+
document.fonts?.ready.then(() => {
|
|
4290
|
+
if (!cancelled) movePill(false);
|
|
4291
|
+
});
|
|
4292
|
+
return () => {
|
|
4293
|
+
cancelled = true;
|
|
4294
|
+
observer?.disconnect();
|
|
4295
|
+
window.removeEventListener("resize", resize);
|
|
4296
|
+
};
|
|
4297
|
+
}, []);
|
|
4298
|
+
React.useEffect(() => {
|
|
4299
|
+
const el = root.current;
|
|
4300
|
+
if (!el) return;
|
|
4301
|
+
let pressed = null;
|
|
4302
|
+
let started = 0;
|
|
4303
|
+
let timer;
|
|
4304
|
+
const clear = () => {
|
|
4305
|
+
if (pressed) delete pressed.dataset.pressed;
|
|
4306
|
+
pressed = null;
|
|
4307
|
+
};
|
|
4308
|
+
const down = (event) => {
|
|
4309
|
+
if (event.pointerType === "mouse") return;
|
|
4310
|
+
const button = event.target.closest("button");
|
|
4311
|
+
if (!button || button.disabled) return;
|
|
4312
|
+
clearTimeout(timer);
|
|
4313
|
+
clear();
|
|
4314
|
+
pressed = button;
|
|
4315
|
+
started = performance.now();
|
|
4316
|
+
button.dataset.pressed = "true";
|
|
4317
|
+
};
|
|
4318
|
+
const up = () => {
|
|
4319
|
+
if (!pressed) return;
|
|
4320
|
+
const duration = parseFloat(getComputedStyle(pressed).getPropertyValue("--mbc-press-dur")) || 150;
|
|
4321
|
+
timer = setTimeout(clear, Math.max(0, duration - (performance.now() - started)));
|
|
4322
|
+
};
|
|
4323
|
+
el.addEventListener("pointerdown", down);
|
|
4324
|
+
window.addEventListener("pointerup", up);
|
|
4325
|
+
window.addEventListener("pointercancel", up);
|
|
4326
|
+
return () => {
|
|
4327
|
+
clearTimeout(timer);
|
|
4328
|
+
clear();
|
|
4329
|
+
el.removeEventListener("pointerdown", down);
|
|
4330
|
+
window.removeEventListener("pointerup", up);
|
|
4331
|
+
window.removeEventListener("pointercancel", up);
|
|
4332
|
+
};
|
|
4333
|
+
}, []);
|
|
4334
|
+
function selectPeriod(item) {
|
|
4335
|
+
if (period?.id === item.id) return;
|
|
4336
|
+
setSelected(item.id);
|
|
4337
|
+
setActive(null);
|
|
4338
|
+
onPeriodChange?.(item);
|
|
4339
|
+
}
|
|
4340
|
+
return /* @__PURE__ */ jsxs13("section", { ref: root, className: `mova-balance ${className}`, "data-theme": theme, style, "aria-label": "Balance chart", children: [
|
|
4194
4341
|
/* @__PURE__ */ jsx13("style", { children: css }),
|
|
4195
4342
|
/* @__PURE__ */ jsx13("div", { className: "mbc-label", children: "Balance" }),
|
|
4196
|
-
/* @__PURE__ */
|
|
4197
|
-
|
|
4198
|
-
period && /* @__PURE__ */
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4343
|
+
/* @__PURE__ */ jsx13("div", { className: "mbc-summary", children: amountParts.map((part, index) => /* @__PURE__ */ jsx13("span", { className: part.type === "decimal" || part.type === "fraction" ? "mbc-cents" : void 0, children: part.value }, index)) }),
|
|
4344
|
+
/* @__PURE__ */ jsxs13("div", { className: "mbc-change-row", children: [
|
|
4345
|
+
period && /* @__PURE__ */ jsx13("span", { className: "mbc-change", "data-negative": negativeChange, children: /* @__PURE__ */ jsx13(SoftText, { text: period.change }) }),
|
|
4346
|
+
/* @__PURE__ */ jsx13("span", { className: "mbc-detail", children: detail ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
|
|
4347
|
+
detail[1],
|
|
4348
|
+
/* @__PURE__ */ jsx13(SoftText, { text: detail[2] }),
|
|
4349
|
+
detail[3],
|
|
4350
|
+
/* @__PURE__ */ jsx13(SoftText, { text: detail[4] })
|
|
4351
|
+
] }) : /* @__PURE__ */ jsx13(SoftText, { text: period?.detail ?? "No balance data" }) })
|
|
4202
4352
|
] }),
|
|
4203
|
-
/* @__PURE__ */
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
/* @__PURE__ */ jsx13(
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
active !== null && period?.points[active] && /* @__PURE__ */ jsxs13("div", { id: tipId, role: "tooltip", className: "mbc-tooltip", children: [
|
|
4210
|
-
period.points[active].label,
|
|
4211
|
-
" \xB7 ",
|
|
4212
|
-
money.format(period.points[active].value)
|
|
4213
|
-
] })
|
|
4353
|
+
/* @__PURE__ */ jsxs13("div", { ref: chart, id: chartId, className: "mbc-chart", role: "tabpanel", "aria-label": period?.label ?? "Balance data", onPointerLeave: () => setActive(null), children: [
|
|
4354
|
+
period?.points.map((point, index) => /* @__PURE__ */ jsxs13("button", { type: "button", className: "mbc-column", "aria-label": `${point.label}: ${money2.format(point.value)}`, "aria-describedby": active === index ? tipId : void 0, onFocus: () => setActive(index), onBlur: () => setActive(null), onPointerEnter: () => setActive(index), onClick: () => setActive(index), "data-current": index === period.points.length - 1, children: [
|
|
4355
|
+
/* @__PURE__ */ jsx13("span", { className: "mbc-track", "data-signed": signed, children: /* @__PURE__ */ jsx13("span", { className: "mbc-bar", style: { height: `${Math.max(4, Math.round(Math.abs(point.value) / max * (signed ? 56 : 72)))}px`, ...signed ? point.value < 0 ? { top: "50%", bottom: "auto", borderRadius: "0 0 2px 2px" } : { bottom: "50%" } : {} } }) }),
|
|
4356
|
+
/* @__PURE__ */ jsx13(SoftText, { className: "mbc-axis", text: point.label })
|
|
4357
|
+
] }, index)),
|
|
4358
|
+
/* @__PURE__ */ jsx13("div", { ref: tooltip, id: tipId, role: "tooltip", className: "mbc-tooltip", "data-show": "false", "aria-hidden": "true", children: /* @__PURE__ */ jsx13("span", { ref: tooltipText, children: lastTooltip.current }) })
|
|
4214
4359
|
] }),
|
|
4215
|
-
/* @__PURE__ */
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4360
|
+
/* @__PURE__ */ jsxs13("div", { ref: tabs, className: "mbc-periods", role: "tablist", "aria-label": "Chart period", children: [
|
|
4361
|
+
/* @__PURE__ */ jsx13("span", { ref: pill, className: "mbc-period-pill", "aria-hidden": "true" }),
|
|
4362
|
+
periods.map((item, index) => /* @__PURE__ */ jsx13("button", { type: "button", role: "tab", "aria-selected": period?.id === item.id, "aria-controls": chartId, tabIndex: period?.id === item.id ? 0 : -1, onClick: () => selectPeriod(item), onKeyDown: (event) => {
|
|
4363
|
+
const next = event.key === "ArrowRight" ? (index + 1) % periods.length : event.key === "ArrowLeft" ? (index - 1 + periods.length) % periods.length : event.key === "Home" ? 0 : event.key === "End" ? periods.length - 1 : -1;
|
|
4364
|
+
if (next < 0) return;
|
|
4365
|
+
event.preventDefault();
|
|
4366
|
+
selectPeriod(periods[next]);
|
|
4367
|
+
tabs.current?.querySelectorAll("[role=tab]")[next]?.focus();
|
|
4368
|
+
}, children: item.label }, item.id))
|
|
4369
|
+
] })
|
|
4220
4370
|
] });
|
|
4221
4371
|
}
|
|
4222
4372
|
var css = `
|
|
4223
|
-
.mova-balance{--mbc-bg:#fff;--mbc-fg:#
|
|
4373
|
+
.mova-balance{--mbc-bg:#fff;--mbc-fg:#0d0d0d;--mbc-muted:#6c6c6c;--mbc-bar:rgba(28,95,251,.14);--mbc-bar-hover:rgba(28,95,251,.26);--mbc-bar-current:#1c5ffb;--mbc-chip:rgba(0,0,0,.04);--mbc-pill:#fff;--mbc-tip-bg:#fff;--mbc-tip-fg:#2f2f2f;--mbc-fill:#e7f9f3;--mbc-ink:#216e55;--mbc-ease:cubic-bezier(.22,1,.36,1);--mbc-press-dur:150ms;--mbc-chart-dur:400ms;--mbc-text-dur:200ms;--mbc-text-resize-dur:240ms;--mbc-tabs-dur:250ms;box-sizing:border-box;width:300px;max-width:100%;padding:24px;border-radius:24px;background:var(--mbc-bg);color:var(--mbc-fg);font:400 13px/20px 'Inter Variable',Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;letter-spacing:0;-webkit-font-smoothing:antialiased;box-shadow:0 0 0 1px #0000000a,0 8px 32px -4px #0000000f,0 1px 3px #0000000a}
|
|
4374
|
+
.mova-balance[data-theme=dark]{--mbc-bg:#1d1d1d;--mbc-fg:#f2f2f2;--mbc-muted:rgba(202,202,202,.7);--mbc-bar:rgba(92,140,255,.22);--mbc-bar-hover:rgba(92,140,255,.36);--mbc-bar-current:#5c8cff;--mbc-chip:rgba(255,255,255,.07);--mbc-pill:rgba(255,255,255,.12);--mbc-tip-bg:#262626;--mbc-tip-fg:#f2f2f2;--mbc-fill:#12291f;--mbc-ink:#6fd3a8;color-scheme:dark;box-shadow:0 0 0 1px #ffffff0f,0 8px 32px -4px #0000004d,0 1px 3px #0003}
|
|
4375
|
+
.mova-balance *{box-sizing:border-box}.mova-balance button{font:inherit;letter-spacing:inherit;margin:0;border:0;padding:0;background:none;color:inherit;-webkit-tap-highlight-color:transparent;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;transition:transform var(--mbc-press-dur) var(--mbc-ease)}.mova-balance button:is(:active,[data-pressed=true]){transform:scale(.97)}.mova-balance button:focus{outline:none}.mova-balance button:focus-visible{box-shadow:0 0 0 2px var(--mbc-bg),0 0 0 4px var(--mbc-fg)}
|
|
4376
|
+
.mbc-label{font-size:13px;line-height:20px;color:var(--mbc-muted)}.mbc-summary{margin-top:16px;font-size:28px;line-height:34px;font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap}.mbc-cents{color:var(--mbc-muted)}.mbc-change-row{margin-top:8px;display:flex;align-items:center;gap:8px;font-size:12px;line-height:16px;color:var(--mbc-muted);min-width:0}.mbc-detail{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}.mbc-change{flex:none;display:inline-flex;align-items:center;height:18px;padding:0 6px;border-radius:50px;font-size:11px;line-height:16px;font-weight:500;background:var(--mbc-fill);color:var(--mbc-ink);font-variant-numeric:tabular-nums;box-shadow:0 1px 3px #0000000a,inset 0 0 0 1px color-mix(in srgb,var(--mbc-ink) 14%,transparent),inset 0 -1px 0 color-mix(in srgb,var(--mbc-ink) 10%,transparent)}.mbc-change[data-negative=true]{--mbc-fill:#fbe9e9;--mbc-ink:#ad3c3c}.mova-balance[data-theme=dark] .mbc-change[data-negative=true]{--mbc-fill:#4c2b2b;--mbc-ink:#ffaaaa}
|
|
4377
|
+
.mbc-soft{display:inline-grid;justify-items:var(--mbc-text-align,start);transition:width var(--mbc-text-resize-dur) var(--mbc-ease)}.mbc-soft>span{grid-area:1/1;white-space:pre;transition:filter var(--mbc-text-dur) ease-in-out,opacity var(--mbc-text-dur) ease-in-out}.mbc-soft-new{opacity:0;filter:blur(2px)}.mbc-soft.is-swapping .mbc-soft-old{opacity:0;filter:blur(2px)}.mbc-soft.is-swapping .mbc-soft-new{opacity:1;filter:blur(0)}
|
|
4378
|
+
.mbc-chart{display:flex;position:relative;width:100%;gap:4px;margin-top:16px}.mova-balance .mbc-column{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:8px;padding-bottom:4px;border-radius:8px;cursor:default}.mbc-track{position:relative;height:112px;width:100%;display:flex;align-items:flex-end;justify-content:center}.mbc-track[data-signed=true]:after{content:"";position:absolute;top:50%;left:0;right:0;height:1px;background:#8885}.mbc-track[data-signed=true] .mbc-bar{position:absolute}.mbc-bar{display:block;width:100%;max-width:24px;border-radius:2px 2px 0 0;background:var(--mbc-bar);transition:height var(--mbc-chart-dur) var(--mbc-ease),background-color 150ms var(--mbc-ease)}.mbc-column:focus-visible .mbc-bar{background:var(--mbc-bar-hover)}@media(hover:hover) and (pointer:fine){.mbc-column:hover .mbc-bar{background:var(--mbc-bar-hover)}.mbc-periods button:not([aria-selected=true]):hover{color:var(--mbc-fg)}}.mbc-column[data-current=true] .mbc-bar{background:var(--mbc-bar-current)}.mbc-axis{font-size:12px;line-height:16px;color:var(--mbc-muted);--mbc-text-align:center}.mbc-column[data-current=true] .mbc-axis{color:var(--mbc-fg)}
|
|
4379
|
+
.mbc-tooltip{position:absolute;top:0;left:0;z-index:2;display:inline-flex;align-items:center;justify-content:center;width:0;max-width:100%;overflow:hidden;translate:var(--mbc-tip-x,0px) 0;scale:.98;transform-origin:50% 100%;padding:8px 12px;border-radius:8px;background:var(--mbc-tip-bg);color:var(--mbc-tip-fg);white-space:nowrap;box-shadow:0 0 0 1px #0000000f,0 2px 6px #0000000d,0 4px 42px #0000000f;opacity:0;pointer-events:none;font-size:12px;line-height:16px;font-variant-numeric:tabular-nums;transition:opacity 50ms ease-out,scale 50ms ease-out,translate 160ms var(--mbc-ease),width 160ms var(--mbc-ease)}.mbc-tooltip[data-show=true]{opacity:1;scale:1;transition:opacity 150ms ease-out 80ms,scale 150ms ease-out 80ms,translate 160ms var(--mbc-ease),width 160ms var(--mbc-ease)}.mova-balance[data-theme=dark] .mbc-tooltip{box-shadow:0 1px 3px #0000000a,inset 0 1px #ffffff0a,inset 0 0 0 1px #c4c4c414}
|
|
4380
|
+
.mbc-periods{position:relative;display:flex;align-items:center;width:100%;gap:3px;background:var(--mbc-chip);padding:3px;border-radius:48px;margin-top:16px}.mova-balance .mbc-periods button{position:relative;flex:1;min-width:0;height:30px;padding:4px 12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:48px;font-size:13px;line-height:20px;font-weight:500;color:var(--mbc-muted);cursor:pointer;z-index:1;transition:color var(--mbc-tabs-dur) var(--mbc-ease),transform var(--mbc-press-dur) var(--mbc-ease)}.mbc-periods button[aria-selected=true]{color:var(--mbc-fg)}.mbc-period-pill{position:absolute;top:3px;left:0;height:30px;width:0;background:var(--mbc-pill);border-radius:48px;box-shadow:0 1px 3px #00000014,0 0 0 1px #0000000a;transform:translateX(0);transition:transform var(--mbc-tabs-dur) var(--mbc-ease),width var(--mbc-tabs-dur) var(--mbc-ease);will-change:transform,width;z-index:0;pointer-events:none}
|
|
4381
|
+
@media(prefers-reduced-motion:reduce){.mova-balance *{animation:none!important;transition:none!important}.mova-balance button:is(:active,[data-pressed=true]){transform:none}}
|
|
4224
4382
|
`;
|
|
4225
4383
|
|
|
4226
4384
|
// .generated/ui/cards/calendar-day-card.tsx
|
|
4227
4385
|
import * as React2 from "react";
|
|
4228
|
-
import {
|
|
4229
|
-
|
|
4230
|
-
var
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4386
|
+
import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4387
|
+
var portrait = (name, photo) => ({ name, image: `https://images.unsplash.com/${photo}?auto=format&fit=crop&q=80&w=48&h=48` });
|
|
4388
|
+
var people = {
|
|
4389
|
+
leo: portrait("Leo Park", "photo-1500648767791-00dcc994a43e"),
|
|
4390
|
+
maya: portrait("Maya Chen", "photo-1534528741775-53994a69daeb"),
|
|
4391
|
+
tom: portrait("Tom Hale", "photo-1506794778202-cad84cf45f1d"),
|
|
4392
|
+
ana: portrait("Ana Ruiz", "photo-1438761681033-6461ffad8d80"),
|
|
4393
|
+
jade: portrait("Jade Wu", "photo-1580489944761-15a19d654956"),
|
|
4394
|
+
priya: portrait("Priya Nair", "photo-1544005313-94ddf0286df2"),
|
|
4395
|
+
sam: portrait("Sam Okafor", "photo-1570158268183-d296b2892211"),
|
|
4396
|
+
nina: portrait("Nina Brooks", "photo-1632765854612-9b02b6ec2b15")
|
|
4397
|
+
};
|
|
4398
|
+
var defaultDays = [
|
|
4399
|
+
{ id: "11", weekday: "Monday", day: 11, dateLabel: "March 11", events: [
|
|
4400
|
+
{ id: "0-0", title: "Weekly planning", time: "9:30 \u2013 10:15", location: "Room 2", color: "#1C5FFB" },
|
|
4401
|
+
{ id: "0-1", title: "Design critique", time: "14:00 \u2013 15:00", location: "Studio", color: "#B01CFB", attendees: [people.maya, people.sam] }
|
|
4402
|
+
] },
|
|
4403
|
+
{ id: "12", weekday: "Tuesday", day: 12, dateLabel: "March 12", events: [
|
|
4404
|
+
{ id: "1-0", title: "Roadmap review", time: "10:00 \u2013 11:00", location: "Zoom", color: "#EF8121", attendees: [people.leo, people.ana, people.nina] },
|
|
4405
|
+
{ id: "1-1", title: "Lunch with Priya", time: "13:30 \u2013 14:30", location: "Caf\xE9", color: "#1EBB26", attendees: [people.priya] },
|
|
4406
|
+
{ id: "1-2", title: "Hiring sync", time: "16:00 \u2013 16:30", location: "Room 4", color: "#1C5FFB" }
|
|
4407
|
+
] },
|
|
4408
|
+
{ id: "13", weekday: "Wednesday", day: 13, dateLabel: "March 13", events: [
|
|
4409
|
+
{ id: "2-0", title: "Customer call", time: "11:00 \u2013 11:30", location: "Zoom", color: "#EC4A4A", attendees: [people.tom, people.jade] },
|
|
4410
|
+
{ id: "2-1", title: "Sprint demo", time: "15:00 \u2013 16:00", location: "Studio", color: "#B01CFB" }
|
|
4411
|
+
] },
|
|
4412
|
+
{ id: "14", weekday: "Thursday", day: 14, dateLabel: "March 14", events: [
|
|
4413
|
+
{ id: "3-0", title: "Standup", time: "9:00 \u2013 9:15", location: "Zoom", color: "#1C5FFB" },
|
|
4414
|
+
{ id: "3-1", title: "Product review", time: "11:30 \u2013 12:30", location: "Room 2", color: "#B01CFB", attendees: [people.jade, people.leo, people.tom] },
|
|
4415
|
+
{ id: "3-2", title: "1:1 with Maya", time: "16:00 \u2013 16:30", location: "Caf\xE9", color: "#1EBB26", attendees: [people.maya] }
|
|
4416
|
+
] },
|
|
4417
|
+
{ id: "15", weekday: "Friday", day: 15, dateLabel: "March 15", events: [
|
|
4418
|
+
{ id: "4-0", title: "Retro", time: "10:00 \u2013 10:45", location: "Studio", color: "#EF8121", attendees: [people.ana, people.sam, people.nina] },
|
|
4419
|
+
{ id: "4-1", title: "Team drinks", time: "15:30 \u2013 16:30", location: "Rooftop", color: "#1EBB26" }
|
|
4420
|
+
] }
|
|
4421
|
+
];
|
|
4422
|
+
function SoftText2({ text, className = "" }) {
|
|
4423
|
+
const root = React2.useRef(null);
|
|
4424
|
+
const incoming = React2.useRef(null);
|
|
4425
|
+
const last = React2.useRef(text);
|
|
4426
|
+
const [content, setContent] = React2.useState({ old: "", next: text });
|
|
4427
|
+
const [swapping, setSwapping] = React2.useState(false);
|
|
4428
|
+
const [width, setWidth] = React2.useState();
|
|
4429
|
+
React2.useLayoutEffect(() => {
|
|
4430
|
+
if (last.current === text) return;
|
|
4431
|
+
const old = last.current;
|
|
4432
|
+
last.current = text;
|
|
4433
|
+
setWidth(root.current?.getBoundingClientRect().width);
|
|
4434
|
+
setSwapping(false);
|
|
4435
|
+
setContent({ old, next: text });
|
|
4436
|
+
const frame = requestAnimationFrame(() => {
|
|
4437
|
+
setWidth(incoming.current?.getBoundingClientRect().width);
|
|
4438
|
+
setSwapping(true);
|
|
4439
|
+
});
|
|
4440
|
+
const timer = setTimeout(() => {
|
|
4441
|
+
setContent({ old: "", next: text });
|
|
4442
|
+
setWidth(void 0);
|
|
4443
|
+
setSwapping(false);
|
|
4444
|
+
}, 280);
|
|
4445
|
+
return () => {
|
|
4446
|
+
cancelAnimationFrame(frame);
|
|
4447
|
+
clearTimeout(timer);
|
|
4448
|
+
};
|
|
4449
|
+
}, [text]);
|
|
4450
|
+
return /* @__PURE__ */ jsxs14("span", { ref: root, className: `mcd-soft ${className}`, "data-swapping": swapping, "data-changing": !!content.old, style: { width }, children: [
|
|
4451
|
+
content.old && /* @__PURE__ */ jsx14("span", { className: "mcd-soft-old", "aria-hidden": "true", children: content.old }),
|
|
4452
|
+
/* @__PURE__ */ jsx14("span", { ref: incoming, className: "mcd-soft-new", children: content.next })
|
|
4453
|
+
] });
|
|
4454
|
+
}
|
|
4455
|
+
function Attendees({ people: attendees }) {
|
|
4456
|
+
const [active, setActive] = React2.useState(null);
|
|
4457
|
+
const [returning, setReturning] = React2.useState(false);
|
|
4458
|
+
const shift = (index) => active === null ? 0 : -4 * Math.pow(0.45, Math.abs(index - active));
|
|
4459
|
+
function activate(index) {
|
|
4460
|
+
setReturning(false);
|
|
4461
|
+
setActive(index);
|
|
4462
|
+
}
|
|
4463
|
+
function reset() {
|
|
4464
|
+
setReturning(true);
|
|
4465
|
+
setActive(null);
|
|
4466
|
+
}
|
|
4467
|
+
return /* @__PURE__ */ jsx14("div", { className: "mcd-attendees", role: "group", "aria-label": `Attendees: ${attendees.map((person) => person.name).join(", ")}`, onMouseLeave: reset, children: attendees.map((person, index) => /* @__PURE__ */ jsx14("span", { className: "mcd-avatar", role: "img", "aria-label": person.name, tabIndex: 0, onMouseEnter: () => activate(index), onFocus: () => activate(index), onBlur: reset, "data-returning": returning, style: { "--mcd-shift": `${shift(index)}px`, "--mcd-scale": active === index ? 1.05 : 1, "--mcd-cut-dy": `${index < attendees.length - 1 ? shift(index + 1) - shift(index) : 0}px`, "--mcd-avatar-color": person.color ?? "#c6b7d8" }, children: person.image ? /* @__PURE__ */ jsx14("img", { src: person.image, alt: "", width: 24, height: 24 }) : /* @__PURE__ */ jsx14("span", { className: "mcd-initials", "aria-hidden": "true", children: person.name.split(/\s+/).map((part) => part[0]).slice(0, 2).join("") }) }, `${person.name}-${index}`)) });
|
|
4468
|
+
}
|
|
4234
4469
|
function CalendarDayCard({ days = defaultDays, defaultSelectedDay = "14", onDayChange, onEventClick, theme = "light", className = "", style } = {}) {
|
|
4235
4470
|
const [selected, setSelected] = React2.useState(defaultSelectedDay);
|
|
4236
4471
|
const currentIndex = Math.max(0, days.findIndex((day) => day.id === selected));
|
|
4237
4472
|
const current = days[currentIndex];
|
|
4238
|
-
const
|
|
4239
|
-
|
|
4473
|
+
const id = React2.useId();
|
|
4474
|
+
const tabs = React2.useRef([]);
|
|
4475
|
+
const dayStrip = React2.useRef(null);
|
|
4476
|
+
const measured = React2.useRef(false);
|
|
4477
|
+
const [pill, setPill] = React2.useState({ left: 0, width: 0, animate: false });
|
|
4478
|
+
React2.useLayoutEffect(() => {
|
|
4479
|
+
const tab = tabs.current[currentIndex];
|
|
4480
|
+
if (tab) setPill({ left: tab.offsetLeft, width: tab.offsetWidth, animate: measured.current });
|
|
4481
|
+
measured.current = true;
|
|
4482
|
+
}, [currentIndex, days]);
|
|
4483
|
+
React2.useLayoutEffect(() => {
|
|
4484
|
+
const measure = () => {
|
|
4485
|
+
const tab = dayStrip.current?.querySelector('[aria-selected="true"]');
|
|
4486
|
+
if (tab) setPill({ left: tab.offsetLeft, width: tab.offsetWidth, animate: false });
|
|
4487
|
+
};
|
|
4488
|
+
const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(measure);
|
|
4489
|
+
if (dayStrip.current) observer?.observe(dayStrip.current);
|
|
4490
|
+
return () => observer?.disconnect();
|
|
4491
|
+
}, [days.length]);
|
|
4492
|
+
const [pressedDay, setPressedDay] = React2.useState(null);
|
|
4493
|
+
const pressStart = React2.useRef(0);
|
|
4494
|
+
const pressTimer = React2.useRef(void 0);
|
|
4495
|
+
React2.useEffect(() => () => clearTimeout(pressTimer.current), []);
|
|
4496
|
+
function startPress(event, index) {
|
|
4497
|
+
if (event.pointerType === "mouse") return;
|
|
4498
|
+
clearTimeout(pressTimer.current);
|
|
4499
|
+
pressStart.current = performance.now();
|
|
4500
|
+
setPressedDay(index);
|
|
4501
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
4502
|
+
}
|
|
4503
|
+
function endPress() {
|
|
4504
|
+
pressTimer.current = setTimeout(() => setPressedDay(null), Math.max(0, 150 - (performance.now() - pressStart.current)));
|
|
4505
|
+
}
|
|
4506
|
+
function select(index, focus = false) {
|
|
4240
4507
|
const day = days[index];
|
|
4241
|
-
if (day)
|
|
4242
|
-
|
|
4243
|
-
|
|
4508
|
+
if (!day) return;
|
|
4509
|
+
if (focus) tabs.current[index]?.focus();
|
|
4510
|
+
if (current?.id === day.id) return;
|
|
4511
|
+
setSelected(day.id);
|
|
4512
|
+
onDayChange?.(day);
|
|
4513
|
+
}
|
|
4514
|
+
function handleKey(event, index) {
|
|
4515
|
+
const next = event.key === "ArrowRight" ? (index + 1) % days.length : event.key === "ArrowLeft" ? (index - 1 + days.length) % days.length : event.key === "Home" ? 0 : event.key === "End" ? days.length - 1 : null;
|
|
4516
|
+
if (next !== null) {
|
|
4517
|
+
event.preventDefault();
|
|
4518
|
+
select(next, true);
|
|
4244
4519
|
}
|
|
4245
4520
|
}
|
|
4246
|
-
return /* @__PURE__ */ jsxs14("section", { className: `mova-calendar ${className}`, "data-theme": theme, style, "aria-label": "Calendar
|
|
4521
|
+
return /* @__PURE__ */ jsxs14("section", { className: `mova-calendar ${className}`, "data-theme": theme, style, "aria-label": "Calendar", children: [
|
|
4247
4522
|
/* @__PURE__ */ jsx14("style", { children: css2 }),
|
|
4248
|
-
/* @__PURE__ */ jsxs14("header", { children: [
|
|
4249
|
-
/* @__PURE__ */
|
|
4250
|
-
|
|
4251
|
-
/* @__PURE__ */ jsx14(
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
/* @__PURE__ */ jsx14("
|
|
4255
|
-
|
|
4256
|
-
] })
|
|
4523
|
+
/* @__PURE__ */ jsxs14("header", { className: "mcd-head", children: [
|
|
4524
|
+
/* @__PURE__ */ jsx14("h2", { children: /* @__PURE__ */ jsx14(SoftText2, { text: current?.weekday ?? "Your calendar" }) }),
|
|
4525
|
+
/* @__PURE__ */ jsx14("p", { className: "mcd-meta", "aria-live": "polite", "aria-atomic": "true", children: current ? /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
4526
|
+
/* @__PURE__ */ jsx14(SoftText2, { text: current.dateLabel }),
|
|
4527
|
+
/* @__PURE__ */ jsx14("span", { children: " \xB7 " }),
|
|
4528
|
+
/* @__PURE__ */ jsx14(SoftText2, { text: String(current.events.length), className: "mcd-number" }),
|
|
4529
|
+
/* @__PURE__ */ jsx14("span", { children: current.events.length === 1 ? " meeting" : " meetings" })
|
|
4530
|
+
] }) : "No days available" })
|
|
4257
4531
|
] }),
|
|
4258
|
-
/* @__PURE__ */
|
|
4259
|
-
/* @__PURE__ */ jsx14("span", {
|
|
4260
|
-
/* @__PURE__ */
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4532
|
+
!!days.length && /* @__PURE__ */ jsxs14("div", { ref: dayStrip, className: "mcd-days", role: "tablist", "aria-label": `Week of ${days[0].dateLabel}`, style: { "--mcd-count": days.length, "--mcd-index": currentIndex }, children: [
|
|
4533
|
+
/* @__PURE__ */ jsx14("span", { className: "mcd-pill", "aria-hidden": "true", style: { width: pill.width, transform: `translateX(${pill.left}px)`, transition: pill.animate ? void 0 : "none" } }),
|
|
4534
|
+
days.map((day, index) => /* @__PURE__ */ jsxs14("button", { type: "button", role: "tab", ref: (element) => {
|
|
4535
|
+
tabs.current[index] = element;
|
|
4536
|
+
}, id: `${id}-tab-${index}`, "aria-selected": current?.id === day.id, "aria-controls": `${id}-panel-${index}`, "aria-label": `${day.weekday}, ${day.dateLabel}`, tabIndex: current?.id === day.id ? 0 : -1, "data-pressed": pressedDay === index, onPointerDown: (event) => startPress(event, index), onPointerUp: endPress, onPointerCancel: endPress, onKeyDown: (event) => handleKey(event, index), onClick: () => select(index), children: [
|
|
4537
|
+
/* @__PURE__ */ jsx14("span", { children: day.weekday.slice(0, 3) }),
|
|
4538
|
+
/* @__PURE__ */ jsx14("strong", { children: day.day })
|
|
4539
|
+
] }, day.id))
|
|
4540
|
+
] }),
|
|
4541
|
+
/* @__PURE__ */ jsxs14("div", { className: "mcd-agenda", children: [
|
|
4542
|
+
days.map((day, index) => /* @__PURE__ */ jsx14("section", { className: "mcd-page", role: "tabpanel", "aria-label": `${day.weekday} meetings`, id: `${id}-panel-${index}`, "aria-labelledby": `${id}-tab-${index}`, "aria-hidden": index !== currentIndex, inert: index !== currentIndex || void 0, "data-active": index === currentIndex, style: { "--mcd-side": index < currentIndex ? "-8px" : "8px" }, children: day.events.length ? /* @__PURE__ */ jsx14("ul", { children: day.events.map((event) => /* @__PURE__ */ jsxs14("li", { className: "mcd-event", style: { "--mcd-event": event.color ?? "#1C5FFB" }, children: [
|
|
4543
|
+
onEventClick ? /* @__PURE__ */ jsxs14("button", { type: "button", className: "mcd-event-main", onClick: () => onEventClick(event), children: [
|
|
4544
|
+
/* @__PURE__ */ jsx14("span", { className: "mcd-event-line", "aria-hidden": "true" }),
|
|
4545
|
+
/* @__PURE__ */ jsxs14("span", { className: "mcd-event-text", children: [
|
|
4546
|
+
/* @__PURE__ */ jsx14("strong", { children: event.title }),
|
|
4547
|
+
/* @__PURE__ */ jsxs14("small", { children: [
|
|
4548
|
+
/* @__PURE__ */ jsx14("span", { children: event.time }),
|
|
4549
|
+
event.location ? ` \xB7 ${event.location}` : ""
|
|
4550
|
+
] })
|
|
4551
|
+
] })
|
|
4552
|
+
] }) : /* @__PURE__ */ jsxs14("div", { className: "mcd-event-main", children: [
|
|
4553
|
+
/* @__PURE__ */ jsx14("span", { className: "mcd-event-line", "aria-hidden": "true" }),
|
|
4554
|
+
/* @__PURE__ */ jsxs14("span", { className: "mcd-event-text", children: [
|
|
4555
|
+
/* @__PURE__ */ jsx14("strong", { children: event.title }),
|
|
4556
|
+
/* @__PURE__ */ jsxs14("small", { children: [
|
|
4557
|
+
/* @__PURE__ */ jsx14("span", { children: event.time }),
|
|
4558
|
+
event.location ? ` \xB7 ${event.location}` : ""
|
|
4559
|
+
] })
|
|
4560
|
+
] })
|
|
4561
|
+
] }),
|
|
4562
|
+
!!event.attendees?.length && /* @__PURE__ */ jsx14(Attendees, { people: event.attendees })
|
|
4563
|
+
] }, event.id)) }) : /* @__PURE__ */ jsx14("p", { className: "mcd-empty", children: "Nothing scheduled. Enjoy your day." }) }, day.id)),
|
|
4564
|
+
!current && /* @__PURE__ */ jsx14("p", { className: "mcd-empty", children: "Nothing scheduled. Enjoy your day." })
|
|
4565
|
+
] })
|
|
4272
4566
|
] });
|
|
4273
4567
|
}
|
|
4274
4568
|
var css2 = `
|
|
4275
|
-
|
|
4569
|
+
@property --mcd-cut-dy{syntax:'<length>';inherits:false;initial-value:0px}
|
|
4570
|
+
.mova-calendar{--mcd-bg:#fff;--mcd-fg:#0d0d0d;--mcd-muted:#6c6c6c;--mcd-track:#0000000a;--mcd-hover:#0000000a;--mcd-pill:#fff;--mcd-tint:7%;--mcd-pill-shadow:0 0 0 1px #0000000f,0 2px 6px #0000000d,0 1px 2px #0000000a;--mcd-ease:cubic-bezier(.22,1,.36,1);width:300px;max-width:100%;box-sizing:border-box;padding:24px;border-radius:24px;color:var(--mcd-fg);background:var(--mcd-bg);font:400 13px/20px "Inter Variable",Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;letter-spacing:0;font-optical-sizing:auto;font-feature-settings:'liga' 1,'calt' 1;-webkit-font-smoothing:antialiased;box-shadow:0 0 0 1px #0000000a,0 8px 32px -4px #0000000f,0 1px 3px #0000000a;display:flex;flex-direction:column;gap:16px}.mova-calendar[data-theme=dark]{--mcd-bg:#1d1d1d;--mcd-fg:#f2f2f2;--mcd-muted:rgba(202,202,202,.7);--mcd-track:#ffffff0a;--mcd-hover:rgba(255,255,255,.065);--mcd-pill:#ffffff1a;--mcd-tint:14%;--mcd-pill-shadow:0 1px 3px #0000003d,inset 0 0 0 1px #ffffff0f,inset 0 1px 0 #ffffff0f;color-scheme:dark}.mova-calendar *{box-sizing:border-box}.mova-calendar h2,.mova-calendar p,.mova-calendar ul{margin:0;padding:0}.mova-calendar button{font:inherit;letter-spacing:inherit;color:inherit;border:0;background:none;padding:0;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none}.mova-calendar button:focus-visible,.mcd-avatar:focus-visible{outline:2px solid var(--mcd-fg);outline-offset:2px}.mcd-head{display:flex;flex-direction:column;gap:4px}.mova-calendar h2{font-size:28px;line-height:34px;font-weight:500}.mcd-meta{display:flex;white-space:pre;font-size:12px;line-height:16px;color:var(--mcd-muted)}.mcd-number,.mcd-event small span{font-variant-numeric:tabular-nums}.mcd-soft{display:inline-grid;justify-items:start;transition:width 240ms var(--mcd-ease)}.mcd-soft>span{grid-area:1/1;white-space:pre;transition:filter 200ms ease-in-out,opacity 200ms ease-in-out}.mcd-soft[data-changing=true] .mcd-soft-new{opacity:0;filter:blur(2px)}.mcd-soft[data-swapping=true] .mcd-soft-old{opacity:0;filter:blur(2px)}.mcd-soft[data-swapping=true] .mcd-soft-new{opacity:1;filter:blur(0)}.mcd-days{position:relative;display:flex;align-items:center;gap:2px;padding:4px;border-radius:16px;background:var(--mcd-track)}.mcd-days button{position:relative;flex:1;min-width:0;height:52px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;border-radius:12px;z-index:1;transition:color 250ms var(--mcd-ease),background-color 250ms var(--mcd-ease),transform 150ms var(--mcd-ease)}.mcd-days button>span{font-size:12px;line-height:16px;color:var(--mcd-muted)}.mcd-days strong{font-size:15px;line-height:20px;font-weight:400;font-variant-numeric:tabular-nums}.mcd-days button:is(:active,[data-pressed=true]){transform:scale(.95)}.mcd-days button:focus-visible{outline:none;box-shadow:0 0 0 2px var(--mcd-bg),0 0 0 4px var(--mcd-fg)}.mcd-pill{position:absolute;top:4px;left:0;height:52px;background:var(--mcd-pill);box-shadow:var(--mcd-pill-shadow);border-radius:12px;transition:transform 250ms var(--mcd-ease),width 250ms var(--mcd-ease);pointer-events:none}.mcd-agenda{display:grid;position:relative}.mcd-page{grid-area:1/1;min-width:0;opacity:0;pointer-events:none;transform:translateX(var(--mcd-side));filter:blur(3px);transition:opacity 250ms var(--mcd-ease),transform 250ms var(--mcd-ease),filter 250ms var(--mcd-ease)}.mcd-page[data-active=true]{opacity:1;pointer-events:auto;transform:translateX(0);filter:blur(0)}.mcd-page ul{list-style:none;display:flex;flex-direction:column;gap:8px}.mcd-event{display:flex;align-items:center;gap:12px;padding:8px 12px 8px 8px;border-radius:12px;background:color-mix(in srgb,var(--mcd-event) var(--mcd-tint),transparent)}.mcd-event-main{flex:1;min-width:0;display:flex;align-self:stretch;align-items:center;gap:12px;text-align:left;border-radius:4px}.mcd-event-line{flex:none;align-self:stretch;width:3px;border-radius:2px;background:var(--mcd-event)}.mcd-event-text{min-width:0;flex:1}.mcd-event strong{display:block;font-size:13px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mcd-event small{display:block;font-size:12px;line-height:16px;color:var(--mcd-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mcd-attendees{display:flex;align-items:center;flex:none;align-self:center}.mcd-avatar{display:flex;flex:none;width:24px;height:24px;border-radius:50%;transform-origin:center;transform:translateY(var(--mcd-shift,0px)) scale(var(--mcd-scale,1));transition:transform 320ms var(--mcd-ease),--mcd-cut-dy 320ms var(--mcd-ease)}.mcd-avatar[data-returning=true]{transition-timing-function:cubic-bezier(.34,3.85,.64,1)}.mcd-avatar+.mcd-avatar{margin-left:-6px}.mcd-avatar:not(:last-child){-webkit-mask:radial-gradient(58.333% 58.333% at 125% calc(50% + var(--mcd-cut-dy)),transparent calc(100% - .5px),#000 calc(100% + .5px));mask:radial-gradient(58.333% 58.333% at 125% calc(50% + var(--mcd-cut-dy)),transparent calc(100% - .5px),#000 calc(100% + .5px))}.mcd-avatar img{display:block;width:24px;height:24px;border-radius:50%;object-fit:cover;outline:1px solid #00000014;outline-offset:-1px}.mova-calendar[data-theme=dark] .mcd-avatar img{outline-color:#ffffff14}.mcd-initials{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;font-size:10px;line-height:1;background:var(--mcd-avatar-color);color:#25212b}.mcd-empty{font-size:12px;color:var(--mcd-muted);padding:8px 0!important;min-height:52px}@media(hover:hover) and (pointer:fine){.mcd-days button:not([aria-selected=true]):hover{background:var(--mcd-hover)}}@media(prefers-reduced-motion:reduce){.mova-calendar *{animation:none!important;transition:none!important}.mcd-days button:is(:active,[data-pressed=true]),.mcd-avatar{transform:none!important}.mcd-page{transform:none;filter:none}}
|
|
4276
4571
|
`;
|
|
4277
4572
|
|
|
4278
4573
|
// .generated/ui/cards/day-trading-order-ticket.tsx
|
|
4279
4574
|
import * as React3 from "react";
|
|
4280
|
-
import { Check as Check2, Minus, Plus as Plus2 } from "lucide-react";
|
|
4281
4575
|
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4576
|
+
var types = [
|
|
4577
|
+
{ id: "market", label: "Market", priceLabel: "", hint: "" },
|
|
4578
|
+
{ id: "limit", label: "Limit", priceLabel: "Limit price", hint: "a limit price" },
|
|
4579
|
+
{ id: "stop", label: "Stop market", priceLabel: "Stop price", hint: "a stop price" },
|
|
4580
|
+
{ id: "trail", label: "Trailing stop", priceLabel: "Trail amount", hint: "a trail amount" }
|
|
4581
|
+
];
|
|
4582
|
+
var money = (value) => new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value);
|
|
4583
|
+
function SwapText({ text }) {
|
|
4584
|
+
const ref = React3.useRef(null);
|
|
4585
|
+
const [shown, setShown] = React3.useState(text);
|
|
4586
|
+
const entering = React3.useRef(false);
|
|
4587
|
+
React3.useEffect(() => {
|
|
4588
|
+
const el = ref.current;
|
|
4589
|
+
if (!el) return;
|
|
4590
|
+
if (text === shown) {
|
|
4591
|
+
el.classList.remove("mot-is-exit");
|
|
4592
|
+
return;
|
|
4593
|
+
}
|
|
4594
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
4595
|
+
setShown(text);
|
|
4596
|
+
return;
|
|
4597
|
+
}
|
|
4598
|
+
el.classList.remove("mot-is-enter-start");
|
|
4599
|
+
el.classList.add("mot-is-exit");
|
|
4600
|
+
const timer = window.setTimeout(() => {
|
|
4601
|
+
entering.current = true;
|
|
4602
|
+
setShown(text);
|
|
4603
|
+
}, 150);
|
|
4604
|
+
return () => window.clearTimeout(timer);
|
|
4605
|
+
}, [text, shown]);
|
|
4606
|
+
React3.useLayoutEffect(() => {
|
|
4607
|
+
if (!entering.current || !ref.current) return;
|
|
4608
|
+
entering.current = false;
|
|
4609
|
+
ref.current.classList.remove("mot-is-exit");
|
|
4610
|
+
ref.current.classList.add("mot-is-enter-start");
|
|
4611
|
+
void ref.current.offsetHeight;
|
|
4612
|
+
ref.current.classList.remove("mot-is-enter-start");
|
|
4613
|
+
}, [shown]);
|
|
4614
|
+
return /* @__PURE__ */ jsx15("span", { ref, className: "mot-t-text-swap", children: shown });
|
|
4615
|
+
}
|
|
4616
|
+
function PopNumber({ value }) {
|
|
4617
|
+
const ref = React3.useRef(null);
|
|
4618
|
+
const previous = React3.useRef(value);
|
|
4619
|
+
const samePrefix = React3.useRef(value.length);
|
|
4620
|
+
if (previous.current !== value) {
|
|
4621
|
+
let same2 = 0;
|
|
4622
|
+
while (same2 < previous.current.length && same2 < value.length && previous.current[same2] === value[same2]) same2++;
|
|
4623
|
+
samePrefix.current = same2;
|
|
4624
|
+
}
|
|
4625
|
+
const same = samePrefix.current;
|
|
4626
|
+
React3.useLayoutEffect(() => {
|
|
4627
|
+
if (previous.current === value || !ref.current) return;
|
|
4628
|
+
previous.current = value;
|
|
4629
|
+
ref.current.classList.remove("mot-is-animating");
|
|
4630
|
+
void ref.current.offsetHeight;
|
|
4631
|
+
ref.current.classList.add("mot-is-animating");
|
|
4632
|
+
}, [value]);
|
|
4633
|
+
return /* @__PURE__ */ jsx15("span", { ref, className: "mot-t-digit-group", "aria-hidden": "true", children: value.split("").map((character, index) => /* @__PURE__ */ jsx15("span", { className: "mot-t-digit", "data-same": index < same ? "" : void 0, "data-stagger": index === value.length - 2 ? "1" : index === value.length - 1 ? "2" : void 0, children: character }, index)) });
|
|
4634
|
+
}
|
|
4635
|
+
function CheckMark({ size = 16 }) {
|
|
4636
|
+
return /* @__PURE__ */ jsx15("svg", { className: "mot-hi", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: size === 24 ? 2 : 3, "aria-hidden": "true", children: /* @__PURE__ */ jsx15("path", { d: "M5.25 12.7033 9.40385 17.37 18.75 6.87" }) });
|
|
4637
|
+
}
|
|
4638
|
+
function useFieldError() {
|
|
4639
|
+
const [error, setError] = React3.useState(false);
|
|
4640
|
+
const [shake, setShake] = React3.useState(0);
|
|
4641
|
+
const timer = React3.useRef(null);
|
|
4642
|
+
const box = React3.useRef(null);
|
|
4643
|
+
React3.useEffect(() => () => {
|
|
4644
|
+
if (timer.current) clearTimeout(timer.current);
|
|
4645
|
+
}, []);
|
|
4646
|
+
React3.useLayoutEffect(() => {
|
|
4647
|
+
if (!error || !box.current) return;
|
|
4648
|
+
box.current.classList.remove("mot-is-shaking");
|
|
4649
|
+
void box.current.offsetWidth;
|
|
4650
|
+
box.current.classList.add("mot-is-shaking");
|
|
4651
|
+
const shakeTimer = setTimeout(() => box.current?.classList.remove("mot-is-shaking"), 300);
|
|
4652
|
+
return () => clearTimeout(shakeTimer);
|
|
4653
|
+
}, [error, shake]);
|
|
4654
|
+
const clear = () => {
|
|
4655
|
+
if (timer.current) clearTimeout(timer.current);
|
|
4656
|
+
setError(false);
|
|
4657
|
+
};
|
|
4658
|
+
const show = () => {
|
|
4659
|
+
if (timer.current) clearTimeout(timer.current);
|
|
4660
|
+
setError(true);
|
|
4661
|
+
setShake((value) => value + 1);
|
|
4662
|
+
timer.current = setTimeout(() => setError(false), 3280);
|
|
4663
|
+
};
|
|
4664
|
+
return { error, box, clear, show };
|
|
4665
|
+
}
|
|
4282
4666
|
function DayTradingOrderTicket({ symbol = "NOVA", company = "Novaline Robotics", quote = 184.2, change = "+1.24%", initialShares = 10, onSubmit, theme = "light", className = "", style } = {}) {
|
|
4283
4667
|
const [side, setSide] = React3.useState("buy");
|
|
4284
4668
|
const [type, setType] = React3.useState("limit");
|
|
4285
|
-
const [shares, setShares] = React3.useState(String(initialShares));
|
|
4669
|
+
const [shares, setShares] = React3.useState(String(Math.min(9999, Math.max(0, Math.trunc(Number.isFinite(initialShares) ? initialShares : 10)))));
|
|
4286
4670
|
const [price, setPrice] = React3.useState(quote.toFixed(2));
|
|
4287
|
-
const [
|
|
4671
|
+
const [menuOpen, setMenuOpen] = React3.useState(false);
|
|
4672
|
+
const [menuClosing, setMenuClosing] = React3.useState(false);
|
|
4288
4673
|
const [busy, setBusy] = React3.useState(false);
|
|
4289
4674
|
const [done, setDone] = React3.useState(null);
|
|
4675
|
+
const [submitError, setSubmitError] = React3.useState("");
|
|
4676
|
+
const sharesError = useFieldError();
|
|
4677
|
+
const priceError = useFieldError();
|
|
4290
4678
|
const guard = React3.useRef(false);
|
|
4291
4679
|
const alive = React3.useRef(true);
|
|
4680
|
+
const placedTimer = React3.useRef(null);
|
|
4681
|
+
const menuTimer = React3.useRef(null);
|
|
4682
|
+
const menu = React3.useRef(null);
|
|
4683
|
+
const typeButton = React3.useRef(null);
|
|
4292
4684
|
const heading = React3.useRef(null);
|
|
4293
4685
|
const shareInput = React3.useRef(null);
|
|
4686
|
+
const priceInput = React3.useRef(null);
|
|
4687
|
+
const newOrderFocus = React3.useRef(false);
|
|
4294
4688
|
const id = React3.useId();
|
|
4295
|
-
const
|
|
4689
|
+
const typeInfo = types.find((item) => item.id === type);
|
|
4690
|
+
const count = parseInt(shares, 10) || 0;
|
|
4691
|
+
const numericPrice = parseFloat(price);
|
|
4692
|
+
const effectivePrice = type === "limit" || type === "stop" ? numericPrice : quote;
|
|
4693
|
+
const total = count > 0 && Number.isFinite(effectivePrice) && effectivePrice > 0 ? count * effectivePrice : 0;
|
|
4694
|
+
const totalText = money(total);
|
|
4695
|
+
const description = (draft) => draft.type === "market" ? "at market" : draft.type === "limit" ? `at ${money(draft.price)}` : draft.type === "stop" ? `stop ${money(draft.price)}` : `trailing ${money(draft.trailAmount ?? 0)}`;
|
|
4296
4696
|
React3.useEffect(() => {
|
|
4297
4697
|
alive.current = true;
|
|
4298
4698
|
return () => {
|
|
4299
4699
|
alive.current = false;
|
|
4700
|
+
if (placedTimer.current) clearTimeout(placedTimer.current);
|
|
4701
|
+
if (menuTimer.current) clearTimeout(menuTimer.current);
|
|
4300
4702
|
};
|
|
4301
4703
|
}, []);
|
|
4302
4704
|
React3.useEffect(() => {
|
|
4303
4705
|
if (done) heading.current?.focus();
|
|
4304
|
-
else if (
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
}
|
|
4308
|
-
}, [done]);
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4706
|
+
else if (newOrderFocus.current) {
|
|
4707
|
+
newOrderFocus.current = false;
|
|
4708
|
+
(type === "market" ? typeButton : shareInput).current?.focus();
|
|
4709
|
+
}
|
|
4710
|
+
}, [done, type]);
|
|
4711
|
+
function closeMenu(focus = false) {
|
|
4712
|
+
setMenuOpen(false);
|
|
4713
|
+
setMenuClosing(true);
|
|
4714
|
+
if (menuTimer.current) clearTimeout(menuTimer.current);
|
|
4715
|
+
menuTimer.current = setTimeout(() => setMenuClosing(false), 150);
|
|
4716
|
+
if (focus) typeButton.current?.focus();
|
|
4717
|
+
}
|
|
4718
|
+
React3.useEffect(() => {
|
|
4719
|
+
if (!menuOpen) return;
|
|
4720
|
+
const onDown = (event) => {
|
|
4721
|
+
if (!menu.current?.contains(event.target)) closeMenu();
|
|
4722
|
+
};
|
|
4723
|
+
const onKey = (event) => {
|
|
4724
|
+
if (event.key === "Escape") {
|
|
4725
|
+
event.preventDefault();
|
|
4726
|
+
closeMenu(true);
|
|
4727
|
+
}
|
|
4728
|
+
};
|
|
4729
|
+
document.addEventListener("pointerdown", onDown);
|
|
4730
|
+
document.addEventListener("keydown", onKey);
|
|
4731
|
+
return () => {
|
|
4732
|
+
document.removeEventListener("pointerdown", onDown);
|
|
4733
|
+
document.removeEventListener("keydown", onKey);
|
|
4734
|
+
};
|
|
4735
|
+
}, [menuOpen]);
|
|
4736
|
+
function openMenu(focusIndex) {
|
|
4737
|
+
if (menuTimer.current) clearTimeout(menuTimer.current);
|
|
4738
|
+
setMenuClosing(false);
|
|
4739
|
+
setMenuOpen(true);
|
|
4740
|
+
if (focusIndex !== void 0) requestAnimationFrame(() => menu.current?.querySelectorAll('[role="menuitemradio"]')[focusIndex]?.focus());
|
|
4741
|
+
}
|
|
4742
|
+
function selectType(value) {
|
|
4743
|
+
if (value === "trail" !== (type === "trail")) setPrice(value === "trail" ? "1.50" : quote.toFixed(2));
|
|
4744
|
+
priceError.clear();
|
|
4745
|
+
sharesError.clear();
|
|
4746
|
+
setSubmitError("");
|
|
4747
|
+
setType(value);
|
|
4748
|
+
closeMenu(true);
|
|
4749
|
+
}
|
|
4750
|
+
const updateShares = (value) => {
|
|
4751
|
+
setShares(value);
|
|
4752
|
+
sharesError.clear();
|
|
4753
|
+
setSubmitError("");
|
|
4754
|
+
};
|
|
4313
4755
|
async function submit(event) {
|
|
4314
4756
|
event.preventDefault();
|
|
4315
|
-
if (guard.current) return;
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4757
|
+
if (guard.current || done) return;
|
|
4758
|
+
const invalidShares = count < 1 || count > 9999;
|
|
4759
|
+
const invalidPrice = type !== "market" && !(Number.isFinite(numericPrice) && numericPrice > 0);
|
|
4760
|
+
if (invalidShares) sharesError.show();
|
|
4761
|
+
if (invalidPrice) priceError.show();
|
|
4762
|
+
if (invalidShares || invalidPrice) {
|
|
4763
|
+
if (type === "market") typeButton.current?.focus();
|
|
4764
|
+
else (invalidShares ? shareInput : priceInput).current?.focus();
|
|
4319
4765
|
return;
|
|
4320
4766
|
}
|
|
4321
4767
|
if (!Number.isFinite(effectivePrice) || effectivePrice <= 0) {
|
|
4322
|
-
|
|
4768
|
+
setSubmitError("The quote must be greater than zero.");
|
|
4323
4769
|
return;
|
|
4324
4770
|
}
|
|
4325
|
-
const draft = { symbol, side, type, shares: count, price: effectivePrice, estimatedTotal: total };
|
|
4771
|
+
const draft = { symbol, side, type, shares: count, price: effectivePrice, estimatedTotal: total, ...type === "trail" ? { trailAmount: numericPrice } : {} };
|
|
4326
4772
|
guard.current = true;
|
|
4327
4773
|
setBusy(true);
|
|
4328
|
-
|
|
4774
|
+
setSubmitError("");
|
|
4775
|
+
closeMenu();
|
|
4329
4776
|
try {
|
|
4330
|
-
await onSubmit?.(draft)
|
|
4777
|
+
await Promise.all([onSubmit?.(draft), new Promise((resolve) => {
|
|
4778
|
+
placedTimer.current = setTimeout(() => {
|
|
4779
|
+
placedTimer.current = null;
|
|
4780
|
+
resolve();
|
|
4781
|
+
}, 1800);
|
|
4782
|
+
})]);
|
|
4331
4783
|
if (alive.current) setDone(draft);
|
|
4332
4784
|
} catch {
|
|
4333
|
-
if (
|
|
4785
|
+
if (placedTimer.current) {
|
|
4786
|
+
clearTimeout(placedTimer.current);
|
|
4787
|
+
placedTimer.current = null;
|
|
4788
|
+
}
|
|
4789
|
+
if (alive.current) setSubmitError("The order could not be submitted. Please try again.");
|
|
4334
4790
|
} finally {
|
|
4335
4791
|
guard.current = false;
|
|
4336
4792
|
if (alive.current) setBusy(false);
|
|
@@ -4338,94 +4794,604 @@ function DayTradingOrderTicket({ symbol = "NOVA", company = "Novaline Robotics",
|
|
|
4338
4794
|
}
|
|
4339
4795
|
return /* @__PURE__ */ jsxs15("section", { className: `mova-order ${className}`, "data-theme": theme, style, "aria-label": "Trading order ticket", children: [
|
|
4340
4796
|
/* @__PURE__ */ jsx15("style", { children: css3 }),
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
/* @__PURE__ */
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
] }),
|
|
4354
|
-
/* @__PURE__ */ jsxs15("div", { className: "mot-total", children: [
|
|
4355
|
-
/* @__PURE__ */ jsx15("span", { children: "Est. total" }),
|
|
4356
|
-
/* @__PURE__ */ jsx15("strong", { children: money(done.estimatedTotal) })
|
|
4357
|
-
] }),
|
|
4358
|
-
/* @__PURE__ */ jsx15("button", { type: "button", className: "mot-submit", onClick: () => {
|
|
4359
|
-
refocus.current = true;
|
|
4360
|
-
setDone(null);
|
|
4361
|
-
}, children: "New order" })
|
|
4362
|
-
] }) : /* @__PURE__ */ jsxs15("form", { onSubmit: (event) => void submit(event), noValidate: true, children: [
|
|
4363
|
-
/* @__PURE__ */ jsxs15("header", { children: [
|
|
4364
|
-
/* @__PURE__ */ jsxs15("div", { children: [
|
|
4365
|
-
/* @__PURE__ */ jsx15("h2", { children: symbol }),
|
|
4366
|
-
/* @__PURE__ */ jsx15("p", { children: company })
|
|
4797
|
+
!onSubmit && /* @__PURE__ */ jsx15("p", { className: "mot-sr-only", children: "Interactive preview \xB7 no real order" }),
|
|
4798
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-t-page-slide", "data-page": done ? 2 : 1, children: [
|
|
4799
|
+
/* @__PURE__ */ jsxs15("form", { className: "mot-t-page mot-page-form", "data-page-id": "1", onSubmit: (event) => void submit(event), noValidate: true, inert: !!done, "aria-hidden": done ? true : void 0, children: [
|
|
4800
|
+
/* @__PURE__ */ jsxs15("header", { className: "mot-head", children: [
|
|
4801
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-head-main", children: [
|
|
4802
|
+
/* @__PURE__ */ jsx15("h2", { className: "mot-ticker", children: symbol }),
|
|
4803
|
+
/* @__PURE__ */ jsx15("p", { className: "mot-company", children: company })
|
|
4804
|
+
] }),
|
|
4805
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-quote", children: [
|
|
4806
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-quote-price", children: money(quote) }),
|
|
4807
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-badge", "data-negative": change.trim().startsWith("-"), children: change })
|
|
4808
|
+
] })
|
|
4367
4809
|
] }),
|
|
4368
|
-
/* @__PURE__ */ jsxs15("div", { className: "mot-
|
|
4369
|
-
/* @__PURE__ */ jsx15("span", {
|
|
4370
|
-
/* @__PURE__ */ jsx15("
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
/* @__PURE__ */
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4810
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-t-tabs", role: "tablist", "aria-label": "Order side", children: [
|
|
4811
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-t-tabs-pill", "aria-hidden": "true", style: { transform: `translateX(${side === "buy" ? "3px" : "calc(100% + 6px)"})` } }),
|
|
4812
|
+
["buy", "sell"].map((value, index) => /* @__PURE__ */ jsx15("button", { type: "button", role: "tab", className: "mot-t-tab", "aria-selected": value === side, tabIndex: value === side ? 0 : -1, disabled: busy, onClick: () => setSide(value), onKeyDown: (event) => {
|
|
4813
|
+
if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
|
|
4814
|
+
event.preventDefault();
|
|
4815
|
+
const next = event.key === "Home" ? "buy" : event.key === "End" ? "sell" : index === 0 ? "sell" : "buy";
|
|
4816
|
+
setSide(next);
|
|
4817
|
+
event.currentTarget.parentElement?.querySelectorAll('[role="tab"]')[next === "buy" ? 0 : 1]?.focus();
|
|
4818
|
+
}
|
|
4819
|
+
}, children: value === "buy" ? "Buy" : "Sell" }, value))
|
|
4820
|
+
] }),
|
|
4821
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-fields", children: [
|
|
4822
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-field", children: [
|
|
4823
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-field-label", id: `${id}-type-label`, children: "Order type" }),
|
|
4824
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-type-anchor", ref: menu, children: [
|
|
4825
|
+
/* @__PURE__ */ jsxs15("button", { type: "button", ref: typeButton, className: "mot-box mot-type-btn mot-t-input", "aria-haspopup": "menu", "aria-expanded": menuOpen, "aria-controls": `${id}-types`, "aria-labelledby": `${id}-type-label ${id}-type-value`, disabled: busy, onClick: () => menuOpen ? closeMenu() : openMenu(), onKeyDown: (event) => {
|
|
4826
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
4827
|
+
event.preventDefault();
|
|
4828
|
+
openMenu(event.key === "ArrowDown" ? 0 : types.length - 1);
|
|
4829
|
+
}
|
|
4830
|
+
}, children: [
|
|
4831
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-type-btn-label", id: `${id}-type-value`, children: /* @__PURE__ */ jsx15(SwapText, { text: typeInfo.label }) }),
|
|
4832
|
+
/* @__PURE__ */ jsx15("svg", { className: "mot-hi", width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx15("path", { d: "M4.46967 6.46967C4.76256 6.17678 5.23744 6.17678 5.53033 6.46967L8 8.93934L10.4697 6.46967C10.7626 6.17678 11.2374 6.17678 11.5303 6.46967C11.8232 6.76256 11.8232 7.23744 11.5303 7.53033L8.53033 10.5303C8.23744 10.8232 7.76256 10.8232 7.46967 10.5303L4.46967 7.53033C4.17678 7.23744 4.17678 6.76256 4.46967 6.46967Z" }) })
|
|
4833
|
+
] }),
|
|
4834
|
+
/* @__PURE__ */ jsx15("div", { id: `${id}-types`, className: `mot-t-dropdown${menuOpen ? " mot-is-open" : menuClosing ? " mot-is-closing" : ""}`, role: "menu", "aria-label": "Order type", "aria-hidden": !menuOpen, inert: !menuOpen, onKeyDown: (event) => {
|
|
4835
|
+
const items2 = Array.from(event.currentTarget.querySelectorAll('[role="menuitemradio"]'));
|
|
4836
|
+
const current = items2.indexOf(document.activeElement);
|
|
4837
|
+
const next = event.key === "ArrowDown" ? (current + 1) % items2.length : event.key === "ArrowUp" ? (current + items2.length - 1) % items2.length : event.key === "Home" ? 0 : event.key === "End" ? items2.length - 1 : -1;
|
|
4838
|
+
if (next >= 0) {
|
|
4839
|
+
event.preventDefault();
|
|
4840
|
+
items2[next]?.focus();
|
|
4841
|
+
}
|
|
4842
|
+
if (event.key === "Tab") closeMenu();
|
|
4843
|
+
}, children: types.map((item) => /* @__PURE__ */ jsxs15("button", { type: "button", role: "menuitemradio", "aria-checked": item.id === type, className: "mot-menu-item", tabIndex: menuOpen ? 0 : -1, onClick: () => selectType(item.id), children: [
|
|
4844
|
+
/* @__PURE__ */ jsx15("span", { children: item.label }),
|
|
4845
|
+
item.id === type && /* @__PURE__ */ jsx15(CheckMark, {})
|
|
4846
|
+
] }, item.id)) })
|
|
4847
|
+
] })
|
|
4848
|
+
] }),
|
|
4849
|
+
/* @__PURE__ */ jsx15("div", { className: "mot-t-acc", "data-open": type !== "market", "aria-hidden": type === "market", inert: type === "market", children: /* @__PURE__ */ jsx15("div", { className: "mot-t-acc-panel", children: /* @__PURE__ */ jsx15("div", { className: "mot-t-acc-panel-inner", children: /* @__PURE__ */ jsxs15("div", { className: "mot-t-acc-body", children: [
|
|
4850
|
+
/* @__PURE__ */ jsxs15("div", { className: `mot-field mot-t-input-wrap${sharesError.error ? " mot-is-error" : ""}`, children: [
|
|
4851
|
+
/* @__PURE__ */ jsx15("label", { className: "mot-field-label", htmlFor: `${id}-shares`, children: "Shares" }),
|
|
4852
|
+
/* @__PURE__ */ jsxs15("div", { className: `mot-box mot-t-input${sharesError.error ? " mot-is-error" : ""}`, ref: sharesError.box, children: [
|
|
4853
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mot-step", "aria-label": "One share less", disabled: busy, onClick: () => updateShares(String(Math.max(0, count - 1))), children: /* @__PURE__ */ jsx15("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "2.25", "aria-hidden": "true", children: /* @__PURE__ */ jsx15("path", { d: "M5 12h14" }) }) }),
|
|
4854
|
+
/* @__PURE__ */ jsx15("input", { ref: shareInput, id: `${id}-shares`, inputMode: "numeric", value: shares, disabled: busy, "aria-invalid": sharesError.error, "aria-describedby": sharesError.error ? `${id}-shares-error` : void 0, onChange: (event) => updateShares(event.target.value.replace(/\D/g, "").slice(0, 4)) }),
|
|
4855
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mot-step", "aria-label": "One share more", disabled: busy, onClick: () => updateShares(String(Math.min(9999, count + 1))), children: /* @__PURE__ */ jsx15("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "2.25", "aria-hidden": "true", children: /* @__PURE__ */ jsx15("path", { d: "M12 4.5v15m7.5-7.5h-15" }) }) })
|
|
4856
|
+
] }),
|
|
4857
|
+
/* @__PURE__ */ jsx15("p", { className: "mot-t-error-msg", id: `${id}-shares-error`, role: sharesError.error ? "alert" : void 0, children: "Enter at least 1 share" })
|
|
4858
|
+
] }),
|
|
4859
|
+
/* @__PURE__ */ jsxs15("div", { className: `mot-field mot-t-input-wrap${priceError.error ? " mot-is-error" : ""}`, children: [
|
|
4860
|
+
/* @__PURE__ */ jsx15("label", { className: "mot-field-label", htmlFor: `${id}-price`, children: /* @__PURE__ */ jsx15(SwapText, { text: typeInfo.priceLabel || "Limit price" }) }),
|
|
4861
|
+
/* @__PURE__ */ jsxs15("div", { className: `mot-box mot-price mot-t-input${priceError.error ? " mot-is-error" : ""}`, ref: priceError.box, children: [
|
|
4862
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-prefix", "aria-hidden": "true", children: "$" }),
|
|
4863
|
+
/* @__PURE__ */ jsx15("input", { ref: priceInput, id: `${id}-price`, tabIndex: type === "market" ? -1 : 0, inputMode: "decimal", value: price, disabled: busy, "aria-invalid": priceError.error, "aria-describedby": priceError.error ? `${id}-price-error` : void 0, onChange: (event) => {
|
|
4864
|
+
setPrice(event.target.value.replace(/[^0-9.]/g, "").replace(/(\..*)\./g, "$1").slice(0, 8));
|
|
4865
|
+
priceError.clear();
|
|
4866
|
+
setSubmitError("");
|
|
4867
|
+
} })
|
|
4868
|
+
] }),
|
|
4869
|
+
/* @__PURE__ */ jsxs15("p", { className: "mot-t-error-msg", id: `${id}-price-error`, role: priceError.error ? "alert" : void 0, children: [
|
|
4870
|
+
"Enter ",
|
|
4871
|
+
typeInfo.hint || "a limit price"
|
|
4872
|
+
] })
|
|
4873
|
+
] })
|
|
4874
|
+
] }) }) }) })
|
|
4875
|
+
] }),
|
|
4876
|
+
/* @__PURE__ */ jsx15("div", { className: "mot-divider", "aria-hidden": "true" }),
|
|
4877
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-total", children: [
|
|
4878
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-total-label", children: "Est. total" }),
|
|
4879
|
+
/* @__PURE__ */ jsxs15("span", { className: "mot-total-value", children: [
|
|
4880
|
+
/* @__PURE__ */ jsx15(PopNumber, { value: totalText }),
|
|
4881
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-sr-only", "aria-live": "polite", children: totalText })
|
|
4882
|
+
] })
|
|
4883
|
+
] }),
|
|
4884
|
+
submitError && /* @__PURE__ */ jsx15("p", { className: "mot-submit-error", role: "alert", children: submitError }),
|
|
4885
|
+
/* @__PURE__ */ jsxs15("button", { type: "submit", className: `mot-submit${busy ? " mot-is-loading" : ""}`, "aria-live": "polite", "aria-busy": busy, disabled: busy, children: [
|
|
4886
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-btn-loader", children: /* @__PURE__ */ jsx15("span", { className: "mot-t-matrix", "aria-hidden": "true", children: Array.from({ length: 16 }, (_, index) => /* @__PURE__ */ jsx15("i", { className: [0, 3, 12, 15].includes(index) ? "mot-is-gap" : void 0, style: { "--d": index % 4 * 120 } }, index)) }) }),
|
|
4887
|
+
/* @__PURE__ */ jsx15(SwapText, { text: busy ? "Placing order" : side === "buy" ? "Buy" : "Sell" })
|
|
4410
4888
|
] })
|
|
4411
4889
|
] }),
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4890
|
+
/* @__PURE__ */ jsxs15("section", { className: "mot-t-page mot-page-done", "data-page-id": "2", "aria-hidden": !done, inert: !done, children: [
|
|
4891
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-done-head", children: [
|
|
4892
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-done-icon", children: /* @__PURE__ */ jsx15(CheckMark, { size: 24 }) }),
|
|
4893
|
+
/* @__PURE__ */ jsx15("h2", { className: "mot-done-title", ref: heading, tabIndex: -1, children: onSubmit ? "Order submitted" : "Order preview ready" }),
|
|
4894
|
+
/* @__PURE__ */ jsx15("p", { className: "mot-done-meta", children: done ? `${done.side === "buy" ? "Buy" : "Sell"} ${done.shares} ${done.symbol} ${description(done)}` : `Buy ${count} ${symbol} at ${money(quote)}` })
|
|
4895
|
+
] }),
|
|
4896
|
+
/* @__PURE__ */ jsx15("div", { className: "mot-divider", "aria-hidden": "true" }),
|
|
4897
|
+
/* @__PURE__ */ jsxs15("div", { className: "mot-total", children: [
|
|
4898
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-total-label", children: "Est. total" }),
|
|
4899
|
+
/* @__PURE__ */ jsx15("span", { className: "mot-total-value", children: money(done?.estimatedTotal ?? total) })
|
|
4900
|
+
] }),
|
|
4901
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mot-again", tabIndex: done ? 0 : -1, onClick: () => {
|
|
4902
|
+
newOrderFocus.current = true;
|
|
4903
|
+
setDone(null);
|
|
4904
|
+
}, children: "New order" })
|
|
4905
|
+
] })
|
|
4419
4906
|
] })
|
|
4420
4907
|
] });
|
|
4421
4908
|
}
|
|
4422
4909
|
var css3 = `
|
|
4423
|
-
.mova-order{--
|
|
4910
|
+
.mova-order{--stage-fg:#0d0d0d;--stage-muted:#6c6c6c;--stage-border:rgba(0,0,0,.08);--stage-surface:#fff;--stage-accent:#17181c;--stage-on-accent:#fff;color-scheme:light;font:400 13px/20px "Inter Variable",Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;font-optical-sizing:auto;font-feature-settings:"liga" 1,"calt" 1;letter-spacing:0;-webkit-font-smoothing:antialiased}
|
|
4911
|
+
.mova-order[data-theme=dark]{--stage-fg:#f2f2f2;--stage-muted:rgba(202,202,202,.7);--stage-border:rgba(255,255,255,.08);--stage-surface:#1d1d1d;--stage-accent:#fff;--stage-on-accent:#0d0d0d;color-scheme:dark}
|
|
4912
|
+
.mova-order *{box-sizing:border-box}
|
|
4913
|
+
.mova-order {
|
|
4914
|
+
--page-slide-dur: 250ms;
|
|
4915
|
+
--page-fade-dur: 250ms;
|
|
4916
|
+
--page-slide-distance: 8px;
|
|
4917
|
+
--page-blur: 3px;
|
|
4918
|
+
--page-stagger: 0ms;
|
|
4919
|
+
--page-exit-enabled: 1;
|
|
4920
|
+
--page-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4921
|
+
--page-fade-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4922
|
+
--matrix-cycle: 1200ms;
|
|
4923
|
+
--matrix-base: color-mix(in srgb, var(--stage-on-accent) 35%, transparent);
|
|
4924
|
+
--matrix-active: var(--stage-on-accent);
|
|
4925
|
+
--matrix-ease: ease-in-out;
|
|
4926
|
+
--done-pop-dur: 500ms;
|
|
4927
|
+
--done-pop-scale: 0.6;
|
|
4928
|
+
--shake-distance: 6px;
|
|
4929
|
+
--shake-overshoot: 4px;
|
|
4930
|
+
--shake-dur-a: 80ms;
|
|
4931
|
+
--shake-dur-b: 60ms;
|
|
4932
|
+
--shake-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4933
|
+
--revert-hold: 3000ms;
|
|
4934
|
+
--revert-dur: 280ms;
|
|
4935
|
+
--digit-dur: 500ms;
|
|
4936
|
+
--digit-distance: 8px;
|
|
4937
|
+
--digit-stagger: 70ms;
|
|
4938
|
+
--digit-blur: 2px;
|
|
4939
|
+
--digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
|
|
4940
|
+
--digit-dir-x: 0;
|
|
4941
|
+
--digit-dir-y: 1;
|
|
4942
|
+
--tabs-dur: 250ms;
|
|
4943
|
+
--tabs-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4944
|
+
--tabs-text-muted: var(--stage-muted);
|
|
4945
|
+
--tabs-text-active: var(--stage-fg);
|
|
4946
|
+
--tabs-bar-bg: var(--chip);
|
|
4947
|
+
--tabs-pill-bg: var(--stage-surface);
|
|
4948
|
+
--text-swap-dur: 150ms;
|
|
4949
|
+
--text-swap-translate-y: 4px;
|
|
4950
|
+
--text-swap-blur: 2px;
|
|
4951
|
+
--text-swap-ease: ease-in-out;
|
|
4952
|
+
--press-scale: 0.99;
|
|
4953
|
+
--press-dur: 150ms;
|
|
4954
|
+
--ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4955
|
+
--duration-quick: 150ms;
|
|
4956
|
+
--ease-out: ease-out;
|
|
4957
|
+
|
|
4958
|
+
--dropdown-open-dur: 250ms;
|
|
4959
|
+
--dropdown-close-dur: 150ms;
|
|
4960
|
+
--dropdown-pre-scale: 0.97;
|
|
4961
|
+
--dropdown-closing-scale: 0.99;
|
|
4962
|
+
--dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4963
|
+
--acc-expand: 250ms;
|
|
4964
|
+
--acc-collapse: 250ms;
|
|
4965
|
+
--acc-chevron: 250ms;
|
|
4966
|
+
--acc-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
4967
|
+
--menu-shadow: 0 4px 42px rgba(0,0,0,.06), 0 2px 6px rgba(0,0,0,.05), 0 0 0 1px rgba(0,0,0,.06);
|
|
4968
|
+
|
|
4969
|
+
--chip: rgba(0,0,0,.04);
|
|
4970
|
+
--chip-hover: rgba(0,0,0,.06);
|
|
4971
|
+
--chip-press: rgba(0,0,0,.08);
|
|
4972
|
+
--ring-soft: rgba(0,0,0,.06);
|
|
4973
|
+
--err: #EC4A4A;
|
|
4974
|
+
--divider: color-mix(in srgb, var(--stage-border) 49%, transparent);
|
|
4975
|
+
--badge-fill: #E7F9F3;
|
|
4976
|
+
--badge-ink: #216E55;
|
|
4977
|
+
--pill-shadow: 0 1px 2px rgba(0,0,0,.06), 0 0 0 1px rgba(0,0,0,.04);
|
|
4978
|
+
--cta-shadow: 0 1px 2px 0 rgba(0,0,0,.2);
|
|
4979
|
+
--cta-hover: rgba(255,255,255,.06);
|
|
4980
|
+
--card-shadow: 0 0 0 1px rgba(0,0,0,.04), 0 8px 32px -4px rgba(0,0,0,.06), 0 1px 3px 0 rgba(0,0,0,.04);
|
|
4981
|
+
}
|
|
4982
|
+
.mova-order[data-theme="dark"] {
|
|
4983
|
+
--chip: rgba(255,255,255,.07);
|
|
4984
|
+
--chip-hover: rgba(255,255,255,.10);
|
|
4985
|
+
--chip-press: rgba(255,255,255,.08);
|
|
4986
|
+
--ring-soft: rgba(255,255,255,.10);
|
|
4987
|
+
--err: #FF6B6B;
|
|
4988
|
+
--badge-fill: rgba(33,110,85,.28);
|
|
4989
|
+
--badge-ink: #7FDDB8;
|
|
4990
|
+
--tabs-pill-bg: rgba(255,255,255,.10);
|
|
4991
|
+
--pill-shadow: 0 1px 2px rgba(0,0,0,.24), inset 0 1px 0 rgba(255,255,255,.06);
|
|
4992
|
+
--cta-shadow: 0 1px 2px 0 rgba(0,0,0,.4);
|
|
4993
|
+
--cta-hover: rgba(0,0,0,.06);
|
|
4994
|
+
--card-shadow: 0 0 0 1px rgba(255,255,255,.06), 0 8px 32px -4px rgba(0,0,0,.3), 0 1px 3px 0 rgba(0,0,0,.2);
|
|
4995
|
+
}
|
|
4996
|
+
|
|
4997
|
+
.mova-order {
|
|
4998
|
+
width: 300px;
|
|
4999
|
+
max-width: 100%;
|
|
5000
|
+
box-sizing: border-box;
|
|
5001
|
+
padding: 24px;
|
|
5002
|
+
border-radius: 24px;
|
|
5003
|
+
background: var(--stage-surface);
|
|
5004
|
+
box-shadow: var(--card-shadow);
|
|
5005
|
+
color: var(--stage-fg);
|
|
5006
|
+
display: flex;
|
|
5007
|
+
flex-direction: column;
|
|
5008
|
+
gap: 16px;
|
|
5009
|
+
}
|
|
5010
|
+
:where(.mova-order) :is(button, input) { font: inherit; color: inherit; }
|
|
5011
|
+
:where(.mova-order) button { padding: 0; border: 0; background: none; cursor: pointer; }
|
|
5012
|
+
:where(.mova-order) p { margin: 0; }
|
|
5013
|
+
.mova-order :focus-visible:not(input) {
|
|
5014
|
+
outline: none;
|
|
5015
|
+
box-shadow: 0 0 0 2px var(--stage-surface), 0 0 0 4px var(--stage-accent);
|
|
5016
|
+
}
|
|
5017
|
+
|
|
5018
|
+
.mot-head { display: flex; align-items: flex-start; gap: 12px; }
|
|
5019
|
+
.mot-head-main { flex: 1; min-width: 0; }
|
|
5020
|
+
.mot-ticker { font-size: 16px; line-height: 22px; font-weight: 500; margin: 0; }
|
|
5021
|
+
.mot-company { font-size: 12px; line-height: 16px; color: var(--stage-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
5022
|
+
.mot-quote { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
|
|
5023
|
+
.mot-quote-price { font-size: 13px; line-height: 20px; font-variant-numeric: tabular-nums; }
|
|
5024
|
+
.mot-badge {
|
|
5025
|
+
display: inline-flex; align-items: center;
|
|
5026
|
+
height: 18px; padding: 0 6px; border-radius: 50px;
|
|
5027
|
+
font-size: 11px; line-height: 16px; font-weight: 500;
|
|
5028
|
+
background: var(--badge-fill); color: var(--badge-ink);
|
|
5029
|
+
box-shadow: 0 1px 3px rgba(0,0,0,.04), inset 0 0 0 1px color-mix(in srgb, var(--badge-ink) 14%, transparent), inset 0 -1px 0 0 color-mix(in srgb, var(--badge-ink) 10%, transparent);
|
|
5030
|
+
font-variant-numeric: tabular-nums;
|
|
5031
|
+
}
|
|
5032
|
+
|
|
5033
|
+
/* Tabs sliding */
|
|
5034
|
+
.mot-t-tabs {
|
|
5035
|
+
position: relative;
|
|
5036
|
+
display: flex;
|
|
5037
|
+
align-items: center;
|
|
5038
|
+
gap: 3px;
|
|
5039
|
+
padding: 3px;
|
|
5040
|
+
border-radius: 48px;
|
|
5041
|
+
background: var(--tabs-bar-bg);
|
|
5042
|
+
}
|
|
5043
|
+
.mot-t-tab {
|
|
5044
|
+
position: relative;
|
|
5045
|
+
flex: 1;
|
|
5046
|
+
appearance: none;
|
|
5047
|
+
border: 0;
|
|
5048
|
+
background: transparent;
|
|
5049
|
+
height: 30px;
|
|
5050
|
+
padding: 4px 12px;
|
|
5051
|
+
font-size: 13px;
|
|
5052
|
+
line-height: 20px;
|
|
5053
|
+
font-weight: 500;
|
|
5054
|
+
color: var(--tabs-text-muted);
|
|
5055
|
+
cursor: pointer;
|
|
5056
|
+
border-radius: 48px;
|
|
5057
|
+
z-index: 1;
|
|
5058
|
+
--press-scale: 0.97;
|
|
5059
|
+
transition: color var(--tabs-dur) var(--tabs-ease), transform var(--press-dur) var(--ease-smooth-out);
|
|
5060
|
+
}
|
|
5061
|
+
.mova-order .mot-t-tab { color: var(--tabs-text-muted); }
|
|
5062
|
+
.mova-order .mot-t-tab[aria-selected="true"] { color: var(--tabs-text-active); }
|
|
5063
|
+
@media (hover: hover) and (pointer: fine) { .mova-order .mot-t-tab:not([aria-selected="true"]):hover { color: var(--tabs-text-active); } }
|
|
5064
|
+
.mot-t-tabs-pill {
|
|
5065
|
+
position: absolute;
|
|
5066
|
+
top: 3px;
|
|
5067
|
+
left: 0;
|
|
5068
|
+
height: 30px;
|
|
5069
|
+
width: calc((100% - 9px) / 2);
|
|
5070
|
+
background: var(--tabs-pill-bg);
|
|
5071
|
+
box-shadow: var(--pill-shadow);
|
|
5072
|
+
border-radius: 48px;
|
|
5073
|
+
transform: translateX(0);
|
|
5074
|
+
transition: transform var(--tabs-dur) var(--tabs-ease), width var(--tabs-dur) var(--tabs-ease);
|
|
5075
|
+
will-change: transform, width;
|
|
5076
|
+
z-index: 0;
|
|
5077
|
+
pointer-events: none;
|
|
5078
|
+
}
|
|
5079
|
+
|
|
5080
|
+
/* Fields */
|
|
5081
|
+
.mot-fields { display: flex; flex-direction: column; gap: 4px; }
|
|
5082
|
+
.mot-field {
|
|
5083
|
+
display: grid;
|
|
5084
|
+
grid-template-columns: 1fr auto;
|
|
5085
|
+
align-items: center;
|
|
5086
|
+
column-gap: 12px;
|
|
5087
|
+
}
|
|
5088
|
+
.mot-field-label { font-size: 13px; line-height: 20px; }
|
|
5089
|
+
.mot-box {
|
|
5090
|
+
width: 136px;
|
|
5091
|
+
height: 36px;
|
|
5092
|
+
box-sizing: border-box;
|
|
5093
|
+
display: flex;
|
|
5094
|
+
align-items: center;
|
|
5095
|
+
gap: 4px;
|
|
5096
|
+
padding: 0 4px;
|
|
5097
|
+
border-radius: 10px;
|
|
5098
|
+
background: var(--stage-surface);
|
|
5099
|
+
box-shadow: 0 0 0 1px var(--stage-border);
|
|
5100
|
+
}
|
|
5101
|
+
.mot-t-input {
|
|
5102
|
+
transition: box-shadow var(--duration-quick) var(--ease-out);
|
|
5103
|
+
will-change: transform;
|
|
5104
|
+
}
|
|
5105
|
+
.mot-box:focus-within { box-shadow: 0 0 0 1px var(--stage-accent), 0 0 0 3px var(--ring-soft); }
|
|
5106
|
+
.mot-t-input.mot-is-error,
|
|
5107
|
+
.mot-t-input.mot-is-error:focus-within {
|
|
5108
|
+
box-shadow: 0 0 0 1px var(--err), 0 0 0 3px color-mix(in srgb, var(--err) 14%, transparent);
|
|
5109
|
+
transition: box-shadow var(--revert-dur, 280ms) ease-out;
|
|
5110
|
+
}
|
|
5111
|
+
.mot-box input {
|
|
5112
|
+
flex: 1;
|
|
5113
|
+
min-width: 0;
|
|
5114
|
+
height: 100%;
|
|
5115
|
+
border: 0;
|
|
5116
|
+
outline: none;
|
|
5117
|
+
background: none;
|
|
5118
|
+
padding: 0;
|
|
5119
|
+
font-size: 13px;
|
|
5120
|
+
line-height: 20px;
|
|
5121
|
+
font-weight: 400;
|
|
5122
|
+
font-variant-numeric: tabular-nums;
|
|
5123
|
+
color: var(--stage-fg);
|
|
5124
|
+
text-align: center;
|
|
5125
|
+
}
|
|
5126
|
+
.mot-box.mot-price { padding: 0 12px; gap: 2px; }
|
|
5127
|
+
.mot-box.mot-price input { text-align: right; }
|
|
5128
|
+
.mot-prefix { font-size: 13px; line-height: 20px; color: var(--stage-muted); }
|
|
5129
|
+
.mot-step {
|
|
5130
|
+
flex: none;
|
|
5131
|
+
width: 28px;
|
|
5132
|
+
height: 28px;
|
|
5133
|
+
border-radius: 6px;
|
|
5134
|
+
display: grid;
|
|
5135
|
+
place-items: center;
|
|
5136
|
+
color: var(--stage-muted);
|
|
5137
|
+
--press-scale: 0.95;
|
|
5138
|
+
transition: background-color var(--duration-quick) var(--ease-out), transform var(--press-dur) var(--ease-smooth-out);
|
|
5139
|
+
}
|
|
5140
|
+
@media (hover: hover) and (pointer: fine) { .mot-step:hover { background: var(--chip); } }
|
|
5141
|
+
.mot-step:is(:active,.mot-is-pressed) { background: var(--chip-press); transform: scale(var(--press-scale)); }
|
|
5142
|
+
|
|
5143
|
+
.mot-t-error-msg {
|
|
5144
|
+
grid-column: 1 / -1;
|
|
5145
|
+
margin: 4px 0 0;
|
|
5146
|
+
height: 16px;
|
|
5147
|
+
font-size: 12px;
|
|
5148
|
+
line-height: 16px;
|
|
5149
|
+
text-align: right;
|
|
5150
|
+
color: var(--err);
|
|
5151
|
+
opacity: 0;
|
|
5152
|
+
visibility: hidden;
|
|
5153
|
+
transition: opacity var(--revert-dur, 280ms) ease-out, visibility 0s linear var(--revert-dur, 280ms);
|
|
5154
|
+
}
|
|
5155
|
+
.mot-t-input-wrap.mot-is-error .mot-t-error-msg {
|
|
5156
|
+
opacity: 1;
|
|
5157
|
+
visibility: visible;
|
|
5158
|
+
transition: opacity var(--revert-dur, 280ms) ease-out, visibility 0s linear 0s;
|
|
5159
|
+
}
|
|
5160
|
+
.mot-t-input.mot-is-shaking {
|
|
5161
|
+
animation: mot-t-input-shake calc(var(--shake-dur-a) * 2 + var(--shake-dur-b) * 2) linear;
|
|
5162
|
+
}
|
|
5163
|
+
@keyframes mot-t-input-shake {
|
|
5164
|
+
0% { transform: translateX(0); animation-timing-function: var(--shake-ease); }
|
|
5165
|
+
28.57% { transform: translateX(var(--shake-distance)); animation-timing-function: var(--shake-ease); }
|
|
5166
|
+
57.14% { transform: translateX(calc(var(--shake-distance) * -1)); animation-timing-function: var(--shake-ease); }
|
|
5167
|
+
78.57% { transform: translateX(var(--shake-overshoot)); animation-timing-function: var(--shake-ease); }
|
|
5168
|
+
100% { transform: translateX(0); }
|
|
5169
|
+
}
|
|
5170
|
+
|
|
5171
|
+
/* Total */
|
|
5172
|
+
.mot-divider { height: 1px; background: linear-gradient(90deg, transparent, var(--divider) 20%, var(--divider) 80%, transparent); }
|
|
5173
|
+
.mot-total { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; line-height: 20px; }
|
|
5174
|
+
.mot-total-label { color: var(--stage-muted); }
|
|
5175
|
+
.mot-total-value { font-variant-numeric: tabular-nums; }
|
|
5176
|
+
|
|
5177
|
+
@keyframes mot-t-digit-pop-in {
|
|
5178
|
+
0% {
|
|
5179
|
+
transform: translate(calc(var(--digit-distance) * var(--digit-dir-x)), calc(var(--digit-distance) * var(--digit-dir-y)));
|
|
5180
|
+
opacity: 0;
|
|
5181
|
+
filter: blur(var(--digit-blur));
|
|
5182
|
+
}
|
|
5183
|
+
100% { transform: translate(0, 0); opacity: 1; filter: blur(0); }
|
|
5184
|
+
}
|
|
5185
|
+
.mot-t-digit-group { display: inline-flex; align-items: baseline; }
|
|
5186
|
+
.mot-t-digit { display: inline-block; white-space: pre; }
|
|
5187
|
+
.mot-t-digit-group.mot-is-animating .mot-t-digit { animation: mot-t-digit-pop-in var(--digit-dur) var(--digit-ease) both; }
|
|
5188
|
+
.mot-t-digit-group.mot-is-animating .mot-t-digit[data-stagger="1"] { animation-delay: var(--digit-stagger); }
|
|
5189
|
+
.mot-t-digit-group.mot-is-animating .mot-t-digit[data-stagger="2"] { animation-delay: calc(var(--digit-stagger) * 2); }
|
|
5190
|
+
.mot-t-digit-group.mot-is-animating .mot-t-digit[data-same] { animation: none; }
|
|
5191
|
+
|
|
5192
|
+
/* Submit */
|
|
5193
|
+
.mot-submit {
|
|
5194
|
+
height: 36px;
|
|
5195
|
+
width: 100%;
|
|
5196
|
+
border-radius: 40px;
|
|
5197
|
+
background: var(--stage-accent);
|
|
5198
|
+
color: var(--stage-on-accent);
|
|
5199
|
+
box-shadow: var(--cta-shadow);
|
|
5200
|
+
font-size: 13px;
|
|
5201
|
+
line-height: 20px;
|
|
5202
|
+
font-weight: 500;
|
|
5203
|
+
padding: 0 12px;
|
|
5204
|
+
overflow: hidden;
|
|
5205
|
+
transition: transform var(--press-dur) var(--ease-smooth-out), background-color var(--duration-quick) var(--ease-out);
|
|
5206
|
+
}
|
|
5207
|
+
.mova-order .mot-submit { color: var(--stage-on-accent); }
|
|
5208
|
+
@media (hover: hover) and (pointer: fine) { .mot-submit:hover { background-image: linear-gradient(var(--cta-hover), var(--cta-hover)); } }
|
|
5209
|
+
.mot-submit:is(:active,.mot-is-pressed) { transform: scale(var(--press-scale)); }
|
|
5210
|
+
.mot-t-tab:is(:active,.mot-is-pressed) { transform: scale(var(--press-scale)); }
|
|
5211
|
+
|
|
5212
|
+
.mot-t-text-swap {
|
|
5213
|
+
display: inline-block;
|
|
5214
|
+
transform: translateY(0);
|
|
5215
|
+
filter: blur(0);
|
|
5216
|
+
opacity: 1;
|
|
5217
|
+
transition: transform var(--text-swap-dur) var(--text-swap-ease), filter var(--text-swap-dur) var(--text-swap-ease), opacity var(--text-swap-dur) var(--text-swap-ease);
|
|
5218
|
+
}
|
|
5219
|
+
.mot-t-text-swap.mot-is-exit { transform: translateY(calc(var(--text-swap-translate-y) * -1)); filter: blur(var(--text-swap-blur)); opacity: 0; }
|
|
5220
|
+
.mot-t-text-swap.mot-is-enter-start { transform: translateY(var(--text-swap-translate-y)); filter: blur(var(--text-swap-blur)); opacity: 0; transition: none; }
|
|
5221
|
+
|
|
5222
|
+
/* Page side-by-side */
|
|
5223
|
+
.mot-t-page-slide { position: relative; display: grid; }
|
|
5224
|
+
.mot-t-page-slide .mot-t-page[data-page-id="1"] { --t-page-from-x: calc(var(--page-slide-distance) * -1); }
|
|
5225
|
+
.mot-t-page-slide .mot-t-page[data-page-id="2"] { --t-page-from-x: var(--page-slide-distance); }
|
|
5226
|
+
.mot-t-page-slide .mot-t-page {
|
|
5227
|
+
grid-area: 1 / 1;
|
|
5228
|
+
opacity: 0;
|
|
5229
|
+
pointer-events: none;
|
|
5230
|
+
transform: translateX(calc(var(--t-page-from-x, 0px) * var(--page-exit-enabled)));
|
|
5231
|
+
filter: blur(calc(var(--page-blur) * var(--page-exit-enabled)));
|
|
5232
|
+
transition: opacity var(--page-fade-dur) var(--page-fade-ease), transform var(--page-slide-dur) var(--page-slide-ease), filter var(--page-slide-dur) var(--page-slide-ease);
|
|
5233
|
+
}
|
|
5234
|
+
.mot-t-page-slide[data-page="1"] .mot-t-page[data-page-id="1"],
|
|
5235
|
+
.mot-t-page-slide[data-page="2"] .mot-t-page[data-page-id="2"] {
|
|
5236
|
+
opacity: 1;
|
|
5237
|
+
pointer-events: auto;
|
|
5238
|
+
transform: translateX(0);
|
|
5239
|
+
filter: blur(0);
|
|
5240
|
+
transition-delay: var(--page-stagger);
|
|
5241
|
+
}
|
|
5242
|
+
.mot-page-form { display: flex; flex-direction: column; gap: 16px; }
|
|
5243
|
+
.mot-page-done { display: flex; flex-direction: column; align-items: stretch; justify-content: center; gap: 16px; text-align: center; }
|
|
5244
|
+
.mot-done-head { display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
|
5245
|
+
.mot-done-icon {
|
|
5246
|
+
width: 48px; height: 48px; border-radius: 50%;
|
|
5247
|
+
display: grid; place-items: center;
|
|
5248
|
+
margin-bottom: 8px;
|
|
5249
|
+
background: var(--badge-fill); color: var(--badge-ink);
|
|
5250
|
+
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--badge-ink) 14%, transparent);
|
|
5251
|
+
opacity: 0;
|
|
5252
|
+
transform: scale(var(--done-pop-scale));
|
|
5253
|
+
transition: opacity var(--done-pop-dur) var(--ease-smooth-out), transform var(--done-pop-dur) var(--ease-smooth-out);
|
|
5254
|
+
}
|
|
5255
|
+
.mot-t-page-slide[data-page="2"] .mot-done-icon { opacity: 1; transform: scale(1); transition-delay: var(--page-slide-dur); }
|
|
5256
|
+
.mot-done-title { font-size: 16px; line-height: 22px; font-weight: 500; }
|
|
5257
|
+
.mot-done-meta { font-size: 12px; line-height: 16px; color: var(--stage-muted); }
|
|
5258
|
+
.mot-again {
|
|
5259
|
+
height: 36px; width: 100%; border-radius: 40px;
|
|
5260
|
+
background: var(--chip); color: var(--stage-fg);
|
|
5261
|
+
font-size: 13px; line-height: 20px; font-weight: 500;
|
|
5262
|
+
--press-scale: 0.97;
|
|
5263
|
+
transition: transform var(--press-dur) var(--ease-smooth-out), background-color var(--duration-quick) var(--ease-out);
|
|
5264
|
+
}
|
|
5265
|
+
@media (hover: hover) and (pointer: fine) { .mot-again:hover { background: var(--chip-hover); } }
|
|
5266
|
+
.mot-again:is(:active,.mot-is-pressed) { background: var(--chip-press); transform: scale(var(--press-scale)); }
|
|
5267
|
+
|
|
5268
|
+
/* Matrix dot loader */
|
|
5269
|
+
.mot-btn-loader { position: absolute; left: 16px; top: 50%; translate: 0 -50%; opacity: 0; transition: opacity var(--duration-quick) var(--ease-out); }
|
|
5270
|
+
.mot-submit.mot-is-loading .mot-btn-loader { opacity: 1; }
|
|
5271
|
+
.mot-submit { position: relative; }
|
|
5272
|
+
.mot-t-matrix { display: grid; grid-template-columns: repeat(4, 2px); grid-auto-rows: 2px; gap: 2px; }
|
|
5273
|
+
.mot-t-matrix i { display: block; background: var(--matrix-base); animation: mot-t-matrix-pulse var(--matrix-cycle) var(--matrix-ease) infinite; animation-delay: calc(var(--d, 0) * 1ms); }
|
|
5274
|
+
.mot-t-matrix i.mot-is-gap { visibility: hidden; animation: none; }
|
|
5275
|
+
@keyframes mot-t-matrix-pulse {
|
|
5276
|
+
0%, 45%, 100% { background-color: var(--matrix-base); }
|
|
5277
|
+
15% { background-color: var(--matrix-active); }
|
|
5278
|
+
}
|
|
5279
|
+
|
|
5280
|
+
.mot-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
5281
|
+
|
|
5282
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5283
|
+
.mot-t-input { animation: none !important; transform: none !important; }
|
|
5284
|
+
.mot-t-digit-group .mot-t-digit { animation: none !important; }
|
|
5285
|
+
.mot-t-tabs-pill, .mot-t-tab { transition: none !important; }
|
|
5286
|
+
.mot-t-text-swap { transition: none !important; }
|
|
5287
|
+
.mot-t-page-slide .mot-t-page, .mot-done-icon { transition: none !important; }
|
|
5288
|
+
.mot-t-matrix i { animation: none !important; }
|
|
5289
|
+
.mot-again:is(:active,.mot-is-pressed) { transform: none; }
|
|
5290
|
+
.mot-submit:is(:active,.mot-is-pressed), .mot-step:is(:active,.mot-is-pressed), .mot-t-tab:is(:active,.mot-is-pressed) { transform: none; }
|
|
5291
|
+
}
|
|
5292
|
+
/* Order type menu */
|
|
5293
|
+
.mova-order[data-theme="dark"] { --menu-shadow: 0 1px 3px rgba(0,0,0,.04), inset 0 1px 0 rgba(255,255,255,.04), inset 0 0 0 1px rgba(196,196,196,.08); }
|
|
5294
|
+
.mot-type-anchor { position: relative; }
|
|
5295
|
+
.mot-box.mot-type-btn {
|
|
5296
|
+
width: 136px;
|
|
5297
|
+
justify-content: space-between;
|
|
5298
|
+
padding: 0 10px 0 12px;
|
|
5299
|
+
gap: 6px;
|
|
5300
|
+
font-size: 13px;
|
|
5301
|
+
line-height: 20px;
|
|
5302
|
+
--press-scale: 0.97;
|
|
5303
|
+
transition: box-shadow var(--duration-quick) var(--ease-out), transform var(--press-dur) var(--ease-smooth-out);
|
|
5304
|
+
}
|
|
5305
|
+
.mot-box.mot-type-btn:is(:active,.mot-is-pressed) { transform: scale(var(--press-scale)); }
|
|
5306
|
+
.mot-type-btn .mot-hi, .mot-type-btn [data-icon] { color: var(--stage-muted); flex: none; }
|
|
5307
|
+
.mot-type-btn-label { overflow: hidden; white-space: nowrap; }
|
|
5308
|
+
.mova-order .mot-box.mot-type-btn:focus-visible { box-shadow: 0 0 0 1px var(--stage-accent), 0 0 0 3px var(--ring-soft); }
|
|
5309
|
+
.mot-t-dropdown {
|
|
5310
|
+
position: absolute;
|
|
5311
|
+
top: 40px;
|
|
5312
|
+
right: 0;
|
|
5313
|
+
z-index: 5;
|
|
5314
|
+
width: 168px;
|
|
5315
|
+
box-sizing: border-box;
|
|
5316
|
+
padding: 6px;
|
|
5317
|
+
border-radius: 12px;
|
|
5318
|
+
background: var(--stage-surface);
|
|
5319
|
+
box-shadow: var(--menu-shadow);
|
|
5320
|
+
transform-origin: top right;
|
|
5321
|
+
transform: scale(var(--dropdown-pre-scale));
|
|
5322
|
+
opacity: 0;
|
|
5323
|
+
pointer-events: none;
|
|
5324
|
+
transition: transform var(--dropdown-open-dur) var(--dropdown-ease), opacity var(--dropdown-open-dur) var(--dropdown-ease);
|
|
5325
|
+
will-change: transform, opacity;
|
|
5326
|
+
}
|
|
5327
|
+
.mot-t-dropdown.mot-is-open { transform: scale(1); opacity: 1; pointer-events: auto; }
|
|
5328
|
+
.mot-t-dropdown.mot-is-closing {
|
|
5329
|
+
transform: scale(var(--dropdown-closing-scale));
|
|
5330
|
+
opacity: 0;
|
|
5331
|
+
pointer-events: none;
|
|
5332
|
+
transition: transform var(--dropdown-close-dur) var(--dropdown-ease), opacity var(--dropdown-close-dur) var(--dropdown-ease);
|
|
5333
|
+
}
|
|
5334
|
+
.mot-menu-item {
|
|
5335
|
+
width: 100%;
|
|
5336
|
+
height: 32px;
|
|
5337
|
+
display: flex;
|
|
5338
|
+
align-items: center;
|
|
5339
|
+
justify-content: space-between;
|
|
5340
|
+
gap: 8px;
|
|
5341
|
+
padding: 0 6px 0 8px;
|
|
5342
|
+
border-radius: 8px;
|
|
5343
|
+
font-size: 13px;
|
|
5344
|
+
line-height: 20px;
|
|
5345
|
+
text-align: left;
|
|
5346
|
+
--press-scale: 0.97;
|
|
5347
|
+
transition: background-color var(--duration-quick) var(--ease-out), transform var(--press-dur) var(--ease-smooth-out);
|
|
5348
|
+
}
|
|
5349
|
+
@media (hover: hover) and (pointer: fine) { .mot-menu-item:hover { background: var(--chip); } }
|
|
5350
|
+
.mot-menu-item:is(:active,.mot-is-pressed) { background: var(--chip-press); transform: scale(var(--press-scale)); }
|
|
5351
|
+
.mot-menu-item [data-icon], .mot-menu-item .mot-hi { color: var(--stage-muted); }
|
|
5352
|
+
|
|
5353
|
+
/* Accordion expand */
|
|
5354
|
+
.mot-t-acc { margin: -4px -4px; }
|
|
5355
|
+
.mot-t-acc-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--acc-collapse) var(--acc-ease); }
|
|
5356
|
+
.mot-t-acc[data-open="true"] .mot-t-acc-panel { grid-template-rows: 1fr; transition: grid-template-rows var(--acc-expand) var(--acc-ease); }
|
|
5357
|
+
.mot-t-acc-panel-inner {
|
|
5358
|
+
min-height: 0;
|
|
5359
|
+
overflow: hidden;
|
|
5360
|
+
opacity: 0;
|
|
5361
|
+
filter: blur(2px);
|
|
5362
|
+
transition: opacity var(--acc-collapse) var(--acc-ease), filter var(--acc-collapse) var(--acc-ease);
|
|
5363
|
+
}
|
|
5364
|
+
.mot-t-acc[data-open="true"] .mot-t-acc-panel-inner {
|
|
5365
|
+
opacity: 1;
|
|
5366
|
+
filter: blur(0);
|
|
5367
|
+
transition: opacity var(--acc-expand) var(--acc-ease), filter var(--acc-expand) var(--acc-ease);
|
|
5368
|
+
}
|
|
5369
|
+
.mot-t-acc-body { padding: 4px; }
|
|
5370
|
+
|
|
5371
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5372
|
+
.mot-t-dropdown, .mot-box.mot-type-btn, .mot-menu-item { transition: none !important; }
|
|
5373
|
+
.mot-box.mot-type-btn:is(:active,.mot-is-pressed), .mot-menu-item:is(:active,.mot-is-pressed) { transform: none; }
|
|
5374
|
+
.mot-t-acc-panel, .mot-t-acc-panel-inner, .mot-t-acc-chevron { transition: none !important; }
|
|
5375
|
+
}
|
|
5376
|
+
|
|
5377
|
+
/* Icons: Heroicons (outline), Copyright (c) Tailwind Labs, Inc. MIT License */
|
|
5378
|
+
.mot-hi-play{translate:1px 0}.mot-hi-heart{translate:0 1px}
|
|
5379
|
+
|
|
5380
|
+
/* Touch press feedback stays local to this component. */
|
|
5381
|
+
.mova-order :is(button,[role="tab"],[role="menuitemradio"]){-webkit-tap-highlight-color:transparent;touch-action:manipulation;user-select:none;-webkit-touch-callout:none}
|
|
5382
|
+
|
|
5383
|
+
.mova-order .mot-done-title{margin:0}
|
|
5384
|
+
.mova-order .mot-done-title:focus{outline:none;box-shadow:none}
|
|
5385
|
+
.mova-order button:disabled{cursor:default}
|
|
5386
|
+
.mova-order .mot-badge[data-negative=true]{--badge-fill:#fbe9e9;--badge-ink:#ad3c3c}
|
|
5387
|
+
.mova-order[data-theme=dark] .mot-badge[data-negative=true]{--badge-fill:#4c2b2b;--badge-ink:#ffaaaa}
|
|
5388
|
+
.mova-order .mot-submit-error{font-size:12px;line-height:16px;color:var(--err)}
|
|
5389
|
+
@media(prefers-reduced-motion:reduce){.mova-order *{animation:none!important;transition:none!important}.mova-order .mot-t-text-swap{transform:none;filter:none;opacity:1}}
|
|
4424
5390
|
`;
|
|
4425
5391
|
|
|
4426
5392
|
// .generated/ui/cards/imessage-chat.tsx
|
|
4427
5393
|
import * as React4 from "react";
|
|
4428
|
-
import {
|
|
5394
|
+
import { Video } from "lucide-react";
|
|
4429
5395
|
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4430
5396
|
var conversation = [
|
|
4431
5397
|
{ id: "1", text: "Are we still on for Saturday?", direction: "incoming" },
|
|
@@ -4434,329 +5400,1469 @@ var conversation = [
|
|
|
4434
5400
|
{ id: "4", text: "The good kind this time", direction: "incoming" },
|
|
4435
5401
|
{ id: "5", text: "You're the best", direction: "outgoing" }
|
|
4436
5402
|
];
|
|
4437
|
-
|
|
5403
|
+
var defaultAvatar = "https://images.unsplash.com/photo-1580489944761-15a19d654956?auto=format&fit=crop&q=80&w=64&h=64";
|
|
5404
|
+
var replies = ["Love that", "See you there!", "Haha deal", "Bringing snacks too"];
|
|
5405
|
+
function IMessageChat({ name = "Maya Chen", avatar = defaultAvatar, deliveryStatus, initialMessages = conversation, onSend, onAudioCall, onVideoCall, theme = "light", className = "", style } = {}) {
|
|
4438
5406
|
const [messages, setMessages] = React4.useState(initialMessages);
|
|
4439
5407
|
const [draft, setDraft] = React4.useState("");
|
|
4440
5408
|
const [status, setStatus] = React4.useState("Read");
|
|
5409
|
+
const [statusPhase, setStatusPhase] = React4.useState("stable");
|
|
5410
|
+
const [receiptAfter, setReceiptAfter] = React4.useState(initialMessages[initialMessages.length - 1]?.id);
|
|
5411
|
+
const [newMessages, setNewMessages] = React4.useState(() => /* @__PURE__ */ new Set());
|
|
5412
|
+
const [receiptNew, setReceiptNew] = React4.useState(false);
|
|
5413
|
+
const [typing, setTyping] = React4.useState(false);
|
|
5414
|
+
const [tooltip, setTooltip] = React4.useState({ text: "", visible: false, width: 0, x: 0 });
|
|
5415
|
+
const [pressed, setPressed] = React4.useState();
|
|
4441
5416
|
const thread = React4.useRef(null);
|
|
5417
|
+
const input = React4.useRef(null);
|
|
5418
|
+
const statusText = React4.useRef(null);
|
|
5419
|
+
const tooltipText = React4.useRef(null);
|
|
5420
|
+
const actions = React4.useRef(null);
|
|
5421
|
+
const tooltipTrigger = React4.useRef(null);
|
|
5422
|
+
const timers = React4.useRef([]);
|
|
5423
|
+
const pressTimer = React4.useRef(void 0);
|
|
5424
|
+
const pressStarted = React4.useRef(0);
|
|
5425
|
+
const initiallyScrolled = React4.useRef(false);
|
|
4442
5426
|
const sequence = React4.useRef(0);
|
|
5427
|
+
const replyIndex = React4.useRef(0);
|
|
4443
5428
|
const instanceId = React4.useId();
|
|
5429
|
+
const tooltipId = `${instanceId}-tooltip`;
|
|
5430
|
+
function clearTimers() {
|
|
5431
|
+
timers.current.forEach(clearTimeout);
|
|
5432
|
+
timers.current = [];
|
|
5433
|
+
}
|
|
5434
|
+
function later(callback, delay) {
|
|
5435
|
+
timers.current.push(setTimeout(callback, delay));
|
|
5436
|
+
}
|
|
5437
|
+
React4.useEffect(() => () => {
|
|
5438
|
+
clearTimers();
|
|
5439
|
+
clearTimeout(pressTimer.current);
|
|
5440
|
+
}, []);
|
|
4444
5441
|
React4.useEffect(() => {
|
|
4445
|
-
if (thread.current)
|
|
4446
|
-
|
|
5442
|
+
if (!thread.current) return;
|
|
5443
|
+
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
5444
|
+
thread.current.scrollTo({ top: thread.current.scrollHeight, behavior: !initiallyScrolled.current || reduced ? "auto" : "smooth" });
|
|
5445
|
+
initiallyScrolled.current = true;
|
|
5446
|
+
}, [messages, typing]);
|
|
5447
|
+
React4.useLayoutEffect(() => {
|
|
5448
|
+
if (statusPhase !== "enter") return;
|
|
5449
|
+
void statusText.current?.offsetHeight;
|
|
5450
|
+
setStatusPhase("stable");
|
|
5451
|
+
}, [statusPhase]);
|
|
5452
|
+
React4.useLayoutEffect(() => {
|
|
5453
|
+
if (!tooltip.visible || !tooltipText.current || !tooltipTrigger.current || !actions.current) return;
|
|
5454
|
+
const width = Math.ceil(tooltipText.current.scrollWidth + 24);
|
|
5455
|
+
const group = actions.current.getBoundingClientRect();
|
|
5456
|
+
const trigger = tooltipTrigger.current.getBoundingClientRect();
|
|
5457
|
+
const x = Math.min(trigger.left - group.left + trigger.width / 2 - width / 2, group.width + 6 - width);
|
|
5458
|
+
setTooltip((current) => current.width === width && current.x === x ? current : { ...current, width, x });
|
|
5459
|
+
}, [tooltip.text, tooltip.visible]);
|
|
5460
|
+
function showTooltip(event, text) {
|
|
5461
|
+
tooltipTrigger.current = event.currentTarget;
|
|
5462
|
+
setTooltip((current) => ({ ...current, text, visible: true }));
|
|
5463
|
+
}
|
|
5464
|
+
function hideTooltip() {
|
|
5465
|
+
setTooltip((current) => ({ ...current, visible: false }));
|
|
5466
|
+
}
|
|
5467
|
+
function press(event) {
|
|
5468
|
+
if (event.pointerType === "mouse") return;
|
|
5469
|
+
clearTimeout(pressTimer.current);
|
|
5470
|
+
pressStarted.current = performance.now();
|
|
5471
|
+
setPressed(event.currentTarget.dataset.press);
|
|
5472
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
5473
|
+
}
|
|
5474
|
+
function releasePress() {
|
|
5475
|
+
pressTimer.current = setTimeout(() => setPressed(void 0), Math.max(0, 150 - (performance.now() - pressStarted.current)));
|
|
5476
|
+
}
|
|
5477
|
+
function finishAnimation(id, event) {
|
|
5478
|
+
if (event.animationName !== "mic-pop") return;
|
|
5479
|
+
setNewMessages((current) => {
|
|
5480
|
+
const next = new Set(current);
|
|
5481
|
+
next.delete(id);
|
|
5482
|
+
return next;
|
|
5483
|
+
});
|
|
5484
|
+
}
|
|
4447
5485
|
function send(event) {
|
|
4448
5486
|
event.preventDefault();
|
|
4449
5487
|
const text = draft.trim();
|
|
4450
5488
|
if (!text) return;
|
|
4451
|
-
|
|
5489
|
+
clearTimers();
|
|
5490
|
+
const id = `${instanceId}-sent-${++sequence.current}`;
|
|
5491
|
+
setTyping(false);
|
|
5492
|
+
setMessages((current) => [...current, { id, text, direction: "outgoing" }]);
|
|
5493
|
+
setNewMessages((current) => new Set(current).add(id));
|
|
5494
|
+
setReceiptAfter(id);
|
|
5495
|
+
setReceiptNew(true);
|
|
5496
|
+
setStatus("Delivered");
|
|
5497
|
+
setStatusPhase("stable");
|
|
4452
5498
|
setDraft("");
|
|
4453
|
-
|
|
5499
|
+
later(() => {
|
|
5500
|
+
setStatusPhase("exit");
|
|
5501
|
+
later(() => {
|
|
5502
|
+
setStatus("Read");
|
|
5503
|
+
setStatusPhase("enter");
|
|
5504
|
+
}, 150);
|
|
5505
|
+
}, 1200);
|
|
5506
|
+
later(() => setTyping(true), 1800);
|
|
5507
|
+
later(() => {
|
|
5508
|
+
setTyping(false);
|
|
5509
|
+
const replyId = `${instanceId}-reply-${++sequence.current}`;
|
|
5510
|
+
const reply = replies[replyIndex.current++ % replies.length];
|
|
5511
|
+
setMessages((current) => [...current, { id: replyId, text: reply, direction: "incoming" }]);
|
|
5512
|
+
setNewMessages((current) => new Set(current).add(replyId));
|
|
5513
|
+
}, 3400);
|
|
4454
5514
|
onSend?.(text);
|
|
4455
5515
|
}
|
|
5516
|
+
const receipt = /* @__PURE__ */ jsx16("div", { className: `mic-status${receiptNew ? " mic-new" : ""}`, role: "status", onAnimationEnd: (event) => {
|
|
5517
|
+
if (event.animationName === "mic-pop") setReceiptNew(false);
|
|
5518
|
+
}, children: /* @__PURE__ */ jsx16("span", { ref: statusText, className: `mic-text-swap${statusPhase === "exit" ? " mic-exit" : statusPhase === "enter" ? " mic-enter-start" : ""}`, children: deliveryStatus ?? status }) }, "receipt");
|
|
5519
|
+
const contents = [/* @__PURE__ */ jsx16("div", { className: "mic-time", children: "Today 9:41 AM" }, "timestamp")];
|
|
5520
|
+
messages.forEach((message) => {
|
|
5521
|
+
contents.push(/* @__PURE__ */ jsx16("div", { className: `mic-bubble mic-${message.direction}${newMessages.has(message.id) ? " mic-new" : ""}`, onAnimationEnd: (event) => finishAnimation(message.id, event), children: message.text }, message.id));
|
|
5522
|
+
if (message.id === receiptAfter) contents.push(receipt);
|
|
5523
|
+
});
|
|
5524
|
+
if (!messages.length) contents.push(receipt);
|
|
5525
|
+
if (typing) contents.push(/* @__PURE__ */ jsxs16("div", { className: "mic-bubble mic-incoming mic-typing mic-new", "aria-label": `${name.split(" ")[0]} is typing`, children: [
|
|
5526
|
+
/* @__PURE__ */ jsx16("i", {}),
|
|
5527
|
+
/* @__PURE__ */ jsx16("i", {}),
|
|
5528
|
+
/* @__PURE__ */ jsx16("i", {})
|
|
5529
|
+
] }, "typing"));
|
|
4456
5530
|
return /* @__PURE__ */ jsxs16("section", { className: `mova-imessage ${className}`, "data-theme": theme, style, "aria-label": `Conversation with ${name}`, children: [
|
|
4457
5531
|
/* @__PURE__ */ jsx16("style", { children: css4 }),
|
|
4458
5532
|
/* @__PURE__ */ jsxs16("header", { children: [
|
|
4459
|
-
/* @__PURE__ */ jsx16("span", { className: "mic-avatar", children: avatar ? /* @__PURE__ */ jsx16("img", { src: avatar, alt:
|
|
5533
|
+
/* @__PURE__ */ jsx16("span", { className: "mic-avatar", children: avatar ? /* @__PURE__ */ jsx16("img", { src: avatar, alt: name, width: 32, height: 32 }) : name.split(" ").map((word) => word[0]).slice(0, 2).join("") }),
|
|
4460
5534
|
/* @__PURE__ */ jsxs16("div", { className: "mic-person", children: [
|
|
4461
5535
|
/* @__PURE__ */ jsx16("strong", { children: name }),
|
|
4462
5536
|
/* @__PURE__ */ jsx16("span", { children: "iMessage" })
|
|
4463
5537
|
] }),
|
|
4464
|
-
/* @__PURE__ */
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
5538
|
+
/* @__PURE__ */ jsxs16("span", { className: "mic-actions", ref: actions, onPointerLeave: hideTooltip, children: [
|
|
5539
|
+
/* @__PURE__ */ jsx16("button", { type: "button", className: "mic-icon", "aria-label": "Audio call", "aria-describedby": tooltipId, "data-press": "audio", "data-pressed": pressed === "audio", onPointerDown: press, onPointerUp: releasePress, onPointerCancel: releasePress, onPointerEnter: (event) => showTooltip(event, "Audio call"), onFocus: (event) => showTooltip(event, "Audio call"), onBlur: hideTooltip, onClick: () => {
|
|
5540
|
+
hideTooltip();
|
|
5541
|
+
onAudioCall?.();
|
|
5542
|
+
}, children: /* @__PURE__ */ jsx16("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.25", "aria-hidden": "true", children: /* @__PURE__ */ jsx16("path", { d: "M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z" }) }) }),
|
|
5543
|
+
onVideoCall && /* @__PURE__ */ jsx16("button", { type: "button", className: "mic-icon", "aria-label": `Video call ${name}`, "aria-describedby": tooltipId, "data-press": "video", "data-pressed": pressed === "video", onPointerDown: press, onPointerUp: releasePress, onPointerCancel: releasePress, onPointerEnter: (event) => showTooltip(event, "Video call"), onFocus: (event) => showTooltip(event, "Video call"), onBlur: hideTooltip, onClick: () => {
|
|
5544
|
+
hideTooltip();
|
|
5545
|
+
onVideoCall();
|
|
5546
|
+
}, children: /* @__PURE__ */ jsx16(Video, { size: 16 }) }),
|
|
5547
|
+
/* @__PURE__ */ jsx16("span", { className: "mic-tooltip", id: tooltipId, role: "tooltip", "aria-hidden": !tooltip.visible, "data-show": tooltip.visible, style: { width: tooltip.width, "--mic-tooltip-x": `${tooltip.x}px` }, children: /* @__PURE__ */ jsx16("span", { ref: tooltipText, children: tooltip.text }) })
|
|
5548
|
+
] })
|
|
4469
5549
|
] }),
|
|
4470
|
-
/* @__PURE__ */ jsx16("div", { className: "mic-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
/* @__PURE__ */ jsx16("
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
/* @__PURE__ */ jsx16("input", { "aria-label": "Message", placeholder: "iMessage", value: draft, maxLength: 2e3, onChange: (event) => setDraft(event.target.value) }),
|
|
4477
|
-
/* @__PURE__ */ jsx16("button", { type: "submit", "aria-label": "Send message", disabled: !draft.trim(), children: /* @__PURE__ */ jsx16(ArrowUp, { size: 18 }) })
|
|
4478
|
-
] })
|
|
5550
|
+
/* @__PURE__ */ jsx16("div", { className: "mic-divider", "aria-hidden": "true" }),
|
|
5551
|
+
/* @__PURE__ */ jsx16("div", { className: "mic-thread", ref: thread, role: "log", "aria-label": "Messages", "aria-live": "polite", "aria-relevant": "additions", children: /* @__PURE__ */ jsx16("div", { className: "mic-messages", children: contents }) }),
|
|
5552
|
+
/* @__PURE__ */ jsx16("form", { onSubmit: send, children: /* @__PURE__ */ jsxs16("label", { className: "mic-field", children: [
|
|
5553
|
+
/* @__PURE__ */ jsx16("input", { ref: input, type: "text", "aria-label": "Message", placeholder: "iMessage", autoComplete: "off", value: draft, maxLength: 2e3, onChange: (event) => setDraft(event.target.value) }),
|
|
5554
|
+
/* @__PURE__ */ jsx16("button", { type: "submit", className: `mic-send${draft.trim() ? " mic-ready" : ""}`, "aria-label": "Send", "aria-disabled": !draft.trim(), "data-press": "send", "data-pressed": pressed === "send", onPointerDown: press, onPointerUp: releasePress, onPointerCancel: releasePress, onClick: () => input.current?.focus(), children: /* @__PURE__ */ jsx16("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.25", "aria-hidden": "true", children: /* @__PURE__ */ jsx16("path", { d: "M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18" }) }) })
|
|
5555
|
+
] }) })
|
|
4479
5556
|
] });
|
|
4480
5557
|
}
|
|
4481
5558
|
var css4 = `
|
|
4482
|
-
.mova-imessage{--mic-bg:#fff;--mic-fg:#
|
|
4483
|
-
.mova-imessage[data-theme=dark]{--mic-bg:#1d1d1d;--mic-fg:#f2f2f2;--mic-muted
|
|
4484
|
-
.mova-imessage *{box-sizing:border-box}.mova-imessage button,.mova-imessage input{font:inherit}.mova-imessage button{
|
|
5559
|
+
.mova-imessage{--mic-bg:#fff;--mic-fg:#0d0d0d;--mic-muted:#6c6c6c;--mic-chip:rgba(0,0,0,.04);--mic-bubble-in:rgba(0,0,0,.05);--mic-bubble-out:#1c5ffb;--mic-input-line:rgba(0,0,0,.14);--mic-input-focus:#585858;--mic-divider:rgba(0,0,0,.0392);--mic-tooltip-bg:#fff;--mic-tooltip-fg:#2f2f2f;box-sizing:border-box;width:300px;max-width:100%;display:flex;flex-direction:column;border-radius:24px;background:var(--mic-bg);color:var(--mic-fg);font:400 13px/20px "Inter Variable",Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;letter-spacing:0;box-shadow:0 0 0 1px #0000000a,0 8px 32px -4px #0000000f,0 1px 3px #0000000a;overflow:hidden;-webkit-font-smoothing:antialiased}
|
|
5560
|
+
.mova-imessage[data-theme=dark]{--mic-bg:#1d1d1d;--mic-fg:#f2f2f2;--mic-muted:rgba(202,202,202,.7);--mic-chip:rgba(255,255,255,.07);--mic-bubble-in:rgba(255,255,255,.08);--mic-bubble-out:#2f6bff;--mic-input-line:rgba(255,255,255,.14);--mic-input-focus:#a5a5a5;--mic-divider:rgba(255,255,255,.0392);--mic-tooltip-bg:#262626;--mic-tooltip-fg:#f2f2f2;color-scheme:dark}
|
|
5561
|
+
.mova-imessage *{box-sizing:border-box}.mova-imessage button,.mova-imessage input{font:inherit;letter-spacing:inherit}.mova-imessage button{padding:0;border:0;background:none;color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}.mova-imessage button:is(:active,[data-pressed=true]){transform:scale(.95)}.mova-imessage :focus-visible:not(input){outline:none;box-shadow:0 0 0 2px var(--mic-bg),0 0 0 4px var(--mic-fg)}.mova-imessage header{display:flex;gap:12px;align-items:center;padding:16px;position:relative;z-index:2}.mic-avatar{display:inline-grid;place-items:center;flex:none;width:32px;height:32px;border-radius:50%;background:#c7b0a1;color:#433b37;font-size:12.8px;font-weight:500;line-height:1;overflow:hidden}.mic-avatar img{display:block;width:32px;height:32px;border-radius:50%;object-fit:cover;outline:1px solid #00000014;outline-offset:-1px}.mova-imessage[data-theme=dark] .mic-avatar img{outline-color:#ffffff14}.mic-person{flex:1;min-width:0;display:flex;flex-direction:column}.mic-person strong{font-size:15px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mic-person>span,.mic-time,.mic-status{font-size:12px;line-height:16px;color:var(--mic-muted)}.mic-actions{position:relative;display:inline-flex;flex:none;gap:4px;margin-right:-6px}.mova-imessage .mic-icon{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;color:var(--mic-muted);transition:transform 150ms cubic-bezier(.22,1,.36,1),background-color 150ms cubic-bezier(.22,1,.36,1)}@media(hover:hover) and (pointer:fine){.mova-imessage .mic-icon:hover{background:var(--mic-chip)}}.mic-tooltip{position:absolute;top:calc(100% + 8px);left:0;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;translate:var(--mic-tooltip-x,0px) 0;scale:.98;transform-origin:50% 0;padding:8px 12px;border-radius:8px;background:var(--mic-tooltip-bg);color:var(--mic-tooltip-fg);font-size:12px;line-height:16px;white-space:nowrap;box-shadow:0 0 0 1px #0000000f,0 2px 6px #0000000d,0 4px 42px #0000000f;opacity:0;pointer-events:none;z-index:3;transition:opacity 50ms ease-out,scale 50ms ease-out,translate 160ms cubic-bezier(.22,1,.36,1),width 160ms cubic-bezier(.22,1,.36,1)}.mic-tooltip[data-show=true]{opacity:1;scale:1;transition:opacity 150ms ease-out 80ms,scale 150ms ease-out 80ms,translate 160ms cubic-bezier(.22,1,.36,1),width 160ms cubic-bezier(.22,1,.36,1)}.mic-tooltip>span{white-space:nowrap}.mic-divider{height:1px;flex:none;background:linear-gradient(90deg,transparent,var(--mic-divider) 20%,var(--mic-divider) 80%,transparent)}.mic-thread{box-sizing:content-box;height:228px;display:flex;flex-direction:column;overflow-y:auto;padding:12px 16px;scrollbar-width:none;overscroll-behavior:contain;-webkit-mask-image:linear-gradient(to bottom,transparent,#000 16px);mask-image:linear-gradient(to bottom,transparent,#000 16px)}.mic-thread::-webkit-scrollbar{display:none}.mic-messages{margin-top:auto;display:flex;flex-direction:column;gap:2px}.mic-time{align-self:center;margin-bottom:8px}.mic-bubble{box-sizing:content-box;max-width:78%;padding:8px 12px;border-radius:18px;font-size:13px;line-height:20px;overflow-wrap:anywhere;text-wrap:pretty;transition:border-radius 250ms cubic-bezier(.22,1,.36,1)}.mic-incoming{align-self:flex-start;background:var(--mic-bubble-in);border-bottom-left-radius:6px;transform-origin:0 100%}.mic-outgoing{align-self:flex-end;background:var(--mic-bubble-out);color:#fff;border-bottom-right-radius:6px;transform-origin:100% 100%}.mic-incoming:has(+.mic-incoming){border-bottom-left-radius:18px}.mic-outgoing:has(+.mic-outgoing){border-bottom-right-radius:18px}.mic-incoming+.mic-outgoing,.mic-outgoing+.mic-incoming,.mic-status+.mic-bubble{margin-top:6px}.mic-status{align-self:flex-end;padding:2px 4px 0 0;transform-origin:100% 0}.mic-new{animation:mic-pop 500ms cubic-bezier(.34,1.36,.64,1) both,mic-fade 400ms cubic-bezier(.22,1,.36,1) both}@keyframes mic-pop{from{transform:translateY(8px) scale(.92)}to{transform:none}}@keyframes mic-fade{from{opacity:0;filter:blur(2px)}to{opacity:1;filter:blur(0)}}.mic-bubble.mic-typing{display:flex;align-items:center;gap:4px;padding:14px 12px}.mic-typing i{width:6px;height:6px;border-radius:50%;background:var(--mic-muted);animation:mic-typing 1200ms ease-in-out infinite}.mic-typing i:nth-child(2){animation-delay:180ms}.mic-typing i:nth-child(3){animation-delay:360ms}@keyframes mic-typing{0%,60%,100%{opacity:.35;transform:translateY(0)}30%{opacity:1;transform:translateY(-2px)}}.mic-text-swap{display:inline-block;transform:translateY(0);filter:blur(0);opacity:1;transition:transform 150ms ease-in-out,filter 150ms ease-in-out,opacity 150ms ease-in-out;will-change:transform,filter,opacity}.mic-text-swap.mic-exit{transform:translateY(-4px);filter:blur(2px);opacity:0}.mic-text-swap.mic-enter-start{transform:translateY(4px);filter:blur(2px);opacity:0;transition:none}.mova-imessage form{padding:8px 16px 16px;margin:0}.mic-field{display:flex;align-items:center;gap:8px;height:36px;padding:0 4px 0 14px;border-radius:40px;background:var(--mic-bg);box-shadow:inset 0 0 0 1px var(--mic-input-line);transition:box-shadow 120ms ease;cursor:text}.mic-field:focus-within{box-shadow:inset 0 0 0 1.5px var(--mic-input-focus)}.mova-imessage input{flex:1;min-width:0;height:100%;padding:0;border:0;outline:none;background:none;color:var(--mic-fg);font-size:13px;line-height:20px}.mova-imessage input::placeholder{color:var(--mic-muted)}.mova-imessage .mic-send{flex:none;width:28px;height:28px;border-radius:50%;display:grid;place-items:center;background:var(--mic-chip);color:var(--mic-muted);transition:transform 150ms cubic-bezier(.22,1,.36,1),background-color 150ms cubic-bezier(.22,1,.36,1),color 150ms cubic-bezier(.22,1,.36,1)}.mova-imessage .mic-send[aria-disabled=true]{cursor:default}.mova-imessage .mic-send.mic-ready{background:var(--mic-bubble-out);color:#fff}@media(prefers-reduced-motion:reduce){.mova-imessage *{animation:none!important;transition:none!important}.mova-imessage .mic-typing i{opacity:.6}.mova-imessage button:is(:active,[data-pressed=true]){transform:none}}
|
|
4485
5562
|
`;
|
|
4486
5563
|
|
|
4487
5564
|
// .generated/ui/cards/liquid-glass-sheet.tsx
|
|
4488
5565
|
import * as React5 from "react";
|
|
4489
|
-
import {
|
|
4490
|
-
|
|
4491
|
-
|
|
5566
|
+
import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5567
|
+
var FOREST_IMAGE = "https://images.unsplash.com/photo-1523712999610-f77fbcfc3843?auto=format&fit=crop&q=80&w=800";
|
|
5568
|
+
var DEFAULT_LINK = "https://liquid-glass-react-studio.vercel.app/components";
|
|
5569
|
+
function refractionMap(width, height, radius, depth) {
|
|
5570
|
+
const resolution = Math.min(1, 280 / Math.max(width, height));
|
|
5571
|
+
const w = Math.max(8, Math.round(width * resolution));
|
|
5572
|
+
const h = Math.max(8, Math.round(height * resolution));
|
|
5573
|
+
const canvas = document.createElement("canvas");
|
|
5574
|
+
canvas.width = w;
|
|
5575
|
+
canvas.height = h;
|
|
5576
|
+
const context = canvas.getContext("2d");
|
|
5577
|
+
if (!context) return "";
|
|
5578
|
+
const pixels = context.createImageData(w, h);
|
|
5579
|
+
const halfW = w / 2, halfH = h / 2;
|
|
5580
|
+
const corner = Math.min(radius * resolution, halfW - 1, halfH - 1);
|
|
5581
|
+
const rimWidth = Math.max(3, (4 + depth / 100 * Math.min(w, h) * 0.42) * resolution);
|
|
5582
|
+
const distance = (x, y) => {
|
|
5583
|
+
const qx = Math.abs(x) - halfW + corner;
|
|
5584
|
+
const qy = Math.abs(y) - halfH + corner;
|
|
5585
|
+
return Math.hypot(Math.max(0, qx), Math.max(0, qy)) + Math.min(0, Math.max(qx, qy)) - corner;
|
|
5586
|
+
};
|
|
5587
|
+
for (let index = 0; index < w * h; index++) {
|
|
5588
|
+
const x = index % w + 0.5 - halfW;
|
|
5589
|
+
const y = Math.floor(index / w) + 0.5 - halfH;
|
|
5590
|
+
const d = distance(x, y);
|
|
5591
|
+
let red = 128, green = 128;
|
|
5592
|
+
if (d <= 0.5) {
|
|
5593
|
+
const edge = Math.pow(1 - Math.min(1, Math.max(0, -d) / rimWidth), 0.72);
|
|
5594
|
+
const curved = edge * edge * (3 - 2 * edge);
|
|
5595
|
+
const dx = distance(x + 1, y) - distance(x - 1, y);
|
|
5596
|
+
const dy = distance(x, y + 1) - distance(x, y - 1);
|
|
5597
|
+
const length = Math.hypot(dx, dy) || 1;
|
|
5598
|
+
const face = 0.18 * (1 - curved);
|
|
5599
|
+
red = Math.round(128 + 127 * (dx / length * curved + x / halfW * face));
|
|
5600
|
+
green = Math.round(128 + 127 * (dy / length * curved + y / halfH * face));
|
|
5601
|
+
}
|
|
5602
|
+
pixels.data.set([Math.max(0, Math.min(255, red)), Math.max(0, Math.min(255, green)), 128, 255], index * 4);
|
|
5603
|
+
}
|
|
5604
|
+
context.putImageData(pixels, 0, 0);
|
|
5605
|
+
return canvas.toDataURL("image/png");
|
|
5606
|
+
}
|
|
5607
|
+
function GlassMaterial({ id, width, height, radius, depth, refraction, dispersion, liquidity }) {
|
|
5608
|
+
const [map, setMap] = React5.useState("");
|
|
5609
|
+
React5.useEffect(() => {
|
|
5610
|
+
setMap(refractionMap(width, height, radius, depth));
|
|
5611
|
+
}, [width, height, radius, depth]);
|
|
5612
|
+
const bend = refraction / 100 * 0.36;
|
|
5613
|
+
const spread = bend * dispersion / 100 * 0.4;
|
|
5614
|
+
const wobble = liquidity / 100 * 0.06;
|
|
5615
|
+
const channelMap = wobble > 2e-3 ? "warped" : "normal";
|
|
5616
|
+
return /* @__PURE__ */ jsx17("svg", { width: "0", height: "0", style: { position: "absolute" }, "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx17("filter", { id, x: "-.08", y: "-.08", width: "1.16", height: "1.16", filterUnits: "objectBoundingBox", primitiveUnits: "objectBoundingBox", colorInterpolationFilters: "sRGB", children: map && /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
5617
|
+
/* @__PURE__ */ jsx17("feImage", { href: map, x: "0", y: "0", width: "1", height: "1", preserveAspectRatio: "none", result: "normal" }),
|
|
5618
|
+
wobble > 2e-3 && /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
5619
|
+
/* @__PURE__ */ jsx17("feTurbulence", { type: "fractalNoise", baseFrequency: ".012 .016", numOctaves: 1, seed: 7, result: "noise" }),
|
|
5620
|
+
/* @__PURE__ */ jsx17("feDisplacementMap", { in: "normal", in2: "noise", scale: wobble, xChannelSelector: "R", yChannelSelector: "G", result: "warped" })
|
|
5621
|
+
] }),
|
|
5622
|
+
/* @__PURE__ */ jsx17("feDisplacementMap", { in: "SourceGraphic", in2: channelMap, scale: Math.max(0, bend - spread), xChannelSelector: "R", yChannelSelector: "G", result: "red" }),
|
|
5623
|
+
/* @__PURE__ */ jsx17("feColorMatrix", { in: "red", type: "matrix", values: "1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0", result: "redOnly" }),
|
|
5624
|
+
/* @__PURE__ */ jsx17("feDisplacementMap", { in: "SourceGraphic", in2: channelMap, scale: bend, xChannelSelector: "R", yChannelSelector: "G", result: "green" }),
|
|
5625
|
+
/* @__PURE__ */ jsx17("feColorMatrix", { in: "green", type: "matrix", values: "0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0", result: "greenOnly" }),
|
|
5626
|
+
/* @__PURE__ */ jsx17("feDisplacementMap", { in: "SourceGraphic", in2: channelMap, scale: bend + spread * 1.15, xChannelSelector: "R", yChannelSelector: "G", result: "blue" }),
|
|
5627
|
+
/* @__PURE__ */ jsx17("feColorMatrix", { in: "blue", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0", result: "blueOnly" }),
|
|
5628
|
+
/* @__PURE__ */ jsx17("feComposite", { in: "redOnly", in2: "greenOnly", operator: "arithmetic", k2: "1", k3: "1", result: "redGreen" }),
|
|
5629
|
+
/* @__PURE__ */ jsx17("feComposite", { in: "redGreen", in2: "blueOnly", operator: "arithmetic", k2: "1", k3: "1" })
|
|
5630
|
+
] }) }) });
|
|
5631
|
+
}
|
|
5632
|
+
function Icon2({ kind, className = "", strokeWidth = 2.25, draw = false }) {
|
|
5633
|
+
const paths = {
|
|
5634
|
+
share: "M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.933-2.185 2.25 2.25 0 0 0-3.933 2.185Z",
|
|
5635
|
+
save: "M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z",
|
|
5636
|
+
check: "M5.25 12.7033 9.40385 17.37 18.75 6.87",
|
|
5637
|
+
globe: "M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418",
|
|
5638
|
+
copy: "M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75"
|
|
5639
|
+
};
|
|
5640
|
+
return /* @__PURE__ */ jsx17("svg", { className: `mgs-icon ${className}`, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth, "aria-hidden": "true", children: /* @__PURE__ */ jsx17("path", { className: draw ? "mgs-tick" : void 0, pathLength: kind === "check" ? 1 : void 0, d: paths[kind] }) });
|
|
5641
|
+
}
|
|
5642
|
+
async function copyText(text) {
|
|
5643
|
+
const previous = document.activeElement;
|
|
5644
|
+
const textarea = document.createElement("textarea");
|
|
5645
|
+
textarea.value = text;
|
|
5646
|
+
textarea.readOnly = true;
|
|
5647
|
+
Object.assign(textarea.style, { position: "fixed", top: "0", left: "0", opacity: "0", pointerEvents: "none" });
|
|
5648
|
+
document.body.append(textarea);
|
|
5649
|
+
textarea.select();
|
|
5650
|
+
let copied = false;
|
|
5651
|
+
try {
|
|
5652
|
+
copied = document.execCommand("copy");
|
|
5653
|
+
} catch {
|
|
5654
|
+
}
|
|
5655
|
+
textarea.remove();
|
|
5656
|
+
previous?.focus({ preventScroll: true });
|
|
5657
|
+
if (copied) return true;
|
|
5658
|
+
try {
|
|
5659
|
+
await navigator.clipboard.writeText(text);
|
|
5660
|
+
return true;
|
|
5661
|
+
} catch {
|
|
5662
|
+
return false;
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5665
|
+
function LiquidGlassSheet({ title = "Autumn forest", subtitle = "Liquid glass sheet", backgroundImage = FOREST_IMAGE, link = DEFAULT_LINK, linkLabel = "liquid-glass-react-studio", defaultOpen = true, onOpenChange, onSaveChange, onShare, theme = "light", className = "", style } = {}) {
|
|
4492
5666
|
const [open, setOpen] = React5.useState(defaultOpen);
|
|
5667
|
+
const [mounted, setMounted] = React5.useState(defaultOpen);
|
|
4493
5668
|
const [saved, setSaved] = React5.useState(false);
|
|
4494
|
-
const [status, setStatus] = React5.useState("");
|
|
5669
|
+
const [status, setStatus] = React5.useState("idle");
|
|
5670
|
+
const [touched, setTouched] = React5.useState(false);
|
|
5671
|
+
const [highlight2, setHighlight] = React5.useState(null);
|
|
4495
5672
|
const [drag, setDrag] = React5.useState(0);
|
|
4496
|
-
const
|
|
5673
|
+
const [dragging, setDragging] = React5.useState(false);
|
|
5674
|
+
const [closing, setClosing] = React5.useState(false);
|
|
4497
5675
|
const trigger = React5.useRef(null);
|
|
4498
|
-
const
|
|
4499
|
-
const
|
|
5676
|
+
const list = React5.useRef(null);
|
|
5677
|
+
const dragStart = React5.useRef(null);
|
|
5678
|
+
const dragOffset = React5.useRef(0);
|
|
5679
|
+
const timer = React5.useRef(void 0);
|
|
5680
|
+
const closeTimer = React5.useRef(void 0);
|
|
5681
|
+
const frames = React5.useRef([]);
|
|
5682
|
+
const attempt = React5.useRef(0);
|
|
5683
|
+
const id = `mgs-${React5.useId().replace(/:/g, "")}`;
|
|
4500
5684
|
const wasOpened = React5.useRef(false);
|
|
4501
|
-
function changeOpen(value) {
|
|
4502
|
-
setOpen(value);
|
|
4503
|
-
setDrag(0);
|
|
4504
|
-
onOpenChange?.(value);
|
|
4505
|
-
if (!value) trigger.current?.focus();
|
|
4506
|
-
}
|
|
4507
5685
|
React5.useEffect(() => {
|
|
4508
|
-
if (open && wasOpened.current)
|
|
5686
|
+
if (open && wasOpened.current) list.current?.querySelector("button")?.focus({ preventScroll: true });
|
|
4509
5687
|
wasOpened.current = true;
|
|
4510
5688
|
}, [open]);
|
|
5689
|
+
React5.useEffect(() => () => {
|
|
5690
|
+
clearTimeout(timer.current);
|
|
5691
|
+
clearTimeout(closeTimer.current);
|
|
5692
|
+
frames.current.forEach(cancelAnimationFrame);
|
|
5693
|
+
attempt.current++;
|
|
5694
|
+
}, []);
|
|
5695
|
+
function changeOpen(next) {
|
|
5696
|
+
if (next === open) return;
|
|
5697
|
+
clearTimeout(closeTimer.current);
|
|
5698
|
+
if (next) {
|
|
5699
|
+
setMounted(true);
|
|
5700
|
+
setClosing(false);
|
|
5701
|
+
} else {
|
|
5702
|
+
setClosing(true);
|
|
5703
|
+
setHighlight(null);
|
|
5704
|
+
closeTimer.current = setTimeout(() => {
|
|
5705
|
+
setMounted(false);
|
|
5706
|
+
setClosing(false);
|
|
5707
|
+
}, 350);
|
|
5708
|
+
}
|
|
5709
|
+
setOpen(next);
|
|
5710
|
+
setDrag(0);
|
|
5711
|
+
dragOffset.current = 0;
|
|
5712
|
+
dragStart.current = null;
|
|
5713
|
+
setDragging(false);
|
|
5714
|
+
onOpenChange?.(next);
|
|
5715
|
+
if (!next) requestAnimationFrame(() => trigger.current?.focus({ preventScroll: true }));
|
|
5716
|
+
}
|
|
4511
5717
|
async function copy() {
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
5718
|
+
const current = ++attempt.current;
|
|
5719
|
+
clearTimeout(timer.current);
|
|
5720
|
+
frames.current.forEach(cancelAnimationFrame);
|
|
5721
|
+
const copied2 = await copyText(link);
|
|
5722
|
+
if (current !== attempt.current) return;
|
|
5723
|
+
setTouched(true);
|
|
5724
|
+
setStatus("idle");
|
|
5725
|
+
frames.current = [requestAnimationFrame(() => {
|
|
5726
|
+
frames.current.push(requestAnimationFrame(() => {
|
|
5727
|
+
if (current !== attempt.current) return;
|
|
5728
|
+
setStatus(copied2 ? "copied" : "failed");
|
|
5729
|
+
timer.current = setTimeout(() => setStatus("idle"), copied2 ? 1800 : 1400);
|
|
5730
|
+
}));
|
|
5731
|
+
})];
|
|
4518
5732
|
}
|
|
4519
5733
|
function keys(event) {
|
|
5734
|
+
if (!open) return;
|
|
4520
5735
|
if (event.key === "Escape") {
|
|
4521
5736
|
event.preventDefault();
|
|
4522
5737
|
changeOpen(false);
|
|
5738
|
+
return;
|
|
4523
5739
|
}
|
|
4524
|
-
if (event.key
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
}
|
|
5740
|
+
if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
|
|
5741
|
+
const buttons = Array.from(list.current?.querySelectorAll("button") ?? []);
|
|
5742
|
+
const index = buttons.indexOf(document.activeElement);
|
|
5743
|
+
event.preventDefault();
|
|
5744
|
+
buttons[(index + (event.key === "ArrowDown" ? 1 : -1) + buttons.length) % buttons.length]?.focus();
|
|
4530
5745
|
}
|
|
4531
|
-
|
|
5746
|
+
function endDrag(cancelled = false) {
|
|
5747
|
+
if (dragStart.current === null) return;
|
|
5748
|
+
dragStart.current = null;
|
|
5749
|
+
setDragging(false);
|
|
5750
|
+
if (!cancelled && dragOffset.current > 90) changeOpen(false);
|
|
5751
|
+
dragOffset.current = 0;
|
|
5752
|
+
setDrag(0);
|
|
5753
|
+
}
|
|
5754
|
+
const copied = status === "copied", failed = status === "failed";
|
|
5755
|
+
const filterStyle = { "--mgs-pane-filter": `url(#${id}-pane)`, "--mgs-trigger-filter": `url(#${id}-trigger)` };
|
|
5756
|
+
return /* @__PURE__ */ jsxs17("section", { className: `mova-glass-sheet${open ? " is-open" : ""} ${className}`, "data-theme": theme, onKeyDown: keys, style: { ...filterStyle, backgroundImage: `url(${JSON.stringify(backgroundImage)})`, ...style }, "aria-label": title, children: [
|
|
4532
5757
|
/* @__PURE__ */ jsx17("style", { children: css5 }),
|
|
4533
|
-
/* @__PURE__ */
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
/* @__PURE__ */ jsx17("
|
|
4539
|
-
/* @__PURE__ */ jsx17("
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
}, "aria-hidden": "true", children: /* @__PURE__ */ jsx17("span", {}) }),
|
|
4556
|
-
/* @__PURE__ */ jsxs17("header", { children: [
|
|
4557
|
-
/* @__PURE__ */ jsxs17("div", { children: [
|
|
4558
|
-
/* @__PURE__ */ jsx17("h2", { id: titleId, children: title }),
|
|
4559
|
-
/* @__PURE__ */ jsx17("p", { children: subtitle })
|
|
5758
|
+
/* @__PURE__ */ jsx17(GlassMaterial, { id: `${id}-pane`, width: 304, height: 244, radius: 28, depth: 30, refraction: 78, dispersion: 42, liquidity: 6 }),
|
|
5759
|
+
/* @__PURE__ */ jsx17(GlassMaterial, { id: `${id}-trigger`, width: 132, height: 44, radius: 22, depth: 26, refraction: 60, dispersion: 30, liquidity: 4 }),
|
|
5760
|
+
/* @__PURE__ */ jsx17("div", { className: `mgs-scrim mgs-t-modal${open ? " is-open" : ""}${closing ? " is-closing" : ""}`, onClick: () => changeOpen(false), "aria-hidden": "true" }),
|
|
5761
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "mgs-trigger", ref: trigger, "aria-label": "Open sheet", "aria-expanded": open, "aria-controls": `${id}-sheet`, "aria-hidden": open, tabIndex: open ? -1 : 0, onClick: () => changeOpen(true), children: /* @__PURE__ */ jsx17("span", { children: "Open sheet" }) }),
|
|
5762
|
+
/* @__PURE__ */ jsxs17("div", { className: `mgs-sheet${dragging ? " is-dragging" : ""}`, role: "dialog", "aria-labelledby": `${id}-title`, "aria-hidden": !open, inert: !open, id: `${id}-sheet`, style: { "--drag": `${drag}px` }, children: [
|
|
5763
|
+
/* @__PURE__ */ jsx17("div", { className: "mgs-glass", "data-open": open }),
|
|
5764
|
+
/* @__PURE__ */ jsx17("div", { className: "mgs-t-panel-slide mgs-panel", "data-open": open, children: mounted && /* @__PURE__ */ jsxs17("div", { className: "mgs-body", children: [
|
|
5765
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "mgs-grab", "aria-label": "Drag down to close", onPointerDown: (event) => {
|
|
5766
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
5767
|
+
dragStart.current = event.clientY;
|
|
5768
|
+
setDragging(true);
|
|
5769
|
+
}, onPointerMove: (event) => {
|
|
5770
|
+
if (dragStart.current === null) return;
|
|
5771
|
+
const delta = event.clientY - dragStart.current;
|
|
5772
|
+
dragOffset.current = delta >= 0 ? delta : -Math.pow(-delta, 0.6) * 2;
|
|
5773
|
+
setDrag(dragOffset.current);
|
|
5774
|
+
}, onPointerUp: () => endDrag(), onPointerCancel: () => endDrag(true), onClick: (event) => {
|
|
5775
|
+
if (event.detail === 0) changeOpen(false);
|
|
5776
|
+
}, children: /* @__PURE__ */ jsx17("span", {}) }),
|
|
5777
|
+
/* @__PURE__ */ jsxs17("header", { className: "mgs-head", children: [
|
|
5778
|
+
/* @__PURE__ */ jsx17("h2", { id: `${id}-title`, className: "mgs-title", children: title }),
|
|
5779
|
+
/* @__PURE__ */ jsx17("p", { className: "mgs-meta", children: subtitle })
|
|
4560
5780
|
] }),
|
|
4561
|
-
/* @__PURE__ */
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
] })
|
|
5781
|
+
/* @__PURE__ */ jsxs17("div", { className: "mgs-list", ref: list, onMouseLeave: () => setHighlight(null), children: [
|
|
5782
|
+
/* @__PURE__ */ jsx17("span", { className: "mgs-hl", style: { transform: `translateY(${(highlight2 ?? 0) * 44}px)`, opacity: highlight2 === null ? 0 : 1 } }),
|
|
5783
|
+
/* @__PURE__ */ jsxs17("button", { type: "button", className: "mgs-row", onMouseEnter: () => setHighlight(0), onFocus: () => setHighlight(0), onBlur: () => setHighlight(null), onClick: () => {
|
|
5784
|
+
onShare?.();
|
|
5785
|
+
changeOpen(false);
|
|
5786
|
+
}, children: [
|
|
5787
|
+
/* @__PURE__ */ jsx17(Icon2, { kind: "share" }),
|
|
5788
|
+
/* @__PURE__ */ jsx17("span", { className: "mgs-label", children: "Share" })
|
|
5789
|
+
] }),
|
|
5790
|
+
/* @__PURE__ */ jsxs17("button", { type: "button", className: `mgs-row${saved ? " mgs-saved" : ""}`, "aria-pressed": saved, onMouseEnter: () => setHighlight(1), onFocus: () => setHighlight(1), onBlur: () => setHighlight(null), onClick: () => {
|
|
5791
|
+
setSaved(!saved);
|
|
5792
|
+
onSaveChange?.(!saved);
|
|
5793
|
+
}, children: [
|
|
5794
|
+
/* @__PURE__ */ jsxs17("span", { className: "mgs-slot", children: [
|
|
5795
|
+
/* @__PURE__ */ jsx17(Icon2, { kind: "save", className: "mgs-icon-a" }),
|
|
5796
|
+
/* @__PURE__ */ jsx17(Icon2, { kind: "check", className: "mgs-icon-b", strokeWidth: 3 })
|
|
5797
|
+
] }),
|
|
5798
|
+
/* @__PURE__ */ jsx17("span", { className: "mgs-label", children: saved ? "Saved" : "Save" })
|
|
5799
|
+
] }),
|
|
5800
|
+
/* @__PURE__ */ jsxs17("div", { className: `mgs-linkrow${copied ? " is-copied" : ""}${failed ? " is-failed" : ""}`, onMouseEnter: () => setHighlight(2), onFocus: () => setHighlight(2), onBlur: () => setHighlight(null), children: [
|
|
5801
|
+
/* @__PURE__ */ jsxs17("button", { type: "button", className: "mgs-row mgs-linkmain", "aria-label": copied ? "Link copied" : failed ? "Copy blocked" : "Copy link", onClick: () => void copy(), children: [
|
|
5802
|
+
/* @__PURE__ */ jsxs17("span", { className: "mgs-slot", children: [
|
|
5803
|
+
/* @__PURE__ */ jsx17(Icon2, { kind: "globe", className: "mgs-icon-a" }),
|
|
5804
|
+
/* @__PURE__ */ jsx17(Icon2, { kind: "check", className: "mgs-icon-b", strokeWidth: 3, draw: true })
|
|
5805
|
+
] }),
|
|
5806
|
+
/* @__PURE__ */ jsx17("span", { className: `mgs-label${touched ? " mgs-label-anim" : ""}`, children: copied ? "Link copied" : failed ? "Copy blocked" : linkLabel }, status)
|
|
5807
|
+
] }),
|
|
5808
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "mgs-copy", "aria-label": "Copy link", onClick: () => void copy(), children: /* @__PURE__ */ jsx17(Icon2, { kind: "copy" }) })
|
|
5809
|
+
] })
|
|
5810
|
+
] })
|
|
5811
|
+
] }) })
|
|
5812
|
+
] }),
|
|
5813
|
+
/* @__PURE__ */ jsx17("span", { className: "mgs-status", role: "status", "aria-live": "polite", children: copied ? "Link copied" : failed ? "Copy blocked" : "" })
|
|
4595
5814
|
] });
|
|
4596
5815
|
}
|
|
4597
5816
|
var css5 = `
|
|
4598
|
-
.mova-glass-sheet{
|
|
5817
|
+
.mova-glass-sheet{
|
|
5818
|
+
--panel-open-dur: 400ms;
|
|
5819
|
+
--panel-close-dur: 350ms;
|
|
5820
|
+
--panel-translate-y: 100px;
|
|
5821
|
+
--panel-blur: 2px;
|
|
5822
|
+
--panel-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
5823
|
+
--modal-open-dur: 250ms;
|
|
5824
|
+
--modal-close-dur: 150ms;
|
|
5825
|
+
--modal-scale: 0.96;
|
|
5826
|
+
--modal-scale-close: 0.96;
|
|
5827
|
+
--modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
5828
|
+
--scrim-dur:150ms;
|
|
5829
|
+
--hl-dur:250ms;
|
|
5830
|
+
--hl-ease:cubic-bezier(0.22,1,0.36,1);
|
|
5831
|
+
--icon-dur:250ms;
|
|
5832
|
+
--press-scale:0.97;
|
|
5833
|
+
--press-dur:150ms;
|
|
5834
|
+
--ease-smooth-out:cubic-bezier(0.22,1,0.36,1);
|
|
5835
|
+
--ease-spring:cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
5836
|
+
--mgs-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
|
|
5837
|
+
--mgs-ease-liquid: cubic-bezier(0.16, 1, 0.3, 1);
|
|
5838
|
+
--mgs-press: 160ms;
|
|
5839
|
+
}
|
|
5840
|
+
|
|
5841
|
+
.mova-glass-sheet{position:relative;box-sizing:border-box;width:320px;max-width:100%;height:360px;font:400 13px/20px Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;border-radius:24px;overflow:hidden;background-size:cover;background-position:center;box-shadow:0 0 0 1px rgba(0,0,0,.04),0 8px 32px -4px rgba(0,0,0,.06),0 1px 3px 0 rgba(0,0,0,.04);color:#fff}
|
|
5842
|
+
.mova-glass-sheet :is(button,a){font:inherit;color:inherit;text-decoration:none}
|
|
5843
|
+
.mova-glass-sheet :where(button){border:0;background:none;padding:0;cursor:pointer}
|
|
5844
|
+
.mgs-scrim{position:absolute;inset:0;background:rgba(0,0,0,.28)}
|
|
5845
|
+
|
|
5846
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Compact iOS 26 glass trigger (44px full-round capsule) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
5847
|
+
.mova-glass-sheet .mgs-trigger{
|
|
5848
|
+
position:absolute;
|
|
5849
|
+
left:50%;
|
|
5850
|
+
bottom:28px;
|
|
5851
|
+
translate:-50% 0;
|
|
5852
|
+
isolation:isolate;
|
|
5853
|
+
overflow:hidden;
|
|
5854
|
+
box-sizing:border-box;
|
|
5855
|
+
width:auto;
|
|
5856
|
+
height:44px;
|
|
5857
|
+
padding:0 22px;
|
|
5858
|
+
border-radius:999px;
|
|
5859
|
+
display:inline-flex;
|
|
5860
|
+
align-items:center;
|
|
5861
|
+
justify-content:center;
|
|
5862
|
+
white-space:nowrap;
|
|
5863
|
+
color:#fff;
|
|
5864
|
+
font-size:15px;
|
|
5865
|
+
line-height:20px;
|
|
5866
|
+
font-weight:600;
|
|
5867
|
+
letter-spacing:-0.01em;
|
|
5868
|
+
text-shadow:0 1px 2px rgb(0 0 0 / 0.25);
|
|
5869
|
+
background:rgb(255 255 255 / 0.10);
|
|
5870
|
+
-webkit-backdrop-filter:var(--mgs-trigger-filter) blur(2px) saturate(170%);
|
|
5871
|
+
backdrop-filter:var(--mgs-trigger-filter) blur(2px) saturate(170%);
|
|
5872
|
+
box-shadow:
|
|
5873
|
+
inset 1.5px 1.5px 0.5px -0.5px rgb(255 255 255 / 0.12),
|
|
5874
|
+
inset -1px -1px 0.5px -0.5px rgb(255 255 255 / 0.04),
|
|
5875
|
+
inset 0 0 0 1px rgb(255 255 255 / 0.18),
|
|
5876
|
+
0 0 0 0.5px rgb(255 255 255 / 0.22),
|
|
5877
|
+
0 8px 24px rgb(0 0 0 / 0.18);
|
|
5878
|
+
transition:
|
|
5879
|
+
transform 380ms var(--ease-spring),
|
|
5880
|
+
box-shadow var(--mgs-press) var(--mgs-ease-out),
|
|
5881
|
+
opacity var(--scrim-dur) var(--ease-smooth-out);
|
|
5882
|
+
}
|
|
5883
|
+
.mgs-trigger::before{
|
|
5884
|
+
content:"";
|
|
5885
|
+
position:absolute;
|
|
5886
|
+
inset:0;
|
|
5887
|
+
z-index:-1;
|
|
5888
|
+
border-radius:inherit;
|
|
5889
|
+
pointer-events:none;
|
|
5890
|
+
background:radial-gradient(70% 55% at 69.8% 30.2%, rgb(255 255 255 / 0.035) 0%, transparent 46%);
|
|
5891
|
+
mix-blend-mode:plus-lighter;
|
|
5892
|
+
opacity:0;
|
|
5893
|
+
transition:opacity 240ms var(--mgs-ease-out);
|
|
5894
|
+
}
|
|
5895
|
+
.mgs-trigger:hover::before{opacity:1}
|
|
5896
|
+
.mgs-trigger::after{
|
|
5897
|
+
content:"";
|
|
5898
|
+
position:absolute;
|
|
5899
|
+
inset:0;
|
|
5900
|
+
z-index:-1;
|
|
5901
|
+
border-radius:inherit;
|
|
5902
|
+
pointer-events:none;
|
|
5903
|
+
background:radial-gradient(circle at 50% 50%, rgb(255 255 255 / 0.95) 0%, rgb(255 255 255 / 0.48) 22%, rgb(255 255 255 / 0.1) 48%, transparent 65%);
|
|
5904
|
+
mix-blend-mode:plus-lighter;
|
|
5905
|
+
opacity:0;
|
|
5906
|
+
transform:scale(0.65);
|
|
5907
|
+
transition:opacity var(--mgs-press) var(--mgs-ease-out), transform var(--mgs-press) var(--mgs-ease-out);
|
|
5908
|
+
}
|
|
5909
|
+
.mgs-trigger:active{transform:scale(0.94)}
|
|
5910
|
+
.mgs-trigger:active::before{opacity:1}
|
|
5911
|
+
.mgs-trigger:active::after{opacity:0.110;transform:scale(1)}
|
|
5912
|
+
.mova-glass-sheet.is-open .mgs-trigger{opacity:0;pointer-events:none}
|
|
5913
|
+
|
|
5914
|
+
@supports not (backdrop-filter: url(#mgs-filter)){
|
|
5915
|
+
.mova-glass-sheet .mgs-trigger{
|
|
5916
|
+
-webkit-backdrop-filter:blur(25px) saturate(160%) brightness(1.06);
|
|
5917
|
+
backdrop-filter:blur(25px) saturate(160%) brightness(1.06);
|
|
5918
|
+
background:linear-gradient(145deg, rgb(255 255 255 / 0.015) 0%, rgb(255 255 255 / 0.004) 45%, rgb(255 255 255 / 0.096) 100%);
|
|
5919
|
+
box-shadow:
|
|
5920
|
+
inset 2px 2px 1px -0.5px rgb(255 255 255 / 0.066),
|
|
5921
|
+
inset -1.5px -1.5px 1px -0.5px rgb(255 255 255 / 0.025),
|
|
5922
|
+
inset 0 0 0 1.2px rgb(255 255 255 / 0.224),
|
|
5923
|
+
0 20px 48px rgb(0 0 0 / 0.24);
|
|
5924
|
+
}
|
|
5925
|
+
.mgs-trigger::before{opacity:0.75}
|
|
5926
|
+
}
|
|
5927
|
+
@media (prefers-reduced-transparency: reduce){
|
|
5928
|
+
.mova-glass-sheet .mgs-trigger{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgb(255 255 255 / 0.88);color:#111;text-shadow:none}
|
|
5929
|
+
}
|
|
5930
|
+
|
|
5931
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Sheet \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
5932
|
+
.mgs-sheet{position:absolute;left:8px;right:8px;bottom:8px;height:244px;border-radius:28px;transform:translateY(var(--drag,0px));transition:transform var(--panel-open-dur) var(--panel-ease);touch-action:none;pointer-events:none}
|
|
5933
|
+
.mova-glass-sheet.is-open .mgs-sheet{pointer-events:auto}
|
|
5934
|
+
.mgs-panel{position:absolute;inset:0}
|
|
5935
|
+
.mgs-sheet.is-dragging{transition:none!important}
|
|
5936
|
+
|
|
5937
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 REAL LIQUID GLASS MATERIAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
5938
|
+
.mgs-glass{
|
|
5939
|
+
position:absolute;
|
|
5940
|
+
inset:0;
|
|
5941
|
+
isolation:isolate;
|
|
5942
|
+
overflow:hidden;
|
|
5943
|
+
border-radius:28px;
|
|
5944
|
+
corner-shape:squircle;
|
|
5945
|
+
pointer-events:none;
|
|
5946
|
+
background:rgb(255 255 255 / 0.080);
|
|
5947
|
+
-webkit-backdrop-filter:var(--mgs-pane-filter) blur(3px) saturate(160%);
|
|
5948
|
+
backdrop-filter:var(--mgs-pane-filter) blur(3px) saturate(160%);
|
|
5949
|
+
box-shadow:
|
|
5950
|
+
inset 1.5px 1.5px 0.5px -0.5px rgb(255 255 255 / 0.055),
|
|
5951
|
+
inset -1px -1px 0.5px -0.5px rgb(255 255 255 / 0.018),
|
|
5952
|
+
inset 0 0 0 1.2px rgb(255 255 255 / 0.140),
|
|
5953
|
+
0 0 0 0.5px rgb(255 255 255 / 0.22),
|
|
5954
|
+
0 18px 40px rgb(0 0 0 / 0.2);
|
|
5955
|
+
transform:translateY(var(--panel-translate-y));
|
|
5956
|
+
opacity:0;
|
|
5957
|
+
transition:
|
|
5958
|
+
transform var(--panel-close-dur) var(--panel-ease),
|
|
5959
|
+
opacity var(--panel-close-dur) var(--panel-ease),
|
|
5960
|
+
box-shadow var(--mgs-press) var(--mgs-ease-out);
|
|
5961
|
+
}
|
|
5962
|
+
.mgs-glass[data-open="true"]{
|
|
5963
|
+
transform:none;
|
|
5964
|
+
opacity:1;
|
|
5965
|
+
transition:
|
|
5966
|
+
transform var(--panel-open-dur) var(--panel-ease),
|
|
5967
|
+
opacity var(--panel-open-dur) var(--panel-ease),
|
|
5968
|
+
box-shadow var(--mgs-press) var(--mgs-ease-out);
|
|
5969
|
+
}
|
|
5970
|
+
.mgs-glass::before{
|
|
5971
|
+
content:"";
|
|
5972
|
+
position:absolute;
|
|
5973
|
+
inset:0;
|
|
5974
|
+
z-index:-1;
|
|
5975
|
+
border-radius:inherit;
|
|
5976
|
+
pointer-events:none;
|
|
5977
|
+
background:radial-gradient(70% 55% at 69.8% 30.2%, rgb(255 255 255 / 0.035) 0%, transparent 46%);
|
|
5978
|
+
mix-blend-mode:plus-lighter;
|
|
5979
|
+
opacity:0;
|
|
5980
|
+
transition:opacity 240ms var(--mgs-ease-out);
|
|
5981
|
+
}
|
|
5982
|
+
.mgs-sheet:hover .mgs-glass::before{opacity:1}
|
|
5983
|
+
.mgs-glass::after{
|
|
5984
|
+
content:"";
|
|
5985
|
+
position:absolute;
|
|
5986
|
+
inset:0;
|
|
5987
|
+
z-index:-1;
|
|
5988
|
+
border-radius:inherit;
|
|
5989
|
+
pointer-events:none;
|
|
5990
|
+
background:radial-gradient(circle at 50% 50%, rgb(255 255 255 / 0.95) 0%, rgb(255 255 255 / 0.48) 22%, rgb(255 255 255 / 0.1) 48%, transparent 65%);
|
|
5991
|
+
mix-blend-mode:plus-lighter;
|
|
5992
|
+
opacity:0;
|
|
5993
|
+
transform:scale(0.65);
|
|
5994
|
+
transition:opacity var(--mgs-press) var(--mgs-ease-out), transform var(--mgs-press) var(--mgs-ease-out);
|
|
5995
|
+
}
|
|
5996
|
+
.mgs-sheet:active .mgs-glass::before{opacity:1}
|
|
5997
|
+
.mgs-sheet:active .mgs-glass::after{opacity:0.110;transform:scale(1)}
|
|
5998
|
+
|
|
5999
|
+
@supports not (backdrop-filter: url(#mgs-filter)){
|
|
6000
|
+
.mgs-glass{
|
|
6001
|
+
-webkit-backdrop-filter:blur(25px) saturate(160%) brightness(1.06);
|
|
6002
|
+
backdrop-filter:blur(25px) saturate(160%) brightness(1.06);
|
|
6003
|
+
background:linear-gradient(145deg, rgb(255 255 255 / 0.015) 0%, rgb(255 255 255 / 0.004) 45%, rgb(255 255 255 / 0.096) 100%);
|
|
6004
|
+
box-shadow:
|
|
6005
|
+
inset 2px 2px 1px -0.5px rgb(255 255 255 / 0.066),
|
|
6006
|
+
inset -1.5px -1.5px 1px -0.5px rgb(255 255 255 / 0.025),
|
|
6007
|
+
inset 0 0 0 1.2px rgb(255 255 255 / 0.224),
|
|
6008
|
+
0 20px 48px rgb(0 0 0 / 0.24);
|
|
6009
|
+
}
|
|
6010
|
+
.mgs-glass::before{opacity:0.75}
|
|
6011
|
+
}
|
|
6012
|
+
@media (prefers-reduced-transparency: reduce){
|
|
6013
|
+
.mgs-glass{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgb(255 255 255 / 0.88)}
|
|
6014
|
+
}
|
|
6015
|
+
|
|
6016
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Body / grabber / header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
6017
|
+
.mgs-body{position:relative;padding:0 8px 8px}
|
|
6018
|
+
.mgs-grab{display:flex;justify-content:center;width:100%;height:24px;align-items:center;cursor:grab;touch-action:none}
|
|
6019
|
+
.mgs-grab:is(:active,.is-pressed){cursor:grabbing}
|
|
6020
|
+
.mgs-grab span{width:36px;height:5px;border-radius:5px;background:rgba(255,255,255,.7)}
|
|
6021
|
+
.mgs-head{padding:0 12px 8px}
|
|
6022
|
+
.mgs-title{margin:0;font-size:16px;line-height:22px;font-weight:500}
|
|
6023
|
+
.mgs-meta{margin:0;font-size:12px;line-height:16px;color:rgba(255,255,255,.85)}
|
|
6024
|
+
|
|
6025
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 List / rows / highlight \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
6026
|
+
.mgs-list{position:relative;display:flex;flex-direction:column;margin-top:4px}
|
|
6027
|
+
.mgs-hl{position:absolute;left:0;right:0;top:0;height:44px;border-radius:16px;background:rgba(255,255,255,.2);box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);opacity:0;transition:transform var(--hl-dur) var(--hl-ease),opacity var(--hl-dur) var(--hl-ease);pointer-events:none}
|
|
6028
|
+
.mgs-row{box-sizing:border-box;position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px 0 10px;border-radius:16px;font-size:13px;line-height:20px;text-align:left;width:100%;outline:none}
|
|
6029
|
+
.mgs-row .mgs-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
6030
|
+
.mgs-row:focus-visible{box-shadow:0 0 0 2px rgba(255,255,255,.9)}
|
|
6031
|
+
.mgs-row .mgs-icon{flex:none}
|
|
6032
|
+
.mgs-slot{position:relative;width:16px;height:16px;flex:none}
|
|
6033
|
+
.mgs-slot .mgs-icon{position:absolute;inset:0;transition:opacity var(--icon-dur) ease-in-out,transform var(--icon-dur) ease-in-out,filter var(--icon-dur) ease-in-out}
|
|
6034
|
+
.mgs-slot .mgs-icon-b{opacity:0;transform:scale(.25);filter:blur(2px)}
|
|
6035
|
+
.mgs-saved .mgs-slot .mgs-icon-a{opacity:0;transform:scale(.25);filter:blur(2px)}
|
|
6036
|
+
.mgs-saved .mgs-slot .mgs-icon-b{opacity:1;transform:scale(1);filter:blur(0)}
|
|
6037
|
+
|
|
6038
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Link row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
6039
|
+
.mgs-linkrow{position:relative;display:flex;align-items:center;height:44px;border-radius:16px}
|
|
6040
|
+
.mgs-linkrow .mgs-row{flex:1;min-width:0;width:auto;padding-right:6px}
|
|
6041
|
+
|
|
6042
|
+
/* the link itself: soft flash when copied, shake when blocked */
|
|
6043
|
+
.mgs-linkmain{cursor:pointer;transition:transform 380ms var(--ease-spring)}
|
|
6044
|
+
.mgs-linkmain:active{transform:scale(var(--press-scale))}
|
|
6045
|
+
.mgs-linkrow.is-copied .mgs-linkmain{animation:mgs-row-flash 700ms var(--mgs-ease-out)}
|
|
6046
|
+
.mgs-linkrow.is-failed .mgs-linkmain{animation:mgs-copy-shake 420ms var(--mgs-ease-out)}
|
|
6047
|
+
|
|
6048
|
+
/* link icon: globe -> drawn checkmark */
|
|
6049
|
+
.mgs-linkrow.is-copied .mgs-linkmain .mgs-slot .mgs-icon-a{opacity:0;transform:scale(.25) rotate(-25deg);filter:blur(2px)}
|
|
6050
|
+
.mgs-linkrow.is-copied .mgs-linkmain .mgs-slot .mgs-icon-b{opacity:1;transform:scale(1);filter:blur(0)}
|
|
6051
|
+
.mgs-tick{stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset 380ms var(--mgs-ease-out)}
|
|
6052
|
+
.mgs-linkrow.is-copied .mgs-linkmain .mgs-tick{stroke-dashoffset:0;transition-delay:140ms}
|
|
6053
|
+
|
|
6054
|
+
/* corner copy icon: static, no copied/failed animation */
|
|
6055
|
+
.mgs-linkrow .mgs-copy{
|
|
6056
|
+
position:relative;
|
|
6057
|
+
display:grid;
|
|
6058
|
+
place-items:center;
|
|
6059
|
+
flex:none;
|
|
6060
|
+
width:32px;
|
|
6061
|
+
height:32px;
|
|
6062
|
+
margin-right:6px;
|
|
6063
|
+
border-radius:11px;
|
|
6064
|
+
corner-shape:squircle;
|
|
6065
|
+
outline:none;
|
|
6066
|
+
color:rgba(255,255,255,.85);
|
|
6067
|
+
background:transparent;
|
|
6068
|
+
}
|
|
6069
|
+
@media (hover: hover) and (pointer: fine){
|
|
6070
|
+
.mgs-linkrow .mgs-copy:hover{background:rgba(255,255,255,.18);color:#fff}
|
|
6071
|
+
}
|
|
6072
|
+
.mgs-linkrow .mgs-copy:focus-visible{box-shadow:0 0 0 2px rgba(255,255,255,.9)}
|
|
6073
|
+
|
|
6074
|
+
/* label swaps with a soft blur-in */
|
|
6075
|
+
.mgs-label-anim{animation:mgs-label-in 320ms var(--mgs-ease-out)}
|
|
6076
|
+
|
|
6077
|
+
@keyframes mgs-copy-shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-4px)}40%{transform:translateX(4px)}60%{transform:translateX(-3px)}80%{transform:translateX(2px)}}
|
|
6078
|
+
@keyframes mgs-label-in{from{opacity:0;transform:translateY(6px);filter:blur(3px)}to{opacity:1;transform:none;filter:blur(0)}}
|
|
6079
|
+
@keyframes mgs-row-flash{0%{background:rgba(255,255,255,.26)}100%{background:rgba(255,255,255,0)}}
|
|
6080
|
+
|
|
6081
|
+
/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Motion helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
6082
|
+
.mgs-t-panel-slide{transform:translateY(var(--panel-translate-y));opacity:0;filter:blur(var(--panel-blur));pointer-events:none;transition:transform var(--panel-close-dur) var(--panel-ease),opacity var(--panel-close-dur) var(--panel-ease),filter var(--panel-close-dur) var(--panel-ease)}
|
|
6083
|
+
.mgs-t-panel-slide[data-open="true"]{transform:translateY(0);opacity:1;filter:none;pointer-events:auto;transition:transform var(--panel-open-dur) var(--panel-ease),opacity var(--panel-open-dur) var(--panel-ease),filter var(--panel-open-dur) var(--panel-ease)}
|
|
6084
|
+
.mgs-t-modal{transform-origin:center;transform:scale(var(--modal-scale));opacity:0;pointer-events:none;transition:transform var(--modal-open-dur) var(--modal-ease),opacity var(--modal-open-dur) var(--modal-ease)}
|
|
6085
|
+
.mgs-t-modal.is-open{transform:scale(1);opacity:1;pointer-events:auto}
|
|
6086
|
+
.mgs-t-modal.is-closing{transform:scale(var(--modal-scale-close));opacity:0;pointer-events:none;transition:transform var(--modal-close-dur) var(--modal-ease),opacity var(--modal-close-dur) var(--modal-ease)}
|
|
6087
|
+
@media (prefers-reduced-motion:reduce){
|
|
6088
|
+
.mgs-sheet,.mgs-t-panel-slide,.mgs-t-modal,.mgs-hl,.mgs-scrim,.mgs-trigger,.mgs-trigger::before,.mgs-trigger::after,.mgs-slot .mgs-icon,.mgs-glass,.mgs-glass::before,.mgs-glass::after,.mgs-linkmain,.mgs-tick{transition:none!important}
|
|
6089
|
+
.mgs-label-anim,.mgs-linkrow.is-copied .mgs-linkmain,.mgs-linkrow.is-failed .mgs-linkmain{animation:none!important}
|
|
6090
|
+
}
|
|
6091
|
+
|
|
6092
|
+
.mgs-icon-play{translate:1px 0}.mgs-icon-heart{translate:0 1px}
|
|
6093
|
+
|
|
6094
|
+
.mova-glass-sheet :where(button,[role="button"],[role="tab"],[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"],[role="option"],[role="switch"],summary,.t-pressable){-webkit-tap-highlight-color:transparent;touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
|
|
6095
|
+
|
|
6096
|
+
.mova-glass-sheet *{box-sizing:border-box}.mgs-trigger:focus-visible,.mgs-grab:focus-visible{outline:2px solid #fff;outline-offset:-3px}.mgs-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
|
|
4599
6097
|
`;
|
|
4600
6098
|
|
|
4601
6099
|
// .generated/ui/cards/voice-assistant-card.tsx
|
|
4602
6100
|
import * as React6 from "react";
|
|
4603
|
-
import {
|
|
4604
|
-
import {
|
|
4605
|
-
var recentChats = [
|
|
6101
|
+
import { VoiceBeam } from "voice-glow";
|
|
6102
|
+
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
6103
|
+
var recentChats = [
|
|
6104
|
+
{ id: "cafe", title: "Quiet caf\xE9 nearby", preview: "Found 3 spots with good wifi", time: "Now" },
|
|
6105
|
+
{ id: "trip", title: "Weekend in Lisbon", preview: "Day trips from the city", time: "Yesterday" },
|
|
6106
|
+
{ id: "dinner", title: "Dinner for four", preview: "Pasta, salad and a cake", time: "Mon" },
|
|
6107
|
+
{ id: "playlist", title: "Morning run playlist", preview: "45 minutes of upbeat songs", time: "Sun" }
|
|
6108
|
+
];
|
|
6109
|
+
function numeric(element, name, fallback) {
|
|
6110
|
+
const value = element ? parseFloat(getComputedStyle(element).getPropertyValue(name)) : NaN;
|
|
6111
|
+
return Number.isFinite(value) ? value : fallback;
|
|
6112
|
+
}
|
|
6113
|
+
function bezier(value) {
|
|
6114
|
+
const match = value.replace(/\s+/g, "").match(/cubic-bezier\(([-\d.]+),([-\d.]+),([-\d.]+),([-\d.]+)\)/);
|
|
6115
|
+
if (!match) return (t) => t;
|
|
6116
|
+
const [x1, y1, x2, y2] = match.slice(1).map(Number);
|
|
6117
|
+
const cx = 3 * x1, bx = 3 * (x2 - x1) - cx, ax = 1 - cx - bx;
|
|
6118
|
+
const cy = 3 * y1, by = 3 * (y2 - y1) - cy, ay = 1 - cy - by;
|
|
6119
|
+
return (t) => {
|
|
6120
|
+
if (t <= 0 || t >= 1) return Math.min(1, Math.max(0, t));
|
|
6121
|
+
let s = t;
|
|
6122
|
+
for (let i = 0; i < 8; i++) {
|
|
6123
|
+
const delta = ((ax * s + bx) * s + cx) * s - t;
|
|
6124
|
+
const derivative = (3 * ax * s + 2 * bx) * s + cx;
|
|
6125
|
+
if (Math.abs(delta) < 1e-6 || derivative === 0) break;
|
|
6126
|
+
s -= delta / derivative;
|
|
6127
|
+
}
|
|
6128
|
+
return ((ay * s + by) * s + cy) * s;
|
|
6129
|
+
};
|
|
6130
|
+
}
|
|
6131
|
+
function SwapText2({ value }) {
|
|
6132
|
+
const [shown, setShown] = React6.useState(value);
|
|
6133
|
+
const ref = React6.useRef(null);
|
|
6134
|
+
React6.useEffect(() => {
|
|
6135
|
+
const el = ref.current;
|
|
6136
|
+
if (!el) return;
|
|
6137
|
+
if (value === shown || window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
6138
|
+
el.classList.remove("is-exit", "is-enter-start");
|
|
6139
|
+
setShown(value);
|
|
6140
|
+
return;
|
|
6141
|
+
}
|
|
6142
|
+
el.classList.remove("is-enter-start");
|
|
6143
|
+
el.classList.add("is-exit");
|
|
6144
|
+
const timer = window.setTimeout(() => setShown(value), numeric(el, "--text-swap-dur", 150));
|
|
6145
|
+
return () => window.clearTimeout(timer);
|
|
6146
|
+
}, [value, shown]);
|
|
6147
|
+
React6.useLayoutEffect(() => {
|
|
6148
|
+
const el = ref.current;
|
|
6149
|
+
if (!el?.classList.contains("is-exit")) return;
|
|
6150
|
+
el.classList.remove("is-exit");
|
|
6151
|
+
el.classList.add("is-enter-start");
|
|
6152
|
+
void el.offsetHeight;
|
|
6153
|
+
el.classList.remove("is-enter-start");
|
|
6154
|
+
}, [shown]);
|
|
6155
|
+
return /* @__PURE__ */ jsx18("span", { ref, className: "mvc-t-text-swap", children: shown });
|
|
6156
|
+
}
|
|
6157
|
+
function useImageUrl(file) {
|
|
6158
|
+
const [url, setUrl] = React6.useState("");
|
|
6159
|
+
React6.useEffect(() => {
|
|
6160
|
+
if (!file) {
|
|
6161
|
+
setUrl("");
|
|
6162
|
+
return;
|
|
6163
|
+
}
|
|
6164
|
+
const next = URL.createObjectURL(file);
|
|
6165
|
+
setUrl(next);
|
|
6166
|
+
return () => URL.revokeObjectURL(next);
|
|
6167
|
+
}, [file]);
|
|
6168
|
+
return url;
|
|
6169
|
+
}
|
|
4606
6170
|
function VoiceAssistantCard({ name = "Aria", chats = recentChats, simulatedTranscript = "Find me a quiet caf\xE9 nearby with good wifi for this afternoon", onSend, onChatChange, theme = "light", className = "", style } = {}) {
|
|
4607
|
-
const [
|
|
6171
|
+
const [page, setPage] = React6.useState(2);
|
|
4608
6172
|
const [chatId, setChatId] = React6.useState(chats[0]?.id);
|
|
4609
|
-
const [draft, setDraft] = React6.useState("");
|
|
4610
|
-
const [transcript, setTranscript] = React6.useState("");
|
|
4611
6173
|
const [phase, setPhase] = React6.useState("idle");
|
|
6174
|
+
const [words, setWords] = React6.useState([]);
|
|
6175
|
+
const [count, setCount] = React6.useState(0);
|
|
6176
|
+
const [runKey, setRunKey] = React6.useState(0);
|
|
6177
|
+
const [text, setText] = React6.useState("");
|
|
4612
6178
|
const [attachment, setAttachment] = React6.useState();
|
|
4613
|
-
const [
|
|
4614
|
-
const
|
|
4615
|
-
const
|
|
6179
|
+
const [attached, setAttached] = React6.useState(false);
|
|
6180
|
+
const [sentImage, setSentImage] = React6.useState();
|
|
6181
|
+
const [clearing, setClearing] = React6.useState(false);
|
|
6182
|
+
const [clearText, setClearText] = React6.useState("");
|
|
6183
|
+
const [pending, setPending] = React6.useState(false);
|
|
6184
|
+
const [reducedMotion, setReducedMotion] = React6.useState(false);
|
|
6185
|
+
const speaking = React6.useRef(false);
|
|
4616
6186
|
const generation = React6.useRef(0);
|
|
4617
6187
|
const sending = React6.useRef(false);
|
|
4618
|
-
const
|
|
6188
|
+
const timers = React6.useRef([]);
|
|
6189
|
+
const raf = React6.useRef(0);
|
|
6190
|
+
const cardRef = React6.useRef(null);
|
|
6191
|
+
const wrapRef = React6.useRef(null);
|
|
6192
|
+
const inputRef = React6.useRef(null);
|
|
6193
|
+
const mirrorRef = React6.useRef(null);
|
|
6194
|
+
const placeholderRef = React6.useRef(null);
|
|
6195
|
+
const glowRef = React6.useRef(null);
|
|
6196
|
+
const fileRef = React6.useRef(null);
|
|
6197
|
+
const menuRef = React6.useRef(null);
|
|
6198
|
+
const focusChat = React6.useRef(false);
|
|
4619
6199
|
const listRef = React6.useRef(null);
|
|
4620
|
-
const
|
|
4621
|
-
const
|
|
6200
|
+
const chatRef = React6.useRef(null);
|
|
6201
|
+
const thumb = useImageUrl(attachment);
|
|
6202
|
+
const sentUrl = useImageUrl(sentImage);
|
|
6203
|
+
const chat = chats.find((item) => item.id === chatId) ?? chats[0];
|
|
6204
|
+
const live = phase === "listening";
|
|
6205
|
+
const hasContent = Boolean(text.trim() || attached);
|
|
6206
|
+
const caption = { idle: "Type, or tap the lines to speak", listening: "Listening\u2026", thinking: "One moment", error: "Could not send. Please try again." }[phase];
|
|
4622
6207
|
React6.useEffect(() => {
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
6208
|
+
const query = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
6209
|
+
const read = () => setReducedMotion(query.matches);
|
|
6210
|
+
read();
|
|
6211
|
+
query.addEventListener("change", read);
|
|
6212
|
+
return () => {
|
|
6213
|
+
query.removeEventListener("change", read);
|
|
6214
|
+
timers.current.forEach(window.clearTimeout);
|
|
6215
|
+
cancelAnimationFrame(raf.current);
|
|
6216
|
+
generation.current++;
|
|
6217
|
+
};
|
|
4633
6218
|
}, []);
|
|
4634
6219
|
React6.useEffect(() => {
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
6220
|
+
listRef.current?.toggleAttribute("inert", page !== 1);
|
|
6221
|
+
chatRef.current?.toggleAttribute("inert", page !== 2);
|
|
6222
|
+
if (page === 2 && focusChat.current) {
|
|
6223
|
+
inputRef.current?.focus();
|
|
6224
|
+
focusChat.current = false;
|
|
6225
|
+
}
|
|
6226
|
+
}, [page]);
|
|
6227
|
+
function clearTimers() {
|
|
6228
|
+
timers.current.forEach(window.clearTimeout);
|
|
6229
|
+
timers.current = [];
|
|
6230
|
+
}
|
|
6231
|
+
function later(callback, duration) {
|
|
6232
|
+
timers.current.push(window.setTimeout(callback, Math.max(0, duration)));
|
|
6233
|
+
}
|
|
6234
|
+
function think() {
|
|
6235
|
+
speaking.current = false;
|
|
6236
|
+
setPhase("thinking");
|
|
6237
|
+
later(() => setPhase("idle"), 1800);
|
|
6238
|
+
}
|
|
6239
|
+
function start() {
|
|
6240
|
+
clearTimers();
|
|
6241
|
+
generation.current++;
|
|
6242
|
+
const transcript = simulatedTranscript.split(/\s+/).filter(Boolean);
|
|
6243
|
+
setWords(transcript);
|
|
6244
|
+
setSentImage(void 0);
|
|
6245
|
+
setCount(0);
|
|
6246
|
+
setRunKey((key) => key + 1);
|
|
6247
|
+
speaking.current = true;
|
|
6248
|
+
setPhase("listening");
|
|
6249
|
+
transcript.forEach((_, index) => later(() => setCount(index + 1), 400 + index * 280));
|
|
6250
|
+
later(think, 400 + transcript.length * 280 + 500);
|
|
6251
|
+
}
|
|
6252
|
+
function buildGlow(value) {
|
|
6253
|
+
const wrap = wrapRef.current, input = inputRef.current;
|
|
6254
|
+
const context = document.createElement("canvas").getContext("2d");
|
|
6255
|
+
if (!context || !wrap || !input) return "";
|
|
6256
|
+
context.font = getComputedStyle(input).font;
|
|
6257
|
+
const rgb = theme === "dark" ? "255,255,255" : "0,0,0";
|
|
6258
|
+
const width = wrap.clientWidth || 200;
|
|
6259
|
+
const padding = parseFloat(getComputedStyle(input).paddingLeft) || 4;
|
|
6260
|
+
const spread = numeric(cardRef.current, "--glow-spread", 1.5);
|
|
6261
|
+
const layers = [];
|
|
6262
|
+
let x = 0;
|
|
6263
|
+
value.split(/(\s+)/).forEach((segment) => {
|
|
6264
|
+
const segmentWidth = context.measureText(segment).width;
|
|
6265
|
+
if (segment.trim()) {
|
|
6266
|
+
const center = padding + x + segmentWidth / 2;
|
|
6267
|
+
const halfWidth = Math.max(segmentWidth * 0.45, 8) * spread;
|
|
6268
|
+
[[0, 0.8, 7, 0.22], [halfWidth * 0.45, 0.55, 8, 0.18], [-halfWidth * 0.4, 0.65, 6, 0.16], [halfWidth * 0.15, 0.9, 5, 0.14]].forEach(([dx, multiplier, height, opacity]) => {
|
|
6269
|
+
layers.push(`radial-gradient(ellipse ${Math.max(halfWidth * multiplier, 2).toFixed(1)}px ${height}px at ${((center + dx) / width * 100).toFixed(2)}% 100%, rgba(${rgb},${opacity}), transparent)`);
|
|
6270
|
+
});
|
|
4645
6271
|
}
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
}
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
6272
|
+
x += segmentWidth;
|
|
6273
|
+
});
|
|
6274
|
+
return layers.join(", ");
|
|
6275
|
+
}
|
|
6276
|
+
function stopDissolve() {
|
|
6277
|
+
cancelAnimationFrame(raf.current);
|
|
6278
|
+
[mirrorRef, placeholderRef, glowRef].forEach((ref) => {
|
|
6279
|
+
if (ref.current) ref.current.style.cssText = "";
|
|
6280
|
+
});
|
|
6281
|
+
setClearing(false);
|
|
6282
|
+
setClearText("");
|
|
6283
|
+
}
|
|
6284
|
+
function dissolve(old) {
|
|
6285
|
+
stopDissolve();
|
|
6286
|
+
const mirror = mirrorRef.current, placeholder = placeholderRef.current, glow = glowRef.current;
|
|
6287
|
+
setText("");
|
|
6288
|
+
if (!mirror || !placeholder || !glow || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
6289
|
+
const token = (name2, fallback) => numeric(cardRef.current, name2, fallback);
|
|
6290
|
+
const total = token("--clear-dur", 1e3), outDuration = Math.max(1, token("--clear-out-dur", 400)), inDuration = Math.max(1, token("--clear-in-dur", 400));
|
|
6291
|
+
const outFly = token("--clear-out-fly", 12), inFly = token("--clear-in-fly", 12), blur = token("--clear-blur", 2);
|
|
6292
|
+
const delay = token("--glow-delay", 50), peakAt = Math.min(0.999, Math.max(1e-3, token("--glow-peak-at", 0.15))), opacity = token("--glow-opacity", 0.42);
|
|
6293
|
+
const computed = getComputedStyle(cardRef.current);
|
|
6294
|
+
const easeOut = bezier(computed.getPropertyValue("--clear-out-ease")), easeIn = bezier(computed.getPropertyValue("--clear-in-ease"));
|
|
6295
|
+
setClearText(old);
|
|
6296
|
+
setClearing(true);
|
|
6297
|
+
glow.style.background = buildGlow(old);
|
|
6298
|
+
glow.style.opacity = "0";
|
|
6299
|
+
placeholder.style.transform = `translateY(-${inFly}px)`;
|
|
6300
|
+
placeholder.style.opacity = ".9";
|
|
6301
|
+
placeholder.style.filter = `blur(${blur}px)`;
|
|
6302
|
+
const started = performance.now();
|
|
6303
|
+
const tick = (now) => {
|
|
6304
|
+
const elapsed = now - started, out = easeOut(Math.min(1, elapsed / outDuration)), incoming = easeIn(Math.min(1, elapsed / inDuration));
|
|
6305
|
+
mirror.style.transform = `translateY(${(out * outFly).toFixed(1)}px)`;
|
|
6306
|
+
mirror.style.opacity = (1 - out).toFixed(3);
|
|
6307
|
+
mirror.style.filter = `blur(${(out * blur).toFixed(1)}px)`;
|
|
6308
|
+
placeholder.style.transform = `translateY(${(-inFly + incoming * inFly).toFixed(1)}px)`;
|
|
6309
|
+
placeholder.style.opacity = (0.9 + incoming * 0.1).toFixed(3);
|
|
6310
|
+
placeholder.style.filter = `blur(${(blur - incoming * blur).toFixed(1)}px)`;
|
|
6311
|
+
let glowStrength = 0;
|
|
6312
|
+
if (elapsed > delay) {
|
|
6313
|
+
const progress = Math.min(1, (elapsed - delay) / Math.max(1, total - delay));
|
|
6314
|
+
glowStrength = progress < peakAt ? progress / peakAt : 1 - (progress - peakAt) / (1 - peakAt);
|
|
6315
|
+
}
|
|
6316
|
+
glow.style.opacity = (glowStrength * opacity).toFixed(3);
|
|
6317
|
+
if (elapsed < total) raf.current = requestAnimationFrame(tick);
|
|
6318
|
+
else stopDissolve();
|
|
6319
|
+
};
|
|
6320
|
+
raf.current = requestAnimationFrame(tick);
|
|
6321
|
+
}
|
|
6322
|
+
function send() {
|
|
6323
|
+
const message = text.trim(), image = attached ? attachment : void 0;
|
|
6324
|
+
if (!message && !image || sending.current || live) return;
|
|
6325
|
+
clearTimers();
|
|
4660
6326
|
const run = ++generation.current;
|
|
6327
|
+
const nextWords = message ? message.split(/\s+/) : [];
|
|
6328
|
+
setWords(nextWords);
|
|
6329
|
+
setSentImage(image);
|
|
6330
|
+
setCount(0);
|
|
6331
|
+
setRunKey((key) => key + 1);
|
|
6332
|
+
if (message) dissolve(text);
|
|
6333
|
+
setAttached(false);
|
|
6334
|
+
speaking.current = false;
|
|
6335
|
+
const gap = numeric(cardRef.current, "--stream-gap", 60), steps = Math.max(nextWords.length, 1);
|
|
6336
|
+
for (let index = 0; index < steps; index++) later(() => setCount(index + 1), 80 + index * gap);
|
|
6337
|
+
later(think, 80 + steps * gap + 400);
|
|
6338
|
+
if (!onSend) return;
|
|
4661
6339
|
sending.current = true;
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
6340
|
+
setPending(true);
|
|
6341
|
+
Promise.resolve().then(() => onSend(message, image)).catch(() => {
|
|
6342
|
+
if (run !== generation.current) return;
|
|
6343
|
+
clearTimers();
|
|
6344
|
+
stopDissolve();
|
|
6345
|
+
setText(message);
|
|
6346
|
+
setAttachment(image);
|
|
6347
|
+
setAttached(Boolean(image));
|
|
6348
|
+
setPhase("error");
|
|
6349
|
+
}).finally(() => {
|
|
6350
|
+
if (run === generation.current) {
|
|
6351
|
+
sending.current = false;
|
|
6352
|
+
setPending(false);
|
|
4669
6353
|
}
|
|
4670
|
-
}
|
|
4671
|
-
|
|
4672
|
-
|
|
6354
|
+
});
|
|
6355
|
+
}
|
|
6356
|
+
function onRight() {
|
|
6357
|
+
if (live) {
|
|
6358
|
+
clearTimers();
|
|
6359
|
+
setCount(words.length);
|
|
6360
|
+
think();
|
|
6361
|
+
} else if (hasContent) send();
|
|
6362
|
+
else start();
|
|
6363
|
+
}
|
|
6364
|
+
function openChat(item) {
|
|
6365
|
+
if (item.id !== chatId) {
|
|
6366
|
+
clearTimers();
|
|
6367
|
+
stopDissolve();
|
|
6368
|
+
generation.current++;
|
|
4673
6369
|
sending.current = false;
|
|
4674
|
-
|
|
6370
|
+
setPending(false);
|
|
6371
|
+
speaking.current = false;
|
|
6372
|
+
setPhase("idle");
|
|
6373
|
+
setWords([]);
|
|
6374
|
+
setSentImage(void 0);
|
|
6375
|
+
setCount(0);
|
|
6376
|
+
setRunKey((key) => key + 1);
|
|
6377
|
+
setChatId(item.id);
|
|
6378
|
+
onChatChange?.(item);
|
|
6379
|
+
}
|
|
6380
|
+
focusChat.current = true;
|
|
6381
|
+
setPage(2);
|
|
4675
6382
|
}
|
|
4676
|
-
function
|
|
4677
|
-
|
|
4678
|
-
setChatId(void 0);
|
|
4679
|
-
generation.current++;
|
|
4680
|
-
setDraft("");
|
|
4681
|
-
setTranscript("");
|
|
4682
|
-
setAttachment(void 0);
|
|
4683
|
-
setPhase("idle");
|
|
4684
|
-
setList(false);
|
|
6383
|
+
function keepFocus(event) {
|
|
6384
|
+
if (document.activeElement === inputRef.current) event.preventDefault();
|
|
4685
6385
|
}
|
|
4686
|
-
|
|
4687
|
-
|
|
6386
|
+
function togglePage() {
|
|
6387
|
+
setPage((current) => current === 2 ? 1 : 2);
|
|
6388
|
+
}
|
|
6389
|
+
const iconState = live ? "a" : hasContent ? "b" : "a";
|
|
6390
|
+
return /* @__PURE__ */ jsxs18("section", { ref: cardRef, className: `mova-voice ${className}`, "data-theme": theme, "data-phase": phase, style, "aria-label": `${name} voice assistant`, children: [
|
|
4688
6391
|
/* @__PURE__ */ jsx18("style", { children: css6 }),
|
|
4689
|
-
/* @__PURE__ */
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
/* @__PURE__ */ jsxs18("
|
|
4695
|
-
/* @__PURE__ */ jsx18("
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
}
|
|
4704
|
-
}, children: [
|
|
4705
|
-
/* @__PURE__ */ jsxs18("button", { type: "button", className: "mvc-new", onClick: reset, children: [
|
|
4706
|
-
/* @__PURE__ */ jsx18(Plus3, { size: 16 }),
|
|
4707
|
-
"New conversation"
|
|
4708
|
-
] }),
|
|
4709
|
-
chats.map((chat) => /* @__PURE__ */ jsxs18("button", { type: "button", className: "mvc-chat", onClick: () => {
|
|
4710
|
-
reset();
|
|
4711
|
-
setChatId(chat.id);
|
|
4712
|
-
onChatChange?.(chat);
|
|
4713
|
-
}, children: [
|
|
4714
|
-
/* @__PURE__ */ jsxs18("span", { children: [
|
|
4715
|
-
/* @__PURE__ */ jsx18("strong", { children: chat.title }),
|
|
4716
|
-
/* @__PURE__ */ jsx18("small", { children: chat.preview })
|
|
4717
|
-
] }),
|
|
4718
|
-
/* @__PURE__ */ jsx18("small", { children: chat.time })
|
|
4719
|
-
] }, chat.id))
|
|
4720
|
-
] }) : /* @__PURE__ */ jsxs18(Fragment7, { children: [
|
|
4721
|
-
/* @__PURE__ */ jsxs18("div", { className: "mvc-body", children: [
|
|
4722
|
-
/* @__PURE__ */ jsx18("p", { className: "mvc-greeting", children: "How can I help you today?" }),
|
|
4723
|
-
/* @__PURE__ */ jsxs18("div", { className: "mvc-transcript", role: "status", "aria-live": phase === "listening" ? "off" : "polite", children: [
|
|
4724
|
-
imageUrl && /* @__PURE__ */ jsx18("img", { src: imageUrl, alt: "Attached image preview" }),
|
|
4725
|
-
transcript && /* @__PURE__ */ jsx18("p", { children: transcript })
|
|
6392
|
+
/* @__PURE__ */ jsx18(VoiceBeam, { className: "mvc-beam", level: () => {
|
|
6393
|
+
if (!speaking.current || reducedMotion) return 0.06;
|
|
6394
|
+
const time = Date.now();
|
|
6395
|
+
return Math.max(0.06, Math.min(1, 0.55 + Math.sin(time / 150) * 0.22 + Math.sin(time / 61) * 0.12 + Math.sin(time / 37) * 0.08)) * 0.6;
|
|
6396
|
+
}, processing: phase === "thinking" || pending, paused: reducedMotion, ...theme === "dark" ? { theme: "dark" } : {}, children: /* @__PURE__ */ jsx18("div", { className: "mvc-inner", children: /* @__PURE__ */ jsxs18("div", { className: "mvc-content", children: [
|
|
6397
|
+
/* @__PURE__ */ jsxs18("header", { className: "mvc-top", children: [
|
|
6398
|
+
/* @__PURE__ */ jsx18("button", { ref: menuRef, type: "button", className: `mvc-menu${page === 1 ? " is-open" : ""}`, "aria-label": page === 1 ? "Close conversations" : "Open conversations", "aria-expanded": page === 1, onClick: togglePage, children: /* @__PURE__ */ jsxs18("svg", { className: "mvc-menu-icon", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", "aria-hidden": "true", children: [
|
|
6399
|
+
/* @__PURE__ */ jsx18("line", { className: "mvc-l1", x1: "2.5", y1: "4", x2: "13.5", y2: "4" }),
|
|
6400
|
+
/* @__PURE__ */ jsx18("line", { className: "mvc-l2", x1: "2.5", y1: "8", x2: "13.5", y2: "8" }),
|
|
6401
|
+
/* @__PURE__ */ jsx18("line", { className: "mvc-l3", x1: "2.5", y1: "12", x2: "13.5", y2: "12" })
|
|
6402
|
+
] }) }),
|
|
6403
|
+
/* @__PURE__ */ jsxs18("div", { className: "mvc-top-text", children: [
|
|
6404
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-name", children: /* @__PURE__ */ jsx18(SwapText2, { value: page === 1 ? "Chats" : name }) }),
|
|
6405
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-meta", children: /* @__PURE__ */ jsx18(SwapText2, { value: page === 1 ? `${chats.length} conversations` : chat?.title ?? "New conversation" }) })
|
|
4726
6406
|
] })
|
|
4727
6407
|
] }),
|
|
4728
|
-
/* @__PURE__ */
|
|
4729
|
-
|
|
4730
|
-
/* @__PURE__ */
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
6408
|
+
/* @__PURE__ */ jsx18("div", { className: "mvc-divider", "aria-hidden": "true" }),
|
|
6409
|
+
/* @__PURE__ */ jsxs18("div", { className: "mvc-t-page-slide", "data-page": page, children: [
|
|
6410
|
+
/* @__PURE__ */ jsx18("section", { className: "mvc-t-page mvc-page", "data-page-id": "1", ref: listRef, "aria-label": "Your conversations", "aria-hidden": page !== 1, inert: page !== 1, onKeyDown: (event) => {
|
|
6411
|
+
if (event.key === "Escape") {
|
|
6412
|
+
setPage(2);
|
|
6413
|
+
menuRef.current?.focus();
|
|
6414
|
+
}
|
|
6415
|
+
}, children: /* @__PURE__ */ jsx18("ul", { className: "mvc-list", children: chats.map((item) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsxs18("button", { type: "button", className: "mvc-row", onClick: () => openChat(item), children: [
|
|
6416
|
+
/* @__PURE__ */ jsxs18("span", { className: "mvc-row-text", children: [
|
|
6417
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-row-title", children: item.title }),
|
|
6418
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-row-preview", children: item.preview })
|
|
6419
|
+
] }),
|
|
6420
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-row-time", children: item.time })
|
|
6421
|
+
] }) }, item.id)) }) }),
|
|
6422
|
+
/* @__PURE__ */ jsxs18("section", { className: "mvc-t-page mvc-page", "data-page-id": "2", ref: chatRef, "aria-label": `Chat with ${name}`, "aria-hidden": page !== 2, inert: page !== 2, children: [
|
|
6423
|
+
/* @__PURE__ */ jsxs18("div", { className: "mvc-body", children: [
|
|
6424
|
+
/* @__PURE__ */ jsx18("div", { className: "mvc-bubble-row", children: /* @__PURE__ */ jsx18("p", { className: "mvc-bubble", children: /* @__PURE__ */ jsx18("span", { children: "How can I help you today?" }) }) }),
|
|
6425
|
+
/* @__PURE__ */ jsxs18("div", { className: "mvc-transcript", "aria-live": "polite", "aria-atomic": "true", children: [
|
|
6426
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-sr-only", children: words.slice(0, count).join(" ") }),
|
|
6427
|
+
sentUrl && /* @__PURE__ */ jsx18("img", { className: `mvc-sent-img mvc-t-stream-w${count > 0 ? " is-in" : ""}`, src: sentUrl, alt: "Image you sent", width: 40, height: 40 }),
|
|
6428
|
+
words.length > 0 && /* @__PURE__ */ jsx18("p", { "aria-hidden": "true", children: /* @__PURE__ */ jsx18("span", { children: words.map((word, index) => /* @__PURE__ */ jsxs18(React6.Fragment, { children: [
|
|
6429
|
+
/* @__PURE__ */ jsx18("span", { className: `mvc-t-stream-w${index < count ? " is-in" : ""}`, children: word }),
|
|
6430
|
+
index < words.length - 1 ? " " : ""
|
|
6431
|
+
] }, index)) }) })
|
|
6432
|
+
] }, runKey)
|
|
6433
|
+
] }),
|
|
6434
|
+
/* @__PURE__ */ jsxs18("div", { className: "mvc-bottom", children: [
|
|
6435
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-caption", role: "status", children: /* @__PURE__ */ jsx18(SwapText2, { value: caption }) }),
|
|
6436
|
+
/* @__PURE__ */ jsxs18("form", { className: "mvc-field", onSubmit: (event) => {
|
|
6437
|
+
event.preventDefault();
|
|
6438
|
+
send();
|
|
6439
|
+
}, children: [
|
|
6440
|
+
/* @__PURE__ */ jsxs18("button", { type: "button", className: "mvc-attach mvc-t-icon-swap", "data-state": attached ? "b" : "a", "aria-label": attached ? "Remove image" : "Attach image", disabled: pending, onPointerDown: keepFocus, onMouseDown: keepFocus, onClick: () => attached ? setAttached(false) : fileRef.current?.click(), children: [
|
|
6441
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-t-icon", "data-icon": "a", children: /* @__PURE__ */ jsx18("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.25", "aria-hidden": "true", children: /* @__PURE__ */ jsx18("path", { d: "m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" }) }) }),
|
|
6442
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-t-icon", "data-icon": "b", children: thumb && /* @__PURE__ */ jsx18("img", { className: "mvc-thumb", src: thumb, alt: "", width: 28, height: 28 }) })
|
|
6443
|
+
] }),
|
|
6444
|
+
/* @__PURE__ */ jsx18("input", { ref: fileRef, type: "file", accept: "image/*", hidden: true, onChange: (event) => {
|
|
6445
|
+
const file = event.target.files?.[0];
|
|
6446
|
+
event.target.value = "";
|
|
6447
|
+
if (file?.type.startsWith("image/") && file.size <= 10 * 1024 * 1024) {
|
|
6448
|
+
setAttachment(file);
|
|
6449
|
+
setAttached(true);
|
|
6450
|
+
}
|
|
6451
|
+
} }),
|
|
6452
|
+
/* @__PURE__ */ jsxs18("div", { ref: wrapRef, className: `mvc-t-clear mvc-input-wrap${text && !clearing ? " has-value" : ""}${clearing ? " is-clearing" : ""}`, children: [
|
|
6453
|
+
/* @__PURE__ */ jsx18("input", { ref: inputRef, className: "mvc-input", type: "text", value: text, "aria-label": `Message ${name}`, disabled: pending, maxLength: 2e3, onChange: (event) => {
|
|
6454
|
+
if (clearing) stopDissolve();
|
|
6455
|
+
setText(event.target.value);
|
|
6456
|
+
} }),
|
|
6457
|
+
/* @__PURE__ */ jsx18("div", { className: "mvc-t-clear-mirror", ref: mirrorRef, "aria-hidden": "true", children: (clearing ? clearText : text).replace(/ /g, "\xA0") }),
|
|
6458
|
+
/* @__PURE__ */ jsxs18("div", { className: "mvc-t-clear-placeholder", ref: placeholderRef, "aria-hidden": "true", children: [
|
|
6459
|
+
"Ask ",
|
|
6460
|
+
name,
|
|
6461
|
+
" anything"
|
|
6462
|
+
] }),
|
|
6463
|
+
/* @__PURE__ */ jsx18("div", { className: "mvc-t-clear-glow", ref: glowRef, "aria-hidden": "true" })
|
|
6464
|
+
] }),
|
|
6465
|
+
/* @__PURE__ */ jsxs18("button", { type: "button", className: `mvc-mic mvc-t-icon-swap${live ? " is-live" : ""}`, "data-state": iconState, "aria-label": live ? "Stop voice preview" : hasContent ? "Send message" : "Start voice preview", "aria-pressed": live, disabled: pending, onPointerDown: keepFocus, onMouseDown: keepFocus, onClick: onRight, children: [
|
|
6466
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-t-icon", "data-icon": "a", children: /* @__PURE__ */ jsxs18("span", { className: "mvc-wave", "aria-hidden": "true", children: [
|
|
6467
|
+
/* @__PURE__ */ jsx18("i", {}),
|
|
6468
|
+
/* @__PURE__ */ jsx18("i", {}),
|
|
6469
|
+
/* @__PURE__ */ jsx18("i", {}),
|
|
6470
|
+
/* @__PURE__ */ jsx18("i", {}),
|
|
6471
|
+
/* @__PURE__ */ jsx18("i", {})
|
|
6472
|
+
] }) }),
|
|
6473
|
+
/* @__PURE__ */ jsx18("span", { className: "mvc-t-icon", "data-icon": "b", children: /* @__PURE__ */ jsx18("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2.25", "aria-hidden": "true", children: /* @__PURE__ */ jsx18("path", { d: "M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18" }) }) })
|
|
6474
|
+
] })
|
|
6475
|
+
] })
|
|
6476
|
+
] })
|
|
4747
6477
|
] })
|
|
4748
6478
|
] })
|
|
4749
|
-
] })
|
|
6479
|
+
] }) }) })
|
|
4750
6480
|
] });
|
|
4751
6481
|
}
|
|
4752
6482
|
var css6 = `
|
|
4753
|
-
|
|
6483
|
+
/* @motion
|
|
6484
|
+
[Page slide] chat and chats screens
|
|
6485
|
+
--page-slide-dur: Duration
|
|
6486
|
+
--page-slide-ease: Easing
|
|
6487
|
+
--page-slide-distance: Distance
|
|
6488
|
+
more --page-fade-dur: Fade duration
|
|
6489
|
+
more --page-fade-ease: Fade easing
|
|
6490
|
+
more --page-blur: Blur
|
|
6491
|
+
more --page-stagger: Delay
|
|
6492
|
+
more --page-exit-enabled: Exit slide
|
|
6493
|
+
[Streaming transcript] your message under Aria's
|
|
6494
|
+
--stream-fade: Duration
|
|
6495
|
+
--stream-ease: Easing
|
|
6496
|
+
--stream-gap: Word gap
|
|
6497
|
+
more --stream-blur: Blur
|
|
6498
|
+
[Send dissolve] prompt text on send
|
|
6499
|
+
--clear-dur: Duration
|
|
6500
|
+
--clear-out-ease: Easing
|
|
6501
|
+
--clear-out-fly: Distance
|
|
6502
|
+
more --clear-out-dur: Text out duration
|
|
6503
|
+
more --clear-in-dur: Placeholder in duration
|
|
6504
|
+
more --clear-in-fly: Placeholder distance
|
|
6505
|
+
more --clear-in-ease: Placeholder easing
|
|
6506
|
+
more --clear-blur: Blur
|
|
6507
|
+
more --glow-delay: Glow delay
|
|
6508
|
+
more --glow-peak-at: Glow peak
|
|
6509
|
+
more --glow-opacity: Glow opacity
|
|
6510
|
+
more --glow-spread: Glow spread
|
|
6511
|
+
more [Status swap] caption and header titles
|
|
6512
|
+
--text-swap-dur: Duration
|
|
6513
|
+
--text-swap-ease: Easing
|
|
6514
|
+
--text-swap-translate-y: Distance
|
|
6515
|
+
more --text-swap-blur: Blur
|
|
6516
|
+
more [Icon swap] voice / send and image buttons
|
|
6517
|
+
--icon-swap-dur: Duration
|
|
6518
|
+
--icon-swap-ease: Easing
|
|
6519
|
+
--icon-swap-start-scale: Start scale
|
|
6520
|
+
more --icon-swap-blur: Blur
|
|
6521
|
+
more [Menu morph] menu lines into a close X
|
|
6522
|
+
--duration-fast: Duration
|
|
6523
|
+
more [Voice lines] bars in the voice button
|
|
6524
|
+
--wave-dur: Duration
|
|
6525
|
+
--wave-min: Rest scale
|
|
6526
|
+
more [Bubble float] assistant message
|
|
6527
|
+
--float-dur: Duration
|
|
6528
|
+
--float-distance: Distance
|
|
6529
|
+
more [Field focus] prompt ring, row hover
|
|
6530
|
+
--duration-quick: Duration
|
|
6531
|
+
more [Button press] all buttons and rows
|
|
6532
|
+
--press-scale: Scale
|
|
6533
|
+
--press-dur: Duration
|
|
6534
|
+
--ease-smooth-out: Easing
|
|
6535
|
+
*/
|
|
6536
|
+
.mova-voice {
|
|
6537
|
+
--page-slide-dur: 250ms;
|
|
6538
|
+
--page-fade-dur: 250ms;
|
|
6539
|
+
--page-slide-distance: 8px;
|
|
6540
|
+
--page-blur: 3px;
|
|
6541
|
+
--page-stagger: 0ms;
|
|
6542
|
+
--page-exit-enabled: 1;
|
|
6543
|
+
--page-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
6544
|
+
--page-fade-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
6545
|
+
--stream-gap: 60ms;
|
|
6546
|
+
--stream-fade: 350ms;
|
|
6547
|
+
--stream-blur: 1px;
|
|
6548
|
+
--stream-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
6549
|
+
--clear-dur: 1000ms;
|
|
6550
|
+
--clear-out-dur: 400ms;
|
|
6551
|
+
--clear-in-dur: 400ms;
|
|
6552
|
+
--clear-out-fly: 12px;
|
|
6553
|
+
--clear-in-fly: 12px;
|
|
6554
|
+
--clear-out-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
6555
|
+
--clear-in-ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
6556
|
+
--clear-blur: 2px;
|
|
6557
|
+
--glow-delay: 50ms;
|
|
6558
|
+
--glow-peak-at: 0.15;
|
|
6559
|
+
--glow-opacity: 0.42;
|
|
6560
|
+
--glow-spread: 1.5;
|
|
6561
|
+
--text-swap-dur: 150ms;
|
|
6562
|
+
--text-swap-translate-y: 4px;
|
|
6563
|
+
--text-swap-blur: 2px;
|
|
6564
|
+
--text-swap-ease: ease-in-out;
|
|
6565
|
+
--icon-swap-dur: 250ms;
|
|
6566
|
+
--icon-swap-blur: 2px;
|
|
6567
|
+
--icon-swap-start-scale: 0.25;
|
|
6568
|
+
--icon-swap-ease: ease-in-out;
|
|
6569
|
+
--duration-fast: 250ms;
|
|
6570
|
+
--duration-quick: 150ms;
|
|
6571
|
+
--wave-dur: 900ms;
|
|
6572
|
+
--wave-min: 0.35;
|
|
6573
|
+
--float-dur: 4000ms;
|
|
6574
|
+
--float-distance: 3px;
|
|
6575
|
+
--press-scale: 0.99;
|
|
6576
|
+
--press-dur: 150ms;
|
|
6577
|
+
--ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1);
|
|
6578
|
+
--mvc-btn-bg: var(--mvc-surface);
|
|
6579
|
+
--mvc-btn-shadow: 0 1px 3px 0 rgba(0,0,0,.04), inset 0 0 0 1px rgba(0,0,0,.08), inset 0 -1px 0 0 rgba(0,0,0,.08);
|
|
6580
|
+
--mvc-hover: rgba(0, 0, 0, 0.02);
|
|
6581
|
+
--mvc-chip: rgba(0, 0, 0, 0.04);
|
|
6582
|
+
--mvc-focus-soft: rgba(0, 115, 229, 0.06);
|
|
6583
|
+
--mvc-img-outline: rgba(0, 0, 0, 0.1);
|
|
6584
|
+
--mvc-card-shadow: 0 0 0 1px rgba(0,0,0,.04), 0 8px 32px -4px rgba(0,0,0,.06), 0 1px 3px 0 rgba(0,0,0,.04);
|
|
6585
|
+
--divider: color-mix(in srgb, var(--mvc-border) 49%, transparent);
|
|
6586
|
+
--bubble: color-mix(in srgb, var(--mvc-fg) 6%, var(--mvc-surface));
|
|
6587
|
+
}
|
|
6588
|
+
.mova-voice[data-theme="dark"] {
|
|
6589
|
+
--mvc-btn-bg: rgba(255, 255, 255, 0.04);
|
|
6590
|
+
--mvc-btn-shadow: 0 1px 1px 0 rgba(0,0,0,.24), inset 0 0 0 1px rgba(255,255,255,.04), inset 0 1px 0 0 rgba(255,255,255,.06);
|
|
6591
|
+
--mvc-hover: rgba(255, 255, 255, 0.02);
|
|
6592
|
+
--mvc-chip: rgba(255, 255, 255, 0.07);
|
|
6593
|
+
--mvc-focus-soft: rgba(0, 115, 229, 0.16);
|
|
6594
|
+
--mvc-img-outline: rgba(255, 255, 255, 0.1);
|
|
6595
|
+
--glow-opacity: 0.85;
|
|
6596
|
+
--bubble: color-mix(in srgb, var(--mvc-fg) 9%, var(--mvc-surface));
|
|
6597
|
+
}
|
|
6598
|
+
|
|
6599
|
+
.mova-voice {
|
|
6600
|
+
display: grid;
|
|
6601
|
+
width: 360px;
|
|
6602
|
+
max-width: 100%;
|
|
6603
|
+
height: 340px;
|
|
6604
|
+
border-radius: 24px;
|
|
6605
|
+
background: var(--mvc-surface);
|
|
6606
|
+
box-shadow: var(--mvc-card-shadow);
|
|
6607
|
+
color: var(--mvc-fg);
|
|
6608
|
+
-webkit-font-smoothing: antialiased;
|
|
6609
|
+
}
|
|
6610
|
+
.mvc-beam { margin: -1px; border-radius: 25px; }
|
|
6611
|
+
.mvc-inner { position: relative; height: 100%; border-radius: 25px; background: transparent; overflow: hidden; }
|
|
6612
|
+
.mvc-content { position: relative; z-index: 5; height: 100%; display: flex; flex-direction: column; }
|
|
6613
|
+
:where(.mova-voice) :is(button, input) { font: inherit; padding: 0; border: 0; background: none; color: inherit; }
|
|
6614
|
+
:where(.mova-voice) button { cursor: pointer; }
|
|
6615
|
+
.mova-voice :focus-visible:not(input) { outline: none; box-shadow: 0 0 0 2px var(--mvc-surface), 0 0 0 4px var(--mvc-accent); }
|
|
6616
|
+
|
|
6617
|
+
.mvc-top { display: flex; align-items: center; gap: 8px; padding: 12px 16px 12px 12px; flex: none; }
|
|
6618
|
+
.mvc-top-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
6619
|
+
.mvc-name { font-size: 16px; line-height: 22px; font-weight: 500; }
|
|
6620
|
+
.mvc-meta { font-size: 12px; line-height: 16px; color: var(--mvc-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
6621
|
+
.mvc-divider { height: 1px; flex: none; background: linear-gradient(90deg, transparent, var(--divider) 20%, var(--divider) 80%, transparent); }
|
|
6622
|
+
|
|
6623
|
+
.mvc-menu {
|
|
6624
|
+
--press-scale: 0.95;
|
|
6625
|
+
flex: none;
|
|
6626
|
+
width: 32px;
|
|
6627
|
+
height: 32px;
|
|
6628
|
+
border-radius: 50%;
|
|
6629
|
+
display: grid;
|
|
6630
|
+
place-items: center;
|
|
6631
|
+
color: var(--mvc-fg);
|
|
6632
|
+
transition: transform var(--press-dur) var(--ease-smooth-out), background-color var(--duration-quick) var(--ease-smooth-out);
|
|
6633
|
+
}
|
|
6634
|
+
@media (hover: hover) and (pointer: fine) { .mvc-menu:hover { background-color: var(--mvc-chip); } }
|
|
6635
|
+
.mvc-menu:is(:active,.is-pressed) { transform: scale(var(--press-scale)); }
|
|
6636
|
+
.mvc-menu-icon line {
|
|
6637
|
+
transform-box: view-box;
|
|
6638
|
+
transform-origin: 8px 8px;
|
|
6639
|
+
transition: transform var(--duration-fast) var(--ease-smooth-out), opacity var(--duration-fast) var(--ease-smooth-out);
|
|
6640
|
+
}
|
|
6641
|
+
.mvc-menu.is-open .mvc-l1 { transform: rotate(45deg) translateY(4px); }
|
|
6642
|
+
.mvc-menu.is-open .mvc-l2 { opacity: 0; }
|
|
6643
|
+
.mvc-menu.is-open .mvc-l3 { transform: rotate(-45deg) translateY(-4px); }
|
|
6644
|
+
|
|
6645
|
+
.mvc-t-page-slide { position: relative; flex: 1; min-height: 0; }
|
|
6646
|
+
.mvc-t-page-slide .mvc-t-page[data-page-id="1"] { --t-page-from-x: calc(var(--page-slide-distance) * -1); }
|
|
6647
|
+
.mvc-t-page-slide .mvc-t-page[data-page-id="2"] { --t-page-from-x: var(--page-slide-distance); }
|
|
6648
|
+
.mvc-t-page-slide .mvc-t-page {
|
|
6649
|
+
position: absolute;
|
|
6650
|
+
inset: 0;
|
|
6651
|
+
opacity: 0;
|
|
6652
|
+
pointer-events: none;
|
|
6653
|
+
transform: translateX(calc(var(--t-page-from-x, 0px) * var(--page-exit-enabled)));
|
|
6654
|
+
filter: blur(calc(var(--page-blur) * var(--page-exit-enabled)));
|
|
6655
|
+
transition:
|
|
6656
|
+
opacity var(--page-fade-dur) var(--page-fade-ease),
|
|
6657
|
+
transform var(--page-slide-dur) var(--page-slide-ease),
|
|
6658
|
+
filter var(--page-slide-dur) var(--page-slide-ease);
|
|
6659
|
+
will-change: opacity, transform, filter;
|
|
6660
|
+
}
|
|
6661
|
+
.mvc-t-page-slide[data-page="1"] .mvc-t-page[data-page-id="1"],
|
|
6662
|
+
.mvc-t-page-slide[data-page="2"] .mvc-t-page[data-page-id="2"] {
|
|
6663
|
+
opacity: 1;
|
|
6664
|
+
pointer-events: auto;
|
|
6665
|
+
transform: translateX(0);
|
|
6666
|
+
filter: blur(0);
|
|
6667
|
+
transition-delay: var(--page-stagger);
|
|
6668
|
+
}
|
|
6669
|
+
.mvc-page { display: flex; flex-direction: column; }
|
|
6670
|
+
|
|
6671
|
+
.mvc-list { list-style: none; margin: 0; padding: 12px; display: flex; flex-direction: column; }
|
|
6672
|
+
.mvc-row {
|
|
6673
|
+
width: 100%;
|
|
6674
|
+
display: flex;
|
|
6675
|
+
align-items: center;
|
|
6676
|
+
gap: 12px;
|
|
6677
|
+
padding: 8px 12px;
|
|
6678
|
+
border-radius: 12px;
|
|
6679
|
+
text-align: left;
|
|
6680
|
+
transition: transform var(--press-dur) var(--ease-smooth-out), background-color var(--duration-quick) var(--ease-smooth-out);
|
|
6681
|
+
}
|
|
6682
|
+
@media (hover: hover) and (pointer: fine) { .mvc-row:hover { background-color: var(--mvc-hover); } }
|
|
6683
|
+
.mvc-row:is(:active,.is-pressed) { transform: scale(var(--press-scale)); }
|
|
6684
|
+
.mvc-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
6685
|
+
.mvc-row-title { font-size: 13px; line-height: 20px; color: var(--mvc-fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
6686
|
+
.mvc-row-preview { font-size: 12px; line-height: 16px; color: var(--mvc-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
6687
|
+
.mvc-row-time { flex: none; font-size: 12px; line-height: 16px; color: var(--mvc-muted); }
|
|
6688
|
+
|
|
6689
|
+
.mvc-body { flex: 1; min-height: 0; overflow: hidden; padding: 24px 24px 0; display: flex; flex-direction: column; gap: 16px; }
|
|
6690
|
+
.mvc-bubble-row { padding-left: 8px; animation: mvc-float var(--float-dur) ease-in-out infinite; }
|
|
6691
|
+
@keyframes mvc-float {
|
|
6692
|
+
0%, 100% { transform: translateY(0); }
|
|
6693
|
+
50% { transform: translateY(calc(var(--float-distance) * -1)); }
|
|
6694
|
+
}
|
|
6695
|
+
.mvc-bubble { position: relative; display: inline-block; max-width: 240px; padding: 8px 12px; border-radius: 18px; background: var(--bubble); font-size: 14px; line-height: 20px; margin: 0; }
|
|
6696
|
+
.mvc-bubble span { position: relative; z-index: 1; }
|
|
6697
|
+
.mvc-bubble::before { content: ""; position: absolute; bottom: 0; left: -7px; width: 20px; height: 20px; background: var(--bubble); border-bottom-right-radius: 16px 14px; }
|
|
6698
|
+
.mvc-bubble::after { content: ""; position: absolute; bottom: 0; left: -26px; width: 26px; height: 20px; background: var(--mvc-surface); border-bottom-right-radius: 10px; }
|
|
6699
|
+
|
|
6700
|
+
.mvc-transcript { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; padding-left: 32px; }
|
|
6701
|
+
.mvc-transcript p {
|
|
6702
|
+
margin: 0;
|
|
6703
|
+
font-size: 14px;
|
|
6704
|
+
line-height: 20px;
|
|
6705
|
+
color: var(--mvc-fg);
|
|
6706
|
+
text-align: right;
|
|
6707
|
+
text-wrap: pretty;
|
|
6708
|
+
display: -webkit-box;
|
|
6709
|
+
-webkit-box-orient: vertical;
|
|
6710
|
+
-webkit-line-clamp: 3;
|
|
6711
|
+
overflow: hidden;
|
|
6712
|
+
}
|
|
6713
|
+
.mvc-sent-img { display: block; width: 40px; height: 40px; border-radius: 10px; object-fit: cover; outline: 1px solid var(--mvc-img-outline); outline-offset: -1px; }
|
|
6714
|
+
.mvc-t-stream-w {
|
|
6715
|
+
opacity: 0;
|
|
6716
|
+
filter: blur(var(--stream-blur));
|
|
6717
|
+
transition:
|
|
6718
|
+
opacity var(--stream-fade) var(--stream-ease),
|
|
6719
|
+
filter var(--stream-fade) var(--stream-ease);
|
|
6720
|
+
}
|
|
6721
|
+
.mvc-t-stream-w.is-in { opacity: 1; filter: blur(0); }
|
|
6722
|
+
|
|
6723
|
+
.mvc-bottom { flex: none; padding: 0 16px 16px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
|
|
6724
|
+
.mvc-caption { font-size: 12px; line-height: 16px; color: var(--mvc-muted); }
|
|
6725
|
+
|
|
6726
|
+
.mvc-t-text-swap {
|
|
6727
|
+
display: inline-block;
|
|
6728
|
+
transform: translateY(0);
|
|
6729
|
+
filter: blur(0);
|
|
6730
|
+
opacity: 1;
|
|
6731
|
+
transition:
|
|
6732
|
+
transform var(--text-swap-dur) var(--text-swap-ease),
|
|
6733
|
+
filter var(--text-swap-dur) var(--text-swap-ease),
|
|
6734
|
+
opacity var(--text-swap-dur) var(--text-swap-ease);
|
|
6735
|
+
will-change: transform, filter, opacity;
|
|
6736
|
+
}
|
|
6737
|
+
.mvc-t-text-swap.is-exit { transform: translateY(calc(var(--text-swap-translate-y) * -1)); filter: blur(var(--text-swap-blur)); opacity: 0; }
|
|
6738
|
+
.mvc-t-text-swap.is-enter-start { transform: translateY(var(--text-swap-translate-y)); filter: blur(var(--text-swap-blur)); opacity: 0; transition: none; }
|
|
6739
|
+
|
|
6740
|
+
.mvc-t-icon-swap { position: relative; display: inline-grid; }
|
|
6741
|
+
.mvc-t-icon-swap .mvc-t-icon {
|
|
6742
|
+
grid-area: 1 / 1;
|
|
6743
|
+
transition:
|
|
6744
|
+
opacity var(--icon-swap-dur) var(--icon-swap-ease),
|
|
6745
|
+
filter var(--icon-swap-dur) var(--icon-swap-ease),
|
|
6746
|
+
transform var(--icon-swap-dur) var(--icon-swap-ease);
|
|
6747
|
+
}
|
|
6748
|
+
.mvc-t-icon-swap[data-state="a"] .mvc-t-icon[data-icon="a"],
|
|
6749
|
+
.mvc-t-icon-swap[data-state="b"] .mvc-t-icon[data-icon="b"] { opacity: 1; filter: blur(0); transform: scale(1); }
|
|
6750
|
+
.mvc-t-icon-swap[data-state="a"] .mvc-t-icon[data-icon="b"],
|
|
6751
|
+
.mvc-t-icon-swap[data-state="b"] .mvc-t-icon[data-icon="a"] { opacity: 0; filter: blur(var(--icon-swap-blur)); transform: scale(var(--icon-swap-start-scale)); }
|
|
6752
|
+
.mvc-t-icon { display: grid; place-items: center; }
|
|
6753
|
+
|
|
6754
|
+
.mvc-field {
|
|
6755
|
+
box-sizing: border-box;
|
|
6756
|
+
width: 100%;
|
|
6757
|
+
height: 44px;
|
|
6758
|
+
padding: 4px;
|
|
6759
|
+
display: flex;
|
|
6760
|
+
align-items: center;
|
|
6761
|
+
gap: 4px;
|
|
6762
|
+
border-radius: 22px;
|
|
6763
|
+
background: var(--mvc-surface);
|
|
6764
|
+
box-shadow: 0 0 0 1px var(--mvc-border);
|
|
6765
|
+
transition: box-shadow var(--duration-quick) var(--ease-smooth-out);
|
|
6766
|
+
}
|
|
6767
|
+
.mvc-field:has(.mvc-input:focus) { box-shadow: 0 0 0 1px var(--mvc-accent), 0 0 0 4px var(--mvc-focus-soft); }
|
|
6768
|
+
.mvc-attach {
|
|
6769
|
+
--press-scale: 0.95;
|
|
6770
|
+
flex: none;
|
|
6771
|
+
width: 36px;
|
|
6772
|
+
height: 36px;
|
|
6773
|
+
border-radius: 50%;
|
|
6774
|
+
display: grid;
|
|
6775
|
+
place-items: center;
|
|
6776
|
+
color: var(--mvc-muted);
|
|
6777
|
+
transition: transform var(--press-dur) var(--ease-smooth-out), background-color var(--duration-quick) var(--ease-smooth-out);
|
|
6778
|
+
}
|
|
6779
|
+
@media (hover: hover) and (pointer: fine) { .mvc-attach:hover { background-color: var(--mvc-chip); } }
|
|
6780
|
+
.mvc-attach:is(:active,.is-pressed) { transform: scale(var(--press-scale)); }
|
|
6781
|
+
.mvc-thumb { display: block; width: 28px; height: 28px; border-radius: 50%; object-fit: cover; outline: 1px solid var(--mvc-img-outline); outline-offset: -1px; }
|
|
6782
|
+
|
|
6783
|
+
.mvc-t-clear { position: relative; overflow: hidden; }
|
|
6784
|
+
.mvc-input-wrap { flex: 1; min-width: 0; height: 36px; }
|
|
6785
|
+
.mvc-input { width: 100%; height: 100%; box-sizing: border-box; padding: 0 4px; outline: none; font-size: 13px; line-height: 20px; color: var(--mvc-fg); caret-color: var(--mvc-fg); }
|
|
6786
|
+
.mvc-t-clear-mirror, .mvc-t-clear-placeholder {
|
|
6787
|
+
position: absolute;
|
|
6788
|
+
inset: 0;
|
|
6789
|
+
display: flex;
|
|
6790
|
+
align-items: center;
|
|
6791
|
+
pointer-events: none;
|
|
6792
|
+
white-space: nowrap;
|
|
6793
|
+
overflow: hidden;
|
|
6794
|
+
z-index: 2;
|
|
6795
|
+
padding: 0 4px;
|
|
6796
|
+
font-size: 13px;
|
|
6797
|
+
line-height: 20px;
|
|
6798
|
+
}
|
|
6799
|
+
.mvc-t-clear-mirror { opacity: 0; color: var(--mvc-fg); }
|
|
6800
|
+
.mvc-t-clear-placeholder { color: var(--mvc-muted); }
|
|
6801
|
+
.mvc-t-clear.has-value .mvc-t-clear-mirror, .mvc-t-clear.is-clearing .mvc-t-clear-mirror { opacity: 1; }
|
|
6802
|
+
.mvc-t-clear.has-value > input, .mvc-t-clear.is-clearing > input { -webkit-text-fill-color: transparent; }
|
|
6803
|
+
.mvc-t-clear.has-value .mvc-t-clear-placeholder { opacity: 0; }
|
|
6804
|
+
.mvc-t-clear-glow { position: absolute; inset: 0; pointer-events: none; opacity: 0; z-index: 3; mix-blend-mode: multiply; }
|
|
6805
|
+
.mova-voice[data-theme="dark"] .mvc-t-clear-glow { mix-blend-mode: screen; }
|
|
6806
|
+
|
|
6807
|
+
.mvc-mic {
|
|
6808
|
+
--press-scale: 0.95;
|
|
6809
|
+
flex: none;
|
|
6810
|
+
width: 36px;
|
|
6811
|
+
height: 36px;
|
|
6812
|
+
border-radius: 50%;
|
|
6813
|
+
display: grid;
|
|
6814
|
+
place-items: center;
|
|
6815
|
+
background: var(--mvc-btn-bg);
|
|
6816
|
+
box-shadow: var(--mvc-btn-shadow);
|
|
6817
|
+
color: var(--mvc-fg);
|
|
6818
|
+
transition: transform var(--press-dur) var(--ease-smooth-out);
|
|
6819
|
+
}
|
|
6820
|
+
:where(.mova-voice) .mvc-mic { background: var(--mvc-btn-bg); }
|
|
6821
|
+
@media (hover: hover) and (pointer: fine) { .mvc-mic:hover { background-image: linear-gradient(var(--mvc-hover), var(--mvc-hover)); } }
|
|
6822
|
+
.mvc-mic:is(:active,.is-pressed) { transform: scale(var(--press-scale)); }
|
|
6823
|
+
.mova-voice .mvc-mic:focus-visible { box-shadow: var(--mvc-btn-shadow), 0 0 0 2px var(--mvc-surface), 0 0 0 4px var(--mvc-accent); }
|
|
6824
|
+
.mvc-wave { display: flex; align-items: center; gap: 2px; height: 16px; }
|
|
6825
|
+
.mvc-wave i { display: block; width: 2px; border-radius: 1px; background: currentColor; transform-origin: center; }
|
|
6826
|
+
.mvc-wave i:nth-child(1) { height: 4px; }
|
|
6827
|
+
.mvc-wave i:nth-child(2) { height: 9px; }
|
|
6828
|
+
.mvc-wave i:nth-child(3) { height: 14px; }
|
|
6829
|
+
.mvc-wave i:nth-child(4) { height: 9px; }
|
|
6830
|
+
.mvc-wave i:nth-child(5) { height: 4px; }
|
|
6831
|
+
.mvc-mic.is-live .mvc-wave i { animation: mvc-wave var(--wave-dur) ease-in-out infinite; }
|
|
6832
|
+
.mvc-mic.is-live .mvc-wave i:nth-child(2) { animation-delay: calc(var(--wave-dur) * -0.3); }
|
|
6833
|
+
.mvc-mic.is-live .mvc-wave i:nth-child(3) { animation-delay: calc(var(--wave-dur) * -0.6); }
|
|
6834
|
+
.mvc-mic.is-live .mvc-wave i:nth-child(4) { animation-delay: calc(var(--wave-dur) * -0.15); }
|
|
6835
|
+
.mvc-mic.is-live .mvc-wave i:nth-child(5) { animation-delay: calc(var(--wave-dur) * -0.45); }
|
|
6836
|
+
@keyframes mvc-wave {
|
|
6837
|
+
0%, 100% { transform: scaleY(1); }
|
|
6838
|
+
50% { transform: scaleY(var(--wave-min)); }
|
|
6839
|
+
}
|
|
6840
|
+
|
|
6841
|
+
@media (prefers-reduced-motion: reduce) {
|
|
6842
|
+
.mvc-bubble-row, .mvc-mic.is-live .mvc-wave i { animation: none !important; }
|
|
6843
|
+
.mvc-t-text-swap, .mvc-t-icon-swap .mvc-t-icon, .mvc-t-page-slide .mvc-t-page, .mvc-menu-icon line { transition: none !important; }
|
|
6844
|
+
.mvc-t-stream-w { transition: none !important; filter: none !important; opacity: 1 !important; }
|
|
6845
|
+
.mvc-t-clear-glow { opacity: 0 !important; }
|
|
6846
|
+
.mvc-mic, .mvc-menu, .mvc-attach, .mvc-row { transition: none; }
|
|
6847
|
+
.mvc-mic:is(:active,.is-pressed), .mvc-menu:is(:active,.is-pressed), .mvc-attach:is(:active,.is-pressed), .mvc-row:is(:active,.is-pressed) { transform: none; }
|
|
6848
|
+
}
|
|
6849
|
+
|
|
6850
|
+
.mova-voice { --mvc-bg:#f9f9f9; --mvc-fg:#0d0d0d; --mvc-muted:#6c6c6c; --mvc-border:rgba(0,0,0,.08); --mvc-surface:#fff; --mvc-accent:#17181c; font:400 13px/20px "Inter Variable",Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; font-optical-sizing:auto; font-feature-settings:"liga" 1,"calt" 1; letter-spacing:0; color-scheme:light; }
|
|
6851
|
+
.mova-voice[data-theme="dark"] { --mvc-bg:#131313; --mvc-fg:#f2f2f2; --mvc-muted:rgba(202,202,202,.7); --mvc-border:rgba(255,255,255,.08); --mvc-surface:#1d1d1d; --mvc-accent:#fff; color-scheme:dark; }
|
|
6852
|
+
.mova-voice { min-width:0; }
|
|
6853
|
+
.mova-voice, .mova-voice * { box-sizing:border-box; }
|
|
6854
|
+
.mova-voice button { -webkit-tap-highlight-color:transparent; touch-action:manipulation; -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
|
|
6855
|
+
.mova-voice button:disabled { cursor:default; opacity:.5; }
|
|
6856
|
+
.mova-voice .mvc-list { overflow:auto; }
|
|
6857
|
+
.mova-voice .mvc-sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0; }
|
|
6858
|
+
.mova-voice .mvc-transcript p { overflow-wrap:anywhere; }
|
|
6859
|
+
@media (prefers-reduced-motion:reduce) { .mova-voice *, .mova-voice *::before, .mova-voice *::after { animation:none!important; transition:none!important; } }
|
|
4754
6860
|
`;
|
|
4755
6861
|
|
|
4756
6862
|
// .generated/ui/cursor/cursor-trail.tsx
|
|
4757
|
-
import { useEffect as
|
|
6863
|
+
import { useEffect as useEffect16, useState as useState20 } from "react";
|
|
4758
6864
|
import { motion as motion7, useSpring } from "framer-motion";
|
|
4759
|
-
import { Fragment as
|
|
6865
|
+
import { Fragment as Fragment11, jsx as jsx19 } from "react/jsx-runtime";
|
|
4760
6866
|
function CursorTrail({
|
|
4761
6867
|
color = "bg-blue-500",
|
|
4762
6868
|
size = 8,
|
|
@@ -4764,7 +6870,7 @@ function CursorTrail({
|
|
|
4764
6870
|
}) {
|
|
4765
6871
|
const [coords, setCoords] = useState20({ x: 0, y: 0 });
|
|
4766
6872
|
const [isVisible, setIsVisible] = useState20(false);
|
|
4767
|
-
|
|
6873
|
+
useEffect16(() => {
|
|
4768
6874
|
const handleMouseMove = (e) => {
|
|
4769
6875
|
setCoords({ x: e.clientX, y: e.clientY });
|
|
4770
6876
|
if (!isVisible) setIsVisible(true);
|
|
@@ -4779,7 +6885,7 @@ function CursorTrail({
|
|
|
4779
6885
|
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
4780
6886
|
};
|
|
4781
6887
|
}, [isVisible]);
|
|
4782
|
-
return /* @__PURE__ */ jsx19(
|
|
6888
|
+
return /* @__PURE__ */ jsx19(Fragment11, { children: isVisible && Array.from({ length: count }).map((_, index) => {
|
|
4783
6889
|
const springConfig = {
|
|
4784
6890
|
stiffness: 300 - index * 30,
|
|
4785
6891
|
damping: 25 + index * 2,
|
|
@@ -4809,7 +6915,7 @@ function TrailDot({
|
|
|
4809
6915
|
}) {
|
|
4810
6916
|
const x = useSpring(coords.x, springConfig);
|
|
4811
6917
|
const y = useSpring(coords.y, springConfig);
|
|
4812
|
-
|
|
6918
|
+
useEffect16(() => {
|
|
4813
6919
|
x.set(coords.x);
|
|
4814
6920
|
y.set(coords.y);
|
|
4815
6921
|
}, [coords, x, y]);
|
|
@@ -4833,7 +6939,7 @@ function TrailDot({
|
|
|
4833
6939
|
}
|
|
4834
6940
|
|
|
4835
6941
|
// .generated/ui/cursor/mouse-follow.tsx
|
|
4836
|
-
import { useEffect as
|
|
6942
|
+
import { useEffect as useEffect17, useState as useState21 } from "react";
|
|
4837
6943
|
import { motion as motion8, useSpring as useSpring2 } from "framer-motion";
|
|
4838
6944
|
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
4839
6945
|
function MouseFollow({
|
|
@@ -4845,7 +6951,7 @@ function MouseFollow({
|
|
|
4845
6951
|
const [isVisible, setIsVisible] = useState21(false);
|
|
4846
6952
|
const x = useSpring2(0, { stiffness, damping });
|
|
4847
6953
|
const y = useSpring2(0, { stiffness, damping });
|
|
4848
|
-
|
|
6954
|
+
useEffect17(() => {
|
|
4849
6955
|
const handleMouseMove = (e) => {
|
|
4850
6956
|
x.set(e.clientX);
|
|
4851
6957
|
y.set(e.clientY);
|
|
@@ -4878,7 +6984,7 @@ function MouseFollow({
|
|
|
4878
6984
|
}
|
|
4879
6985
|
|
|
4880
6986
|
// .generated/ui/cursor/spotlight.tsx
|
|
4881
|
-
import { useRef as
|
|
6987
|
+
import { useRef as useRef13, useState as useState22 } from "react";
|
|
4882
6988
|
import { motion as motion9 } from "framer-motion";
|
|
4883
6989
|
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4884
6990
|
function Spotlight({
|
|
@@ -4887,7 +6993,7 @@ function Spotlight({
|
|
|
4887
6993
|
glowColor = "rgba(255, 255, 255, 0.08)",
|
|
4888
6994
|
glowSize = 250
|
|
4889
6995
|
}) {
|
|
4890
|
-
const containerRef =
|
|
6996
|
+
const containerRef = useRef13(null);
|
|
4891
6997
|
const [coords, setCoords] = useState22({ x: 0, y: 0 });
|
|
4892
6998
|
const [opacity, setOpacity] = useState22(0);
|
|
4893
6999
|
const handleMouseMove = (e) => {
|
|
@@ -5163,7 +7269,7 @@ function CardHover({
|
|
|
5163
7269
|
}
|
|
5164
7270
|
|
|
5165
7271
|
// .generated/ui/hover/glow-button.tsx
|
|
5166
|
-
import { useRef as
|
|
7272
|
+
import { useRef as useRef14, useState as useState24 } from "react";
|
|
5167
7273
|
import { motion as motion18 } from "framer-motion";
|
|
5168
7274
|
import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5169
7275
|
function GlowButton({
|
|
@@ -5173,7 +7279,7 @@ function GlowButton({
|
|
|
5173
7279
|
// Light blue default
|
|
5174
7280
|
onClick
|
|
5175
7281
|
}) {
|
|
5176
|
-
const containerRef =
|
|
7282
|
+
const containerRef = useRef14(null);
|
|
5177
7283
|
const [coords, setCoords] = useState24({ x: 0, y: 0 });
|
|
5178
7284
|
const [opacity, setOpacity] = useState24(0);
|
|
5179
7285
|
const handleMouseMove = (e) => {
|
|
@@ -5211,7 +7317,7 @@ function GlowButton({
|
|
|
5211
7317
|
}
|
|
5212
7318
|
|
|
5213
7319
|
// .generated/ui/hover/inset-button.tsx
|
|
5214
|
-
import { Fragment as
|
|
7320
|
+
import { Fragment as Fragment12, jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5215
7321
|
var insetButtonStyles = `
|
|
5216
7322
|
.mova-inset-button {
|
|
5217
7323
|
--surface-elevated: oklch(0.996 0.001 95);
|
|
@@ -5284,7 +7390,7 @@ var insetButtonStyles = `
|
|
|
5284
7390
|
}
|
|
5285
7391
|
`;
|
|
5286
7392
|
function InsetButton({ variant = "text", theme = "dark", children, className = "", type = "button", ...props }) {
|
|
5287
|
-
return /* @__PURE__ */ jsxs22(
|
|
7393
|
+
return /* @__PURE__ */ jsxs22(Fragment12, { children: [
|
|
5288
7394
|
/* @__PURE__ */ jsx31("style", { children: insetButtonStyles }),
|
|
5289
7395
|
/* @__PURE__ */ jsx31(
|
|
5290
7396
|
"button",
|
|
@@ -5302,7 +7408,7 @@ function InsetButton({ variant = "text", theme = "dark", children, className = "
|
|
|
5302
7408
|
}
|
|
5303
7409
|
|
|
5304
7410
|
// .generated/ui/hover/magnetic-button.tsx
|
|
5305
|
-
import { useRef as
|
|
7411
|
+
import { useRef as useRef15, useState as useState25 } from "react";
|
|
5306
7412
|
import { motion as motion19, useSpring as useSpring3 } from "framer-motion";
|
|
5307
7413
|
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
5308
7414
|
function MagneticButton({
|
|
@@ -5312,7 +7418,7 @@ function MagneticButton({
|
|
|
5312
7418
|
className = "",
|
|
5313
7419
|
onClick
|
|
5314
7420
|
}) {
|
|
5315
|
-
const ref =
|
|
7421
|
+
const ref = useRef15(null);
|
|
5316
7422
|
const [position, setPosition] = useState25({ x: 0, y: 0 });
|
|
5317
7423
|
const springConfig = { stiffness: 150, damping: 15, mass: 0.6 };
|
|
5318
7424
|
const x = useSpring3(0, springConfig);
|
|
@@ -5353,7 +7459,7 @@ function MagneticButton({
|
|
|
5353
7459
|
}
|
|
5354
7460
|
|
|
5355
7461
|
// .generated/ui/hover/tilt-card.tsx
|
|
5356
|
-
import { useRef as
|
|
7462
|
+
import { useRef as useRef16, useState as useState26 } from "react";
|
|
5357
7463
|
import { motion as motion20, useMotionValue, useSpring as useSpring4, useTransform } from "framer-motion";
|
|
5358
7464
|
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
5359
7465
|
function TiltCard({
|
|
@@ -5362,7 +7468,7 @@ function TiltCard({
|
|
|
5362
7468
|
className = "",
|
|
5363
7469
|
cardClassName = ""
|
|
5364
7470
|
}) {
|
|
5365
|
-
const cardRef =
|
|
7471
|
+
const cardRef = useRef16(null);
|
|
5366
7472
|
const [isHovered, setIsHovered] = useState26(false);
|
|
5367
7473
|
const x = useMotionValue(0);
|
|
5368
7474
|
const y = useMotionValue(0);
|
|
@@ -8110,7 +10216,7 @@ var WanderingCube = () => {
|
|
|
8110
10216
|
};
|
|
8111
10217
|
|
|
8112
10218
|
// .generated/ui/loading/wandering-eyes.tsx
|
|
8113
|
-
import { Fragment as
|
|
10219
|
+
import { Fragment as Fragment13, jsx as jsx165, jsxs as jsxs79 } from "react/jsx-runtime";
|
|
8114
10220
|
function clamp(value, min, max) {
|
|
8115
10221
|
return Math.min(Math.max(value, min), max);
|
|
8116
10222
|
}
|
|
@@ -8138,7 +10244,7 @@ function WanderingEyes({
|
|
|
8138
10244
|
"--mova-wandering-eyes-blink": `${safeBlinkScale}`,
|
|
8139
10245
|
"--mova-wandering-eyes-travel-scale": `${safeTravelScale}`
|
|
8140
10246
|
};
|
|
8141
|
-
return /* @__PURE__ */ jsxs79(
|
|
10247
|
+
return /* @__PURE__ */ jsxs79(Fragment13, { children: [
|
|
8142
10248
|
/* @__PURE__ */ jsx165("style", { children: `
|
|
8143
10249
|
@keyframes mova-wandering-eyes-move {
|
|
8144
10250
|
0%, 10% { background-position: 0 0; }
|
|
@@ -8364,7 +10470,7 @@ var ZigZagPulse = () => {
|
|
|
8364
10470
|
};
|
|
8365
10471
|
|
|
8366
10472
|
// .generated/ui/patterns/animated-tags.tsx
|
|
8367
|
-
import { CircleX, Plus as
|
|
10473
|
+
import { CircleX, Plus as Plus2 } from "lucide-react";
|
|
8368
10474
|
import { AnimatePresence as AnimatePresence7, motion as motion155, useReducedMotion as useReducedMotion9 } from "framer-motion";
|
|
8369
10475
|
import { useState as useState27 } from "react";
|
|
8370
10476
|
import { jsx as jsx171, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
@@ -8444,7 +10550,7 @@ function AnimatedTags({
|
|
|
8444
10550
|
tag,
|
|
8445
10551
|
" ",
|
|
8446
10552
|
/* @__PURE__ */ jsx171(
|
|
8447
|
-
|
|
10553
|
+
Plus2,
|
|
8448
10554
|
{
|
|
8449
10555
|
className: "ease flex items-center justify-center rounded-full transition-all duration-200 group-hover/tag:bg-primary group-hover/tag:text-foreground",
|
|
8450
10556
|
size: 16
|
|
@@ -8458,7 +10564,7 @@ function AnimatedTags({
|
|
|
8458
10564
|
}
|
|
8459
10565
|
|
|
8460
10566
|
// .generated/ui/patterns/expanding-icon-tabs.tsx
|
|
8461
|
-
import { useEffect as
|
|
10567
|
+
import { useEffect as useEffect18, useRef as useRef17, useState as useState28 } from "react";
|
|
8462
10568
|
import { Activity as Activity2, Compass, CreditCard, SlidersHorizontal as SlidersHorizontal2, Users } from "lucide-react";
|
|
8463
10569
|
import { jsx as jsx172, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
8464
10570
|
var items = [
|
|
@@ -8471,8 +10577,8 @@ var items = [
|
|
|
8471
10577
|
];
|
|
8472
10578
|
function ExpandingIconTabs() {
|
|
8473
10579
|
const [active, setActive] = useState28(null);
|
|
8474
|
-
const rootRef =
|
|
8475
|
-
|
|
10580
|
+
const rootRef = useRef17(null);
|
|
10581
|
+
useEffect18(() => {
|
|
8476
10582
|
if (!active) return;
|
|
8477
10583
|
const region = rootRef.current?.parentElement;
|
|
8478
10584
|
if (!region) return;
|
|
@@ -8553,13 +10659,13 @@ function ExpandingIconTabs() {
|
|
|
8553
10659
|
|
|
8554
10660
|
// .generated/ui/patterns/gooey-popover.tsx
|
|
8555
10661
|
import gsap from "gsap";
|
|
8556
|
-
import { useCallback as
|
|
10662
|
+
import { useCallback as useCallback4, useEffect as useEffect19, useId as useId11, useRef as useRef18, useState as useState29 } from "react";
|
|
8557
10663
|
import { jsx as jsx173, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
8558
10664
|
function cn2(...classes) {
|
|
8559
10665
|
return classes.filter(Boolean).join(" ");
|
|
8560
10666
|
}
|
|
8561
10667
|
function useClickOutside(ref, handler, eventType = "mousedown") {
|
|
8562
|
-
|
|
10668
|
+
useEffect19(() => {
|
|
8563
10669
|
function callback(event) {
|
|
8564
10670
|
const target = event.target;
|
|
8565
10671
|
if (!target?.isConnected) return;
|
|
@@ -8599,15 +10705,15 @@ function GooeyPopover({
|
|
|
8599
10705
|
const [internalIsOpen, setInternalIsOpen] = useState29(false);
|
|
8600
10706
|
const isOpen = isControlled ? controlledIsOpen : internalIsOpen;
|
|
8601
10707
|
const [isVisible, setIsVisible] = useState29(false);
|
|
8602
|
-
const containerRef =
|
|
8603
|
-
const measureRef =
|
|
8604
|
-
const filteredContentRef =
|
|
8605
|
-
const unfilteredContentRef =
|
|
8606
|
-
const innerContentRef =
|
|
8607
|
-
const timelineRef =
|
|
10708
|
+
const containerRef = useRef18(null);
|
|
10709
|
+
const measureRef = useRef18(null);
|
|
10710
|
+
const filteredContentRef = useRef18(null);
|
|
10711
|
+
const unfilteredContentRef = useRef18(null);
|
|
10712
|
+
const innerContentRef = useRef18(null);
|
|
10713
|
+
const timelineRef = useRef18(null);
|
|
8608
10714
|
const [contentHeight, setContentHeight] = useState29(0);
|
|
8609
10715
|
const [prefersReducedMotion, setPrefersReducedMotion] = useState29(false);
|
|
8610
|
-
|
|
10716
|
+
useEffect19(() => {
|
|
8611
10717
|
const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
8612
10718
|
setPrefersReducedMotion(mq.matches);
|
|
8613
10719
|
const handler = (e) => {
|
|
@@ -8616,7 +10722,7 @@ function GooeyPopover({
|
|
|
8616
10722
|
mq.addEventListener("change", handler);
|
|
8617
10723
|
return () => mq.removeEventListener("change", handler);
|
|
8618
10724
|
}, []);
|
|
8619
|
-
const setIsOpen =
|
|
10725
|
+
const setIsOpen = useCallback4(
|
|
8620
10726
|
(open) => {
|
|
8621
10727
|
if (!isControlled) {
|
|
8622
10728
|
setInternalIsOpen(open);
|
|
@@ -8625,13 +10731,13 @@ function GooeyPopover({
|
|
|
8625
10731
|
},
|
|
8626
10732
|
[isControlled, onOpenChange]
|
|
8627
10733
|
);
|
|
8628
|
-
const handleClose =
|
|
10734
|
+
const handleClose = useCallback4(() => {
|
|
8629
10735
|
if (isOpen) {
|
|
8630
10736
|
setIsOpen(false);
|
|
8631
10737
|
}
|
|
8632
10738
|
}, [isOpen, setIsOpen]);
|
|
8633
10739
|
useClickOutside(containerRef, handleClose);
|
|
8634
|
-
|
|
10740
|
+
useEffect19(() => {
|
|
8635
10741
|
const handleKeyDown = (event) => {
|
|
8636
10742
|
if (event.key === "Escape" && isOpen) {
|
|
8637
10743
|
setIsOpen(false);
|
|
@@ -8640,7 +10746,7 @@ function GooeyPopover({
|
|
|
8640
10746
|
window.addEventListener("keydown", handleKeyDown);
|
|
8641
10747
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
8642
10748
|
}, [isOpen, setIsOpen]);
|
|
8643
|
-
|
|
10749
|
+
useEffect19(() => {
|
|
8644
10750
|
const measureHeight = () => {
|
|
8645
10751
|
if (measureRef.current) {
|
|
8646
10752
|
const height = measureRef.current.scrollHeight;
|
|
@@ -8662,7 +10768,7 @@ function GooeyPopover({
|
|
|
8662
10768
|
const triggerRadius = triggerSize / 2;
|
|
8663
10769
|
const translateY = side === "top" ? -(contentHeight + sideOffset) : triggerSize + sideOffset;
|
|
8664
10770
|
const contentLeft = triggerRadius - contentWidth / 2;
|
|
8665
|
-
|
|
10771
|
+
useEffect19(() => {
|
|
8666
10772
|
if (contentHeight === 0) {
|
|
8667
10773
|
return;
|
|
8668
10774
|
}
|
|
@@ -9019,7 +11125,7 @@ function ScrollReveal({
|
|
|
9019
11125
|
}
|
|
9020
11126
|
|
|
9021
11127
|
// .generated/ui/scroll/sticky-reveal.tsx
|
|
9022
|
-
import { useRef as
|
|
11128
|
+
import { useRef as useRef19, useState as useState30 } from "react";
|
|
9023
11129
|
import { motion as motion158, useMotionValueEvent, useScroll as useScroll2 } from "framer-motion";
|
|
9024
11130
|
import { jsx as jsx176, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
9025
11131
|
function StickyReveal({
|
|
@@ -9027,7 +11133,7 @@ function StickyReveal({
|
|
|
9027
11133
|
className = ""
|
|
9028
11134
|
}) {
|
|
9029
11135
|
const [activeCard, setActiveCard] = useState30(0);
|
|
9030
|
-
const ref =
|
|
11136
|
+
const ref = useRef19(null);
|
|
9031
11137
|
const { scrollYProgress } = useScroll2({
|
|
9032
11138
|
target: ref,
|
|
9033
11139
|
offset: ["start start", "end end"]
|
|
@@ -9322,7 +11428,7 @@ var ClassicToggle = () => {
|
|
|
9322
11428
|
};
|
|
9323
11429
|
|
|
9324
11430
|
// .generated/ui/transitions/page-transition.tsx
|
|
9325
|
-
import { useEffect as
|
|
11431
|
+
import { useEffect as useEffect20, useRef as useRef20 } from "react";
|
|
9326
11432
|
import { motion as motion164 } from "framer-motion";
|
|
9327
11433
|
import { jsx as jsx182, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
9328
11434
|
var PageTransition = ({
|
|
@@ -9331,8 +11437,8 @@ var PageTransition = ({
|
|
|
9331
11437
|
onComplete,
|
|
9332
11438
|
className = ""
|
|
9333
11439
|
}) => {
|
|
9334
|
-
const pathRefs =
|
|
9335
|
-
|
|
11440
|
+
const pathRefs = useRef20([]);
|
|
11441
|
+
useEffect20(() => {
|
|
9336
11442
|
if (type !== "liquid-wave" || !isVisible) return;
|
|
9337
11443
|
let animId;
|
|
9338
11444
|
const numPoints = 12;
|