@lumir-company/editor 0.4.12 → 0.4.13

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.
package/dist/style.css CHANGED
@@ -1,1041 +1,1041 @@
1
- @import "@blocknote/core/fonts/inter.css";
2
- @import "@blocknote/mantine/style.css";
3
- @import "@blocknote/react/style.css";
4
-
5
- .lumirEditor {
6
- width: 100%;
7
- height: 100%;
8
- min-width: 200px;
9
- overflow: visible; /* 슬래시 메뉴가 컨테이너를 넘어서 표시되도록 변경 */
10
- background-color: #ffffff;
11
- }
12
-
13
- /* 에디터 내부 콘텐츠 영역만 스크롤 가능하게 설정 */
14
- .lumirEditor .bn-container {
15
- overflow: auto;
16
- max-height: 100%;
17
- }
18
-
19
- /* 슬래시 메뉴(SuggestionMenu)가 컨테이너를 넘어서 표시되도록 */
20
- .bn-suggestion-menu,
21
- .bn-slash-menu,
22
- .mantine-Menu-dropdown,
23
- .mantine-Popover-dropdown {
24
- z-index: 9999 !important;
25
- }
26
- /* 포커스 상태 스타일 - 테두리 없음 */
27
- .lumirEditor:focus-within {
28
- outline: none;
29
- box-shadow: none;
30
- }
31
- .lumirEditor {
32
- border: none;
33
- }
34
-
35
- /* BlockNote 에디터 내부 폰트 설정 */
36
- .lumirEditor .bn-editor,
37
- .lumirEditor .bn-inline-content {
38
- font-family:
39
- "Pretendard",
40
- "Noto Sans KR",
41
- -apple-system,
42
- BlinkMacSystemFont,
43
- "Segoe UI",
44
- "Roboto",
45
- "Oxygen",
46
- "Ubuntu",
47
- "Cantarell",
48
- sans-serif;
49
- }
50
-
51
- /* 링크 스타일 - Tailwind Preflight 리셋 복원 */
52
- .lumirEditor .bn-editor a,
53
- .lumirEditor .bn-inline-content a {
54
- color: #0b6e99;
55
- text-decoration: underline;
56
- text-underline-offset: 2px;
57
- cursor: pointer;
58
- }
59
-
60
- .lumirEditor .bn-editor a:hover,
61
- .lumirEditor .bn-inline-content a:hover {
62
- color: #0b6e99;
63
- }
64
-
65
- /* CSS 변수를 사용한 패딩 설정 */
66
- .lumirEditor .bn-editor {
67
- padding-left: 25px;
68
- padding-right: 10px;
69
- padding-top: 5px;
70
- padding-bottom: 0;
71
- }
72
-
73
- /*
74
- * 본문·번호·글머리·체크 목록 인라인 텍스트 14px 통일
75
- * BlockNote `.bn-default-styles { font-size: 16px }` + `p { font-size: inherit }` 때문에
76
- * `p.bn-inline-content`에 명시적으로 14px (`.bn-block-content`에 data-type이 붙음)
77
- */
78
- .lumirEditor
79
- .bn-block-content[data-content-type="paragraph"]
80
- p.bn-inline-content,
81
- .lumirEditor
82
- .bn-block-content[data-content-type="numberedListItem"]
83
- p.bn-inline-content,
84
- .lumirEditor
85
- .bn-block-content[data-content-type="bulletListItem"]
86
- p.bn-inline-content,
87
- .lumirEditor
88
- .bn-block-content[data-content-type="checkListItem"]
89
- p.bn-inline-content {
90
- font-size: 14px;
91
- }
92
-
93
- /* 마커(번호·불릿)·체크 행 */
94
- .lumirEditor .bn-block-content[data-content-type="numberedListItem"],
95
- .lumirEditor .bn-block-content[data-content-type="bulletListItem"],
96
- .lumirEditor .bn-block-content[data-content-type="checkListItem"] {
97
- font-size: 14px;
98
- }
99
-
100
- .lumirEditor .bn-block-content {
101
- max-width: 100%;
102
- }
103
-
104
- /* File Panel: Embed 탭 미노출 (URL 입력 방식 비활성화) */
105
- .lumirEditor [data-test="embed-tab"] {
106
- display: none !important;
107
- }
108
-
109
- /* 정렬된 블록의 인라인 콘텐츠 - 빈 블록에서 스크롤 방지 */
110
- .lumirEditor .bn-inline-content {
111
- overflow: hidden;
112
- max-width: 100%;
113
- min-width: 0;
114
- }
115
-
116
- /* 우측 정렬 시 빈 블록 placeholder 위치 수정 */
117
- .lumirEditor [data-text-alignment="right"] .bn-inline-content::before {
118
- position: relative;
119
- max-width: 100%;
120
- }
121
-
122
- /* 이미지 업로드 로딩 스피너 */
123
- .lumirEditor-upload-overlay {
124
- position: absolute;
125
- top: 0;
126
- left: 0;
127
- right: 0;
128
- bottom: 0;
129
- display: flex;
130
- flex-direction: column;
131
- align-items: center;
132
- justify-content: center;
133
- gap: 8px;
134
- background-color: rgba(255, 255, 255, 0.8);
135
- backdrop-filter: blur(2px);
136
- z-index: 1000;
137
- }
138
-
139
- .lumirEditor-spinner {
140
- width: 30px;
141
- height: 30px;
142
- border: 3px solid #f3f3f3;
143
- border-top: 3px solid #3b82f6;
144
- border-radius: 50%;
145
- animation: lumir-spin 1s linear infinite;
146
- }
147
-
148
- .lumirEditor-upload-progress {
149
- font-size: 14px;
150
- font-weight: 500;
151
- color: #374151;
152
- }
153
-
154
- @keyframes lumir-spin {
155
- 0% {
156
- transform: rotate(0deg);
157
- }
158
- 100% {
159
- transform: rotate(360deg);
160
- }
161
- }
162
-
163
- /* ========================================
164
- Floating Toolbar 스타일 (컴팩트 + 반응형)
165
- ======================================== */
166
-
167
- /* CSS 변수 정의 */
168
- .lumir-floating-toolbar-wrapper {
169
- --lumir-bg-light: #fafaf9;
170
- --lumir-bg-dark: #1c1917;
171
- --lumir-paper-light: #ffffff;
172
- --lumir-paper-dark: #292524;
173
- --lumir-border-light: #e7e5e4;
174
- --lumir-border-dark: #44403c;
175
- --lumir-text-light: #1c1917;
176
- --lumir-text-dark: #fafaf9;
177
- --lumir-text-muted-light: #78716c;
178
- --lumir-text-muted-dark: #a8a29e;
179
- --lumir-hover-light: #f5f5f4;
180
- --lumir-hover-dark: #44403c;
181
- --lumir-active-bg: rgba(59, 130, 246, 0.1);
182
- --lumir-active-color: #3b82f6;
183
- --lumir-radius-lg: 0.5rem;
184
- --lumir-radius-md: 0.25rem;
185
- --lumir-transition: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
186
- --lumir-btn-size: 28px;
187
- --lumir-btn-padding: 6px;
188
- --lumir-icon-size: 16px;
189
- }
190
-
191
- /* Toolbar Wrapper */
192
- .lumir-floating-toolbar-wrapper {
193
- width: 100%;
194
- display: flex;
195
- justify-content: center;
196
- padding: 8px 12px;
197
- z-index: 40;
198
- }
199
-
200
- /* 최소화 모드일 때는 좌측 상단 배치 */
201
- .lumir-floating-toolbar-wrapper.is-minimizable {
202
- justify-content: flex-start;
203
- padding: 0;
204
- }
205
-
206
- .lumir-floating-toolbar-wrapper[data-position="sticky"] {
207
- position: sticky;
208
- top: 0;
209
- }
210
-
211
- .lumir-floating-toolbar-wrapper[data-position="fixed"] {
212
- position: fixed;
213
- top: 64px;
214
- left: 0;
215
- right: 0;
216
- }
217
-
218
- /* Toolbar Container - 항상 밝은 배경 유지 */
219
- .lumir-floating-toolbar {
220
- display: flex;
221
- flex-wrap: wrap;
222
- align-items: center;
223
- gap: 2px;
224
- padding: 4px;
225
- background-color: #ffffff !important;
226
- border: 1px solid #e5e7eb !important;
227
- border-radius: var(--lumir-radius-lg);
228
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
229
- max-width: 100%;
230
- font-family: ui-sans-serif, system-ui, sans-serif;
231
- font-size: 13px;
232
- }
233
-
234
- /* 1단 레이아웃 (넓은 화면) */
235
- .lumir-floating-toolbar {
236
- flex-wrap: nowrap;
237
- }
238
-
239
- /* 2단 레이아웃 (좁은 화면) */
240
- .lumir-floating-toolbar.is-compact {
241
- flex-wrap: wrap;
242
- justify-content: center;
243
- }
244
-
245
- .lumir-floating-toolbar.is-compact .lumir-toolbar-row {
246
- display: flex;
247
- align-items: center;
248
- width: 100%;
249
- justify-content: center;
250
- gap: 2px;
251
- }
252
-
253
- .lumir-floating-toolbar.is-compact .lumir-toolbar-row:not(:last-child) {
254
- padding-bottom: 4px;
255
- border-bottom: 1px solid var(--lumir-border-light);
256
- margin-bottom: 4px;
257
- }
258
-
259
- /* 최소화 가능 레이아웃 (400px 이하) */
260
- .lumir-floating-toolbar.is-minimizable {
261
- flex-wrap: wrap; /* 여러 줄로 확장 가능 */
262
- justify-content: flex-start; /* 좌측 정렬 */
263
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
264
- padding: 0; /* 내부 공백 제거 */
265
- }
266
-
267
- /* 토글 버튼 스타일 */
268
- .lumir-floating-toolbar.is-minimizable .lumir-toggle-button {
269
- order: -1; /* 항상 맨 앞에 배치 */
270
- flex-shrink: 0;
271
- width: 24px; /* 컴팩트한 크기 */
272
- height: 24px;
273
- padding: 0; /* 패딩 제거하여 정확한 정렬 */
274
- margin: 0;
275
- border-radius: 4px;
276
- display: flex;
277
- align-items: center;
278
- justify-content: center;
279
- cursor: pointer;
280
- transition: transform 0.2s ease;
281
- }
282
-
283
- .lumir-floating-toolbar.is-minimizable .lumir-toggle-button:hover {
284
- transform: scale(1.1);
285
- }
286
-
287
- .lumir-floating-toolbar.is-minimizable .lumir-toggle-button svg {
288
- width: 16px;
289
- height: 16px;
290
- display: block; /* inline 여백 제거 */
291
- transition: transform 0.3s ease;
292
- }
293
-
294
- /* 메뉴 항목 애니메이션 */
295
- .lumir-floating-toolbar.is-minimizable > *:not(.lumir-toggle-button) {
296
- opacity: 1;
297
- transform: translateX(0);
298
- transition:
299
- opacity 0.3s ease,
300
- transform 0.3s ease;
301
- }
302
-
303
- /* 최소화 상태 - 토글 버튼만 표시 */
304
- .lumir-floating-toolbar.is-minimizable.is-minimized {
305
- width: auto;
306
- min-width: 24px;
307
- padding: 0;
308
- border: none;
309
- background: transparent !important;
310
- box-shadow: none;
311
- }
312
-
313
- .lumir-floating-toolbar.is-minimizable.is-minimized
314
- > *:not(.lumir-toggle-button) {
315
- opacity: 0;
316
- transform: translateX(-10px);
317
- pointer-events: none;
318
- max-width: 0;
319
- overflow: hidden;
320
- margin: 0;
321
- padding: 0;
322
- }
323
-
324
- /* Toolbar Group */
325
- .lumir-toolbar-group {
326
- display: flex;
327
- align-items: center;
328
- gap: 1px;
329
- padding: 0 2px;
330
- }
331
-
332
- /* Divider */
333
- .lumir-toolbar-divider {
334
- width: 1px;
335
- height: 18px;
336
- background-color: var(--lumir-border-light);
337
- margin: 0 2px;
338
- flex-shrink: 0;
339
- }
340
-
341
- /* 2단에서 divider 숨기기 */
342
- .lumir-floating-toolbar.is-compact .lumir-toolbar-divider.row-break {
343
- display: none;
344
- }
345
-
346
- /* Toolbar Button (컴팩트) */
347
- .lumir-toolbar-btn {
348
- display: flex;
349
- align-items: center;
350
- justify-content: center;
351
- width: var(--lumir-btn-size);
352
- height: var(--lumir-btn-size);
353
- padding: var(--lumir-btn-padding);
354
- border: none;
355
- background: transparent;
356
- color: var(--lumir-text-muted-light);
357
- cursor: pointer;
358
- border-radius: var(--lumir-radius-md);
359
- transition: all var(--lumir-transition);
360
- position: relative;
361
- flex-shrink: 0;
362
- }
363
-
364
- .lumir-toolbar-btn svg {
365
- width: var(--lumir-icon-size);
366
- height: var(--lumir-icon-size);
367
- }
368
-
369
- .lumir-toolbar-btn:hover {
370
- background-color: var(--lumir-hover-light);
371
- color: var(--lumir-text-light);
372
- }
373
-
374
- .lumir-toolbar-btn.is-active {
375
- background-color: var(--lumir-active-bg);
376
- color: var(--lumir-active-color);
377
- }
378
-
379
- .lumir-toolbar-btn:disabled {
380
- opacity: 0.4;
381
- cursor: not-allowed;
382
- }
383
-
384
- /* 색상 버튼 인디케이터 */
385
- .lumir-color-btn {
386
- flex-direction: column;
387
- gap: 1px;
388
- width: var(--lumir-btn-size);
389
- height: var(--lumir-btn-size);
390
- padding: 4px;
391
- }
392
-
393
- .lumir-color-btn svg {
394
- width: 14px;
395
- height: 14px;
396
- }
397
-
398
- .lumir-color-indicator {
399
- width: 12px;
400
- height: 2px;
401
- border-radius: 1px;
402
- border: 1px solid rgba(0, 0, 0, 0.1);
403
- }
404
-
405
- /* SVG 아이콘 스타일 */
406
- .lumir-toolbar-btn svg,
407
- .lumir-dropdown-btn svg {
408
- flex-shrink: 0;
409
- }
410
-
411
- /* Dropdown Wrapper */
412
- .lumir-dropdown-wrapper {
413
- position: relative;
414
- }
415
-
416
- /* Dropdown Button (컴팩트) */
417
- .lumir-dropdown-btn {
418
- display: flex;
419
- align-items: center;
420
- justify-content: space-between;
421
- min-width: 90px;
422
- max-width: 110px;
423
- height: var(--lumir-btn-size);
424
- padding: 4px 8px;
425
- border: none;
426
- background: transparent;
427
- color: inherit;
428
- cursor: pointer;
429
- border-radius: var(--lumir-radius-md);
430
- font-size: 12px;
431
- font-weight: 500;
432
- transition: all var(--lumir-transition);
433
- gap: 2px;
434
- white-space: nowrap;
435
- overflow: hidden;
436
- }
437
-
438
- .lumir-dropdown-btn span {
439
- overflow: hidden;
440
- text-overflow: ellipsis;
441
- }
442
-
443
- .lumir-dropdown-btn:hover {
444
- background-color: var(--lumir-hover-light);
445
- }
446
-
447
- .lumir-dropdown-btn svg {
448
- width: 14px;
449
- height: 14px;
450
- flex-shrink: 0;
451
- color: var(--lumir-text-muted-light);
452
- }
453
-
454
- /* Dropdown Menu - 항상 밝은 배경 유지 */
455
- .lumir-dropdown-menu {
456
- position: absolute;
457
- top: calc(100% + 4px);
458
- left: 0;
459
- min-width: 160px;
460
- background-color: #ffffff !important;
461
- border: 1px solid #e5e7eb !important;
462
- border-radius: 10px;
463
- box-shadow:
464
- 0 4px 16px rgba(0, 0, 0, 0.12),
465
- 0 0 0 1px rgba(0, 0, 0, 0.04);
466
- z-index: 9999;
467
- padding: 6px;
468
- animation: lumir-dropdown-appear 0.15s ease;
469
- }
470
-
471
- @keyframes lumir-dropdown-appear {
472
- from {
473
- opacity: 0;
474
- transform: translateY(-4px);
475
- }
476
- to {
477
- opacity: 1;
478
- transform: translateY(0);
479
- }
480
- }
481
-
482
- /* Dropdown Item - 항상 밝은 스타일 */
483
- .lumir-dropdown-item {
484
- display: flex;
485
- align-items: center;
486
- width: 100%;
487
- padding: 8px 12px;
488
- text-align: left;
489
- border: none;
490
- background: transparent;
491
- color: #374151 !important;
492
- cursor: pointer;
493
- border-radius: 6px;
494
- font-size: 14px;
495
- transition: background-color 0.1s ease;
496
- }
497
-
498
- .lumir-dropdown-item:hover {
499
- background-color: #f3f4f6 !important;
500
- }
501
-
502
- .lumir-dropdown-item.is-active {
503
- background-color: rgba(59, 130, 246, 0.1) !important;
504
- color: #3b82f6 !important;
505
- }
506
-
507
- /* Block Type Dropdown Button */
508
- .lumir-block-type-btn {
509
- min-width: 110px;
510
- max-width: 130px;
511
- gap: 4px;
512
- padding: 4px 8px;
513
- }
514
-
515
- .lumir-block-icon {
516
- display: flex;
517
- align-items: center;
518
- justify-content: center;
519
- width: 22px;
520
- height: 22px;
521
- flex-shrink: 0;
522
- color: #6b7280;
523
- }
524
-
525
- .lumir-block-icon svg {
526
- width: 18px;
527
- height: 18px;
528
- }
529
-
530
- .lumir-block-icon-text {
531
- font-size: 13px;
532
- font-weight: 700;
533
- color: #6b7280;
534
- line-height: 1;
535
- }
536
-
537
- .lumir-block-label {
538
- flex: 1;
539
- text-align: left;
540
- overflow: hidden;
541
- text-overflow: ellipsis;
542
- white-space: nowrap;
543
- font-size: 13px;
544
- }
545
-
546
- /* Block Type Dropdown Menu - 최대 컴팩트 */
547
- .lumir-block-menu {
548
- min-width: 160px;
549
- max-height: 320px;
550
- overflow-y: auto;
551
- padding: 3px;
552
- }
553
-
554
- /* 커스텀 스크롤바 - 더 얇게 */
555
- .lumir-block-menu::-webkit-scrollbar {
556
- width: 4px;
557
- }
558
-
559
- .lumir-block-menu::-webkit-scrollbar-track {
560
- background: transparent;
561
- }
562
-
563
- .lumir-block-menu::-webkit-scrollbar-thumb {
564
- background-color: #d1d5db;
565
- border-radius: 2px;
566
- }
567
-
568
- .lumir-block-menu::-webkit-scrollbar-thumb:hover {
569
- background-color: #9ca3af;
570
- }
571
-
572
- /* Block Type Menu Item - 최대 컴팩트 */
573
- .lumir-block-item {
574
- display: flex;
575
- align-items: center;
576
- gap: 6px;
577
- padding: 4px 8px;
578
- border-radius: 4px;
579
- margin-bottom: 0;
580
- transition: all 0.1s ease;
581
- }
582
-
583
- .lumir-block-item:last-child {
584
- margin-bottom: 0;
585
- }
586
-
587
- .lumir-block-item .lumir-block-icon {
588
- width: 20px;
589
- height: 20px;
590
- background-color: #f3f4f6;
591
- border-radius: 3px;
592
- display: flex;
593
- align-items: center;
594
- justify-content: center;
595
- flex-shrink: 0;
596
- }
597
-
598
- .lumir-block-item .lumir-block-icon svg {
599
- width: 14px;
600
- height: 14px;
601
- }
602
-
603
- .lumir-block-item .lumir-block-icon-text {
604
- font-size: 10px;
605
- font-weight: 700;
606
- }
607
-
608
- .lumir-block-item-title {
609
- font-size: 12px;
610
- font-weight: 500;
611
- color: #374151;
612
- }
613
-
614
- .lumir-block-item:hover {
615
- background-color: #f3f4f6 !important;
616
- }
617
-
618
- .lumir-block-item:hover .lumir-block-icon {
619
- background-color: #e5e7eb;
620
- color: #374151;
621
- }
622
-
623
- .lumir-block-item:hover .lumir-block-icon-text {
624
- color: #374151;
625
- }
626
-
627
- .lumir-block-item.is-active {
628
- background-color: rgba(59, 130, 246, 0.08) !important;
629
- }
630
-
631
- .lumir-block-item.is-active .lumir-block-icon {
632
- background-color: rgba(59, 130, 246, 0.15);
633
- color: #3b82f6;
634
- }
635
-
636
- .lumir-block-item.is-active .lumir-block-icon-text {
637
- color: #3b82f6;
638
- }
639
-
640
- /* Block Type Category - 최대 컴팩트 */
641
- .lumir-block-category {
642
- margin-bottom: 2px;
643
- }
644
-
645
- .lumir-block-category:last-child {
646
- margin-bottom: 0;
647
- }
648
-
649
- .lumir-block-category-title {
650
- font-size: 9px;
651
- font-weight: 600;
652
- color: #9ca3af;
653
- text-transform: uppercase;
654
- letter-spacing: 0.05em;
655
- padding: 4px 8px 2px;
656
- margin-bottom: 0;
657
- }
658
-
659
- /* Block Item Title */
660
- .lumir-block-item:hover .lumir-block-item-title {
661
- color: #1f2937;
662
- }
663
-
664
- .lumir-block-item.is-active .lumir-block-item-title {
665
- color: #3b82f6;
666
- font-weight: 600;
667
- }
668
-
669
- /* Toggle Heading 아이콘 - 컴팩트 */
670
- .lumir-block-icon-toggle {
671
- display: flex;
672
- align-items: center;
673
- gap: 2px;
674
- font-size: 9px;
675
- font-weight: 700;
676
- color: #6b7280;
677
- line-height: 1;
678
- }
679
-
680
- .lumir-block-icon-toggle svg {
681
- width: 6px;
682
- height: 6px;
683
- flex-shrink: 0;
684
- }
685
-
686
- .lumir-block-icon-toggle span {
687
- font-size: 9px;
688
- font-weight: 700;
689
- }
690
-
691
- .lumir-block-item .lumir-block-icon-toggle {
692
- font-size: 10px;
693
- }
694
-
695
- .lumir-block-item .lumir-block-icon-toggle svg {
696
- width: 7px;
697
- height: 7px;
698
- }
699
-
700
- .lumir-block-item .lumir-block-icon-toggle span {
701
- font-size: 10px;
702
- }
703
-
704
- .lumir-block-item:hover .lumir-block-icon-toggle,
705
- .lumir-block-item.is-active .lumir-block-icon-toggle {
706
- color: inherit;
707
- }
708
-
709
- /* Color Picker Menu */
710
- .lumir-color-menu {
711
- min-width: 180px;
712
- padding: 8px;
713
- }
714
-
715
- .lumir-color-grid {
716
- display: grid;
717
- grid-template-columns: repeat(5, 1fr);
718
- gap: 6px;
719
- }
720
-
721
- .lumir-color-swatch {
722
- width: 28px;
723
- height: 28px;
724
- border: 1px solid rgba(0, 0, 0, 0.15);
725
- border-radius: 4px;
726
- cursor: pointer;
727
- transition: all 0.15s ease;
728
- position: relative;
729
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
730
- }
731
-
732
- .lumir-color-swatch:hover {
733
- transform: scale(1.15);
734
- border-color: #3b82f6;
735
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
736
- z-index: 1;
737
- }
738
-
739
- .lumir-color-swatch.is-active {
740
- border-color: #3b82f6;
741
- border-width: 2px;
742
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
743
- }
744
-
745
- .lumir-color-swatch.is-active::after {
746
- content: "✓";
747
- position: absolute;
748
- top: 50%;
749
- left: 50%;
750
- transform: translate(-50%, -50%);
751
- color: #ffffff;
752
- font-size: 12px;
753
- font-weight: bold;
754
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
755
- }
756
-
757
- .lumir-color-remove {
758
- width: 100%;
759
- padding: 6px 8px;
760
- border: none;
761
- background-color: #f3f4f6;
762
- color: #6b7280;
763
- font-size: 11px;
764
- font-weight: 500;
765
- border-radius: 4px;
766
- cursor: pointer;
767
- transition: all 0.15s ease;
768
- }
769
-
770
- .lumir-color-remove:hover {
771
- background-color: #e5e7eb;
772
- color: #374151;
773
- }
774
-
775
- /* Text Controls Group */
776
- .lumir-text-controls {
777
- gap: 8px;
778
- }
779
-
780
- /* Link Input Menu - Compact */
781
- .lumir-link-menu {
782
- min-width: 240px;
783
- padding: 8px;
784
- left: auto;
785
- right: 0;
786
- }
787
-
788
- .lumir-link-form {
789
- display: flex;
790
- flex-direction: column;
791
- gap: 6px;
792
- }
793
-
794
- .lumir-link-input {
795
- width: 100%;
796
- padding: 6px 8px;
797
- border: 1px solid #d1d5db;
798
- border-radius: 4px;
799
- font-size: 12px;
800
- font-family: inherit;
801
- outline: none;
802
- transition: all 0.15s ease;
803
- }
804
-
805
- .lumir-link-input:focus {
806
- border-color: #3b82f6;
807
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
808
- }
809
-
810
- .lumir-link-input::placeholder {
811
- color: #9ca3af;
812
- font-size: 11px;
813
- }
814
-
815
- .lumir-link-actions {
816
- display: flex;
817
- gap: 4px;
818
- justify-content: flex-end;
819
- }
820
-
821
- .lumir-link-btn {
822
- padding: 4px 10px;
823
- border: none;
824
- border-radius: 4px;
825
- font-size: 11px;
826
- font-weight: 500;
827
- cursor: pointer;
828
- transition: all 0.15s ease;
829
- }
830
-
831
- .lumir-link-cancel {
832
- background-color: #f3f4f6;
833
- color: #6b7280;
834
- }
835
-
836
- .lumir-link-cancel:hover {
837
- background-color: #e5e7eb;
838
- color: #374151;
839
- }
840
-
841
- .lumir-link-submit {
842
- background-color: #3b82f6;
843
- color: #ffffff;
844
- }
845
-
846
- .lumir-link-submit:hover:not(:disabled) {
847
- background-color: #2563eb;
848
- }
849
-
850
- .lumir-link-submit:disabled {
851
- opacity: 0.5;
852
- cursor: not-allowed;
853
- }
854
-
855
- /*
856
- * 플로팅 툴바는 다크모드와 관계없이 항상 밝은 스타일 유지
857
- * 다크모드 오버라이드를 적용하지 않음
858
- */
859
-
860
- /* ========================================
861
- 에러 토스트 스타일
862
- ======================================== */
863
-
864
- .lumirEditor-error-toast {
865
- position: absolute;
866
- bottom: 16px;
867
- left: 50%;
868
- transform: translateX(-50%);
869
- display: flex;
870
- align-items: center;
871
- gap: 8px;
872
- padding: 12px 16px;
873
- background-color: #fef2f2;
874
- border: 1px solid #fecaca;
875
- border-radius: 8px;
876
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
877
- z-index: 1001;
878
- animation: lumirEditor-toast-appear 0.3s ease;
879
- max-width: 90%;
880
- }
881
-
882
- @keyframes lumirEditor-toast-appear {
883
- from {
884
- opacity: 0;
885
- transform: translateX(-50%) translateY(10px);
886
- }
887
- to {
888
- opacity: 1;
889
- transform: translateX(-50%) translateY(0);
890
- }
891
- }
892
-
893
- .lumirEditor-error-icon {
894
- flex-shrink: 0;
895
- font-size: 16px;
896
- }
897
-
898
- .lumirEditor-error-message {
899
- font-size: 13px;
900
- font-weight: 500;
901
- color: #991b1b;
902
- line-height: 1.4;
903
- }
904
-
905
- .lumirEditor-error-close {
906
- flex-shrink: 0;
907
- display: flex;
908
- align-items: center;
909
- justify-content: center;
910
- width: 20px;
911
- height: 20px;
912
- padding: 0;
913
- border: none;
914
- background: transparent;
915
- color: #991b1b;
916
- font-size: 14px;
917
- cursor: pointer;
918
- border-radius: 4px;
919
- transition: background-color 0.15s ease;
920
- }
921
-
922
- .lumirEditor-error-close:hover {
923
- background-color: #fee2e2;
924
- }
925
-
926
- /* ========================================
927
- Link Preview 카드 스타일
928
- ======================================== */
929
-
930
- @keyframes lumir-skeleton-pulse {
931
- 0% {
932
- opacity: 1;
933
- }
934
- 50% {
935
- opacity: 0.4;
936
- }
937
- 100% {
938
- opacity: 1;
939
- }
940
- }
941
-
942
- .lumir-link-preview-card:hover .lumir-link-preview-delete {
943
- opacity: 1 !important;
944
- }
945
-
946
- .lumir-link-preview-delete:hover {
947
- background-color: rgba(0, 0, 0, 0.7) !important;
948
- }
949
-
950
- .lumir-resize-handle {
951
- position: absolute;
952
- width: 8px;
953
- height: 30px;
954
- background-color: black;
955
- border: 1px solid white;
956
- border-radius: 4px;
957
- cursor: ew-resize;
958
- top: 50%;
959
- transform: translateY(-50%);
960
- z-index: 3;
961
- }
962
-
963
- .lumir-resize-handle-bottom {
964
- position: absolute;
965
- bottom: 4px;
966
- left: 50%;
967
- transform: translateX(-50%);
968
- width: 30px;
969
- height: 8px;
970
- background-color: black;
971
- border: 1px solid white;
972
- border-radius: 4px;
973
- cursor: ns-resize;
974
- z-index: 3;
975
- }
976
-
977
- .lumir-link-preview-card:hover {
978
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
979
- }
980
-
981
- .node-linkPreview.ProseMirror-selectednode .bn-block-content {
982
- outline: 2px solid #3b82f6;
983
- outline-offset: 2px;
984
- border-radius: 8px;
985
- }
986
-
987
- .node-linkPreview .bn-block-content {
988
- outline: none !important;
989
- }
990
-
991
- /* 다크 테마 대응 */
992
- [data-color-scheme="dark"] .lumir-link-preview-card,
993
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-card {
994
- background-color: #292524 !important;
995
- border-color: #44403c !important;
996
- }
997
-
998
- [data-color-scheme="dark"] .lumir-link-preview-card:hover,
999
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-card:hover {
1000
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
1001
- }
1002
-
1003
- [data-color-scheme="dark"] .lumir-link-preview-skeleton,
1004
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-skeleton {
1005
- background-color: #292524 !important;
1006
- border-color: #44403c !important;
1007
- }
1008
-
1009
- [data-color-scheme="dark"] .lumir-link-preview-error,
1010
- .bn-container[data-color-scheme="dark"] .lumir-link-preview-error {
1011
- background-color: #292524 !important;
1012
- border-color: #44403c !important;
1013
- }
1014
-
1015
- /* 인용·코드·테이블 본문 14px */
1016
- .lumirEditor .bn-block-content[data-content-type="quote"] p.bn-inline-content,
1017
- .lumirEditor [data-content-type="quote"] blockquote {
1018
- font-size: 14px;
1019
- }
1020
-
1021
- .lumirEditor .bn-block-content[data-content-type="codeBlock"] pre,
1022
- .lumirEditor .bn-block-content[data-content-type="codeBlock"] pre code {
1023
- font-size: 14px;
1024
- }
1025
-
1026
- .lumirEditor .bn-editor [data-content-type="table"] th,
1027
- .lumirEditor .bn-editor [data-content-type="table"] td,
1028
- .lumirEditor .bn-editor [data-content-type="table"] p.bn-inline-content {
1029
- font-size: 14px;
1030
- }
1031
-
1032
- /* 테이블 셀 세로 정렬 (VerticalAlignmentExtension) */
1033
- .lumirEditor .bn-editor [data-content-type="table"] td[data-vertical-alignment="middle"],
1034
- .lumirEditor .bn-editor [data-content-type="table"] th[data-vertical-alignment="middle"] {
1035
- vertical-align: middle;
1036
- }
1037
-
1038
- .lumirEditor .bn-editor [data-content-type="table"] td[data-vertical-alignment="bottom"],
1039
- .lumirEditor .bn-editor [data-content-type="table"] th[data-vertical-alignment="bottom"] {
1040
- vertical-align: bottom;
1041
- }
1
+ @import "@blocknote/core/fonts/inter.css";
2
+ @import "@blocknote/mantine/style.css";
3
+ @import "@blocknote/react/style.css";
4
+
5
+ .lumirEditor {
6
+ width: 100%;
7
+ height: 100%;
8
+ min-width: 200px;
9
+ overflow: visible; /* 슬래시 메뉴가 컨테이너를 넘어서 표시되도록 변경 */
10
+ background-color: #ffffff;
11
+ }
12
+
13
+ /* 에디터 내부 콘텐츠 영역만 스크롤 가능하게 설정 */
14
+ .lumirEditor .bn-container {
15
+ overflow: auto;
16
+ max-height: 100%;
17
+ }
18
+
19
+ /* 슬래시 메뉴(SuggestionMenu)가 컨테이너를 넘어서 표시되도록 */
20
+ .bn-suggestion-menu,
21
+ .bn-slash-menu,
22
+ .mantine-Menu-dropdown,
23
+ .mantine-Popover-dropdown {
24
+ z-index: 9999 !important;
25
+ }
26
+ /* 포커스 상태 스타일 - 테두리 없음 */
27
+ .lumirEditor:focus-within {
28
+ outline: none;
29
+ box-shadow: none;
30
+ }
31
+ .lumirEditor {
32
+ border: none;
33
+ }
34
+
35
+ /* BlockNote 에디터 내부 폰트 설정 */
36
+ .lumirEditor .bn-editor,
37
+ .lumirEditor .bn-inline-content {
38
+ font-family:
39
+ "Pretendard",
40
+ "Noto Sans KR",
41
+ -apple-system,
42
+ BlinkMacSystemFont,
43
+ "Segoe UI",
44
+ "Roboto",
45
+ "Oxygen",
46
+ "Ubuntu",
47
+ "Cantarell",
48
+ sans-serif;
49
+ }
50
+
51
+ /* 링크 스타일 - Tailwind Preflight 리셋 복원 */
52
+ .lumirEditor .bn-editor a,
53
+ .lumirEditor .bn-inline-content a {
54
+ color: #0b6e99;
55
+ text-decoration: underline;
56
+ text-underline-offset: 2px;
57
+ cursor: pointer;
58
+ }
59
+
60
+ .lumirEditor .bn-editor a:hover,
61
+ .lumirEditor .bn-inline-content a:hover {
62
+ color: #0b6e99;
63
+ }
64
+
65
+ /* CSS 변수를 사용한 패딩 설정 */
66
+ .lumirEditor .bn-editor {
67
+ padding-left: 25px;
68
+ padding-right: 10px;
69
+ padding-top: 5px;
70
+ padding-bottom: 0;
71
+ }
72
+
73
+ /*
74
+ * 본문·번호·글머리·체크 목록 인라인 텍스트 14px 통일
75
+ * BlockNote `.bn-default-styles { font-size: 16px }` + `p { font-size: inherit }` 때문에
76
+ * `p.bn-inline-content`에 명시적으로 14px (`.bn-block-content`에 data-type이 붙음)
77
+ */
78
+ .lumirEditor
79
+ .bn-block-content[data-content-type="paragraph"]
80
+ p.bn-inline-content,
81
+ .lumirEditor
82
+ .bn-block-content[data-content-type="numberedListItem"]
83
+ p.bn-inline-content,
84
+ .lumirEditor
85
+ .bn-block-content[data-content-type="bulletListItem"]
86
+ p.bn-inline-content,
87
+ .lumirEditor
88
+ .bn-block-content[data-content-type="checkListItem"]
89
+ p.bn-inline-content {
90
+ font-size: 14px;
91
+ }
92
+
93
+ /* 마커(번호·불릿)·체크 행 */
94
+ .lumirEditor .bn-block-content[data-content-type="numberedListItem"],
95
+ .lumirEditor .bn-block-content[data-content-type="bulletListItem"],
96
+ .lumirEditor .bn-block-content[data-content-type="checkListItem"] {
97
+ font-size: 14px;
98
+ }
99
+
100
+ .lumirEditor .bn-block-content {
101
+ max-width: 100%;
102
+ }
103
+
104
+ /* File Panel: Embed 탭 미노출 (URL 입력 방식 비활성화) */
105
+ .lumirEditor [data-test="embed-tab"] {
106
+ display: none !important;
107
+ }
108
+
109
+ /* 정렬된 블록의 인라인 콘텐츠 - 빈 블록에서 스크롤 방지 */
110
+ .lumirEditor .bn-inline-content {
111
+ overflow: hidden;
112
+ max-width: 100%;
113
+ min-width: 0;
114
+ }
115
+
116
+ /* 우측 정렬 시 빈 블록 placeholder 위치 수정 */
117
+ .lumirEditor [data-text-alignment="right"] .bn-inline-content::before {
118
+ position: relative;
119
+ max-width: 100%;
120
+ }
121
+
122
+ /* 이미지 업로드 로딩 스피너 */
123
+ .lumirEditor-upload-overlay {
124
+ position: absolute;
125
+ top: 0;
126
+ left: 0;
127
+ right: 0;
128
+ bottom: 0;
129
+ display: flex;
130
+ flex-direction: column;
131
+ align-items: center;
132
+ justify-content: center;
133
+ gap: 8px;
134
+ background-color: rgba(255, 255, 255, 0.8);
135
+ backdrop-filter: blur(2px);
136
+ z-index: 1000;
137
+ }
138
+
139
+ .lumirEditor-spinner {
140
+ width: 30px;
141
+ height: 30px;
142
+ border: 3px solid #f3f3f3;
143
+ border-top: 3px solid #3b82f6;
144
+ border-radius: 50%;
145
+ animation: lumir-spin 1s linear infinite;
146
+ }
147
+
148
+ .lumirEditor-upload-progress {
149
+ font-size: 14px;
150
+ font-weight: 500;
151
+ color: #374151;
152
+ }
153
+
154
+ @keyframes lumir-spin {
155
+ 0% {
156
+ transform: rotate(0deg);
157
+ }
158
+ 100% {
159
+ transform: rotate(360deg);
160
+ }
161
+ }
162
+
163
+ /* ========================================
164
+ Floating Toolbar 스타일 (컴팩트 + 반응형)
165
+ ======================================== */
166
+
167
+ /* CSS 변수 정의 */
168
+ .lumir-floating-toolbar-wrapper {
169
+ --lumir-bg-light: #fafaf9;
170
+ --lumir-bg-dark: #1c1917;
171
+ --lumir-paper-light: #ffffff;
172
+ --lumir-paper-dark: #292524;
173
+ --lumir-border-light: #e7e5e4;
174
+ --lumir-border-dark: #44403c;
175
+ --lumir-text-light: #1c1917;
176
+ --lumir-text-dark: #fafaf9;
177
+ --lumir-text-muted-light: #78716c;
178
+ --lumir-text-muted-dark: #a8a29e;
179
+ --lumir-hover-light: #f5f5f4;
180
+ --lumir-hover-dark: #44403c;
181
+ --lumir-active-bg: rgba(59, 130, 246, 0.1);
182
+ --lumir-active-color: #3b82f6;
183
+ --lumir-radius-lg: 0.5rem;
184
+ --lumir-radius-md: 0.25rem;
185
+ --lumir-transition: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
186
+ --lumir-btn-size: 28px;
187
+ --lumir-btn-padding: 6px;
188
+ --lumir-icon-size: 16px;
189
+ }
190
+
191
+ /* Toolbar Wrapper */
192
+ .lumir-floating-toolbar-wrapper {
193
+ width: 100%;
194
+ display: flex;
195
+ justify-content: center;
196
+ padding: 8px 12px;
197
+ z-index: 40;
198
+ }
199
+
200
+ /* 최소화 모드일 때는 좌측 상단 배치 */
201
+ .lumir-floating-toolbar-wrapper.is-minimizable {
202
+ justify-content: flex-start;
203
+ padding: 0;
204
+ }
205
+
206
+ .lumir-floating-toolbar-wrapper[data-position="sticky"] {
207
+ position: sticky;
208
+ top: 0;
209
+ }
210
+
211
+ .lumir-floating-toolbar-wrapper[data-position="fixed"] {
212
+ position: fixed;
213
+ top: 64px;
214
+ left: 0;
215
+ right: 0;
216
+ }
217
+
218
+ /* Toolbar Container - 항상 밝은 배경 유지 */
219
+ .lumir-floating-toolbar {
220
+ display: flex;
221
+ flex-wrap: wrap;
222
+ align-items: center;
223
+ gap: 2px;
224
+ padding: 4px;
225
+ background-color: #ffffff !important;
226
+ border: 1px solid #e5e7eb !important;
227
+ border-radius: var(--lumir-radius-lg);
228
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
229
+ max-width: 100%;
230
+ font-family: ui-sans-serif, system-ui, sans-serif;
231
+ font-size: 13px;
232
+ }
233
+
234
+ /* 1단 레이아웃 (넓은 화면) */
235
+ .lumir-floating-toolbar {
236
+ flex-wrap: nowrap;
237
+ }
238
+
239
+ /* 2단 레이아웃 (좁은 화면) */
240
+ .lumir-floating-toolbar.is-compact {
241
+ flex-wrap: wrap;
242
+ justify-content: center;
243
+ }
244
+
245
+ .lumir-floating-toolbar.is-compact .lumir-toolbar-row {
246
+ display: flex;
247
+ align-items: center;
248
+ width: 100%;
249
+ justify-content: center;
250
+ gap: 2px;
251
+ }
252
+
253
+ .lumir-floating-toolbar.is-compact .lumir-toolbar-row:not(:last-child) {
254
+ padding-bottom: 4px;
255
+ border-bottom: 1px solid var(--lumir-border-light);
256
+ margin-bottom: 4px;
257
+ }
258
+
259
+ /* 최소화 가능 레이아웃 (400px 이하) */
260
+ .lumir-floating-toolbar.is-minimizable {
261
+ flex-wrap: wrap; /* 여러 줄로 확장 가능 */
262
+ justify-content: flex-start; /* 좌측 정렬 */
263
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
264
+ padding: 0; /* 내부 공백 제거 */
265
+ }
266
+
267
+ /* 토글 버튼 스타일 */
268
+ .lumir-floating-toolbar.is-minimizable .lumir-toggle-button {
269
+ order: -1; /* 항상 맨 앞에 배치 */
270
+ flex-shrink: 0;
271
+ width: 24px; /* 컴팩트한 크기 */
272
+ height: 24px;
273
+ padding: 0; /* 패딩 제거하여 정확한 정렬 */
274
+ margin: 0;
275
+ border-radius: 4px;
276
+ display: flex;
277
+ align-items: center;
278
+ justify-content: center;
279
+ cursor: pointer;
280
+ transition: transform 0.2s ease;
281
+ }
282
+
283
+ .lumir-floating-toolbar.is-minimizable .lumir-toggle-button:hover {
284
+ transform: scale(1.1);
285
+ }
286
+
287
+ .lumir-floating-toolbar.is-minimizable .lumir-toggle-button svg {
288
+ width: 16px;
289
+ height: 16px;
290
+ display: block; /* inline 여백 제거 */
291
+ transition: transform 0.3s ease;
292
+ }
293
+
294
+ /* 메뉴 항목 애니메이션 */
295
+ .lumir-floating-toolbar.is-minimizable > *:not(.lumir-toggle-button) {
296
+ opacity: 1;
297
+ transform: translateX(0);
298
+ transition:
299
+ opacity 0.3s ease,
300
+ transform 0.3s ease;
301
+ }
302
+
303
+ /* 최소화 상태 - 토글 버튼만 표시 */
304
+ .lumir-floating-toolbar.is-minimizable.is-minimized {
305
+ width: auto;
306
+ min-width: 24px;
307
+ padding: 0;
308
+ border: none;
309
+ background: transparent !important;
310
+ box-shadow: none;
311
+ }
312
+
313
+ .lumir-floating-toolbar.is-minimizable.is-minimized
314
+ > *:not(.lumir-toggle-button) {
315
+ opacity: 0;
316
+ transform: translateX(-10px);
317
+ pointer-events: none;
318
+ max-width: 0;
319
+ overflow: hidden;
320
+ margin: 0;
321
+ padding: 0;
322
+ }
323
+
324
+ /* Toolbar Group */
325
+ .lumir-toolbar-group {
326
+ display: flex;
327
+ align-items: center;
328
+ gap: 1px;
329
+ padding: 0 2px;
330
+ }
331
+
332
+ /* Divider */
333
+ .lumir-toolbar-divider {
334
+ width: 1px;
335
+ height: 18px;
336
+ background-color: var(--lumir-border-light);
337
+ margin: 0 2px;
338
+ flex-shrink: 0;
339
+ }
340
+
341
+ /* 2단에서 divider 숨기기 */
342
+ .lumir-floating-toolbar.is-compact .lumir-toolbar-divider.row-break {
343
+ display: none;
344
+ }
345
+
346
+ /* Toolbar Button (컴팩트) */
347
+ .lumir-toolbar-btn {
348
+ display: flex;
349
+ align-items: center;
350
+ justify-content: center;
351
+ width: var(--lumir-btn-size);
352
+ height: var(--lumir-btn-size);
353
+ padding: var(--lumir-btn-padding);
354
+ border: none;
355
+ background: transparent;
356
+ color: var(--lumir-text-muted-light);
357
+ cursor: pointer;
358
+ border-radius: var(--lumir-radius-md);
359
+ transition: all var(--lumir-transition);
360
+ position: relative;
361
+ flex-shrink: 0;
362
+ }
363
+
364
+ .lumir-toolbar-btn svg {
365
+ width: var(--lumir-icon-size);
366
+ height: var(--lumir-icon-size);
367
+ }
368
+
369
+ .lumir-toolbar-btn:hover {
370
+ background-color: var(--lumir-hover-light);
371
+ color: var(--lumir-text-light);
372
+ }
373
+
374
+ .lumir-toolbar-btn.is-active {
375
+ background-color: var(--lumir-active-bg);
376
+ color: var(--lumir-active-color);
377
+ }
378
+
379
+ .lumir-toolbar-btn:disabled {
380
+ opacity: 0.4;
381
+ cursor: not-allowed;
382
+ }
383
+
384
+ /* 색상 버튼 인디케이터 */
385
+ .lumir-color-btn {
386
+ flex-direction: column;
387
+ gap: 1px;
388
+ width: var(--lumir-btn-size);
389
+ height: var(--lumir-btn-size);
390
+ padding: 4px;
391
+ }
392
+
393
+ .lumir-color-btn svg {
394
+ width: 14px;
395
+ height: 14px;
396
+ }
397
+
398
+ .lumir-color-indicator {
399
+ width: 12px;
400
+ height: 2px;
401
+ border-radius: 1px;
402
+ border: 1px solid rgba(0, 0, 0, 0.1);
403
+ }
404
+
405
+ /* SVG 아이콘 스타일 */
406
+ .lumir-toolbar-btn svg,
407
+ .lumir-dropdown-btn svg {
408
+ flex-shrink: 0;
409
+ }
410
+
411
+ /* Dropdown Wrapper */
412
+ .lumir-dropdown-wrapper {
413
+ position: relative;
414
+ }
415
+
416
+ /* Dropdown Button (컴팩트) */
417
+ .lumir-dropdown-btn {
418
+ display: flex;
419
+ align-items: center;
420
+ justify-content: space-between;
421
+ min-width: 90px;
422
+ max-width: 110px;
423
+ height: var(--lumir-btn-size);
424
+ padding: 4px 8px;
425
+ border: none;
426
+ background: transparent;
427
+ color: inherit;
428
+ cursor: pointer;
429
+ border-radius: var(--lumir-radius-md);
430
+ font-size: 12px;
431
+ font-weight: 500;
432
+ transition: all var(--lumir-transition);
433
+ gap: 2px;
434
+ white-space: nowrap;
435
+ overflow: hidden;
436
+ }
437
+
438
+ .lumir-dropdown-btn span {
439
+ overflow: hidden;
440
+ text-overflow: ellipsis;
441
+ }
442
+
443
+ .lumir-dropdown-btn:hover {
444
+ background-color: var(--lumir-hover-light);
445
+ }
446
+
447
+ .lumir-dropdown-btn svg {
448
+ width: 14px;
449
+ height: 14px;
450
+ flex-shrink: 0;
451
+ color: var(--lumir-text-muted-light);
452
+ }
453
+
454
+ /* Dropdown Menu - 항상 밝은 배경 유지 */
455
+ .lumir-dropdown-menu {
456
+ position: absolute;
457
+ top: calc(100% + 4px);
458
+ left: 0;
459
+ min-width: 160px;
460
+ background-color: #ffffff !important;
461
+ border: 1px solid #e5e7eb !important;
462
+ border-radius: 10px;
463
+ box-shadow:
464
+ 0 4px 16px rgba(0, 0, 0, 0.12),
465
+ 0 0 0 1px rgba(0, 0, 0, 0.04);
466
+ z-index: 9999;
467
+ padding: 6px;
468
+ animation: lumir-dropdown-appear 0.15s ease;
469
+ }
470
+
471
+ @keyframes lumir-dropdown-appear {
472
+ from {
473
+ opacity: 0;
474
+ transform: translateY(-4px);
475
+ }
476
+ to {
477
+ opacity: 1;
478
+ transform: translateY(0);
479
+ }
480
+ }
481
+
482
+ /* Dropdown Item - 항상 밝은 스타일 */
483
+ .lumir-dropdown-item {
484
+ display: flex;
485
+ align-items: center;
486
+ width: 100%;
487
+ padding: 8px 12px;
488
+ text-align: left;
489
+ border: none;
490
+ background: transparent;
491
+ color: #374151 !important;
492
+ cursor: pointer;
493
+ border-radius: 6px;
494
+ font-size: 14px;
495
+ transition: background-color 0.1s ease;
496
+ }
497
+
498
+ .lumir-dropdown-item:hover {
499
+ background-color: #f3f4f6 !important;
500
+ }
501
+
502
+ .lumir-dropdown-item.is-active {
503
+ background-color: rgba(59, 130, 246, 0.1) !important;
504
+ color: #3b82f6 !important;
505
+ }
506
+
507
+ /* Block Type Dropdown Button */
508
+ .lumir-block-type-btn {
509
+ min-width: 110px;
510
+ max-width: 130px;
511
+ gap: 4px;
512
+ padding: 4px 8px;
513
+ }
514
+
515
+ .lumir-block-icon {
516
+ display: flex;
517
+ align-items: center;
518
+ justify-content: center;
519
+ width: 22px;
520
+ height: 22px;
521
+ flex-shrink: 0;
522
+ color: #6b7280;
523
+ }
524
+
525
+ .lumir-block-icon svg {
526
+ width: 18px;
527
+ height: 18px;
528
+ }
529
+
530
+ .lumir-block-icon-text {
531
+ font-size: 13px;
532
+ font-weight: 700;
533
+ color: #6b7280;
534
+ line-height: 1;
535
+ }
536
+
537
+ .lumir-block-label {
538
+ flex: 1;
539
+ text-align: left;
540
+ overflow: hidden;
541
+ text-overflow: ellipsis;
542
+ white-space: nowrap;
543
+ font-size: 13px;
544
+ }
545
+
546
+ /* Block Type Dropdown Menu - 최대 컴팩트 */
547
+ .lumir-block-menu {
548
+ min-width: 160px;
549
+ max-height: 320px;
550
+ overflow-y: auto;
551
+ padding: 3px;
552
+ }
553
+
554
+ /* 커스텀 스크롤바 - 더 얇게 */
555
+ .lumir-block-menu::-webkit-scrollbar {
556
+ width: 4px;
557
+ }
558
+
559
+ .lumir-block-menu::-webkit-scrollbar-track {
560
+ background: transparent;
561
+ }
562
+
563
+ .lumir-block-menu::-webkit-scrollbar-thumb {
564
+ background-color: #d1d5db;
565
+ border-radius: 2px;
566
+ }
567
+
568
+ .lumir-block-menu::-webkit-scrollbar-thumb:hover {
569
+ background-color: #9ca3af;
570
+ }
571
+
572
+ /* Block Type Menu Item - 최대 컴팩트 */
573
+ .lumir-block-item {
574
+ display: flex;
575
+ align-items: center;
576
+ gap: 6px;
577
+ padding: 4px 8px;
578
+ border-radius: 4px;
579
+ margin-bottom: 0;
580
+ transition: all 0.1s ease;
581
+ }
582
+
583
+ .lumir-block-item:last-child {
584
+ margin-bottom: 0;
585
+ }
586
+
587
+ .lumir-block-item .lumir-block-icon {
588
+ width: 20px;
589
+ height: 20px;
590
+ background-color: #f3f4f6;
591
+ border-radius: 3px;
592
+ display: flex;
593
+ align-items: center;
594
+ justify-content: center;
595
+ flex-shrink: 0;
596
+ }
597
+
598
+ .lumir-block-item .lumir-block-icon svg {
599
+ width: 14px;
600
+ height: 14px;
601
+ }
602
+
603
+ .lumir-block-item .lumir-block-icon-text {
604
+ font-size: 10px;
605
+ font-weight: 700;
606
+ }
607
+
608
+ .lumir-block-item-title {
609
+ font-size: 12px;
610
+ font-weight: 500;
611
+ color: #374151;
612
+ }
613
+
614
+ .lumir-block-item:hover {
615
+ background-color: #f3f4f6 !important;
616
+ }
617
+
618
+ .lumir-block-item:hover .lumir-block-icon {
619
+ background-color: #e5e7eb;
620
+ color: #374151;
621
+ }
622
+
623
+ .lumir-block-item:hover .lumir-block-icon-text {
624
+ color: #374151;
625
+ }
626
+
627
+ .lumir-block-item.is-active {
628
+ background-color: rgba(59, 130, 246, 0.08) !important;
629
+ }
630
+
631
+ .lumir-block-item.is-active .lumir-block-icon {
632
+ background-color: rgba(59, 130, 246, 0.15);
633
+ color: #3b82f6;
634
+ }
635
+
636
+ .lumir-block-item.is-active .lumir-block-icon-text {
637
+ color: #3b82f6;
638
+ }
639
+
640
+ /* Block Type Category - 최대 컴팩트 */
641
+ .lumir-block-category {
642
+ margin-bottom: 2px;
643
+ }
644
+
645
+ .lumir-block-category:last-child {
646
+ margin-bottom: 0;
647
+ }
648
+
649
+ .lumir-block-category-title {
650
+ font-size: 9px;
651
+ font-weight: 600;
652
+ color: #9ca3af;
653
+ text-transform: uppercase;
654
+ letter-spacing: 0.05em;
655
+ padding: 4px 8px 2px;
656
+ margin-bottom: 0;
657
+ }
658
+
659
+ /* Block Item Title */
660
+ .lumir-block-item:hover .lumir-block-item-title {
661
+ color: #1f2937;
662
+ }
663
+
664
+ .lumir-block-item.is-active .lumir-block-item-title {
665
+ color: #3b82f6;
666
+ font-weight: 600;
667
+ }
668
+
669
+ /* Toggle Heading 아이콘 - 컴팩트 */
670
+ .lumir-block-icon-toggle {
671
+ display: flex;
672
+ align-items: center;
673
+ gap: 2px;
674
+ font-size: 9px;
675
+ font-weight: 700;
676
+ color: #6b7280;
677
+ line-height: 1;
678
+ }
679
+
680
+ .lumir-block-icon-toggle svg {
681
+ width: 6px;
682
+ height: 6px;
683
+ flex-shrink: 0;
684
+ }
685
+
686
+ .lumir-block-icon-toggle span {
687
+ font-size: 9px;
688
+ font-weight: 700;
689
+ }
690
+
691
+ .lumir-block-item .lumir-block-icon-toggle {
692
+ font-size: 10px;
693
+ }
694
+
695
+ .lumir-block-item .lumir-block-icon-toggle svg {
696
+ width: 7px;
697
+ height: 7px;
698
+ }
699
+
700
+ .lumir-block-item .lumir-block-icon-toggle span {
701
+ font-size: 10px;
702
+ }
703
+
704
+ .lumir-block-item:hover .lumir-block-icon-toggle,
705
+ .lumir-block-item.is-active .lumir-block-icon-toggle {
706
+ color: inherit;
707
+ }
708
+
709
+ /* Color Picker Menu */
710
+ .lumir-color-menu {
711
+ min-width: 180px;
712
+ padding: 8px;
713
+ }
714
+
715
+ .lumir-color-grid {
716
+ display: grid;
717
+ grid-template-columns: repeat(5, 1fr);
718
+ gap: 6px;
719
+ }
720
+
721
+ .lumir-color-swatch {
722
+ width: 28px;
723
+ height: 28px;
724
+ border: 1px solid rgba(0, 0, 0, 0.15);
725
+ border-radius: 4px;
726
+ cursor: pointer;
727
+ transition: all 0.15s ease;
728
+ position: relative;
729
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
730
+ }
731
+
732
+ .lumir-color-swatch:hover {
733
+ transform: scale(1.15);
734
+ border-color: #3b82f6;
735
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
736
+ z-index: 1;
737
+ }
738
+
739
+ .lumir-color-swatch.is-active {
740
+ border-color: #3b82f6;
741
+ border-width: 2px;
742
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
743
+ }
744
+
745
+ .lumir-color-swatch.is-active::after {
746
+ content: "✓";
747
+ position: absolute;
748
+ top: 50%;
749
+ left: 50%;
750
+ transform: translate(-50%, -50%);
751
+ color: #ffffff;
752
+ font-size: 12px;
753
+ font-weight: bold;
754
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
755
+ }
756
+
757
+ .lumir-color-remove {
758
+ width: 100%;
759
+ padding: 6px 8px;
760
+ border: none;
761
+ background-color: #f3f4f6;
762
+ color: #6b7280;
763
+ font-size: 11px;
764
+ font-weight: 500;
765
+ border-radius: 4px;
766
+ cursor: pointer;
767
+ transition: all 0.15s ease;
768
+ }
769
+
770
+ .lumir-color-remove:hover {
771
+ background-color: #e5e7eb;
772
+ color: #374151;
773
+ }
774
+
775
+ /* Text Controls Group */
776
+ .lumir-text-controls {
777
+ gap: 8px;
778
+ }
779
+
780
+ /* Link Input Menu - Compact */
781
+ .lumir-link-menu {
782
+ min-width: 240px;
783
+ padding: 8px;
784
+ left: auto;
785
+ right: 0;
786
+ }
787
+
788
+ .lumir-link-form {
789
+ display: flex;
790
+ flex-direction: column;
791
+ gap: 6px;
792
+ }
793
+
794
+ .lumir-link-input {
795
+ width: 100%;
796
+ padding: 6px 8px;
797
+ border: 1px solid #d1d5db;
798
+ border-radius: 4px;
799
+ font-size: 12px;
800
+ font-family: inherit;
801
+ outline: none;
802
+ transition: all 0.15s ease;
803
+ }
804
+
805
+ .lumir-link-input:focus {
806
+ border-color: #3b82f6;
807
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
808
+ }
809
+
810
+ .lumir-link-input::placeholder {
811
+ color: #9ca3af;
812
+ font-size: 11px;
813
+ }
814
+
815
+ .lumir-link-actions {
816
+ display: flex;
817
+ gap: 4px;
818
+ justify-content: flex-end;
819
+ }
820
+
821
+ .lumir-link-btn {
822
+ padding: 4px 10px;
823
+ border: none;
824
+ border-radius: 4px;
825
+ font-size: 11px;
826
+ font-weight: 500;
827
+ cursor: pointer;
828
+ transition: all 0.15s ease;
829
+ }
830
+
831
+ .lumir-link-cancel {
832
+ background-color: #f3f4f6;
833
+ color: #6b7280;
834
+ }
835
+
836
+ .lumir-link-cancel:hover {
837
+ background-color: #e5e7eb;
838
+ color: #374151;
839
+ }
840
+
841
+ .lumir-link-submit {
842
+ background-color: #3b82f6;
843
+ color: #ffffff;
844
+ }
845
+
846
+ .lumir-link-submit:hover:not(:disabled) {
847
+ background-color: #2563eb;
848
+ }
849
+
850
+ .lumir-link-submit:disabled {
851
+ opacity: 0.5;
852
+ cursor: not-allowed;
853
+ }
854
+
855
+ /*
856
+ * 플로팅 툴바는 다크모드와 관계없이 항상 밝은 스타일 유지
857
+ * 다크모드 오버라이드를 적용하지 않음
858
+ */
859
+
860
+ /* ========================================
861
+ 에러 토스트 스타일
862
+ ======================================== */
863
+
864
+ .lumirEditor-error-toast {
865
+ position: absolute;
866
+ bottom: 16px;
867
+ left: 50%;
868
+ transform: translateX(-50%);
869
+ display: flex;
870
+ align-items: center;
871
+ gap: 8px;
872
+ padding: 12px 16px;
873
+ background-color: #fef2f2;
874
+ border: 1px solid #fecaca;
875
+ border-radius: 8px;
876
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
877
+ z-index: 1001;
878
+ animation: lumirEditor-toast-appear 0.3s ease;
879
+ max-width: 90%;
880
+ }
881
+
882
+ @keyframes lumirEditor-toast-appear {
883
+ from {
884
+ opacity: 0;
885
+ transform: translateX(-50%) translateY(10px);
886
+ }
887
+ to {
888
+ opacity: 1;
889
+ transform: translateX(-50%) translateY(0);
890
+ }
891
+ }
892
+
893
+ .lumirEditor-error-icon {
894
+ flex-shrink: 0;
895
+ font-size: 16px;
896
+ }
897
+
898
+ .lumirEditor-error-message {
899
+ font-size: 13px;
900
+ font-weight: 500;
901
+ color: #991b1b;
902
+ line-height: 1.4;
903
+ }
904
+
905
+ .lumirEditor-error-close {
906
+ flex-shrink: 0;
907
+ display: flex;
908
+ align-items: center;
909
+ justify-content: center;
910
+ width: 20px;
911
+ height: 20px;
912
+ padding: 0;
913
+ border: none;
914
+ background: transparent;
915
+ color: #991b1b;
916
+ font-size: 14px;
917
+ cursor: pointer;
918
+ border-radius: 4px;
919
+ transition: background-color 0.15s ease;
920
+ }
921
+
922
+ .lumirEditor-error-close:hover {
923
+ background-color: #fee2e2;
924
+ }
925
+
926
+ /* ========================================
927
+ Link Preview 카드 스타일
928
+ ======================================== */
929
+
930
+ @keyframes lumir-skeleton-pulse {
931
+ 0% {
932
+ opacity: 1;
933
+ }
934
+ 50% {
935
+ opacity: 0.4;
936
+ }
937
+ 100% {
938
+ opacity: 1;
939
+ }
940
+ }
941
+
942
+ .lumir-link-preview-card:hover .lumir-link-preview-delete {
943
+ opacity: 1 !important;
944
+ }
945
+
946
+ .lumir-link-preview-delete:hover {
947
+ background-color: rgba(0, 0, 0, 0.7) !important;
948
+ }
949
+
950
+ .lumir-resize-handle {
951
+ position: absolute;
952
+ width: 8px;
953
+ height: 30px;
954
+ background-color: black;
955
+ border: 1px solid white;
956
+ border-radius: 4px;
957
+ cursor: ew-resize;
958
+ top: 50%;
959
+ transform: translateY(-50%);
960
+ z-index: 3;
961
+ }
962
+
963
+ .lumir-resize-handle-bottom {
964
+ position: absolute;
965
+ bottom: 4px;
966
+ left: 50%;
967
+ transform: translateX(-50%);
968
+ width: 30px;
969
+ height: 8px;
970
+ background-color: black;
971
+ border: 1px solid white;
972
+ border-radius: 4px;
973
+ cursor: ns-resize;
974
+ z-index: 3;
975
+ }
976
+
977
+ .lumir-link-preview-card:hover {
978
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
979
+ }
980
+
981
+ .node-linkPreview.ProseMirror-selectednode .bn-block-content {
982
+ outline: 2px solid #3b82f6;
983
+ outline-offset: 2px;
984
+ border-radius: 8px;
985
+ }
986
+
987
+ .node-linkPreview .bn-block-content {
988
+ outline: none !important;
989
+ }
990
+
991
+ /* 다크 테마 대응 */
992
+ [data-color-scheme="dark"] .lumir-link-preview-card,
993
+ .bn-container[data-color-scheme="dark"] .lumir-link-preview-card {
994
+ background-color: #292524 !important;
995
+ border-color: #44403c !important;
996
+ }
997
+
998
+ [data-color-scheme="dark"] .lumir-link-preview-card:hover,
999
+ .bn-container[data-color-scheme="dark"] .lumir-link-preview-card:hover {
1000
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
1001
+ }
1002
+
1003
+ [data-color-scheme="dark"] .lumir-link-preview-skeleton,
1004
+ .bn-container[data-color-scheme="dark"] .lumir-link-preview-skeleton {
1005
+ background-color: #292524 !important;
1006
+ border-color: #44403c !important;
1007
+ }
1008
+
1009
+ [data-color-scheme="dark"] .lumir-link-preview-error,
1010
+ .bn-container[data-color-scheme="dark"] .lumir-link-preview-error {
1011
+ background-color: #292524 !important;
1012
+ border-color: #44403c !important;
1013
+ }
1014
+
1015
+ /* 인용·코드·테이블 본문 14px */
1016
+ .lumirEditor .bn-block-content[data-content-type="quote"] p.bn-inline-content,
1017
+ .lumirEditor [data-content-type="quote"] blockquote {
1018
+ font-size: 14px;
1019
+ }
1020
+
1021
+ .lumirEditor .bn-block-content[data-content-type="codeBlock"] pre,
1022
+ .lumirEditor .bn-block-content[data-content-type="codeBlock"] pre code {
1023
+ font-size: 14px;
1024
+ }
1025
+
1026
+ .lumirEditor .bn-editor [data-content-type="table"] th,
1027
+ .lumirEditor .bn-editor [data-content-type="table"] td,
1028
+ .lumirEditor .bn-editor [data-content-type="table"] p.bn-inline-content {
1029
+ font-size: 14px;
1030
+ }
1031
+
1032
+ /* 테이블 셀 세로 정렬 (VerticalAlignmentExtension) */
1033
+ .lumirEditor .bn-editor [data-content-type="table"] td[data-vertical-alignment="middle"],
1034
+ .lumirEditor .bn-editor [data-content-type="table"] th[data-vertical-alignment="middle"] {
1035
+ vertical-align: middle;
1036
+ }
1037
+
1038
+ .lumirEditor .bn-editor [data-content-type="table"] td[data-vertical-alignment="bottom"],
1039
+ .lumirEditor .bn-editor [data-content-type="table"] th[data-vertical-alignment="bottom"] {
1040
+ vertical-align: bottom;
1041
+ }