@xhub-short/ui 0.1.0-beta.1 → 0.1.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/CommentSheet.css-DyEc3Sro.d.ts +217 -0
  2. package/dist/VideoSlotPlayIndicator-DPs8Xt5C.d.ts +51 -0
  3. package/dist/chunk-3OB3OVYR.js +349 -0
  4. package/dist/{chunk-WKX2WBVO.js → chunk-3XPJHUYL.js} +1 -39
  5. package/dist/chunk-4RIMQOBR.js +58 -0
  6. package/dist/chunk-4TUBNA2X.js +180 -0
  7. package/dist/{chunk-4YDIRPIN.js → chunk-ANCP53F3.js} +3 -3
  8. package/dist/{chunk-UXMA4KJZ.js → chunk-CAWE42LH.js} +5 -3
  9. package/dist/{chunk-ANGBSV7L.js → chunk-CIIZ3IHV.js} +10 -5
  10. package/dist/chunk-DR7KR7OT.js +103 -0
  11. package/dist/chunk-DXLCQ4FH.js +102 -0
  12. package/dist/chunk-EDWS2IPH.js +1 -0
  13. package/dist/chunk-FR7UQSZP.js +570 -0
  14. package/dist/chunk-IWSBYOSS.js +91 -0
  15. package/dist/chunk-JEY6R4KJ.js +334 -0
  16. package/dist/chunk-KMJ3PQ7M.js +1262 -0
  17. package/dist/chunk-MFJS65C5.js +368 -0
  18. package/dist/{chunk-HW4LXTFT.js → chunk-OM4L7RE5.js} +18 -6
  19. package/dist/chunk-PBIH2F2Q.js +344 -0
  20. package/dist/chunk-PJ4NMVMY.js +326 -0
  21. package/dist/chunk-Q6MG7AVG.js +531 -0
  22. package/dist/chunk-QCKVF2DR.js +713 -0
  23. package/dist/chunk-QCRRF76W.js +75 -0
  24. package/dist/chunk-QUEJHA24.js +508 -0
  25. package/dist/chunk-VXW7AOGM.js +285 -0
  26. package/dist/chunk-YB7AXTX7.js +430 -0
  27. package/dist/chunk-ZGWSJ6Z5.js +601 -0
  28. package/dist/components/ActionBar/index.js +1 -1
  29. package/dist/components/AdvanceMenu/index.d.ts +78 -0
  30. package/dist/components/AdvanceMenu/index.js +1 -0
  31. package/dist/components/AuthorInfo/index.d.ts +5 -1
  32. package/dist/components/AuthorInfo/index.js +1 -1
  33. package/dist/components/BottomSheet/index.d.ts +82 -0
  34. package/dist/components/BottomSheet/index.js +1 -0
  35. package/dist/components/CleanModeOverlay/index.d.ts +60 -0
  36. package/dist/components/CleanModeOverlay/index.js +1 -0
  37. package/dist/components/CommentSheet/index.d.ts +164 -0
  38. package/dist/components/CommentSheet/index.js +1 -0
  39. package/dist/components/DetailView/index.d.ts +311 -0
  40. package/dist/components/DetailView/index.js +1 -0
  41. package/dist/components/ErrorBoundary/index.js +1 -1
  42. package/dist/components/ImageCarousel/index.d.ts +50 -0
  43. package/dist/components/ImageCarousel/index.js +1 -0
  44. package/dist/components/ImagePostSlot/index.d.ts +207 -0
  45. package/dist/components/ImagePostSlot/index.js +1 -0
  46. package/dist/components/ProgressBar/index.d.ts +30 -2
  47. package/dist/components/ProgressBar/index.js +1 -1
  48. package/dist/components/QualityPicker/index.d.ts +35 -0
  49. package/dist/components/QualityPicker/index.js +1 -0
  50. package/dist/components/ReportSheet/index.d.ts +68 -0
  51. package/dist/components/ReportSheet/index.js +1 -0
  52. package/dist/components/Skeleton/index.js +1 -1
  53. package/dist/components/SpeedPicker/index.d.ts +32 -0
  54. package/dist/components/SpeedPicker/index.js +1 -0
  55. package/dist/components/VideoFeed/index.d.ts +12 -1
  56. package/dist/components/VideoFeed/index.js +1 -1
  57. package/dist/components/VideoInfo/index.d.ts +4 -2
  58. package/dist/components/VideoInfo/index.js +1 -1
  59. package/dist/components/VideoPlayer/index.d.ts +14 -41
  60. package/dist/components/VideoPlayer/index.js +1 -1
  61. package/dist/components/VideoSlot/index.d.ts +84 -65
  62. package/dist/components/VideoSlot/index.js +2 -1
  63. package/dist/components/VirtualSlider/index.d.ts +339 -0
  64. package/dist/components/VirtualSlider/index.js +1 -0
  65. package/dist/components/icons/index.js +1 -1
  66. package/dist/index.d.ts +107 -95
  67. package/dist/index.js +84 -27
  68. package/package.json +51 -7
  69. package/dist/chunk-2PTMP65P.js +0 -738
  70. package/dist/chunk-4MN72OZH.js +0 -148
  71. package/dist/chunk-DHQJBXQW.js +0 -562
  72. package/dist/chunk-SSJDO24Q.js +0 -204
  73. package/dist/chunk-XAOEHLOX.js +0 -1326
  74. package/dist/chunk-YW23IBKF.js +0 -530
  75. package/dist/chunk-ZZDQKP4R.js +0 -418
  76. package/dist/use-gesture-react.esm-3SV4QLEJ.js +0 -1893
package/dist/index.d.ts CHANGED
@@ -1,18 +1,28 @@
1
1
  import { VideoItem, UIPlayerState, UIPlayerControls, UIInteractionState, UIInteractionActions } from '@xhub-short/contracts';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, ReactElement } from 'react';
4
- export { clsx } from 'clsx';
4
+ export { clsx, clsx as cn } from 'clsx';
5
5
  export { ErrorBoundary, ErrorBoundaryProps, ErrorMode } from './components/ErrorBoundary/index.js';
6
6
  export { Skeleton, SkeletonAnimation, SkeletonAvatar, SkeletonProps, SkeletonText, SkeletonVideo } from './components/Skeleton/index.js';
7
7
  export { BookmarkFilledIcon, BookmarkIcon, CloseIcon, CommentIcon, HeartFilledIcon, HeartIcon, IconProps, MoreIcon, MusicIcon, PauseIcon, PlayIcon, PlusIcon, ShareIcon, UserCheckIcon, UserPlusIcon, VerifiedIcon, VolumeIcon, VolumeMutedIcon } from './components/icons/index.js';
