@standhigher/react-email-editor 0.0.0-stage → 0.2.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.
@@ -0,0 +1,1906 @@
1
+ /* ==========================================================================
2
+ @standhigher/react-email-editor
3
+ Polaris 风格主题(浅色),CSS 变量 + ree- 前缀。间距刻意放大,营造大气留白。
4
+ ========================================================================== */
5
+
6
+ /* 富文本工具栏会 portal 到 .ree-root 之外(例如 document.body)。
7
+ 主题变量必须同时挂在工具栏上,否则下拉、输入框和按钮的 var() 会失效。 */
8
+ .ree-root,
9
+ .ree-rte-toolbar {
10
+ --ree-bg: #f1f1f1; /* --p-color-bg-app */
11
+ --ree-panel: #ffffff; /* --p-color-bg */
12
+ --ree-panel-secondary: #f6f6f7; /* --p-color-bg-surface-secondary */
13
+ --ree-border: #e3e3e5; /* --p-color-border */
14
+ --ree-border-subdued: #ececec;
15
+ --ree-text: #202223; /* --p-color-text */
16
+ --ree-muted: #6d7175; /* --p-color-text-subdued */
17
+ --ree-primary: #005bd3; /* --p-color-bg-fill-brand */
18
+ --ree-primary-hover: #084eb3;
19
+ --ree-primary-fg: #ffffff;
20
+ --ree-primary-soft: #eef4ff;
21
+ --ree-accent-border: #a9c8f4; /* 区块 hover 浅蓝边框 */
22
+ --ree-accent-bg: #f1f6ff; /* 区块 hover 浅蓝背景 */
23
+ --ree-accent-bg-strong: #e8f1ff; /* 区块选中背景 */
24
+ --ree-danger: #d72c0d;
25
+ --ree-danger-soft: #fbeae5;
26
+
27
+ --ree-radius-sm: 6px;
28
+ --ree-radius: 8px;
29
+ --ree-radius-lg: 12px;
30
+
31
+ --ree-shadow-sm: 0 1px 0 rgba(0, 0, 0, 0.05);
32
+ --ree-shadow-md: 0 2px 16px rgba(31, 33, 36, 0.08);
33
+ --ree-shadow-lg: 0 6px 32px rgba(31, 33, 36, 0.16);
34
+
35
+ --ree-font: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
36
+ "Helvetica Neue", Arial, "PingFang SC", "Microsoft YaHei", sans-serif;
37
+ }
38
+
39
+ .ree-root {
40
+ display: flex;
41
+ flex-direction: column;
42
+ width: 100%;
43
+ height: 100%;
44
+ min-height: 0;
45
+ background: var(--ree-bg);
46
+ color: var(--ree-text);
47
+ font-family: var(--ree-font);
48
+ font-size: 14px;
49
+ overflow: hidden;
50
+ box-sizing: border-box;
51
+ }
52
+
53
+ .ree-root *,
54
+ .ree-root *::before,
55
+ .ree-root *::after,
56
+ .ree-rte-toolbar,
57
+ .ree-rte-toolbar *,
58
+ .ree-rte-toolbar *::before,
59
+ .ree-rte-toolbar *::after {
60
+ box-sizing: border-box;
61
+ }
62
+
63
+
64
+ /* ---------- 共享表单控件 ---------- */
65
+
66
+ .ree-input {
67
+ width: 100%;
68
+ border: 1px solid var(--ree-border, #e3e3e5);
69
+ border-radius: var(--ree-radius, 8px);
70
+ --ree-control-padding-x: 12px;
71
+ --ree-control-padding-y: 8px;
72
+ --ree-control-padding-end: var(--ree-control-padding-x);
73
+ padding: var(--ree-control-padding-y) var(--ree-control-padding-end) var(--ree-control-padding-y) var(--ree-control-padding-x);
74
+ font-size: 14px;
75
+ line-height: 1.4;
76
+ font-family: inherit;
77
+ color: var(--ree-text, #202223);
78
+ background: var(--ree-panel, #ffffff);
79
+ transition: border-color 0.12s ease, box-shadow 0.12s ease;
80
+ }
81
+
82
+ .ree-input:focus {
83
+ outline: none;
84
+ border: 2px solid #202223;
85
+ padding: max(0px, calc(var(--ree-control-padding-y) - 1px)) calc(var(--ree-control-padding-end) - 1px) max(0px, calc(var(--ree-control-padding-y) - 1px)) calc(var(--ree-control-padding-x) - 1px);
86
+ box-shadow: none;
87
+ }
88
+
89
+ .ree-select {
90
+ display: block;
91
+ min-width: 0;
92
+ width: 100%;
93
+ position: relative;
94
+ }
95
+
96
+ .ree-select .ree-input {
97
+ appearance: none;
98
+ -webkit-appearance: none;
99
+ --ree-control-padding-end: 40px;
100
+ cursor: pointer;
101
+ background-color: var(--ree-panel);
102
+ }
103
+
104
+ .ree-select-icon {
105
+ position: absolute;
106
+ top: 0;
107
+ right: 12px;
108
+ bottom: 0;
109
+ display: flex;
110
+ align-items: center;
111
+ pointer-events: none;
112
+ color: var(--ree-muted);
113
+ }
114
+
115
+ .ree-select.is-compact {
116
+ width: auto;
117
+ flex-shrink: 0;
118
+ }
119
+
120
+ .ree-select.is-compact .ree-input {
121
+ --ree-control-padding-x: 8px;
122
+ --ree-control-padding-y: 0px;
123
+ --ree-control-padding-end: 32px;
124
+ height: 28px;
125
+ font-size: 12px;
126
+ line-height: 1;
127
+ border-radius: 6px;
128
+ }
129
+
130
+ .ree-select.is-compact .ree-select-icon svg {
131
+ width: 12px;
132
+ height: 12px;
133
+ }
134
+
135
+ .ree-color-control {
136
+ display: inline-flex;
137
+ min-width: 0;
138
+ }
139
+
140
+ .ree-color-chip {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ gap: 8px;
144
+ min-width: 0;
145
+ width: fit-content;
146
+ max-width: 100%;
147
+ justify-self: start;
148
+ cursor: pointer;
149
+ appearance: none;
150
+ border: 0;
151
+ padding: 0;
152
+ background: transparent;
153
+ font: inherit;
154
+ }
155
+
156
+ .ree-color-swatch {
157
+ position: relative;
158
+ width: 36px;
159
+ height: 22px;
160
+ flex-shrink: 0;
161
+ }
162
+
163
+ .ree-color-swatch-face {
164
+ display: block;
165
+ width: 100%;
166
+ height: 100%;
167
+ border: 1px solid #d2d5d8;
168
+ border-radius: 999px;
169
+ background: #ffffff;
170
+ }
171
+
172
+ .ree-color-swatch-face.is-empty {
173
+ background:
174
+ linear-gradient(45deg, #e3e3e5 25%, transparent 25%),
175
+ linear-gradient(-45deg, #e3e3e5 25%, transparent 25%),
176
+ linear-gradient(45deg, transparent 75%, #e3e3e5 75%),
177
+ linear-gradient(-45deg, transparent 75%, #e3e3e5 75%);
178
+ background-size: 8px 8px;
179
+ background-position: 0 0, 0 4px, 4px -4px, -4px 0;
180
+ background-color: #ffffff;
181
+ }
182
+
183
+ .ree-color-chip-label {
184
+ min-width: 0;
185
+ overflow-wrap: anywhere;
186
+ color: var(--ree-text);
187
+ font-size: 13px;
188
+ line-height: 1.3;
189
+ }
190
+
191
+ .ree-checkbox-control {
192
+ display: inline-flex;
193
+ align-items: center;
194
+ justify-self: start;
195
+ gap: 8px;
196
+ width: fit-content;
197
+ max-width: 100%;
198
+ cursor: pointer;
199
+ }
200
+
201
+ .ree-checkbox-control input {
202
+ appearance: none;
203
+ display: grid;
204
+ place-items: center;
205
+ flex-shrink: 0;
206
+ width: 16px;
207
+ height: 16px;
208
+ margin: 0;
209
+ border: 1px solid #b5b5b5;
210
+ border-radius: 3px;
211
+ background: #ffffff;
212
+ cursor: pointer;
213
+ }
214
+
215
+ .ree-checkbox-control input:checked {
216
+ border-color: #202223;
217
+ background: #202223;
218
+ }
219
+
220
+ .ree-checkbox-control input:checked::before {
221
+ content: "";
222
+ width: 5px;
223
+ height: 9px;
224
+ margin-top: -2px;
225
+ border: solid #ffffff;
226
+ border-width: 0 2px 2px 0;
227
+ transform: rotate(45deg);
228
+ }
229
+
230
+ .ree-checkbox-control input:focus-visible,
231
+ .ree-color-chip:focus-visible .ree-color-swatch-face {
232
+ border: 2px solid #202223;
233
+ }
234
+
235
+ .ree-checkbox-control input:focus,
236
+ .ree-color-chip:focus {
237
+ outline: none;
238
+ box-shadow: none;
239
+ }
240
+
241
+ .ree-checkbox-control:has(input:disabled) {
242
+ opacity: 0.4;
243
+ cursor: default;
244
+ }
245
+
246
+ .ree-checkbox-control input:disabled,
247
+ .ree-select .ree-input:disabled {
248
+ cursor: default;
249
+ }
250
+
251
+ .ree-range {
252
+ -webkit-appearance: none;
253
+ appearance: none;
254
+ display: block;
255
+ flex: 1 1 auto;
256
+ width: 100%;
257
+ min-width: 0;
258
+ height: 20px;
259
+ margin: 0;
260
+ background: transparent;
261
+ cursor: pointer;
262
+ }
263
+
264
+ .ree-range::-webkit-slider-container {
265
+ width: 100%;
266
+ }
267
+
268
+ .ree-range::-webkit-slider-runnable-track {
269
+ width: 100%;
270
+ height: 4px;
271
+ border: 0;
272
+ border-radius: 999px;
273
+ background: linear-gradient(to right, #303030 0%, #303030 var(--ree-range-progress), #e3e3e5 var(--ree-range-progress), #e3e3e5 100%);
274
+ }
275
+
276
+ .ree-range::-webkit-slider-thumb {
277
+ appearance: none;
278
+ width: 14px;
279
+ height: 14px;
280
+ margin-top: -5px;
281
+ border: 0;
282
+ border-radius: 50%;
283
+ background: #303030;
284
+ }
285
+
286
+ .ree-range::-moz-range-track {
287
+ height: 4px;
288
+ border: 0;
289
+ border-radius: 999px;
290
+ background: #e3e3e5;
291
+ }
292
+
293
+ .ree-range::-moz-range-progress {
294
+ height: 4px;
295
+ border: 0;
296
+ border-radius: 999px;
297
+ background: #303030;
298
+ }
299
+
300
+ .ree-range::-moz-range-thumb {
301
+ width: 14px;
302
+ height: 14px;
303
+ border: 0;
304
+ border-radius: 50%;
305
+ background: #303030;
306
+ }
307
+
308
+ /* ---------- 共享普通按钮 ---------- */
309
+
310
+ .ree-btn {
311
+ appearance: none;
312
+ border: 1px solid #b5b5b5;
313
+ background: var(--ree-panel, #ffffff);
314
+ color: var(--ree-text, #202223);
315
+ border-radius: var(--ree-radius, 8px);
316
+ --ree-button-padding-y: 8px;
317
+ --ree-button-padding-x: 16px;
318
+ padding: var(--ree-button-padding-y) var(--ree-button-padding-x);
319
+ font-size: 14px;
320
+ font-weight: 500;
321
+ line-height: 1.4;
322
+ cursor: pointer;
323
+ font-family: inherit;
324
+ transition: background 0.12s ease, border-color 0.12s ease,
325
+ box-shadow 0.12s ease;
326
+ }
327
+
328
+ .ree-btn:hover {
329
+ background: var(--ree-panel-secondary);
330
+ border-color: var(--ree-border);
331
+ }
332
+
333
+ .ree-btn:active {
334
+ background: #f0f0f1;
335
+ }
336
+
337
+ .ree-btn-primary {
338
+ background: var(--ree-primary, #005bd3);
339
+ border-color: var(--ree-primary, #005bd3);
340
+ color: var(--ree-primary-fg, #ffffff);
341
+ }
342
+
343
+ .ree-btn-primary:hover {
344
+ background: var(--ree-primary-hover);
345
+ border-color: var(--ree-primary-hover);
346
+ }
347
+
348
+ .ree-btn-primary:active {
349
+ background: var(--ree-primary-hover);
350
+ }
351
+
352
+
353
+ .ree-btn:disabled {
354
+ opacity: 0.4;
355
+ cursor: default;
356
+ }
357
+
358
+ .ree-btn-solid {
359
+ background: #202223;
360
+ border-color: #202223;
361
+ color: #ffffff;
362
+ }
363
+
364
+ .ree-btn-solid:hover,
365
+ .ree-btn-solid:active {
366
+ background: #000000;
367
+ border-color: #000000;
368
+ }
369
+
370
+ .ree-btn:focus-visible {
371
+ outline: none;
372
+ box-shadow: none;
373
+ border-width: 2px;
374
+ border-color: #202223;
375
+ padding: calc(var(--ree-button-padding-y) - 1px) calc(var(--ree-button-padding-x) - 1px);
376
+ }
377
+
378
+ .ree-reset {
379
+ appearance: none;
380
+ display: inline-flex;
381
+ align-items: center;
382
+ justify-content: center;
383
+ width: 22px;
384
+ height: 22px;
385
+ flex-shrink: 0;
386
+ padding: 0;
387
+ border: 0;
388
+ border-radius: 6px;
389
+ background: transparent;
390
+ color: var(--ree-muted);
391
+ cursor: pointer;
392
+ }
393
+
394
+ .ree-reset:hover {
395
+ background: var(--ree-panel-secondary);
396
+ color: var(--ree-text);
397
+ }
398
+
399
+ .ree-reset:disabled {
400
+ opacity: 0.35;
401
+ cursor: default;
402
+ }
403
+
404
+ .ree-reset:disabled:hover {
405
+ background: transparent;
406
+ color: var(--ree-muted);
407
+ }
408
+
409
+ .ree-reset:focus-visible {
410
+ outline: 1px solid #202223;
411
+ outline-offset: -1px;
412
+ }
413
+
414
+ .ree-color-picker {
415
+ position: fixed;
416
+ inset: auto;
417
+ width: min(256px, calc(100vw - 16px));
418
+ max-height: calc(100dvh - 16px);
419
+ margin: 0;
420
+ padding: 12px;
421
+ overflow: auto;
422
+ border: 1px solid var(--ree-border, #e3e3e5);
423
+ border-radius: 10px;
424
+ background: var(--ree-panel, #ffffff);
425
+ box-shadow: var(--ree-shadow-lg, 0 6px 32px rgba(31, 33, 36, 0.16));
426
+ color: var(--ree-text, #202223);
427
+ font: 400 13px/1.4 var(--ree-font, Arial, sans-serif);
428
+ }
429
+
430
+ .ree-color-picker:popover-open {
431
+ display: grid;
432
+ gap: 12px;
433
+ }
434
+
435
+ .ree-color-saturation {
436
+ position: relative;
437
+ height: 144px;
438
+ border-radius: 6px;
439
+ background: linear-gradient(to top, #000000, transparent), linear-gradient(to right, #ffffff, transparent), var(--ree-color-hue);
440
+ cursor: crosshair;
441
+ touch-action: none;
442
+ }
443
+
444
+ .ree-color-saturation:focus-visible {
445
+ outline: 2px solid #202223;
446
+ outline-offset: 2px;
447
+ }
448
+
449
+ .ree-color-cursor {
450
+ position: absolute;
451
+ width: 12px;
452
+ height: 12px;
453
+ border: 2px solid #ffffff;
454
+ border-radius: 50%;
455
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
456
+ transform: translate(-50%, -50%);
457
+ pointer-events: none;
458
+ }
459
+
460
+ .ree-color-hue .ree-range::-webkit-slider-runnable-track {
461
+ height: 10px;
462
+ background: linear-gradient(to right, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
463
+ }
464
+
465
+ .ree-color-hue .ree-range::-moz-range-track {
466
+ height: 10px;
467
+ background: linear-gradient(to right, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
468
+ }
469
+
470
+ .ree-color-hue .ree-range::-moz-range-progress {
471
+ background: transparent;
472
+ }
473
+
474
+ .ree-color-hue .ree-range::-webkit-slider-thumb {
475
+ margin-top: -2px;
476
+ border: 2px solid #ffffff;
477
+ box-shadow: 0 0 0 1px #6d7175;
478
+ }
479
+
480
+ .ree-color-hue .ree-range::-moz-range-thumb {
481
+ border: 2px solid #ffffff;
482
+ box-shadow: 0 0 0 1px #6d7175;
483
+ }
484
+
485
+ .ree-color-hex-row {
486
+ display: flex;
487
+ align-items: center;
488
+ gap: 10px;
489
+ }
490
+
491
+ .ree-color-preview {
492
+ flex: 0 0 28px;
493
+ height: 28px;
494
+ border: 1px solid var(--ree-border);
495
+ border-radius: 6px;
496
+ }
497
+
498
+ .ree-color-hex-field {
499
+ display: flex;
500
+ flex: 1;
501
+ align-items: center;
502
+ gap: 8px;
503
+ min-width: 0;
504
+ }
505
+
506
+ .ree-color-hex-field .ree-input {
507
+ min-width: 0;
508
+ font-variant-numeric: tabular-nums;
509
+ }
510
+
511
+ .ree-color-error {
512
+ margin: 0;
513
+ color: var(--ree-danger, #d72c0d);
514
+ font-size: 12px;
515
+ }
516
+
517
+ /* ---------- 邮件主题 ---------- */
518
+
519
+ .ree-subject-bar {
520
+ display: flex;
521
+ align-items: center;
522
+ flex-wrap: wrap;
523
+ gap: 10px 12px;
524
+ padding: 10px 16px;
525
+ background: var(--ree-panel);
526
+ border-bottom: 1px solid var(--ree-border);
527
+ min-height: 56px;
528
+ }
529
+
530
+ .ree-subject-label {
531
+ flex-shrink: 0;
532
+ font-size: 13px;
533
+ font-weight: 500;
534
+ color: var(--ree-text);
535
+ }
536
+
537
+ .ree-subject-input {
538
+ flex: 1 1 360px;
539
+ min-width: 240px;
540
+ width: auto;
541
+ }
542
+
543
+ .ree-subject-count {
544
+ flex-shrink: 0;
545
+ color: var(--ree-muted);
546
+ font-size: 13px;
547
+ font-variant-numeric: tabular-nums;
548
+ }
549
+
550
+ .ree-personalization {
551
+ position: relative;
552
+ flex-shrink: 0;
553
+ }
554
+
555
+ .ree-personalization-btn {
556
+ appearance: none;
557
+ display: inline-flex;
558
+ align-items: center;
559
+ gap: 6px;
560
+ border: 1px solid var(--ree-border);
561
+ background: var(--ree-panel);
562
+ color: var(--ree-text);
563
+ border-radius: var(--ree-radius);
564
+ padding: 7px 10px 7px 12px;
565
+ font: inherit;
566
+ font-size: 13px;
567
+ font-weight: 500;
568
+ line-height: 1.2;
569
+ cursor: pointer;
570
+ }
571
+
572
+ .ree-personalization-btn:hover {
573
+ background: var(--ree-panel-secondary);
574
+ }
575
+
576
+ .ree-personalization-menu {
577
+ left: 0;
578
+ min-width: 240px;
579
+ }
580
+
581
+ .ree-subject-hint {
582
+ flex: 0 1 auto;
583
+ margin: 0;
584
+ color: var(--ree-muted);
585
+ font-size: 13px;
586
+ line-height: 1.4;
587
+ white-space: nowrap;
588
+ }
589
+
590
+
591
+ /* ---------- 三栏布局 ---------- */
592
+
593
+ .ree-body {
594
+ display: flex;
595
+ flex: 1;
596
+ min-height: 0;
597
+ }
598
+
599
+ .ree-col {
600
+ display: flex;
601
+ flex-direction: column;
602
+ min-height: 0;
603
+ background: var(--ree-panel);
604
+ }
605
+
606
+ .ree-col-head {
607
+ display: flex;
608
+ align-items: center;
609
+ flex-shrink: 0;
610
+ height: 52px;
611
+ padding: 7px 16px;
612
+ font-weight: 600;
613
+ font-size: 12px;
614
+ color: var(--ree-muted);
615
+ text-transform: uppercase;
616
+ letter-spacing: 0.05em;
617
+ border-bottom: 1px solid var(--ree-border);
618
+ background: var(--ree-panel);
619
+ }
620
+
621
+ .ree-stage-head {
622
+ justify-content: center;
623
+ gap: 12px;
624
+ text-transform: none;
625
+ letter-spacing: normal;
626
+ font-weight: 500;
627
+ color: var(--ree-text);
628
+ }
629
+
630
+ .ree-segment {
631
+ display: inline-flex;
632
+ align-items: stretch;
633
+ border: 1px solid #c9cccf;
634
+ border-radius: 8px;
635
+ overflow: hidden;
636
+ background: #ffffff;
637
+ }
638
+
639
+ .ree-segment-btn {
640
+ appearance: none;
641
+ border: none;
642
+ background: #ffffff;
643
+ color: #303030;
644
+ min-width: 46px;
645
+ height: 34px;
646
+ padding: 0 10px;
647
+ display: inline-flex;
648
+ align-items: center;
649
+ justify-content: center;
650
+ cursor: pointer;
651
+ font: inherit;
652
+ font-size: 13px;
653
+ font-weight: 550;
654
+ transition: background-color 0.16s ease, color 0.16s ease,
655
+ box-shadow 0.16s ease;
656
+ }
657
+
658
+ .ree-segment-divider {
659
+ flex-shrink: 0;
660
+ align-self: stretch;
661
+ width: 1px;
662
+ background: #c9cccf;
663
+ }
664
+
665
+ .ree-segment-btn.is-active {
666
+ background: #e3e3e3;
667
+ }
668
+
669
+ .ree-segment-btn:hover {
670
+ background: #f3f3f3;
671
+ color: #1f1f1f;
672
+ }
673
+
674
+ .ree-segment-btn.is-active:hover {
675
+ background: #d9d9d9;
676
+ }
677
+
678
+ .ree-segment-btn:active,
679
+ .ree-segment-btn.is-active:active {
680
+ background: #d4d4d4;
681
+ }
682
+
683
+ .ree-segment-btn:focus-visible {
684
+ outline: none;
685
+ box-shadow: inset 0 0 0 2px var(--ree-primary);
686
+ }
687
+
688
+ .ree-segment-btn:disabled {
689
+ opacity: 0.4;
690
+ cursor: default;
691
+ }
692
+
693
+ .ree-segment-btn:disabled:hover {
694
+ background: #ffffff;
695
+ color: #303030;
696
+ }
697
+
698
+ .ree-segment-btn-label {
699
+ padding: 0 10px;
700
+ }
701
+
702
+ .ree-inspector-tabs {
703
+ display: flex;
704
+ align-items: center;
705
+ gap: 16px;
706
+ }
707
+
708
+ .ree-inspector-tab {
709
+ appearance: none;
710
+ border: 0;
711
+ padding: 0;
712
+ background: transparent;
713
+ color: var(--ree-muted);
714
+ font: inherit;
715
+ font-size: 12px;
716
+ font-weight: 600;
717
+ letter-spacing: 0.05em;
718
+ cursor: pointer;
719
+ }
720
+
721
+ .ree-inspector-tab:hover,
722
+ .ree-inspector-tab.is-active {
723
+ color: var(--ree-text);
724
+ }
725
+
726
+ .ree-inspector-tab:focus-visible {
727
+ outline: 2px solid var(--ree-primary);
728
+ outline-offset: 3px;
729
+ border-radius: 2px;
730
+ }
731
+
732
+ .ree-inspector-tab:disabled {
733
+ color: var(--ree-muted);
734
+ opacity: 0.4;
735
+ cursor: default;
736
+ }
737
+
738
+ .ree-col-left {
739
+ width: 320px;
740
+ border-right: 1px solid var(--ree-border);
741
+ flex-shrink: 0;
742
+ }
743
+
744
+ .ree-col-center {
745
+ flex: 1;
746
+ min-width: 0;
747
+ background: var(--ree-bg);
748
+ }
749
+
750
+ .ree-col-right {
751
+ width: 400px;
752
+ border-left: 1px solid var(--ree-border);
753
+ flex-shrink: 0;
754
+ overflow: hidden;
755
+ }
756
+
757
+ .ree-inspector-bar {
758
+ text-transform: none;
759
+ letter-spacing: normal;
760
+ font-weight: 500;
761
+ color: var(--ree-text);
762
+ }
763
+
764
+ .ree-inspector-tab {
765
+ max-width: 180px;
766
+ overflow: hidden;
767
+ text-overflow: ellipsis;
768
+ white-space: nowrap;
769
+ }
770
+
771
+
772
+ /* ---------- 区块库 ---------- */
773
+
774
+ .ree-lib {
775
+ padding: 16px;
776
+ display: grid;
777
+ grid-template-columns: 1fr 1fr;
778
+ gap: 12px;
779
+ overflow-y: auto;
780
+ }
781
+
782
+ .ree-lib-item {
783
+ display: flex;
784
+ align-items: center;
785
+ gap: 10px;
786
+ padding: 12px 14px;
787
+ border: 1px solid var(--ree-border);
788
+ border-radius: var(--ree-radius);
789
+ cursor: grab;
790
+ user-select: none;
791
+ background: var(--ree-panel);
792
+ transition: box-shadow 0.12s ease, border-color 0.12s ease;
793
+ }
794
+
795
+ .ree-lib-item:hover {
796
+ border-color: var(--ree-primary);
797
+ box-shadow: var(--ree-shadow-sm);
798
+ }
799
+
800
+ .ree-lib-item.is-dragging {
801
+ opacity: 0.4;
802
+ }
803
+
804
+ .ree-lib-icon {
805
+ display: inline-flex;
806
+ color: var(--ree-muted);
807
+ flex-shrink: 0;
808
+ }
809
+
810
+ .ree-lib-title {
811
+ font-size: 14px;
812
+ font-weight: 500;
813
+ }
814
+
815
+
816
+ /* ---------- 画布 ---------- */
817
+
818
+ .ree-stage-view {
819
+ display: flex;
820
+ flex: 1;
821
+ min-height: 0;
822
+ min-width: 0;
823
+ background-color: var(--ree-panel);
824
+ background-image:
825
+ linear-gradient(45deg, rgba(0, 0, 0, 0.02) 25%, transparent 25%),
826
+ linear-gradient(-45deg, rgba(0, 0, 0, 0.02) 25%, transparent 25%),
827
+ linear-gradient(45deg, transparent 75%, rgba(0, 0, 0, 0.02) 75%),
828
+ linear-gradient(-45deg, transparent 75%, rgba(0, 0, 0, 0.02) 75%);
829
+ background-size: 20px 20px;
830
+ background-position: 0 0, 0 10px, 10px -10px, -10px 0;
831
+ }
832
+
833
+ .ree-stage-view[hidden] {
834
+ display: none;
835
+ }
836
+
837
+ .ree-canvas,
838
+ .ree-preview-stage {
839
+ display: flex;
840
+ flex-direction: column;
841
+ flex: 1;
842
+ min-height: 0;
843
+ min-width: 0;
844
+ overflow: auto;
845
+ padding: 64px 24px;
846
+ }
847
+
848
+ .ree-canvas.is-over {
849
+ outline: 2px dashed var(--ree-primary);
850
+ outline-offset: -12px;
851
+ }
852
+
853
+ .ree-email-surface {
854
+ box-sizing: border-box;
855
+ margin: 0 auto;
856
+ }
857
+
858
+ .ree-root .ree-canvas-inner {
859
+ width: 100%;
860
+ box-sizing: border-box;
861
+ margin: 0 auto;
862
+ background: transparent;
863
+ display: flex;
864
+ flex-direction: column;
865
+ gap: var(--ree-block-gap, 0px);
866
+ }
867
+
868
+ .ree-preview-frame {
869
+ display: block;
870
+ width: 100%;
871
+ height: 1px;
872
+ flex-shrink: 0;
873
+ border: none;
874
+ background: #ffffff;
875
+ }
876
+
877
+ .ree-inspector-scroll {
878
+ flex: 1;
879
+ min-height: 0;
880
+ overflow-y: auto;
881
+ }
882
+
883
+ .ree-canvas-empty {
884
+ padding: 72px 24px;
885
+ text-align: center;
886
+ color: var(--ree-muted);
887
+ border: 2px dashed var(--ree-border);
888
+ }
889
+
890
+
891
+ .ree-email-viewport {
892
+ box-sizing: border-box;
893
+ flex: 1 0 auto;
894
+ }
895
+
896
+ .ree-canvas .ree-email-viewport {
897
+ background: rgb(246, 246, 247);
898
+ box-shadow: var(--ree-shadow-md);
899
+ }
900
+
901
+ /* ---------- 区块 ---------- */
902
+
903
+ .ree-block {
904
+ position: relative;
905
+ border: 0;
906
+ border-radius: 0;
907
+ background: transparent;
908
+ cursor: pointer;
909
+ transition: background 0.12s ease;
910
+ width: 100%;
911
+ display: flow-root;
912
+ }
913
+
914
+ /* hover 和选中共用外侧辅助框,内沿贴住区块,不覆盖真实边框或占用布局空间。 */
915
+ .ree-block-highlight {
916
+ position: absolute;
917
+ inset: -1px;
918
+ z-index: 5;
919
+ border: 1px solid transparent;
920
+ pointer-events: none;
921
+ transition: border-color 0.12s ease;
922
+ }
923
+
924
+ .ree-block:hover {
925
+ z-index: 1;
926
+ background: var(--ree-accent-bg);
927
+ }
928
+
929
+ .ree-block:hover > .ree-block-highlight {
930
+ border-color: var(--ree-accent-border);
931
+ }
932
+
933
+ .ree-block.is-selected {
934
+ z-index: 8;
935
+ background: var(--ree-accent-bg-strong);
936
+ }
937
+
938
+ .ree-block.is-selected > .ree-block-highlight {
939
+ border-color: var(--ree-primary);
940
+ }
941
+
942
+ .ree-block.is-dragging {
943
+ opacity: 0.5;
944
+ }
945
+
946
+ .ree-block.is-drop-before::before,
947
+ .ree-block.is-drop-after::after {
948
+ content: "";
949
+ position: absolute;
950
+ left: 0;
951
+ right: 0;
952
+ height: 2px;
953
+ background: var(--ree-primary);
954
+ pointer-events: none;
955
+ z-index: 9;
956
+ }
957
+
958
+ .ree-block.is-drop-before::before {
959
+ top: -1px;
960
+ }
961
+
962
+ .ree-block.is-drop-after::after {
963
+ bottom: -1px;
964
+ }
965
+
966
+ /* 左侧拖拽把手(hover / 选中时出现,可拖动排序) */
967
+ .ree-block-grip {
968
+ position: absolute;
969
+ left: -12px;
970
+ top: 50%;
971
+ transform: translateY(-50%);
972
+ z-index: 6;
973
+ appearance: none;
974
+ display: flex;
975
+ align-items: center;
976
+ justify-content: center;
977
+ width: 24px;
978
+ height: 34px;
979
+ padding: 0;
980
+ background: var(--ree-panel);
981
+ border: 1px solid var(--ree-border);
982
+ border-radius: var(--ree-radius-sm);
983
+ color: var(--ree-muted);
984
+ box-shadow: var(--ree-shadow-sm);
985
+ cursor: grab;
986
+ opacity: 0;
987
+ visibility: hidden;
988
+ pointer-events: none;
989
+ transition: opacity 0.12s ease, visibility 0.12s ease, border-color 0.12s ease,
990
+ color 0.12s ease;
991
+ }
992
+
993
+ .ree-block-grip:active {
994
+ cursor: grabbing;
995
+ }
996
+
997
+ .ree-block-grip:focus-visible {
998
+ outline: none;
999
+ box-shadow: 0 0 0 2px var(--ree-panel), 0 0 0 4px var(--ree-primary);
1000
+ }
1001
+
1002
+ .ree-block:hover .ree-block-grip,
1003
+ .ree-block.is-selected .ree-block-grip {
1004
+ opacity: 1;
1005
+ visibility: visible;
1006
+ pointer-events: auto;
1007
+ }
1008
+
1009
+ .ree-block:hover .ree-block-grip {
1010
+ border-color: var(--ree-accent-border);
1011
+ color: var(--ree-primary);
1012
+ }
1013
+
1014
+ /* 右下角当前区块类型标签 */
1015
+ .ree-block-badge {
1016
+ position: absolute;
1017
+ right: 8px;
1018
+ bottom: -11px;
1019
+ z-index: 6;
1020
+ padding: 2px 9px;
1021
+ font-size: 11px;
1022
+ font-weight: 600;
1023
+ letter-spacing: 0.02em;
1024
+ line-height: 1.5;
1025
+ color: var(--ree-primary);
1026
+ background: var(--ree-panel);
1027
+ border: 1px solid var(--ree-accent-border);
1028
+ border-radius: 999px;
1029
+ box-shadow: var(--ree-shadow-sm);
1030
+ opacity: 0;
1031
+ pointer-events: none;
1032
+ transition: opacity 0.12s ease;
1033
+ }
1034
+
1035
+ .ree-block:hover .ree-block-badge,
1036
+ .ree-block.is-selected .ree-block-badge {
1037
+ opacity: 1;
1038
+ }
1039
+
1040
+ .ree-block-toolbar {
1041
+ position: absolute;
1042
+ top: calc(100% + 4px);
1043
+ left: 0;
1044
+ z-index: 7;
1045
+ display: flex;
1046
+ gap: 2px;
1047
+ background: var(--ree-panel, #ffffff);
1048
+ border: 1px solid var(--ree-border);
1049
+ border-radius: var(--ree-radius);
1050
+ padding: 3px;
1051
+ box-shadow: var(--ree-shadow-md);
1052
+ font-family: var(--ree-font);
1053
+ }
1054
+
1055
+ .ree-block-btn {
1056
+ position: relative;
1057
+ appearance: none;
1058
+ border: none;
1059
+ background: transparent;
1060
+ width: 26px;
1061
+ height: 26px;
1062
+ border-radius: var(--ree-radius-sm);
1063
+ cursor: pointer;
1064
+ color: var(--ree-text);
1065
+ display: inline-flex;
1066
+ align-items: center;
1067
+ justify-content: center;
1068
+ transition: background 0.12s ease, color 0.12s ease;
1069
+ }
1070
+
1071
+ .ree-block-btn:hover {
1072
+ background: var(--ree-panel-secondary);
1073
+ color: var(--ree-primary);
1074
+ }
1075
+
1076
+ .ree-block-btn:active {
1077
+ background: var(--ree-accent-bg-strong);
1078
+ color: var(--ree-primary);
1079
+ }
1080
+
1081
+ .ree-block-btn:focus-visible {
1082
+ outline: 2px solid var(--ree-primary);
1083
+ outline-offset: 1px;
1084
+ }
1085
+
1086
+ .ree-block-btn.ree-danger:hover {
1087
+ background: var(--ree-danger-soft);
1088
+ color: var(--ree-danger);
1089
+ }
1090
+
1091
+ .ree-block-btn.ree-danger:active {
1092
+ background: var(--ree-danger-soft);
1093
+ color: var(--ree-danger);
1094
+ }
1095
+
1096
+ .ree-block-tooltip {
1097
+ position: absolute;
1098
+ top: calc(100% + 8px);
1099
+ left: 0;
1100
+ z-index: 10;
1101
+ display: none;
1102
+ padding: 6px 9px;
1103
+ border-radius: var(--ree-radius-sm);
1104
+ background: var(--ree-text);
1105
+ color: var(--ree-panel);
1106
+ box-shadow: var(--ree-shadow-md);
1107
+ font-size: 12px;
1108
+ font-weight: 500;
1109
+ line-height: 1.4;
1110
+ white-space: nowrap;
1111
+ cursor: default;
1112
+ }
1113
+
1114
+ .ree-block-tooltip::before {
1115
+ content: "";
1116
+ position: absolute;
1117
+ top: -8px;
1118
+ left: 0;
1119
+ width: 100%;
1120
+ height: 8px;
1121
+ }
1122
+
1123
+ .ree-block-btn:hover .ree-block-tooltip,
1124
+ .ree-block-btn:focus-visible .ree-block-tooltip {
1125
+ display: block;
1126
+ }
1127
+
1128
+ .ree-block-content {
1129
+ width: 100%;
1130
+ overflow: hidden;
1131
+ /* 预览 iframe 使用浏览器默认渲染。宿主页面的抗锯齿和连字设置不要渗进邮件正文。 */
1132
+ font-feature-settings: normal;
1133
+ -webkit-font-smoothing: auto;
1134
+ -moz-osx-font-smoothing: auto;
1135
+ }
1136
+
1137
+ /* 宿主样式会直接写到 p 和标题上,例如 Polaris 把它们的字重设为 450。
1138
+ 这些规则压过容器上的继承,画布就会和预览不一致。正文改回继承区块排版。
1139
+ strong、em、a、span 除外,行内加粗、斜体和链接色仍然有效。 */
1140
+ .ree-block-content :is(p, h1, h2, h3, h4, h5, h6, li) {
1141
+ font-family: inherit;
1142
+ font-size: inherit;
1143
+ font-weight: inherit;
1144
+ font-style: inherit;
1145
+ line-height: inherit;
1146
+ letter-spacing: inherit;
1147
+ color: inherit;
1148
+ text-align: inherit;
1149
+ }
1150
+
1151
+ /* 文案在框内编辑。工具栏和下拉要画出内容盒,不能被选中框裁掉。 */
1152
+ .ree-block-content.is-inline {
1153
+ overflow: visible;
1154
+ }
1155
+
1156
+ .ree-block-static {
1157
+ min-height: 0;
1158
+ }
1159
+
1160
+ .ree-html-canvas {
1161
+ position: relative;
1162
+ width: 100%;
1163
+ min-height: 0;
1164
+ overflow: hidden;
1165
+ }
1166
+
1167
+ .ree-html-canvas-text {
1168
+ white-space: pre-wrap;
1169
+ overflow-wrap: anywhere;
1170
+ }
1171
+
1172
+ .ree-html-canvas-hitbox {
1173
+ position: absolute;
1174
+ inset: 0;
1175
+ z-index: 2;
1176
+ display: block;
1177
+ width: 100%;
1178
+ height: 100%;
1179
+ padding: 0;
1180
+ border: 0;
1181
+ background: transparent;
1182
+ cursor: pointer;
1183
+ }
1184
+
1185
+ .ree-html-canvas-hitbox:focus {
1186
+ outline: none;
1187
+ }
1188
+
1189
+ .ree-html-canvas-frame {
1190
+ position: absolute;
1191
+ top: 0;
1192
+ left: 0;
1193
+ display: block;
1194
+ border: 0;
1195
+ transform-origin: top left;
1196
+ pointer-events: none;
1197
+ }
1198
+
1199
+ .ree-block-content a {
1200
+ pointer-events: none;
1201
+ }
1202
+
1203
+ .ree-button-canvas-row {
1204
+ width: 100%;
1205
+ border: 0;
1206
+ }
1207
+
1208
+ /* ---------- 富文本 ---------- */
1209
+
1210
+ .ree-rte-loading {
1211
+ color: var(--ree-muted);
1212
+ font-size: 14px;
1213
+ padding: 8px 0;
1214
+ }
1215
+
1216
+ /* 挂到 .ree-root,避开画布 overflow,同时继承主题变量。位置按区块视口计算。 */
1217
+ .ree-rte-toolbar {
1218
+ position: fixed;
1219
+ z-index: 80;
1220
+ top: 0;
1221
+ left: 0;
1222
+ visibility: hidden;
1223
+ display: flex;
1224
+ flex-wrap: wrap;
1225
+ align-items: center;
1226
+ gap: 4px 0;
1227
+ width: auto;
1228
+ margin: 0;
1229
+ padding: 4px;
1230
+ background: var(--ree-panel, #ffffff);
1231
+ border: 1px solid var(--ree-border, #e3e3e5);
1232
+ border-radius: var(--ree-radius, 8px);
1233
+ box-shadow: var(--ree-shadow-md, 0 2px 16px rgba(31, 33, 36, 0.08));
1234
+ color: var(--ree-text, #202223);
1235
+ font-family: var(--ree-font, Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
1236
+ font-weight: 500;
1237
+ }
1238
+
1239
+ .ree-rte-toolbar.is-placed {
1240
+ visibility: visible;
1241
+ }
1242
+
1243
+ .ree-rte-group {
1244
+ display: flex;
1245
+ flex: 0 0 auto;
1246
+ flex-wrap: wrap;
1247
+ align-items: center;
1248
+ gap: 2px;
1249
+ max-width: 100%;
1250
+ box-sizing: border-box;
1251
+ padding: 0 4px;
1252
+ }
1253
+
1254
+ .ree-rte-group + .ree-rte-group {
1255
+ border-inline-start: 1px solid var(--ree-border);
1256
+ }
1257
+
1258
+ .ree-rte-group.is-row-start {
1259
+ border-inline-start-color: transparent;
1260
+ }
1261
+
1262
+ .ree-rte-group > * {
1263
+ flex-shrink: 0;
1264
+ }
1265
+
1266
+ .ree-tool-btn,
1267
+ .ree-rte-select {
1268
+ appearance: none;
1269
+ border: none;
1270
+ background: transparent;
1271
+ height: 28px;
1272
+ border-radius: var(--ree-radius-sm);
1273
+ cursor: pointer;
1274
+ color: var(--ree-text);
1275
+ font: inherit;
1276
+ font-size: 13px;
1277
+ line-height: 1;
1278
+ transition: background 0.12s ease, color 0.12s ease;
1279
+ }
1280
+
1281
+ .ree-tool-btn {
1282
+ display: inline-flex;
1283
+ align-items: center;
1284
+ justify-content: center;
1285
+ min-width: 28px;
1286
+ padding: 0 4px;
1287
+ }
1288
+
1289
+ .ree-rte-select {
1290
+ display: inline-flex;
1291
+ align-items: center;
1292
+ gap: 4px;
1293
+ max-width: 168px;
1294
+ padding: 0 6px 0 8px;
1295
+ }
1296
+
1297
+ .ree-rte-select-label {
1298
+ overflow: hidden;
1299
+ text-overflow: ellipsis;
1300
+ white-space: nowrap;
1301
+ }
1302
+
1303
+ .ree-tool-btn:hover,
1304
+ .ree-tool-btn.is-open,
1305
+ .ree-rte-select:hover,
1306
+ .ree-rte-select.is-open {
1307
+ background: var(--ree-panel-secondary);
1308
+ }
1309
+
1310
+ .ree-tool-btn.is-active {
1311
+ background: #202223;
1312
+ color: #ffffff;
1313
+ }
1314
+
1315
+ .ree-tool-btn:disabled {
1316
+ opacity: 0.35;
1317
+ cursor: default;
1318
+ }
1319
+
1320
+ .ree-tool-btn:disabled:hover {
1321
+ background: transparent;
1322
+ color: var(--ree-text);
1323
+ }
1324
+
1325
+ .ree-tool-bold {
1326
+ font-weight: 700;
1327
+ }
1328
+
1329
+ .ree-tool-italic {
1330
+ font-family: Georgia, "Times New Roman", serif;
1331
+ font-style: italic;
1332
+ }
1333
+
1334
+ .ree-tool-underline {
1335
+ text-decoration: underline;
1336
+ text-underline-offset: 2px;
1337
+ }
1338
+
1339
+ .ree-tool-strike {
1340
+ text-decoration: line-through;
1341
+ }
1342
+
1343
+ .ree-tool-color {
1344
+ font-weight: 700;
1345
+ font-size: 14px;
1346
+ line-height: 1;
1347
+ border-bottom: 3px solid currentColor;
1348
+ padding-bottom: 1px;
1349
+ }
1350
+
1351
+ .ree-rte-pop {
1352
+ position: relative;
1353
+ }
1354
+
1355
+ .ree-rte-menu {
1356
+ position: absolute;
1357
+ top: calc(100% + 6px);
1358
+ left: 0;
1359
+ z-index: 30;
1360
+ min-width: 180px;
1361
+ max-height: 280px;
1362
+ overflow: auto;
1363
+ padding: 6px;
1364
+ background: var(--ree-panel, #ffffff);
1365
+ border: 1px solid var(--ree-border, #e3e3e5);
1366
+ border-radius: var(--ree-radius, 8px);
1367
+ box-shadow: var(--ree-shadow-lg, 0 6px 32px rgba(31, 33, 36, 0.16));
1368
+ color: var(--ree-text, #202223);
1369
+ font-size: 14px;
1370
+ }
1371
+
1372
+ .ree-rte-menu.is-end {
1373
+ left: auto;
1374
+ right: 0;
1375
+ }
1376
+
1377
+ .ree-rte-pop.is-up .ree-rte-menu {
1378
+ top: auto;
1379
+ bottom: calc(100% + 6px);
1380
+ }
1381
+
1382
+ .ree-rte-option {
1383
+ display: flex;
1384
+ width: 100%;
1385
+ border: none;
1386
+ background: transparent;
1387
+ padding: 7px 8px;
1388
+ border-radius: var(--ree-radius-sm);
1389
+ cursor: pointer;
1390
+ color: var(--ree-text);
1391
+ font: inherit;
1392
+ font-size: 13px;
1393
+ text-align: left;
1394
+ }
1395
+
1396
+ .ree-rte-option:hover,
1397
+ .ree-rte-option.is-active {
1398
+ background: var(--ree-panel-secondary);
1399
+ }
1400
+
1401
+ .ree-rte-option.is-active {
1402
+ font-weight: 600;
1403
+ }
1404
+
1405
+ .ree-rte-emoji-grid {
1406
+ display: grid;
1407
+ grid-template-columns: repeat(8, 28px);
1408
+ gap: 2px;
1409
+ }
1410
+
1411
+ .ree-rte-emoji {
1412
+ width: 28px;
1413
+ height: 28px;
1414
+ padding: 0;
1415
+ border: none;
1416
+ border-radius: var(--ree-radius-sm);
1417
+ background: transparent;
1418
+ cursor: pointer;
1419
+ font-size: 16px;
1420
+ line-height: 1;
1421
+ }
1422
+
1423
+ .ree-rte-emoji:hover {
1424
+ background: var(--ree-panel-secondary);
1425
+ }
1426
+
1427
+ .ree-rte-variables {
1428
+ min-width: 220px;
1429
+ }
1430
+
1431
+ .ree-rte .ProseMirror {
1432
+ outline: none;
1433
+ display: flow-root;
1434
+ line-height: inherit;
1435
+ }
1436
+
1437
+ .ree-rte .ProseMirror p {
1438
+ margin: 0;
1439
+ margin-top: var(--ree-paragraph-gap, 0px);
1440
+ }
1441
+
1442
+ .ree-rte .ProseMirror p + p {
1443
+ margin-top: var(--ree-paragraph-gap, var(--ree-paragraph-spacing, 0px));
1444
+ }
1445
+
1446
+ .ree-rte-metric {
1447
+ display: grid;
1448
+ gap: 8px;
1449
+ width: 220px;
1450
+ padding: 4px;
1451
+ }
1452
+
1453
+ .ree-rte-metric-label {
1454
+ display: flex;
1455
+ align-items: center;
1456
+ justify-content: space-between;
1457
+ gap: 8px;
1458
+ color: var(--ree-muted);
1459
+ font-size: 12px;
1460
+ }
1461
+
1462
+ .ree-rte-metric-meta {
1463
+ display: inline-flex;
1464
+ align-items: center;
1465
+ gap: 6px;
1466
+ }
1467
+
1468
+ .ree-rte-option:disabled {
1469
+ opacity: 0.35;
1470
+ cursor: default;
1471
+ }
1472
+
1473
+ .ree-rte .ProseMirror li p {
1474
+ margin: 0;
1475
+ }
1476
+
1477
+ .ree-rte .ProseMirror p.is-editor-empty:first-child::before {
1478
+ content: attr(data-placeholder);
1479
+ color: var(--ree-muted);
1480
+ float: left;
1481
+ height: 0;
1482
+ pointer-events: none;
1483
+ }
1484
+
1485
+ .ree-rte .ProseMirror a {
1486
+ color: var(--ree-link-color, #005bd3);
1487
+ text-decoration: var(--ree-link-decoration, underline);
1488
+ }
1489
+
1490
+ .ree-rte .ProseMirror ul,
1491
+ .ree-rte .ProseMirror ol {
1492
+ margin: var(--ree-list-spacing, 0.25em) 0;
1493
+ padding-left: var(--ree-list-indent, 1.4em);
1494
+ }
1495
+
1496
+ .ree-rte .ProseMirror sup,
1497
+ .ree-rte .ProseMirror sub {
1498
+ font-size: 0.75em;
1499
+ }
1500
+
1501
+ .ree-rte-button .ProseMirror p {
1502
+ margin: 0;
1503
+ text-align: center;
1504
+ }
1505
+
1506
+ /* ---------- 变量 ---------- */
1507
+
1508
+ .ree-var-wrap {
1509
+ position: relative;
1510
+ }
1511
+
1512
+ .ree-var-btn {
1513
+ appearance: none;
1514
+ border: none;
1515
+ background: transparent;
1516
+ min-width: 30px;
1517
+ height: 24px;
1518
+ padding: 0 6px;
1519
+ border-radius: var(--ree-radius-sm);
1520
+ cursor: pointer;
1521
+ color: var(--ree-muted);
1522
+ font-size: 12px;
1523
+ }
1524
+
1525
+ .ree-var-btn:hover {
1526
+ background: var(--ree-panel-secondary);
1527
+ }
1528
+
1529
+ .ree-var-menu {
1530
+ position: absolute;
1531
+ top: 100%;
1532
+ left: 0;
1533
+ z-index: 20;
1534
+ min-width: 200px;
1535
+ background: var(--ree-panel, #ffffff);
1536
+ border: 1px solid var(--ree-border, #e3e3e5);
1537
+ border-radius: var(--ree-radius, 8px);
1538
+ box-shadow: var(--ree-shadow-lg, 0 6px 32px rgba(31, 33, 36, 0.16));
1539
+ padding: 6px;
1540
+ max-height: 240px;
1541
+ overflow-y: auto;
1542
+ color: var(--ree-text, #202223);
1543
+ }
1544
+
1545
+ .ree-var-item {
1546
+ display: flex;
1547
+ flex-direction: column;
1548
+ align-items: flex-start;
1549
+ width: 100%;
1550
+ border: none;
1551
+ background: transparent;
1552
+ padding: 8px 10px;
1553
+ border-radius: var(--ree-radius-sm);
1554
+ cursor: pointer;
1555
+ text-align: left;
1556
+ }
1557
+
1558
+ .ree-var-item:hover {
1559
+ background: var(--ree-panel-secondary);
1560
+ }
1561
+
1562
+ .ree-var-name {
1563
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
1564
+ font-size: 12px;
1565
+ color: var(--ree-primary);
1566
+ }
1567
+
1568
+ .ree-var-label {
1569
+ font-size: 12px;
1570
+ color: var(--ree-muted);
1571
+ }
1572
+
1573
+
1574
+ /* ---------- 配置区 ---------- */
1575
+
1576
+ .ree-col-right {
1577
+ --ree-primary: #202223;
1578
+ --ree-primary-hover: #303030;
1579
+ --ree-primary-soft: #f6f6f7;
1580
+ }
1581
+
1582
+ .ree-inspector {
1583
+ --ree-inspector-section-space: 16px;
1584
+ padding: 20px 16px;
1585
+ display: flex;
1586
+ flex-direction: column;
1587
+ }
1588
+
1589
+ .ree-inspector-empty {
1590
+ padding: 40px 16px;
1591
+ text-align: center;
1592
+ color: var(--ree-muted);
1593
+ font-size: 14px;
1594
+ }
1595
+
1596
+ .ree-inspector-head {
1597
+ display: flex;
1598
+ align-items: center;
1599
+ gap: 10px;
1600
+ padding-bottom: var(--ree-inspector-section-space);
1601
+ font-weight: 600;
1602
+ }
1603
+
1604
+ .ree-inspector-icon {
1605
+ display: inline-flex;
1606
+ color: var(--ree-muted);
1607
+ }
1608
+
1609
+ .ree-inspector-title {
1610
+ font-size: 15px;
1611
+ }
1612
+
1613
+ .ree-inspector-section {
1614
+ border-top: 1px solid var(--ree-border-subdued);
1615
+ display: flex;
1616
+ flex-direction: column;
1617
+ }
1618
+
1619
+ .ree-inspector-section-toggle {
1620
+ display: flex;
1621
+ align-items: center;
1622
+ justify-content: space-between;
1623
+ width: 100%;
1624
+ margin: 0;
1625
+ padding: var(--ree-inspector-section-space) 0;
1626
+ border: 0;
1627
+ background: transparent;
1628
+ cursor: pointer;
1629
+ font: inherit;
1630
+ font-size: 13px;
1631
+ font-weight: 600;
1632
+ color: var(--ree-text);
1633
+ text-align: left;
1634
+ }
1635
+
1636
+ .ree-inspector-section-toggle svg {
1637
+ flex-shrink: 0;
1638
+ color: var(--ree-muted);
1639
+ transition: transform 0.15s ease;
1640
+ }
1641
+
1642
+ .ree-inspector-section-toggle[aria-expanded="false"] svg {
1643
+ transform: rotate(-90deg);
1644
+ }
1645
+
1646
+ .ree-inspector-section-body {
1647
+ display: flex;
1648
+ flex-direction: column;
1649
+ gap: 14px;
1650
+ padding-bottom: var(--ree-inspector-section-space);
1651
+ }
1652
+
1653
+ /* Global 没有标题区,容器顶部留白会叠到第一个类目上。 */
1654
+ .ree-inspector-global {
1655
+ padding-top: 0;
1656
+ padding-bottom: 0;
1657
+ }
1658
+
1659
+ .ree-inspector-global > .ree-inspector-section:first-child {
1660
+ border-top: 0;
1661
+ }
1662
+
1663
+ .ree-inspector-hint {
1664
+ font-size: 13px;
1665
+ color: var(--ree-muted);
1666
+ }
1667
+
1668
+ .ree-field {
1669
+ display: flex;
1670
+ flex-direction: column;
1671
+ gap: 6px;
1672
+ }
1673
+
1674
+ .ree-field-label {
1675
+ display: flex;
1676
+ align-items: center;
1677
+ justify-content: space-between;
1678
+ gap: 8px;
1679
+ font-size: 13px;
1680
+ color: var(--ree-muted, #6d7175);
1681
+ }
1682
+
1683
+ .ree-field-meta {
1684
+ display: inline-flex;
1685
+ align-items: center;
1686
+ gap: 6px;
1687
+ margin-left: auto;
1688
+ }
1689
+
1690
+ .ree-inspector-advanced summary {
1691
+ cursor: pointer;
1692
+ color: var(--ree-muted);
1693
+ font-size: 12px;
1694
+ }
1695
+
1696
+ .ree-inspector-advanced[open] summary {
1697
+ margin-bottom: 14px;
1698
+ }
1699
+
1700
+ .ree-field-label:has(> .ree-var-wrap) {
1701
+ position: relative;
1702
+ justify-content: flex-start;
1703
+ }
1704
+
1705
+ .ree-field-label > .ree-var-wrap {
1706
+ position: static;
1707
+ }
1708
+
1709
+ .ree-field-label .ree-var-menu {
1710
+ left: 0;
1711
+ width: min(280px, 100%);
1712
+ min-width: 0;
1713
+ }
1714
+
1715
+ .ree-field-label .ree-var-name,
1716
+ .ree-field-label .ree-var-label {
1717
+ max-width: 100%;
1718
+ overflow-wrap: anywhere;
1719
+ white-space: pre-wrap;
1720
+ }
1721
+
1722
+ /* ---------- 配置控件 ---------- */
1723
+
1724
+ .ree-textarea {
1725
+ resize: vertical;
1726
+ min-height: 60px;
1727
+ line-height: 1.5;
1728
+ }
1729
+
1730
+ .ree-html-editor {
1731
+ --ree-html-editor-min: 220px;
1732
+ border: 1px solid var(--ree-border);
1733
+ border-radius: var(--ree-radius);
1734
+ overflow: hidden;
1735
+ background: #f6f8fa;
1736
+ }
1737
+
1738
+ .ree-html-editor:focus-within {
1739
+ border-color: var(--ree-primary);
1740
+ box-shadow: 0 0 0 1px var(--ree-primary);
1741
+ }
1742
+
1743
+ .ree-html-editor .cm-editor {
1744
+ width: 100%;
1745
+ max-height: 440px;
1746
+ background: #f6f8fa;
1747
+ }
1748
+
1749
+ .ree-html-editor .cm-scroller {
1750
+ min-height: var(--ree-html-editor-min);
1751
+ max-height: 440px;
1752
+ overflow: auto;
1753
+ }
1754
+
1755
+ .ree-html-editor .ree-cm-template {
1756
+ color: #9a6700;
1757
+ background: #fff8c5;
1758
+ border-radius: 2px;
1759
+ }
1760
+
1761
+ .ree-color-grid {
1762
+ display: flex;
1763
+ flex-wrap: wrap;
1764
+ gap: 12px 16px;
1765
+ }
1766
+
1767
+ .ree-color-chip-row {
1768
+ display: flex;
1769
+ align-items: center;
1770
+ gap: 2px;
1771
+ min-width: 0;
1772
+ }
1773
+
1774
+ .ree-field-value {
1775
+ font-size: 12px;
1776
+ color: var(--ree-muted);
1777
+ font-variant-numeric: tabular-nums;
1778
+ }
1779
+
1780
+ .ree-input-group {
1781
+ display: flex;
1782
+ align-items: center;
1783
+ gap: 8px;
1784
+ }
1785
+
1786
+ .ree-input-group .ree-input {
1787
+ flex: 1;
1788
+ }
1789
+
1790
+ .ree-input-unit {
1791
+ font-size: 13px;
1792
+ color: var(--ree-muted);
1793
+ flex-shrink: 0;
1794
+ }
1795
+
1796
+ .ree-range-row {
1797
+ display: flex;
1798
+ align-items: center;
1799
+ gap: 8px;
1800
+ width: 100%;
1801
+ }
1802
+
1803
+ .ree-align-row {
1804
+ display: flex;
1805
+ gap: 4px;
1806
+ }
1807
+
1808
+ .ree-align-btn {
1809
+ flex: 1;
1810
+ appearance: none;
1811
+ border: 1px solid var(--ree-border);
1812
+ background: var(--ree-panel);
1813
+ border-radius: var(--ree-radius-sm);
1814
+ padding: 7px 0;
1815
+ cursor: pointer;
1816
+ color: var(--ree-muted);
1817
+ font-size: 14px;
1818
+ transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
1819
+ }
1820
+
1821
+ .ree-align-btn:hover {
1822
+ background: var(--ree-panel-secondary);
1823
+ }
1824
+
1825
+ .ree-align-btn.is-active {
1826
+ border-color: var(--ree-text);
1827
+ color: var(--ree-text);
1828
+ background: var(--ree-panel-secondary);
1829
+ }
1830
+
1831
+
1832
+ .ree-spacing-control { display: grid; gap: 10px; }
1833
+ .ree-spacing-link { gap: 6px; font-size: 12px; color: var(--ree-muted); }
1834
+ .ree-spacing-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
1835
+
1836
+ /* 原生 modal dialog 进入 top layer,覆盖整个视口并隔离背景交互。 */
1837
+ .ree-rte-link {
1838
+ position: fixed;
1839
+ inset: 0;
1840
+ width: min(440px, calc(100vw - 32px));
1841
+ max-width: none;
1842
+ max-height: calc(100dvh - 32px);
1843
+ margin: auto;
1844
+ padding: 0;
1845
+ overflow: auto;
1846
+ background: var(--ree-panel, #ffffff);
1847
+ border: 1px solid var(--ree-border, #e3e3e5);
1848
+ border-radius: 12px;
1849
+ box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);
1850
+ color: var(--ree-text, #202223);
1851
+ font: 400 14px/1.5 var(--ree-font, Arial, sans-serif);
1852
+ visibility: visible;
1853
+ }
1854
+
1855
+ .ree-rte-link::backdrop {
1856
+ background: rgba(0, 0, 0, 0.6);
1857
+ -webkit-backdrop-filter: blur(4px);
1858
+ backdrop-filter: blur(4px);
1859
+ }
1860
+
1861
+ .ree-rte-link-title {
1862
+ margin: 0;
1863
+ padding: 20px 24px;
1864
+ border-bottom: 1px solid var(--ree-border);
1865
+ font-size: 18px;
1866
+ font-weight: 600;
1867
+ line-height: 1.4;
1868
+ }
1869
+
1870
+ .ree-rte-link-fields {
1871
+ display: grid;
1872
+ gap: 20px;
1873
+ padding: 24px;
1874
+ }
1875
+
1876
+ .ree-rte-link-actions {
1877
+ display: flex;
1878
+ justify-content: flex-end;
1879
+ gap: 8px;
1880
+ padding: 16px 24px;
1881
+ border-top: 1px solid var(--ree-border);
1882
+ }
1883
+
1884
+ .ree-rte-link-actions .ree-btn {
1885
+ min-width: 80px;
1886
+ }
1887
+
1888
+ .ree-rte-link-error {
1889
+ margin: -12px 0 0;
1890
+ color: var(--ree-danger);
1891
+ font-size: 12px;
1892
+ }
1893
+
1894
+ /* ---------- 拖拽浮层 ---------- */
1895
+
1896
+ .ree-drag-overlay {
1897
+ display: flex;
1898
+ align-items: center;
1899
+ gap: 10px;
1900
+ padding: 12px 16px;
1901
+ background: var(--ree-panel);
1902
+ border: 1px solid var(--ree-primary);
1903
+ box-shadow: var(--ree-shadow-lg);
1904
+ cursor: grabbing;
1905
+ font-weight: 500;
1906
+ }