@lumir-company/editor 0.4.23 → 0.4.25

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,1463 +1,1463 @@
1
- @import '@blocknote/core/fonts/inter.css';
2
- @import '@blocknote/mantine/style.css';
3
- @import '@blocknote/react/style.css';
4
-
5
- /* Pretendard 한글 글꼴 (가변 폰트, swap).
6
- @import url()은 번들 시 @import 순서 규칙을 위반해 사용 불가 → @font-face로 로드.
7
- 호스트 앱이 Pretendard를 자체 로드한다면 이 블록은 제거해도 된다. */
8
- @font-face {
9
- font-family: 'Pretendard';
10
- font-weight: 100 900;
11
- font-style: normal;
12
- font-display: swap;
13
- src: url('https://cdn.jsdelivr.net/npm/pretendard@1.3.9/dist/web/variable/woff2/PretendardVariable.woff2')
14
- format('woff2-variations');
15
- }
16
-
17
- .lumirEditor {
18
- width: 100%;
19
- height: 100%;
20
- min-width: 200px;
21
- overflow: visible; /* 슬래시 메뉴가 컨테이너를 넘어서 표시되도록 변경 */
22
- background-color: #ffffff;
23
- /* 에디터 전체(본문·툴바·인-DOM 드롭다운) 한글 글꼴 Pretendard */
24
- font-family:
25
- 'Pretendard',
26
- 'Noto Sans KR',
27
- -apple-system,
28
- BlinkMacSystemFont,
29
- 'Segoe UI',
30
- 'Roboto',
31
- sans-serif;
32
- }
33
-
34
- /* 에디터 내부 콘텐츠 영역만 스크롤 가능하게 설정 */
35
- .lumirEditor .bn-container {
36
- overflow: auto;
37
- max-height: 100%;
38
- }
39
-
40
- /* 슬래시 메뉴(SuggestionMenu)가 컨테이너를 넘어서 표시되도록 */
41
- .bn-suggestion-menu,
42
- .bn-slash-menu,
43
- .mantine-Menu-dropdown,
44
- .mantine-Popover-dropdown {
45
- z-index: 9999 !important;
46
- }
47
-
48
- /* 포털(body)로 빠지는 메뉴/드롭다운에도 Pretendard 적용 */
49
- .bn-suggestion-menu,
50
- .bn-slash-menu,
51
- .mantine-Menu-dropdown,
52
- .mantine-Popover-dropdown,
53
- .bn-table-handle-menu,
54
- .bn-menu-dropdown {
55
- font-family:
56
- 'Pretendard',
57
- 'Noto Sans KR',
58
- -apple-system,
59
- BlinkMacSystemFont,
60
- 'Segoe UI',
61
- 'Roboto',
62
- sans-serif;
63
- }
64
- /* 포커스 상태 스타일 - 테두리 없음 */
65
- .lumirEditor:focus-within {
66
- outline: none;
67
- box-shadow: none;
68
- }
69
- .lumirEditor {
70
- border: none;
71
- }
72
-
73
- /* BlockNote 에디터 내부 폰트 설정 */
74
- .lumirEditor .bn-editor,
75
- .lumirEditor .bn-inline-content {
76
- font-family:
77
- 'Pretendard',
78
- 'Noto Sans KR',
79
- -apple-system,
80
- BlinkMacSystemFont,
81
- 'Segoe UI',
82
- 'Roboto',
83
- 'Oxygen',
84
- 'Ubuntu',
85
- 'Cantarell',
86
- sans-serif;
87
- }
88
-
89
- /* 링크 스타일 - Tailwind Preflight 리셋 복원 */
90
- .lumirEditor .bn-editor a,
91
- .lumirEditor .bn-inline-content a {
92
- color: #0b6e99;
93
- text-decoration: underline;
94
- text-underline-offset: 2px;
95
- cursor: pointer;
96
- }
97
-
98
- .lumirEditor .bn-editor a:hover,
99
- .lumirEditor .bn-inline-content a:hover {
100
- color: #0b6e99;
101
- }
102
-
103
- /* CSS 변수를 사용한 패딩 설정 */
104
- .lumirEditor .bn-editor {
105
- padding-left: 25px;
106
- padding-right: 10px;
107
- padding-top: 5px;
108
- padding-bottom: 0;
109
- }
110
-
111
- /*
112
- * 본문·번호·글머리·체크 목록 인라인 텍스트 14px 통일
113
- * BlockNote `.bn-default-styles { font-size: 16px }` + `p { font-size: inherit }` 때문에
114
- * `p.bn-inline-content`에 명시적으로 14px (`.bn-block-content`에 data-type이 붙음)
115
- */
116
- .lumirEditor
117
- .bn-block-content[data-content-type='paragraph']
118
- p.bn-inline-content,
119
- .lumirEditor
120
- .bn-block-content[data-content-type='numberedListItem']
121
- p.bn-inline-content,
122
- .lumirEditor
123
- .bn-block-content[data-content-type='bulletListItem']
124
- p.bn-inline-content,
125
- .lumirEditor
126
- .bn-block-content[data-content-type='checkListItem']
127
- p.bn-inline-content {
128
- font-size: 14px;
129
- }
130
-
131
- /* 마커(번호·불릿)·체크 행 */
132
- .lumirEditor .bn-block-content[data-content-type='numberedListItem'],
133
- .lumirEditor .bn-block-content[data-content-type='bulletListItem'],
134
- .lumirEditor .bn-block-content[data-content-type='checkListItem'] {
135
- font-size: 14px;
136
- }
137
-
138
- .lumirEditor .bn-block-content {
139
- max-width: 100%;
140
- }
141
-
142
- /* File Panel: Embed 탭 미노출 (URL 입력 방식 비활성화) */
143
- .lumirEditor [data-test='embed-tab'] {
144
- display: none !important;
145
- }
146
-
147
- /* 정렬된 블록의 인라인 콘텐츠 - 빈 블록에서 스크롤 방지 */
148
- .lumirEditor .bn-inline-content {
149
- overflow: hidden;
150
- max-width: 100%;
151
- min-width: 0;
152
- }
153
-
154
- /* 우측 정렬 시 빈 블록 placeholder 위치 수정 */
155
- .lumirEditor [data-text-alignment='right'] .bn-inline-content::before {
156
- position: relative;
157
- max-width: 100%;
158
- }
159
-
160
- /* 이미지 업로드 로딩 스피너 */
161
- .lumirEditor-upload-overlay {
162
- position: absolute;
163
- top: 0;
164
- left: 0;
165
- right: 0;
166
- bottom: 0;
167
- display: flex;
168
- flex-direction: column;
169
- align-items: center;
170
- justify-content: center;
171
- gap: 8px;
172
- background-color: rgba(255, 255, 255, 0.8);
173
- backdrop-filter: blur(2px);
174
- z-index: 1000;
175
- }
176
-
177
- .lumirEditor-spinner {
178
- width: 30px;
179
- height: 30px;
180
- border: 3px solid #f3f3f3;
181
- border-top: 3px solid #3b82f6;
182
- border-radius: 50%;
183
- animation: lumir-spin 1s linear infinite;
184
- }
185
-
186
- .lumirEditor-upload-progress {
187
- font-size: 14px;
188
- font-weight: 500;
189
- color: #374151;
190
- }
191
-
192
- @keyframes lumir-spin {
193
- 0% {
194
- transform: rotate(0deg);
195
- }
196
- 100% {
197
- transform: rotate(360deg);
198
- }
199
- }
200
-
201
- /* ========================================
202
- Floating Toolbar 스타일 (컴팩트 + 반응형)
203
- ======================================== */
204
-
205
- /* CSS 변수 정의 */
206
- .lumir-floating-toolbar-wrapper {
207
- --lumir-bg-light: #fafaf9;
208
- --lumir-bg-dark: #1c1917;
209
- --lumir-paper-light: #ffffff;
210
- --lumir-paper-dark: #292524;
211
- --lumir-border-light: #e7e5e4;
212
- --lumir-border-dark: #44403c;
213
- --lumir-text-light: #1c1917;
214
- --lumir-text-dark: #fafaf9;
215
- --lumir-text-muted-light: #78716c;
216
- --lumir-text-muted-dark: #a8a29e;
217
- --lumir-hover-light: #f5f5f4;
218
- --lumir-hover-dark: #44403c;
219
- --lumir-active-bg: rgba(59, 130, 246, 0.1);
220
- --lumir-active-color: #3b82f6;
221
- --lumir-radius-lg: 0.5rem;
222
- --lumir-radius-md: 0.25rem;
223
- --lumir-transition: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
224
- --lumir-btn-size: 28px;
225
- --lumir-btn-padding: 6px;
226
- --lumir-icon-size: 16px;
227
- }
228
-
229
- /* Toolbar Wrapper */
230
- .lumir-floating-toolbar-wrapper {
231
- width: 100%;
232
- display: flex;
233
- justify-content: center;
234
- padding: 8px 12px;
235
- z-index: 40;
236
- }
237
-
238
- /* 최소화 모드일 때는 좌측 상단 배치 */
239
- .lumir-floating-toolbar-wrapper.is-minimizable {
240
- justify-content: flex-start;
241
- padding: 0;
242
- }
243
-
244
- .lumir-floating-toolbar-wrapper[data-position='sticky'] {
245
- position: sticky;
246
- top: 0;
247
- }
248
-
249
- .lumir-floating-toolbar-wrapper[data-position='fixed'] {
250
- position: fixed;
251
- top: 64px;
252
- left: 0;
253
- right: 0;
254
- }
255
-
256
- /* Toolbar Container - 항상 밝은 배경 유지 */
257
- .lumir-floating-toolbar {
258
- display: flex;
259
- flex-wrap: wrap;
260
- align-items: center;
261
- gap: 2px;
262
- padding: 4px;
263
- background-color: #ffffff !important;
264
- border: 1px solid #e5e7eb !important;
265
- border-radius: var(--lumir-radius-lg);
266
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
267
- max-width: 100%;
268
- font-family: ui-sans-serif, system-ui, sans-serif;
269
- font-size: 13px;
270
- }
271
-
272
- /* 1단 레이아웃 (넓은 화면) */
273
- .lumir-floating-toolbar {
274
- flex-wrap: nowrap;
275
- }
276
-
277
- /* 2단 레이아웃 (좁은 화면) */
278
- .lumir-floating-toolbar.is-compact {
279
- flex-wrap: wrap;
280
- justify-content: center;
281
- }
282
-
283
- .lumir-floating-toolbar.is-compact .lumir-toolbar-row {
284
- display: flex;
285
- align-items: center;
286
- width: 100%;
287
- justify-content: center;
288
- gap: 2px;
289
- }
290
-
291
- .lumir-floating-toolbar.is-compact .lumir-toolbar-row:not(:last-child) {
292
- padding-bottom: 4px;
293
- border-bottom: 1px solid var(--lumir-border-light);
294
- margin-bottom: 4px;
295
- }
296
-
297
- /* 최소화 가능 레이아웃 (400px 이하) */
298
- .lumir-floating-toolbar.is-minimizable {
299
- flex-wrap: wrap; /* 여러 줄로 확장 가능 */
300
- justify-content: flex-start; /* 좌측 정렬 */
301
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
302
- padding: 0; /* 내부 공백 제거 */
303
- }
304
-
305
- /* 토글 버튼 스타일 */
306
- .lumir-floating-toolbar.is-minimizable .lumir-toggle-button {
307
- order: -1; /* 항상 맨 앞에 배치 */
308
- flex-shrink: 0;
309
- width: 24px; /* 컴팩트한 크기 */
310
- height: 24px;
311
- padding: 0; /* 패딩 제거하여 정확한 정렬 */
312
- margin: 0;
313
- border-radius: 4px;
314
- display: flex;
315
- align-items: center;
316
- justify-content: center;
317
- cursor: pointer;
318
- transition: transform 0.2s ease;
319
- }
320
-
321
- .lumir-floating-toolbar.is-minimizable .lumir-toggle-button:hover {
322
- transform: scale(1.1);
323
- }
324
-
325
- .lumir-floating-toolbar.is-minimizable .lumir-toggle-button svg {
326
- width: 16px;
327
- height: 16px;
328
- display: block; /* inline 여백 제거 */
329
- transition: transform 0.3s ease;
330
- }
331
-
332
- /* 메뉴 항목 애니메이션 */
333
- .lumir-floating-toolbar.is-minimizable > *:not(.lumir-toggle-button) {
334
- opacity: 1;
335
- transform: translateX(0);
336
- transition:
337
- opacity 0.3s ease,
338
- transform 0.3s ease;
339
- }
340
-
341
- /* 최소화 상태 - 토글 버튼만 표시 */
342
- .lumir-floating-toolbar.is-minimizable.is-minimized {
343
- width: auto;
344
- min-width: 24px;
345
- padding: 0;
346
- border: none;
347
- background: transparent !important;
348
- box-shadow: none;
349
- }
350
-
351
- .lumir-floating-toolbar.is-minimizable.is-minimized
352
- > *:not(.lumir-toggle-button) {
353
- opacity: 0;
354
- transform: translateX(-10px);
355
- pointer-events: none;
356
- max-width: 0;
357
- overflow: hidden;
358
- margin: 0;
359
- padding: 0;
360
- }
361
-
362
- /* Toolbar Group */
363
- .lumir-toolbar-group {
364
- display: flex;
365
- align-items: center;
366
- gap: 1px;
367
- padding: 0 2px;
368
- }
369
-
370
- /* Divider */
371
- .lumir-toolbar-divider {
372
- width: 1px;
373
- height: 18px;
374
- background-color: var(--lumir-border-light);
375
- margin: 0 2px;
376
- flex-shrink: 0;
377
- }
378
-
379
- /* 2단에서 divider 숨기기 */
380
- .lumir-floating-toolbar.is-compact .lumir-toolbar-divider.row-break {
381
- display: none;
382
- }
383
-
384
- /* Toolbar Button (컴팩트) */
385
- .lumir-toolbar-btn {
386
- display: flex;
387
- align-items: center;
388
- justify-content: center;
389
- width: var(--lumir-btn-size);
390
- height: var(--lumir-btn-size);
391
- padding: var(--lumir-btn-padding);
392
- border: none;
393
- background: transparent;
394
- color: var(--lumir-text-muted-light);
395
- cursor: pointer;
396
- border-radius: var(--lumir-radius-md);
397
- transition: all var(--lumir-transition);
398
- position: relative;
399
- flex-shrink: 0;
400
- }
401
-
402
- .lumir-toolbar-btn svg {
403
- width: var(--lumir-icon-size);
404
- height: var(--lumir-icon-size);
405
- }
406
-
407
- .lumir-toolbar-btn:hover {
408
- background-color: var(--lumir-hover-light);
409
- color: var(--lumir-text-light);
410
- }
411
-
412
- .lumir-toolbar-btn.is-active {
413
- background-color: var(--lumir-active-bg);
414
- color: var(--lumir-active-color);
415
- }
416
-
417
- .lumir-toolbar-btn:disabled {
418
- opacity: 0.4;
419
- cursor: not-allowed;
420
- }
421
-
422
- /* 색상 버튼 인디케이터 */
423
- .lumir-color-btn {
424
- flex-direction: column;
425
- gap: 1px;
426
- width: var(--lumir-btn-size);
427
- height: var(--lumir-btn-size);
428
- padding: 4px;
429
- }
430
-
431
- .lumir-color-btn svg {
432
- width: 14px;
433
- height: 14px;
434
- }
435
-
436
- .lumir-color-indicator {
437
- width: 12px;
438
- height: 2px;
439
- border-radius: 1px;
440
- border: 1px solid rgba(0, 0, 0, 0.1);
441
- }
442
-
443
- /* SVG 아이콘 스타일 */
444
- .lumir-toolbar-btn svg,
445
- .lumir-dropdown-btn svg {
446
- flex-shrink: 0;
447
- }
448
-
449
- /* Dropdown Wrapper */
450
- .lumir-dropdown-wrapper {
451
- position: relative;
452
- }
453
-
454
- /* Dropdown Button (컴팩트) */
455
- .lumir-dropdown-btn {
456
- display: flex;
457
- align-items: center;
458
- justify-content: space-between;
459
- min-width: 90px;
460
- max-width: 110px;
461
- height: var(--lumir-btn-size);
462
- padding: 4px 8px;
463
- border: none;
464
- background: transparent;
465
- color: inherit;
466
- cursor: pointer;
467
- border-radius: var(--lumir-radius-md);
468
- font-size: 12px;
469
- font-weight: 500;
470
- transition: all var(--lumir-transition);
471
- gap: 2px;
472
- white-space: nowrap;
473
- overflow: hidden;
474
- }
475
-
476
- .lumir-dropdown-btn span {
477
- overflow: hidden;
478
- text-overflow: ellipsis;
479
- }
480
-
481
- .lumir-dropdown-btn:hover {
482
- background-color: var(--lumir-hover-light);
483
- }
484
-
485
- .lumir-dropdown-btn svg {
486
- width: 14px;
487
- height: 14px;
488
- flex-shrink: 0;
489
- color: var(--lumir-text-muted-light);
490
- }
491
-
492
- /* Dropdown Menu - 항상 밝은 배경 유지 */
493
- .lumir-dropdown-menu {
494
- position: absolute;
495
- top: calc(100% + 4px);
496
- left: 0;
497
- min-width: 160px;
498
- background-color: #ffffff !important;
499
- border: 1px solid #e5e7eb !important;
500
- border-radius: 10px;
501
- box-shadow:
502
- 0 4px 16px rgba(0, 0, 0, 0.12),
503
- 0 0 0 1px rgba(0, 0, 0, 0.04);
504
- z-index: 9999;
505
- padding: 6px;
506
- animation: lumir-dropdown-appear 0.15s ease;
507
- }
508
-
509
- @keyframes lumir-dropdown-appear {
510
- from {
511
- opacity: 0;
512
- transform: translateY(-4px);
513
- }
514
- to {
515
- opacity: 1;
516
- transform: translateY(0);
517
- }
518
- }
519
-
520
- /* Dropdown Item - 항상 밝은 스타일 */
521
- .lumir-dropdown-item {
522
- display: flex;
523
- align-items: center;
524
- width: 100%;
525
- padding: 8px 12px;
526
- text-align: left;
527
- border: none;
528
- background: transparent;
529
- color: #374151 !important;
530
- cursor: pointer;
531
- border-radius: 6px;
532
- font-size: 14px;
533
- transition: background-color 0.1s ease;
534
- }
535
-
536
- .lumir-dropdown-item:hover {
537
- background-color: #f3f4f6 !important;
538
- }
539
-
540
- .lumir-dropdown-item.is-active {
541
- background-color: rgba(59, 130, 246, 0.1) !important;
542
- color: #3b82f6 !important;
543
- }
544
-
545
- /* Font Size Dropdown Button (글자 크기) */
546
- .lumir-font-size-btn {
547
- min-width: 52px;
548
- max-width: 72px;
549
- }
550
-
551
- .lumir-font-size-label {
552
- flex: 1;
553
- text-align: center;
554
- }
555
-
556
- .lumir-font-size-menu {
557
- min-width: 96px;
558
- max-height: 280px;
559
- overflow-y: auto;
560
- }
561
-
562
- /* blur 상태에서도 텍스트 선택 하이라이트 유지 (InactiveSelectionExtension).
563
- 툴바 드롭다운(글자 크기 등) 조작 시 에디터가 blur돼 네이티브 선택이 사라지는 문제 보완. */
564
- .bn-inactive-selection {
565
- background-color: var(--lumir-inactive-selection, rgba(35, 131, 226, 0.28));
566
- }
567
-
568
- /* Font Size 1px Stepper (글자 크기 −/+ + 직접 입력) — 두 드롭다운(FormattingToolbar/FloatingMenu) 공용 */
569
- .lumir-fs-stepper {
570
- display: flex;
571
- align-items: center;
572
- justify-content: center;
573
- gap: 4px;
574
- padding: 6px 8px;
575
- border-bottom: 1px solid #e5e7eb;
576
- }
577
-
578
- .lumir-fs-stepper-btn {
579
- width: 24px;
580
- height: 24px;
581
- display: flex;
582
- align-items: center;
583
- justify-content: center;
584
- border: 1px solid #d1d5db;
585
- border-radius: 4px;
586
- background: #fff;
587
- color: #374151;
588
- cursor: pointer;
589
- font-size: 14px;
590
- line-height: 1;
591
- flex-shrink: 0;
592
- }
593
-
594
- .lumir-fs-stepper-btn:hover:not(:disabled) {
595
- background: #f3f4f6;
596
- }
597
-
598
- .lumir-fs-stepper-btn:disabled {
599
- opacity: 0.4;
600
- cursor: default;
601
- }
602
-
603
- .lumir-fs-stepper-input {
604
- width: 40px;
605
- text-align: center;
606
- border: 1px solid #d1d5db;
607
- border-radius: 4px;
608
- padding: 3px 2px;
609
- font-size: 13px;
610
- color: #111827;
611
- background: #fff;
612
- -moz-appearance: textfield;
613
- appearance: textfield;
614
- }
615
-
616
- .lumir-fs-stepper-input:focus {
617
- outline: none;
618
- border-color: #3b82f6;
619
- }
620
-
621
- .lumir-fs-stepper-input::-webkit-outer-spin-button,
622
- .lumir-fs-stepper-input::-webkit-inner-spin-button {
623
- -webkit-appearance: none;
624
- margin: 0;
625
- }
626
-
627
- /* Block Type Dropdown Button */
628
- .lumir-block-type-btn {
629
- min-width: 110px;
630
- max-width: 130px;
631
- gap: 4px;
632
- padding: 4px 8px;
633
- }
634
-
635
- .lumir-block-icon {
636
- display: flex;
637
- align-items: center;
638
- justify-content: center;
639
- width: 22px;
640
- height: 22px;
641
- flex-shrink: 0;
642
- color: #6b7280;
643
- }
644
-
645
- .lumir-block-icon svg {
646
- width: 18px;
647
- height: 18px;
648
- }
649
-
650
- .lumir-block-icon-text {
651
- font-size: 13px;
652
- font-weight: 700;
653
- color: #6b7280;
654
- line-height: 1;
655
- }
656
-
657
- .lumir-block-label {
658
- flex: 1;
659
- text-align: left;
660
- overflow: hidden;
661
- text-overflow: ellipsis;
662
- white-space: nowrap;
663
- font-size: 13px;
664
- }
665
-
666
- /* Block Type Dropdown Menu - 최대 컴팩트 */
667
- .lumir-block-menu {
668
- min-width: 160px;
669
- max-height: 320px;
670
- overflow-y: auto;
671
- padding: 3px;
672
- }
673
-
674
- /* 커스텀 스크롤바 - 더 얇게 */
675
- .lumir-block-menu::-webkit-scrollbar {
676
- width: 4px;
677
- }
678
-
679
- .lumir-block-menu::-webkit-scrollbar-track {
680
- background: transparent;
681
- }
682
-
683
- .lumir-block-menu::-webkit-scrollbar-thumb {
684
- background-color: #d1d5db;
685
- border-radius: 2px;
686
- }
687
-
688
- .lumir-block-menu::-webkit-scrollbar-thumb:hover {
689
- background-color: #9ca3af;
690
- }
691
-
692
- /* Block Type Menu Item - 최대 컴팩트 */
693
- .lumir-block-item {
694
- display: flex;
695
- align-items: center;
696
- gap: 6px;
697
- padding: 4px 8px;
698
- border-radius: 4px;
699
- margin-bottom: 0;
700
- transition: all 0.1s ease;
701
- }
702
-
703
- .lumir-block-item:last-child {
704
- margin-bottom: 0;
705
- }
706
-
707
- .lumir-block-item .lumir-block-icon {
708
- width: 20px;
709
- height: 20px;
710
- background-color: #f3f4f6;
711
- border-radius: 3px;
712
- display: flex;
713
- align-items: center;
714
- justify-content: center;
715
- flex-shrink: 0;
716
- }
717
-
718
- .lumir-block-item .lumir-block-icon svg {
719
- width: 14px;
720
- height: 14px;
721
- }
722
-
723
- .lumir-block-item .lumir-block-icon-text {
724
- font-size: 10px;
725
- font-weight: 700;
726
- }
727
-
728
- .lumir-block-item-title {
729
- font-size: 12px;
730
- font-weight: 500;
731
- color: #374151;
732
- }
733
-
734
- .lumir-block-item:hover {
735
- background-color: #f3f4f6 !important;
736
- }
737
-
738
- .lumir-block-item:hover .lumir-block-icon {
739
- background-color: #e5e7eb;
740
- color: #374151;
741
- }
742
-
743
- .lumir-block-item:hover .lumir-block-icon-text {
744
- color: #374151;
745
- }
746
-
747
- .lumir-block-item.is-active {
748
- background-color: rgba(59, 130, 246, 0.08) !important;
749
- }
750
-
751
- .lumir-block-item.is-active .lumir-block-icon {
752
- background-color: rgba(59, 130, 246, 0.15);
753
- color: #3b82f6;
754
- }
755
-
756
- .lumir-block-item.is-active .lumir-block-icon-text {
757
- color: #3b82f6;
758
- }
759
-
760
- /* Block Type Category - 최대 컴팩트 */
761
- .lumir-block-category {
762
- margin-bottom: 2px;
763
- }
764
-
765
- .lumir-block-category:last-child {
766
- margin-bottom: 0;
767
- }
768
-
769
- .lumir-block-category-title {
770
- font-size: 9px;
771
- font-weight: 600;
772
- color: #9ca3af;
773
- text-transform: uppercase;
774
- letter-spacing: 0.05em;
775
- padding: 4px 8px 2px;
776
- margin-bottom: 0;
777
- }
778
-
779
- /* Block Item Title */
780
- .lumir-block-item:hover .lumir-block-item-title {
781
- color: #1f2937;
782
- }
783
-
784
- .lumir-block-item.is-active .lumir-block-item-title {
785
- color: #3b82f6;
786
- font-weight: 600;
787
- }
788
-
789
- /* Toggle Heading 아이콘 - 컴팩트 */
790
- .lumir-block-icon-toggle {
791
- display: flex;
792
- align-items: center;
793
- gap: 2px;
794
- font-size: 9px;
795
- font-weight: 700;
796
- color: #6b7280;
797
- line-height: 1;
798
- }
799
-
800
- .lumir-block-icon-toggle svg {
801
- width: 6px;
802
- height: 6px;
803
- flex-shrink: 0;
804
- }
805
-
806
- .lumir-block-icon-toggle span {
807
- font-size: 9px;
808
- font-weight: 700;
809
- }
810
-
811
- .lumir-block-item .lumir-block-icon-toggle {
812
- font-size: 10px;
813
- }
814
-
815
- .lumir-block-item .lumir-block-icon-toggle svg {
816
- width: 7px;
817
- height: 7px;
818
- }
819
-
820
- .lumir-block-item .lumir-block-icon-toggle span {
821
- font-size: 10px;
822
- }
823
-
824
- .lumir-block-item:hover .lumir-block-icon-toggle,
825
- .lumir-block-item.is-active .lumir-block-icon-toggle {
826
- color: inherit;
827
- }
828
-
829
- /* Color Picker Menu */
830
- .lumir-color-menu {
831
- min-width: 180px;
832
- padding: 8px;
833
- }
834
-
835
- .lumir-color-grid {
836
- display: grid;
837
- grid-template-columns: repeat(5, 1fr);
838
- gap: 6px;
839
- }
840
-
841
- .lumir-color-swatch {
842
- width: 28px;
843
- height: 28px;
844
- border: 1px solid rgba(0, 0, 0, 0.15);
845
- border-radius: 4px;
846
- cursor: pointer;
847
- transition: all 0.15s ease;
848
- position: relative;
849
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
850
- }
851
-
852
- .lumir-color-swatch:hover {
853
- transform: scale(1.15);
854
- border-color: #3b82f6;
855
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
856
- z-index: 1;
857
- }
858
-
859
- .lumir-color-swatch.is-active {
860
- border-color: #3b82f6;
861
- border-width: 2px;
862
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
863
- }
864
-
865
- .lumir-color-swatch.is-active::after {
866
- content: '✓';
867
- position: absolute;
868
- top: 50%;
869
- left: 50%;
870
- transform: translate(-50%, -50%);
871
- color: #ffffff;
872
- font-size: 12px;
873
- font-weight: bold;
874
- text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
875
- }
876
-
877
- .lumir-color-remove {
878
- width: 100%;
879
- padding: 6px 8px;
880
- border: none;
881
- background-color: #f3f4f6;
882
- color: #6b7280;
883
- font-size: 11px;
884
- font-weight: 500;
885
- border-radius: 4px;
886
- cursor: pointer;
887
- transition: all 0.15s ease;
888
- }
889
-
890
- .lumir-color-remove:hover {
891
- background-color: #e5e7eb;
892
- color: #374151;
893
- }
894
-
895
- /* Text Controls Group */
896
- .lumir-text-controls {
897
- gap: 8px;
898
- }
899
-
900
- /* Link Input Menu - Compact */
901
- .lumir-link-menu {
902
- min-width: 240px;
903
- padding: 8px;
904
- left: auto;
905
- right: 0;
906
- }
907
-
908
- .lumir-link-form {
909
- display: flex;
910
- flex-direction: column;
911
- gap: 6px;
912
- }
913
-
914
- .lumir-link-input {
915
- width: 100%;
916
- padding: 6px 8px;
917
- border: 1px solid #d1d5db;
918
- border-radius: 4px;
919
- font-size: 12px;
920
- font-family: inherit;
921
- outline: none;
922
- transition: all 0.15s ease;
923
- }
924
-
925
- .lumir-link-input:focus {
926
- border-color: #3b82f6;
927
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
928
- }
929
-
930
- .lumir-link-input::placeholder {
931
- color: #9ca3af;
932
- font-size: 11px;
933
- }
934
-
935
- .lumir-link-actions {
936
- display: flex;
937
- gap: 4px;
938
- justify-content: flex-end;
939
- }
940
-
941
- .lumir-link-btn {
942
- padding: 4px 10px;
943
- border: none;
944
- border-radius: 4px;
945
- font-size: 11px;
946
- font-weight: 500;
947
- cursor: pointer;
948
- transition: all 0.15s ease;
949
- }
950
-
951
- .lumir-link-cancel {
952
- background-color: #f3f4f6;
953
- color: #6b7280;
954
- }
955
-
956
- .lumir-link-cancel:hover {
957
- background-color: #e5e7eb;
958
- color: #374151;
959
- }
960
-
961
- .lumir-link-submit {
962
- background-color: #3b82f6;
963
- color: #ffffff;
964
- }
965
-
966
- .lumir-link-submit:hover:not(:disabled) {
967
- background-color: #2563eb;
968
- }
969
-
970
- .lumir-link-submit:disabled {
971
- opacity: 0.5;
972
- cursor: not-allowed;
973
- }
974
-
975
- /*
976
- * 플로팅 툴바는 다크모드와 관계없이 항상 밝은 스타일 유지
977
- * 다크모드 오버라이드를 적용하지 않음
978
- */
979
-
980
- /* ========================================
981
- 에러 토스트 스타일
982
- ======================================== */
983
-
984
- .lumirEditor-error-toast {
985
- position: absolute;
986
- bottom: 16px;
987
- left: 50%;
988
- transform: translateX(-50%);
989
- display: flex;
990
- align-items: center;
991
- gap: 8px;
992
- padding: 12px 16px;
993
- background-color: #fef2f2;
994
- border: 1px solid #fecaca;
995
- border-radius: 8px;
996
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
997
- z-index: 1001;
998
- animation: lumirEditor-toast-appear 0.3s ease;
999
- max-width: 90%;
1000
- }
1001
-
1002
- @keyframes lumirEditor-toast-appear {
1003
- from {
1004
- opacity: 0;
1005
- transform: translateX(-50%) translateY(10px);
1006
- }
1007
- to {
1008
- opacity: 1;
1009
- transform: translateX(-50%) translateY(0);
1010
- }
1011
- }
1012
-
1013
- .lumirEditor-error-icon {
1014
- flex-shrink: 0;
1015
- font-size: 16px;
1016
- }
1017
-
1018
- .lumirEditor-error-message {
1019
- font-size: 13px;
1020
- font-weight: 500;
1021
- color: #991b1b;
1022
- line-height: 1.4;
1023
- }
1024
-
1025
- .lumirEditor-error-close {
1026
- flex-shrink: 0;
1027
- display: flex;
1028
- align-items: center;
1029
- justify-content: center;
1030
- width: 20px;
1031
- height: 20px;
1032
- padding: 0;
1033
- border: none;
1034
- background: transparent;
1035
- color: #991b1b;
1036
- font-size: 14px;
1037
- cursor: pointer;
1038
- border-radius: 4px;
1039
- transition: background-color 0.15s ease;
1040
- }
1041
-
1042
- .lumirEditor-error-close:hover {
1043
- background-color: #fee2e2;
1044
- }
1045
-
1046
- /* ========================================
1047
- Link Preview 카드 스타일
1048
- ======================================== */
1049
-
1050
- @keyframes lumir-skeleton-pulse {
1051
- 0% {
1052
- opacity: 1;
1053
- }
1054
- 50% {
1055
- opacity: 0.4;
1056
- }
1057
- 100% {
1058
- opacity: 1;
1059
- }
1060
- }
1061
-
1062
- .lumir-link-preview-card:hover .lumir-link-preview-delete {
1063
- opacity: 1 !important;
1064
- }
1065
-
1066
- .lumir-link-preview-delete:hover {
1067
- background-color: rgba(0, 0, 0, 0.7) !important;
1068
- }
1069
-
1070
- .lumir-resize-handle {
1071
- position: absolute;
1072
- width: 8px;
1073
- height: 30px;
1074
- background-color: black;
1075
- border: 1px solid white;
1076
- border-radius: 4px;
1077
- cursor: ew-resize;
1078
- top: 50%;
1079
- transform: translateY(-50%);
1080
- z-index: 3;
1081
- }
1082
-
1083
- .lumir-resize-handle-bottom {
1084
- position: absolute;
1085
- bottom: 4px;
1086
- left: 50%;
1087
- transform: translateX(-50%);
1088
- width: 30px;
1089
- height: 8px;
1090
- background-color: black;
1091
- border: 1px solid white;
1092
- border-radius: 4px;
1093
- cursor: ns-resize;
1094
- z-index: 3;
1095
- }
1096
-
1097
- .lumir-link-preview-card:hover {
1098
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
1099
- }
1100
-
1101
- .node-linkPreview.ProseMirror-selectednode .bn-block-content {
1102
- outline: 2px solid #3b82f6;
1103
- outline-offset: 2px;
1104
- border-radius: 8px;
1105
- }
1106
-
1107
- .node-linkPreview .bn-block-content {
1108
- outline: none !important;
1109
- }
1110
-
1111
- /* 다크 테마 대응 */
1112
- [data-color-scheme='dark'] .lumir-link-preview-card,
1113
- .bn-container[data-color-scheme='dark'] .lumir-link-preview-card {
1114
- background-color: #292524 !important;
1115
- border-color: #44403c !important;
1116
- }
1117
-
1118
- [data-color-scheme='dark'] .lumir-link-preview-card:hover,
1119
- .bn-container[data-color-scheme='dark'] .lumir-link-preview-card:hover {
1120
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
1121
- }
1122
-
1123
- [data-color-scheme='dark'] .lumir-link-preview-skeleton,
1124
- .bn-container[data-color-scheme='dark'] .lumir-link-preview-skeleton {
1125
- background-color: #292524 !important;
1126
- border-color: #44403c !important;
1127
- }
1128
-
1129
- [data-color-scheme='dark'] .lumir-link-preview-error,
1130
- .bn-container[data-color-scheme='dark'] .lumir-link-preview-error {
1131
- background-color: #292524 !important;
1132
- border-color: #44403c !important;
1133
- }
1134
-
1135
- /* 인용·코드·테이블 본문 14px */
1136
- .lumirEditor .bn-block-content[data-content-type='quote'] p.bn-inline-content,
1137
- .lumirEditor [data-content-type='quote'] blockquote {
1138
- font-size: 14px;
1139
- }
1140
-
1141
- .lumirEditor .bn-block-content[data-content-type='codeBlock'] pre,
1142
- .lumirEditor .bn-block-content[data-content-type='codeBlock'] pre code {
1143
- font-size: 14px;
1144
- }
1145
-
1146
- .lumirEditor .bn-editor [data-content-type='table'] th,
1147
- .lumirEditor .bn-editor [data-content-type='table'] td,
1148
- .lumirEditor .bn-editor [data-content-type='table'] p.bn-inline-content {
1149
- font-size: 14px;
1150
- }
1151
-
1152
- /* 테이블 셀 세로 정렬 (VerticalAlignmentExtension) */
1153
- .lumirEditor
1154
- .bn-editor
1155
- [data-content-type='table']
1156
- td[data-vertical-alignment='middle'],
1157
- .lumirEditor
1158
- .bn-editor
1159
- [data-content-type='table']
1160
- th[data-vertical-alignment='middle'] {
1161
- vertical-align: middle;
1162
- }
1163
-
1164
- .lumirEditor
1165
- .bn-editor
1166
- [data-content-type='table']
1167
- td[data-vertical-alignment='bottom'],
1168
- .lumirEditor
1169
- .bn-editor
1170
- [data-content-type='table']
1171
- th[data-vertical-alignment='bottom'] {
1172
- vertical-align: bottom;
1173
- }
1174
-
1175
- /* ==========================================================================
1176
- Notion 스타일 FOCUS 기반 테이블 gutter/grip (LumirTableHandlesController)
1177
- - 셀 focus 시: 셀 테두리 하이라이트(파란 보더, 셀을 살짝 감쌈)
1178
- - 상단(열)·좌측(행): 짧고 두꺼운 회색 gutter 바 / 우측(셀): 작은 파란 앵커
1179
- - gutter hover 시: 발판 grip 노출 → 클릭 시 드롭다운
1180
- - active(메뉴 열림/드래그): 발판이 파란 배경 + 흰 점
1181
- 기본 BlockNote hover 핸들은 tableHandles={false}로 비활성.
1182
- ========================================================================== */
1183
-
1184
- /* focus된 셀 테두리 하이라이트 (셀을 ~2px 바깥에서 감싸는 비클릭 오버레이) */
1185
- .lumirEditor .lumir-tbl-cell-focus {
1186
- position: absolute;
1187
- top: 0;
1188
- left: 0;
1189
- box-sizing: border-box;
1190
- border: 2px solid #2383e2;
1191
- border-radius: 2px;
1192
- pointer-events: none;
1193
- z-index: 1;
1194
- }
1195
-
1196
- /* gutter wrapper = hover 히트 영역. 보더에 걸쳐 중앙 배치(positioner offset -7). */
1197
- .lumirEditor .lumir-tbl-gutter-wrap {
1198
- position: absolute;
1199
- z-index: 2;
1200
- cursor: pointer;
1201
- }
1202
-
1203
- .lumirEditor .lumir-tbl-gutter-wrap--col {
1204
- width: 34px;
1205
- height: 14px;
1206
- }
1207
-
1208
- .lumirEditor .lumir-tbl-gutter-wrap--row,
1209
- .lumirEditor .lumir-tbl-gutter-wrap--cell {
1210
- width: 14px;
1211
- height: 34px;
1212
- }
1213
-
1214
- /* 기본 노출: 짧고 두꺼운 gutter 바. wrapper가 셀 보더에 중앙 정렬되어 있으므로,
1215
- gutter를 wrapper 중앙에 두면 "거터 중앙이 셀 보더선 위"에 오도록 걸쳐진다
1216
- (절반은 셀 안쪽, 절반은 바깥쪽). */
1217
- .lumirEditor .lumir-tbl-gutter {
1218
- position: absolute;
1219
- inset: 0;
1220
- margin: auto;
1221
- box-sizing: border-box;
1222
- background-color: #c0c0c2;
1223
- transition: opacity 0.1s ease;
1224
- }
1225
-
1226
- /* 상(top): 가로 pill — 상단 보더 중앙 */
1227
- .lumirEditor .lumir-tbl-gutter-wrap--col .lumir-tbl-gutter {
1228
- width: 14px;
1229
- height: 4px;
1230
- border-left: 1px solid #fff;
1231
- border-right: 1px solid #fff;
1232
- }
1233
-
1234
- /* 좌(left): 세로 pill — 좌측 보더 중앙 (Notion도 좌측에 표시) */
1235
- .lumirEditor .lumir-tbl-gutter-wrap--row .lumir-tbl-gutter {
1236
- width: 4px;
1237
- height: 14px;
1238
- border-top: 1px solid #fff;
1239
- border-bottom: 1px solid #fff;
1240
- }
1241
-
1242
- /* 우(right): Notion의 파란 선택 앵커 — 우측 보더 중앙 */
1243
- /* 우(right): 셀 우측 보더의 파란 세로 앵커 */
1244
- .lumirEditor .lumir-tbl-gutter-wrap--cell .lumir-tbl-gutter {
1245
- width: 4px;
1246
- height: 14px;
1247
- background-color: #2383e2;
1248
- border-top: 1px solid #fff;
1249
- border-bottom: 1px solid #fff;
1250
- }
1251
-
1252
- .lumirEditor .lumir-tbl-gutter-wrap:hover .lumir-tbl-gutter {
1253
- opacity: 0;
1254
- }
1255
-
1256
- /* 발판 grip: 기본 숨김, gutter hover 시 노출 */
1257
- .lumirEditor .lumir-tbl-grip {
1258
- position: absolute;
1259
- inset: 0;
1260
- display: flex;
1261
- align-items: center;
1262
- justify-content: center;
1263
- opacity: 0;
1264
- pointer-events: none;
1265
- cursor: pointer;
1266
- transition: opacity 0.1s ease;
1267
- }
1268
-
1269
- .lumirEditor .lumir-tbl-gutter-wrap:hover .lumir-tbl-grip {
1270
- opacity: 1;
1271
- pointer-events: auto;
1272
- }
1273
-
1274
- /* 메뉴 열림(active) 동안 발판 유지(마우스가 떠나도) + rest 바 숨김 */
1275
- .lumirEditor .lumir-tbl-gutter-wrap--active .lumir-tbl-grip {
1276
- opacity: 1;
1277
- pointer-events: auto;
1278
- }
1279
-
1280
- .lumirEditor .lumir-tbl-gutter-wrap--active .lumir-tbl-gutter {
1281
- opacity: 0;
1282
- }
1283
-
1284
- /* 드롭다운 오픈(active)·드래그 시 발판: 배경·보더 파랑(#2383e2) + 흰 아이콘 */
1285
- .lumirEditor .lumir-tbl-gutter-wrap--active .bn-table-handle,
1286
- .lumirEditor .lumir-tbl-gutter-wrap--active .bn-table-cell-handle,
1287
- .lumirEditor .lumir-tbl-grip .bn-table-handle-dragging {
1288
- background-color: #2383e2 !important;
1289
- border-color: #2383e2 !important;
1290
- color: #fff !important;
1291
- }
1292
-
1293
- /* 발판 크기: 너비(11)↓·높이(14) 유지. 상단 발판은 90° 회전이라 너비↓ = 시각적 높이↓.
1294
- 배경 흰색 + 보더 진하게(#999). */
1295
- .lumirEditor .lumir-tbl-grip .bn-table-handle,
1296
- .lumirEditor .lumir-tbl-grip .bn-table-cell-handle {
1297
- width: 12px;
1298
- min-width: 12px;
1299
- height: 16px;
1300
- padding: 0;
1301
- border-radius: 3px;
1302
- cursor: pointer; /* mantine 기본 grab → pointer */
1303
- background-color: #fff;
1304
- border: 1px solid #cfcfcf;
1305
- box-shadow: none; /* mantine 기본 그림자(--bn-shadow-light, 블러처럼 보임) 제거 */
1306
- }
1307
-
1308
- /* hover 시에도 흰 배경 유지 (mantine hover 회색 오버라이드) */
1309
- .lumirEditor .lumir-tbl-grip .bn-table-handle:hover,
1310
- .lumirEditor .lumir-tbl-grip .bn-table-cell-handle:hover {
1311
- background-color: #fff;
1312
- }
1313
-
1314
- .lumirEditor .lumir-tbl-grip .bn-table-handle svg {
1315
- width: 12px;
1316
- height: 12px;
1317
- margin-inline: 0;
1318
- }
1319
-
1320
- .lumirEditor .lumir-tbl-grip .bn-table-cell-handle svg {
1321
- width: 12px;
1322
- height: 12px;
1323
- }
1324
-
1325
- /* =========================================================
1326
- 표 행 높이(row height) 드래그 리사이즈 — rowResizing 플러그인
1327
- prosemirror-tables의 column-resize 스타일을 수직축으로 미러링.
1328
- ========================================================= */
1329
-
1330
- /* activeHandle 동안 에디터 전체 커서를 행 리사이즈로 */
1331
- .lumirEditor .ProseMirror.row-resize-cursor {
1332
- cursor: ns-resize;
1333
- cursor: row-resize;
1334
- }
1335
-
1336
- /* 핸들 위젯의 절대배치 기준(셀). prosemirror-tables 기본값 보강. */
1337
- .lumirEditor .ProseMirror td,
1338
- .lumirEditor .ProseMirror th {
1339
- position: relative;
1340
- }
1341
-
1342
- /* 셀 하단 경계 핸들(셀별 1개가 모여 행 폭 전체를 덮음). */
1343
- .lumirEditor .ProseMirror .row-resize-handle {
1344
- position: absolute;
1345
- left: 0;
1346
- right: 0;
1347
- bottom: -2px;
1348
- height: 4px;
1349
- z-index: 20;
1350
- background-color: #adf;
1351
- pointer-events: none;
1352
- }
1353
-
1354
- /* 드래그 중 셀: 레이아웃 트랜지션 제거로 프리뷰 떨림 방지. */
1355
- .lumirEditor .ProseMirror .row-resize-dragging {
1356
- transition: none;
1357
- }
1358
-
1359
- /* 표 전체 스케일: 우하단 모서리 hit-zone(투명). 오버레이라 에디터 위에 떠서 코너의
1360
- hover/클릭을 가로채므로 행/열 리사이즈(하단·우측 경계)와 충돌하지 않는다.
1361
- 보이는 핸들 없이 hover 시 대각 리사이즈 커서만 노출 + 드래그로 크기 조절. */
1362
- .lumirEditor .lumir-tbl-scale-handle {
1363
- width: 18px;
1364
- height: 18px;
1365
- background: transparent;
1366
- cursor: nwse-resize;
1367
- z-index: 30;
1368
- pointer-events: auto;
1369
- touch-action: none;
1370
- }
1371
- /* 드래그 중 셀: 트랜지션 제거로 프리뷰 떨림 방지. */
1372
- .lumirEditor .ProseMirror .lumir-table-scale-dragging {
1373
- transition: none;
1374
- }
1375
-
1376
- /* =========================================================
1377
- 표 블록 정렬(좌/가운데/우) — TableAlignmentExtension
1378
- <table>이 width:auto(content 폭)이므로 margin으로 수평 정렬.
1379
- 좌측(기본)은 별도 규칙 불필요.
1380
- ========================================================= */
1381
- .lumirEditor
1382
- .bn-editor
1383
- [data-content-type='table'][data-table-alignment='center']
1384
- table {
1385
- margin-left: auto;
1386
- margin-right: auto;
1387
- }
1388
-
1389
- .lumirEditor
1390
- .bn-editor
1391
- [data-content-type='table'][data-table-alignment='right']
1392
- table {
1393
- margin-left: auto;
1394
- margin-right: 0;
1395
- }
1396
-
1397
- /* =========================================================
1398
- 표 하단 여백 축소
1399
- @blocknote 기본 .tableWrapper는 `position:relative; top:-16px`라서, 화면상 16px
1400
- 위로 그리되 레이아웃 공간은 원위치에 예약 → 래퍼 박스 아래에 사용되지 않는 16px가
1401
- 남는다(순수 artifact). 음수 margin-bottom으로 이 예약 공백만 정확히 상쇄한다.
1402
- 래퍼의 padding/overflow는 건드리지 않으므로 행/열 추가 버튼·리사이즈 핸들·거터의
1403
- 클리어런스(클립 경계)는 그대로 유지된다 → 사이드이펙트 없음.
1404
- ========================================================= */
1405
- .lumirEditor .bn-editor [data-content-type='table'] .tableWrapper {
1406
- margin-bottom: -16px;
1407
- }
1408
-
1409
- /* =========================================================
1410
- 다단(컬럼) 레이아웃 — columnList / column 노드
1411
- columnList: 가로 flex 컨테이너, column: 균등 폭 flex 아이템.
1412
- ========================================================= */
1413
- .lumirEditor .bn-column-list {
1414
- display: flex;
1415
- gap: 16px;
1416
- width: 100%;
1417
- }
1418
-
1419
- .lumirEditor .bn-column {
1420
- flex: 1 1 0;
1421
- min-width: 0; /* 컬럼 내 넓은 콘텐츠(표 등) 오버플로 방지 */
1422
- }
1423
-
1424
- /* 컬럼 중앙 세로 구분선. 두 가지 방식으로 켜진다(둘 중 하나라도 켜지면 표시):
1425
- 1) 전역: columnDivider prop → 루트 `.lumir-column-divider` (모든 컬럼).
1426
- 2) 블록별: columnList의 `showDivider` attr → `data-divider="true"` (드래그핸들 메뉴 토글).
1427
- divider가 드래그 핸들(grip)에 가려지지 않도록 gap을 넓혀(기본 16px → grip-space×2)
1428
- divider를 정중앙에 두고 양쪽에 grip 너비만큼 여백을 둔다. 마지막 컬럼 제외 → N컬럼이면
1429
- N-1개. flex 기본 align-items:stretch로 컬럼 높이가 같아 구분선이 전체 높이를 채운다.
1430
- grip-space/색은 CSS 변수로 조정 가능. */
1431
- .lumirEditor.lumir-column-divider .bn-column-list,
1432
- .lumirEditor .bn-column-list[data-divider="true"] {
1433
- --lumir-column-grip-space: 28px; /* divider ~ 콘텐츠 여백(≈grip 너비 + 여유) */
1434
- gap: calc(var(--lumir-column-grip-space) * 2);
1435
- }
1436
- .lumirEditor.lumir-column-divider .bn-column,
1437
- .lumirEditor .bn-column-list[data-divider="true"] .bn-column {
1438
- position: relative;
1439
- }
1440
- .lumirEditor.lumir-column-divider .bn-column:not(:last-child)::after,
1441
- .lumirEditor .bn-column-list[data-divider="true"] .bn-column:not(:last-child)::after {
1442
- content: "";
1443
- position: absolute;
1444
- top: 0;
1445
- bottom: 0;
1446
- right: calc(var(--lumir-column-grip-space) * -1); /* gap 정중앙 */
1447
- width: 1px;
1448
- background: var(--lumir-column-divider-color, #e5e7eb);
1449
- pointer-events: none;
1450
- }
1451
-
1452
- /* DnD 컬럼 생성: 드롭 대상 블록의 좌/우 가장자리 세로 인디케이터(레이아웃 비이동 box-shadow) */
1453
- .lumirEditor .lumir-col-drop-left {
1454
- box-shadow: -3px 0 0 0 #3b82f6;
1455
- }
1456
- .lumirEditor .lumir-col-drop-right {
1457
- box-shadow: 3px 0 0 0 #3b82f6;
1458
- }
1459
- /* 가장자리 드롭 중에는 기본(가로) 드롭커서를 숨겨 인디케이터 중복 방지 */
1460
- .lumirEditor .lumir-col-dnd-active .prosemirror-dropcursor,
1461
- .lumirEditor .lumir-col-dnd-active .ProseMirror-dropcursor {
1462
- display: none !important;
1463
- }
1
+ @import '@blocknote/core/fonts/inter.css';
2
+ @import '@blocknote/mantine/style.css';
3
+ @import '@blocknote/react/style.css';
4
+
5
+ /* Pretendard 한글 글꼴 (가변 폰트, swap).
6
+ @import url()은 번들 시 @import 순서 규칙을 위반해 사용 불가 → @font-face로 로드.
7
+ 호스트 앱이 Pretendard를 자체 로드한다면 이 블록은 제거해도 된다. */
8
+ @font-face {
9
+ font-family: 'Pretendard';
10
+ font-weight: 100 900;
11
+ font-style: normal;
12
+ font-display: swap;
13
+ src: url('https://cdn.jsdelivr.net/npm/pretendard@1.3.9/dist/web/variable/woff2/PretendardVariable.woff2')
14
+ format('woff2-variations');
15
+ }
16
+
17
+ .lumirEditor {
18
+ width: 100%;
19
+ height: 100%;
20
+ min-width: 200px;
21
+ overflow: visible; /* 슬래시 메뉴가 컨테이너를 넘어서 표시되도록 변경 */
22
+ background-color: #ffffff;
23
+ /* 에디터 전체(본문·툴바·인-DOM 드롭다운) 한글 글꼴 Pretendard */
24
+ font-family:
25
+ 'Pretendard',
26
+ 'Noto Sans KR',
27
+ -apple-system,
28
+ BlinkMacSystemFont,
29
+ 'Segoe UI',
30
+ 'Roboto',
31
+ sans-serif;
32
+ }
33
+
34
+ /* 에디터 내부 콘텐츠 영역만 스크롤 가능하게 설정 */
35
+ .lumirEditor .bn-container {
36
+ overflow: auto;
37
+ max-height: 100%;
38
+ }
39
+
40
+ /* 슬래시 메뉴(SuggestionMenu)가 컨테이너를 넘어서 표시되도록 */
41
+ .bn-suggestion-menu,
42
+ .bn-slash-menu,
43
+ .mantine-Menu-dropdown,
44
+ .mantine-Popover-dropdown {
45
+ z-index: 9999 !important;
46
+ }
47
+
48
+ /* 포털(body)로 빠지는 메뉴/드롭다운에도 Pretendard 적용 */
49
+ .bn-suggestion-menu,
50
+ .bn-slash-menu,
51
+ .mantine-Menu-dropdown,
52
+ .mantine-Popover-dropdown,
53
+ .bn-table-handle-menu,
54
+ .bn-menu-dropdown {
55
+ font-family:
56
+ 'Pretendard',
57
+ 'Noto Sans KR',
58
+ -apple-system,
59
+ BlinkMacSystemFont,
60
+ 'Segoe UI',
61
+ 'Roboto',
62
+ sans-serif;
63
+ }
64
+ /* 포커스 상태 스타일 - 테두리 없음 */
65
+ .lumirEditor:focus-within {
66
+ outline: none;
67
+ box-shadow: none;
68
+ }
69
+ .lumirEditor {
70
+ border: none;
71
+ }
72
+
73
+ /* BlockNote 에디터 내부 폰트 설정 */
74
+ .lumirEditor .bn-editor,
75
+ .lumirEditor .bn-inline-content {
76
+ font-family:
77
+ 'Pretendard',
78
+ 'Noto Sans KR',
79
+ -apple-system,
80
+ BlinkMacSystemFont,
81
+ 'Segoe UI',
82
+ 'Roboto',
83
+ 'Oxygen',
84
+ 'Ubuntu',
85
+ 'Cantarell',
86
+ sans-serif;
87
+ }
88
+
89
+ /* 링크 스타일 - Tailwind Preflight 리셋 복원 */
90
+ .lumirEditor .bn-editor a,
91
+ .lumirEditor .bn-inline-content a {
92
+ color: #0b6e99;
93
+ text-decoration: underline;
94
+ text-underline-offset: 2px;
95
+ cursor: pointer;
96
+ }
97
+
98
+ .lumirEditor .bn-editor a:hover,
99
+ .lumirEditor .bn-inline-content a:hover {
100
+ color: #0b6e99;
101
+ }
102
+
103
+ /* CSS 변수를 사용한 패딩 설정 */
104
+ .lumirEditor .bn-editor {
105
+ padding-left: 25px;
106
+ padding-right: 10px;
107
+ padding-top: 5px;
108
+ padding-bottom: 0;
109
+ }
110
+
111
+ /*
112
+ * 본문·번호·글머리·체크 목록 인라인 텍스트 14px 통일
113
+ * BlockNote `.bn-default-styles { font-size: 16px }` + `p { font-size: inherit }` 때문에
114
+ * `p.bn-inline-content`에 명시적으로 14px (`.bn-block-content`에 data-type이 붙음)
115
+ */
116
+ .lumirEditor
117
+ .bn-block-content[data-content-type='paragraph']
118
+ p.bn-inline-content,
119
+ .lumirEditor
120
+ .bn-block-content[data-content-type='numberedListItem']
121
+ p.bn-inline-content,
122
+ .lumirEditor
123
+ .bn-block-content[data-content-type='bulletListItem']
124
+ p.bn-inline-content,
125
+ .lumirEditor
126
+ .bn-block-content[data-content-type='checkListItem']
127
+ p.bn-inline-content {
128
+ font-size: 14px;
129
+ }
130
+
131
+ /* 마커(번호·불릿)·체크 행 */
132
+ .lumirEditor .bn-block-content[data-content-type='numberedListItem'],
133
+ .lumirEditor .bn-block-content[data-content-type='bulletListItem'],
134
+ .lumirEditor .bn-block-content[data-content-type='checkListItem'] {
135
+ font-size: 14px;
136
+ }
137
+
138
+ .lumirEditor .bn-block-content {
139
+ max-width: 100%;
140
+ }
141
+
142
+ /* File Panel: Embed 탭 미노출 (URL 입력 방식 비활성화) */
143
+ .lumirEditor [data-test='embed-tab'] {
144
+ display: none !important;
145
+ }
146
+
147
+ /* 정렬된 블록의 인라인 콘텐츠 - 빈 블록에서 스크롤 방지 */
148
+ .lumirEditor .bn-inline-content {
149
+ overflow: hidden;
150
+ max-width: 100%;
151
+ min-width: 0;
152
+ }
153
+
154
+ /* 우측 정렬 시 빈 블록 placeholder 위치 수정 */
155
+ .lumirEditor [data-text-alignment='right'] .bn-inline-content::before {
156
+ position: relative;
157
+ max-width: 100%;
158
+ }
159
+
160
+ /* 이미지 업로드 로딩 스피너 */
161
+ .lumirEditor-upload-overlay {
162
+ position: absolute;
163
+ top: 0;
164
+ left: 0;
165
+ right: 0;
166
+ bottom: 0;
167
+ display: flex;
168
+ flex-direction: column;
169
+ align-items: center;
170
+ justify-content: center;
171
+ gap: 8px;
172
+ background-color: rgba(255, 255, 255, 0.8);
173
+ backdrop-filter: blur(2px);
174
+ z-index: 1000;
175
+ }
176
+
177
+ .lumirEditor-spinner {
178
+ width: 30px;
179
+ height: 30px;
180
+ border: 3px solid #f3f3f3;
181
+ border-top: 3px solid #3b82f6;
182
+ border-radius: 50%;
183
+ animation: lumir-spin 1s linear infinite;
184
+ }
185
+
186
+ .lumirEditor-upload-progress {
187
+ font-size: 14px;
188
+ font-weight: 500;
189
+ color: #374151;
190
+ }
191
+
192
+ @keyframes lumir-spin {
193
+ 0% {
194
+ transform: rotate(0deg);
195
+ }
196
+ 100% {
197
+ transform: rotate(360deg);
198
+ }
199
+ }
200
+
201
+ /* ========================================
202
+ Floating Toolbar 스타일 (컴팩트 + 반응형)
203
+ ======================================== */
204
+
205
+ /* CSS 변수 정의 */
206
+ .lumir-floating-toolbar-wrapper {
207
+ --lumir-bg-light: #fafaf9;
208
+ --lumir-bg-dark: #1c1917;
209
+ --lumir-paper-light: #ffffff;
210
+ --lumir-paper-dark: #292524;
211
+ --lumir-border-light: #e7e5e4;
212
+ --lumir-border-dark: #44403c;
213
+ --lumir-text-light: #1c1917;
214
+ --lumir-text-dark: #fafaf9;
215
+ --lumir-text-muted-light: #78716c;
216
+ --lumir-text-muted-dark: #a8a29e;
217
+ --lumir-hover-light: #f5f5f4;
218
+ --lumir-hover-dark: #44403c;
219
+ --lumir-active-bg: rgba(59, 130, 246, 0.1);
220
+ --lumir-active-color: #3b82f6;
221
+ --lumir-radius-lg: 0.5rem;
222
+ --lumir-radius-md: 0.25rem;
223
+ --lumir-transition: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
224
+ --lumir-btn-size: 28px;
225
+ --lumir-btn-padding: 6px;
226
+ --lumir-icon-size: 16px;
227
+ }
228
+
229
+ /* Toolbar Wrapper */
230
+ .lumir-floating-toolbar-wrapper {
231
+ width: 100%;
232
+ display: flex;
233
+ justify-content: center;
234
+ padding: 8px 12px;
235
+ z-index: 40;
236
+ }
237
+
238
+ /* 최소화 모드일 때는 좌측 상단 배치 */
239
+ .lumir-floating-toolbar-wrapper.is-minimizable {
240
+ justify-content: flex-start;
241
+ padding: 0;
242
+ }
243
+
244
+ .lumir-floating-toolbar-wrapper[data-position='sticky'] {
245
+ position: sticky;
246
+ top: 0;
247
+ }
248
+
249
+ .lumir-floating-toolbar-wrapper[data-position='fixed'] {
250
+ position: fixed;
251
+ top: 64px;
252
+ left: 0;
253
+ right: 0;
254
+ }
255
+
256
+ /* Toolbar Container - 항상 밝은 배경 유지 */
257
+ .lumir-floating-toolbar {
258
+ display: flex;
259
+ flex-wrap: wrap;
260
+ align-items: center;
261
+ gap: 2px;
262
+ padding: 4px;
263
+ background-color: #ffffff !important;
264
+ border: 1px solid #e5e7eb !important;
265
+ border-radius: var(--lumir-radius-lg);
266
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
267
+ max-width: 100%;
268
+ font-family: ui-sans-serif, system-ui, sans-serif;
269
+ font-size: 13px;
270
+ }
271
+
272
+ /* 1단 레이아웃 (넓은 화면) */
273
+ .lumir-floating-toolbar {
274
+ flex-wrap: nowrap;
275
+ }
276
+
277
+ /* 2단 레이아웃 (좁은 화면) */
278
+ .lumir-floating-toolbar.is-compact {
279
+ flex-wrap: wrap;
280
+ justify-content: center;
281
+ }
282
+
283
+ .lumir-floating-toolbar.is-compact .lumir-toolbar-row {
284
+ display: flex;
285
+ align-items: center;
286
+ width: 100%;
287
+ justify-content: center;
288
+ gap: 2px;
289
+ }
290
+
291
+ .lumir-floating-toolbar.is-compact .lumir-toolbar-row:not(:last-child) {
292
+ padding-bottom: 4px;
293
+ border-bottom: 1px solid var(--lumir-border-light);
294
+ margin-bottom: 4px;
295
+ }
296
+
297
+ /* 최소화 가능 레이아웃 (400px 이하) */
298
+ .lumir-floating-toolbar.is-minimizable {
299
+ flex-wrap: wrap; /* 여러 줄로 확장 가능 */
300
+ justify-content: flex-start; /* 좌측 정렬 */
301
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
302
+ padding: 0; /* 내부 공백 제거 */
303
+ }
304
+
305
+ /* 토글 버튼 스타일 */
306
+ .lumir-floating-toolbar.is-minimizable .lumir-toggle-button {
307
+ order: -1; /* 항상 맨 앞에 배치 */
308
+ flex-shrink: 0;
309
+ width: 24px; /* 컴팩트한 크기 */
310
+ height: 24px;
311
+ padding: 0; /* 패딩 제거하여 정확한 정렬 */
312
+ margin: 0;
313
+ border-radius: 4px;
314
+ display: flex;
315
+ align-items: center;
316
+ justify-content: center;
317
+ cursor: pointer;
318
+ transition: transform 0.2s ease;
319
+ }
320
+
321
+ .lumir-floating-toolbar.is-minimizable .lumir-toggle-button:hover {
322
+ transform: scale(1.1);
323
+ }
324
+
325
+ .lumir-floating-toolbar.is-minimizable .lumir-toggle-button svg {
326
+ width: 16px;
327
+ height: 16px;
328
+ display: block; /* inline 여백 제거 */
329
+ transition: transform 0.3s ease;
330
+ }
331
+
332
+ /* 메뉴 항목 애니메이션 */
333
+ .lumir-floating-toolbar.is-minimizable > *:not(.lumir-toggle-button) {
334
+ opacity: 1;
335
+ transform: translateX(0);
336
+ transition:
337
+ opacity 0.3s ease,
338
+ transform 0.3s ease;
339
+ }
340
+
341
+ /* 최소화 상태 - 토글 버튼만 표시 */
342
+ .lumir-floating-toolbar.is-minimizable.is-minimized {
343
+ width: auto;
344
+ min-width: 24px;
345
+ padding: 0;
346
+ border: none;
347
+ background: transparent !important;
348
+ box-shadow: none;
349
+ }
350
+
351
+ .lumir-floating-toolbar.is-minimizable.is-minimized
352
+ > *:not(.lumir-toggle-button) {
353
+ opacity: 0;
354
+ transform: translateX(-10px);
355
+ pointer-events: none;
356
+ max-width: 0;
357
+ overflow: hidden;
358
+ margin: 0;
359
+ padding: 0;
360
+ }
361
+
362
+ /* Toolbar Group */
363
+ .lumir-toolbar-group {
364
+ display: flex;
365
+ align-items: center;
366
+ gap: 1px;
367
+ padding: 0 2px;
368
+ }
369
+
370
+ /* Divider */
371
+ .lumir-toolbar-divider {
372
+ width: 1px;
373
+ height: 18px;
374
+ background-color: var(--lumir-border-light);
375
+ margin: 0 2px;
376
+ flex-shrink: 0;
377
+ }
378
+
379
+ /* 2단에서 divider 숨기기 */
380
+ .lumir-floating-toolbar.is-compact .lumir-toolbar-divider.row-break {
381
+ display: none;
382
+ }
383
+
384
+ /* Toolbar Button (컴팩트) */
385
+ .lumir-toolbar-btn {
386
+ display: flex;
387
+ align-items: center;
388
+ justify-content: center;
389
+ width: var(--lumir-btn-size);
390
+ height: var(--lumir-btn-size);
391
+ padding: var(--lumir-btn-padding);
392
+ border: none;
393
+ background: transparent;
394
+ color: var(--lumir-text-muted-light);
395
+ cursor: pointer;
396
+ border-radius: var(--lumir-radius-md);
397
+ transition: all var(--lumir-transition);
398
+ position: relative;
399
+ flex-shrink: 0;
400
+ }
401
+
402
+ .lumir-toolbar-btn svg {
403
+ width: var(--lumir-icon-size);
404
+ height: var(--lumir-icon-size);
405
+ }
406
+
407
+ .lumir-toolbar-btn:hover {
408
+ background-color: var(--lumir-hover-light);
409
+ color: var(--lumir-text-light);
410
+ }
411
+
412
+ .lumir-toolbar-btn.is-active {
413
+ background-color: var(--lumir-active-bg);
414
+ color: var(--lumir-active-color);
415
+ }
416
+
417
+ .lumir-toolbar-btn:disabled {
418
+ opacity: 0.4;
419
+ cursor: not-allowed;
420
+ }
421
+
422
+ /* 색상 버튼 인디케이터 */
423
+ .lumir-color-btn {
424
+ flex-direction: column;
425
+ gap: 1px;
426
+ width: var(--lumir-btn-size);
427
+ height: var(--lumir-btn-size);
428
+ padding: 4px;
429
+ }
430
+
431
+ .lumir-color-btn svg {
432
+ width: 14px;
433
+ height: 14px;
434
+ }
435
+
436
+ .lumir-color-indicator {
437
+ width: 12px;
438
+ height: 2px;
439
+ border-radius: 1px;
440
+ border: 1px solid rgba(0, 0, 0, 0.1);
441
+ }
442
+
443
+ /* SVG 아이콘 스타일 */
444
+ .lumir-toolbar-btn svg,
445
+ .lumir-dropdown-btn svg {
446
+ flex-shrink: 0;
447
+ }
448
+
449
+ /* Dropdown Wrapper */
450
+ .lumir-dropdown-wrapper {
451
+ position: relative;
452
+ }
453
+
454
+ /* Dropdown Button (컴팩트) */
455
+ .lumir-dropdown-btn {
456
+ display: flex;
457
+ align-items: center;
458
+ justify-content: space-between;
459
+ min-width: 90px;
460
+ max-width: 110px;
461
+ height: var(--lumir-btn-size);
462
+ padding: 4px 8px;
463
+ border: none;
464
+ background: transparent;
465
+ color: inherit;
466
+ cursor: pointer;
467
+ border-radius: var(--lumir-radius-md);
468
+ font-size: 12px;
469
+ font-weight: 500;
470
+ transition: all var(--lumir-transition);
471
+ gap: 2px;
472
+ white-space: nowrap;
473
+ overflow: hidden;
474
+ }
475
+
476
+ .lumir-dropdown-btn span {
477
+ overflow: hidden;
478
+ text-overflow: ellipsis;
479
+ }
480
+
481
+ .lumir-dropdown-btn:hover {
482
+ background-color: var(--lumir-hover-light);
483
+ }
484
+
485
+ .lumir-dropdown-btn svg {
486
+ width: 14px;
487
+ height: 14px;
488
+ flex-shrink: 0;
489
+ color: var(--lumir-text-muted-light);
490
+ }
491
+
492
+ /* Dropdown Menu - 항상 밝은 배경 유지 */
493
+ .lumir-dropdown-menu {
494
+ position: absolute;
495
+ top: calc(100% + 4px);
496
+ left: 0;
497
+ min-width: 160px;
498
+ background-color: #ffffff !important;
499
+ border: 1px solid #e5e7eb !important;
500
+ border-radius: 10px;
501
+ box-shadow:
502
+ 0 4px 16px rgba(0, 0, 0, 0.12),
503
+ 0 0 0 1px rgba(0, 0, 0, 0.04);
504
+ z-index: 9999;
505
+ padding: 6px;
506
+ animation: lumir-dropdown-appear 0.15s ease;
507
+ }
508
+
509
+ @keyframes lumir-dropdown-appear {
510
+ from {
511
+ opacity: 0;
512
+ transform: translateY(-4px);
513
+ }
514
+ to {
515
+ opacity: 1;
516
+ transform: translateY(0);
517
+ }
518
+ }
519
+
520
+ /* Dropdown Item - 항상 밝은 스타일 */
521
+ .lumir-dropdown-item {
522
+ display: flex;
523
+ align-items: center;
524
+ width: 100%;
525
+ padding: 8px 12px;
526
+ text-align: left;
527
+ border: none;
528
+ background: transparent;
529
+ color: #374151 !important;
530
+ cursor: pointer;
531
+ border-radius: 6px;
532
+ font-size: 14px;
533
+ transition: background-color 0.1s ease;
534
+ }
535
+
536
+ .lumir-dropdown-item:hover {
537
+ background-color: #f3f4f6 !important;
538
+ }
539
+
540
+ .lumir-dropdown-item.is-active {
541
+ background-color: rgba(59, 130, 246, 0.1) !important;
542
+ color: #3b82f6 !important;
543
+ }
544
+
545
+ /* Font Size Dropdown Button (글자 크기) */
546
+ .lumir-font-size-btn {
547
+ min-width: 52px;
548
+ max-width: 72px;
549
+ }
550
+
551
+ .lumir-font-size-label {
552
+ flex: 1;
553
+ text-align: center;
554
+ }
555
+
556
+ .lumir-font-size-menu {
557
+ min-width: 96px;
558
+ max-height: 280px;
559
+ overflow-y: auto;
560
+ }
561
+
562
+ /* blur 상태에서도 텍스트 선택 하이라이트 유지 (InactiveSelectionExtension).
563
+ 툴바 드롭다운(글자 크기 등) 조작 시 에디터가 blur돼 네이티브 선택이 사라지는 문제 보완. */
564
+ .bn-inactive-selection {
565
+ background-color: var(--lumir-inactive-selection, rgba(35, 131, 226, 0.28));
566
+ }
567
+
568
+ /* Font Size 1px Stepper (글자 크기 −/+ + 직접 입력) — 두 드롭다운(FormattingToolbar/FloatingMenu) 공용 */
569
+ .lumir-fs-stepper {
570
+ display: flex;
571
+ align-items: center;
572
+ justify-content: center;
573
+ gap: 4px;
574
+ padding: 6px 8px;
575
+ border-bottom: 1px solid #e5e7eb;
576
+ }
577
+
578
+ .lumir-fs-stepper-btn {
579
+ width: 24px;
580
+ height: 24px;
581
+ display: flex;
582
+ align-items: center;
583
+ justify-content: center;
584
+ border: 1px solid #d1d5db;
585
+ border-radius: 4px;
586
+ background: #fff;
587
+ color: #374151;
588
+ cursor: pointer;
589
+ font-size: 14px;
590
+ line-height: 1;
591
+ flex-shrink: 0;
592
+ }
593
+
594
+ .lumir-fs-stepper-btn:hover:not(:disabled) {
595
+ background: #f3f4f6;
596
+ }
597
+
598
+ .lumir-fs-stepper-btn:disabled {
599
+ opacity: 0.4;
600
+ cursor: default;
601
+ }
602
+
603
+ .lumir-fs-stepper-input {
604
+ width: 40px;
605
+ text-align: center;
606
+ border: 1px solid #d1d5db;
607
+ border-radius: 4px;
608
+ padding: 3px 2px;
609
+ font-size: 13px;
610
+ color: #111827;
611
+ background: #fff;
612
+ -moz-appearance: textfield;
613
+ appearance: textfield;
614
+ }
615
+
616
+ .lumir-fs-stepper-input:focus {
617
+ outline: none;
618
+ border-color: #3b82f6;
619
+ }
620
+
621
+ .lumir-fs-stepper-input::-webkit-outer-spin-button,
622
+ .lumir-fs-stepper-input::-webkit-inner-spin-button {
623
+ -webkit-appearance: none;
624
+ margin: 0;
625
+ }
626
+
627
+ /* Block Type Dropdown Button */
628
+ .lumir-block-type-btn {
629
+ min-width: 110px;
630
+ max-width: 130px;
631
+ gap: 4px;
632
+ padding: 4px 8px;
633
+ }
634
+
635
+ .lumir-block-icon {
636
+ display: flex;
637
+ align-items: center;
638
+ justify-content: center;
639
+ width: 22px;
640
+ height: 22px;
641
+ flex-shrink: 0;
642
+ color: #6b7280;
643
+ }
644
+
645
+ .lumir-block-icon svg {
646
+ width: 18px;
647
+ height: 18px;
648
+ }
649
+
650
+ .lumir-block-icon-text {
651
+ font-size: 13px;
652
+ font-weight: 700;
653
+ color: #6b7280;
654
+ line-height: 1;
655
+ }
656
+
657
+ .lumir-block-label {
658
+ flex: 1;
659
+ text-align: left;
660
+ overflow: hidden;
661
+ text-overflow: ellipsis;
662
+ white-space: nowrap;
663
+ font-size: 13px;
664
+ }
665
+
666
+ /* Block Type Dropdown Menu - 최대 컴팩트 */
667
+ .lumir-block-menu {
668
+ min-width: 160px;
669
+ max-height: 320px;
670
+ overflow-y: auto;
671
+ padding: 3px;
672
+ }
673
+
674
+ /* 커스텀 스크롤바 - 더 얇게 */
675
+ .lumir-block-menu::-webkit-scrollbar {
676
+ width: 4px;
677
+ }
678
+
679
+ .lumir-block-menu::-webkit-scrollbar-track {
680
+ background: transparent;
681
+ }
682
+
683
+ .lumir-block-menu::-webkit-scrollbar-thumb {
684
+ background-color: #d1d5db;
685
+ border-radius: 2px;
686
+ }
687
+
688
+ .lumir-block-menu::-webkit-scrollbar-thumb:hover {
689
+ background-color: #9ca3af;
690
+ }
691
+
692
+ /* Block Type Menu Item - 최대 컴팩트 */
693
+ .lumir-block-item {
694
+ display: flex;
695
+ align-items: center;
696
+ gap: 6px;
697
+ padding: 4px 8px;
698
+ border-radius: 4px;
699
+ margin-bottom: 0;
700
+ transition: all 0.1s ease;
701
+ }
702
+
703
+ .lumir-block-item:last-child {
704
+ margin-bottom: 0;
705
+ }
706
+
707
+ .lumir-block-item .lumir-block-icon {
708
+ width: 20px;
709
+ height: 20px;
710
+ background-color: #f3f4f6;
711
+ border-radius: 3px;
712
+ display: flex;
713
+ align-items: center;
714
+ justify-content: center;
715
+ flex-shrink: 0;
716
+ }
717
+
718
+ .lumir-block-item .lumir-block-icon svg {
719
+ width: 14px;
720
+ height: 14px;
721
+ }
722
+
723
+ .lumir-block-item .lumir-block-icon-text {
724
+ font-size: 10px;
725
+ font-weight: 700;
726
+ }
727
+
728
+ .lumir-block-item-title {
729
+ font-size: 12px;
730
+ font-weight: 500;
731
+ color: #374151;
732
+ }
733
+
734
+ .lumir-block-item:hover {
735
+ background-color: #f3f4f6 !important;
736
+ }
737
+
738
+ .lumir-block-item:hover .lumir-block-icon {
739
+ background-color: #e5e7eb;
740
+ color: #374151;
741
+ }
742
+
743
+ .lumir-block-item:hover .lumir-block-icon-text {
744
+ color: #374151;
745
+ }
746
+
747
+ .lumir-block-item.is-active {
748
+ background-color: rgba(59, 130, 246, 0.08) !important;
749
+ }
750
+
751
+ .lumir-block-item.is-active .lumir-block-icon {
752
+ background-color: rgba(59, 130, 246, 0.15);
753
+ color: #3b82f6;
754
+ }
755
+
756
+ .lumir-block-item.is-active .lumir-block-icon-text {
757
+ color: #3b82f6;
758
+ }
759
+
760
+ /* Block Type Category - 최대 컴팩트 */
761
+ .lumir-block-category {
762
+ margin-bottom: 2px;
763
+ }
764
+
765
+ .lumir-block-category:last-child {
766
+ margin-bottom: 0;
767
+ }
768
+
769
+ .lumir-block-category-title {
770
+ font-size: 9px;
771
+ font-weight: 600;
772
+ color: #9ca3af;
773
+ text-transform: uppercase;
774
+ letter-spacing: 0.05em;
775
+ padding: 4px 8px 2px;
776
+ margin-bottom: 0;
777
+ }
778
+
779
+ /* Block Item Title */
780
+ .lumir-block-item:hover .lumir-block-item-title {
781
+ color: #1f2937;
782
+ }
783
+
784
+ .lumir-block-item.is-active .lumir-block-item-title {
785
+ color: #3b82f6;
786
+ font-weight: 600;
787
+ }
788
+
789
+ /* Toggle Heading 아이콘 - 컴팩트 */
790
+ .lumir-block-icon-toggle {
791
+ display: flex;
792
+ align-items: center;
793
+ gap: 2px;
794
+ font-size: 9px;
795
+ font-weight: 700;
796
+ color: #6b7280;
797
+ line-height: 1;
798
+ }
799
+
800
+ .lumir-block-icon-toggle svg {
801
+ width: 6px;
802
+ height: 6px;
803
+ flex-shrink: 0;
804
+ }
805
+
806
+ .lumir-block-icon-toggle span {
807
+ font-size: 9px;
808
+ font-weight: 700;
809
+ }
810
+
811
+ .lumir-block-item .lumir-block-icon-toggle {
812
+ font-size: 10px;
813
+ }
814
+
815
+ .lumir-block-item .lumir-block-icon-toggle svg {
816
+ width: 7px;
817
+ height: 7px;
818
+ }
819
+
820
+ .lumir-block-item .lumir-block-icon-toggle span {
821
+ font-size: 10px;
822
+ }
823
+
824
+ .lumir-block-item:hover .lumir-block-icon-toggle,
825
+ .lumir-block-item.is-active .lumir-block-icon-toggle {
826
+ color: inherit;
827
+ }
828
+
829
+ /* Color Picker Menu */
830
+ .lumir-color-menu {
831
+ min-width: 180px;
832
+ padding: 8px;
833
+ }
834
+
835
+ .lumir-color-grid {
836
+ display: grid;
837
+ grid-template-columns: repeat(5, 1fr);
838
+ gap: 6px;
839
+ }
840
+
841
+ .lumir-color-swatch {
842
+ width: 28px;
843
+ height: 28px;
844
+ border: 1px solid rgba(0, 0, 0, 0.15);
845
+ border-radius: 4px;
846
+ cursor: pointer;
847
+ transition: all 0.15s ease;
848
+ position: relative;
849
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
850
+ }
851
+
852
+ .lumir-color-swatch:hover {
853
+ transform: scale(1.15);
854
+ border-color: #3b82f6;
855
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
856
+ z-index: 1;
857
+ }
858
+
859
+ .lumir-color-swatch.is-active {
860
+ border-color: #3b82f6;
861
+ border-width: 2px;
862
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
863
+ }
864
+
865
+ .lumir-color-swatch.is-active::after {
866
+ content: '✓';
867
+ position: absolute;
868
+ top: 50%;
869
+ left: 50%;
870
+ transform: translate(-50%, -50%);
871
+ color: #ffffff;
872
+ font-size: 12px;
873
+ font-weight: bold;
874
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
875
+ }
876
+
877
+ .lumir-color-remove {
878
+ width: 100%;
879
+ padding: 6px 8px;
880
+ border: none;
881
+ background-color: #f3f4f6;
882
+ color: #6b7280;
883
+ font-size: 11px;
884
+ font-weight: 500;
885
+ border-radius: 4px;
886
+ cursor: pointer;
887
+ transition: all 0.15s ease;
888
+ }
889
+
890
+ .lumir-color-remove:hover {
891
+ background-color: #e5e7eb;
892
+ color: #374151;
893
+ }
894
+
895
+ /* Text Controls Group */
896
+ .lumir-text-controls {
897
+ gap: 8px;
898
+ }
899
+
900
+ /* Link Input Menu - Compact */
901
+ .lumir-link-menu {
902
+ min-width: 240px;
903
+ padding: 8px;
904
+ left: auto;
905
+ right: 0;
906
+ }
907
+
908
+ .lumir-link-form {
909
+ display: flex;
910
+ flex-direction: column;
911
+ gap: 6px;
912
+ }
913
+
914
+ .lumir-link-input {
915
+ width: 100%;
916
+ padding: 6px 8px;
917
+ border: 1px solid #d1d5db;
918
+ border-radius: 4px;
919
+ font-size: 12px;
920
+ font-family: inherit;
921
+ outline: none;
922
+ transition: all 0.15s ease;
923
+ }
924
+
925
+ .lumir-link-input:focus {
926
+ border-color: #3b82f6;
927
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
928
+ }
929
+
930
+ .lumir-link-input::placeholder {
931
+ color: #9ca3af;
932
+ font-size: 11px;
933
+ }
934
+
935
+ .lumir-link-actions {
936
+ display: flex;
937
+ gap: 4px;
938
+ justify-content: flex-end;
939
+ }
940
+
941
+ .lumir-link-btn {
942
+ padding: 4px 10px;
943
+ border: none;
944
+ border-radius: 4px;
945
+ font-size: 11px;
946
+ font-weight: 500;
947
+ cursor: pointer;
948
+ transition: all 0.15s ease;
949
+ }
950
+
951
+ .lumir-link-cancel {
952
+ background-color: #f3f4f6;
953
+ color: #6b7280;
954
+ }
955
+
956
+ .lumir-link-cancel:hover {
957
+ background-color: #e5e7eb;
958
+ color: #374151;
959
+ }
960
+
961
+ .lumir-link-submit {
962
+ background-color: #3b82f6;
963
+ color: #ffffff;
964
+ }
965
+
966
+ .lumir-link-submit:hover:not(:disabled) {
967
+ background-color: #2563eb;
968
+ }
969
+
970
+ .lumir-link-submit:disabled {
971
+ opacity: 0.5;
972
+ cursor: not-allowed;
973
+ }
974
+
975
+ /*
976
+ * 플로팅 툴바는 다크모드와 관계없이 항상 밝은 스타일 유지
977
+ * 다크모드 오버라이드를 적용하지 않음
978
+ */
979
+
980
+ /* ========================================
981
+ 에러 토스트 스타일
982
+ ======================================== */
983
+
984
+ .lumirEditor-error-toast {
985
+ position: absolute;
986
+ bottom: 16px;
987
+ left: 50%;
988
+ transform: translateX(-50%);
989
+ display: flex;
990
+ align-items: center;
991
+ gap: 8px;
992
+ padding: 12px 16px;
993
+ background-color: #fef2f2;
994
+ border: 1px solid #fecaca;
995
+ border-radius: 8px;
996
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
997
+ z-index: 1001;
998
+ animation: lumirEditor-toast-appear 0.3s ease;
999
+ max-width: 90%;
1000
+ }
1001
+
1002
+ @keyframes lumirEditor-toast-appear {
1003
+ from {
1004
+ opacity: 0;
1005
+ transform: translateX(-50%) translateY(10px);
1006
+ }
1007
+ to {
1008
+ opacity: 1;
1009
+ transform: translateX(-50%) translateY(0);
1010
+ }
1011
+ }
1012
+
1013
+ .lumirEditor-error-icon {
1014
+ flex-shrink: 0;
1015
+ font-size: 16px;
1016
+ }
1017
+
1018
+ .lumirEditor-error-message {
1019
+ font-size: 13px;
1020
+ font-weight: 500;
1021
+ color: #991b1b;
1022
+ line-height: 1.4;
1023
+ }
1024
+
1025
+ .lumirEditor-error-close {
1026
+ flex-shrink: 0;
1027
+ display: flex;
1028
+ align-items: center;
1029
+ justify-content: center;
1030
+ width: 20px;
1031
+ height: 20px;
1032
+ padding: 0;
1033
+ border: none;
1034
+ background: transparent;
1035
+ color: #991b1b;
1036
+ font-size: 14px;
1037
+ cursor: pointer;
1038
+ border-radius: 4px;
1039
+ transition: background-color 0.15s ease;
1040
+ }
1041
+
1042
+ .lumirEditor-error-close:hover {
1043
+ background-color: #fee2e2;
1044
+ }
1045
+
1046
+ /* ========================================
1047
+ Link Preview 카드 스타일
1048
+ ======================================== */
1049
+
1050
+ @keyframes lumir-skeleton-pulse {
1051
+ 0% {
1052
+ opacity: 1;
1053
+ }
1054
+ 50% {
1055
+ opacity: 0.4;
1056
+ }
1057
+ 100% {
1058
+ opacity: 1;
1059
+ }
1060
+ }
1061
+
1062
+ .lumir-link-preview-card:hover .lumir-link-preview-delete {
1063
+ opacity: 1 !important;
1064
+ }
1065
+
1066
+ .lumir-link-preview-delete:hover {
1067
+ background-color: rgba(0, 0, 0, 0.7) !important;
1068
+ }
1069
+
1070
+ .lumir-resize-handle {
1071
+ position: absolute;
1072
+ width: 8px;
1073
+ height: 30px;
1074
+ background-color: black;
1075
+ border: 1px solid white;
1076
+ border-radius: 4px;
1077
+ cursor: ew-resize;
1078
+ top: 50%;
1079
+ transform: translateY(-50%);
1080
+ z-index: 3;
1081
+ }
1082
+
1083
+ .lumir-resize-handle-bottom {
1084
+ position: absolute;
1085
+ bottom: 4px;
1086
+ left: 50%;
1087
+ transform: translateX(-50%);
1088
+ width: 30px;
1089
+ height: 8px;
1090
+ background-color: black;
1091
+ border: 1px solid white;
1092
+ border-radius: 4px;
1093
+ cursor: ns-resize;
1094
+ z-index: 3;
1095
+ }
1096
+
1097
+ .lumir-link-preview-card:hover {
1098
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
1099
+ }
1100
+
1101
+ .node-linkPreview.ProseMirror-selectednode .bn-block-content {
1102
+ outline: 2px solid #3b82f6;
1103
+ outline-offset: 2px;
1104
+ border-radius: 8px;
1105
+ }
1106
+
1107
+ .node-linkPreview .bn-block-content {
1108
+ outline: none !important;
1109
+ }
1110
+
1111
+ /* 다크 테마 대응 */
1112
+ [data-color-scheme='dark'] .lumir-link-preview-card,
1113
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-card {
1114
+ background-color: #292524 !important;
1115
+ border-color: #44403c !important;
1116
+ }
1117
+
1118
+ [data-color-scheme='dark'] .lumir-link-preview-card:hover,
1119
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-card:hover {
1120
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
1121
+ }
1122
+
1123
+ [data-color-scheme='dark'] .lumir-link-preview-skeleton,
1124
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-skeleton {
1125
+ background-color: #292524 !important;
1126
+ border-color: #44403c !important;
1127
+ }
1128
+
1129
+ [data-color-scheme='dark'] .lumir-link-preview-error,
1130
+ .bn-container[data-color-scheme='dark'] .lumir-link-preview-error {
1131
+ background-color: #292524 !important;
1132
+ border-color: #44403c !important;
1133
+ }
1134
+
1135
+ /* 인용·코드·테이블 본문 14px */
1136
+ .lumirEditor .bn-block-content[data-content-type='quote'] p.bn-inline-content,
1137
+ .lumirEditor [data-content-type='quote'] blockquote {
1138
+ font-size: 14px;
1139
+ }
1140
+
1141
+ .lumirEditor .bn-block-content[data-content-type='codeBlock'] pre,
1142
+ .lumirEditor .bn-block-content[data-content-type='codeBlock'] pre code {
1143
+ font-size: 14px;
1144
+ }
1145
+
1146
+ .lumirEditor .bn-editor [data-content-type='table'] th,
1147
+ .lumirEditor .bn-editor [data-content-type='table'] td,
1148
+ .lumirEditor .bn-editor [data-content-type='table'] p.bn-inline-content {
1149
+ font-size: 14px;
1150
+ }
1151
+
1152
+ /* 테이블 셀 세로 정렬 (VerticalAlignmentExtension) */
1153
+ .lumirEditor
1154
+ .bn-editor
1155
+ [data-content-type='table']
1156
+ td[data-vertical-alignment='middle'],
1157
+ .lumirEditor
1158
+ .bn-editor
1159
+ [data-content-type='table']
1160
+ th[data-vertical-alignment='middle'] {
1161
+ vertical-align: middle;
1162
+ }
1163
+
1164
+ .lumirEditor
1165
+ .bn-editor
1166
+ [data-content-type='table']
1167
+ td[data-vertical-alignment='bottom'],
1168
+ .lumirEditor
1169
+ .bn-editor
1170
+ [data-content-type='table']
1171
+ th[data-vertical-alignment='bottom'] {
1172
+ vertical-align: bottom;
1173
+ }
1174
+
1175
+ /* ==========================================================================
1176
+ Notion 스타일 FOCUS 기반 테이블 gutter/grip (LumirTableHandlesController)
1177
+ - 셀 focus 시: 셀 테두리 하이라이트(파란 보더, 셀을 살짝 감쌈)
1178
+ - 상단(열)·좌측(행): 짧고 두꺼운 회색 gutter 바 / 우측(셀): 작은 파란 앵커
1179
+ - gutter hover 시: 발판 grip 노출 → 클릭 시 드롭다운
1180
+ - active(메뉴 열림/드래그): 발판이 파란 배경 + 흰 점
1181
+ 기본 BlockNote hover 핸들은 tableHandles={false}로 비활성.
1182
+ ========================================================================== */
1183
+
1184
+ /* focus된 셀 테두리 하이라이트 (셀을 ~2px 바깥에서 감싸는 비클릭 오버레이) */
1185
+ .lumirEditor .lumir-tbl-cell-focus {
1186
+ position: absolute;
1187
+ top: 0;
1188
+ left: 0;
1189
+ box-sizing: border-box;
1190
+ border: 2px solid #2383e2;
1191
+ border-radius: 2px;
1192
+ pointer-events: none;
1193
+ z-index: 1;
1194
+ }
1195
+
1196
+ /* gutter wrapper = hover 히트 영역. 보더에 걸쳐 중앙 배치(positioner offset -7). */
1197
+ .lumirEditor .lumir-tbl-gutter-wrap {
1198
+ position: absolute;
1199
+ z-index: 2;
1200
+ cursor: pointer;
1201
+ }
1202
+
1203
+ .lumirEditor .lumir-tbl-gutter-wrap--col {
1204
+ width: 34px;
1205
+ height: 14px;
1206
+ }
1207
+
1208
+ .lumirEditor .lumir-tbl-gutter-wrap--row,
1209
+ .lumirEditor .lumir-tbl-gutter-wrap--cell {
1210
+ width: 14px;
1211
+ height: 34px;
1212
+ }
1213
+
1214
+ /* 기본 노출: 짧고 두꺼운 gutter 바. wrapper가 셀 보더에 중앙 정렬되어 있으므로,
1215
+ gutter를 wrapper 중앙에 두면 "거터 중앙이 셀 보더선 위"에 오도록 걸쳐진다
1216
+ (절반은 셀 안쪽, 절반은 바깥쪽). */
1217
+ .lumirEditor .lumir-tbl-gutter {
1218
+ position: absolute;
1219
+ inset: 0;
1220
+ margin: auto;
1221
+ box-sizing: border-box;
1222
+ background-color: #c0c0c2;
1223
+ transition: opacity 0.1s ease;
1224
+ }
1225
+
1226
+ /* 상(top): 가로 pill — 상단 보더 중앙 */
1227
+ .lumirEditor .lumir-tbl-gutter-wrap--col .lumir-tbl-gutter {
1228
+ width: 14px;
1229
+ height: 4px;
1230
+ border-left: 1px solid #fff;
1231
+ border-right: 1px solid #fff;
1232
+ }
1233
+
1234
+ /* 좌(left): 세로 pill — 좌측 보더 중앙 (Notion도 좌측에 표시) */
1235
+ .lumirEditor .lumir-tbl-gutter-wrap--row .lumir-tbl-gutter {
1236
+ width: 4px;
1237
+ height: 14px;
1238
+ border-top: 1px solid #fff;
1239
+ border-bottom: 1px solid #fff;
1240
+ }
1241
+
1242
+ /* 우(right): Notion의 파란 선택 앵커 — 우측 보더 중앙 */
1243
+ /* 우(right): 셀 우측 보더의 파란 세로 앵커 */
1244
+ .lumirEditor .lumir-tbl-gutter-wrap--cell .lumir-tbl-gutter {
1245
+ width: 4px;
1246
+ height: 14px;
1247
+ background-color: #2383e2;
1248
+ border-top: 1px solid #fff;
1249
+ border-bottom: 1px solid #fff;
1250
+ }
1251
+
1252
+ .lumirEditor .lumir-tbl-gutter-wrap:hover .lumir-tbl-gutter {
1253
+ opacity: 0;
1254
+ }
1255
+
1256
+ /* 발판 grip: 기본 숨김, gutter hover 시 노출 */
1257
+ .lumirEditor .lumir-tbl-grip {
1258
+ position: absolute;
1259
+ inset: 0;
1260
+ display: flex;
1261
+ align-items: center;
1262
+ justify-content: center;
1263
+ opacity: 0;
1264
+ pointer-events: none;
1265
+ cursor: pointer;
1266
+ transition: opacity 0.1s ease;
1267
+ }
1268
+
1269
+ .lumirEditor .lumir-tbl-gutter-wrap:hover .lumir-tbl-grip {
1270
+ opacity: 1;
1271
+ pointer-events: auto;
1272
+ }
1273
+
1274
+ /* 메뉴 열림(active) 동안 발판 유지(마우스가 떠나도) + rest 바 숨김 */
1275
+ .lumirEditor .lumir-tbl-gutter-wrap--active .lumir-tbl-grip {
1276
+ opacity: 1;
1277
+ pointer-events: auto;
1278
+ }
1279
+
1280
+ .lumirEditor .lumir-tbl-gutter-wrap--active .lumir-tbl-gutter {
1281
+ opacity: 0;
1282
+ }
1283
+
1284
+ /* 드롭다운 오픈(active)·드래그 시 발판: 배경·보더 파랑(#2383e2) + 흰 아이콘 */
1285
+ .lumirEditor .lumir-tbl-gutter-wrap--active .bn-table-handle,
1286
+ .lumirEditor .lumir-tbl-gutter-wrap--active .bn-table-cell-handle,
1287
+ .lumirEditor .lumir-tbl-grip .bn-table-handle-dragging {
1288
+ background-color: #2383e2 !important;
1289
+ border-color: #2383e2 !important;
1290
+ color: #fff !important;
1291
+ }
1292
+
1293
+ /* 발판 크기: 너비(11)↓·높이(14) 유지. 상단 발판은 90° 회전이라 너비↓ = 시각적 높이↓.
1294
+ 배경 흰색 + 보더 진하게(#999). */
1295
+ .lumirEditor .lumir-tbl-grip .bn-table-handle,
1296
+ .lumirEditor .lumir-tbl-grip .bn-table-cell-handle {
1297
+ width: 12px;
1298
+ min-width: 12px;
1299
+ height: 16px;
1300
+ padding: 0;
1301
+ border-radius: 3px;
1302
+ cursor: pointer; /* mantine 기본 grab → pointer */
1303
+ background-color: #fff;
1304
+ border: 1px solid #cfcfcf;
1305
+ box-shadow: none; /* mantine 기본 그림자(--bn-shadow-light, 블러처럼 보임) 제거 */
1306
+ }
1307
+
1308
+ /* hover 시에도 흰 배경 유지 (mantine hover 회색 오버라이드) */
1309
+ .lumirEditor .lumir-tbl-grip .bn-table-handle:hover,
1310
+ .lumirEditor .lumir-tbl-grip .bn-table-cell-handle:hover {
1311
+ background-color: #fff;
1312
+ }
1313
+
1314
+ .lumirEditor .lumir-tbl-grip .bn-table-handle svg {
1315
+ width: 12px;
1316
+ height: 12px;
1317
+ margin-inline: 0;
1318
+ }
1319
+
1320
+ .lumirEditor .lumir-tbl-grip .bn-table-cell-handle svg {
1321
+ width: 12px;
1322
+ height: 12px;
1323
+ }
1324
+
1325
+ /* =========================================================
1326
+ 표 행 높이(row height) 드래그 리사이즈 — rowResizing 플러그인
1327
+ prosemirror-tables의 column-resize 스타일을 수직축으로 미러링.
1328
+ ========================================================= */
1329
+
1330
+ /* activeHandle 동안 에디터 전체 커서를 행 리사이즈로 */
1331
+ .lumirEditor .ProseMirror.row-resize-cursor {
1332
+ cursor: ns-resize;
1333
+ cursor: row-resize;
1334
+ }
1335
+
1336
+ /* 핸들 위젯의 절대배치 기준(셀). prosemirror-tables 기본값 보강. */
1337
+ .lumirEditor .ProseMirror td,
1338
+ .lumirEditor .ProseMirror th {
1339
+ position: relative;
1340
+ }
1341
+
1342
+ /* 셀 하단 경계 핸들(셀별 1개가 모여 행 폭 전체를 덮음). */
1343
+ .lumirEditor .ProseMirror .row-resize-handle {
1344
+ position: absolute;
1345
+ left: 0;
1346
+ right: 0;
1347
+ bottom: -2px;
1348
+ height: 4px;
1349
+ z-index: 20;
1350
+ background-color: #adf;
1351
+ pointer-events: none;
1352
+ }
1353
+
1354
+ /* 드래그 중 셀: 레이아웃 트랜지션 제거로 프리뷰 떨림 방지. */
1355
+ .lumirEditor .ProseMirror .row-resize-dragging {
1356
+ transition: none;
1357
+ }
1358
+
1359
+ /* 표 전체 스케일: 우하단 모서리 hit-zone(투명). 오버레이라 에디터 위에 떠서 코너의
1360
+ hover/클릭을 가로채므로 행/열 리사이즈(하단·우측 경계)와 충돌하지 않는다.
1361
+ 보이는 핸들 없이 hover 시 대각 리사이즈 커서만 노출 + 드래그로 크기 조절. */
1362
+ .lumirEditor .lumir-tbl-scale-handle {
1363
+ width: 18px;
1364
+ height: 18px;
1365
+ background: transparent;
1366
+ cursor: nwse-resize;
1367
+ z-index: 30;
1368
+ pointer-events: auto;
1369
+ touch-action: none;
1370
+ }
1371
+ /* 드래그 중 셀: 트랜지션 제거로 프리뷰 떨림 방지. */
1372
+ .lumirEditor .ProseMirror .lumir-table-scale-dragging {
1373
+ transition: none;
1374
+ }
1375
+
1376
+ /* =========================================================
1377
+ 표 블록 정렬(좌/가운데/우) — TableAlignmentExtension
1378
+ <table>이 width:auto(content 폭)이므로 margin으로 수평 정렬.
1379
+ 좌측(기본)은 별도 규칙 불필요.
1380
+ ========================================================= */
1381
+ .lumirEditor
1382
+ .bn-editor
1383
+ [data-content-type='table'][data-table-alignment='center']
1384
+ table {
1385
+ margin-left: auto;
1386
+ margin-right: auto;
1387
+ }
1388
+
1389
+ .lumirEditor
1390
+ .bn-editor
1391
+ [data-content-type='table'][data-table-alignment='right']
1392
+ table {
1393
+ margin-left: auto;
1394
+ margin-right: 0;
1395
+ }
1396
+
1397
+ /* =========================================================
1398
+ 표 하단 여백 축소
1399
+ @blocknote 기본 .tableWrapper는 `position:relative; top:-16px`라서, 화면상 16px
1400
+ 위로 그리되 레이아웃 공간은 원위치에 예약 → 래퍼 박스 아래에 사용되지 않는 16px가
1401
+ 남는다(순수 artifact). 음수 margin-bottom으로 이 예약 공백만 정확히 상쇄한다.
1402
+ 래퍼의 padding/overflow는 건드리지 않으므로 행/열 추가 버튼·리사이즈 핸들·거터의
1403
+ 클리어런스(클립 경계)는 그대로 유지된다 → 사이드이펙트 없음.
1404
+ ========================================================= */
1405
+ .lumirEditor .bn-editor [data-content-type='table'] .tableWrapper {
1406
+ margin-bottom: -16px;
1407
+ }
1408
+
1409
+ /* =========================================================
1410
+ 다단(컬럼) 레이아웃 — columnList / column 노드
1411
+ columnList: 가로 flex 컨테이너, column: 균등 폭 flex 아이템.
1412
+ ========================================================= */
1413
+ .lumirEditor .bn-column-list {
1414
+ display: flex;
1415
+ gap: 16px;
1416
+ width: 100%;
1417
+ }
1418
+
1419
+ .lumirEditor .bn-column {
1420
+ flex: 1 1 0;
1421
+ min-width: 0; /* 컬럼 내 넓은 콘텐츠(표 등) 오버플로 방지 */
1422
+ }
1423
+
1424
+ /* 컬럼 중앙 세로 구분선. 두 가지 방식으로 켜진다(둘 중 하나라도 켜지면 표시):
1425
+ 1) 전역: columnDivider prop → 루트 `.lumir-column-divider` (모든 컬럼).
1426
+ 2) 블록별: columnList의 `showDivider` attr → `data-divider="true"` (드래그핸들 메뉴 토글).
1427
+ divider가 드래그 핸들(grip)에 가려지지 않도록 gap을 넓혀(기본 16px → grip-space×2)
1428
+ divider를 정중앙에 두고 양쪽에 grip 너비만큼 여백을 둔다. 마지막 컬럼 제외 → N컬럼이면
1429
+ N-1개. flex 기본 align-items:stretch로 컬럼 높이가 같아 구분선이 전체 높이를 채운다.
1430
+ grip-space/색은 CSS 변수로 조정 가능. */
1431
+ .lumirEditor.lumir-column-divider .bn-column-list,
1432
+ .lumirEditor .bn-column-list[data-divider="true"] {
1433
+ --lumir-column-grip-space: 28px; /* divider ~ 콘텐츠 여백(≈grip 너비 + 여유) */
1434
+ gap: calc(var(--lumir-column-grip-space) * 2);
1435
+ }
1436
+ .lumirEditor.lumir-column-divider .bn-column,
1437
+ .lumirEditor .bn-column-list[data-divider="true"] .bn-column {
1438
+ position: relative;
1439
+ }
1440
+ .lumirEditor.lumir-column-divider .bn-column:not(:last-child)::after,
1441
+ .lumirEditor .bn-column-list[data-divider="true"] .bn-column:not(:last-child)::after {
1442
+ content: "";
1443
+ position: absolute;
1444
+ top: 0;
1445
+ bottom: 0;
1446
+ right: calc(var(--lumir-column-grip-space) * -1); /* gap 정중앙 */
1447
+ width: 1px;
1448
+ background: var(--lumir-column-divider-color, #e5e7eb);
1449
+ pointer-events: none;
1450
+ }
1451
+
1452
+ /* DnD 컬럼 생성: 드롭 대상 블록의 좌/우 가장자리 세로 인디케이터(레이아웃 비이동 box-shadow) */
1453
+ .lumirEditor .lumir-col-drop-left {
1454
+ box-shadow: -3px 0 0 0 #3b82f6;
1455
+ }
1456
+ .lumirEditor .lumir-col-drop-right {
1457
+ box-shadow: 3px 0 0 0 #3b82f6;
1458
+ }
1459
+ /* 가장자리 드롭 중에는 기본(가로) 드롭커서를 숨겨 인디케이터 중복 방지 */
1460
+ .lumirEditor .lumir-col-dnd-active .prosemirror-dropcursor,
1461
+ .lumirEditor .lumir-col-dnd-active .ProseMirror-dropcursor {
1462
+ display: none !important;
1463
+ }