@ermis-network/ermis-chat-react 1.0.0

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 (88) hide show
  1. package/dist/index.cjs +6593 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.css +3375 -0
  4. package/dist/index.css.map +1 -0
  5. package/dist/index.d.mts +1138 -0
  6. package/dist/index.d.ts +1138 -0
  7. package/dist/index.mjs +6500 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +42 -0
  10. package/src/components/Avatar.tsx +102 -0
  11. package/src/components/Channel.tsx +77 -0
  12. package/src/components/ChannelHeader.tsx +85 -0
  13. package/src/components/ChannelInfo/AddMemberModal.tsx +204 -0
  14. package/src/components/ChannelInfo/ChannelInfo.tsx +455 -0
  15. package/src/components/ChannelInfo/ChannelInfoTabs.tsx +282 -0
  16. package/src/components/ChannelInfo/ChannelSettingsPanel.tsx +479 -0
  17. package/src/components/ChannelInfo/EditChannelModal.tsx +272 -0
  18. package/src/components/ChannelInfo/FileListItem.tsx +49 -0
  19. package/src/components/ChannelInfo/LinkListItem.tsx +62 -0
  20. package/src/components/ChannelInfo/MediaGridItem.tsx +90 -0
  21. package/src/components/ChannelInfo/MemberListItem.tsx +85 -0
  22. package/src/components/ChannelInfo/MessageSearchPanel.tsx +333 -0
  23. package/src/components/ChannelInfo/States.tsx +36 -0
  24. package/src/components/ChannelInfo/index.ts +10 -0
  25. package/src/components/ChannelInfo/utils.tsx +49 -0
  26. package/src/components/ChannelList.tsx +395 -0
  27. package/src/components/Dropdown.tsx +120 -0
  28. package/src/components/EditPreview.tsx +102 -0
  29. package/src/components/FilesPreview.tsx +108 -0
  30. package/src/components/ForwardMessageModal.tsx +234 -0
  31. package/src/components/MentionSuggestions.tsx +59 -0
  32. package/src/components/MessageActionsBox.tsx +186 -0
  33. package/src/components/MessageInput.tsx +513 -0
  34. package/src/components/MessageInputDefaults.tsx +50 -0
  35. package/src/components/MessageItem.tsx +218 -0
  36. package/src/components/MessageQuickReactions.tsx +73 -0
  37. package/src/components/MessageReactions.tsx +59 -0
  38. package/src/components/MessageRenderers.tsx +565 -0
  39. package/src/components/Modal.tsx +58 -0
  40. package/src/components/Panel.tsx +64 -0
  41. package/src/components/PinnedMessages.tsx +165 -0
  42. package/src/components/QuotedMessagePreview.tsx +55 -0
  43. package/src/components/ReadReceipts.tsx +80 -0
  44. package/src/components/ReplyPreview.tsx +98 -0
  45. package/src/components/TypingIndicator.tsx +57 -0
  46. package/src/components/VirtualMessageList.tsx +425 -0
  47. package/src/context/ChatProvider.tsx +73 -0
  48. package/src/hooks/useBannedState.ts +48 -0
  49. package/src/hooks/useBlockedState.ts +55 -0
  50. package/src/hooks/useChannel.ts +18 -0
  51. package/src/hooks/useChannelCapabilities.ts +42 -0
  52. package/src/hooks/useChannelData.ts +55 -0
  53. package/src/hooks/useChannelListUpdates.ts +224 -0
  54. package/src/hooks/useChannelMessages.ts +159 -0
  55. package/src/hooks/useChannelRowUpdates.ts +78 -0
  56. package/src/hooks/useChatClient.ts +11 -0
  57. package/src/hooks/useEmojiPicker.ts +53 -0
  58. package/src/hooks/useFileUpload.ts +128 -0
  59. package/src/hooks/useLoadMessages.ts +178 -0
  60. package/src/hooks/useMentions.ts +287 -0
  61. package/src/hooks/useMessageActions.ts +87 -0
  62. package/src/hooks/useMessageSend.ts +164 -0
  63. package/src/hooks/usePendingState.ts +63 -0
  64. package/src/hooks/useScrollToMessage.ts +155 -0
  65. package/src/hooks/useTypingIndicator.ts +86 -0
  66. package/src/index.ts +129 -0
  67. package/src/styles/_add-member-modal.css +122 -0
  68. package/src/styles/_base.css +32 -0
  69. package/src/styles/_channel-info.css +941 -0
  70. package/src/styles/_channel-list.css +217 -0
  71. package/src/styles/_dropdown.css +69 -0
  72. package/src/styles/_forward-modal.css +191 -0
  73. package/src/styles/_mentions.css +102 -0
  74. package/src/styles/_message-actions.css +61 -0
  75. package/src/styles/_message-bubble.css +656 -0
  76. package/src/styles/_message-input.css +389 -0
  77. package/src/styles/_message-list.css +416 -0
  78. package/src/styles/_message-quick-reactions.css +62 -0
  79. package/src/styles/_message-reactions.css +67 -0
  80. package/src/styles/_modal.css +113 -0
  81. package/src/styles/_panel.css +69 -0
  82. package/src/styles/_pinned-messages.css +140 -0
  83. package/src/styles/_search-panel.css +219 -0
  84. package/src/styles/_tokens.css +92 -0
  85. package/src/styles/_typing-indicator.css +59 -0
  86. package/src/styles/index.css +24 -0
  87. package/src/types.ts +955 -0
  88. package/src/utils.ts +242 -0
