@xhub-short/ui 0.1.0-beta.9 → 1.0.0-beta.22

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 (78) hide show
  1. package/dist/CommentSheet.css-DuBy01rU.d.ts +219 -0
  2. package/dist/VideoSlotPlayIndicator-DPs8Xt5C.d.ts +51 -0
  3. package/dist/chunk-3LINB7GV.js +498 -0
  4. package/dist/chunk-3OB3OVYR.js +349 -0
  5. package/dist/chunk-4RIMQOBR.js +58 -0
  6. package/dist/chunk-5MKYDI4X.js +1 -0
  7. package/dist/chunk-5Y43HNRG.js +296 -0
  8. package/dist/chunk-7WXAQHJI.js +350 -0
  9. package/dist/chunk-BADA7OLG.js +564 -0
  10. package/dist/chunk-BEJAJFV6.js +191 -0
  11. package/dist/{chunk-RMLTPW5S.js → chunk-CAWE42LH.js} +4 -3
  12. package/dist/chunk-DGKMO3AE.js +717 -0
  13. package/dist/chunk-DR7KR7OT.js +103 -0
  14. package/dist/chunk-GRO2POPB.js +700 -0
  15. package/dist/chunk-GSNIZ6DF.js +605 -0
  16. package/dist/chunk-HXQPEZRG.js +105 -0
  17. package/dist/{chunk-FNXTPQ6L.js → chunk-IC2KUU4V.js} +31 -1340
  18. package/dist/chunk-IWSBYOSS.js +91 -0
  19. package/dist/{chunk-AC2IFAJR.js → chunk-NJXIYSDZ.js} +12 -1
  20. package/dist/{chunk-CL6BS7GB.js → chunk-OM4L7RE5.js} +12 -2
  21. package/dist/chunk-OTCSGHTG.js +334 -0
  22. package/dist/chunk-QCRRF76W.js +75 -0
  23. package/dist/chunk-QUEJHA24.js +508 -0
  24. package/dist/chunk-TJCPW4AO.js +105 -0
  25. package/dist/chunk-UTLVQ3FL.js +244 -0
  26. package/dist/chunk-UYBQTE4M.js +337 -0
  27. package/dist/chunk-VXW7AOGM.js +285 -0
  28. package/dist/{chunk-AQHD6LPS.js → chunk-YB7AXTX7.js} +1 -1
  29. package/dist/components/ActionBar/index.d.ts +7 -2
  30. package/dist/components/ActionBar/index.js +1 -1
  31. package/dist/components/AdvanceMenu/index.d.ts +80 -0
  32. package/dist/components/AdvanceMenu/index.js +1 -0
  33. package/dist/components/ArticleSlot/index.d.ts +213 -0
  34. package/dist/components/ArticleSlot/index.js +1 -0
  35. package/dist/components/AuthorInfo/index.js +1 -1
  36. package/dist/components/BottomSheet/index.d.ts +87 -0
  37. package/dist/components/BottomSheet/index.js +1 -0
  38. package/dist/components/CleanModeOverlay/index.d.ts +60 -0
  39. package/dist/components/CleanModeOverlay/index.js +1 -0
  40. package/dist/components/CommentSheet/index.d.ts +1 -1
  41. package/dist/components/CommentSheet/index.js +1 -1
  42. package/dist/components/DetailView/index.d.ts +314 -0
  43. package/dist/components/DetailView/index.js +1 -0
  44. package/dist/components/ErrorBoundary/index.js +1 -1
  45. package/dist/components/{VideoFeed → Feed}/index.d.ts +64 -45
  46. package/dist/components/Feed/index.js +1 -0
  47. package/dist/components/ImageCarousel/index.d.ts +50 -0
  48. package/dist/components/ImageCarousel/index.js +1 -0
  49. package/dist/components/Playlist/index.d.ts +117 -0
  50. package/dist/components/Playlist/index.js +1 -0
  51. package/dist/components/ProgressBar/index.js +1 -1
  52. package/dist/components/QualityPicker/index.d.ts +35 -0
  53. package/dist/components/QualityPicker/index.js +1 -0
  54. package/dist/components/ReportSheet/index.d.ts +74 -0
  55. package/dist/components/ReportSheet/index.js +1 -0
  56. package/dist/components/Skeleton/index.js +1 -1
  57. package/dist/components/SpeedPicker/index.d.ts +32 -0
  58. package/dist/components/SpeedPicker/index.js +1 -0
  59. package/dist/components/VideoInfo/index.d.ts +7 -3
  60. package/dist/components/VideoInfo/index.js +1 -1
  61. package/dist/components/VideoPlayer/index.js +1 -1
  62. package/dist/components/VideoSlot/index.d.ts +37 -68
  63. package/dist/components/VideoSlot/index.js +2 -1
  64. package/dist/components/VirtualSlider/index.js +1 -1
  65. package/dist/components/ZoomableContainer/index.d.ts +39 -0
  66. package/dist/components/ZoomableContainer/index.js +1 -0
  67. package/dist/index.d.ts +128 -11
  68. package/dist/index.js +25 -13
  69. package/package.json +8 -4
  70. package/dist/CommentSheet.css-BeCrEaUG.d.ts +0 -221
  71. package/dist/chunk-2FSDVYER.js +0 -737
  72. package/dist/chunk-ECR42RKK.js +0 -571
  73. package/dist/chunk-KWHMZ6H5.js +0 -562
  74. package/dist/chunk-SZXFH334.js +0 -204
  75. package/dist/chunk-UNV3NWN6.js +0 -148
  76. package/dist/chunk-WCRDTBCZ.js +0 -357
  77. package/dist/chunk-XDIH66C4.js +0 -1519
  78. package/dist/components/VideoFeed/index.js +0 -1
