@aeriz/wysiwyg 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/LICENSE +201 -0
  2. package/dist/aeriz-wysiwyg.css +1471 -0
  3. package/dist/aeriz-wysiwyg.esm.js +5602 -0
  4. package/dist/aeriz-wysiwyg.esm.min.js +4227 -0
  5. package/dist/aeriz-wysiwyg.js +5605 -0
  6. package/dist/aeriz-wysiwyg.min.css +1 -0
  7. package/dist/aeriz-wysiwyg.min.js +23 -0
  8. package/dist-types/core/AerizEditor.d.ts +337 -0
  9. package/dist-types/core/AerizEditor.d.ts.map +1 -0
  10. package/dist-types/core/AerizViewer.d.ts +49 -0
  11. package/dist-types/core/AerizViewer.d.ts.map +1 -0
  12. package/dist-types/core/blocks.d.ts +303 -0
  13. package/dist-types/core/blocks.d.ts.map +1 -0
  14. package/dist-types/core/fonts.d.ts +49 -0
  15. package/dist-types/core/fonts.d.ts.map +1 -0
  16. package/dist-types/core/highlight.d.ts +44 -0
  17. package/dist-types/core/highlight.d.ts.map +1 -0
  18. package/dist-types/core/i18n.d.ts +209 -0
  19. package/dist-types/core/i18n.d.ts.map +1 -0
  20. package/dist-types/core/import-html.d.ts +28 -0
  21. package/dist-types/core/import-html.d.ts.map +1 -0
  22. package/dist-types/core/import-markdown.d.ts +37 -0
  23. package/dist-types/core/import-markdown.d.ts.map +1 -0
  24. package/dist-types/index.d.ts +11 -0
  25. package/dist-types/index.d.ts.map +1 -0
  26. package/dist-types/types/index.d.ts +40 -0
  27. package/dist-types/types/index.d.ts.map +1 -0
  28. package/dist-types/ui/Toolbar.d.ts +21 -0
  29. package/dist-types/ui/Toolbar.d.ts.map +1 -0
  30. package/dist-types/ui/dialogs.d.ts +74 -0
  31. package/dist-types/ui/dialogs.d.ts.map +1 -0
  32. package/dist-types/ui/icons.d.ts +2 -0
  33. package/dist-types/ui/icons.d.ts.map +1 -0
  34. package/dist-types/ui/popovers.d.ts +70 -0
  35. package/dist-types/ui/popovers.d.ts.map +1 -0
  36. package/package.json +57 -0