8
+ export { DEFAULT_BUFFER_SIZE, DEFAULT_EMPTY_TEXT, DEFAULT_END_REACHED_THRESHOLD, DEFAULT_END_TEXT, DEFAULT_LOADING_TEXT, SLIDER_CLASS, SLIDER_CONTAINER_CLASS, SLIDER_CONTAINER_SNAPPING_CLASS, SLIDER_CONTAINER_SWIPING_CLASS, SLOT_ACTIVE_ATTR as SLIDER_SLOT_ACTIVE_ATTR, SLIDER_SLOT_ACTIVE_CLASS, SLOT_ACTIVE_DATASET_KEY as SLIDER_SLOT_ACTIVE_DATASET_KEY, SLIDER_SLOT_ADJACENT_CLASS, SLIDER_SLOT_CLASS, SLOT_INDEX_ATTR as SLIDER_SLOT_INDEX_ATTR, SLOT_INDEX_DATASET_KEY as SLIDER_SLOT_INDEX_DATASET_KEY, SLIDER_SLOT_TRANSITIONING_CLASS, SlotPosition as SliderSlotPosition, UseSliderPositionOptions, UseSliderPositionReturn, VIRTUAL_SLIDER_CSS, VirtualSlider, VirtualSliderContext, VirtualSliderContextValue, VirtualSliderProps, getSlotIndexFromPosition as getSliderIndexFromPosition, useOptionalVirtualSliderContext, useSliderActiveIndex, useSliderIsSwiping, useSliderPosition, useVirtualSliderContext } from './components/VirtualSlider/index.js';
9
+ export { IMAGE_CAROUSEL_CSS, ImageCarouselHeadless, ImageCarouselProps } from './components/ImageCarousel/index.js';
10
+ export { IMAGE_POST_ACTIVE_ATTR, IMAGE_POST_ID_ATTR, IMAGE_POST_SLOT_ACTIVE_CLASS, IMAGE_POST_SLOT_CLASS, IMAGE_POST_SLOT_CLEAN_MODE_CLASS, IMAGE_POST_SLOT_CSS, ImagePostSlotActions, ImagePostSlotActionsProps, ImagePostSlotBottom, ImagePostSlotBottomProps, ImagePostSlotCaption, ImagePostSlotCaptionProps, ImagePostSlotContextValue, ImagePostSlotHeadless, ImagePostSlotHeadlessProps, ImagePostSlotMusic, ImagePostSlotMusicProps, ImagePostSlotOverlay, ImagePostSlotOverlayProps, ImagePostSlotPlayIndicator, ImagePostSlotPlayIndicatorProps, ImagePostSlotReadMore, ImagePostSlotReadMoreProps, useImagePostSlotContext, useOptionalImagePostSlotContext } from './components/ImagePostSlot/index.js';
11
+ export { DETAIL_VIEW_CSS, DetailViewAuthor, DetailViewAuthorProps, DetailViewCaption, DetailViewCaptionProps, DetailViewContextValue, DetailViewGallery, DetailViewGalleryProps, DetailViewHeadless, DetailViewHeadlessProps, DetailViewMusic, DetailViewMusicProps, DetailViewStats, DetailViewStatsProps, useDetailViewContext } from './components/DetailView/index.js';
8
12
  export { SLOT_ACTIVE_ATTR, SLOT_ACTIVE_DATASET_KEY, SLOT_INDEX_ATTR, SLOT_INDEX_DATASET_KEY, SlotPosition, UseVideoFeedPositionOptions, UseVideoFeedPositionReturn, VIDEO_FEED_CLASS_PREFIX, VIDEO_FEED_CSS, VideoFeedContext, VideoFeedContextValue, VideoFeedHeadless, VideoFeedHeadlessProps, getSlotIndexFromPosition, useOptionalVideoFeedContext, useVideoFeedContext, useVideoFeedPosition } from './components/VideoFeed/index.js';
9
- export { HeartInstance, LOADING_ATTR, LOADING_DATASET_KEY, LikeAnimationStyle, PLAYER_STATE_ATTR, PLAYER_STATE_DATASET_KEY, SLOT_CLASS, SLOT_ERROR_CLASS, SLOT_LOADING_CLASS, SLOT_PAUSED_CLASS, SLOT_PLAYING_CLASS, VIDEO_ID_ATTR, VIDEO_ID_DATASET_KEY, VIDEO_SLOT_CSS, VIDEO_SLOT_LIKE_ANIMATION_CSS, VideoSlotContext, VideoSlotContextValue, VideoSlotHeadless, VideoSlotHeadlessExtendedProps, VideoSlotLikeAnimation, VideoSlotLikeAnimationProps, VideoSlotLikeAnimationRef, VideoSlotOverlay, VideoSlotOverlayProps, VideoSlotOverlayRegionProps, VideoSlotPoster, VideoSlotPosterProps, VideoSlotSkeleton, Z_INDEX, Z_INDEX_CSS_VARS, useOptionalVideoSlotContext, useVideoSlotContext, useVideoSlotIsActive, useVideoSlotIsPlaying, useVideoSlotPlayer, useVideoSlotResource, useVideoSlotVideo } from './components/VideoSlot/index.js';
13
+ export { HeartInstance, LOADING_ATTR, LOADING_DATASET_KEY, LikeAnimationStyle, PLAYER_STATE_ATTR, PLAYER_STATE_DATASET_KEY, ReportedVideoOverlay, ReportedVideoOverlayProps, SLOT_CLASS, SLOT_ERROR_CLASS, SLOT_LOADING_CLASS, SLOT_PAUSED_CLASS, SLOT_PLAYING_CLASS, VIDEO_ID_ATTR, VIDEO_ID_DATASET_KEY, VIDEO_SLOT_CSS, VIDEO_SLOT_LIKE_ANIMATION_CSS, VideoSlotContext, VideoSlotContextValue, VideoSlotHeadless, VideoSlotHeadlessExtendedProps, VideoSlotLikeAnimation, VideoSlotLikeAnimationProps, VideoSlotLikeAnimationRef, VideoSlotOverlay, VideoSlotOverlayProps, VideoSlotOverlayRegionProps, VideoSlotPoster, VideoSlotPosterProps, VideoSlotSkeleton, Z_INDEX, Z_INDEX_CSS_VARS, useOptionalVideoSlotContext, useVideoSlotContext, useVideoSlotIsActive, useVideoSlotIsPlaying, useVideoSlotPlayer, useVideoSlotResource, useVideoSlotVideo } from './components/VideoSlot/index.js';
14
+ export { V as VideoSlotPlayIndicator, a as VideoSlotPlayIndicatorProps } from './VideoSlotPlayIndicator-DPs8Xt5C.js';
10
15
  export { BUFFERING_STATE_CLASS, ENDED_CLASS, ERROR_CLASS, ERROR_STATE_CLASS, LOADING_CLASS, LOADING_STATE_ATTR, LOADING_STATE_CLASS, PAUSED_CLASS, PLAYBACK_STATE_ATTR, PLAYER_CLASS, PLAYING_CLASS, POSTER_CLASS, READY_CLASS, UseAutoFirstFrameCaptureConfig, UseFirstFrameCaptureConfig, UseFirstFrameCaptureReturn, UseVideoElementConfig, UseVideoElementReturn, VIDEO_CLASS, VIDEO_PLAYER_CSS, Z_INDEX as VIDEO_PLAYER_Z_INDEX, Z_INDEX_CSS_VARS as VIDEO_PLAYER_Z_INDEX_CSS_VARS, VIDEO_TYPE_ATTR, VIDEO_WRAPPER_CLASS, VideoElementError, VideoErrorOrigin, VideoPlayerHeadless, VideoPlayerHeadlessExtendedProps, VideoSourceType, useAutoFirstFrameCapture, useFirstFrameCapture, useVideoElement } from './components/VideoPlayer/index.js';