@@ -0,0 +1,656 @@
1
+ /* --- Quoted message preview --- */
2
+ .ermis-quoted-message {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 2px;
6
+ padding: var(--ermis-spacing-xs) var(--ermis-spacing-sm);
7
+ border-left: 3px solid var(--ermis-accent);
8
+ background-color: var(--ermis-quote-other-bg);
9
+ border-radius: 0 var(--ermis-radius-sm) var(--ermis-radius-sm) 0;
10
+ cursor: pointer;
11
+ max-width: 100%;
12
+ transition: background-color 0.15s;
13
+ margin-top: var(--ermis-spacing-sm);
14
+ }
15
+
16
+ .ermis-quoted-message:hover {
17
+ background-color: var(--ermis-quote-other-bg-hover);
18
+ }
19
+
20
+ .ermis-quoted-message--own {
21
+ border-left-color: var(--ermis-quote-own-border);
22
+ background-color: var(--ermis-quote-own-bg);
23
+ border-radius: var(--ermis-radius-sm);
24
+ }
25
+
26
+ .ermis-quoted-message--own:hover {
27
+ background-color: var(--ermis-quote-own-bg-hover);
28
+ }
29
+
30
+ .ermis-quoted-message__author {
31
+ font-size: var(--ermis-font-size-xs);
32
+ font-weight: 600;
33
+ color: var(--ermis-accent);
34
+ }
35
+
36
+ .ermis-quoted-message--own .ermis-quoted-message__author {
37
+ color: var(--ermis-quote-own-author);
38
+ }
39
+
40
+ .ermis-quoted-message__text {
41
+ font-size: var(--ermis-font-size-xs);
42
+ color: var(--ermis-text-muted);
43
+ overflow: hidden;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ }
47
+
48
+ .ermis-quoted-message--own .ermis-quoted-message__text {
49
+ color: var(--ermis-quote-own-text);
50
+ }
51
+
52
+ /* Light theme: same approach works since we darken the accent bg */
53
+
54
+ /* Avatar column: fixed width for consistent alignment */
55
+ .ermis-message-list__item-avatar {
56
+ flex-shrink: 0;
57
+ }
58
+
59
+ .ermis-message-list__item-content {
60
+ display: flex;
61
+ flex-direction: column;
62
+ min-width: 0;
63
+ max-width: 75%;
64
+ gap: 2px;
65
+ }
66
+
67
+ .ermis-message-list__item--own .ermis-message-list__item-content {
68
+ align-items: flex-end;
69
+ }
70
+
71
+ .ermis-message-list__bubble-wrapper {
72
+ display: flex;
73
+ flex-wrap: wrap;
74
+ flex-direction: row;
75
+ align-items: center; /* Center actions vertically with the bubble */
76
+ position: relative;
77
+ width: 100%;
78
+ }
79
+
80
+ .ermis-message-list__item--own .ermis-message-list__bubble-wrapper {
81
+ flex-direction: row-reverse;
82
+ }
83
+
84
+ .ermis-message-list__item-user {
85
+ font-size: var(--ermis-font-size-xs);
86
+ font-weight: 600;
87
+ color: var(--ermis-accent);
88
+ margin-bottom: 1px;
89
+ }
90
+
91
+ /* Timestamp inside bubble — bottom right */
92
+ .ermis-message-list__item-time {
93
+ font-size: 0.625rem;
94
+ color: var(--ermis-text-muted);
95
+ margin-left: auto;
96
+ padding-left: var(--ermis-spacing-md);
97
+ white-space: nowrap;
98
+ line-height: 1;
99
+ align-self: flex-end;
100
+ padding-top: 4px;
101
+ width: 100%;
102
+ text-align: right;
103
+ display: inline-flex;
104
+ align-items: center;
105
+ justify-content: flex-end;
106
+ gap: 3px;
107
+ }
108
+
109
+ .ermis-message-list__edited-indicator {
110
+ margin-right: 2px;
111
+ }
112
+
113
+ /* --- Inline message status icon (inside bubble, after timestamp) --- */
114
+ .ermis-message-status-icon {
115
+ display: inline-flex;
116
+ align-items: center;
117
+ flex-shrink: 0;
118
+ line-height: 0;
119
+ }
120
+
121
+ .ermis-message-status-icon--sent {
122
+ color: var(--ermis-text-muted);
123
+ opacity: 0.5;
124
+ }
125
+
126
+ .ermis-message-bubble--own .ermis-message-status-icon--sent {
127
+ color: rgba(255, 255, 255, 0.6);
128
+ opacity: 1;
129
+ }
130
+
131
+ .ermis-message-status-icon--sending {
132
+ color: var(--ermis-text-muted);
133
+ opacity: 0.4;
134
+ }
135
+
136
+ .ermis-message-bubble--own .ermis-message-status-icon--sending {
137
+ color: rgba(255, 255, 255, 0.4);
138
+ opacity: 1;
139
+ }
140
+
141
+ .ermis-message-status-icon--failed {
142
+ color: var(--ermis-color-error, #f44336);
143
+ }
144
+
145
+ .ermis-message-bubble--own .ermis-message-list__item-time {
146
+ color: rgba(255, 255, 255, 0.6);
147
+ }
148
+
149
+ .ermis-message-list__item-text {
150
+ font-size: var(--ermis-font-size-sm);
151
+ line-height: 1.5;
152
+ word-break: break-word;
153
+ }
154
+
155
+ /* --- Mentions --- */
156
+ .ermis-mention {
157
+ color: var(--ermis-accent);
158
+ font-weight: 600;
159
+ cursor: pointer;
160
+ }
161
+
162
+ .ermis-message-bubble--own .ermis-mention {
163
+ color: rgba(255, 255, 255, 0.9);
164
+ text-decoration: underline;
165
+ text-underline-offset: 2px;
166
+ }
167
+
168
+ /* Auto-detected URLs/emails in message text */
169
+ .ermis-text-link {
170
+ color: var(--ermis-accent);
171
+ text-decoration: underline;
172
+ text-underline-offset: 2px;
173
+ cursor: pointer;
174
+ word-break: break-all;
175
+ }
176
+
177
+ .ermis-text-link:hover {
178
+ opacity: 0.8;
179
+ }
180
+
181
+ .ermis-message-bubble--own .ermis-text-link {
182
+ color: rgba(255, 255, 255, 0.9);
183
+ }
184
+
185
+ /* --- Message Bubble --- */
186
+ .ermis-message-bubble {
187
+ position: relative;
188
+ display: flex;
189
+ flex-wrap: wrap;
190
+ align-items: flex-end;
191
+ padding: var(--ermis-spacing-sm) var(--ermis-spacing-md);
192
+ border-radius: var(--ermis-radius-lg);
193
+ width: 100%;
194
+ word-break: break-word;
195
+ }
196
+
197
+ .ermis-message-bubble--own {
198
+ background-color: var(--ermis-bubble-own-bg);
199
+ color: var(--ermis-bubble-own-text);
200
+ border-bottom-right-radius: var(--ermis-radius-sm);
201
+ }
202
+
203
+ .ermis-message-bubble--other {
204
+ background-color: var(--ermis-bubble-other-bg);
205
+ color: var(--ermis-bubble-other-text);
206
+ border-bottom-left-radius: var(--ermis-radius-sm);
207
+ }
208
+
209
+ /* --- System messages --- */
210
+ .ermis-message-list__system {
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ gap: var(--ermis-spacing-sm);
215
+ padding: var(--ermis-spacing-sm) 0;
216
+ margin: var(--ermis-spacing-xs) 0;
217
+ align-self: center;
218
+ }
219
+
220
+ .ermis-message-list__system-text {
221
+ font-size: var(--ermis-font-size-xs);
222
+ color: var(--ermis-text-muted);
223
+ font-style: italic;
224
+ }
225
+
226
+ /* --- Signal messages (call events) --- */
227
+ .ermis-message-list__signal-text {
228
+ font-size: var(--ermis-font-size-sm);
229
+ color: inherit;
230
+ line-height: 1.5;
231
+ word-break: break-word;
232
+ }
233
+
234
+ /* --- Attachments --- */
235
+
236
+ /* When message has attachments, constrain entire content column (quote + bubble) */
237
+ .ermis-message-list__item-content--has-attachments {
238
+ width: 350px;
239
+ }
240
+
241
+ /* Container for messages with both text + attachments */
242
+ .ermis-message-content--with-attachments {
243
+ display: flex;
244
+ flex-direction: column;
245
+ width: 100%;
246
+ }
247
+
248
+ .ermis-message-content--with-attachments .ermis-message-list__item-text {
249
+ word-wrap: break-word;
250
+ overflow-wrap: break-word;
251
+ }
252
+
253
+ .ermis-attachment-list {
254
+ display: flex;
255
+ flex-direction: column;
256
+ gap: var(--ermis-spacing-xs);
257
+ margin-top: var(--ermis-spacing-xs);
258
+ width: 100%;
259
+ }
260
+
261
+ /* Media grid (images + videos) */
262
+ .ermis-attachment-grid {
263
+ display: grid;
264
+ gap: 2px;
265
+ border-radius: var(--ermis-radius-md);
266
+ overflow: hidden;
267
+ }
268
+
269
+ .ermis-attachment-grid--single {
270
+ grid-template-columns: 1fr;
271
+ }
272
+
273
+ .ermis-attachment-grid--multi {
274
+ grid-template-columns: 1fr 1fr;
275
+ }
276
+
277
+ .ermis-attachment-grid .ermis-attachment--image,
278
+ .ermis-attachment-grid .ermis-attachment--video {
279
+ width: 100%;
280
+ height: 100%;
281
+ max-width: none;
282
+ max-height: 200px;
283
+ object-fit: cover;
284
+ border-radius: 0;
285
+ display: block;
286
+ }
287
+
288
+ /* Single media: larger height allowed */
289
+ .ermis-attachment-grid--single .ermis-attachment--image,
290
+ .ermis-attachment-grid--single .ermis-attachment--video {
291
+ max-height: 300px;
292
+ }
293
+
294
+ /* If odd number of media in multi-grid, last item spans full width */
295
+ .ermis-attachment-grid--multi > :last-child:nth-child(odd) {
296
+ grid-column: 1 / -1;
297
+ }
298
+
299
+ /* --- Aspect Ratio Box — prevents CLS (Cumulative Layout Shift) --- */
300
+ .ermis-attachment-aspect-box {
301
+ position: relative;
302
+ overflow: hidden;
303
+ border-radius: var(--ermis-radius-md);
304
+ width: 100%;
305
+ max-width: 300px;
306
+ min-height: 120px;
307
+ background-color: var(--ermis-bg-hover, #2a2a4a);
308
+ }
309
+
310
+ /* Blurred thumbnail preview (shown while full image loads) */
311
+ .ermis-attachment-blur-preview {
312
+ position: absolute;
313
+ top: 0;
314
+ left: 0;
315
+ width: 100%;
316
+ height: 100%;
317
+ object-fit: cover;
318
+ filter: blur(20px);
319
+ transform: scale(1.1); /* hide blur edges */
320
+ z-index: 1;
321
+ }
322
+
323
+ /* Shimmer animation placeholder (when no thumbnail available) */
324
+ .ermis-attachment-shimmer {
325
+ position: absolute;
326
+ top: 0;
327
+ left: 0;
328
+ width: 100%;
329
+ height: 100%;
330
+ z-index: 1;
331
+ background: linear-gradient(
332
+ 110deg,
333
+ var(--ermis-bg-hover, #2a2a4a) 30%,
334
+ var(--ermis-bg-active, #3a3a5a) 50%,
335
+ var(--ermis-bg-hover, #2a2a4a) 70%
336
+ );
337
+ background-size: 200% 100%;
338
+ animation: ermis-shimmer 1.5s ease-in-out infinite;
339
+ }
340
+
341
+ @keyframes ermis-shimmer {
342
+ 0% {
343
+ background-position: 200% 0;
344
+ }
345
+ 100% {
346
+ background-position: -200% 0;
347
+ }
348
+ }
349
+
350
+ /* Full image — hidden until loaded, fades in over blur/shimmer */
351
+ .ermis-attachment-aspect-box .ermis-attachment--image {
352
+ position: absolute;
353
+ top: 0;
354
+ left: 0;
355
+ width: 100%;
356
+ height: 100%;
357
+ object-fit: cover;
358
+ opacity: 0;
359
+ transition: opacity 0.3s ease;
360
+ z-index: 2;
361
+ /* Reset standalone styles inside aspect-box */
362
+ max-width: none;
363
+ max-height: none;
364
+ border-radius: 0;
365
+ }
366
+
367
+ .ermis-attachment-aspect-box .ermis-attachment--image.ermis-attachment--loaded {
368
+ opacity: 1;
369
+ }
370
+
371
+ /* Override aspect-box inside grid: remove constraints */
372
+ .ermis-attachment-grid .ermis-attachment-aspect-box {
373
+ max-width: none;
374
+ border-radius: 0;
375
+ min-height: 100px;
376
+ }
377
+
378
+ .ermis-attachment--image {
379
+ max-width: 300px;
380
+ max-height: 200px;
381
+ border-radius: var(--ermis-radius-md);
382
+ object-fit: cover;
383
+ cursor: pointer;
384
+ }
385
+
386
+ .ermis-attachment--video {
387
+ max-width: 300px;
388
+ max-height: 200px;
389
+ border-radius: var(--ermis-radius-md);
390
+ }
391
+
392
+ .ermis-attachment--file {
393
+ display: flex;
394
+ align-items: center;
395
+ gap: var(--ermis-spacing-sm);
396
+ padding: var(--ermis-spacing-sm) var(--ermis-spacing-md);
397
+ border-radius: var(--ermis-radius-md);
398
+ background-color: var(--ermis-bg-hover);
399
+ text-decoration: none;
400
+ color: var(--ermis-text-primary);
401
+ transition: background-color var(--ermis-transition);
402
+ }
403
+
404
+ .ermis-attachment--file:hover {
405
+ background-color: var(--ermis-bg-active);
406
+ }
407
+
408
+ .ermis-attachment__file-icon {
409
+ font-size: 1.25rem;
410
+ flex-shrink: 0;
411
+ }
412
+
413
+ .ermis-attachment__file-info {
414
+ display: flex;
415
+ flex-direction: column;
416
+ min-width: 0;
417
+ }
418
+
419
+ .ermis-attachment__file-name {
420
+ font-size: var(--ermis-font-size-sm);
421
+ font-weight: 500;
422
+ white-space: nowrap;
423
+ overflow: hidden;
424
+ text-overflow: ellipsis;
425
+ }
426
+
427
+ .ermis-attachment__file-size {
428
+ font-size: var(--ermis-font-size-xs);
429
+ color: var(--ermis-text-muted);
430
+ }
431
+
432
+ /* --- Voice recording --- */
433
+ .ermis-attachment--voice {
434
+ display: flex;
435
+ align-items: center;
436
+ gap: var(--ermis-spacing-sm);
437
+ padding: var(--ermis-spacing-sm) var(--ermis-spacing-md);
438
+ border-radius: var(--ermis-radius-md);
439
+ background-color: var(--ermis-bg-hover);
440
+ overflow: hidden;
441
+ width: 100%;
442
+ box-sizing: border-box;
443
+ }
444
+
445
+ .ermis-attachment__voice-icon {
446
+ font-size: 1.25rem;
447
+ flex-shrink: 0;
448
+ }
449
+
450
+ .ermis-attachment__voice-player {
451
+ flex: 1;
452
+ min-width: 0;
453
+ width: 100%;
454
+ max-width: 100%;
455
+ height: 32px;
456
+ }
457
+
458
+ .ermis-attachment__voice-duration {
459
+ font-size: var(--ermis-font-size-xs);
460
+ color: var(--ermis-text-muted);
461
+ flex-shrink: 0;
462
+ }
463
+
464
+ /* --- Link preview --- */
465
+ .ermis-attachment--link-preview {
466
+ display: flex;
467
+ flex-direction: column;
468
+ border-radius: var(--ermis-radius-md);
469
+ overflow: hidden;
470
+ border: 1px solid var(--ermis-border);
471
+ text-decoration: none;
472
+ color: var(--ermis-text-primary);
473
+ transition: border-color var(--ermis-transition);
474
+ }
475
+
476
+ .ermis-attachment--link-preview:hover {
477
+ border-color: var(--ermis-accent);
478
+ }
479
+
480
+ .ermis-attachment__link-image {
481
+ width: 100%;
482
+ max-height: 160px;
483
+ object-fit: cover;
484
+ }
485
+
486
+ .ermis-attachment__link-info {
487
+ display: flex;
488
+ flex-direction: column;
489
+ gap: 2px;
490
+ padding: var(--ermis-spacing-sm) var(--ermis-spacing-md);
491
+ }
492
+
493
+ .ermis-attachment__link-title {
494
+ font-size: var(--ermis-font-size-sm);
495
+ font-weight: 600;
496
+ display: -webkit-box;
497
+ -webkit-line-clamp: 2;
498
+ line-clamp: 2;
499
+ -webkit-box-orient: vertical;
500
+ overflow: hidden;
501
+ }
502
+
503
+ .ermis-attachment__link-description {
504
+ font-size: var(--ermis-font-size-xs);
505
+ color: var(--ermis-text-secondary);
506
+ display: -webkit-box;
507
+ -webkit-line-clamp: 2;
508
+ line-clamp: 2;
509
+ -webkit-box-orient: vertical;
510
+ overflow: hidden;
511
+ }
512
+
513
+ .ermis-attachment__link-url {
514
+ font-size: var(--ermis-font-size-xs);
515
+ color: var(--ermis-text-muted);
516
+ margin-top: 2px;
517
+ }
518
+
519
+ /* --- Poll message --- */
520
+ .ermis-message-poll {
521
+ display: flex;
522
+ align-items: center;
523
+ gap: var(--ermis-spacing-sm);
524
+ }
525
+
526
+ .ermis-message-poll__icon {
527
+ font-size: 1.25rem;
528
+ }
529
+
530
+ .ermis-message-poll__text {
531
+ font-size: var(--ermis-font-size-sm);
532
+ }
533
+
534
+ /* --- Sticker message --- */
535
+ .ermis-message-sticker {
536
+ max-width: 120px;
537
+ max-height: 120px;
538
+ }
539
+
540
+ /* --- Error message --- */
541
+ .ermis-message-error {
542
+ font-size: var(--ermis-font-size-sm);
543
+ color: #ef4444;
544
+ font-style: italic;
545
+ }
546
+
547
+ /* --- Read receipts --- */
548
+ .ermis-read-receipts {
549
+ display: flex;
550
+ justify-content: flex-end;
551
+ width: 100%;
552
+ padding-top: 2px;
553
+ }
554
+
555
+ .ermis-read-receipts__avatars {
556
+ display: flex;
557
+ flex-direction: row;
558
+ align-items: center;
559
+ cursor: default;
560
+ position: relative;
561
+ }
562
+
563
+ .ermis-read-receipts__avatar {
564
+ flex-shrink: 0;
565
+ border: 1.5px solid var(--ermis-bg-primary, #1a1a2e);
566
+ border-radius: 50%;
567
+ box-sizing: content-box;
568
+ }
569
+
570
+ /* Stack overlapping */
571
+ .ermis-read-receipts__avatar + .ermis-read-receipts__avatar {
572
+ margin-left: -4px;
573
+ }
574
+
575
+ .ermis-read-receipts__overflow {
576
+ display: flex;
577
+ align-items: center;
578
+ justify-content: center;
579
+ width: 16px;
580
+ height: 16px;
581
+ border-radius: 50%;
582
+ background-color: var(--ermis-bg-hover, #2a2a4a);
583
+ color: var(--ermis-text-muted, #888);
584
+ font-size: 0.5rem;
585
+ font-weight: 700;
586
+ margin-left: -4px;
587
+ border: 1.5px solid var(--ermis-bg-primary, #1a1a2e);
588
+ box-sizing: content-box;
589
+ flex-shrink: 0;
590
+ }
591
+
592
+ /* Tooltip Wrapper — hidden by default, shown on hover of __avatars */
593
+ .ermis-read-receipts__tooltip-wrapper {
594
+ display: none;
595
+ position: absolute;
596
+ bottom: calc(100% + 6px);
597
+ right: 0;
598
+ z-index: 50;
599
+ }
600
+
601
+ /* Invisible bridge to prevent hover loss when moving mouse from avatar to tooltip */
602
+ .ermis-read-receipts__tooltip-wrapper::after {
603
+ content: '';
604
+ position: absolute;
605
+ top: 100%;
606
+ left: 0;
607
+ right: 0;
608
+ height: 6px;
609
+ background: transparent;
610
+ }
611
+
612
+ .ermis-read-receipts__avatars:hover .ermis-read-receipts__tooltip-wrapper {
613
+ display: flex;
614
+ }
615
+
616
+ /* Inner Tooltip with scrolling and styling */
617
+ .ermis-read-receipts__tooltip {
618
+ display: flex;
619
+ flex-direction: column;
620
+ gap: 8px;
621
+ background-color: var(--ermis-bg-secondary, #1e1e3a);
622
+ border: 1px solid var(--ermis-border, #333);
623
+ border-radius: var(--ermis-radius-md, 8px);
624
+ padding: var(--ermis-spacing-xs, 6px) var(--ermis-spacing-sm, 8px);
625
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
626
+ width: 200px;
627
+ max-height: 200px;
628
+ overflow-y: auto;
629
+ }
630
+
631
+ .ermis-read-receipts__tooltip-item {
632
+ display: flex;
633
+ align-items: center;
634
+ gap: var(--ermis-spacing-sm, 8px);
635
+ }
636
+
637
+ .ermis-read-receipts__tooltip-info {
638
+ display: flex;
639
+ flex-direction: column;
640
+ gap: 1px;
641
+ min-width: 0;
642
+ }
643
+
644
+ .ermis-read-receipts__tooltip-name {
645
+ font-size: var(--ermis-font-size-xs, 0.75rem);
646
+ color: var(--ermis-text-primary, #e0e0e0);
647
+ white-space: nowrap;
648
+ overflow: hidden;
649
+ text-overflow: ellipsis;
650
+ }
651
+
652
+ .ermis-read-receipts__tooltip-time {
653
+ font-size: 0.625rem;
654
+ color: var(--ermis-text-muted, #888);
655
+ white-space: nowrap;
656
+ }