@capillarytech/creatives-library 8.0.329 → 8.0.330-alpha.1

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 (89) hide show
  1. package/constants/unified.js +4 -0
  2. package/package.json +1 -1
  3. package/utils/commonUtils.js +19 -1
  4. package/utils/templateVarUtils.js +35 -6
  5. package/utils/tests/tagValidations.test.js +20 -0
  6. package/utils/tests/templateVarUtils.test.js +44 -0
  7. package/v2Components/CapActionButton/constants.js +7 -0
  8. package/v2Components/CapActionButton/index.js +167 -109
  9. package/v2Components/CapActionButton/index.scss +157 -6
  10. package/v2Components/CapActionButton/messages.js +19 -3
  11. package/v2Components/CapActionButton/tests/index.test.js +41 -17
  12. package/v2Components/CapTagList/index.js +28 -23
  13. package/v2Components/CapTagList/style.scss +29 -0
  14. package/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
  15. package/v2Components/CapTagListWithInput/index.js +4 -0
  16. package/v2Components/CapWhatsappCTA/index.js +2 -0
  17. package/v2Components/CommonTestAndPreview/ExistingCustomerModal.js +1 -0
  18. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +160 -15
  19. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +18 -0
  20. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +323 -77
  21. package/v2Components/CommonTestAndPreview/index.js +49 -57
  22. package/v2Components/CommonTestAndPreview/messages.js +8 -0
  23. package/v2Components/CommonTestAndPreview/reducer.js +3 -1
  24. package/v2Components/CommonTestAndPreview/sagas.js +2 -1
  25. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
  26. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
  27. package/v2Components/FormBuilder/index.js +1 -0
  28. package/v2Components/HtmlEditor/HTMLEditor.js +6 -1
  29. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
  30. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +927 -2
  31. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +3 -0
  32. package/v2Components/SmsFallback/smsFallbackUtils.js +14 -3
  33. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +16 -0
  34. package/v2Components/TemplatePreview/_templatePreview.scss +33 -23
  35. package/v2Components/TemplatePreview/constants.js +2 -0
  36. package/v2Components/TemplatePreview/index.js +143 -28
  37. package/v2Components/TemplatePreview/tests/index.test.js +142 -0
  38. package/v2Components/TestAndPreviewSlidebox/index.js +5 -0
  39. package/v2Components/mockdata.js +1 -0
  40. package/v2Containers/BeeEditor/index.js +19 -1
  41. package/v2Containers/CreativesContainer/SlideBoxContent.js +28 -1
  42. package/v2Containers/CreativesContainer/index.js +9 -3
  43. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +5 -0
  44. package/v2Containers/Email/index.js +78 -39
  45. package/v2Containers/Email/reducer.js +2 -2
  46. package/v2Containers/Email/sagas.js +3 -1
  47. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -2
  48. package/v2Containers/Email/tests/sagas.test.js +230 -0
  49. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +6 -1
  50. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
  51. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +20 -2
  52. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
  53. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -1
  54. package/v2Containers/EmailWrapper/index.js +4 -0
  55. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
  56. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +9 -0
  57. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +1 -0
  58. package/v2Containers/MobilePush/Create/index.js +2 -0
  59. package/v2Containers/MobilePush/Edit/index.js +2 -0
  60. package/v2Containers/MobilepushWrapper/index.js +3 -1
  61. package/v2Containers/Rcs/constants.js +85 -7
  62. package/v2Containers/Rcs/index.js +1592 -156
  63. package/v2Containers/Rcs/index.js.rej +1336 -0
  64. package/v2Containers/Rcs/index.scss +191 -0
  65. package/v2Containers/Rcs/index.scss.rej +74 -0
  66. package/v2Containers/Rcs/messages.js +28 -2
  67. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +20 -0
  68. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +69178 -117691
  69. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +128 -0
  70. package/v2Containers/Rcs/tests/index.test.js +132 -94
  71. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +67 -0
  72. package/v2Containers/Rcs/tests/utils.test.js +276 -38
  73. package/v2Containers/Rcs/utils.js +130 -7
  74. package/v2Containers/Sms/Edit/index.js +2 -0
  75. package/v2Containers/SmsTrai/Edit/index.js +27 -0
  76. package/v2Containers/SmsTrai/Edit/messages.js +5 -0
  77. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
  78. package/v2Containers/SmsWrapper/index.js +2 -0
  79. package/v2Containers/TagList/index.js +73 -20
  80. package/v2Containers/TagList/messages.js +4 -0
  81. package/v2Containers/TagList/tests/TagList.test.js +124 -20
  82. package/v2Containers/TagList/tests/mockdata.js +17 -0
  83. package/v2Containers/Templates/_templates.scss +99 -0
  84. package/v2Containers/Templates/index.js +29 -14
  85. package/v2Containers/Viber/index.js +3 -0
  86. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -2
  87. package/v2Containers/WebPush/Create/index.js +10 -2
  88. package/v2Containers/Whatsapp/index.js +5 -0
  89. package/v2Containers/Zalo/index.js +2 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * UnifiedPreview Styles