11
16
  export { PROGRESS_BAR_CSS, ProgressBarHeadless, ProgressBarHeadlessExtendedProps, calculateProgress, formatTime } from './components/ProgressBar/index.js';
12
17
  export { ACTION_BAR_CSS, ActionBarBookmark, ActionBarComment, ActionBarHeadless, ActionBarHeadlessExtendedProps, ActionBarLike, ActionBarShare, ActionButton, ActionButtonExtendedProps, BookmarkButton, BookmarkButtonProps, CommentButton, CommentButtonProps, LikeButton, LikeButtonProps, ShareButton, ShareButtonProps } from './components/ActionBar/index.js';
13
18
  export { AUTHOR_INFO_CSS, AuthorAvatar, AuthorAvatarProps, AuthorDescription, AuthorDescriptionProps, AuthorInfoContext, AuthorInfoContextValue, AuthorInfoHeadless, AuthorInfoHeadlessExtendedProps, AuthorInfoVariant, AuthorName, AuthorNameProps, AvatarSize, FollowButton, FollowButtonProps, FollowButtonSize, useAuthorInfoContext, useOptionalAuthorInfoContext } from './components/AuthorInfo/index.js';
14
19
  export { VIDEO_INFO_CSS, VideoAuthorName, VideoAuthorNameProps, VideoCaption, VideoCaptionProps, VideoHashtags, VideoHashtagsProps, VideoInfoContext, VideoInfoContextValue, VideoInfoHeadless, VideoInfoHeadlessExtendedProps, VideoLocation, VideoLocationProps, VideoMusic, VideoMusicProps, useOptionalVideoInfoContext, useVideoInfoContext } from './components/VideoInfo/index.js';
15
- import * as _use_gesture_react from '@use-gesture/react';
20
+ export { n as COMMENT_SHEET_CSS, f as CommentInput, g as CommentInputProps, h as CommentItemComponent, i as CommentItemProps, d as CommentList, e as CommentListProps, C as CommentSheet, j as CommentSheetContext, l as CommentSheetContextValue, a as CommentSheetHeadless, b as CommentSheetHeadlessProps, m as CommentSheetI18n, R as ReplyTarget, S as SheetHeader, c as SheetHeaderProps, u as useCommentSheetContext, k as useOptionalCommentSheetContext } from './CommentSheet.css-DyEc3Sro.js';
21
+ export { ADVANCE_MENU_CSS, AdvanceMenuHeadless, AdvanceMenuHeadlessProps, AdvanceMenuItemProps, AdvanceMenuSectionTitleProps, AdvanceMenuSeparatorProps } from './components/AdvanceMenu/index.js';
22
+ export { DEFAULT_SPEEDS, SPEED_PICKER_CSS, SpeedPickerHeadless, SpeedPickerHeadlessProps } from './components/SpeedPicker/index.js';
23
+ export { QUALITY_PICKER_CSS, QualityPickerHeadless, QualityPickerHeadlessProps } from './components/QualityPicker/index.js';
24
+ export { CLEAN_MODE_OVERLAY_CSS, CleanModeOverlayHeadless, CleanModeOverlayHeadlessProps, injectCleanModeOverlayCSS } from './components/CleanModeOverlay/index.js';
25
+ export { REPORT_SHEET_CSS, ReportSheetHeadless, ReportSheetHeadlessProps, ReportSheetState, injectReportSheetCSS } from './components/ReportSheet/index.js';
16
26
  import 'react/jsx-runtime';
17
27
 
18
28
  /**
@@ -85,8 +95,26 @@ declare function areStylesInjected(): boolean;
85
95
  * - Works with any bundler (Next.js, Vite, Webpack)
86
96
  *
87
97
  * Design Tokens from: User-provided tokens (Urbanist font, light/dark mode)
98
+ *
99
+ * ## CSS Layers
100
+ *
101
+ * SDK styles use `@layer sv` for low specificity. This allows host apps to
102
+ * override styles easily WITHOUT using `!important`.
103
+ *
104
+ * Host app can override by:
105
+ * 1. Using any CSS without @layer (higher priority)
106
+ * 2. Overriding CSS Variables (recommended for theming)
107
+ * 3. Using `@layer host { }` declared AFTER `sv` layer
108
+ *
109
+ * @example
110
+ * ```css
111
+ * // Host app styles - no !important needed
112
+ * .my-custom-action-bar {
113
+ * gap: 20px; // Overrides SDK's gap easily
114
+ * }
115
+ * ```
88
116
  */