@@ -0,0 +1,1471 @@
1
+ .aeriz-wysiwyg {
2
+ --aw-bg: #ffffff;
3
+ --aw-fg: #1a1a1a;
4
+ --aw-fg-muted: #6b7280;
5
+ --aw-border: #e5e7eb;
6
+ --aw-toolbar-bg: #f9fafb;
7
+ --aw-toolbar-fg: #374151;
8
+ --aw-btn-hover-bg: #e5e7eb;
9
+ --aw-btn-active-bg: #dbeafe;
10
+ --aw-btn-active-fg: #1d4ed8;
11
+ --aw-primary: #03c75a;
12
+ --aw-primary-fg: #ffffff;
13
+ --aw-primary-hover: #02b150;
14
+ --aw-divider: #e5e7eb;
15
+ --aw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
16
+ --aw-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
17
+ --aw-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
18
+ --aw-radius: 6px;
19
+ --aw-radius-sm: 4px;
20
+ --aw-font: -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Pretendard',
21
+ 'Noto Sans KR', 'Malgun Gothic', sans-serif;
22
+ --aw-font-mono: 'SF Mono', Menlo, Monaco, Consolas, 'D2Coding', monospace;
23
+
24
+ --aw-toolbar-height: 44px;
25
+ --aw-z-toolbar: 10;
26
+ --aw-z-popover: 100;
27
+ --aw-z-dialog: 1000;
28
+ }
29
+
30
+ .aeriz-wysiwyg[data-theme='dark'] {
31
+ --aw-bg: #0a0e14;
32
+ --aw-fg: #e7eef5;
33
+ --aw-fg-muted: #6a7a8a;
34
+ --aw-border: rgba(100, 200, 255, 0.12);
35
+ --aw-toolbar-bg: #0d1320;
36
+ --aw-toolbar-fg: #cfd6dd;
37
+ --aw-btn-hover-bg: rgba(100, 200, 255, 0.06);
38
+ --aw-btn-active-bg: rgba(100, 200, 255, 0.14);
39
+ --aw-btn-active-fg: #64c8ff;
40
+ --aw-primary: #64c8ff;
41
+ --aw-primary-fg: #050810;
42
+ --aw-primary-hover: #8ad6ff;
43
+ --aw-divider: rgba(100, 200, 255, 0.12);
44
+ }
45
+
46
+ .aeriz-wysiwyg {
47
+ font-family: var(--aw-font);
48
+ background-color: var(--aw-bg);
49
+ color: var(--aw-fg);
50
+ border: 1px solid var(--aw-border);
51
+ border-radius: var(--aw-radius);
52
+ overflow: hidden;
53
+ display: flex;
54
+ flex-direction: column;
55
+ /* 부모가 명시적 높이를 주면 그 높이를 채우고 내부 컨텐츠가 스크롤되며,
56
+ 부모가 auto 면 min-height 가 floor 로 작용한다. */
57
+ height: 100%;
58
+ min-height: 320px;
59
+ box-shadow: var(--aw-shadow-sm);
60
+ }
61
+
62
+ .aeriz-wysiwyg *,
63
+ .aeriz-wysiwyg *::before,
64
+ .aeriz-wysiwyg *::after {
65
+ box-sizing: border-box;
66
+ }
67
+
68
+ .aw-content-wrap {
69
+ flex: 1;
70
+ /* flex 자식이 기본 min-content 크기 이상으로 줄어들 수 있게 함 — 이게 없으면
71
+ overflow-y:auto 가 부모를 밀어내 스크롤이 발생하지 않는다. */
72
+ min-height: 0;
73
+ overflow-y: auto;
74
+ background-color: var(--aw-bg);
75
+ position: relative; /* 드래그 핸들 / 드롭 인디케이터 절대 위치 기준 */
76
+ }
77
+
78
+ /* ─── 뷰어 모드 ─────────────────────────────────────────────────────
79
+ AerizViewer 는 컨텐츠 길이만큼 자연스럽게 늘어난다 (스크롤 / 고정 높이 X).
80
+ 에디터 기본 규칙을 viewer 클래스가 좁게 덮어쓴다. */
81
+
82
+ .aeriz-wysiwyg-viewer {
83
+ height: auto;
84
+ min-height: 0;
85
+ }
86
+
87
+ .aeriz-wysiwyg-viewer .aw-content-wrap {
88
+ flex: 0 0 auto;
89
+ overflow: visible;
90
+ min-height: 0;
91
+ }
92
+
93
+ .aeriz-wysiwyg-viewer .aw-content {
94
+ min-height: 0;
95
+ }
96
+
97
+ /* ─── 드래그 핸들 오버레이 ───────────────────────────────────────────── */
98
+
99
+ .aw-block-handles {
100
+ position: absolute;
101
+ top: 0;
102
+ left: 0;
103
+ width: 24px;
104
+ height: 100%;
105
+ pointer-events: none;
106
+ z-index: 2;
107
+ }
108
+
109
+ /* 블록별 컨트롤 그룹 — 드래그 핸들 + 단락 추가 버튼을 세로로 묶는다. */
110
+
111
+ .aw-block-controls {
112
+ position: absolute;
113
+ left: 4px;
114
+ display: flex;
115
+ flex-direction: column;
116
+ gap: 0;
117
+ pointer-events: none;
118
+ opacity: 0;
119
+ transition: opacity 0.12s ease;
120
+ }
121
+
122
+ .aw-content-wrap:hover .aw-block-controls {
123
+ opacity: 0.45;
124
+ }
125
+
126
+ .aw-block-controls:hover {
127
+ opacity: 1;
128
+ }
129
+
130
+ .aw-block-handle,
131
+ .aw-block-add {
132
+ width: 18px;
133
+ height: 22px;
134
+ display: inline-flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ background: transparent;
138
+ border: 1px solid transparent;
139
+ border-radius: 3px;
140
+ color: var(--aw-fg-muted);
141
+ pointer-events: auto;
142
+ user-select: none;
143
+ appearance: none;
144
+ padding: 0;
145
+ cursor: pointer;
146
+ transition: color 0.12s, background-color 0.12s, border-color 0.12s;
147
+ }
148
+
149
+ .aw-block-handle { cursor: grab; }
150
+
151
+ .aw-block-handle svg,
152
+ .aw-block-add svg {
153
+ width: 12px;
154
+ height: 14px;
155
+ }
156
+
157
+ .aw-block-handle:hover,
158
+ .aw-block-add:hover {
159
+ color: var(--aw-btn-active-fg, var(--aw-primary));
160
+ background-color: var(--aw-btn-hover-bg);
161
+ border-color: var(--aw-border);
162
+ }
163
+
164
+ .aw-block-handle.is-dragging {
165
+ cursor: grabbing;
166
+ color: var(--aw-primary);
167
+ }
168
+
169
+ .is-block-dragging {
170
+ opacity: 0.4;
171
+ }
172
+
173
+ /* ─── 드롭 위치 인디케이터 ───────────────────────────────────────────── */
174
+
175
+ .aw-block-drop-indicator {
176
+ position: absolute;
177
+ left: 28px;
178
+ right: 28px;
179
+ height: 2px;
180
+ background: var(--aw-primary);
181
+ border-radius: 1px;
182
+ pointer-events: none;
183
+ z-index: 3;
184
+ transform: translateY(-1px);
185
+ box-shadow: 0 0 6px var(--aw-primary);
186
+ }
187
+
188
+ /* ─── Status Bar ─────────────────────────────────────────────────────
189
+ 에디터 하단의 메타 정보 표시(활성 블록 / 블록 수 / 글자 수). 뷰어에는
190
+ 불필요하므로 .aeriz-wysiwyg-viewer 안에서는 숨긴다. */
191
+
192
+ .aw-status-bar {
193
+ display: flex;
194
+ align-items: center;
195
+ justify-content: space-between;
196
+ gap: 12px;
197
+ padding: 5px 12px;
198
+ border-top: 1px solid var(--aw-border);
199
+ background-color: var(--aw-toolbar-bg);
200
+ color: var(--aw-fg-muted);
201
+ font-family: var(--aw-font-mono);
202
+ font-size: 11px;
203
+ letter-spacing: 0.02em;
204
+ flex-shrink: 0;
205
+ }
206
+
207
+ .aw-status-left,
208
+ .aw-status-right {
209
+ display: inline-flex;
210
+ align-items: center;
211
+ gap: 12px;
212
+ min-width: 0;
213
+ }
214
+
215
+ .aw-status-item {
216
+ display: inline-flex;
217
+ align-items: center;
218
+ gap: 6px;
219
+ white-space: nowrap;
220
+ overflow: hidden;
221
+ text-overflow: ellipsis;
222
+ }
223
+
224
+ .aw-status-item::before {
225
+ content: '';
226
+ width: 5px;
227
+ height: 5px;
228
+ border-radius: 50%;
229
+ background: var(--aw-primary);
230
+ opacity: 0.55;
231
+ flex-shrink: 0;
232
+ }
233
+
234
+ /* status bar 안의 작은 아이콘 액션 버튼 (undo/redo 등) */
235
+
236
+ .aw-status-action {
237
+ appearance: none;
238
+ cursor: pointer;
239
+ background: transparent;
240
+ border: 1px solid transparent;
241
+ color: var(--aw-fg-muted);
242
+ padding: 0;
243
+ width: 22px;
244
+ height: 22px;
245
+ border-radius: 3px;
246
+ display: inline-flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ flex-shrink: 0;
250
+ transition: color 0.12s, background-color 0.12s, border-color 0.12s;
251
+ }
252
+
253
+ .aw-status-action svg {
254
+ width: 13px;
255
+ height: 13px;
256
+ }
257
+
258
+ .aw-status-action:hover {
259
+ color: var(--aw-btn-active-fg, var(--aw-primary));
260
+ background-color: var(--aw-btn-hover-bg);
261
+ border-color: var(--aw-border);
262
+ }
263
+
264
+ .aw-status-action:active {
265
+ background-color: var(--aw-btn-active-bg);
266
+ }
267
+
268
+ .aeriz-wysiwyg-viewer .aw-status-bar {
269
+ display: none;
270
+ }
271
+
272
+ /* ─── 블록 포커스 인디케이터 + 라벨 태그 ─────────────────────────────── */
273
+
274
+ .aw-content > [data-block-id] {
275
+ position: relative;
276
+ transition: background-color 0.12s ease, box-shadow 0.12s ease;
277
+ }
278
+
279
+ .aw-content > [data-block-focused] {
280
+ background-color: color-mix(in srgb, var(--aw-primary) 8%, transparent);
281
+ box-shadow: -3px 0 0 var(--aw-primary);
282
+ border-radius: 2px;
283
+ }
284
+
285
+ /* ─── 인터랙티브 블록 라벨 pill ───────────────────────────────────────
286
+ 활성 블록 위에 떠 있는 작은 버튼. 정적 ::before pseudo 라벨을 대체하며
287
+ 클릭 시 블록 유형 드롭다운을 열어 마이크로 인터랙션으로 유형 변경. */
288
+
289
+ .aw-block-label-pill {
290
+ position: absolute;
291
+ z-index: 4;
292
+ appearance: none;
293
+ font-family: var(--aw-font-mono);
294
+ font-size: 9px;
295
+ font-weight: 700;
296
+ letter-spacing: 0.08em;
297
+ text-transform: uppercase;
298
+ color: var(--aw-primary);
299
+ background: var(--aw-bg);
300
+ padding: 2px 6px 2px 6px;
301
+ border: 1px solid var(--aw-primary);
302
+ border-radius: 3px;
303
+ cursor: pointer;
304
+ user-select: none;
305
+ display: inline-flex;
306
+ align-items: center;
307
+ gap: 4px;
308
+ line-height: 1;
309
+ transition: transform 0.12s ease, background-color 0.12s, color 0.12s,
310
+ box-shadow 0.12s;
311
+ }
312
+
313
+ .aw-block-label-pill::after {
314
+ content: '▾';
315
+ font-size: 9px;
316
+ opacity: 0.7;
317
+ }
318
+
319
+ .aw-block-label-pill:hover {
320
+ background: var(--aw-primary);
321
+ color: var(--aw-bg);
322
+ transform: translateY(-1px);
323
+ box-shadow: 0 2px 6px color-mix(in srgb, var(--aw-primary) 35%, transparent);
324
+ }
325
+
326
+ .aw-block-label-pill:active {
327
+ transform: translateY(0);
328
+ }
329
+
330
+ .aw-content {
331
+ outline: none;
332
+ padding: 24px 28px;
333
+ min-height: 240px;
334
+ font-size: 15px;
335
+ line-height: 1.7;
336
+ color: var(--aw-fg);
337
+ word-break: break-word;
338
+ }
339
+
340
+ .aw-content:empty::before,
341
+ .aw-content[data-placeholder]:has(p:only-child > br:only-child)::before {
342
+ content: attr(data-placeholder);
343
+ color: var(--aw-fg-muted);
344
+ pointer-events: none;
345
+ position: absolute;
346
+ }
347
+
348
+ .aw-content > p {
349
+ margin: 0 0 0.8em 0;
350
+ }
351
+
352
+ .aw-content > p:last-child {
353
+ margin-bottom: 0;
354
+ }
355
+
356
+ .aw-content h1,
357
+ .aw-content h2,
358
+ .aw-content h3 {
359
+ font-weight: 700;
360
+ margin: 0.6em 0 0.4em;
361
+ padding-bottom: 0.25em;
362
+ border-bottom: 1px solid var(--aw-border);
363
+ }
364
+
365
+ .aw-content h1 { font-size: 1.875rem; line-height: 1.3; }
366
+
367
+ .aw-content h2 { font-size: 1.5rem; line-height: 1.35; }
368
+
369
+ .aw-content h3 { font-size: 1.25rem; line-height: 1.4; }
370
+
371
+ .aw-content blockquote {
372
+ margin: 1em 0;
373
+ padding: 0.5em 1em;
374
+ border-left: 4px solid var(--aw-primary);
375
+ background-color: color-mix(in srgb, var(--aw-primary) 8%, transparent);
376
+ color: var(--aw-fg);
377
+ font-style: italic;
378
+ }
379
+
380
+ .aw-content pre {
381
+ position: relative;
382
+ background-color: color-mix(in srgb, var(--aw-fg) 6%, var(--aw-bg));
383
+ border: 1px solid var(--aw-border);
384
+ border-radius: var(--aw-radius-sm);
385
+ padding: 12px 16px;
386
+ font-family: var(--aw-font-mono);
387
+ font-size: 13px;
388
+ line-height: 1.6;
389
+ overflow-x: auto;
390
+ margin: 1em 0;
391
+ }
392
+
393
+ /* 코드 블록 우상단의 언어 라벨 — `<code data-language="javascript">` 의
394
+ * data-language 가 있을 때만 표시. attr() 로 자동 동기화돼 별도 JS 갱신
395
+ * 불필요. 사용자가 드롭다운으로 언어 변경 시 CSS 가 즉시 반영. */
396
+
397
+ .aw-content > pre > code[data-language]:not([data-language=""])::before {
398
+ content: attr(data-language);
399
+ position: absolute;
400
+ top: 6px;
401
+ right: 10px;
402
+ font-size: 10px;
403
+ font-weight: 600;
404
+ letter-spacing: 0.06em;
405
+ text-transform: uppercase;
406
+ color: var(--aw-fg-muted);
407
+ background: color-mix(in srgb, var(--aw-fg) 10%, transparent);
408
+ padding: 2px 8px;
409
+ border-radius: 4px;
410
+ pointer-events: none;
411
+ user-select: none;
412
+ }
413
+
414
+ .aw-content code {
415
+ font-family: var(--aw-font-mono);
416
+ font-size: 0.9em;
417
+ background-color: color-mix(in srgb, var(--aw-fg) 8%, transparent);
418
+ padding: 0.15em 0.4em;
419
+ border-radius: 3px;
420
+ }
421
+
422
+ .aw-content pre code {
423
+ background: transparent;
424
+ padding: 0;
425
+ }
426
+
427
+ /* ─── Syntax highlight 토큰 색 (자체 highlight.ts 출력) ──────────── */
428
+
429
+ .aw-content pre code .hl-keyword { color: #c678dd; font-weight: 600; }
430
+
431
+ .aw-content pre code .hl-string { color: #98c379; }
432
+
433
+ .aw-content pre code .hl-number { color: #d19a66; }
434
+
435
+ .aw-content pre code .hl-comment { color: var(--aw-fg-muted); font-style: italic; }
436
+
437
+ .aw-content pre code .hl-fn { color: #61afef; }
438
+
439
+ .aw-content pre code .hl-builtin { color: #56b6c2; }
440
+
441
+ .aw-content pre code .hl-tag { color: #e06c75; }
442
+
443
+ .aw-content pre code .hl-attr { color: #d19a66; }
444
+
445
+ .aw-content pre code .hl-prop { color: #61afef; }
446
+
447
+ .aw-content pre code .hl-punct { color: var(--aw-fg-muted); }
448
+
449
+ /* light 테마 보정 */
450
+
451
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-keyword { color: #a626a4; }
452
+
453
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-string { color: #50a14f; }
454
+
455
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-number { color: #986801; }
456
+
457
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-fn { color: #4078f2; }
458
+
459
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-builtin { color: #0184bc; }
460
+
461
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-tag { color: #e45649; }
462
+
463
+ .aeriz-wysiwyg[data-theme='light'] .aw-content pre code .hl-prop { color: #4078f2; }
464
+
465
+ .aw-content ul,
466
+ .aw-content ol {
467
+ margin: 0.6em 0;
468
+ padding-left: 1.6em;
469
+ }
470
+
471
+ .aw-content li {
472
+ margin: 0.2em 0;
473
+ }
474
+
475
+ .aw-content a {
476
+ color: var(--aw-primary);
477
+ text-decoration: underline;
478
+ }
479
+
480
+ .aw-content img {
481
+ max-width: 100%;
482
+ height: auto;
483
+ border-radius: var(--aw-radius-sm);
484
+ margin: 0.5em 0;
485
+ }
486
+
487
+ .aw-content hr {
488
+ border: none;
489
+ border-top: 1px solid var(--aw-border);
490
+ margin: 1.5em 0;
491
+ }
492
+
493
+ /* ─── 유튜브 임베드 (16:9 반응형 컨테이너) ──────────────────── */
494
+
495
+ .aw-content > div.aw-youtube-embed {
496
+ position: relative;
497
+ width: 100%;
498
+ aspect-ratio: 16 / 9;
499
+ margin: 1em 0;
500
+ border-radius: 8px;
501
+ overflow: hidden;
502
+ background: #000;
503
+ border: 1px solid var(--aw-border);
504
+ }
505
+
506
+ .aw-content > div.aw-youtube-embed iframe {
507
+ position: absolute;
508
+ inset: 0;
509
+ width: 100%;
510
+ height: 100%;
511
+ border: 0;
512
+ display: block;
513
+ }
514
+
515
+ /* ─── 파일 첨부 (다운로드 카드) ──────────────────── */
516
+
517
+ .aw-content > a.aw-file-attachment {
518
+ display: flex;
519
+ align-items: center;
520
+ gap: 12px;
521
+ margin: 1em 0;
522
+ padding: 10px 14px;
523
+ border: 1px solid var(--aw-border);
524
+ border-radius: 8px;
525
+ background: var(--aw-bg);
526
+ color: var(--aw-fg);
527
+ text-decoration: none;
528
+ transition: background-color 0.08s, border-color 0.08s;
529
+ cursor: pointer;
530
+ user-select: none;
531
+ }
532
+
533
+ .aw-content > a.aw-file-attachment:hover {
534
+ background: color-mix(in srgb, var(--aw-fg) 5%, var(--aw-bg));
535
+ border-color: color-mix(in srgb, var(--aw-primary) 40%, var(--aw-border));
536
+ }
537
+
538
+ .aw-content > a.aw-file-attachment .aw-file-icon {
539
+ flex: 0 0 auto;
540
+ display: inline-flex;
541
+ width: 36px;
542
+ height: 36px;
543
+ align-items: center;
544
+ justify-content: center;
545
+ border-radius: 6px;
546
+ background: color-mix(in srgb, var(--aw-primary) 12%, transparent);
547
+ color: var(--aw-primary);
548
+ }
549
+
550
+ .aw-content > a.aw-file-attachment .aw-file-icon svg {
551
+ width: 20px;
552
+ height: 20px;
553
+ }
554
+
555
+ .aw-content > a.aw-file-attachment .aw-file-meta {
556
+ flex: 1 1 auto;
557
+ min-width: 0;
558
+ display: flex;
559
+ flex-direction: column;
560
+ gap: 2px;
561
+ }
562
+
563
+ .aw-content > a.aw-file-attachment .aw-file-name {
564
+ font-weight: 600;
565
+ font-size: 0.95rem;
566
+ color: var(--aw-fg);
567
+ word-break: break-all;
568
+ line-height: 1.3;
569
+ }
570
+
571
+ .aw-content > a.aw-file-attachment .aw-file-info {
572
+ font-size: 0.75rem;
573
+ color: var(--aw-fg-muted);
574
+ font-family: var(--aw-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
575
+ letter-spacing: 0.02em;
576
+ }
577
+
578
+ .aw-content > a.aw-file-attachment .aw-file-action {
579
+ flex: 0 0 auto;
580
+ display: inline-flex;
581
+ width: 32px;
582
+ height: 32px;
583
+ align-items: center;
584
+ justify-content: center;
585
+ color: var(--aw-fg-muted);
586
+ }
587
+
588
+ .aw-content > a.aw-file-attachment .aw-file-action svg {
589
+ width: 18px;
590
+ height: 18px;
591
+ }
592
+
593
+ .aw-content > a.aw-file-attachment:hover .aw-file-action {
594
+ color: var(--aw-primary);
595
+ }
596
+
597
+ /* ─── 링크 카드 (Open Graph 스타일 미리보기) ──────────────────── */
598
+
599
+ .aw-content > a.aw-link-card {
600
+ display: flex;
601
+ align-items: stretch;
602
+ gap: 14px;
603
+ text-decoration: none;
604
+ margin: 1em 0;
605
+ padding: 0;
606
+ border: 1px solid var(--aw-border);
607
+ border-radius: 8px;
608
+ background-color: color-mix(in srgb, var(--aw-primary) 5%, var(--aw-bg));
609
+ color: var(--aw-fg);
610
+ overflow: hidden;
611
+ transition: border-color 0.12s, background-color 0.12s;
612
+ }
613
+
614
+ .aw-content > a.aw-link-card:hover {
615
+ border-color: var(--aw-primary);
616
+ background-color: color-mix(in srgb, var(--aw-primary) 9%, var(--aw-bg));
617
+ }
618
+
619
+ /* 좌측 og:image 썸네일 — 있을 때만. */
620
+
621
+ .aw-content > a.aw-link-card > .aw-link-card-image {
622
+ flex: 0 0 auto;
623
+ width: 120px;
624
+ height: auto;
625
+ object-fit: cover;
626
+ align-self: stretch;
627
+ background: color-mix(in srgb, var(--aw-fg) 5%, var(--aw-bg));
628
+ }
629
+
630
+ /* 우측 본문 — title / desc / url 행. */
631
+
632
+ .aw-content > a.aw-link-card > .aw-link-card-body {
633
+ flex: 1 1 auto;
634
+ min-width: 0;
635
+ display: flex;
636
+ flex-direction: column;
637
+ gap: 4px;
638
+ padding: 12px 14px;
639
+ }
640
+
641
+ .aw-content > a.aw-link-card .aw-link-card-title {
642
+ font-weight: 600;
643
+ font-size: 1rem;
644
+ line-height: 1.3;
645
+ color: var(--aw-fg);
646
+ display: -webkit-box;
647
+ -webkit-line-clamp: 2;
648
+ -webkit-box-orient: vertical;
649
+ overflow: hidden;
650
+ }
651
+
652
+ .aw-content > a.aw-link-card .aw-link-card-desc {
653
+ font-size: 0.85rem;
654
+ line-height: 1.4;
655
+ color: var(--aw-fg-muted);
656
+ display: -webkit-box;
657
+ -webkit-line-clamp: 2;
658
+ -webkit-box-orient: vertical;
659
+ overflow: hidden;
660
+ }
661
+
662
+ .aw-content > a.aw-link-card .aw-link-card-url {
663
+ display: flex;
664
+ align-items: center;
665
+ gap: 6px;
666
+ margin-top: 2px;
667
+ font-size: 0.78rem;
668
+ color: var(--aw-primary);
669
+ font-family: var(--aw-font-mono);
670
+ word-break: break-all;
671
+ }
672
+
673
+ .aw-content > a.aw-link-card .aw-link-card-favicon {
674
+ flex: 0 0 auto;
675
+ width: 14px;
676
+ height: 14px;
677
+ border-radius: 2px;
678
+ background: transparent;
679
+ }
680
+
681
+ .aw-content > a.aw-link-card .aw-link-card-url-text {
682
+ flex: 1 1 auto;
683
+ min-width: 0;
684
+ overflow: hidden;
685
+ text-overflow: ellipsis;
686
+ white-space: nowrap;
687
+ }
688
+
689
+ .aw-content table {
690
+ border-collapse: collapse;
691
+ width: 100%;
692
+ margin: 1em 0;
693
+ }
694
+
695
+ .aw-content table td,
696
+ .aw-content table th {
697
+ border: 1px solid var(--aw-border);
698
+ padding: 8px 12px;
699
+ vertical-align: top;
700
+ min-width: 40px;
701
+ /* td/th 의 inline background-color 가 overflow 자식에 가려지지 않도록 */
702
+ background-clip: padding-box;
703
+ }
704
+
705
+ .aw-content table th {
706
+ background-color: color-mix(in srgb, var(--aw-fg) 5%, var(--aw-bg));
707
+ font-weight: 600;
708
+ }
709
+
710
+ /* 커스텀 드래그-셀렉션으로 마킹된 표 셀 — 다중 선택 시각 강조. */
711
+
712
+ .aw-content table td.aw-cell-selected,
713
+ .aw-content table th.aw-cell-selected {
714
+ outline: 2px solid var(--aw-primary);
715
+ outline-offset: -2px;
716
+ background-color: color-mix(in srgb, var(--aw-primary) 18%, transparent) !important;
717
+ }
718
+
719
+ .aeriz-wysiwyg-viewer .aw-cell-selected {
720
+ outline: none;
721
+ background-color: revert !important;
722
+ }
723
+
724
+ /* ─── 리사이즈 핸들 + 정렬 컨트롤 (이미지·유튜브) ──────────────────── */
725
+
726
+ .aw-content > figure,
727
+ .aw-content > div.aw-youtube-embed {
728
+ position: relative;
729
+ }
730
+
731
+ /* 좌상단 정렬 컨트롤 — 좌/중/우 3 버튼. hover 시 fade-in. */
732
+
733
+ .aw-block-align-controls {
734
+ position: absolute;
735
+ top: 6px;
736
+ left: 6px;
737
+ display: flex;
738
+ gap: 1px;
739
+ background: rgba(0, 0, 0, 0.55);
740
+ border-radius: 5px;
741
+ padding: 2px;
742
+ z-index: 11;
743
+ opacity: 0;
744
+ transition: opacity 0.12s;
745
+ user-select: none;
746
+ }
747
+
748
+ .aw-content > figure:hover .aw-block-align-controls,
749
+ .aw-content > div.aw-youtube-embed:hover .aw-block-align-controls,
750
+ .aw-resizing .aw-block-align-controls {
751
+ opacity: 1;
752
+ }
753
+
754
+ .aw-block-align-btn {
755
+ width: 22px;
756
+ height: 22px;
757
+ display: inline-flex;
758
+ align-items: center;
759
+ justify-content: center;
760
+ background: transparent;
761
+ border: none;
762
+ color: #fff;
763
+ cursor: pointer;
764
+ border-radius: 3px;
765
+ padding: 0;
766
+ }
767
+
768
+ .aw-block-align-btn:hover {
769
+ background: rgba(255, 255, 255, 0.18);
770
+ }
771
+
772
+ .aw-block-align-btn svg {
773
+ width: 14px;
774
+ height: 14px;
775
+ }
776
+
777
+ .aw-resize-handle {
778
+ position: absolute;
779
+ right: -1px;
780
+ bottom: -1px;
781
+ width: 14px;
782
+ height: 14px;
783
+ background: var(--aw-primary);
784
+ border: 2px solid var(--aw-bg);
785
+ border-radius: 3px;
786
+ cursor: nwse-resize;
787
+ z-index: 10;
788
+ user-select: none;
789
+ opacity: 0;
790
+ transition: opacity 0.12s, transform 0.08s;
791
+ }
792
+
793
+ .aw-content > figure:hover .aw-resize-handle,
794
+ .aw-content > div.aw-youtube-embed:hover .aw-resize-handle,
795
+ .aw-resizing .aw-resize-handle {
796
+ opacity: 1;
797
+ }
798
+
799
+ .aw-resize-handle:hover {
800
+ transform: scale(1.15);
801
+ }
802
+
803
+ .aw-resizing {
804
+ user-select: none;
805
+ }
806
+
807
+ /* 뷰어(읽기 전용) 모드에서는 편집용 컨트롤(리사이즈 핸들 / 정렬 컨트롤) 을
808
+ * 모두 숨긴다. AerizViewer.root 의 className 'aeriz-wysiwyg-viewer' 를 타겟. */
809
+
810
+ .aeriz-wysiwyg-viewer .aw-resize-handle,
811
+ .aeriz-wysiwyg-viewer .aw-block-align-controls {
812
+ display: none !important;
813
+ }
814
+
815
+ .aw-toolbar {
816
+ display: flex;
817
+ align-items: center;
818
+ flex-wrap: wrap;
819
+ gap: 2px;
820
+ padding: 6px 8px;
821
+ background-color: var(--aw-toolbar-bg);
822
+ border-bottom: 1px solid var(--aw-border);
823
+ color: var(--aw-toolbar-fg);
824
+ z-index: var(--aw-z-toolbar);
825
+ }
826
+
827
+ .aw-toolbar-sticky {
828
+ position: sticky;
829
+ top: 0;
830
+ }
831
+
832
+ .aw-toolbar-group {
833
+ display: flex;
834
+ align-items: center;
835
+ gap: 1px;
836
+ padding: 0 4px;
837
+ border-right: 1px solid var(--aw-divider);
838
+ }
839
+
840
+ .aw-toolbar-group:last-child {
841
+ border-right: none;
842
+ }
843
+
844
+ .aw-toolbar-group:empty {
845
+ display: none;
846
+ }
847
+
848
+ .aw-toolbar-btn {
849
+ display: inline-flex;
850
+ align-items: center;
851
+ justify-content: center;
852
+ height: 32px;
853
+ min-width: 32px;
854
+ padding: 0 6px;
855
+ background: transparent;
856
+ border: 1px solid transparent;
857
+ border-radius: var(--aw-radius-sm);
858
+ cursor: pointer;
859
+ color: var(--aw-toolbar-fg);
860
+ transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
861
+ }
862
+
863
+ .aw-toolbar-btn:hover:not(:disabled) {
864
+ background-color: var(--aw-btn-hover-bg);
865
+ }
866
+
867
+ .aw-toolbar-btn:disabled {
868
+ opacity: 0.4;
869
+ cursor: not-allowed;
870
+ }
871
+
872
+ .aw-toolbar-btn-active {
873
+ background-color: var(--aw-btn-active-bg);
874
+ color: var(--aw-btn-active-fg);
875
+ }
876
+
877
+ .aw-toolbar-btn-active:hover:not(:disabled) {
878
+ background-color: var(--aw-btn-active-bg);
879
+ }
880
+
881
+ .aw-toolbar-btn-icon {
882
+ display: inline-flex;
883
+ width: 18px;
884
+ height: 18px;
885
+ }
886
+
887
+ .aw-toolbar-btn-icon svg {
888
+ width: 100%;
889
+ height: 100%;
890
+ }
891
+
892
+ .aw-toolbar-btn-chevron {
893
+ display: inline-flex;
894
+ width: 12px;
895
+ height: 12px;
896
+ margin-left: 2px;
897
+ opacity: 0.7;
898
+ }
899
+
900
+ .aw-toolbar-btn-chevron svg {
901
+ width: 100%;
902
+ height: 100%;
903
+ }
904
+
905
+ /*
906
+ * Dialog / popover 는 .aeriz-wysiwyg 의 자식이 아닌 document.body 에 attach
907
+ * 되므로 에디터의 CSS 변수를 직접 받지 못한다. 대신 자기 자신에
908
+ * data-theme 속성을 받아 아래의 변수 토큰을 분기한다. 호출자(에디터)는
909
+ * dialog/popover 를 열 때 자신의 theme 을 전달한다.
910
+ */
911
+
912
+ .aw-dialog-overlay,
913
+ .aw-popover {
914
+ --d-bg: #ffffff;
915
+ --d-fg: #1a1a1a;
916
+ --d-fg-muted: #6b7280;
917
+ --d-border: #e5e7eb;
918
+ --d-border-strong: #d1d5db;
919
+ --d-input-bg: #ffffff;
920
+ --d-input-fg: #1a1a1a;
921
+ --d-footer-bg: #f9fafb;
922
+ --d-hover-bg: #f3f4f6;
923
+ --d-primary: #64c8ff;
924
+ --d-primary-hover: #38bdf8;
925
+ --d-primary-soft: rgba(100, 200, 255, 0.18);
926
+ --d-on-primary: #050810;
927
+ --d-overlay: rgba(0, 0, 0, 0.45);
928
+ --d-mono: ui-monospace, SFMono-Regular, 'JetBrains Mono', Menlo, Consolas, monospace;
929
+ }
930
+
931
+ .aw-dialog-overlay[data-theme='dark'],
932
+ .aw-popover[data-theme='dark'] {
933
+ --d-bg: #0a0e14;
934
+ --d-fg: #e7eef5;
935
+ --d-fg-muted: #76849b;
936
+ --d-border: rgba(100, 200, 255, 0.16);
937
+ --d-border-strong: rgba(100, 200, 255, 0.30);
938
+ --d-input-bg: #0d1320;
939
+ --d-input-fg: #e7eef5;
940
+ --d-footer-bg: #05080d;
941
+ --d-hover-bg: rgba(100, 200, 255, 0.10);
942
+ --d-primary: #64c8ff;
943
+ --d-primary-hover: #8ad6ff;
944
+ --d-primary-soft: rgba(100, 200, 255, 0.22);
945
+ --d-on-primary: #050810;
946
+ --d-overlay: rgba(0, 0, 0, 0.65);
947
+ }
948
+
949
+ .aw-dialog-overlay {
950
+ position: fixed;
951
+ inset: 0;
952
+ background-color: var(--d-overlay);
953
+ display: flex;
954
+ align-items: center;
955
+ justify-content: center;
956
+ z-index: var(--aw-z-dialog, 1000);
957
+ font-family: -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Pretendard',
958
+ 'Noto Sans KR', 'Malgun Gothic', sans-serif;
959
+ animation: aw-fade-in 0.12s ease;
960
+ }
961
+
962
+ @keyframes aw-fade-in { from { opacity: 0; } to { opacity: 1; } }
963
+
964
+ .aw-dialog {
965
+ background: var(--d-bg);
966
+ color: var(--d-fg);
967
+ border-radius: 8px;
968
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.45);
969
+ width: 480px;
970
+ max-width: 95vw;
971
+ max-height: 85vh;
972
+ display: flex;
973
+ flex-direction: column;
974
+ overflow: hidden;
975
+ animation: aw-slide-up 0.18s ease;
976
+ border: 1px solid var(--d-border);
977
+ }
978
+
979
+ @keyframes aw-slide-up {
980
+ from { transform: translateY(8px); opacity: 0; }
981
+ to { transform: translateY(0); opacity: 1; }
982
+ }
983
+
984
+ .aw-dialog-header {
985
+ display: flex;
986
+ align-items: center;
987
+ justify-content: space-between;
988
+ padding: 16px 20px;
989
+ border-bottom: 1px solid var(--d-border);
990
+ }
991
+
992
+ .aw-dialog-title {
993
+ margin: 0;
994
+ font-size: 16px;
995
+ font-weight: 700;
996
+ color: var(--d-fg);
997
+ }
998
+
999
+ .aw-dialog-close {
1000
+ background: transparent;
1001
+ border: none;
1002
+ cursor: pointer;
1003
+ width: 28px; height: 28px;
1004
+ display: inline-flex; align-items: center; justify-content: center;
1005
+ border-radius: 4px;
1006
+ color: var(--d-fg-muted);
1007
+ transition: background-color 0.12s, color 0.12s;
1008
+ }
1009
+
1010
+ .aw-dialog-close:hover { background-color: var(--d-hover-bg); color: var(--d-fg); }
1011
+
1012
+ .aw-dialog-close svg { width: 18px; height: 18px; }
1013
+
1014
+ .aw-dialog-body {
1015
+ padding: 20px;
1016
+ overflow-y: auto;
1017
+ display: flex; flex-direction: column; gap: 14px;
1018
+ }
1019
+
1020
+ .aw-dialog-footer {
1021
+ padding: 12px 20px;
1022
+ border-top: 1px solid var(--d-border);
1023
+ display: flex; justify-content: flex-end; gap: 8px;
1024
+ background-color: var(--d-footer-bg);
1025
+ }
1026
+
1027
+ .aw-field { display: flex; flex-direction: column; gap: 6px; }
1028
+
1029
+ .aw-field-label { font-size: 13px; font-weight: 600; color: var(--d-fg); }
1030
+
1031
+ .aw-input {
1032
+ width: 100%;
1033
+ padding: 8px 12px;
1034
+ font-size: 14px;
1035
+ font-family: inherit;
1036
+ border: 1px solid var(--d-border-strong);
1037
+ border-radius: 6px;
1038
+ outline: none;
1039
+ transition: border-color 0.12s, box-shadow 0.12s;
1040
+ color: var(--d-input-fg);
1041
+ background-color: var(--d-input-bg);
1042
+ }
1043
+
1044
+ .aw-input:focus {
1045
+ border-color: var(--d-primary);
1046
+ box-shadow: 0 0 0 3px var(--d-primary-soft);
1047
+ }
1048
+
1049
+ .aw-textarea {
1050
+ resize: vertical;
1051
+ min-height: 120px;
1052
+ font-family: var(--d-mono);
1053
+ font-size: 12px;
1054
+ line-height: 1.5;
1055
+ }
1056
+
1057
+ .aw-checkbox {
1058
+ display: inline-flex; align-items: center; gap: 8px;
1059
+ font-size: 14px;
1060
+ color: var(--d-fg);
1061
+ cursor: pointer; user-select: none;
1062
+ }
1063
+
1064
+ .aw-checkbox input { width: 16px; height: 16px; accent-color: var(--d-primary); }
1065
+
1066
+ .aw-btn {
1067
+ padding: 8px 16px;
1068
+ font-size: 14px;
1069
+ font-weight: 600;
1070
+ border-radius: 6px;
1071
+ border: 1px solid transparent;
1072
+ cursor: pointer;
1073
+ font-family: inherit;
1074
+ transition: background-color 0.12s, border-color 0.12s, color 0.12s;
1075
+ }
1076
+
1077
+ .aw-btn-primary { background-color: var(--d-primary); color: var(--d-on-primary); }
1078
+
1079
+ .aw-btn-primary:hover { background-color: var(--d-primary-hover); }
1080
+
1081
+ .aw-btn-ghost {
1082
+ background-color: transparent;
1083
+ color: var(--d-fg);
1084
+ border-color: var(--d-border-strong);
1085
+ }
1086
+
1087
+ .aw-btn-ghost:hover { background-color: var(--d-hover-bg); }
1088
+
1089
+ .aw-tabs {
1090
+ display: flex; gap: 4px;
1091
+ border-bottom: 1px solid var(--d-border);
1092
+ margin: -4px -4px 8px;
1093
+ }
1094
+
1095
+ .aw-tab {
1096
+ padding: 8px 14px;
1097
+ background: transparent;
1098
+ border: none;
1099
+ border-bottom: 2px solid transparent;
1100
+ font-size: 14px;
1101
+ font-family: inherit;
1102
+ font-weight: 500;
1103
+ color: var(--d-fg-muted);
1104
+ cursor: pointer;
1105
+ transition: color 0.12s, border-color 0.12s;
1106
+ }
1107
+
1108
+ .aw-tab:hover { color: var(--d-fg); }
1109
+
1110
+ .aw-tab-active { color: var(--d-primary); border-bottom-color: var(--d-primary); }
1111
+
1112
+ .aw-tab-disabled,
1113
+ .aw-tab[disabled] {
1114
+ opacity: 0.4;
1115
+ cursor: not-allowed;
1116
+ text-decoration: line-through;
1117
+ color: var(--d-fg-muted);
1118
+ }
1119
+
1120
+ .aw-tab-disabled:hover,
1121
+ .aw-tab[disabled]:hover { color: var(--d-fg-muted); }
1122
+
1123
+ .aw-dialog-hint {
1124
+ font-size: 12px;
1125
+ color: var(--d-fg-muted);
1126
+ margin-top: -4px;
1127
+ }
1128
+
1129
+ .aw-pane-notice {
1130
+ padding: 24px 16px;
1131
+ text-align: center;
1132
+ font-size: 13px;
1133
+ color: var(--d-fg-muted);
1134
+ background-color: var(--d-input-bg);
1135
+ border: 1px dashed var(--d-border-strong);
1136
+ border-radius: 8px;
1137
+ }
1138
+
1139
+ .aw-pane { display: flex; flex-direction: column; gap: 12px; }
1140
+
1141
+ .aw-dropzone {
1142
+ display: flex; flex-direction: column;
1143
+ align-items: center; justify-content: center;
1144
+ gap: 10px;
1145
+ padding: 32px 20px;
1146
+ border: 2px dashed var(--d-border-strong);
1147
+ border-radius: 8px;
1148
+ cursor: pointer;
1149
+ text-align: center;
1150
+ color: var(--d-fg-muted);
1151
+ transition: border-color 0.12s, background-color 0.12s, color 0.12s;
1152
+ background-color: var(--d-input-bg);
1153
+ }
1154
+
1155
+ .aw-dropzone:hover {
1156
+ border-color: var(--d-primary);
1157
+ background-color: var(--d-hover-bg);
1158
+ color: var(--d-primary);
1159
+ }
1160
+
1161
+ .aw-dropzone svg { width: 36px; height: 36px; }
1162
+
1163
+ .aw-dropzone-text { font-size: 13px; line-height: 1.5; }
1164
+
1165
+ .aw-dropzone-loading { opacity: 0.6; pointer-events: none; }
1166
+
1167
+ .aw-preview {
1168
+ width: 100%; height: 160px;
1169
+ border-radius: 6px;
1170
+ background-size: cover; background-position: center;
1171
+ border: 1px solid var(--d-border);
1172
+ }
1173
+
1174
+ .aw-table-grid {
1175
+ display: grid;
1176
+ grid-template-columns: repeat(10, 22px);
1177
+ grid-template-rows: repeat(10, 22px);
1178
+ gap: 2px;
1179
+ padding: 8px;
1180
+ background-color: var(--d-footer-bg);
1181
+ border-radius: 6px;
1182
+ width: max-content;
1183
+ margin: 0 auto;
1184
+ }
1185
+
1186
+ .aw-table-cell {
1187
+ background-color: var(--d-input-bg);
1188
+ border: 1px solid var(--d-border-strong);
1189
+ border-radius: 2px;
1190
+ cursor: pointer;
1191
+ transition: background-color 0.08s;
1192
+ }
1193
+
1194
+ .aw-table-cell-active {
1195
+ background-color: var(--d-primary-soft);
1196
+ border-color: var(--d-primary);
1197
+ }
1198
+
1199
+ .aw-table-status {
1200
+ text-align: center;
1201
+ font-size: 13px;
1202
+ color: var(--d-fg-muted);
1203
+ margin-top: 4px;
1204
+ }
1205
+
1206
+ /* ─── Popovers ──────────────────────────────────────────────── */
1207
+
1208
+ .aw-popover {
1209
+ background: var(--d-bg);
1210
+ color: var(--d-fg);
1211
+ border: 1px solid var(--d-border);
1212
+ border-radius: 8px;
1213
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.35);
1214
+ padding: 8px;
1215
+ z-index: var(--aw-z-popover, 100);
1216
+ animation: aw-fade-in 0.1s ease;
1217
+ min-width: 160px;
1218
+ font-family: -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Pretendard',
1219
+ 'Noto Sans KR', 'Malgun Gothic', sans-serif;
1220
+ }
1221
+
1222
+ .aw-color-popover {
1223
+ /* 8 swatch × 22 + 7 gap × 4 + 8 padding × 2 = 220px 컨텐츠에 맞게 */
1224
+ width: max-content;
1225
+ min-width: 220px;
1226
+ }
1227
+
1228
+ .aw-color-grid {
1229
+ display: grid;
1230
+ grid-template-columns: repeat(8, 22px);
1231
+ gap: 4px;
1232
+ justify-content: start;
1233
+ }
1234
+
1235
+ .aw-color-swatch {
1236
+ width: 22px; height: 22px;
1237
+ border-radius: 4px;
1238
+ border: 1px solid var(--d-border);
1239
+ cursor: pointer;
1240
+ padding: 0;
1241
+ transition: transform 0.08s;
1242
+ }
1243
+
1244
+ .aw-color-swatch:hover { transform: scale(1.15); }
1245
+
1246
+ .aw-color-section {
1247
+ font-size: 10px;
1248
+ letter-spacing: 0.08em;
1249
+ text-transform: uppercase;
1250
+ color: var(--d-fg-muted);
1251
+ font-weight: 700;
1252
+ padding: 6px 2px 4px;
1253
+ }
1254
+
1255
+ .aw-color-section + .aw-color-grid { margin-bottom: 4px; }
1256
+
1257
+ .aw-popover-action {
1258
+ display: block;
1259
+ width: 100%;
1260
+ text-align: left;
1261
+ padding: 8px 10px;
1262
+ background: transparent;
1263
+ border: none;
1264
+ border-radius: 4px;
1265
+ cursor: pointer;
1266
+ font-size: 13px;
1267
+ color: var(--d-fg);
1268
+ font-family: inherit;
1269
+ margin-top: 4px;
1270
+ position: relative;
1271
+ }
1272
+
1273
+ .aw-popover-action:hover { background-color: var(--d-hover-bg); }
1274
+
1275
+ .aw-popover-item {
1276
+ display: flex;
1277
+ align-items: center;
1278
+ gap: 8px;
1279
+ width: 100%;
1280
+ text-align: left;
1281
+ padding: 4px 8px;
1282
+ background: transparent;
1283
+ border: none;
1284
+ border-radius: 4px;
1285
+ cursor: pointer;
1286
+ color: var(--d-fg);
1287
+ font-family: inherit;
1288
+ font-size: 12.5px;
1289
+ }
1290
+
1291
+ .aw-popover-item:hover { background-color: var(--d-hover-bg); }
1292
+
1293
+ .aw-popover-item-glyph {
1294
+ display: inline-flex;
1295
+ width: 18px; height: 18px;
1296
+ align-items: center; justify-content: center;
1297
+ flex-shrink: 0;
1298
+ border-radius: 3px;
1299
+ background: var(--d-hover-bg);
1300
+ color: var(--d-fg-muted);
1301
+ font-family: var(--d-mono);
1302
+ font-size: 10px;
1303
+ font-weight: 700;
1304
+ }
1305
+
1306
+ .aw-popover-item-glyph svg { width: 11px; height: 11px; }
1307
+
1308
+ .aw-popover-item-label { flex: 1; min-width: 0; }
1309
+
1310
+ .aw-popover-item-icon {
1311
+ display: inline-flex;
1312
+ width: auto;
1313
+ padding: 8px;
1314
+ align-items: center; justify-content: center;
1315
+ gap: 0;
1316
+ }
1317
+
1318
+ .aw-popover-item-icon svg { width: 18px; height: 18px; }
1319
+
1320
+ .aw-popover-divider {
1321
+ height: 1px;
1322
+ background: var(--d-border);
1323
+ margin: 4px 6px;
1324
+ }
1325
+
1326
+ /* 블록 유형 드롭다운 — 항목이 많아 세로로 길어지지 않도록 2 컬럼 그리드.
1327
+ * 섹션 구분 divider 는 grid-column 으로 두 컬럼을 모두 가로지른다. */
1328
+
1329
+ .aw-block-type-popover {
1330
+ display: grid;
1331
+ grid-template-columns: repeat(2, minmax(150px, 1fr));
1332
+ column-gap: 2px;
1333
+ min-width: 320px;
1334
+ }
1335
+
1336
+ .aw-block-type-popover .aw-popover-divider {
1337
+ grid-column: 1 / -1;
1338
+ }
1339
+
1340
+ /* 글꼴 드롭다운 — 라벨(작게) + '가A' 미리보기(글꼴 자체) 두 영역. */
1341
+
1342
+ .aw-font-family-popover {
1343
+ min-width: 180px;
1344
+ max-height: 360px;
1345
+ overflow-y: auto;
1346
+ }
1347
+
1348
+ .aw-font-family-item {
1349
+ padding: 4px 8px;
1350
+ display: flex;
1351
+ align-items: center;
1352
+ gap: 8px;
1353
+ }
1354
+
1355
+ .aw-font-family-name {
1356
+ flex: 1 1 auto;
1357
+ min-width: 0;
1358
+ font-size: 11px;
1359
+ line-height: 1.4;
1360
+ color: var(--d-fg);
1361
+ white-space: nowrap;
1362
+ overflow: hidden;
1363
+ text-overflow: ellipsis;
1364
+ }
1365
+
1366
+ .aw-font-family-preview {
1367
+ flex: 0 0 auto;
1368
+ font-size: 13px;
1369
+ line-height: 1.4;
1370
+ color: var(--d-fg-muted);
1371
+ letter-spacing: 0.05em;
1372
+ }
1373
+
1374
+ /* 표 편집 드롭다운 — 행/열 추가·삭제 텍스트 항목 */
1375
+
1376
+ .aw-table-menu-popover {
1377
+ min-width: 160px;
1378
+ }
1379
+
1380
+ .aw-table-menu-item {
1381
+ font-size: 12px;
1382
+ padding: 6px 10px;
1383
+ }
1384
+
1385
+ /* 글자 크기 드롭다운 — 한 줄당 px 라벨이 그 크기로 렌더되는 컴팩트 리스트 */
1386
+
1387
+ .aw-font-size-popover {
1388
+ min-width: 80px;
1389
+ max-height: 320px;
1390
+ overflow-y: auto;
1391
+ }
1392
+
1393
+ .aw-font-size-item {
1394
+ padding: 2px 10px;
1395
+ justify-content: space-between;
1396
+ }
1397
+
1398
+ .aw-font-size-label {
1399
+ font-size: 11px;
1400
+ color: var(--d-fg);
1401
+ font-family: var(--d-mono);
1402
+ letter-spacing: 0.02em;
1403
+ }
1404
+
1405
+ .aw-popover-item-active {
1406
+ background-color: color-mix(in srgb, var(--d-primary) 14%, transparent);
1407
+ color: var(--d-primary);
1408
+ }
1409
+
1410
+ .aw-popover-item-active::after {
1411
+ content: '✓';
1412
+ margin-left: auto;
1413
+ font-size: 11px;
1414
+ }
1415
+
1416
+ .aw-align-popover {
1417
+ display: flex;
1418
+ gap: 2px;
1419
+ min-width: auto;
1420
+ }
1421
+
1422
+ /* 표 삽입 드롭다운 — 호버에 따라 동적으로 늘어나는 셀 그리드 */
1423
+
1424
+ .aw-table-popover {
1425
+ padding: 10px;
1426
+ min-width: auto;
1427
+ }
1428
+
1429
+ .aw-table-picker-grid {
1430
+ display: grid;
1431
+ gap: 2px;
1432
+ margin-bottom: 6px;
1433
+ }
1434
+
1435
+ .aw-table-picker-grid .aw-table-cell {
1436
+ width: 18px;
1437
+ height: 18px;
1438
+ background-color: var(--d-input-bg);
1439
+ border: 1px solid var(--d-border-strong);
1440
+ border-radius: 2px;
1441
+ cursor: pointer;
1442
+ transition: background-color 0.06s, border-color 0.06s;
1443
+ }
1444
+
1445
+ .aw-table-picker-grid .aw-table-cell.aw-table-cell-active {
1446
+ background-color: var(--d-primary-soft);
1447
+ border-color: var(--d-primary);
1448
+ }
1449
+
1450
+ .aw-table-popover .aw-table-status {
1451
+ text-align: center;
1452
+ font-size: 12px;
1453
+ color: var(--d-fg-muted);
1454
+ font-family: var(--d-mono);
1455
+ margin: 0;
1456
+ }
1457
+
1458
+ .aw-coming-soon-popover .aw-popover-section {
1459
+ font-size: 11px;
1460
+ letter-spacing: 0.08em;
1461
+ text-transform: uppercase;
1462
+ color: var(--d-fg-muted);
1463
+ padding: 4px 8px;
1464
+ font-weight: 700;
1465
+ }
1466
+
1467
+ .aw-coming-soon-popover .aw-popover-empty {
1468
+ padding: 10px 8px;
1469
+ font-size: 13px;
1470
+ color: var(--d-fg-muted);
1471
+ }