5
- *
5
+ *
6
6
  * Consistent styling for preview across all channels
7
7
  */
8
8
 
@@ -12,23 +12,23 @@
12
12
  display: flex;
13
13
  flex-direction: column;
14
14
  overflow: hidden;
15
-
15
+
16
16
  // Preview Chrome wrapper (matches old TestAndPreviewSlidebox design)
17
17
  .preview-chrome {
18
18
  background: $CAP_WHITE;
19
19
  overflow: hidden;
20
-
20
+
21
21
  .preview-divider {
22
22
  margin: 0;
23
23
  }
24
-
24
+
25
25
  .preview-header {
26
26
  display: flex;
27
27
  justify-content: space-between;
28
28
  align-items: center;
29
29
  padding: $CAP_SPACE_08 $CAP_SPACE_16 $CAP_SPACE_06 $CAP_SPACE_16;
30
30
  background: $CAP_G09;
31
-
31
+
32
32
  .preview-for {
33
33
  font-size: $FONT_SIZE_M;
34
34
  color: #595959;
@@ -38,20 +38,20 @@
38
38
  margin-left: $CAP_SPACE_04;
39
39
  }
40
40
  }
41
-
41
+
42
42
  .device-toggle {
43
43
  display: flex;
44
44
  gap: $CAP_SPACE_08;
45
45
  background-color: #e0e0e0;
46
46
  padding: $CAP_SPACE_06 $CAP_SPACE_08;
47
47
  border-radius: $CAP_SPACE_08;
48
-
48
+
49
49
  .anticon {
50
50
  padding: $CAP_SPACE_04;
51
51
  border-radius: $CAP_SPACE_04;
52
52
  cursor: pointer;
53
53
  color: #595959;
54
-
54
+
55
55
  &.active {
56
56
  background-color: $CAP_WHITE;
57
57
  color: #262626;
@@ -62,19 +62,19 @@
62
62
  }
63
63
  }
64
64
 
65
- .unified-preview.unified-preview-rcs-tabs {
65
+ .unified-preview.unified-preview-rcs-tabs {
66
66
  .ant-tabs-nav {
67
67
  margin: 0;
68
68
  padding: 0 $CAP_SPACE_16;
69
69
  }
70
-
70
+
71
71
  // Prevent white hover/active backgrounds from default antd styles
72
72
  .ant-tabs-tab,
73
73
  .ant-tabs-tab:hover,
74
74
  .ant-tabs-tab-active {
75
75
  background: transparent;
76
76
  }
77
-
77
+
78
78
  .ant-tabs-tab-btn,
79
79
  .ant-tabs-tab-btn:hover,
80
80
  .ant-tabs-tab-btn:active {
@@ -94,25 +94,25 @@
94
94
  .preview-content-container-no-header {
95
95
  background-color: $CAP_WHITE;
96
96
  }
97
-
97
+
98
98
  // Device Frames
99
99
  .unified-preview-frame {
100
100
  width: 100%;
101
101
  display: flex;
102
102
  justify-content: center;
103
-
103
+
104
104
  .device-frame {
105
105
  background: $CAP_WHITE;
106
106
  border-radius: $CAP_SPACE_08;
107
107
  box-shadow: 0 $CAP_SPACE_04 $CAP_SPACE_12 rgba(0, 0, 0, 0.15);
108
108
  overflow: hidden;
109
109
  transition: all 0.3s ease;
110
-
110
+
111
111
  // Desktop Frame
112
112
  &.device-frame-desktop {
113
113
  width: 100%;
114
114
  min-height: 42.857rem;
115
-
115
+
116
116
  .desktop-chrome {
117
117
  height: $CAP_SPACE_40;
118
118
  background: $CAP_G12;
@@ -121,30 +121,30 @@
121
121
  align-items: center;
122
122
  padding: 0 $CAP_SPACE_12;
123
123
  gap: $CAP_SPACE_12;
124
-
124
+
125
125
  .chrome-dots {
126
126
  display: flex;
127
127
  gap: $CAP_SPACE_06;
128
-
128
+
129
129
  .dot {
130
130
  width: $CAP_SPACE_12;
131
131
  height: $CAP_SPACE_12;
132
132
  border-radius: 50%;
133
-
133
+
134
134
  &.dot-close {
135
135
  background: #ff5f56;
136
136
  }
137
-
137
+
138
138
  &.dot-minimize {
139
139
  background: #ffbd2e;
140
140
  }
141
-
141
+
142
142
  &.dot-maximize {
143
143
  background: #27c93f;
144
144
  }
145
145
  }
146
146
  }
147
-
147
+
148
148
  .chrome-address-bar {
149
149
  flex: 1;
150
150
  background: $CAP_WHITE;
@@ -154,25 +154,25 @@
154
154
  color: #8c8c8c;
155
155
  }
156
156
  }
157
-
157
+
158
158
  .device-content {
159
159
  min-height: 40rem;
160
160
  background: $CAP_WHITE;
161
161
  }
162
162
  }
163
-
163
+
164
164
  // Tablet Frame
165
165
  &.device-frame-tablet {
166
166
  width: 54.857rem;
167
167
  max-width: 90%;
168
-
168
+
169
169
  .tablet-chrome {
170
170
  height: $CAP_SPACE_24;
171
171
  background: #333333;
172
172
  display: flex;
173
173
  align-items: center;
174
174
  justify-content: center;
175
-
175
+
176
176
  .tablet-camera {
177
177
  width: $CAP_SPACE_08;
178
178
  height: $CAP_SPACE_08;
@@ -181,19 +181,19 @@
181
181
  border: $CAP_SPACE_01 solid #666666;
182
182
  }
183
183
  }
184
-
184
+
185
185
  .device-content {
186
186
  min-height: 73.143rem;
187
187
  background: $CAP_WHITE;
188
188
  }
189
-
189
+
190
190
  .tablet-footer {
191
191
  height: 3.571rem;
192
192
  background: #333333;
193
193
  display: flex;
194
194
  align-items: center;
195
195
  justify-content: center;
196
-
196
+
197
197
  .home-button {
198
198
  width: $CAP_SPACE_40;
199
199
  height: $CAP_SPACE_40;
@@ -203,19 +203,19 @@
203
203
  }
204
204
  }
205
205
  }
206
-
206
+
207
207
  // Mobile Frame
208
208
  &.device-frame-mobile {
209
209
  width: 26.786rem;
210
210
  max-width: 90%;
211
-
211
+
212
212
  .mobile-chrome {
213
213
  height: $CAP_SPACE_24;
214
214
  background: #000000;
215
215
  display: flex;
216
216
  align-items: center;
217
217
  justify-content: center;
218
-
218
+
219
219
  .mobile-notch {
220
220
  width: 10.714rem;
221
221
  height: 1.571rem;
@@ -223,19 +223,19 @@
223
223
  border-radius: 0 0 $CAP_SPACE_12 $CAP_SPACE_12;
224
224
  }
225
225
  }
226
-
226
+
227
227
  .device-content {
228
228
  min-height: 47.643rem;
229
229
  background: $CAP_WHITE;
230
230
  }
231
-
231
+
232
232
  .mobile-footer {
233
233
  height: $CAP_SPACE_24;
234
234
  background: #000000;
235
235
  display: flex;
236
236
  align-items: center;
237
237
  justify-content: center;
238
-
238
+
239
239
  .home-indicator {
240
240
  width: $CAP_SPACE_80;
241
241
  height: $CAP_SPACE_04;
@@ -247,7 +247,7 @@
247
247
  }
248
248
  }
249
249
  }
250
-
250
+
251
251
  // Channel Preview Placeholders (Phase 5)
252
252
  .channel-preview-placeholder {
253
253
  display: flex;
@@ -257,7 +257,7 @@
257
257
  padding: $CAP_SPACE_60 $CAP_SPACE_24;
258
258
  text-align: center;
259
259
  min-height: 28.571rem;
260
-
260
+
261
261
  .question-circle {
262
262
  font-size: $CAP_SPACE_48;
263
263
  color: $CAP_COLOR_16;
@@ -268,13 +268,13 @@
268
268
  font-weight: 600;
269
269
  color: #262626;
270
270
  }
271
-
271
+
272
272
  p {
273
273
  margin-top: $CAP_SPACE_08;
274
274
  font-size: $FONT_SIZE_M;
275
275
  color: #8c8c8c;
276
276
  }
277
-
277
+
278
278
  .preview-subject {
279
279
  margin-top: $CAP_SPACE_24;
280
280
  padding: $CAP_SPACE_12 $CAP_SPACE_16;
@@ -283,26 +283,26 @@
283
283
  text-align: left;
284
284
  width: 100%;
285
285
  max-width: 35.714rem;
286
-
286
+
287
287
  strong {
288
288
  color: #595959;
289
289
  margin-right: $CAP_SPACE_08;
290
290
  }
291
291
  }
292
-
292
+
293
293
  .preview-body-placeholder {
294
294
  margin-top: $CAP_SPACE_12;
295
295
  padding: $CAP_SPACE_08 $CAP_SPACE_12;
296
296
  background: #fafafa;
297
297
  border: $CAP_SPACE_01 dashed $CAP_COLOR_16;
298
298
  border-radius: $CAP_SPACE_04;
299
-
299
+
300
300
  small {
301
301
  color: #8c8c8c;
302
302
  }
303
303
  }
304
304
  }
305
-
305
+
306
306
  // Loading State
307
307
  &.unified-preview-loading {
308
308
  .preview-loading-container {
@@ -313,14 +313,14 @@
313
313
  justify-content: center;
314
314
  gap: $CAP_SPACE_16;
315
315
  min-height: 28.571rem;
316
-
316
+
317
317
  .loading-text {
318
318
  font-size: $FONT_SIZE_M;
319
319
  color: #8c8c8c;
320
320
  }
321
321
  }
322
322
  }
323
-
323
+
324
324
  // Error State
325
325
  &.unified-preview-error {
326
326
  .preview-error-container {
@@ -331,7 +331,7 @@
331
331
  justify-content: center;
332
332
  gap: $CAP_SPACE_16;
333
333
  min-height: 28.571rem;
334
-
334
+
335
335
  .exclamation-circle {
336
336
  font-size: $CAP_SPACE_48;
337
337
  color: #ff4d4f;
@@ -341,7 +341,7 @@
341
341
  font-weight: 600;
342
342
  color: #262626;
343
343
  }
344
-
344
+
345
345
  .error-message {
346
346
  font-size: $FONT_SIZE_M;
347
347
  color: #ff4d4f;
@@ -350,7 +350,7 @@
350
350
  }
351
351
  }
352
352
  }
353
-
353
+
354
354
  // Preview Metadata
355
355
  .preview-metadata {
356
356
  padding: $CAP_SPACE_12 $CAP_SPACE_24;
@@ -360,7 +360,7 @@
360
360
  color: #8c8c8c;
361
361
  display: flex;
362
362
  gap: $CAP_SPACE_16;
363
-
363
+
364
364
  .metadata-item {
365
365
  display: flex;
366
366
  gap: $CAP_SPACE_04;
@@ -553,7 +553,7 @@
553
553
  font-weight: 600;
554
554
  color: #262626;
555
555
  }
556
-
556
+
557
557
  .error-message {
558
558
  font-size: $FONT_SIZE_M;
559
559
  color: #ff4d4f;
@@ -595,9 +595,12 @@
595
595
  transform: translateX(-50%);
596
596
  width: 100%;
597
597
  max-width: 26.786rem;
598
+ min-width: 0; // flex descendant overflow: allow shrink inside narrow screen
598
599
  height: calc(100% - 4.5rem);
599
600
  display: flex;
600
601
  flex-direction: column;
602
+ overflow-x: hidden;
603
+ box-sizing: border-box;
601
604
 
602
605
  &.sms-content-overlay-android {
603
606
  height: calc(100% - 3.8rem);
@@ -759,7 +762,7 @@
759
762
  font-weight: 600;
760
763
  color: #262626;
761
764
  }
762
-
765
+
763
766
  .sms-error-message {
764
767
  font-size: $FONT_SIZE_M;
765
768
  color: #ff4d4f;
@@ -781,13 +784,256 @@
781
784
  }
782
785
  }
783
786
 
787
+ // RCS carousel: allow cards to slide "behind" the phone frame/bezel
788
+ // (device png covers overflow while screen cutout still shows overlay)
789
+ .rcs-device-container.rcs-device-container-carousel {
790
+ .sms-device-image {
791
+ position: relative;
792
+ z-index: 0; // keep device image behind the overlay so preview never disappears
793
+ pointer-events: none; // allow horizontal scroll/drag on carousel underneath
794
+ }
795
+
796
+ .rcs-content-overlay {
797
+ z-index: 1; // overlay above device image (preview visible)
798
+ }
799
+ }
800
+
801
+ // RCS-only overrides for SMS-style preview frame (scoped; does not affect SMS channel preview)
802
+ .rcs-device-container {
803
+ .rcs-content-overlay {
804
+
805
+ &.sms-preview.sms-ios {
806
+ .sms-message-container.rcs-message-container-carousel {
807
+ margin-right: 0; // allow carousel to reach device edge
808
+ }
809
+ }
810
+
811
+ .sms-message-container {
812
+ &.rcs-message-container-carousel {
813
+ // Let carousel reach the right edge of the device frame (match expected)
814
+ padding-right: 0;
815
+ }
816
+
817
+ .sms-message-bubble {
818
+ &.rcs-message-bubble-carousel {
819
+ background: transparent;
820
+ padding: 0;
821
+ max-width: 100%;
822
+ border-radius: 0;
823
+ width: 100%;
824
+
825
+ .sms-message-text {
826
+ width: 100%;
827
+ }
828
+ }
829
+ }
830
+ }
831
+ }
832
+ }
833
+
834
+ // RCS Carousel preview inside SMS-style device frame
835
+ // RcsPreviewContent uses msg-container-carousel/scroll-container/message-pop-carousel classes.
836
+ .rcs-device-container {
837
+ .rcs-content-overlay {
838
+ .sms-message-text {
839
+ .message-pop.sms {
840
+ width: 100%;
841
+ .msg-container-carousel {
842
+ display: flex;
843
+ flex-direction: column;
844
+ width: 100%;
845
+ }
846
+
847
+ .scroll-container {
848
+ overflow-x: auto;
849
+ overflow-y: hidden;
850
+ display: flex;
851
+ flex-wrap: nowrap; // CapRow defaults can wrap; carousel must stay in one row
852
+ align-items: stretch;
853
+ padding-top: $CAP_SPACE_06;
854
+ padding-right: 0; // allow cards to align flush on the right
855
+ white-space: nowrap;
856
+ scrollbar-width: none; // Hide scrollbar in Firefox
857
+ gap: 0.75rem; // 12px; no trailing whitespace like margin-right
858
+ width: 100%;
859
+
860
+ &::-webkit-scrollbar {
861
+ display: none; // Hide scrollbar in Chrome/Safari/Opera
862
+ }
863
+ }
864
+
865
+ .message-pop-carousel {
866
+ // Match TemplatePreview carousel card look (big card + subtle shadow)
867
+ background-color: $CAP_WHITE;
868
+ border-radius: $CAP_SPACE_08;
869
+ // Ensure card width is stable and does not shrink to text width
870
+ width: 16.125rem; // 258px (shows 1 card + a peek of the next)
871
+ min-width: 16.125rem;
872
+ flex: 0 0 16.125rem;
873
+ padding: 0;
874
+ margin-right: 0; // spacing handled by scroll-container gap
875
+ color: $CAP_G01;
876
+ overflow: hidden;
877
+ box-shadow: 0 0 0.625rem 0 rgba(0, 0, 0, 0.08);
878
+ position: relative;
879
+ }
880
+
881
+ .whatsapp-content {
882
+ font-family: Roboto, 'Open Sans', sans-serif;
883
+ margin: 0;
884
+ width: 100%;
885
+ }
886
+
887
+ // Height follows width × aspect-ratio; inline style from carouselPreviewDimensions overrides fallback.
888
+ .whatsapp-image.rcs-carousel-media-wrap {
889
+ width: 100%;
890
+ height: auto;
891
+ aspect-ratio: 1280 / 720; // MEDIUM_MEDIUM image fallback when dimensions not passed
892
+ display: block;
893
+ overflow: hidden;
894
+ border-radius: 0.5rem 0.5rem 0 0; // 8px
895
+ margin-bottom: 0;
896
+
897
+ // CapImage (antd Image) applies className on wrapper; ensure inner img is constrained too.
898
+ img,
899
+ .ant-image-img {
900
+ width: 100%;
901
+ height: 100%;
902
+ object-fit: cover;
903
+ border-radius: inherit;
904
+ display: block;
905
+ }
906
+
907
+ // Plain <img> in RCS carousel preview (not CapImage)
908
+ .rcs-carousel-img {
909
+ width: 100%;
910
+ height: 100%;
911
+ object-fit: cover;
912
+ border-radius: inherit;
913
+ display: block;
914
+ }
915
+ }
916
+
917
+ .video-preview {
918
+ position: relative;
919
+ width: 100%;
920
+ margin-bottom: 0;
921
+
922
+ .whatsapp-image.rcs-carousel-media-wrap {
923
+ width: 100%;
924
+ height: auto;
925
+ aspect-ratio: 796 / 448; // MEDIUM_MEDIUM video thumbnail fallback
926
+ margin-bottom: 0;
927
+
928
+ img,
929
+ .ant-image-img,
930
+ .rcs-carousel-img {
931
+ width: 100%;
932
+ height: 100%;
933
+ object-fit: cover;
934
+ border-radius: inherit;
935
+ display: block;
936
+ }
937
+ }
938
+
939
+ .icon-position {
940
+ position: absolute;
941
+ top: 50%;
942
+ left: 50%;
943
+ transform: translate(-50%, -50%);
944
+ display: flex;
945
+ align-items: center;
946
+ justify-content: center;
947
+
948
+ .video-icon {
949
+ width: $CAP_SPACE_48;
950
+ height: $CAP_SPACE_48;
951
+ }
952
+ }
953
+ }
954
+
955
+ .carousel-content {
956
+ padding: 0.625rem 0.75rem; // 10px 12px
957
+ width: 100%;
958
+ background-color: #ebecf0;
959
+ white-space: normal; // override scroll-container's nowrap so text can wrap
960
+ display: flex;
961
+ flex-direction: column;
962
+ border-bottom-left-radius: 0.25rem; // 4px — text panel tucks above CTA gap (Figma)
963
+ border-bottom-right-radius: 0.25rem;
964
+
965
+ // Title/body typography via CapLabel type (label1 / label2, etc.)
966
+ .carousel-title {
967
+ margin-bottom: 0.25rem; // 4px
968
+ display: block;
969
+ overflow: visible;
970
+ white-space: normal;
971
+ overflow-wrap: anywhere;
972
+ }
973
+
974
+ .carousel-message {
975
+ display: block;
976
+ overflow: visible;
977
+ white-space: normal;
978
+ overflow-wrap: anywhere;
979
+ }
980
+
981
+ .rcs-carousel-field-placeholder {
982
+ color: $CAP_G05;
983
+ font-weight: $FONT_WEIGHT_REGULAR;
984
+ }
985
+ }
986
+
987
+ // Divider and suggestions should render like a CTA bar list (no extra margins)
988
+ .whatsapp-divider {
989
+ margin: 0;
990
+ border-top: 1px solid $CAP_WHITE;
991
+ }
992
+
993
+ // Stacked full-width CTA bars below card copy, separated by white gap (Figma RCS carousel)
994
+ .rcs-carousel-cta-stack.cap-row-v2 {
995
+ display: flex;
996
+ flex-direction: column;
997
+ flex-wrap: nowrap;
998
+ width: 100%;
999
+ gap: 0.25rem;
1000
+ box-sizing: border-box;
1001
+ align-items: stretch;
1002
+ }
1003
+
1004
+ .rcs-cta-preview--carousel-bar {
1005
+ display: flex;
1006
+ align-items: center;
1007
+ justify-content: center;
1008
+ gap: 0.375rem;
1009
+ width: 100%;
1010
+ margin: 0;
1011
+ padding: 0.625rem 0.75rem;
1012
+ box-sizing: border-box;
1013
+ background-color: #ebecf0;
1014
+ border-radius: 0.25rem;
1015
+ font-size: $FONT_SIZE_M;
1016
+ font-weight: $FONT_WEIGHT_MEDIUM;
1017
+ color: $CAP_G01;
1018
+ text-align: center;
1019
+ }
1020
+
1021
+ .rcs-cta-preview-phone-icon-end {
1022
+ margin-left: 0.25rem;
1023
+ flex-shrink: 0;
1024
+ }
1025
+ }
1026
+ }
1027
+ }
1028
+ }
1029
+
784
1030
  // WhatsApp Preview Content Styles (Phase 8)
785
1031
  // All WhatsApp styles wrapped in parent class for increased specificity
786
1032
  // This prevents other CSS (like CapLabel) from overriding WhatsApp-specific styles
787
1033
  .whatsapp-preview-wrapper {
788
1034
  // Using same CSS classes as TemplatePreview for consistency
789
1035
  // Styles are copied from TemplatePreview/_templatePreview.scss to ensure they work
790
-
1036
+
791
1037
  .shell-v2-whatsapp {
792
1038
  position: relative;
793
1039
  -webkit-transform: translate(-50%);
@@ -862,23 +1108,23 @@
862
1108
  }
863
1109
 
864
1110
  // WhatsApp message pop styles (matching TemplatePreview)
865
- &.whatsapp-message-pop {
1111
+ &.whatsapp-message-pop,
1112
+ &.whatsapp-message-pop-carousel {
866
1113
  padding: $CAP_SPACE_04 0 $CAP_SPACE_08;
867
1114
  border-radius: $CAP_SPACE_06;
868
1115
  background-color: $CAP_WHITE;
869
- width: 88%;
870
1116
  left: 0;
871
1117
  }
872
1118
 
1119
+ &.whatsapp-message-pop {
1120
+ width: 88%;
1121
+ }
1122
+
873
1123
  // WhatsApp carousel message pop styles
874
1124
  &.whatsapp-message-pop-carousel {
875
- padding: $CAP_SPACE_04 0 $CAP_SPACE_08;
876
- border-radius: $CAP_SPACE_06;
877
- background-color: $CAP_WHITE;
878
1125
  width: 10.4rem;
879
1126
  cursor: pointer;
880
1127
  flex-shrink: 0;
881
- left: 0;
882
1128
  }
883
1129
  }
884
1130
  }
@@ -943,7 +1189,7 @@
943
1189
  line-height: 1rem;
944
1190
  font-family: Roboto, 'Open Sans', sans-serif;
945
1191
  }
946
-
1192
+
947
1193
  .whatsapp-template-footer-preview {
948
1194
  // From WhatsApp/index.scss: color: $CAP_G04, but use white for preview
949
1195
  color: $CAP_G01;
@@ -999,19 +1245,19 @@
999
1245
  color: #8c8c8c;
1000
1246
  font-size: $FONT_SIZE_M;
1001
1247
  }
1002
-
1248
+
1003
1249
  .whatsapp-error-text {
1004
1250
  font-size: $FONT_SIZE_L;
1005
1251
  font-weight: 600;
1006
1252
  color: #262626;
1007
1253
  }
1008
-
1254
+
1009
1255
  .whatsapp-error-message {
1010
1256
  font-size: $FONT_SIZE_M;
1011
1257
  color: #ff4d4f;
1012
1258
  text-align: center;
1013
1259
  }
1014
-
1260
+
1015
1261
  .whatsapp-no-content {
1016
1262
  color: #8c8c8c;
1017
1263
  font-size: $FONT_SIZE_M;
@@ -1063,14 +1309,14 @@
1063
1309
  color: #8c8c8c;
1064
1310
  margin-top: $CAP_SPACE_04;
1065
1311
  }
1066
-
1312
+
1067
1313
  .url-preview {
1068
1314
  font-size: $FONT_SIZE_S;
1069
1315
  color: #1890ff;
1070
1316
  word-break: break-all;
1071
1317
  }
1072
1318
  }
1073
-
1319
+
1074
1320
  // InApp Preview Content Styles (Phase 10)
1075
1321
  // Styles copied from TemplatePreview/_templatePreview.scss to ensure consistency
1076
1322
  // These styles work within the SMS device container structure
@@ -1131,11 +1377,11 @@
1131
1377
  .inapp-message-container-FULLSCREEN {
1132
1378
  position: relative;
1133
1379
  background-color: $CAP_WHITE;
1134
- width: 100%;
1380
+ width: 100%;
1135
1381
  height: 100%;
1136
1382
  align-items: center;
1137
1383
  padding: 0 $CAP_SPACE_16;
1138
- border-bottom-left-radius: 2.6rem;
1384
+ border-bottom-left-radius: 2.6rem;
1139
1385
  border-bottom-right-radius: 2.6rem;
1140
1386
  .inapp-title-FULLSCREEN {
1141
1387
  align-items: center;
@@ -1965,7 +2211,7 @@
1965
2211
  max-height: 7.5rem;
1966
2212
  margin-left: $CAP_SPACE_24;
1967
2213
  }
1968
-
2214
+
1969
2215
  .mpush-gif-preview {
1970
2216
  max-width: 100%;
1971
2217
  max-height: 7.5rem;
@@ -2225,6 +2471,7 @@
2225
2471
  font-weight: 500;
2226
2472
  display: -webkit-box;
2227
2473
  -webkit-line-clamp: 1;
2474
+ line-clamp: 1;
2228
2475
  -webkit-box-orient: vertical;
2229
2476
  overflow: hidden;
2230
2477
  color: $CAP_WHITE;
@@ -2276,7 +2523,7 @@
2276
2523
  color: $FONT_COLOR_01;
2277
2524
  margin-bottom: $CAP_SPACE_12;
2278
2525
  }
2279
-
2526
+
2280
2527
  .preview-text {
2281
2528
  font-weight: 400;
2282
2529
  font-size: $FONT_SIZE_S;
@@ -2311,13 +2558,13 @@
2311
2558
  justify-content: center;
2312
2559
  padding: $CAP_SPACE_60 $CAP_SPACE_24;
2313
2560
  gap: $CAP_SPACE_16;
2314
-
2561
+
2315
2562
  .zalo-loading-text {
2316
2563
  color: #8c8c8c;
2317
2564
  font-size: $FONT_SIZE_M;
2318
2565
  }
2319
2566
  }
2320
-
2567
+
2321
2568
  // Error state
2322
2569
  .zalo-error-container {
2323
2570
  display: flex;
@@ -2326,13 +2573,13 @@
2326
2573
  justify-content: center;
2327
2574
  padding: $CAP_SPACE_60 $CAP_SPACE_24;
2328
2575
  gap: $CAP_SPACE_16;
2329
-
2576
+
2330
2577
  .zalo-error-text {
2331
2578
  font-size: $FONT_SIZE_L;
2332
2579
  font-weight: 600;
2333
2580
  color: #262626;
2334
2581
  }
2335
-
2582
+
2336
2583
  .zalo-error-message {
2337
2584
  font-size: $FONT_SIZE_M;
2338
2585
  color: #ff4d4f;
@@ -2350,31 +2597,31 @@
2350
2597
  }
2351
2598
  }
2352
2599
  }
2353
-
2600
+
2354
2601
  @media (max-width: 54.857rem) {
2355
2602
  .unified-preview {
2356
2603
  .preview-header {
2357
2604
  flex-direction: column;
2358
2605
  align-items: flex-start;
2359
2606
  gap: $CAP_SPACE_12;
2360
-
2607
+
2361
2608
  .preview-header-right {
2362
2609
  width: 100%;
2363
2610
  justify-content: flex-start;
2364
2611
  }
2365
2612
  }
2366
-
2613
+
2367
2614
  .preview-content-container {
2368
2615
  padding: $CAP_SPACE_16;
2369
2616
  }
2370
-
2617
+
2371
2618
  .device-frame {
2372
2619
  &.device-frame-desktop,
2373
2620
  &.device-frame-tablet {
2374
2621
  width: 100% !important;
2375
2622
  max-width: 100% !important;
2376
2623
  }
2377
-
2624
+
2378
2625
  &.device-frame-mobile {
2379
2626
  width: 100% !important;
2380
2627
  max-width: 100% !important;
@@ -2382,4 +2629,3 @@
2382
2629
  }
2383
2630
  }
2384
2631
  }
2385
-