89
- declare const CSS_CONTENT = "\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n XHub-short UI Styles - Auto-injected\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FONT LOADING\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@import url('https://fonts.googleapis.com/css2?family=Urbanist:wght@400;500;600;700&display=swap');\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CSS VARIABLES - Light Mode (Default)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n:root {\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n COLOR TOKENS - Light Mode\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-color-primary: #164c8e;\n --sv-color-primary-alpha: #164c8e5b;\n --sv-color-secondary: #9fc5e9;\n --sv-color-tertiary: #e9f8ff;\n --sv-color-quaternary: #164c8e5b;\n\n --sv-color-contrast-positive: #121212;\n --sv-color-contrast-negative: #ffffff;\n\n --sv-color-accent: #a2a2a2;\n --sv-color-accent-2: #6b7271;\n --sv-color-accent-stroke: #e5e6e6;\n\n --sv-color-error: #ff434e;\n --sv-color-success: #1da031;\n --sv-color-warning: #daa000;\n --sv-color-info: #29c8f0;\n\n /* Semantic aliases */\n --sv-color-background: var(--sv-color-contrast-negative);\n --sv-color-text: var(--sv-color-contrast-positive);\n --sv-color-text-secondary: var(--sv-color-accent-2);\n --sv-color-text-muted: var(--sv-color-accent);\n --sv-color-border: var(--sv-color-accent-stroke);\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n TYPOGRAPHY TOKENS - Mobile (Default)\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-font-family: 'Urbanist', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n --sv-font-family-display: 'SF Pro Display', 'Urbanist', system-ui, sans-serif;\n\n --sv-font-size-xxs: 10px;\n --sv-font-size-xs: 12px;\n --sv-font-size-sm: 13px;\n --sv-font-size-md: 14px;\n --sv-font-size-lg: 16px;\n --sv-font-size-xl: 20px;\n\n --sv-font-weight-regular: 400;\n --sv-font-weight-medium: 500;\n --sv-font-weight-semibold: 600;\n --sv-font-weight-bold: 700;\n\n --sv-line-height-tight: 1.2;\n --sv-line-height-normal: 1.4;\n --sv-line-height-relaxed: 1.6;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n SPACING TOKENS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-spacing-xxs: 2px;\n --sv-spacing-xs: 4px;\n --sv-spacing-sm: 8px;\n --sv-spacing-md: 12px;\n --sv-spacing-lg: 16px;\n --sv-spacing-xl: 24px;\n --sv-spacing-xxl: 32px;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n BORDER RADIUS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-radius-sm: 4px;\n --sv-radius-md: 8px;\n --sv-radius-lg: 12px;\n --sv-radius-xl: 16px;\n --sv-radius-full: 9999px;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n TRANSITIONS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-transition-fast: 150ms ease;\n --sv-transition-normal: 250ms ease;\n --sv-transition-slow: 350ms ease;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Z-INDEX LAYERS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-z-base: 1;\n --sv-z-video: 1;\n --sv-z-overlay: 10;\n --sv-z-controls: 20;\n --sv-z-modal: 100;\n --sv-z-toast: 1000;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n SHADOWS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --sv-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);\n --sv-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.15);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CSS VARIABLES - Dark Mode\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* System preference */\n@media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n --sv-color-primary: #a6cec7;\n --sv-color-primary-alpha: #164c8e5b;\n --sv-color-secondary: #143a0c;\n --sv-color-tertiary: #252825;\n --sv-color-quaternary: #164c8e5b;\n\n --sv-color-contrast-positive: #ffffff;\n --sv-color-contrast-negative: #121212;\n\n --sv-color-accent: #6b7271;\n --sv-color-accent-2: #d2dddb;\n --sv-color-accent-stroke: #373737;\n\n --sv-color-error: #b62a32;\n --sv-color-success: #20a634;\n --sv-color-warning: #c29823;\n --sv-color-info: #1fa0c0;\n\n /* Semantic aliases update automatically */\n --sv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);\n --sv-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);\n --sv-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);\n }\n}\n\n/* Explicit dark mode (override) */\n[data-theme=\"dark\"],\n.dark {\n --sv-color-primary: #a6cec7;\n --sv-color-primary-alpha: #164c8e5b;\n --sv-color-secondary: #143a0c;\n --sv-color-tertiary: #252825;\n --sv-color-quaternary: #164c8e5b;\n\n --sv-color-contrast-positive: #ffffff;\n --sv-color-contrast-negative: #121212;\n\n --sv-color-accent: #6b7271;\n --sv-color-accent-2: #d2dddb;\n --sv-color-accent-stroke: #373737;\n\n --sv-color-error: #b62a32;\n --sv-color-success: #20a634;\n --sv-color-warning: #c29823;\n --sv-color-info: #1fa0c0;\n\n --sv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);\n --sv-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);\n --sv-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n TABLET BREAKPOINT - Typography scaling\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@media (min-width: 768px) {\n :root {\n --sv-font-size-xxs: 11px;\n --sv-font-size-xs: 13px;\n --sv-font-size-sm: 14px;\n --sv-font-size-md: 16px;\n --sv-font-size-lg: 18px;\n --sv-font-size-xl: 24px;\n }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n BASE STYLES\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-root {\n font-family: var(--sv-font-family);\n font-size: var(--sv-font-size-md);\n font-weight: var(--sv-font-weight-regular);\n line-height: var(--sv-line-height-normal);\n color: var(--sv-color-text);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FEED CONTAINER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-feed {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n background: var(--sv-color-contrast-negative);\n touch-action: pan-y;\n -webkit-overflow-scrolling: touch;\n}\n\n.sv-feed::-webkit-scrollbar {\n display: none;\n}\n\n.sv-feed {\n -ms-overflow-style: none;\n scrollbar-width: none;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n VIDEO SLOT\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-slot {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--sv-color-contrast-negative);\n will-change: transform;\n}\n\n.sv-slot--active {\n z-index: var(--sv-z-video);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n VIDEO PLAYER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-player {\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--sv-color-contrast-negative);\n}\n\n.sv-player__video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n background: var(--sv-color-contrast-negative);\n}\n\n.sv-player__poster {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n z-index: 1;\n transition: opacity var(--sv-transition-normal);\n}\n\n.sv-player__poster--hidden {\n opacity: 0;\n pointer-events: none;\n}\n\n.sv-player__overlay {\n position: absolute;\n inset: 0;\n background: linear-gradient(\n to bottom,\n transparent 0%,\n transparent 50%,\n rgba(0, 0, 0, 0.3) 100%\n );\n pointer-events: none;\n z-index: var(--sv-z-overlay);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PROGRESS BAR\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-progress {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: rgba(255, 255, 255, 0.2);\n z-index: var(--sv-z-controls);\n}\n\n.sv-progress__bar {\n height: 100%;\n background: var(--sv-color-contrast-positive);\n transition: width 100ms linear;\n will-change: width;\n}\n\n.sv-progress__bar--buffered {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.3);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n INTERACTION BAR (Right side actions)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-actions {\n position: absolute;\n right: var(--sv-spacing-md);\n bottom: 120px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--sv-spacing-xl);\n z-index: var(--sv-z-controls);\n}\n\n.sv-action-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--sv-spacing-xs);\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--sv-color-contrast-positive);\n transition: transform var(--sv-transition-fast);\n -webkit-tap-highlight-color: transparent;\n}\n\n.sv-action-btn:active {\n transform: scale(0.9);\n}\n\n.sv-action-btn__icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.3);\n border-radius: var(--sv-radius-full);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n}\n\n.sv-action-btn__icon svg {\n width: 24px;\n height: 24px;\n fill: currentColor;\n}\n\n.sv-action-btn__count {\n font-size: var(--sv-font-size-xs);\n font-weight: var(--sv-font-weight-semibold);\n color: var(--sv-color-contrast-positive);\n}\n\n/* Like button states */\n.sv-action-btn--liked .sv-action-btn__icon {\n color: var(--sv-color-error);\n}\n\n.sv-action-btn--liked .sv-action-btn__icon svg {\n animation: sv-like-pop 0.3s ease;\n}\n\n@keyframes sv-like-pop {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.3); }\n 100% { transform: scale(1); }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n AUTHOR INFO (Bottom left)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-author {\n position: absolute;\n left: var(--sv-spacing-md);\n bottom: 80px;\n display: flex;\n flex-direction: column;\n gap: var(--sv-spacing-md);\n max-width: calc(100% - 80px);\n z-index: var(--sv-z-controls);\n}\n\n.sv-author__row {\n display: flex;\n align-items: center;\n gap: var(--sv-spacing-md);\n}\n\n.sv-author__avatar {\n width: 48px;\n height: 48px;\n border-radius: var(--sv-radius-full);\n border: 2px solid var(--sv-color-contrast-positive);\n object-fit: cover;\n flex-shrink: 0;\n}\n\n.sv-author__info {\n display: flex;\n flex-direction: column;\n gap: var(--sv-spacing-xxs);\n min-width: 0;\n}\n\n.sv-author__name {\n font-size: var(--sv-font-size-lg);\n font-weight: var(--sv-font-weight-semibold);\n color: var(--sv-color-contrast-positive);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sv-author__handle {\n font-size: var(--sv-font-size-sm);\n color: rgba(255, 255, 255, 0.8);\n}\n\n.sv-author__description {\n font-size: var(--sv-font-size-sm);\n color: var(--sv-color-contrast-positive);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: var(--sv-line-height-relaxed);\n}\n\n/* Follow button */\n.sv-follow-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--sv-spacing-xs) var(--sv-spacing-md);\n font-size: var(--sv-font-size-sm);\n font-weight: var(--sv-font-weight-semibold);\n font-family: var(--sv-font-family);\n color: var(--sv-color-contrast-negative);\n background: var(--sv-color-primary);\n border: none;\n border-radius: var(--sv-radius-sm);\n cursor: pointer;\n transition: all var(--sv-transition-fast);\n -webkit-tap-highlight-color: transparent;\n}\n\n.sv-follow-btn:active {\n transform: scale(0.95);\n}\n\n.sv-follow-btn--following {\n background: transparent;\n color: var(--sv-color-contrast-positive);\n border: 1px solid var(--sv-color-contrast-positive);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n SPINNER / LOADING\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-spinner {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.sv-spinner__circle {\n width: 32px;\n height: 32px;\n border: 3px solid rgba(255, 255, 255, 0.2);\n border-top-color: var(--sv-color-contrast-positive);\n border-radius: var(--sv-radius-full);\n animation: sv-spin 0.8s linear infinite;\n}\n\n.sv-spinner--sm .sv-spinner__circle {\n width: 20px;\n height: 20px;\n border-width: 2px;\n}\n\n.sv-spinner--lg .sv-spinner__circle {\n width: 48px;\n height: 48px;\n border-width: 4px;\n}\n\n@keyframes sv-spin {\n to { transform: rotate(360deg); }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n MUSIC INFO (Bottom - optional)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-music {\n position: absolute;\n left: var(--sv-spacing-md);\n bottom: var(--sv-spacing-lg);\n display: flex;\n align-items: center;\n gap: var(--sv-spacing-sm);\n max-width: calc(100% - 80px);\n z-index: var(--sv-z-controls);\n}\n\n.sv-music__icon {\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n}\n\n.sv-music__text {\n font-size: var(--sv-font-size-sm);\n color: var(--sv-color-contrast-positive);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sv-music__marquee {\n animation: sv-marquee 10s linear infinite;\n}\n\n@keyframes sv-marquee {\n 0% { transform: translateX(0); }\n 100% { transform: translateX(-50%); }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n UTILITIES\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sv-tap-highlight-none {\n -webkit-tap-highlight-color: transparent;\n}\n\n/* Prevent text selection during gestures */\n.sv-no-select {\n -webkit-user-select: none;\n user-select: none;\n}\n\n/* Hardware acceleration hint */\n.sv-gpu {\n transform: translateZ(0);\n will-change: transform;\n}\n";
117
+ declare const CSS_CONTENT = "\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n XHub-short UI Styles - Auto-injected\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CSS LAYER DECLARATION\n \n Declare the 'sv' layer first. All SDK component styles go into this layer.\n Host app styles WITHOUT @layer automatically have HIGHER priority.\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@layer sv;\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FONT LOADING (outside layer - needs to be global)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@import url('https://fonts.googleapis.com/css2?family=Urbanist:wght@400;500;600;700&display=swap');\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CSS VARIABLES - Light Mode (Default)\n Outside layer so host app can easily override variables\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n:root {\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n COLOR TOKENS - Light Mode\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-color-primary: #164c8e;\n --sv-color-primary-alpha: #164c8e5b;\n --sv-color-secondary: #9fc5e9;\n --sv-color-tertiary: #e9f8ff;\n --sv-color-quaternary: #164c8e5b;\n\n --sv-color-contrast-positive: #121212;\n --sv-color-contrast-negative: #ffffff;\n\n --sv-color-accent: #a2a2a2;\n --sv-color-accent-2: #6b7271;\n --sv-color-accent-stroke: #e5e6e6;\n\n --sv-color-error: #ff434e;\n --sv-color-success: #1da031;\n --sv-color-warning: #daa000;\n --sv-color-info: #29c8f0;\n\n /* Semantic aliases */\n --sv-color-background: var(--sv-color-contrast-negative);\n --sv-color-text: var(--sv-color-contrast-positive);\n --sv-color-text-secondary: var(--sv-color-accent-2);\n --sv-color-text-muted: var(--sv-color-accent);\n --sv-color-border: var(--sv-color-accent-stroke);\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n TYPOGRAPHY TOKENS - Mobile (Default)\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-font-family: 'Urbanist', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;\n --sv-font-family-display: 'SF Pro Display', 'Urbanist', system-ui, sans-serif;\n\n --sv-font-size-xxs: 10px;\n --sv-font-size-xs: 12px;\n --sv-font-size-sm: 13px;\n --sv-font-size-md: 14px;\n --sv-font-size-lg: 16px;\n --sv-font-size-xl: 20px;\n\n --sv-font-weight-regular: 400;\n --sv-font-weight-medium: 500;\n --sv-font-weight-semibold: 600;\n --sv-font-weight-bold: 700;\n\n --sv-line-height-tight: 1.2;\n --sv-line-height-normal: 1.4;\n --sv-line-height-relaxed: 1.6;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n SPACING TOKENS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-spacing-xxs: 2px;\n --sv-spacing-xs: 4px;\n --sv-spacing-sm: 8px;\n --sv-spacing-md: 12px;\n --sv-spacing-lg: 16px;\n --sv-spacing-xl: 24px;\n --sv-spacing-xxl: 32px;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n BORDER RADIUS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-radius-sm: 4px;\n --sv-radius-md: 8px;\n --sv-radius-lg: 12px;\n --sv-radius-xl: 16px;\n --sv-radius-full: 9999px;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n TRANSITIONS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-transition-fast: 150ms ease;\n --sv-transition-normal: 250ms ease;\n --sv-transition-slow: 350ms ease;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Z-INDEX LAYERS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-z-base: 1;\n --sv-z-video: 1;\n --sv-z-overlay: 10;\n --sv-z-controls: 20;\n --sv-z-modal: 100;\n --sv-z-toast: 1000;\n\n /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n SHADOWS\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n --sv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --sv-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);\n --sv-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.15);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CSS VARIABLES - Dark Mode\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n/* System preference */\n@media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n --sv-color-primary: #a6cec7;\n --sv-color-primary-alpha: #164c8e5b;\n --sv-color-secondary: #143a0c;\n --sv-color-tertiary: #252825;\n --sv-color-quaternary: #164c8e5b;\n\n --sv-color-contrast-positive: #ffffff;\n --sv-color-contrast-negative: #121212;\n\n --sv-color-accent: #6b7271;\n --sv-color-accent-2: #d2dddb;\n --sv-color-accent-stroke: #373737;\n\n --sv-color-error: #b62a32;\n --sv-color-success: #20a634;\n --sv-color-warning: #c29823;\n --sv-color-info: #1fa0c0;\n\n /* Semantic aliases update automatically */\n --sv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);\n --sv-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);\n --sv-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);\n }\n}\n\n/* Explicit dark mode (override) */\n[data-theme=\"dark\"],\n.dark {\n --sv-color-primary: #a6cec7;\n --sv-color-primary-alpha: #164c8e5b;\n --sv-color-secondary: #143a0c;\n --sv-color-tertiary: #252825;\n --sv-color-quaternary: #164c8e5b;\n\n --sv-color-contrast-positive: #ffffff;\n --sv-color-contrast-negative: #121212;\n\n --sv-color-accent: #6b7271;\n --sv-color-accent-2: #d2dddb;\n --sv-color-accent-stroke: #373737;\n\n --sv-color-error: #b62a32;\n --sv-color-success: #20a634;\n --sv-color-warning: #c29823;\n --sv-color-info: #1fa0c0;\n\n --sv-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);\n --sv-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);\n --sv-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n TABLET BREAKPOINT - Typography scaling\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@media (min-width: 768px) {\n :root {\n --sv-font-size-xxs: 11px;\n --sv-font-size-xs: 13px;\n --sv-font-size-sm: 14px;\n --sv-font-size-md: 16px;\n --sv-font-size-lg: 18px;\n --sv-font-size-xl: 24px;\n }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n BASE STYLES - Inside @layer sv for easy host app overrides\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n@layer sv {\n\n.sv-root {\n font-family: var(--sv-font-family);\n font-size: var(--sv-font-size-md);\n font-weight: var(--sv-font-weight-regular);\n line-height: var(--sv-line-height-normal);\n color: var(--sv-color-text);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n FEED CONTAINER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-feed {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n background: var(--sv-color-contrast-negative);\n touch-action: pan-y;\n -webkit-overflow-scrolling: touch;\n}\n\n.sv-feed::-webkit-scrollbar {\n display: none;\n}\n\n.sv-feed {\n -ms-overflow-style: none;\n scrollbar-width: none;\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n VIDEO SLOT\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-slot {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--sv-color-contrast-negative);\n will-change: transform;\n}\n\n.sv-slot--active {\n z-index: var(--sv-z-video);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n VIDEO PLAYER\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-player {\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--sv-color-contrast-negative);\n}\n\n.sv-player__video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n background: var(--sv-color-contrast-negative);\n}\n\n.sv-player__poster {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n object-fit: cover;\n z-index: 1;\n transition: opacity var(--sv-transition-normal);\n}\n\n.sv-player__poster--hidden {\n opacity: 0;\n pointer-events: none;\n}\n\n.sv-player__overlay {\n position: absolute;\n inset: 0;\n background: linear-gradient(\n to bottom,\n transparent 0%,\n transparent 50%,\n rgba(0, 0, 0, 0.3) 100%\n );\n pointer-events: none;\n z-index: var(--sv-z-overlay);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n PROGRESS BAR\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-progress {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: rgba(255, 255, 255, 0.2);\n z-index: var(--sv-z-controls);\n}\n\n.sv-progress__bar {\n height: 100%;\n background: var(--sv-color-contrast-positive);\n transition: width 100ms linear;\n will-change: width;\n}\n\n.sv-progress__bar--buffered {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.3);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n INTERACTION BAR (Right side actions)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-actions {\n position: absolute;\n right: var(--sv-spacing-md);\n bottom: 120px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--sv-spacing-xl);\n z-index: var(--sv-z-controls);\n}\n\n.sv-action-btn {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--sv-spacing-xs);\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--sv-color-contrast-positive);\n transition: transform var(--sv-transition-fast);\n -webkit-tap-highlight-color: transparent;\n}\n\n.sv-action-btn:active {\n transform: scale(0.9);\n}\n\n.sv-action-btn__icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.3);\n border-radius: var(--sv-radius-full);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n}\n\n.sv-action-btn__icon svg {\n width: 24px;\n height: 24px;\n fill: currentColor;\n}\n\n.sv-action-btn__count {\n font-size: var(--sv-font-size-xs);\n font-weight: var(--sv-font-weight-semibold);\n color: var(--sv-color-contrast-positive);\n}\n\n/* Like button states */\n.sv-action-btn--liked .sv-action-btn__icon {\n color: var(--sv-color-error);\n}\n\n.sv-action-btn--liked .sv-action-btn__icon svg {\n animation: sv-like-pop 0.3s ease;\n}\n\n@keyframes sv-like-pop {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.3); }\n 100% { transform: scale(1); }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n AUTHOR INFO (Bottom left)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-author {\n position: absolute;\n left: var(--sv-spacing-md);\n bottom: 80px;\n display: flex;\n flex-direction: column;\n gap: var(--sv-spacing-md);\n max-width: calc(100% - 80px);\n z-index: var(--sv-z-controls);\n}\n\n.sv-author__row {\n display: flex;\n align-items: center;\n gap: var(--sv-spacing-md);\n}\n\n.sv-author__avatar {\n width: 48px;\n height: 48px;\n border-radius: var(--sv-radius-full);\n border: 2px solid var(--sv-color-contrast-positive);\n object-fit: cover;\n flex-shrink: 0;\n}\n\n.sv-author__info {\n display: flex;\n flex-direction: column;\n gap: var(--sv-spacing-xxs);\n min-width: 0;\n}\n\n.sv-author__name {\n font-size: var(--sv-font-size-lg);\n font-weight: var(--sv-font-weight-semibold);\n color: var(--sv-color-contrast-positive);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sv-author__handle {\n font-size: var(--sv-font-size-sm);\n color: rgba(255, 255, 255, 0.8);\n}\n\n.sv-author__description {\n font-size: var(--sv-font-size-sm);\n color: var(--sv-color-contrast-positive);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: var(--sv-line-height-relaxed);\n}\n\n/* Follow button */\n.sv-follow-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--sv-spacing-xs) var(--sv-spacing-md);\n font-size: var(--sv-font-size-sm);\n font-weight: var(--sv-font-weight-semibold);\n font-family: var(--sv-font-family);\n color: var(--sv-color-contrast-negative);\n background: var(--sv-color-primary);\n border: none;\n border-radius: var(--sv-radius-sm);\n cursor: pointer;\n transition: all var(--sv-transition-fast);\n -webkit-tap-highlight-color: transparent;\n}\n\n.sv-follow-btn:active {\n transform: scale(0.95);\n}\n\n.sv-follow-btn--following {\n background: transparent;\n color: var(--sv-color-contrast-positive);\n border: 1px solid var(--sv-color-contrast-positive);\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n SPINNER / LOADING\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-spinner {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.sv-spinner__circle {\n width: 32px;\n height: 32px;\n border: 3px solid rgba(255, 255, 255, 0.2);\n border-top-color: var(--sv-color-contrast-positive);\n border-radius: var(--sv-radius-full);\n animation: sv-spin 0.8s linear infinite;\n}\n\n.sv-spinner--sm .sv-spinner__circle {\n width: 20px;\n height: 20px;\n border-width: 2px;\n}\n\n.sv-spinner--lg .sv-spinner__circle {\n width: 48px;\n height: 48px;\n border-width: 4px;\n}\n\n@keyframes sv-spin {\n to { transform: rotate(360deg); }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n MUSIC INFO (Bottom - optional)\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-music {\n position: absolute;\n left: var(--sv-spacing-md);\n bottom: var(--sv-spacing-lg);\n display: flex;\n align-items: center;\n gap: var(--sv-spacing-sm);\n max-width: calc(100% - 80px);\n z-index: var(--sv-z-controls);\n}\n\n.sv-music__icon {\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n}\n\n.sv-music__text {\n font-size: var(--sv-font-size-sm);\n color: var(--sv-color-contrast-positive);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sv-music__marquee {\n animation: sv-marquee 10s linear infinite;\n}\n\n@keyframes sv-marquee {\n 0% { transform: translateX(0); }\n 100% { transform: translateX(-50%); }\n}\n\n/* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n UTILITIES\n \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.sv-tap-highlight-none {\n -webkit-tap-highlight-color: transparent;\n}\n\n/* Prevent text selection during gestures */\n.sv-no-select {\n -webkit-user-select: none;\n user-select: none;\n}\n\n/* Hardware acceleration hint */\n.sv-gpu {\n transform: translateZ(0);\n will-change: transform;\n}\n\n} /* End @layer sv */\n";
90
118
 