@@ -0,0 +1,219 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactElement, ReactNode } from 'react';
3
+ import { CommentItem, UICommentState, UICommentActions, CommentConfig } from '@xhub-short/contracts';
4
+
5
+ interface CommentInputProps {
6
+ /** Placeholder text */
7
+ placeholder?: string;
8
+ /** Quick emojis */
9
+ emojis?: string[];
10
+ /** Max input length */
11
+ maxLength?: number;
12
+ /** Custom class */
13
+ className?: string;
14
+ /** On submit callback */
15
+ onSubmitSuccess?: () => void;
16
+ /** On media button click */
17
+ onMediaClick?: () => void;
18
+ /** Reply to text (default: "Replying to") */
19
+ replyingToText?: string;
20
+ /** Reply placeholder template (default: "Reply to @{name}...") - {name} will be replaced */
21
+ replyPlaceholderTemplate?: string;
22
+ /** Cancel reply aria-label (default: "Cancel reply") */
23
+ cancelReplyAriaLabel?: string;
24
+ /** Add media aria-label (default: "Add media") */
25
+ addMediaAriaLabel?: string;
26
+ /** Submit comment aria-label (default: "Submit comment") */
27
+ submitAriaLabel?: string;
28
+ /** Open emoji aria-label (default: "Open emoji") */
29
+ emojiAriaLabel?: string;
30
+ /** Emoji button aria-label template (default: "Add {emoji}") */
31
+ addEmojiAriaLabel?: string;
32
+ }
33
+ declare const CommentInput: react.NamedExoticComponent<CommentInputProps>;
34
+
35
+ interface CommentItemProps {
36
+ comment: CommentItem;
37
+ className?: string;
38
+ }
39
+ declare const CommentItemComponent: react.NamedExoticComponent<CommentItemProps>;
40
+
41
+ interface CommentListProps {
42
+ /** Custom empty state */
43
+ emptyState?: ReactElement;
44
+ /** Custom loading state */
45
+ loadingState?: ReactElement;
46
+ /** Custom error state */
47
+ errorState?: (error: Error, retry: () => void) => ReactElement;
48
+ /** Custom class */
49
+ className?: string;
50
+ /** Error text (default: "Failed to load comments") */
51
+ errorText?: string;
52
+ /** Retry button text (default: "Try again") */
53
+ retryText?: string;
54
+ /** Empty state text (default: "No comments yet. Be the first!") */
55
+ emptyText?: string;
56
+ /** Load more button text (default: "Load more comments") */
57
+ loadMoreText?: string;
58
+ }
59
+ declare const CommentList: react.NamedExoticComponent<CommentListProps>;
60
+
61
+ /**
62
+ * i18n strings for CommentSheet internal components
63
+ */
64
+ interface CommentSheetI18n {
65
+ /** Text for "See more" button (default: "See more") */
66
+ expandText?: string;
67
+ /** Text for "See less" button (default: "See less") */
68
+ collapseText?: string;
69
+ /** Text for view replies - use {count} placeholder (default: "View {count} more replies") */
70
+ viewRepliesText?: string;
71
+ /** Text for hide replies (default: "Hide replies") */
72
+ hideRepliesText?: string;
73
+ /** Text for load replies (default: "Load replies") */
74
+ loadRepliesText?: string;
75
+ /** Text for view more replies (default: "View more replies") */
76
+ viewMoreRepliesText?: string;
77
+ /** Function to format relative time */
78
+ formatRelativeTime?: (dateStr: string) => string;
79
+ /** Text for delete menu option (default: "Delete") */
80
+ deleteText?: string;
81
+ /** Text for edit menu option (default: "Edit") */
82
+ editText?: string;
83
+ /** Text for report menu option (default: "Report") */
84
+ reportText?: string;
85
+ /** Delete confirmation title (default: "Delete comment?") */
86
+ deleteConfirmTitle?: string;
87
+ /** Delete confirmation message (default: "This action cannot be undone.") */
88
+ deleteConfirmMessage?: string;
89
+ /** Delete confirm button (default: "Delete") */
90
+ deleteConfirmButton?: string;
91
+ /** Cancel button (default: "Cancel") */
92
+ cancelButton?: string;
93
+ }
94
+ /**
95
+ * CommentSheet context value
96
+ */
97
+ interface CommentSheetContextValue {
98
+ /** Comment state */
99
+ state: UICommentState;
100
+ /** Comment actions */
101
+ actions: UICommentActions;
102
+ /** Video ID */
103
+ videoId: string;
104
+ /** Config */
105
+ config: CommentConfig;
106
+ /** Whether sheet is open */
107
+ isOpen: boolean;
108
+ /** Close sheet */
109
+ onClose: () => void;
110
+ /** Reply target (when replying to a comment) */
111
+ replyTarget: ReplyTarget | null;
112
+ /** Set reply target */
113
+ setReplyTarget: (target: ReplyTarget | null) => void;
114
+ /** Initial count from video data (used before API loads) */
115
+ initialCount?: number;
116
+ /** i18n strings for internal components */
117
+ i18n: CommentSheetI18n;
118
+ }
119
+ /**
120
+ * Reply target info
121
+ */
122
+ interface ReplyTarget {
123
+ /** Parent comment ID */
124
+ commentId: string;
125
+ /** Author name for @mention */
126
+ authorName: string;
127
+ /** Author ID */
128
+ authorId: string;
129
+ }
130
+ /**
131
+ * CommentSheet context
132
+ */
133
+ declare const CommentSheetContext: react.Context<CommentSheetContextValue | undefined>;
134
+ /**
135
+ * Hook to use CommentSheet context
136
+ * @throws if used outside of CommentSheetHeadless
137
+ */
138
+ declare function useCommentSheetContext(): CommentSheetContextValue;
139
+ /**
140
+ * Hook to optionally use CommentSheet context
141
+ * @returns context or undefined if not within CommentSheetHeadless
142
+ */
143
+ declare function useOptionalCommentSheetContext(): CommentSheetContextValue | undefined;
144
+
145
+ interface SheetHeaderProps {
146
+ /** Custom title label (default: "Comments") */
147
+ titleLabel?: string;
148
+ /** Show drag handle */
149
+ showHandle?: boolean;
150
+ /** Show sort button */
151
+ showSort?: boolean;
152
+ /** Sort click handler */
153
+ onSortClick?: () => void;
154
+ /** Custom close icon */
155
+ closeIcon?: ReactElement;
156
+ /** Custom class */
157
+ className?: string;
158
+ /** Sort button aria-label (default: "Sort comments") */
159
+ sortAriaLabel?: string;
160
+ /** Close button aria-label (default: "Close comments") */
161
+ closeAriaLabel?: string;
162
+ }
163
+ declare const SheetHeader: react__default.NamedExoticComponent<SheetHeaderProps>;
164
+
165
+ interface CommentSheetHeadlessProps {
166
+ /** Whether sheet is open */
167
+ isOpen: boolean;
168
+ /** Close callback */
169
+ onClose: () => void;
170
+ /** Video ID for comments */
171
+ videoId: string;
172
+ /** Comment state from SDK */
173
+ state: UICommentState;
174
+ /** Comment actions from SDK */
175
+ actions: UICommentActions;
176
+ /** Config */
177
+ config?: Partial<CommentConfig>;
178
+ /** Initial count from video data (displayed before API loads) */
179
+ initialCount?: number;
180
+ /** Custom children (compound pattern) */
181
+ children?: ReactNode;
182
+ /** Root class name */
183
+ className?: string;
184
+ /** Backdrop class name */
185
+ backdropClassName?: string;
186
+ /** Close on backdrop click */
187
+ closeOnBackdropClick?: boolean;
188
+ /** Close on escape key */
189
+ closeOnEscape?: boolean;
190
+ /** Enable drag-to-dismiss */
191
+ enableDragToDismiss?: boolean;
192
+ /** Drag threshold to close (px) */
193
+ dragCloseThreshold?: number;
194
+ /** i18n strings for internal components (CommentItem, etc.) */
195
+ i18n?: CommentSheetI18n;
196
+ /** Callback to lock/unlock global gestures */
197
+ onGestureLock?: (isLocked: boolean) => void;
198
+ }
199
+ declare const CommentSheetHeadless: react.NamedExoticComponent<CommentSheetHeadlessProps>;
200
+ declare const CommentSheet: react.NamedExoticComponent<CommentSheetHeadlessProps> & {
201
+ Header: react.NamedExoticComponent<SheetHeaderProps>;
202
+ List: react.NamedExoticComponent<CommentListProps>;
203
+ Input: react.NamedExoticComponent<CommentInputProps>;
204
+ Item: react.NamedExoticComponent<CommentItemProps>;
205
+ };
206
+
207
+ /**
208
+ * CommentSheet CSS
209
+ *
210
+ * Modern bottom sheet for comments (Light Theme)
211
+ * Based on Figma design: https://figma.com/design/Kd1lJUJ4B3Kuw3dV9UcUok
212
+ *
213
+ * Note: CommentSheet is built on BottomSheetHeadless, so this CSS
214
+ * only provides CommentSheet-specific styling (colors, items, etc.)
215
+ * The base sheet structure is handled by BottomSheet.css.ts
216
+ */
217
+ declare const COMMENT_SHEET_CSS = "\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\n CSS VARIABLES (Light Theme)\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 */\n\n:root {\n /* Primary colors */\n --sv-comment-primary: #164d8e;\n --sv-comment-primary-light: #1354ae;\n --sv-comment-primary-dark: #003477;\n \n /* Contrast colors */\n --sv-comment-bg: #ffffff;\n --sv-comment-text: #121212;\n --sv-comment-text-secondary: #6b7271;\n --sv-comment-border: rgba(18, 18, 18, 0.08);\n \n /* Accent colors */\n --sv-comment-like-color: #ff434e;\n --sv-comment-verified-color: #1ea031;\n --sv-comment-mention-color: #164d8e;\n \n /* Component specific */\n --sv-comment-avatar-bg: #e5e6e6;\n --sv-comment-input-border: #a3a3a3;\n --sv-comment-reply-line: #e5e6e6;\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\n OVERRIDE BOTTOMSHEET 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 */\n\n.sv-comment-sheet {\n /* Override BottomSheet theming */\n --sv-sheet-bg: var(--sv-comment-bg, #ffffff);\n --sv-sheet-border-radius: var(--sv-comment-sheet-radius, 24px);\n --sv-sheet-animation-duration: var(--sv-comment-animation-duration, 400ms);\n --sv-sheet-animation-easing: var(--sv-comment-animation-easing, cubic-bezier(0.32, 0.72, 0, 1));\n \n /* Add margin for rounded corners effect */\n margin: 16px;\n border-radius: var(--sv-comment-sheet-radius, 24px);\n}\n\n.sv-comment-sheet-backdrop {\n --sv-sheet-backdrop-bg: var(--sv-comment-backdrop-bg, rgba(0, 0, 0, 0.5));\n}\n\n/* Inner content wrapper */\n.sv-comment-sheet__inner {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n/* Content wrapper - remove BottomSheet default scroll */\n.sv-comment-sheet .sv-bottom-sheet__content {\n overflow: visible;\n display: flex;\n flex-direction: column;\n flex: 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\n HEADER\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 */\n\n.sv-comment-sheet__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid var(--sv-comment-border);\n flex-shrink: 0;\n position: relative;\n cursor: grab;\n touch-action: none;\n}\n\n.sv-comment-sheet__header:active {\n cursor: grabbing;\n}\n\n.sv-comment-sheet__header-handle {\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 36px;\n height: 4px;\n background: var(--sv-comment-text-secondary);\n border-radius: 2px;\n opacity: 0.3;\n}\n\n.sv-comment-sheet__header-left {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.sv-comment-sheet__title {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--sv-comment-text);\n opacity: 0.9;\n margin: 0;\n}\n\n.sv-comment-sheet__sort-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--sv-comment-text);\n}\n\n.sv-comment-sheet__sort-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-sheet__close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 100px;\n background: linear-gradient(180deg, var(--sv-comment-primary-light) 0%, var(--sv-comment-primary-dark) 100%);\n cursor: pointer;\n transition: opacity 0.15s ease;\n}\n\n.sv-comment-sheet__close-btn:hover {\n opacity: 0.9;\n}\n\n.sv-comment-sheet__close-btn svg {\n width: 20px;\n height: 20px;\n color: #ffffff;\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\n COMMENT LIST\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 */\n\n.sv-comment-sheet__list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 8px 16px 28px 16px;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior: contain;\n touch-action: pan-y;\n}\n\n.sv-comment-sheet__list::-webkit-scrollbar {\n width: 0px;\n}\n\n.sv-comment-sheet__list::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.0);\n border-radius: 0px;\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\n COMMENT ITEM\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 */\n\n.sv-comment-item {\n display: flex;\n gap: 6px;\n padding: 16px 0;\n position: relative;\n}\n\n.sv-comment-item--pending {\n opacity: 0.6;\n}\n\n.sv-comment-item--pinned {\n background: var(--sv-comment-bg);\n}\n\n.sv-comment-item__avatar {\n width: 40px;\n height: 40px;\n border-radius: 120px;\n flex-shrink: 0;\n object-fit: cover;\n background: var(--sv-comment-avatar-bg);\n}\n\n.sv-comment-item__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.sv-comment-item__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 4px;\n}\n\n.sv-comment-item__header-left {\n display: flex;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n\n.sv-comment-item__pin-icon {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n color: var(--sv-comment-primary);\n}\n\n.sv-comment-item__author {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 14px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--sv-comment-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.sv-comment-item__verified {\n width: 12px;\n height: 12px;\n flex-shrink: 0;\n color: var(--sv-comment-verified-color);\n}\n\n.sv-comment-item__badge {\n font-size: 10px;\n padding: 2px 6px;\n background: var(--sv-comment-primary);\n color: #ffffff;\n border-radius: 4px;\n flex-shrink: 0;\n}\n\n.sv-comment-item__menu-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-item__menu-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-item__text {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 400;\n line-height: 1.4;\n color: var(--sv-comment-text);\n word-break: break-word;\n margin: 0;\n padding-right: 16px;\n}\n\n/* Text collapse */\n.sv-comment-item__text--collapsed {\n display: -webkit-box;\n -webkit-line-clamp: var(--sv-comment-max-lines, 3);\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.sv-comment-item__expand-btn {\n background: none;\n border: none;\n padding: 0;\n font-size: 12px;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n margin-top: 4px;\n}\n\n.sv-comment-item__expand-btn:hover {\n color: var(--sv-comment-text);\n}\n\n/* Actions row */\n.sv-comment-item__actions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.sv-comment-item__time {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.2;\n color: var(--sv-comment-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.sv-comment-item__action-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n background: none;\n border: none;\n padding: 0;\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.2;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n transition: color 0.15s ease;\n}\n\n.sv-comment-item__action-btn:hover {\n color: var(--sv-comment-text);\n}\n\n.sv-comment-item__action-btn--active {\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-item__action-btn--active:hover {\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-item__action-icon {\n width: 20px;\n height: 20px;\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\n REPLIES\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 */\n\n.sv-comment-replies {\n margin-top: 12px;\n position: relative;\n}\n\n/* Vertical connecting line */\n.sv-comment-item--has-replies::before {\n content: '';\n position: absolute;\n left: 20px;\n top: 56px;\n bottom: 0;\n width: 1px;\n background: var(--sv-comment-reply-line);\n}\n\n.sv-comment-replies__toggle {\n display: flex;\n align-items: center;\n gap: 0;\n background: none;\n border: none;\n padding: 4px 0;\n cursor: pointer;\n}\n\n.sv-comment-replies__toggle-line {\n width: 24px;\n height: 1px;\n background: #a3a3a3;\n margin-right: 0;\n}\n\n.sv-comment-replies__toggle-text {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 13px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--sv-comment-text-secondary);\n white-space: nowrap;\n}\n\n.sv-comment-replies__toggle-icon {\n width: 20px;\n height: 20px;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-replies__list {\n margin-top: 12px;\n}\n\n.sv-comment-reply {\n display: flex;\n gap: 6px;\n padding: 0 0 12px 0;\n position: relative;\n}\n\n.sv-comment-reply__avatar {\n width: 24px;\n height: 24px;\n border-radius: 100px;\n flex-shrink: 0;\n object-fit: cover;\n background: var(--sv-comment-avatar-bg);\n}\n\n.sv-comment-reply__mention {\n color: var(--sv-comment-mention-color);\n font-weight: 500;\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\n INPUT AREA\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 */\n\n.sv-comment-sheet__input-area {\n padding: 0 16px 36px 16px;\n flex-shrink: 0;\n}\n\n/* Guest mode - login prompt instead of input */\n.sv-comment-input-guest {\n padding: 16px;\n border-top: 1px solid var(--sv-comment-border);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n background: var(--sv-comment-bg);\n color: var(--sv-comment-primary);\n font-weight: 600;\n font-size: 14px;\n width: 100%;\n transition: background 0.15s ease;\n}\n\n.sv-comment-input-guest:hover {\n background: rgba(22, 77, 142, 0.05);\n}\n\n.sv-comment-input-guest:active {\n background: rgba(22, 77, 142, 0.1);\n}\n\n.sv-comment-sheet__reply-to {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 0;\n margin-bottom: 8px;\n font-size: 12px;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-sheet__reply-to-author-name {\n font-size: 12px;\n color: var(--sv-comment-text);\n font-weight: 500;\n}\n\n.sv-comment-sheet__reply-to-clear {\n background: none;\n border: none;\n padding: 4px;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n font-size: 12px;\n}\n\n.sv-comment-sheet__input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 44px;\n padding: 16px;\n background: var(--sv-comment-bg);\n border: 1px solid var(--sv-comment-input-border);\n border-radius: 12px;\n backdrop-filter: blur(50px);\n}\n\n.sv-comment-sheet__input-left {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n}\n\n.sv-comment-sheet__media-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.sv-comment-sheet__media-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-sheet__input {\n flex: 1;\n background: none;\n border: none;\n outline: none;\n resize: none;\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-style: italic;\n font-weight: 400;\n line-height: 1.4;\n color: var(--sv-comment-text);\n padding: 0;\n min-width: 0;\n}\n\n.sv-comment-sheet__input::placeholder {\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-sheet__input:not(:placeholder-shown) {\n font-style: normal;\n}\n\n.sv-comment-sheet__emoji-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.sv-comment-sheet__emoji-btn svg {\n width: 20px;\n height: 20px;\n color: var(--sv-comment-primary);\n}\n\n/* Hidden emoji bar (can be toggled) */\n.sv-comment-sheet__emoji-bar {\n display: none;\n gap: 8px;\n padding: 8px 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.sv-comment-sheet__emoji-bar--visible {\n display: flex;\n}\n\n.sv-comment-sheet__emoji-bar::-webkit-scrollbar {\n display: none;\n}\n\n.sv-comment-sheet__emoji-bar-btn {\n background: none;\n border: none;\n padding: 4px;\n font-size: 20px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.sv-comment-sheet__emoji-bar-btn:hover {\n background: rgba(0, 0, 0, 0.05);\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\n STATES\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 */\n\n.sv-comment-sheet__loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-sheet__loading-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid rgba(0, 0, 0, 0.1);\n border-top-color: var(--sv-comment-primary);\n border-radius: 50%;\n animation: sv-comment-spin 0.8s linear infinite;\n}\n\n@keyframes sv-comment-spin {\n to { transform: rotate(360deg); }\n}\n\n.sv-comment-sheet__empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n text-align: center;\n}\n\n.sv-comment-sheet__empty-icon {\n font-size: 48px;\n margin-bottom: 12px;\n}\n\n.sv-comment-sheet__empty-text {\n color: var(--sv-comment-text-secondary);\n font-size: 14px;\n}\n\n.sv-comment-sheet__error {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n text-align: center;\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-sheet__error-btn {\n margin-top: 12px;\n padding: 8px 16px;\n background: rgba(0, 0, 0, 0.05);\n border: none;\n border-radius: 8px;\n color: var(--sv-comment-text);\n cursor: pointer;\n}\n\n/* Load more */\n.sv-comment-sheet__load-more {\n display: flex;\n justify-content: center;\n padding: 12px;\n}\n\n.sv-comment-sheet__load-more-btn {\n background: none;\n border: none;\n padding: 8px 16px;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n font-size: 13px;\n}\n\n.sv-comment-sheet__load-more-btn:hover {\n color: var(--sv-comment-text);\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\n COMMENT MENU (Dropdown)\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 */\n\n.sv-comment-menu {\n position: relative;\n}\n\n.sv-comment-menu__trigger {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--sv-comment-text-secondary);\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.sv-comment-menu__trigger:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.sv-comment-menu__icon {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-menu__dropdown {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 140px;\n background: var(--sv-comment-bg);\n border: 1px solid var(--sv-comment-border);\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 10;\n overflow: hidden;\n animation: sv-menu-fade-in 0.15s ease;\n}\n\n@keyframes sv-menu-fade-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.sv-comment-menu__item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 10px 12px;\n background: none;\n border: none;\n cursor: pointer;\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 14px;\n font-weight: 500;\n color: var(--sv-comment-text);\n text-align: left;\n transition: background 0.15s ease;\n}\n\n.sv-comment-menu__item:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.sv-comment-menu__item--danger {\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-menu__item--danger:hover {\n background: rgba(255, 67, 78, 0.08);\n}\n\n.sv-comment-menu__item-icon {\n width: 18px;\n height: 18px;\n flex-shrink: 0;\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\n DELETE CONFIRMATION DIALOG\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 */\n\n.sv-comment-dialog-overlay {\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n z-index: var(--sv-comment-modal-z-index, 1100);\n animation: sv-dialog-overlay-fade-in 0.2s ease;\n}\n\n@keyframes sv-dialog-overlay-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.sv-comment-dialog {\n background: var(--sv-comment-bg);\n border-radius: 16px;\n padding: 24px;\n max-width: 300px;\n width: calc(100% - 48px);\n text-align: center;\n animation: sv-dialog-scale-in 0.2s ease;\n}\n\n@keyframes sv-dialog-scale-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.sv-comment-dialog__title {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 17px;\n font-weight: 600;\n color: var(--sv-comment-text);\n margin: 0 0 8px 0;\n}\n\n.sv-comment-dialog__message {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 14px;\n color: var(--sv-comment-text-secondary);\n margin: 0 0 20px 0;\n line-height: 1.4;\n}\n\n.sv-comment-dialog__actions {\n display: flex;\n gap: 12px;\n}\n\n.sv-comment-dialog__btn {\n flex: 1;\n padding: 12px 16px;\n border: none;\n border-radius: 10px;\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 15px;\n font-weight: 600;\n cursor: pointer;\n transition: opacity 0.15s ease;\n}\n\n.sv-comment-dialog__btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.sv-comment-dialog__btn--cancel {\n background: rgba(0, 0, 0, 0.06);\n color: var(--sv-comment-text);\n}\n\n.sv-comment-dialog__btn--cancel:hover:not(:disabled) {\n background: rgba(0, 0, 0, 0.1);\n}\n\n.sv-comment-dialog__btn--danger {\n background: var(--sv-comment-like-color);\n color: #ffffff;\n}\n\n.sv-comment-dialog__btn--danger:hover:not(:disabled) {\n opacity: 0.9;\n}\n\n/* Legacy classes (keep for backwards compatibility) */\n.sv-comment-delete-confirm {\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n z-index: var(--sv-comment-modal-z-index, 1100);\n}\n\n.sv-comment-delete-confirm__dialog {\n background: var(--sv-comment-bg);\n border-radius: 12px;\n padding: 16px;\n max-width: 280px;\n text-align: center;\n}\n\n.sv-comment-delete-confirm__title {\n font-size: 16px;\n font-weight: 600;\n color: var(--sv-comment-text);\n margin-bottom: 8px;\n}\n\n.sv-comment-delete-confirm__text {\n font-size: 14px;\n color: var(--sv-comment-text-secondary);\n margin-bottom: 16px;\n}\n\n.sv-comment-delete-confirm__actions {\n display: flex;\n gap: 8px;\n}\n\n.sv-comment-delete-confirm__btn {\n flex: 1;\n padding: 8px 12px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.sv-comment-delete-confirm__btn--cancel {\n background: rgba(0, 0, 0, 0.05);\n color: var(--sv-comment-text);\n}\n\n.sv-comment-delete-confirm__btn--delete {\n background: var(--sv-comment-like-color);\n color: #ffffff;\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\n SKELETON 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 */\n\n@keyframes sv-skeleton-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n}\n\n.sv-comment-skeleton-list {\n display: flex;\n flex-direction: column;\n}\n\n.sv-comment-skeleton {\n animation: sv-skeleton-fade-in 0.3s ease;\n}\n\n@keyframes sv-skeleton-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.sv-comment-skeleton__avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.sv-comment-skeleton__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sv-comment-skeleton__header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.sv-comment-skeleton__author {\n width: 80px;\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n animation-delay: 0.1s;\n}\n\n.sv-comment-skeleton__time {\n width: 40px;\n height: 12px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n animation-delay: 0.15s;\n}\n\n.sv-comment-skeleton__text {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sv-comment-skeleton__line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.sv-comment-skeleton__line--full {\n width: 100%;\n animation-delay: 0.2s;\n}\n\n.sv-comment-skeleton__line--medium {\n width: 65%;\n animation-delay: 0.25s;\n}\n\n.sv-comment-skeleton__actions {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-top: 4px;\n}\n\n.sv-comment-skeleton__action {\n width: 50px;\n height: 12px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n animation-delay: 0.3s;\n}\n";
218
+
219
+ export { COMMENT_SHEET_CSS as C, type ReplyTarget as R, SheetHeader as S, CommentInput as a, type CommentInputProps as b, CommentItemComponent as c, type CommentItemProps as d, CommentList as e, type CommentListProps as f, CommentSheet as g, CommentSheetContext as h, type CommentSheetContextValue as i, CommentSheetHeadless as j, type CommentSheetHeadlessProps as k, type CommentSheetI18n as l, type SheetHeaderProps as m, useOptionalCommentSheetContext as n, useCommentSheetContext as u };
@@ -0,0 +1,51 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface VideoSlotPlayIndicatorProps {
5
+ /** Custom play icon */
6
+ playIcon?: ReactNode;
7
+ /** Custom pause icon */
8
+ pauseIcon?: ReactNode;
9
+ /** Icon size in pixels */
10
+ size?: number;
11
+ /** Animation duration in ms */
12
+ duration?: number;
13
+ /**
14
+ * Keep play icon visible while video is paused (YouTube style)
15
+ * When false, icon auto-hides after duration
16
+ */
17
+ persistWhenPaused?: boolean;
18
+ /** Additional CSS class */
19
+ className?: string;
20
+ /** Test ID */
21
+ testId?: string;
22
+ }
23
+ interface VideoSlotPlayIndicatorInnerProps extends VideoSlotPlayIndicatorProps {
24
+ lastUserToggleTime: number;
25
+ isPlaying: boolean;
26
+ }
27
+ /**
28
+ * VideoSlotPlayIndicatorInner - Memoized inner component
29
+ *
30
+ * This component is wrapped with React.memo and receives all data via props.
31
+ * It will only re-render when props actually change (shallow comparison).
32
+ */
33
+ declare const VideoSlotPlayIndicatorInner: react.NamedExoticComponent<VideoSlotPlayIndicatorInnerProps>;
34
+
35
+ /**
36
+ * VideoSlotPlayIndicator Component
37
+ *
38
+ * This outer component:
39
+ * 1. Consumes context (will re-render when context changes)
40
+ * 2. Selects only the needed values
41
+ * 3. Passes them as props to memoized inner component
42
+ *
43
+ * The inner component will only re-render when the selected values change,
44
+ * NOT when unrelated context values change (e.g., during seek operations).
45
+ */
46
+ declare function VideoSlotPlayIndicator(props: VideoSlotPlayIndicatorProps): React.ReactElement | null;
47
+ declare namespace VideoSlotPlayIndicator {
48
+ var displayName: string;
49
+ }
50
+
51
+ export { VideoSlotPlayIndicator as V, type VideoSlotPlayIndicatorProps as a, type VideoSlotPlayIndicatorInnerProps as b, VideoSlotPlayIndicatorInner as c };