@lumir-company/editor 0.4.7 → 0.4.8

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