91
119
  /**
92
120
  * Styles Module
@@ -147,6 +175,7 @@ declare const Components: {
147
175
  VideoFeedHeadless: () => null;
148
176
  VideoSlotHeadless: () => null;
149
177
  VideoPlayerHeadless: () => null;
178
+ CommentSheetHeadless: () => null;
150
179
  ErrorBoundary: () => null;
151
180
  Skeleton: () => null;
152
181
  };
@@ -354,8 +383,12 @@ interface UseDoubleTapConfig {
354
383
  onSingleTap?: () => void;
355
384
  /** Callback for double tap with position */
356
385
  onDoubleTap?: (position: TapPosition) => void;
386
+ /** Callback for long press (hold > longPressDelay without moving) */
387
+ onLongPress?: (position: TapPosition) => void;
357
388
  /** Delay in ms to detect double tap (default: 300) */
358
389
  doubleTapDelay?: number;
390
+ /** Delay in ms to detect long press (default: 500) */
391
+ longPressDelay?: number;
359
392
  /** Whether the hook is disabled */
360
393
  disabled?: boolean;
361
394
  /**
@@ -369,6 +402,7 @@ interface UseDoubleTapReturn {
369
402
  /** Event handlers to spread onto the target element */
370
403
  handlers: {
371
404
  onPointerDown: (e: React.PointerEvent) => void;
405
+ onPointerMove: (e: React.PointerEvent) => void;
372
406
  onPointerUp: (e: React.PointerEvent) => void;
373
407
  onClick: (e: React.MouseEvent) => void;
374
408
  };
