@rt-tools/ui-kit-v2 0.5.0 → 0.6.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 (103) hide show
  1. package/README.md +71 -0
  2. package/fesm2022/rt-tools-ui-kit-v2.mjs +166 -166
  3. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
  4. package/package.json +1 -1
  5. package/rt-tools-ui-kit-v2-0.6.0.tgz +0 -0
  6. package/src/lib/components/aside/_rt-aside-overlay.scss +73 -71
  7. package/src/lib/components/aside/footer/rt-aside-footer.component.scss +20 -16
  8. package/src/lib/components/aside/header/rt-aside-header.component.scss +72 -70
  9. package/src/lib/components/aside/rt-aside.component.scss +107 -105
  10. package/src/lib/components/aside/unsaved-dialog/rt-aside-unsaved-dialog.component.scss +33 -31
  11. package/src/lib/components/aside-section/rt-aside-section.component.scss +27 -23
  12. package/src/lib/components/autocomplete/rt-autocomplete.component.scss +124 -118
  13. package/src/lib/components/bar-list/rt-bar-list.component.scss +85 -81
  14. package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +64 -57
  15. package/src/lib/components/button/rt-button.directive.scss +319 -280
  16. package/src/lib/components/calendar/rt-calendar.component.scss +106 -102
  17. package/src/lib/components/card/rt-card.component.scss +53 -45
  18. package/src/lib/components/chat/rt-chat.component.scss +312 -306
  19. package/src/lib/components/checkbox/rt-checkbox.component.scss +61 -54
  20. package/src/lib/components/collapsible-text/rt-collapsible-text.component.scss +36 -34
  21. package/src/lib/components/confirm-popover/rt-confirm-popover.component.scss +36 -30
  22. package/src/lib/components/container/rt-container.component.scss +91 -87
  23. package/src/lib/components/counter/rt-counter.component.scss +14 -12
  24. package/src/lib/components/counter-row/rt-counter-row.component.scss +31 -27
  25. package/src/lib/components/date-picker/rt-date-picker.component.scss +73 -71
  26. package/src/lib/components/delta-view/rt-delta-view.component.scss +27 -25
  27. package/src/lib/components/detail-list/rt-detail-list.component.scss +8 -6
  28. package/src/lib/components/detail-list/rt-detail-row.component.scss +18 -16
  29. package/src/lib/components/dialog/footer/rt-dialog-footer.component.scss +19 -17
  30. package/src/lib/components/dialog/header/rt-dialog-header.component.scss +27 -25
  31. package/src/lib/components/dialog/rt-dialog.component.scss +59 -56
  32. package/src/lib/components/download-link/rt-download-link.component.scss +32 -27
  33. package/src/lib/components/empty-state/rt-empty-state.component.scss +50 -46
  34. package/src/lib/components/field/rt-field.component.scss +63 -61
  35. package/src/lib/components/file-card/rt-file-card.component.scss +84 -78
  36. package/src/lib/components/file-drop/rt-file-drop.component.scss +83 -77
  37. package/src/lib/components/file-input/rt-file-input.component.scss +20 -18
  38. package/src/lib/components/file-list/rt-file-list.component.scss +9 -7
  39. package/src/lib/components/filter-control/rt-filter-control.component.scss +16 -14
  40. package/src/lib/components/header/rt-header.component.scss +61 -55
  41. package/src/lib/components/icon/rt-icon.component.scss +14 -12
  42. package/src/lib/components/icon-button/CONTEXT.md +4 -2
  43. package/src/lib/components/icon-button/rt-icon-button.component.scss +128 -112
  44. package/src/lib/components/info-item/rt-info-item.component.scss +38 -36
  45. package/src/lib/components/input/rt-input.component.scss +102 -98
  46. package/src/lib/components/input-number/rt-input-number.component.scss +84 -82
  47. package/src/lib/components/live-badge/rt-live-badge.component.scss +27 -23
  48. package/src/lib/components/logo/rt-logo.component.scss +54 -52
  49. package/src/lib/components/menu/rt-menu-confirm-dialog.component.scss +30 -28
  50. package/src/lib/components/menu/rt-menu-item.component.scss +47 -42
  51. package/src/lib/components/menu/rt-menu.component.scss +23 -15
  52. package/src/lib/components/message/rt-message.component.scss +53 -49
  53. package/src/lib/components/message-composer/rt-message-composer.component.scss +55 -49
  54. package/src/lib/components/money-list/rt-money-list.component.scss +13 -9
  55. package/src/lib/components/money-list/rt-money-row.component.scss +23 -19
  56. package/src/lib/components/multiselect/rt-multiselect.component.scss +169 -161
  57. package/src/lib/components/night-grid/rt-night-grid.component.scss +47 -42
  58. package/src/lib/components/note/rt-note.component.scss +15 -11
  59. package/src/lib/components/notifications-bell/rt-notifications-bell.component.scss +34 -27
  60. package/src/lib/components/page-header/rt-page-header-mobile.scss +142 -134
  61. package/src/lib/components/page-header/rt-page-header-submenu.scss +130 -123
  62. package/src/lib/components/page-header/rt-page-header.component.scss +221 -210
  63. package/src/lib/components/pagination/rt-pagination.component.scss +88 -81
  64. package/src/lib/components/photo-viewer/rt-photo-viewer.component.scss +109 -105
  65. package/src/lib/components/rich-editor/rt-rich-editor.component.scss +63 -59
  66. package/src/lib/components/section-nav/rt-section-nav.component.scss +53 -47
  67. package/src/lib/components/select/rt-select.component.scss +146 -138
  68. package/src/lib/components/skeleton/rt-skeleton.component.scss +50 -41
  69. package/src/lib/components/skeleton-wrapper/rt-skeleton-wrapper.component.scss +8 -6
  70. package/src/lib/components/spinner/rt-spinner.component.scss +35 -32
  71. package/src/lib/components/split-button/rt-split-button.component.scss +74 -62
  72. package/src/lib/components/stat-tile/rt-stat-tile.component.scss +95 -91
  73. package/src/lib/components/stepper/rt-stepper.component.scss +107 -101
  74. package/src/lib/components/table/copy-cell/rt-copy-cell.component.scss +34 -30
  75. package/src/lib/components/table/rt-table.component.scss +260 -252
  76. package/src/lib/components/table/settings-aside/rt-table-settings-aside.component.scss +7 -5
  77. package/src/lib/components/table/settings-panel/rt-table-settings-panel.component.scss +71 -61
  78. package/src/lib/components/table/sort-header/rt-table-sort-header.component.scss +31 -29
  79. package/src/lib/components/tabs/rt-tabs.component.scss +184 -175
  80. package/src/lib/components/tag/rt-tag.component.scss +97 -92
  81. package/src/lib/components/textarea/rt-textarea.component.scss +62 -60
  82. package/src/lib/components/theme-toggle/rt-theme-toggle.component.scss +7 -5
  83. package/src/lib/components/thread-list/rt-thread-list.component.scss +221 -212
  84. package/src/lib/components/timeline/rt-timeline.component.scss +82 -76
  85. package/src/lib/components/toast/rt-toast.component.scss +169 -160
  86. package/src/lib/components/toast/rt-toaster.component.scss +37 -35
  87. package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +129 -122
  88. package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +97 -91
  89. package/src/lib/components/toolbar/rt-toolbar.component.scss +56 -54
  90. package/src/lib/components/tooltip/rt-tooltip.component.scss +20 -15
  91. package/src/lib/components/welcome-dialog/rt-welcome-dialog.component.scss +46 -44
  92. package/src/lib/components/workspace/rt-workspace.component.scss +139 -131
  93. package/src/lib/components/workspace-details/rt-workspace-details.component.scss +105 -101
  94. package/src/styles/_index.scss +4 -0
  95. package/src/styles/_layers.scss +22 -0
  96. package/src/styles/_login.scss +87 -85
  97. package/src/styles/_mixins.scss +1 -1
  98. package/src/styles/_primitives.scss +126 -67
  99. package/src/styles/_scrollbar.scss +21 -19
  100. package/src/styles/_semantic.scss +140 -56
  101. package/src/styles/_theme-dark.scss +60 -27
  102. package/styles/tokens.css +628 -408
  103. package/rt-tools-ui-kit-v2-0.5.0.tgz +0 -0