@@ -395,7 +429,7 @@ interface UseDoubleTapReturn {
395
429
  * Returns tap position as percentage (0-100) relative to container.
396
430
  * Falls back to center (50, 50) if container ref is null.
397
431
  */
398
- declare function useDoubleTap({ containerRef, onSingleTap, onDoubleTap, doubleTapDelay, disabled, movementThreshold, }: UseDoubleTapConfig): UseDoubleTapReturn;
432
+ declare function useDoubleTap({ containerRef, onSingleTap, onDoubleTap, onLongPress, doubleTapDelay, longPressDelay, disabled, movementThreshold, }: UseDoubleTapConfig): UseDoubleTapReturn;
399
433
 
400
434
  /**
401
435
  * CustomLayout - Fully Composable Layout
@@ -563,6 +597,12 @@ interface DefaultLayoutProps {
563
597
  error?: Error | null;
564
598
  /** Retry callback */
565
599
  onRetry?: () => void;
600
+ /** Network error text (default: "No internet connection") */
601
+ networkErrorText?: string;
602
+ /** Generic error text (default: "Video failed to load") */
603
+ genericErrorText?: string;
604
+ /** Retry button text (default: "Tap to retry") */
605
+ retryText?: string;
566
606
  /** Additional class name */
567
607
  className?: string;
568
608
  /** Test ID */
@@ -633,6 +673,14 @@ interface MinimalLayoutProps {
633
673
  error?: Error | null;
634
674
  /** Retry callback */
635
675
  onRetry?: () => void;
676
+ /** Error fallback text (default: "Video failed to load") */
677
+ errorFallbackText?: string;
678
+ /** Retry button text (default: "Retry") */
679
+ retryText?: string;
680
+ /** Play button aria-label (default: "Play") */
681
+ playAriaLabel?: string;
682
+ /** Pause button aria-label (default: "Pause") */
683
+ pauseAriaLabel?: string;
636
684
  /** Called when play button is clicked */
637
685
  onPlayClick?: () => void;
638
686
  /** Additional class name */
@@ -640,7 +688,7 @@ interface MinimalLayoutProps {
640
688
  /** Test ID */
641
689
  testId?: string;
642
690
  }
643
- declare function MinimalLayout({ video: _video, index: _index, playerState, playerControls, renderPlayer, renderPoster, renderProgressBar, renderError, playIcon, pauseIcon, showPoster, showPlayButton, showProgressBar, autoHidePlayButton, hideDelay, error, onRetry, onPlayClick, className, testId, }: MinimalLayoutProps): ReactElement;
691
+ declare function MinimalLayout({ video: _video, index: _index, playerState, playerControls, renderPlayer, renderPoster, renderProgressBar, renderError, playIcon, pauseIcon, showPoster, showPlayButton, showProgressBar, autoHidePlayButton, hideDelay, error, onRetry, onPlayClick, className, testId, errorFallbackText, retryText, playAriaLabel, pauseAriaLabel, }: MinimalLayoutProps): ReactElement;
644
692
  declare namespace MinimalLayout {
645
693
  var displayName: string;
646
694
  }
@@ -674,9 +722,36 @@ declare const Layouts: {
674
722
  *
675
723
  * Features:
676
724
  * - Deduplication: Each component's CSS is injected only once
725
+ * - Persistent by default: CSS stays in DOM after injection (no cleanup overhead)
677
726
  * - SSR-safe: Checks for document existence
678
- * - Cleanup-ready: Returns remove function
679
727
  * - Hydration-aware: Checks for existing styles from SSR
728
+ * - **CSS Layers**: All component CSS is wrapped in `@layer sv` for easy host overrides
729
+ *
730
+ * ## CSS Layers for Host App Overrides
731
+ *
732
+ * All SDK component styles are injected inside `@layer sv`. This means:
733
+ * - Host app CSS without @layer has HIGHER priority
734
+ * - No need for `!important` to override SDK styles
735
+ *
736
+ * @example
737
+ * ```css
738
+ * // Host app can easily override without !important
739
+ * .my-custom-button {
740
+ * background: blue; // Overrides SDK styles easily
741
+ * }
742
+ * ```
743
+ *
744
+ * ## Why No Auto-Cleanup?
745
+ *
746
+ * In a video feed app, components like VideoPlayer, ActionBar, etc. are
747
+ * continuously mounted/unmounted as user scrolls. Removing and re-injecting
748
+ * CSS would be wasteful since:
749
+ * 1. These components will be needed again immediately
750
+ * 2. CSS injection triggers style recalculation (performance cost)
751
+ * 3. The CSS payload is small (~5-10KB total for all components)
752
+ *
753
+ * CSS is only removed via explicit `removeComponentCSS()` or `removeAllComponentCSS()`
754
+ * calls, typically only needed for testing cleanup.
680
755
  *
681
756
  * @example
682
757
  * ```tsx
@@ -694,17 +769,38 @@ declare const Layouts: {
694
769
  * }
695
770
  * ```
696
771
  */
772
+ /**
773
+ * Options for CSS injection
774
+ */
775
+ interface InjectCSSOptions {
776
+ /**
777
+ * Whether to wrap CSS in @layer sv.
778
+ *
779
+ * - `true` (default): CSS wrapped in @layer sv, host app can override easily
780
+ * - `false`: CSS injected without layer, useful for critical components
781
+ * that need to resist global resets like `* { margin: 0; padding: 0; }`
782
+ *
783
+ * @default true
784
+ */
785
+ layered?: boolean;
786
+ }
697
787
  /**
698
788
  * Inject CSS for a specific component.
699
789
  *
790
+ * CSS is injected once and persists in the DOM. This is optimal for
791
+ * video feed apps where components are frequently mounted/unmounted.
792
+ *
700
793
  * @param componentId - Unique identifier for the component (e.g., 'video-player')
701
794
  * @param css - CSS string to inject
702
- * @returns Cleanup function to remove the injected styles
795
+ * @param options - Injection options
796
+ * @returns Empty cleanup function (CSS persists intentionally)
703
797
  */
704
- declare function injectComponentCSS(componentId: string, css: string): () => void;
798
+ declare function injectComponentCSS(componentId: string, css: string, options?: InjectCSSOptions): () => void;
705
799
  /**
706
800
  * Remove CSS for a specific component.
707
- * Useful for cleanup in tests or component unmount.
801
+ * Mainly used for testing cleanup.
802
+ *
803
+ * Note: In normal app usage, CSS persists and this is rarely needed.
708
804
  *
709
805
  * @param componentId - Component identifier to remove
710
806
  */
@@ -717,70 +813,6 @@ declare function removeComponentCSS(componentId: string): void;
717
813
  */
718
814
  declare function isComponentCSSInjected(componentId: string): boolean;
719
815
 
720
- /**
721
- * Lazy Loading Wrapper for @use-gesture/react
722
- *
723
- * This module provides lazy loading for the gesture library (~8KB gzip).
724
- * Only VideoFeed component needs gestures, so we don't want to bundle it
725
- * for components that don't use it.
726
- *
727
- * @example
728
- * ```tsx
729
- * // In VideoFeed component
730
- * import { useEffect, useState } from 'react';
731
- * import { loadGesture, type GestureModule } from '../../utils/lazyGesture';
732
- *
733
- * export function VideoFeed() {
734
- * const [gesture, setGesture] = useState<GestureModule | null>(null);
735
- *
736
- * useEffect(() => {
737
- * loadGesture().then(setGesture);
738
- * }, []);
739
- *
740
- * if (!gesture) {
741
- * return <div>Loading...</div>;
742
- * }
743
- *
744
- * const { useDrag } = gesture;
745
- * // ... use gesture hooks
746
- * }
747
- * ```
748
- */
749
- /** Type for the gesture module */
750
- type GestureModule = typeof _use_gesture_react;
751
- /**
752
- * Lazy load @use-gesture/react library.
753
- *
754
- * Benefits:
755
- * - Only loaded when actually needed
756
- * - Cached after first load
757
- * - Single pending promise prevents duplicate loads
758
- *
759
- * @returns Promise resolving to the gesture module
760
- */
761
- declare function loadGesture(): Promise<GestureModule>;
762
- /**
763
- * Check if gesture library is loaded.
764
- * Useful for conditional rendering.
765
- *
766
- * @returns true if module is loaded and cached
767
- */
768
- declare function isGestureLoaded(): boolean;
769
- /**
770
- * Preload gesture library without awaiting.
771
- * Call this early if you know gestures will be needed soon.
772
- *
773
- * @example
774
- * ```tsx
775
- * // In app initialization
776
- * import { preloadGesture } from '@xhub-short/ui/utils/lazyGesture';
777
- *
778
- * // Start loading early
779
- * preloadGesture();
780
- * ```
781
- */
782
- declare function preloadGesture(): void;
783
-
784
816
  /**
785
817
  * Format Count Utility
786
818
  *
@@ -835,24 +867,4 @@ declare function formatCountWithSeparators(count: number, locale?: string): stri
835
867
  */
836
868
  declare function parseFormattedCount(formatted: string): number;
837
869
 
838
- /**
839
- * UI Utilities
840
- *
841
- * Internal utilities for the UI package.
842
- * Most are not exported publicly - they're used internally by components.
843
- */
844
-
845
- /**
846
- * Merge class names with SDK prefix awareness.
847
- * Wrapper around clsx for consistent className handling.
848
- *
849
- * @example
850
- * ```tsx
851
- * import { cn } from '../../utils';
852
- *
853
- * <div className={cn('sv-video-player', isActive && 'sv-video-player--active', className)} />
854
- * ```
855
- */
856
- declare function cn(...inputs: (string | undefined | null | false | Record<string, boolean>)[]): string;
857
-
858
- export { CSS_CONTENT, CSS_VAR_PREFIX, type CacheStats, Components, CustomLayout, type CustomLayoutProps, DefaultLayout, type DefaultLayoutProps, type FirstFrameCacheConfig, type FormatCountOptions, type GestureModule, Layouts, MinimalLayout, type MinimalLayoutProps, type TapPosition, type Theme, type UseDoubleTapConfig, type UseDoubleTapReturn, areStylesInjected, cn, createFirstFrameCache, firstFrameCache, formatCount, formatCountWithSeparators, getTheme, injectComponentCSS, injectSDKStyles, isComponentCSSInjected, isDarkMode, isGestureLoaded, loadGesture, parseFormattedCount, preloadGesture, removeComponentCSS, removeStyles, setTheme, useCustomLayout, useDoubleTap, useStyles };
870
+ export { CSS_CONTENT, CSS_VAR_PREFIX, type CacheStats, Components, CustomLayout, type CustomLayoutProps, DefaultLayout, type DefaultLayoutProps, type FirstFrameCacheConfig, type FormatCountOptions, Layouts, MinimalLayout, type MinimalLayoutProps, type TapPosition, type Theme, type UseDoubleTapConfig, type UseDoubleTapReturn, areStylesInjected, createFirstFrameCache, firstFrameCache, formatCount, formatCountWithSeparators, getTheme, injectComponentCSS, injectSDKStyles, isComponentCSSInjected, isDarkMode, parseFormattedCount, removeComponentCSS, removeStyles, setTheme, useCustomLayout, useDoubleTap, useStyles };