@@ -1,366 +1,372 @@
1
- .rt-chat {
2
- display: flex;
3
- flex-direction: column;
4
-
5
- // Встроенная drop-обёртка несёт колоночную раскладку чата (тред/композер
6
- // стопкой) и служит позиционным якорем для drag-оверлея. Тред/композер
7
- // проецируются внутрь, BEM-контекст `rt-chat` сохраняется (DI декларации).
8
- > .rt-file-drop {
9
- display: flex;
10
- flex: 1 1 auto;
11
- flex-direction: column;
12
- gap: var(--rt-space-3);
13
- min-block-size: 0;
14
- }
15
-
16
- // Полноэкранный режим — overlay поверх страницы. Чат заполняет вьюпорт как
17
- // flex-колонка: скроллится только тред, а композер и футер (доменные действия
18
- // потребителя) остаются прижаты к низу и всегда видны. Раньше overflow-y был
19
- // на всём чате — тред рос на все сообщения и выталкивал композер за экран.
20
- // Собственный фон нужен только здесь: в обычном режиме фон даёт потребитель.
21
- &--expanded {
22
- position: fixed;
23
- z-index: var(--rt-z-modal);
24
- box-sizing: border-box;
25
- padding: var(--rt-space-md);
26
- background: var(--rt-color-bg-surface);
27
- inset: 0;
28
- }
29
-
30
- &--expanded > .rt-file-drop {
31
- block-size: 100%;
32
-
33
- // На широких экранах чат не растягивается на весь вьюпорт: тред и
34
- // композер иначе разрежены. Свыше 1440px фиксируем колонку по центру.
35
- @media (width >= 1441px) {
36
- inline-size: 1000px;
37
- margin-inline: auto;
38
- max-inline-size: 100%;
39
- }
40
- }
41
-
42
- &--expanded &__thread-viewport {
43
- flex: 1 1 auto;
44
- min-block-size: 0;
45
- }
46
-
47
- &--expanded &__thread {
48
- max-height: none;
49
- }
50
-
51
- // Fill-режим: чат занимает всю высоту контейнера, тред растягивается на
52
- // свободное место, композер остаётся прижатым к низу.
53
- &--fill {
54
- block-size: 100%;
55
- }
56
-
57
- &--fill &__thread-viewport {
58
- flex: 1 1 auto;
59
- min-block-size: 0;
60
- }
61
-
62
- &--fill &__thread {
63
- max-height: none;
64
- }
65
-
66
- &__title {
67
- margin: 0;
68
- color: var(--rt-color-text-primary);
69
- font-family: var(--rt-font-family-sans);
70
- font-size: var(--rt-text-md);
71
- font-weight: var(--rt-font-weight-bold);
72
- letter-spacing: var(--rt-letter-spacing-wide);
73
- line-height: var(--rt-leading-snug);
74
- }
75
-
76
- &__thread-viewport {
77
- position: relative;
78
- display: flex;
79
- flex-direction: column;
80
-
81
- // Пузыри меряют максимальную ширину в процентах от треда: без contain
82
- // длинное неразрывное слово сначала распирает тред, и только потом от
83
- // него считаются проценты — лента уезжает по горизонтали.
84
- contain: inline-size;
85
- min-block-size: 0;
86
- }
1
+ @layer rt-kit.components {
2
+ .rt-chat {
3
+ --rt-chat-bubble-radius: var(--rt-radius-lg);
4
+ --rt-chat-message-border-width: var(--rt-border-width-thin);
5
+ --rt-chat-transition-duration: var(--rt-duration-fast);
87
6
 
88
- &__thread {
89
7
  display: flex;
90
- max-height: 280px;
91
- flex: 1 1 auto;
92
8
  flex-direction: column;
93
- gap: var(--rt-space-4);
94
- min-block-size: 0;
95
- overflow-y: auto;
96
9
 
97
- &--frozen {
98
- overflow-y: hidden;
10
+ // Встроенная drop-обёртка несёт колоночную раскладку чата (тред/композер
11
+ // стопкой) и служит позиционным якорем для drag-оверлея. Тред/композер
12
+ // проецируются внутрь, BEM-контекст `rt-chat` сохраняется (DI декларации).
13
+ > .rt-file-drop {
14
+ display: flex;
15
+ flex: 1 1 auto;
16
+ flex-direction: column;
17
+ gap: var(--rt-space-4);
18
+ min-block-size: 0;
99
19
  }
100
- }
101
20
 
102
- &__thread-overlay {
103
- position: absolute;
104
- z-index: 1;
105
- display: flex;
106
- align-items: center;
107
- justify-content: center;
108
- background: color-mix(in srgb, var(--rt-color-bg-surface) 60%, transparent);
109
- inset: 0;
110
- }
21
+ // Полноэкранный режим — overlay поверх страницы. Чат заполняет вьюпорт как
22
+ // flex-колонка: скроллится только тред, а композер и футер (доменные действия
23
+ // потребителя) остаются прижаты к низу и всегда видны. Раньше overflow-y был
24
+ // на всём чате — тред рос на все сообщения и выталкивал композер за экран.
25
+ // Собственный фон нужен только здесь: в обычном режиме фон даёт потребитель.
26
+ &--expanded {
27
+ position: fixed;
28
+ z-index: var(--rt-z-modal);
29
+ box-sizing: border-box;
30
+ padding: var(--rt-space-md);
31
+ background: var(--rt-color-bg-surface);
32
+ inset: 0;
33
+ }
111
34
 
112
- &__footer-slot {
113
- display: flex;
114
- flex-direction: column;
35
+ &--expanded > .rt-file-drop {
36
+ block-size: 100%;
115
37
 
116
- &:empty {
117
- display: none;
38
+ // На широких экранах чат не растягивается на весь вьюпорт: тред и
39
+ // композер иначе разрежены. Свыше 1440px фиксируем колонку по центру.
40
+ @media (width >= 1441px) {
41
+ inline-size: 1000px;
42
+ margin-inline: auto;
43
+ max-inline-size: 100%;
44
+ }
118
45
  }
119
46
 
120
- &--blocked {
121
- opacity: 0.6;
122
- pointer-events: none;
47
+ &--expanded &__thread-viewport {
48
+ flex: 1 1 auto;
49
+ min-block-size: 0;
123
50
  }
124
- }
125
-
126
- // Строка сообщения — общий hover-контейнер пузыря и боковой кнопки удаления.
127
- // Ховер отслеживается по всей строке, поэтому переход курсора с текста на
128
- // кнопку (она снаружи пузыря) непрерывен: кнопка не пропадает в зазоре.
129
- &__message-row {
130
- display: flex;
131
- max-width: min(80%, 480px);
132
- align-items: center;
133
51
 
134
- // Входящие — влево, свои — вправо. max-width на строке: пузырь + кнопка
135
- // вместе не растягиваются через весь тред.
136
- align-self: flex-start;
137
- gap: var(--rt-space-1-5);
52
+ &--expanded &__thread {
53
+ max-height: none;
54
+ }
138
55
 
139
- &--own {
140
- align-self: flex-end;
56
+ // Fill-режим: чат занимает всю высоту контейнера, тред растягивается на
57
+ // свободное место, композер остаётся прижатым к низу.
58
+ &--fill {
59
+ block-size: 100%;
141
60
  }
142
61
 
143
- // Кнопка проявляется по наведению/фокусу в пределах всей строки.
144
- &:hover .rt-chat__message-delete,
145
- &:focus-within .rt-chat__message-delete {
146
- opacity: 1;
147
- pointer-events: auto;
62
+ &--fill &__thread-viewport {
63
+ flex: 1 1 auto;
64
+ min-block-size: 0;
148
65
  }
149
- }
150
66
 
151
- &__message {
152
- display: flex;
153
- min-width: 0;
67
+ &--fill &__thread {
68
+ max-height: none;
69
+ }
154
70
 
155
- // grow:0 — пузырь обнимает контент (короткие не растягиваются); shrink:1 +
156
- // min-width:0 — длинный текст переносится внутри строки, не распирая её.
157
- flex: 0 1 auto;
158
- flex-direction: column;
159
- padding: var(--rt-space-2-5);
71
+ &__title {
72
+ margin: 0;
73
+ color: var(--rt-color-text-primary);
74
+ font-family: var(--rt-font-family-sans);
75
+ font-size: var(--rt-text-md);
76
+ font-weight: var(--rt-font-weight-bold);
77
+ letter-spacing: var(--rt-letter-spacing-wide);
78
+ line-height: var(--rt-leading-snug);
79
+ }
160
80
 
161
- // Срезанный угол со стороны автора заменяет «хвостик» пузыря: направление
162
- // видно даже когда соседние сообщения одного цвета идут подряд.
163
- border-radius: var(--rt-radius-lg) var(--rt-radius-lg) var(--rt-radius-lg) 0;
164
- background: var(--rt-chat-bubble-in-bg);
165
- gap: var(--rt-space-2-5);
81
+ &__thread-viewport {
82
+ position: relative;
83
+ display: flex;
84
+ flex-direction: column;
166
85
 
167
- &--own {
168
- border-radius: var(--rt-radius-lg) var(--rt-radius-lg) 0 var(--rt-radius-lg);
169
- background: var(--rt-chat-bubble-own-bg);
86
+ // Пузыри меряют максимальную ширину в процентах от треда: без contain
87
+ // длинное неразрывное слово сначала распирает тред, и только потом от
88
+ // него считаются проценты — лента уезжает по горизонтали.
89
+ contain: inline-size;
90
+ min-block-size: 0;
170
91
  }
171
92
 
172
- // Удалённое сообщение остаётся в ленте, но приглушено и с пунктиром.
173
- &--deleted {
174
- border: var(--rt-border-width-thin) dashed var(--rt-color-border-default);
175
- background: transparent;
93
+ &__thread {
94
+ display: flex;
95
+ max-height: 280px;
96
+ flex: 1 1 auto;
97
+ flex-direction: column;
98
+ gap: var(--rt-space-4);
99
+ min-block-size: 0;
100
+ overflow-y: auto;
101
+
102
+ &--frozen {
103
+ overflow-y: hidden;
104
+ }
176
105
  }
177
- }
178
106
 
179
- &__message-author {
180
- margin: 0;
181
- color: var(--rt-chat-bubble-in-author);
182
- font-size: var(--rt-text-2xs);
183
- font-weight: var(--rt-font-weight-bold);
184
- letter-spacing: var(--rt-letter-spacing-wide);
185
- line-height: var(--rt-leading-snug);
186
- }
107
+ &__thread-overlay {
108
+ position: absolute;
109
+ z-index: 1;
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ background: color-mix(in srgb, var(--rt-color-bg-surface) 60%, transparent);
114
+ inset: 0;
115
+ }
187
116
 
188
- &__message--own &__message-author {
189
- color: var(--rt-chat-bubble-own-author);
190
- }
117
+ &__footer-slot {
118
+ display: flex;
119
+ flex-direction: column;
191
120
 
192
- &__message-text {
193
- margin: 0;
194
- color: var(--rt-color-text-primary);
195
- font-size: var(--rt-text-xs);
196
- font-weight: var(--rt-font-weight-regular);
197
- line-height: var(--rt-leading-snug);
198
- white-space: pre-wrap;
121
+ &:empty {
122
+ display: none;
123
+ }
199
124
 
200
- // Плейсхолдер удалённого сообщения — курсив, приглушённый цвет.
201
- &--deleted {
202
- color: var(--rt-color-text-muted);
203
- font-style: italic;
125
+ &--blocked {
126
+ opacity: 0.6;
127
+ pointer-events: none;
128
+ }
204
129
  }
205
- }
206
130
 
207
- // Боковая кнопка удаления: flex-сосед пузыря (не наезжает на текст), место
208
- // под неё зарезервировано всегда (opacity, не display) — тред не «прыгает»
209
- // при наведении. Проявляется по ховеру строки (см. `&__message-row`).
210
- &__message-delete {
211
- flex: 0 0 auto;
212
- opacity: 0;
213
- pointer-events: none;
214
- transition: opacity var(--rt-duration-fast) ease;
215
- }
216
-
217
- &__message-attachment {
218
- display: block;
219
- }
131
+ // Строка сообщения — общий hover-контейнер пузыря и боковой кнопки удаления.
132
+ // Ховер отслеживается по всей строке, поэтому переход курсора с текста на
133
+ // кнопку (она снаружи пузыря) непрерывен: кнопка не пропадает в зазоре.
134
+ &__message-row {
135
+ display: flex;
136
+ max-width: min(80%, 480px);
137
+ align-items: center;
138
+
139
+ // Входящие — влево, свои — вправо. max-width на строке: пузырь + кнопка
140
+ // вместе не растягиваются через весь тред.
141
+ align-self: flex-start;
142
+ gap: var(--rt-space-2);
143
+
144
+ &--own {
145
+ align-self: flex-end;
146
+ }
147
+
148
+ // Кнопка проявляется по наведению/фокусу в пределах всей строки.
149
+ &:hover .rt-chat__message-delete,
150
+ &:focus-within .rt-chat__message-delete {
151
+ opacity: 1;
152
+ pointer-events: auto;
153
+ }
154
+ }
220
155
 
221
- &__message-footer {
222
- display: flex;
223
- align-items: center;
224
- gap: var(--rt-space-1);
225
- }
156
+ &__message {
157
+ display: flex;
158
+ min-width: 0;
159
+
160
+ // grow:0 — пузырь обнимает контент (короткие не растягиваются); shrink:1 +
161
+ // min-width:0 — длинный текст переносится внутри строки, не распирая её.
162
+ flex: 0 1 auto;
163
+ flex-direction: column;
164
+ padding: var(--rt-space-2);
165
+
166
+ // Срезанный угол со стороны автора заменяет «хвостик» пузыря: направление
167
+ // видно даже когда соседние сообщения одного цвета идут подряд.
168
+ border-radius: var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;
169
+ background: var(--rt-chat-bubble-in-bg);
170
+ gap: var(--rt-space-2);
171
+
172
+ &--own {
173
+ border-radius: var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);
174
+ background: var(--rt-chat-bubble-own-bg);
175
+ }
176
+
177
+ // Удалённое сообщение остаётся в ленте, но приглушено и с пунктиром.
178
+ &--deleted {
179
+ border: var(--rt-chat-message-border-width) dashed var(--rt-color-border-default);
180
+ background: transparent;
181
+ }
182
+ }
226
183
 
227
- &__message-date {
228
- color: var(--rt-chat-bubble-date);
229
- font-size: var(--rt-text-xs);
230
- line-height: var(--rt-leading-none);
231
- }
184
+ &__message-author {
185
+ margin: 0;
186
+ color: var(--rt-chat-bubble-in-author);
187
+ font-size: var(--rt-text-2xs);
188
+ font-weight: var(--rt-font-weight-bold);
189
+ letter-spacing: var(--rt-letter-spacing-wide);
190
+ line-height: var(--rt-leading-snug);
191
+ }
232
192
 
233
- // Пер-месседж статус своего сообщения: часы / двойной чек / «!»+retry.
234
- // sending и sent приглушены — цветом выделены только два состояния, о
235
- // которых стоит знать: прочитано (синий) и не ушло (красный).
236
- &__message-status {
237
- display: inline-flex;
238
- align-items: center;
239
- color: var(--rt-color-text-muted);
240
- gap: var(--rt-space-0-5);
193
+ &__message--own &__message-author {
194
+ color: var(--rt-chat-bubble-own-author);
195
+ }
241
196
 
242
- &--status--read {
243
- color: var(--rt-chat-status-read);
197
+ &__message-text {
198
+ margin: 0;
199
+ color: var(--rt-color-text-primary);
200
+ font-size: var(--rt-text-xs);
201
+ font-weight: var(--rt-font-weight-regular);
202
+ line-height: var(--rt-leading-snug);
203
+ white-space: pre-wrap;
204
+
205
+ // Плейсхолдер удалённого сообщения — курсив, приглушённый цвет.
206
+ &--deleted {
207
+ color: var(--rt-color-text-muted);
208
+ font-style: italic;
209
+ }
244
210
  }
245
211
 
246
- &--status--failed {
247
- color: var(--rt-color-state-danger);
212
+ // Боковая кнопка удаления: flex-сосед пузыря (не наезжает на текст), место
213
+ // под неё зарезервировано всегда (opacity, не display) — тред не «прыгает»
214
+ // при наведении. Проявляется по ховеру строки (см. `&__message-row`).
215
+ &__message-delete {
216
+ flex: 0 0 auto;
217
+ opacity: 0;
218
+ pointer-events: none;
219
+ transition: opacity var(--rt-chat-transition-duration) ease;
248
220
  }
249
- }
250
221
 
251
- &__status-icon {
252
- font-size: var(--rt-text-sm);
253
- }
222
+ &__message-attachment {
223
+ display: block;
224
+ }
254
225
 
255
- // Скелетон-пузырь повторяет геометрию `&__message`, чтобы подмена на реальное
256
- // сообщение не сдвигала тред.
257
- &__message-skeleton {
258
- display: flex;
259
- max-width: min(80%, 480px);
260
- flex-direction: column;
261
- align-self: flex-start;
262
- padding: var(--rt-space-2-5);
263
- border-radius: var(--rt-radius-lg) var(--rt-radius-lg) var(--rt-radius-lg) 0;
264
- background: var(--rt-chat-bubble-in-bg);
265
- gap: var(--rt-space-1);
226
+ &__message-footer {
227
+ display: flex;
228
+ align-items: center;
229
+ gap: var(--rt-space-1);
230
+ }
266
231
 
267
- &--own {
268
- align-self: flex-end;
269
- border-radius: var(--rt-radius-lg) var(--rt-radius-lg) 0 var(--rt-radius-lg);
270
- background: var(--rt-chat-bubble-own-bg);
232
+ &__message-date {
233
+ color: var(--rt-chat-bubble-date);
234
+ font-size: var(--rt-text-xs);
235
+ line-height: var(--rt-leading-none);
271
236
  }
272
- }
273
237
 
274
- &__skeleton-line {
275
- display: block;
276
- }
238
+ // Пер-месседж статус своего сообщения: часы / двойной чек / «!»+retry.
239
+ // sending и sent приглушены — цветом выделены только два состояния, о
240
+ // которых стоит знать: прочитано (синий) и не ушло (красный).
241
+ &__message-status {
242
+ display: inline-flex;
243
+ align-items: center;
244
+ color: var(--rt-color-text-muted);
245
+ gap: var(--rt-space-0-5);
277
246
 
278
- // Кнопка-ссылка (привязка Telegram) внутри пузыря сообщения — прижата влево
279
- // под текстом. Класс — на span'е, а не на rtButton: host-class rt-button затёр
280
- // бы rtElem. Вид (outlined) даёт сам rtButton.
281
- &__message-deeplink {
282
- display: flex;
283
- justify-content: flex-start;
284
- margin-top: var(--rt-space-1);
285
- }
247
+ &--status--read {
248
+ color: var(--rt-chat-status-read);
249
+ }
286
250
 
287
- // Композер (и note-замена) отбиваем от ленты сильнее общего gap'а, чтобы поле
288
- // ввода визуально отделялось от последнего сообщения.
289
- &__composer,
290
- &__composer-rich,
291
- &__reply-block {
292
- margin-top: var(--rt-space-3);
293
- }
251
+ &--status--failed {
252
+ color: var(--rt-color-state-danger);
253
+ }
254
+ }
294
255
 
295
- &__composer {
296
- display: flex;
297
- flex-direction: column;
298
- gap: var(--rt-space-2-5);
299
- }
256
+ &__status-icon {
257
+ font-size: var(--rt-text-sm);
258
+ }
300
259
 
301
- &__composer-files {
302
- display: flex;
303
- flex-wrap: wrap;
304
- gap: var(--rt-space-2);
305
- }
260
+ // Скелетон-пузырь повторяет геометрию `&__message`, чтобы подмена на реальное
261
+ // сообщение не сдвигала тред.
262
+ &__message-skeleton {
263
+ display: flex;
264
+ max-width: min(80%, 480px);
265
+ flex-direction: column;
266
+ align-self: flex-start;
267
+ padding: var(--rt-space-2);
268
+ border-radius: var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;
269
+ background: var(--rt-chat-bubble-in-bg);
270
+ gap: var(--rt-space-1);
271
+
272
+ &--own {
273
+ align-self: flex-end;
274
+ border-radius: var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);
275
+ background: var(--rt-chat-bubble-own-bg);
276
+ }
277
+ }
306
278
 
307
- // Поле ввода — одна рамка на скрепку и текст: скрепка снаружи читалась бы
308
- // как отдельное действие, а не как часть сообщения. Геометрия взята из
309
- // input-токенов, поэтому поле совпадает с остальными контролами формы.
310
- &__composer-field {
311
- display: flex;
312
- box-sizing: border-box;
313
- align-items: center;
314
- border: var(--rt-input-border-width) solid var(--rt-input-color-border);
315
- border-radius: var(--rt-input-radius);
316
- background-color: var(--rt-input-color-bg);
317
- gap: var(--rt-space-1);
318
- min-block-size: var(--rt-input-height);
319
- padding-inline: var(--rt-input-padding-x);
320
- transition: var(--rt-input-transition);
279
+ &__skeleton-line {
280
+ display: block;
281
+ }
321
282
 
322
- // Подсветка на всём поле, а не на textarea: рамка принадлежит обёртке.
323
- &:focus-within {
324
- border-color: var(--rt-input-color-border-focus);
325
- box-shadow: var(--rt-input-focus-shadow);
283
+ // Кнопка-ссылка (привязка Telegram) внутри пузыря сообщения — прижата влево
284
+ // под текстом. Класс — на span'е, а не на rtButton: host-class rt-button затёр
285
+ // бы rtElem. Вид (outlined) даёт сам rtButton.
286
+ &__message-deeplink {
287
+ display: flex;
288
+ justify-content: flex-start;
289
+ margin-top: var(--rt-space-1);
326
290
  }
327
291
 
328
- &--attach {
329
- padding-inline-start: var(--rt-space-1);
292
+ // Композер (и note-замена) отбиваем от ленты сильнее общего gap'а, чтобы поле
293
+ // ввода визуально отделялось от последнего сообщения.
294
+ &__composer,
295
+ &__composer-rich,
296
+ &__reply-block {
297
+ margin-top: var(--rt-space-4);
330
298
  }
331
- }
332
299
 
333
- &__composer-input {
334
- // Именно content-box: cdkTextareaAutosize задаёт height по высоте строк,
335
- // не прибавляя вертикальные поля. С глобальным border-box поле выходит
336
- // ровно на одну строку меньше, и текст режется нижней границей.
337
- box-sizing: content-box;
338
- flex: 1 1 auto;
339
- border: 0;
340
- background: transparent;
341
- color: var(--rt-input-color-text);
342
- font-family: inherit;
343
- font-size: var(--rt-input-font-size);
344
- inline-size: 100%;
345
- line-height: var(--rt-textarea-line-height);
346
- padding-block: var(--rt-space-2);
347
- resize: none;
300
+ &__composer {
301
+ display: flex;
302
+ flex-direction: column;
303
+ gap: var(--rt-space-2);
304
+ }
348
305
 
349
- &::placeholder {
350
- color: var(--rt-input-color-text-placeholder);
351
- opacity: 1;
306
+ &__composer-files {
307
+ display: flex;
308
+ flex-wrap: wrap;
309
+ gap: var(--rt-space-2);
352
310
  }
353
311
 
354
- &:focus-visible {
355
- outline: none;
312
+ // Поле ввода — одна рамка на скрепку и текст: скрепка снаружи читалась бы
313
+ // как отдельное действие, а не как часть сообщения. Геометрия взята из
314
+ // input-токенов, поэтому поле совпадает с остальными контролами формы.
315
+ &__composer-field {
316
+ display: flex;
317
+ box-sizing: border-box;
318
+ align-items: center;
319
+ border: var(--rt-input-border-width) solid var(--rt-input-color-border);
320
+ border-radius: var(--rt-input-radius);
321
+ background-color: var(--rt-input-color-bg);
322
+ gap: var(--rt-space-1);
323
+ min-block-size: var(--rt-input-height);
324
+ padding-inline: var(--rt-input-padding-x);
325
+ transition: var(--rt-input-transition);
326
+
327
+ // Подсветка на всём поле, а не на textarea: рамка принадлежит обёртке.
328
+ &:focus-within {
329
+ border-color: var(--rt-input-color-border-focus);
330
+ box-shadow: var(--rt-input-focus-shadow);
331
+ }
332
+
333
+ &--attach {
334
+ padding-inline-start: var(--rt-space-1);
335
+ }
356
336
  }
357
337
 
358
- &:disabled {
359
- cursor: not-allowed;
338
+ &__composer-input {
339
+ // Именно content-box: cdkTextareaAutosize задаёт height по высоте строк,
340
+ // не прибавляя вертикальные поля. С глобальным border-box поле выходит
341
+ // ровно на одну строку меньше, и текст режется нижней границей.
342
+ box-sizing: content-box;
343
+ flex: 1 1 auto;
344
+ border: 0;
345
+ background: transparent;
346
+ color: var(--rt-input-color-text);
347
+ font-family: inherit;
348
+ font-size: var(--rt-input-font-size);
349
+ inline-size: 100%;
350
+ line-height: var(--rt-textarea-line-height);
351
+ padding-block: var(--rt-space-2);
352
+ resize: none;
353
+
354
+ &::placeholder {
355
+ color: var(--rt-input-color-text-placeholder);
356
+ opacity: 1;
357
+ }
358
+
359
+ &:focus-visible {
360
+ outline: none;
361
+ }
362
+
363
+ &:disabled {
364
+ cursor: not-allowed;
365
+ }
360
366
  }
361
- }
362
367
 
363
- &__composer-send {
364
- inline-size: 100%;
368
+ &__composer-send {
369
+ inline-size: 100%;
370
+ }
365
371
  }
366
372
  }