neiki-editor 2.9.1 → 2.9.3

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.
@@ -1,2215 +1,2372 @@
1
- /**
2
- * NeikiEditor - Production-Ready WYSIWYG Rich Text Editor
3
- * CSS Stylesheet
4
- * Version: 2.9.1
5
- */
6
-
7
- /* ============================================
8
- CSS Custom Properties (Light/Dark Themes)
9
- ============================================ */
10
- :root {
11
- /* Light Theme (default) */
12
- --neiki-bg-primary: #ffffff;
13
- --neiki-bg-secondary: #f8f9fa;
14
- --neiki-bg-tertiary: #e9ecef;
15
- --neiki-bg-hover: #dee2e6;
16
- --neiki-bg-active: #ced4da;
17
- --neiki-border-color: #dee2e6;
18
- --neiki-border-color-dark: #adb5bd;
19
- --neiki-text-primary: #212529;
20
- --neiki-text-secondary: #495057;
21
- --neiki-text-muted: #6c757d;
22
- --neiki-accent-color: #0d6efd;
23
- --neiki-accent-hover: #0b5ed7;
24
- --neiki-danger-color: #dc3545;
25
- --neiki-success-color: #198754;
26
- --neiki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
27
- --neiki-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
28
- --neiki-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
29
- --neiki-editor-bg: #ffffff;
30
- --neiki-toolbar-bg: #f8f9fa;
31
- --neiki-statusbar-bg: #f8f9fa;
32
- --neiki-modal-overlay: rgba(0, 0, 0, 0.5);
33
- --neiki-scrollbar-thumb: #ced4da;
34
- --neiki-scrollbar-track: #f8f9fa;
35
- --neiki-selection-bg: #b3d7ff;
36
- --neiki-highlight-color: #fff3cd;
37
- --neiki-table-border: #dee2e6;
38
- }
39
-
40
- /* Dark Theme */
41
- .neiki-editor.neiki-dark {
42
- --neiki-bg-primary: #1e1e1e;
43
- --neiki-bg-secondary: #252526;
44
- --neiki-bg-tertiary: #2d2d30;
45
- --neiki-bg-hover: #3e3e42;
46
- --neiki-bg-active: #505050;
47
- --neiki-border-color: #3e3e42;
48
- --neiki-border-color-dark: #505050;
49
- --neiki-text-primary: #d4d4d4;
50
- --neiki-text-secondary: #a0a0a0;
51
- --neiki-text-muted: #808080;
52
- --neiki-accent-color: #4fc3f7;
53
- --neiki-accent-hover: #29b6f6;
54
- --neiki-danger-color: #f44336;
55
- --neiki-success-color: #4caf50;
56
- --neiki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
57
- --neiki-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
58
- --neiki-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);
59
- --neiki-editor-bg: #1e1e1e;
60
- --neiki-toolbar-bg: #252526;
61
- --neiki-statusbar-bg: #252526;
62
- --neiki-modal-overlay: rgba(0, 0, 0, 0.7);
63
- --neiki-scrollbar-thumb: #505050;
64
- --neiki-scrollbar-track: #2d2d30;
65
- --neiki-selection-bg: #264f78;
66
- --neiki-highlight-color: #5c4d00;
67
- --neiki-table-border: #3e3e42;
68
- }
69
-
70
- /* ============================================
71
- Base Editor Container
72
- ============================================ */
73
- .neiki-editor {
74
- display: flex;
75
- flex-direction: column;
76
- width: 100%;
77
- height: 100%;
78
- min-height: 400px;
79
- background: var(--neiki-bg-primary);
80
- border: 1px solid var(--neiki-border-color);
81
- border-radius: 8px;
82
- overflow: hidden;
83
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
84
- font-size: 14px;
85
- color: var(--neiki-text-primary);
86
- box-shadow: var(--neiki-shadow-md);
87
- }
88
-
89
- .neiki-editor * {
90
- box-sizing: border-box;
91
- }
92
-
93
- /* Fullscreen Mode */
94
- .neiki-editor.neiki-fullscreen {
95
- position: fixed !important;
96
- top: 0 !important;
97
- left: 0 !important;
98
- right: 0 !important;
99
- bottom: 0 !important;
100
- width: 100vw !important;
101
- height: 100vh !important;
102
- z-index: 999999 !important;
103
- border-radius: 0 !important;
104
- border: none !important;
105
- }
106
-
107
- /* ============================================
108
- Toolbar
109
- ============================================ */
110
- .neiki-toolbar {
111
- display: flex;
112
- flex-wrap: wrap;
113
- align-items: center;
114
- gap: 2px;
115
- padding: 6px 8px;
116
- background: var(--neiki-toolbar-bg);
117
- border-bottom: 1px solid var(--neiki-border-color);
118
- min-height: 44px;
119
- }
120
-
121
- .neiki-toolbar-group {
122
- display: inline-flex;
123
- align-items: center;
124
- gap: 2px;
125
- padding: 0 4px;
126
- flex-wrap: nowrap;
127
- }
128
-
129
- .neiki-toolbar-group:not(:last-child) {
130
- border-right: 1px solid var(--neiki-border-color);
131
- padding-right: 8px;
132
- margin-right: 4px;
133
- }
134
-
135
- .neiki-toolbar-divider {
136
- width: 1px;
137
- height: 24px;
138
- background: var(--neiki-border-color);
139
- margin: 0 4px;
140
- }
141
-
142
- /* Toolbar Buttons */
143
- .neiki-btn,
144
- .neiki-toolbar-btn {
145
- position: relative;
146
- display: inline-flex;
147
- align-items: center;
148
- justify-content: center;
149
- width: 32px;
150
- height: 32px;
151
- padding: 0;
152
- background: transparent;
153
- border: 1px solid transparent;
154
- border-radius: 4px;
155
- cursor: pointer;
156
- color: var(--neiki-text-secondary);
157
- transition: all 0.15s ease;
158
- position: relative;
159
- }
160
-
161
- .neiki-btn:hover,
162
- .neiki-toolbar-btn:hover {
163
- background: var(--neiki-bg-hover);
164
- color: var(--neiki-text-primary);
165
- }
166
-
167
- .neiki-btn:active,
168
- .neiki-toolbar-btn:active {
169
- background: var(--neiki-bg-active);
170
- }
171
-
172
- .neiki-btn.active,
173
- .neiki-toolbar-btn.active {
174
- background: var(--neiki-bg-active);
175
- color: var(--neiki-accent-color);
176
- border-color: var(--neiki-accent-color);
177
- }
178
-
179
- .neiki-btn:disabled,
180
- .neiki-toolbar-btn:disabled {
181
- opacity: 0.4;
182
- cursor: not-allowed;
183
- }
184
-
185
- .neiki-btn svg,
186
- .neiki-toolbar-btn svg {
187
- width: 18px;
188
- height: 18px;
189
- fill: currentColor;
190
- pointer-events: none;
191
- }
192
-
193
- /* Toolbar Selects */
194
- .neiki-select {
195
- height: 32px;
196
- padding: 0 28px 0 10px;
197
- background: var(--neiki-bg-primary);
198
- border: 1px solid var(--neiki-border-color);
199
- border-radius: 4px;
200
- color: var(--neiki-text-primary);
201
- font-size: 13px;
202
- cursor: pointer;
203
- appearance: none;
204
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
205
- background-repeat: no-repeat;
206
- background-position: right 8px center;
207
- min-width: 100px;
208
- }
209
-
210
- .neiki-select:hover {
211
- border-color: var(--neiki-border-color-dark);
212
- }
213
-
214
- .neiki-select:focus {
215
- outline: none;
216
- border-color: var(--neiki-accent-color);
217
- box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.15);
218
- }
219
-
220
- /* Color Picker Button */
221
- .neiki-color-btn {
222
- position: relative;
223
- width: 36px;
224
- }
225
-
226
- .neiki-color-btn .neiki-color-indicator {
227
- position: absolute;
228
- bottom: 4px;
229
- left: 50%;
230
- transform: translateX(-50%);
231
- width: 16px;
232
- height: 3px;
233
- border-radius: 1px;
234
- background: currentColor;
235
- }
236
-
237
- /* Checkbox Toggle */
238
- .neiki-checkbox-wrapper {
239
- display: flex;
240
- align-items: center;
241
- gap: 6px;
242
- padding: 0 8px;
243
- height: 32px;
244
- font-size: 12px;
245
- color: var(--neiki-text-secondary);
246
- cursor: pointer;
247
- user-select: none;
248
- }
249
-
250
- .neiki-checkbox {
251
- width: 16px;
252
- height: 16px;
253
- accent-color: var(--neiki-accent-color);
254
- cursor: pointer;
255
- }
256
-
257
- /* ============================================
258
- Editor Content Area
259
- ============================================ */
260
- .neiki-editor-wrapper,
261
- .neiki-content-wrapper {
262
- flex: 1;
263
- display: flex;
264
- flex-direction: column;
265
- overflow: hidden;
266
- position: relative;
267
- }
268
-
269
- .neiki-content {
270
- flex: 1;
271
- padding: 20px 24px;
272
- background: var(--neiki-editor-bg);
273
- overflow-y: auto;
274
- outline: none;
275
- line-height: 1.6;
276
- color: var(--neiki-text-primary);
277
- min-height: 200px;
278
- }
279
-
280
- .neiki-content:focus {
281
- outline: none;
282
- }
283
-
284
- /* Placeholder */
285
- .neiki-content:empty::before {
286
- content: attr(data-placeholder);
287
- color: var(--neiki-text-muted);
288
- font-style: italic;
289
- pointer-events: none;
290
- }
291
-
292
- .neiki-content.neiki-drag-over {
293
- border: 2px dashed var(--neiki-accent-color);
294
- background: rgba(13, 110, 253, 0.05);
295
- }
296
-
297
- .neiki-content.neiki-drag-over::after {
298
- content: 'Drop images here';
299
- position: absolute;
300
- top: 50%;
301
- left: 50%;
302
- transform: translate(-50%, -50%);
303
- color: var(--neiki-accent-color);
304
- font-weight: 600;
305
- font-size: 16px;
306
- pointer-events: none;
307
- z-index: 10;
308
- }
309
-
310
- /* Focus state for editor container - disabled */
311
- /* .neiki-editor.neiki-focused removed */
312
-
313
- /* Disabled state */
314
- .neiki-editor.neiki-disabled {
315
- opacity: 0.6;
316
- pointer-events: none;
317
- }
318
-
319
- /* Content Scrollbar */
320
- .neiki-content::-webkit-scrollbar {
321
- width: 10px;
322
- }
323
-
324
- .neiki-content::-webkit-scrollbar-track {
325
- background: var(--neiki-scrollbar-track);
326
- }
327
-
328
- .neiki-content::-webkit-scrollbar-thumb {
329
- background: var(--neiki-scrollbar-thumb);
330
- border-radius: 5px;
331
- }
332
-
333
- .neiki-content::-webkit-scrollbar-thumb:hover {
334
- background: var(--neiki-border-color-dark);
335
- }
336
-
337
- /* Content Typography */
338
- .neiki-content p {
339
- margin: 0 0 1em 0;
340
- }
341
-
342
- .neiki-content h1 {
343
- font-size: 2em;
344
- font-weight: 700;
345
- margin: 0 0 0.5em 0;
346
- }
347
-
348
- .neiki-content h2 {
349
- font-size: 1.5em;
350
- font-weight: 600;
351
- margin: 0 0 0.5em 0;
352
- }
353
-
354
- .neiki-content h3 {
355
- font-size: 1.25em;
356
- font-weight: 600;
357
- margin: 0 0 0.5em 0;
358
- }
359
-
360
- .neiki-content h4 {
361
- font-size: 1.1em;
362
- font-weight: 600;
363
- margin: 0 0 0.5em 0;
364
- }
365
-
366
- .neiki-content h5 {
367
- font-size: 1em;
368
- font-weight: 600;
369
- margin: 0 0 0.5em 0;
370
- }
371
-
372
- .neiki-content h6 {
373
- font-size: 0.9em;
374
- font-weight: 600;
375
- margin: 0 0 0.5em 0;
376
- }
377
-
378
- .neiki-content ul,
379
- .neiki-content ol {
380
- margin: 0 0 1em 0;
381
- padding-left: 2em;
382
- }
383
-
384
- .neiki-content li {
385
- margin-bottom: 0.25em;
386
- }
387
-
388
- .neiki-content blockquote {
389
- margin: 0 0 1em 0;
390
- padding: 10px 20px;
391
- border-left: 4px solid var(--neiki-accent-color);
392
- background: var(--neiki-bg-secondary);
393
- font-style: italic;
394
- }
395
-
396
- .neiki-content pre {
397
- margin: 0 0 1em 0;
398
- padding: 16px;
399
- background: var(--neiki-bg-tertiary);
400
- border-radius: 4px;
401
- overflow-x: auto;
402
- font-family: 'Consolas', 'Monaco', monospace;
403
- font-size: 13px;
404
- }
405
-
406
- .neiki-content code {
407
- padding: 2px 6px;
408
- background: var(--neiki-bg-tertiary);
409
- border-radius: 3px;
410
- font-family: 'Consolas', 'Monaco', monospace;
411
- font-size: 0.9em;
412
- }
413
-
414
- .neiki-content a {
415
- color: var(--neiki-accent-color);
416
- text-decoration: underline;
417
- }
418
-
419
- .neiki-content a:hover {
420
- color: var(--neiki-accent-hover);
421
- }
422
-
423
- .neiki-content img {
424
- max-width: 100%;
425
- height: auto;
426
- border-radius: 4px;
427
- cursor: pointer;
428
- }
429
-
430
- .neiki-content img.neiki-selected {
431
- outline: 2px solid var(--neiki-accent-color);
432
- outline-offset: 2px;
433
- }
434
-
435
- /* Search Highlight */
436
- .neiki-highlight {
437
- background: var(--neiki-highlight-color);
438
- padding: 1px 0;
439
- }
440
-
441
- .neiki-highlight-current {
442
- background: #ffc107;
443
- outline: 2px solid #ff9800;
444
- }
445
-
446
- /* ============================================
447
- Tables
448
- ============================================ */
449
- .neiki-content table,
450
- .neiki-table {
451
- width: 100%;
452
- border-collapse: collapse;
453
- margin: 1em 0;
454
- table-layout: fixed;
455
- }
456
-
457
- .neiki-content table td,
458
- .neiki-content table th {
459
- border: 1px solid var(--neiki-table-border);
460
- padding: 8px 12px;
461
- min-width: 50px;
462
- vertical-align: top;
463
- position: relative;
464
- }
465
-
466
- .neiki-content table th {
467
- background: var(--neiki-bg-secondary);
468
- font-weight: 600;
469
- }
470
-
471
- .neiki-content table td:hover,
472
- .neiki-content table th:hover {
473
- background: var(--neiki-bg-hover);
474
- }
475
-
476
- .neiki-content table td.neiki-cell-selected,
477
- .neiki-content table th.neiki-cell-selected {
478
- background: var(--neiki-selection-bg);
479
- }
480
-
481
- /* Table Resize Handle */
482
- .neiki-table-resize-handle {
483
- position: absolute;
484
- top: 0;
485
- right: -3px;
486
- width: 6px;
487
- height: 100%;
488
- cursor: col-resize;
489
- z-index: 10;
490
- }
491
-
492
- .neiki-table-resize-handle:hover {
493
- background: var(--neiki-accent-color);
494
- }
495
-
496
- /* ============================================
497
- Status Bar
498
- ============================================ */
499
- .neiki-statusbar {
500
- display: flex;
501
- justify-content: space-between;
502
- align-items: center;
503
- padding: 6px 12px;
504
- background: var(--neiki-statusbar-bg);
505
- border-top: 1px solid var(--neiki-border-color);
506
- font-size: 12px;
507
- color: var(--neiki-text-muted);
508
- }
509
-
510
- .neiki-statusbar-left,
511
- .neiki-statusbar-right {
512
- display: flex;
513
- align-items: center;
514
- gap: 16px;
515
- }
516
-
517
- .neiki-statusbar-item {
518
- display: flex;
519
- align-items: center;
520
- gap: 4px;
521
- }
522
-
523
- .neiki-statusbar-block {
524
- font-family: 'Consolas', 'Monaco', monospace;
525
- font-size: 11px;
526
- padding: 2px 6px;
527
- background: var(--neiki-bg-tertiary);
528
- border-radius: 3px;
529
- color: var(--neiki-accent-color);
530
- font-weight: 600;
531
- border: 1px solid var(--neiki-border-color);
532
- }
533
-
534
- /* ============================================
535
- Dropdowns & Popups
536
- ============================================ */
537
- .neiki-dropdown {
538
- position: absolute;
539
- top: 100%;
540
- left: 0;
541
- z-index: 1000;
542
- min-width: 180px;
543
- background: var(--neiki-bg-primary);
544
- border: 1px solid var(--neiki-border-color);
545
- border-radius: 6px;
546
- box-shadow: var(--neiki-shadow-lg);
547
- padding: 4px;
548
- margin-top: 4px;
549
- }
550
-
551
- /* Remove the .show requirement - JS adds/removes element directly */
552
-
553
- .neiki-dropdown-item {
554
- display: flex;
555
- align-items: center;
556
- gap: 6px;
557
- padding: 7px 10px;
558
- border-radius: 4px;
559
- cursor: pointer;
560
- color: var(--neiki-text-primary);
561
- font-size: 13px;
562
- transition: background 0.1s;
563
- }
564
-
565
- .neiki-dropdown-item:hover {
566
- background: var(--neiki-bg-hover);
567
- }
568
-
569
- .neiki-dropdown-item.active {
570
- background: var(--neiki-bg-active);
571
- color: var(--neiki-accent-color);
572
- }
573
-
574
- .neiki-dropdown-divider {
575
- height: 1px;
576
- background: var(--neiki-border-color);
577
- margin: 4px 0;
578
- }
579
-
580
- /* ============================================
581
- Color Picker
582
- ============================================ */
583
- .neiki-color-picker {
584
- position: absolute;
585
- top: 100%;
586
- left: 0;
587
- z-index: 1000;
588
- background: var(--neiki-bg-primary);
589
- border: 1px solid var(--neiki-border-color);
590
- border-radius: 8px;
591
- box-shadow: var(--neiki-shadow-lg);
592
- padding: 8px;
593
- margin-top: 4px;
594
- display: flex;
595
- flex-direction: column;
596
- gap: 6px;
597
- }
598
-
599
- .neiki-color-grid {
600
- display: grid;
601
- grid-template-columns: repeat(10, 1fr);
602
- gap: 2px;
603
- }
604
-
605
- .neiki-color-custom {
606
- display: flex;
607
- align-items: center;
608
- gap: 6px;
609
- padding-top: 6px;
610
- border-top: 1px solid var(--neiki-border-color);
611
- }
612
-
613
- .neiki-color-custom-input {
614
- -webkit-appearance: none;
615
- -moz-appearance: none;
616
- appearance: none;
617
- width: 28px;
618
- height: 28px;
619
- border: 1px solid var(--neiki-border-color);
620
- border-radius: 4px;
621
- padding: 2px;
622
- cursor: pointer;
623
- background: transparent;
624
- }
625
-
626
- .neiki-color-custom-input::-webkit-color-swatch-wrapper {
627
- padding: 0;
628
- }
629
-
630
- .neiki-color-custom-input::-webkit-color-swatch {
631
- border: none;
632
- border-radius: 2px;
633
- }
634
-
635
- .neiki-color-custom-input::-moz-color-swatch {
636
- border: none;
637
- border-radius: 2px;
638
- }
639
-
640
- .neiki-color-hex-input {
641
- flex: 1;
642
- height: 28px;
643
- padding: 0 8px;
644
- border: 1px solid var(--neiki-border-color);
645
- border-radius: 4px;
646
- font-size: 12px;
647
- font-family: monospace;
648
- background: var(--neiki-bg-secondary);
649
- color: var(--neiki-text-primary);
650
- outline: none;
651
- }
652
-
653
- .neiki-color-hex-input:focus {
654
- border-color: var(--neiki-accent-color);
655
- box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.15);
656
- }
657
-
658
- .neiki-color-apply-btn {
659
- height: 28px;
660
- padding: 0 10px;
661
- border: none;
662
- border-radius: 4px;
663
- font-size: 12px;
664
- font-weight: 500;
665
- background: var(--neiki-accent-color);
666
- color: #fff;
667
- cursor: pointer;
668
- transition: background 0.15s;
669
- }
670
-
671
- .neiki-color-apply-btn:hover {
672
- background: var(--neiki-accent-hover);
673
- }
674
-
675
- .neiki-color-swatch {
676
- width: 22px;
677
- height: 22px;
678
- border-radius: 3px;
679
- cursor: pointer;
680
- border: 1px solid var(--neiki-border-color);
681
- transition: transform 0.1s;
682
- }
683
-
684
- .neiki-color-swatch:hover {
685
- transform: scale(1.2);
686
- z-index: 1;
687
- }
688
-
689
- .neiki-color-swatch.neiki-color-reset {
690
- background: white;
691
- position: relative;
692
- overflow: hidden;
693
- border: 1px solid #ccc;
694
- }
695
-
696
- .neiki-color-swatch.neiki-color-reset::after {
697
- content: '';
698
- position: absolute;
699
- top: 50%;
700
- left: -2px;
701
- right: -2px;
702
- height: 2px;
703
- background: #e53935;
704
- transform: rotate(-45deg);
705
- transform-origin: center;
706
- pointer-events: none;
707
- }
708
-
709
- .neiki-color-picker-label {
710
- font-size: 11px;
711
- font-weight: 600;
712
- color: var(--neiki-text-muted);
713
- text-transform: uppercase;
714
- margin-bottom: 8px;
715
- }
716
-
717
- /* Emoji Picker */
718
- .neiki-emoji-picker {
719
- position: absolute;
720
- top: 100%;
721
- left: 0;
722
- z-index: 1000;
723
- width: 280px;
724
- max-width: calc(100vw - 16px);
725
- max-height: 250px;
726
- overflow-y: auto;
727
- background: var(--neiki-bg-primary);
728
- border: 1px solid var(--neiki-border-color);
729
- border-radius: 8px;
730
- box-shadow: var(--neiki-shadow-lg);
731
- padding: 8px;
732
- margin-top: 4px;
733
- display: grid;
734
- grid-template-columns: repeat(10, 1fr);
735
- gap: 2px;
736
- }
737
-
738
- .neiki-emoji-item {
739
- display: flex;
740
- align-items: center;
741
- justify-content: center;
742
- width: 24px;
743
- height: 24px;
744
- font-size: 18px;
745
- cursor: pointer;
746
- border-radius: 4px;
747
- transition: background 0.15s, transform 0.1s;
748
- }
749
-
750
- .neiki-emoji-item:hover {
751
- background: var(--neiki-bg-hover);
752
- transform: scale(1.2);
753
- }
754
-
755
- /* Special Characters Picker */
756
- .neiki-special-picker {
757
- position: absolute;
758
- top: 100%;
759
- left: 0;
760
- z-index: 1000;
761
- width: 320px;
762
- max-width: calc(100vw - 16px);
763
- max-height: 280px;
764
- overflow-y: auto;
765
- background: var(--neiki-bg-primary);
766
- border: 1px solid var(--neiki-border-color);
767
- border-radius: 8px;
768
- box-shadow: var(--neiki-shadow-lg);
769
- padding: 8px;
770
- margin-top: 4px;
771
- display: grid;
772
- grid-template-columns: repeat(8, 1fr);
773
- gap: 4px;
774
- }
775
-
776
- .neiki-special-item {
777
- display: flex;
778
- align-items: center;
779
- justify-content: center;
780
- width: 32px;
781
- height: 32px;
782
- font-size: 18px;
783
- cursor: pointer;
784
- border-radius: 4px;
785
- border: 1px solid var(--neiki-border-color);
786
- background: var(--neiki-bg-secondary);
787
- transition: all 0.15s;
788
- }
789
-
790
- .neiki-special-item:hover {
791
- background: var(--neiki-accent-color);
792
- color: white;
793
- border-color: var(--neiki-accent-color);
794
- transform: scale(1.1);
795
- }
796
-
797
- /* Find & Replace Highlights */
798
- .neiki-highlight-find {
799
- background: #ffeb3b;
800
- padding: 1px 0;
801
- border-radius: 2px;
802
- }
803
-
804
- .neiki-highlight-current {
805
- background: #ff9800;
806
- outline: 2px solid #e65100;
807
- }
808
-
809
- .neiki-color-presets {
810
- display: grid;
811
- grid-template-columns: repeat(5, 1fr);
812
- gap: 6px;
813
- margin-bottom: 12px;
814
- }
815
-
816
- .neiki-color-preset {
817
- width: 32px;
818
- height: 32px;
819
- border-radius: 4px;
820
- border: 2px solid transparent;
821
- cursor: pointer;
822
- transition: transform 0.1s, border-color 0.1s;
823
- }
824
-
825
- .neiki-color-preset:hover {
826
- transform: scale(1.1);
827
- }
828
-
829
- .neiki-color-preset.active {
830
- border-color: var(--neiki-accent-color);
831
- }
832
-
833
- .neiki-color-preset.neiki-color-reset {
834
- background: linear-gradient(45deg, #fff 45%, #ff0000 45%, #ff0000 55%, #fff 55%);
835
- border: 1px solid var(--neiki-border-color);
836
- }
837
-
838
- .neiki-color-custom {
839
- display: flex;
840
- align-items: center;
841
- gap: 8px;
842
- padding-top: 8px;
843
- border-top: 1px solid var(--neiki-border-color);
844
- }
845
-
846
- .neiki-color-custom input[type="color"] {
847
- width: 40px;
848
- height: 32px;
849
- padding: 0;
850
- border: 1px solid var(--neiki-border-color);
851
- border-radius: 4px;
852
- cursor: pointer;
853
- }
854
-
855
- .neiki-color-custom input[type="text"] {
856
- flex: 1;
857
- height: 32px;
858
- padding: 0 8px;
859
- border: 1px solid var(--neiki-border-color);
860
- border-radius: 4px;
861
- background: var(--neiki-bg-primary);
862
- color: var(--neiki-text-primary);
863
- font-size: 12px;
864
- font-family: monospace;
865
- }
866
-
867
- /* ============================================
868
- Table Picker
869
- ============================================ */
870
- .neiki-table-picker {
871
- position: absolute;
872
- top: 100%;
873
- left: 0;
874
- z-index: 1000;
875
- background: var(--neiki-bg-primary);
876
- border: 1px solid var(--neiki-border-color);
877
- border-radius: 8px;
878
- box-shadow: var(--neiki-shadow-lg);
879
- padding: 12px;
880
- display: none;
881
- }
882
-
883
- .neiki-table-picker.show {
884
- display: block;
885
- }
886
-
887
- .neiki-table-picker-label {
888
- font-size: 12px;
889
- color: var(--neiki-text-secondary);
890
- margin-bottom: 8px;
891
- text-align: center;
892
- }
893
-
894
- .neiki-table-picker-grid {
895
- display: grid;
896
- grid-template-columns: repeat(10, 20px);
897
- gap: 2px;
898
- }
899
-
900
- .neiki-table-picker-cell {
901
- width: 20px;
902
- height: 20px;
903
- border: 1px solid var(--neiki-border-color);
904
- border-radius: 2px;
905
- background: var(--neiki-bg-primary);
906
- cursor: pointer;
907
- transition: background 0.1s;
908
- }
909
-
910
- .neiki-table-picker-cell:hover,
911
- .neiki-table-picker-cell.active {
912
- background: var(--neiki-accent-color);
913
- border-color: var(--neiki-accent-color);
914
- }
915
-
916
- /* ============================================
917
- Special Characters Picker (duplicate removed)
918
- ============================================ */
919
- .neiki-special-chars {
920
- position: absolute;
921
- top: 100%;
922
- left: 0;
923
- z-index: 1000;
924
- width: 280px;
925
- max-height: 300px;
926
- background: var(--neiki-bg-primary);
927
- border: 1px solid var(--neiki-border-color);
928
- border-radius: 8px;
929
- box-shadow: var(--neiki-shadow-lg);
930
- display: none;
931
- overflow: hidden;
932
- }
933
-
934
- .neiki-special-chars.show {
935
- display: flex;
936
- flex-direction: column;
937
- }
938
-
939
- .neiki-special-chars-grid {
940
- display: grid;
941
- grid-template-columns: repeat(10, 1fr);
942
- gap: 2px;
943
- padding: 8px;
944
- overflow-y: auto;
945
- }
946
-
947
- .neiki-special-char-item {
948
- display: flex;
949
- align-items: center;
950
- justify-content: center;
951
- width: 24px;
952
- height: 24px;
953
- font-size: 16px;
954
- border-radius: 4px;
955
- cursor: pointer;
956
- transition: background 0.1s;
957
- }
958
-
959
- .neiki-special-char-item:hover {
960
- background: var(--neiki-bg-hover);
961
- }
962
-
963
- /* ============================================
964
- Modals
965
- ============================================ */
966
- .neiki-modal-overlay {
967
- position: fixed;
968
- top: 0;
969
- left: 0;
970
- right: 0;
971
- bottom: 0;
972
- background: var(--neiki-modal-overlay);
973
- z-index: 10000;
974
- display: flex;
975
- align-items: center;
976
- justify-content: center;
977
- opacity: 0;
978
- visibility: hidden;
979
- transition: opacity 0.2s, visibility 0.2s;
980
- }
981
-
982
- .neiki-modal-overlay.active {
983
- opacity: 1;
984
- visibility: visible;
985
- }
986
-
987
- .neiki-modal {
988
- background: var(--neiki-bg-primary);
989
- border-radius: 12px;
990
- box-shadow: var(--neiki-shadow-lg);
991
- width: 100%;
992
- max-width: 440px;
993
- max-height: 90vh;
994
- overflow: hidden;
995
- animation: neiki-modal-in 0.2s ease;
996
- }
997
-
998
- .neiki-modal-wide {
999
- max-width: 520px;
1000
- }
1001
-
1002
- .neiki-modal-header {
1003
- display: flex;
1004
- align-items: center;
1005
- justify-content: space-between;
1006
- padding: 16px 20px;
1007
- border-bottom: 1px solid var(--neiki-border-color);
1008
- }
1009
-
1010
- .neiki-modal-title {
1011
- font-size: 16px;
1012
- font-weight: 600;
1013
- color: var(--neiki-text-primary);
1014
- margin: 0;
1015
- }
1016
-
1017
- .neiki-modal-close {
1018
- width: 32px;
1019
- height: 32px;
1020
- display: flex;
1021
- align-items: center;
1022
- justify-content: center;
1023
- background: transparent;
1024
- border: none;
1025
- border-radius: 4px;
1026
- cursor: pointer;
1027
- color: var(--neiki-text-muted);
1028
- transition: background 0.15s;
1029
- }
1030
-
1031
- .neiki-modal-close:hover {
1032
- background: var(--neiki-bg-hover);
1033
- color: var(--neiki-text-primary);
1034
- }
1035
-
1036
- .neiki-modal-body {
1037
- padding: 20px;
1038
- overflow-y: auto;
1039
- }
1040
-
1041
- .neiki-modal h3,
1042
- .neiki-modal-header h3 {
1043
- color: #000000;
1044
- margin: 0;
1045
- }
1046
-
1047
- .neiki-dark .neiki-modal h3,
1048
- .neiki-dark .neiki-modal-header h3 {
1049
- color: var(--neiki-text-primary);
1050
- }
1051
-
1052
- .neiki-modal-footer {
1053
- display: flex;
1054
- justify-content: flex-end;
1055
- gap: 10px;
1056
- padding: 16px 20px;
1057
- border-top: 1px solid var(--neiki-border-color);
1058
- }
1059
-
1060
- .neiki-modal-footer .neiki-btn {
1061
- width: auto;
1062
- height: 38px;
1063
- padding: 0 16px;
1064
- font-size: 14px;
1065
- font-weight: 500;
1066
- border-radius: 6px;
1067
- }
1068
-
1069
- /* Form Elements */
1070
- .neiki-form-group {
1071
- margin-bottom: 16px;
1072
- }
1073
-
1074
- .neiki-form-group:last-child {
1075
- margin-bottom: 0;
1076
- }
1077
-
1078
- .neiki-form-label {
1079
- display: block;
1080
- margin-bottom: 6px;
1081
- font-size: 13px;
1082
- font-weight: 500;
1083
- color: var(--neiki-text-secondary);
1084
- }
1085
-
1086
- .neiki-form-input,
1087
- .neiki-input {
1088
- width: 100%;
1089
- height: 40px;
1090
- padding: 0 12px;
1091
- border: 1px solid var(--neiki-border-color);
1092
- border-radius: 6px;
1093
- background: var(--neiki-bg-primary);
1094
- color: var(--neiki-text-primary);
1095
- font-size: 14px;
1096
- transition: border-color 0.15s;
1097
- }
1098
-
1099
- .neiki-form-input:focus,
1100
- .neiki-input:focus {
1101
- outline: none;
1102
- border-color: var(--neiki-accent-color);
1103
- box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.15);
1104
- }
1105
-
1106
- .neiki-form-input::placeholder,
1107
- .neiki-input::placeholder {
1108
- color: var(--neiki-text-muted);
1109
- }
1110
-
1111
- .neiki-input[type="file"] {
1112
- display: flex;
1113
- align-items: center;
1114
- padding: 0 12px;
1115
- line-height: 40px;
1116
- cursor: pointer;
1117
- }
1118
-
1119
- .neiki-form-row {
1120
- display: flex;
1121
- gap: 16px;
1122
- }
1123
-
1124
- .neiki-form-divider {
1125
- display: flex;
1126
- align-items: center;
1127
- margin: 16px 0;
1128
- text-align: center;
1129
- position: relative;
1130
- }
1131
-
1132
- .neiki-form-divider::before {
1133
- content: '';
1134
- flex: 1;
1135
- height: 1px;
1136
- background: var(--neiki-border-color);
1137
- margin-right: 12px;
1138
- }
1139
-
1140
- .neiki-form-divider::after {
1141
- content: '';
1142
- flex: 1;
1143
- height: 1px;
1144
- background: var(--neiki-border-color);
1145
- margin-left: 12px;
1146
- }
1147
-
1148
- .neiki-form-divider span {
1149
- color: var(--neiki-text-muted);
1150
- font-size: 12px;
1151
- font-weight: 500;
1152
- text-transform: uppercase;
1153
- }
1154
-
1155
- .neiki-form-group label {
1156
- display: block;
1157
- margin-bottom: 6px;
1158
- font-size: 13px;
1159
- font-weight: 500;
1160
- color: var(--neiki-text-secondary);
1161
- }
1162
-
1163
- .neiki-form-textarea {
1164
- width: 100%;
1165
- min-height: 120px;
1166
- padding: 12px;
1167
- border: 1px solid var(--neiki-border-color);
1168
- border-radius: 6px;
1169
- background: var(--neiki-bg-primary);
1170
- color: var(--neiki-text-primary);
1171
- font-size: 14px;
1172
- font-family: inherit;
1173
- resize: vertical;
1174
- transition: border-color 0.15s;
1175
- }
1176
-
1177
- .neiki-form-textarea:focus {
1178
- outline: none;
1179
- border-color: var(--neiki-accent-color);
1180
- box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.15);
1181
- }
1182
-
1183
- /* Buttons */
1184
- .neiki-button {
1185
- display: inline-flex;
1186
- align-items: center;
1187
- justify-content: center;
1188
- gap: 6px;
1189
- height: 38px;
1190
- padding: 0 16px;
1191
- border: 1px solid transparent;
1192
- border-radius: 6px;
1193
- font-size: 14px;
1194
- font-weight: 500;
1195
- cursor: pointer;
1196
- transition: all 0.15s;
1197
- }
1198
-
1199
- .neiki-button-primary,
1200
- .neiki-btn-primary {
1201
- background: var(--neiki-accent-color);
1202
- color: #fff;
1203
- }
1204
-
1205
- .neiki-button-primary:hover,
1206
- .neiki-btn-primary:hover {
1207
- background: var(--neiki-accent-hover);
1208
- }
1209
-
1210
- .neiki-button-secondary,
1211
- .neiki-btn-secondary {
1212
- background: var(--neiki-bg-secondary);
1213
- color: var(--neiki-text-primary);
1214
- border-color: var(--neiki-border-color);
1215
- }
1216
-
1217
- .neiki-btn-primary,
1218
- .neiki-btn-secondary {
1219
- display: inline-flex;
1220
- align-items: center;
1221
- justify-content: center;
1222
- height: 38px;
1223
- padding: 0 16px;
1224
- border: 1px solid transparent;
1225
- border-radius: 6px;
1226
- font-size: 14px;
1227
- font-weight: 500;
1228
- cursor: pointer;
1229
- transition: all 0.15s;
1230
- }
1231
-
1232
- .neiki-btn-secondary {
1233
- border-color: var(--neiki-border-color);
1234
- }
1235
-
1236
- .neiki-btn-secondary:hover {
1237
- background: var(--neiki-bg-hover);
1238
- }
1239
-
1240
- .neiki-button-secondary:hover {
1241
- background: var(--neiki-bg-hover);
1242
- }
1243
-
1244
- .neiki-button-danger {
1245
- background: var(--neiki-danger-color);
1246
- color: #fff;
1247
- }
1248
-
1249
- .neiki-button-danger:hover {
1250
- opacity: 0.9;
1251
- }
1252
-
1253
- /* ============================================
1254
- Find & Replace Panel
1255
- ============================================ */
1256
- .neiki-find-replace {
1257
- position: absolute;
1258
- top: 0;
1259
- right: 0;
1260
- z-index: 100;
1261
- width: 360px;
1262
- background: var(--neiki-bg-primary);
1263
- border: 1px solid var(--neiki-border-color);
1264
- border-radius: 0 0 0 8px;
1265
- box-shadow: var(--neiki-shadow-lg);
1266
- display: none;
1267
- }
1268
-
1269
- .neiki-find-replace.show {
1270
- display: block;
1271
- }
1272
-
1273
- .neiki-find-replace-header {
1274
- display: flex;
1275
- align-items: center;
1276
- justify-content: space-between;
1277
- padding: 10px 12px;
1278
- border-bottom: 1px solid var(--neiki-border-color);
1279
- }
1280
-
1281
- .neiki-find-replace-title {
1282
- font-size: 13px;
1283
- font-weight: 600;
1284
- color: var(--neiki-text-primary);
1285
- }
1286
-
1287
- .neiki-find-replace-body {
1288
- padding: 12px;
1289
- }
1290
-
1291
- .neiki-find-replace-row {
1292
- display: flex;
1293
- gap: 8px;
1294
- margin-bottom: 10px;
1295
- }
1296
-
1297
- .neiki-find-replace-row:last-child {
1298
- margin-bottom: 0;
1299
- }
1300
-
1301
- .neiki-find-replace-input {
1302
- flex: 1;
1303
- height: 32px;
1304
- padding: 0 10px;
1305
- border: 1px solid var(--neiki-border-color);
1306
- border-radius: 4px;
1307
- background: var(--neiki-bg-primary);
1308
- color: var(--neiki-text-primary);
1309
- font-size: 13px;
1310
- }
1311
-
1312
- .neiki-find-replace-input:focus {
1313
- outline: none;
1314
- border-color: var(--neiki-accent-color);
1315
- }
1316
-
1317
- .neiki-find-replace-options {
1318
- display: flex;
1319
- align-items: center;
1320
- gap: 12px;
1321
- margin-bottom: 10px;
1322
- }
1323
-
1324
- .neiki-find-replace-option {
1325
- display: flex;
1326
- align-items: center;
1327
- gap: 4px;
1328
- font-size: 12px;
1329
- color: var(--neiki-text-secondary);
1330
- cursor: pointer;
1331
- }
1332
-
1333
- .neiki-find-replace-option input {
1334
- accent-color: var(--neiki-accent-color);
1335
- }
1336
-
1337
- .neiki-find-replace-actions {
1338
- display: flex;
1339
- gap: 6px;
1340
- flex-wrap: wrap;
1341
- }
1342
-
1343
- .neiki-find-replace-btn {
1344
- height: 28px;
1345
- padding: 0 10px;
1346
- font-size: 12px;
1347
- border-radius: 4px;
1348
- }
1349
-
1350
- .neiki-find-replace-count {
1351
- font-size: 12px;
1352
- color: var(--neiki-text-muted);
1353
- margin-left: auto;
1354
- }
1355
-
1356
- /* ============================================
1357
- HTML Code View
1358
- ============================================ */
1359
- .neiki-code-view {
1360
- position: absolute;
1361
- top: 0;
1362
- left: 0;
1363
- right: 0;
1364
- bottom: 0;
1365
- z-index: 50;
1366
- background: var(--neiki-bg-primary);
1367
- display: none;
1368
- flex-direction: column;
1369
- }
1370
-
1371
- .neiki-code-view.show {
1372
- display: flex;
1373
- }
1374
-
1375
- .neiki-code-view-header {
1376
- display: flex;
1377
- align-items: center;
1378
- justify-content: space-between;
1379
- padding: 8px 16px;
1380
- background: var(--neiki-bg-secondary);
1381
- border-bottom: 1px solid var(--neiki-border-color);
1382
- flex-shrink: 0;
1383
- }
1384
-
1385
- .neiki-code-view-title {
1386
- font-size: 13px;
1387
- font-weight: 600;
1388
- color: var(--neiki-text-primary);
1389
- }
1390
-
1391
- .neiki-code-view-textarea {
1392
- flex: 1;
1393
- width: 100%;
1394
- padding: 16px;
1395
- border: none;
1396
- background: var(--neiki-bg-primary);
1397
- color: var(--neiki-text-primary);
1398
- font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
1399
- font-size: 13px;
1400
- line-height: 1.5;
1401
- resize: none;
1402
- }
1403
-
1404
- .neiki-code-view-textarea:focus {
1405
- outline: none;
1406
- }
1407
-
1408
- .neiki-code-view-apply {
1409
- width: auto !important;
1410
- padding: 0 12px !important;
1411
- display: inline-flex;
1412
- align-items: center;
1413
- gap: 4px;
1414
- height: 30px;
1415
- font-size: 12px;
1416
- background: var(--neiki-accent-color) !important;
1417
- color: white !important;
1418
- border-radius: 5px;
1419
- }
1420
-
1421
- .neiki-code-view-apply:hover {
1422
- background: var(--neiki-accent-hover) !important;
1423
- color: white !important;
1424
- }
1425
-
1426
- .neiki-code-view-apply svg {
1427
- width: 14px !important;
1428
- height: 14px !important;
1429
- }
1430
-
1431
- /* ============================================
1432
- Context Menu
1433
- ============================================ */
1434
- .neiki-context-menu {
1435
- position: fixed;
1436
- z-index: 10001;
1437
- min-width: 180px;
1438
- background: var(--neiki-bg-primary);
1439
- border: 1px solid var(--neiki-border-color);
1440
- border-radius: 8px;
1441
- box-shadow: var(--neiki-shadow-lg);
1442
- padding: 4px;
1443
- display: none;
1444
- }
1445
-
1446
- .neiki-context-menu.show {
1447
- display: block;
1448
- }
1449
-
1450
- .neiki-context-item,
1451
- .neiki-context-menu-item {
1452
- display: flex;
1453
- align-items: center;
1454
- gap: 10px;
1455
- padding: 8px 12px;
1456
- border-radius: 4px;
1457
- cursor: pointer;
1458
- color: var(--neiki-text-primary);
1459
- font-size: 13px;
1460
- transition: background 0.1s;
1461
- }
1462
-
1463
- .neiki-context-item:hover,
1464
- .neiki-context-menu-item:hover {
1465
- background: var(--neiki-bg-hover);
1466
- }
1467
-
1468
- .neiki-context-item.neiki-context-danger,
1469
- .neiki-context-menu-item.danger {
1470
- color: var(--neiki-danger-color);
1471
- }
1472
-
1473
- .neiki-context-item svg,
1474
- .neiki-context-menu-item svg {
1475
- width: 16px;
1476
- height: 16px;
1477
- fill: currentColor;
1478
- }
1479
-
1480
- .neiki-context-divider,
1481
- .neiki-context-menu-divider {
1482
- height: 1px;
1483
- background: var(--neiki-border-color);
1484
- margin: 4px 0;
1485
- }
1486
-
1487
- /* ============================================
1488
- Floating Selection Toolbar
1489
- ============================================ */
1490
- .neiki-floating-toolbar {
1491
- position: absolute;
1492
- z-index: 1000;
1493
- display: none;
1494
- background: var(--neiki-bg-primary);
1495
- border: 1px solid var(--neiki-border-color);
1496
- border-radius: 8px;
1497
- box-shadow: var(--neiki-shadow-lg);
1498
- padding: 4px;
1499
- }
1500
-
1501
- .neiki-floating-toolbar.show {
1502
- display: flex;
1503
- align-items: center;
1504
- gap: 2px;
1505
- }
1506
-
1507
- .neiki-floating-btn {
1508
- width: 32px;
1509
- height: 32px;
1510
- border: none;
1511
- background: var(--neiki-bg-primary);
1512
- color: var(--neiki-text-primary);
1513
- border-radius: 6px;
1514
- cursor: pointer;
1515
- display: flex;
1516
- align-items: center;
1517
- justify-content: center;
1518
- transition: all 0.15s;
1519
- }
1520
-
1521
- .neiki-floating-btn:hover {
1522
- background: var(--neiki-bg-hover);
1523
- color: var(--neiki-accent-color);
1524
- }
1525
-
1526
- .neiki-floating-btn:active {
1527
- background: var(--neiki-bg-active);
1528
- }
1529
-
1530
- .neiki-floating-btn svg {
1531
- width: 16px;
1532
- height: 16px;
1533
- fill: currentColor;
1534
- }
1535
-
1536
- .neiki-floating-toolbar .neiki-btn {
1537
- width: 28px;
1538
- height: 28px;
1539
- }
1540
-
1541
- .neiki-floating-toolbar .neiki-btn svg {
1542
- width: 14px;
1543
- height: 14px;
1544
- }
1545
-
1546
- .neiki-floating-divider {
1547
- width: 1px;
1548
- height: 20px;
1549
- background: var(--neiki-border-color);
1550
- margin: 0 2px;
1551
- }
1552
-
1553
- .neiki-floating-move-btn svg {
1554
- width: 16px;
1555
- height: 16px;
1556
- }
1557
-
1558
- /* ============================================
1559
- Tooltips
1560
- ============================================ */
1561
- [data-tooltip] {
1562
- position: relative;
1563
- }
1564
-
1565
- [data-tooltip]::after {
1566
- content: attr(data-tooltip);
1567
- position: absolute;
1568
- bottom: 100%;
1569
- left: 50%;
1570
- transform: translateX(-50%);
1571
- padding: 6px 10px;
1572
- background: var(--neiki-text-primary);
1573
- color: var(--neiki-bg-primary);
1574
- font-size: 11px;
1575
- font-weight: 500;
1576
- white-space: nowrap;
1577
- border-radius: 4px;
1578
- opacity: 0;
1579
- visibility: hidden;
1580
- transition: opacity 0.15s, visibility 0.15s;
1581
- pointer-events: none;
1582
- z-index: 10002;
1583
- margin-bottom: 6px;
1584
- }
1585
-
1586
- [data-tooltip]:hover::after {
1587
- opacity: 1;
1588
- visibility: visible;
1589
- }
1590
-
1591
- /* ============================================
1592
- Drag & Drop Overlay
1593
- ============================================ */
1594
- .neiki-drop-overlay {
1595
- position: absolute;
1596
- top: 0;
1597
- left: 0;
1598
- right: 0;
1599
- bottom: 0;
1600
- background: rgba(13, 110, 253, 0.1);
1601
- border: 3px dashed var(--neiki-accent-color);
1602
- border-radius: 8px;
1603
- display: none;
1604
- align-items: center;
1605
- justify-content: center;
1606
- z-index: 100;
1607
- pointer-events: none;
1608
- }
1609
-
1610
- .neiki-drop-overlay.show {
1611
- display: flex;
1612
- }
1613
-
1614
- .neiki-drop-overlay-text {
1615
- font-size: 18px;
1616
- font-weight: 600;
1617
- color: var(--neiki-accent-color);
1618
- }
1619
-
1620
- /* ============================================
1621
- Image Resize Handles
1622
- ============================================ */
1623
- .neiki-img-resizable {
1624
- display: inline-block;
1625
- position: relative;
1626
- outline: 2px solid var(--neiki-accent-color);
1627
- outline-offset: 2px;
1628
- border-radius: 4px;
1629
- line-height: 0;
1630
- }
1631
-
1632
- .neiki-img-resizable img {
1633
- display: block;
1634
- max-width: 100%;
1635
- }
1636
-
1637
- .neiki-img-resize-handle {
1638
- position: absolute;
1639
- width: 12px;
1640
- height: 12px;
1641
- background: var(--neiki-accent-color);
1642
- border: 2px solid #fff;
1643
- border-radius: 2px;
1644
- z-index: 10;
1645
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
1646
- }
1647
-
1648
- .neiki-img-resize-handle.nw { top: -6px; left: -6px; cursor: nw-resize; }
1649
- .neiki-img-resize-handle.ne { top: -6px; right: -6px; cursor: ne-resize; }
1650
- .neiki-img-resize-handle.sw { bottom: -6px; left: -6px; cursor: sw-resize; }
1651
- .neiki-img-resize-handle.se { bottom: -6px; right: -6px; cursor: se-resize; }
1652
-
1653
- .neiki-img-size-label {
1654
- position: absolute;
1655
- bottom: -32px;
1656
- left: 50%;
1657
- transform: translateX(-50%);
1658
- background: var(--neiki-text-primary);
1659
- color: var(--neiki-bg-primary);
1660
- font-size: 13px;
1661
- line-height: 1.4;
1662
- font-weight: 600;
1663
- padding: 4px 12px;
1664
- border-radius: 6px;
1665
- white-space: nowrap;
1666
- pointer-events: none;
1667
- z-index: 10;
1668
- opacity: 0.9;
1669
- }
1670
-
1671
- /* Touch-friendly resize handles */
1672
- @media (pointer: coarse) {
1673
- .neiki-img-resize-handle {
1674
- width: 20px;
1675
- height: 20px;
1676
- }
1677
- .neiki-img-resize-handle.nw { top: -10px; left: -10px; }
1678
- .neiki-img-resize-handle.ne { top: -10px; right: -10px; }
1679
- .neiki-img-resize-handle.sw { bottom: -10px; left: -10px; }
1680
- .neiki-img-resize-handle.se { bottom: -10px; right: -10px; }
1681
- }
1682
-
1683
- /* ============================================
1684
- Table Column Resize Handle
1685
- ============================================ */
1686
- .neiki-table-col-resize-handle {
1687
- position: absolute;
1688
- width: 6px;
1689
- cursor: col-resize;
1690
- z-index: 10;
1691
- background: transparent;
1692
- transition: background 0.1s;
1693
- }
1694
-
1695
- .neiki-table-col-resize-handle:hover,
1696
- .neiki-table-col-resize-handle:active {
1697
- background: var(--neiki-accent-color);
1698
- opacity: 0.6;
1699
- border-radius: 3px;
1700
- }
1701
-
1702
- /* ============================================
1703
- Block Drag & Drop
1704
- ============================================ */
1705
- .neiki-block-grip {
1706
- position: absolute;
1707
- width: 22px;
1708
- height: 22px;
1709
- display: flex;
1710
- align-items: center;
1711
- justify-content: center;
1712
- cursor: grab;
1713
- color: var(--neiki-text-muted);
1714
- opacity: 0;
1715
- transition: opacity 0.15s, color 0.15s;
1716
- border-radius: 4px;
1717
- z-index: 5;
1718
- user-select: none;
1719
- }
1720
-
1721
- .neiki-content:hover .neiki-block-grip {
1722
- opacity: 0.5;
1723
- }
1724
-
1725
- .neiki-block-grip:hover {
1726
- opacity: 1 !important;
1727
- color: var(--neiki-text-primary);
1728
- background: var(--neiki-bg-hover);
1729
- }
1730
-
1731
- .neiki-block-grip:active {
1732
- cursor: grabbing;
1733
- }
1734
-
1735
- .neiki-block-grip svg {
1736
- width: 14px;
1737
- height: 14px;
1738
- fill: currentColor;
1739
- pointer-events: none;
1740
- }
1741
-
1742
- .neiki-block-ghost {
1743
- position: fixed;
1744
- z-index: 100000;
1745
- pointer-events: none;
1746
- opacity: 0.7;
1747
- background: var(--neiki-bg-primary);
1748
- border: 2px solid var(--neiki-accent-color);
1749
- border-radius: 6px;
1750
- padding: 8px 12px;
1751
- box-shadow: var(--neiki-shadow-lg);
1752
- max-height: 120px;
1753
- overflow: hidden;
1754
- }
1755
-
1756
- .neiki-block-placeholder {
1757
- border: 2px dashed var(--neiki-accent-color);
1758
- border-radius: 6px;
1759
- background: rgba(13, 110, 253, 0.05);
1760
- margin: 2px 0;
1761
- transition: height 0.15s ease;
1762
- }
1763
-
1764
- /* ============================================
1765
- Print Styles
1766
- ============================================ */
1767
- @media print {
1768
- .neiki-editor {
1769
- border: none !important;
1770
- box-shadow: none !important;
1771
- }
1772
-
1773
- .neiki-toolbar,
1774
- .neiki-statusbar,
1775
- .neiki-floating-toolbar,
1776
- .neiki-find-replace,
1777
- .neiki-code-view-header,
1778
- .neiki-block-grip,
1779
- .neiki-img-resize-handle,
1780
- .neiki-img-size-label,
1781
- .neiki-table-col-resize-handle {
1782
- display: none !important;
1783
- }
1784
-
1785
- .neiki-content {
1786
- padding: 0 !important;
1787
- overflow: visible !important;
1788
- }
1789
-
1790
- .neiki-editor-wrapper {
1791
- overflow: visible !important;
1792
- }
1793
- }
1794
-
1795
- /* ============================================
1796
- Responsive Adjustments
1797
- ============================================ */
1798
- @media (max-width: 768px) {
1799
- .neiki-toolbar {
1800
- padding: 4px;
1801
- gap: 1px;
1802
- }
1803
-
1804
- .neiki-toolbar-group {
1805
- padding: 0 2px;
1806
- }
1807
-
1808
- .neiki-toolbar-group:not(:last-child) {
1809
- padding-right: 4px;
1810
- margin-right: 2px;
1811
- }
1812
-
1813
- .neiki-btn {
1814
- width: 28px;
1815
- height: 28px;
1816
- }
1817
-
1818
- .neiki-btn svg {
1819
- width: 16px;
1820
- height: 16px;
1821
- }
1822
-
1823
- .neiki-select {
1824
- height: 28px;
1825
- min-width: 80px;
1826
- font-size: 12px;
1827
- padding: 0 24px 0 8px;
1828
- }
1829
-
1830
- .neiki-content {
1831
- padding: 12px 16px;
1832
- }
1833
-
1834
- .neiki-statusbar {
1835
- padding: 4px 8px;
1836
- font-size: 11px;
1837
- }
1838
-
1839
- .neiki-modal {
1840
- width: 95%;
1841
- max-width: none;
1842
- margin: 10px;
1843
- }
1844
-
1845
- .neiki-find-replace {
1846
- width: 100%;
1847
- border-radius: 0;
1848
- }
1849
-
1850
- .neiki-checkbox-wrapper {
1851
- padding: 0 4px;
1852
- font-size: 11px;
1853
- }
1854
-
1855
- .neiki-color-picker {
1856
- left: auto;
1857
- right: 0;
1858
- }
1859
- }
1860
-
1861
- @media (max-width: 480px) {
1862
- .neiki-toolbar-group:not(:last-child) {
1863
- border-right: none;
1864
- padding-right: 2px;
1865
- margin-right: 0;
1866
- }
1867
-
1868
- .neiki-select {
1869
- min-width: 60px;
1870
- }
1871
-
1872
- .neiki-statusbar-left,
1873
- .neiki-statusbar-right {
1874
- gap: 8px;
1875
- }
1876
- }
1877
-
1878
- /* ============================================
1879
- Animations
1880
- ============================================ */
1881
- @keyframes neiki-fade-in {
1882
- from {
1883
- opacity: 0;
1884
- transform: translateY(-10px);
1885
- }
1886
- to {
1887
- opacity: 1;
1888
- transform: translateY(0);
1889
- }
1890
- }
1891
-
1892
- .neiki-dropdown.show,
1893
- .neiki-color-picker.show,
1894
- .neiki-table-picker.show,
1895
- .neiki-emoji-picker.show,
1896
- .neiki-special-chars.show {
1897
- animation: neiki-fade-in 0.15s ease;
1898
- }
1899
-
1900
- @keyframes neiki-modal-in {
1901
- from {
1902
- opacity: 0;
1903
- transform: scale(0.95);
1904
- }
1905
- to {
1906
- opacity: 1;
1907
- transform: scale(1);
1908
- }
1909
- }
1910
-
1911
- .neiki-modal-overlay.show .neiki-modal {
1912
- animation: neiki-modal-in 0.2s ease;
1913
- }
1914
-
1915
- /* ============================================
1916
- Font Size Widget
1917
- ============================================ */
1918
- .neiki-fontsize-widget {
1919
- display: inline-flex;
1920
- align-items: center;
1921
- position: relative;
1922
- height: 32px;
1923
- border: 1px solid var(--neiki-border-color);
1924
- border-radius: 4px;
1925
- overflow: visible;
1926
- background: var(--neiki-bg-primary);
1927
- }
1928
-
1929
- .neiki-fontsize-btn {
1930
- display: flex;
1931
- align-items: center;
1932
- justify-content: center;
1933
- width: 26px;
1934
- height: 30px;
1935
- background: transparent;
1936
- border: none;
1937
- cursor: pointer;
1938
- color: var(--neiki-text-secondary);
1939
- transition: background 0.15s, color 0.15s;
1940
- padding: 0;
1941
- }
1942
-
1943
- .neiki-fontsize-btn:hover {
1944
- background: var(--neiki-bg-hover);
1945
- color: var(--neiki-text-primary);
1946
- }
1947
-
1948
- .neiki-fontsize-input {
1949
- width: 38px;
1950
- height: 30px;
1951
- text-align: center;
1952
- border: none;
1953
- border-left: 1px solid var(--neiki-border-color);
1954
- border-right: 1px solid var(--neiki-border-color);
1955
- background: var(--neiki-bg-primary);
1956
- color: var(--neiki-text-primary);
1957
- font-size: 13px;
1958
- outline: none;
1959
- -moz-appearance: textfield;
1960
- appearance: textfield;
1961
- padding: 0;
1962
- }
1963
-
1964
- .neiki-fontsize-input::-webkit-outer-spin-button,
1965
- .neiki-fontsize-input::-webkit-inner-spin-button {
1966
- -webkit-appearance: none;
1967
- margin: 0;
1968
- }
1969
-
1970
- .neiki-fontsize-dropdown {
1971
- display: none;
1972
- position: absolute;
1973
- top: 100%;
1974
- left: 0;
1975
- z-index: 1000;
1976
- min-width: 70px;
1977
- max-height: 240px;
1978
- overflow-y: auto;
1979
- background: var(--neiki-bg-primary);
1980
- border: 1px solid var(--neiki-border-color);
1981
- border-radius: 6px;
1982
- box-shadow: var(--neiki-shadow-lg);
1983
- padding: 4px;
1984
- margin-top: 4px;
1985
- }
1986
-
1987
- .neiki-fontsize-dropdown.show {
1988
- display: block;
1989
- }
1990
-
1991
- .neiki-fontsize-dropdown-item {
1992
- padding: 6px 12px;
1993
- font-size: 13px;
1994
- cursor: pointer;
1995
- border-radius: 4px;
1996
- color: var(--neiki-text-primary);
1997
- text-align: center;
1998
- transition: background 0.1s;
1999
- }
2000
-
2001
- .neiki-fontsize-dropdown-item:hover {
2002
- background: var(--neiki-bg-hover);
2003
- }
2004
-
2005
- /* ============================================
2006
- Insert Dropdown Button
2007
- ============================================ */
2008
- .neiki-insert-dropdown-btn {
2009
- width: auto !important;
2010
- padding: 0 8px !important;
2011
- gap: 4px;
2012
- font-size: 13px;
2013
- font-weight: 500;
2014
- }
2015
-
2016
- .neiki-insert-label {
2017
- font-size: 13px;
2018
- pointer-events: none;
2019
- }
2020
-
2021
- .neiki-chevron {
2022
- display: inline-flex;
2023
- pointer-events: none;
2024
- }
2025
-
2026
- .neiki-chevron svg {
2027
- width: 14px;
2028
- height: 14px;
2029
- }
2030
-
2031
- .neiki-insert-dropdown {
2032
- display: none;
2033
- position: absolute;
2034
- top: 100%;
2035
- left: 0;
2036
- z-index: 1000;
2037
- min-width: 160px;
2038
- max-width: calc(100vw - 16px);
2039
- background: var(--neiki-bg-primary);
2040
- border: 1px solid var(--neiki-border-color);
2041
- border-radius: 6px;
2042
- box-shadow: var(--neiki-shadow-lg);
2043
- padding: 4px;
2044
- margin-top: 4px;
2045
- }
2046
-
2047
- .neiki-insert-dropdown.show {
2048
- display: block;
2049
- animation: neiki-fade-in 0.15s ease;
2050
- }
2051
-
2052
- /* ============================================
2053
- More Menu (⋯) Dropdown
2054
- ============================================ */
2055
- .neiki-more-btn {
2056
- position: relative;
2057
- }
2058
-
2059
- .neiki-more-dropdown {
2060
- display: none;
2061
- position: absolute;
2062
- top: 100%;
2063
- right: 0;
2064
- z-index: 1000;
2065
- min-width: 140px;
2066
- max-width: 170px;
2067
- background: var(--neiki-bg-primary);
2068
- border: 1px solid var(--neiki-border-color);
2069
- border-radius: 6px;
2070
- box-shadow: var(--neiki-shadow-lg);
2071
- padding: 4px;
2072
- margin-top: 4px;
2073
- }
2074
-
2075
- .neiki-more-dropdown.show {
2076
- display: block;
2077
- animation: neiki-fade-in 0.15s ease;
2078
- }
2079
-
2080
- /* Czech language - wider dropdown for longer labels */
2081
- .neiki-lang-cs .neiki-more-dropdown {
2082
- min-width: 165px;
2083
- }
2084
-
2085
- /* Dropdown item with icon */
2086
- .neiki-dropdown-item-icon {
2087
- display: inline-flex;
2088
- align-items: center;
2089
- justify-content: center;
2090
- width: 18px;
2091
- height: 18px;
2092
- flex-shrink: 0;
2093
- }
2094
-
2095
- .neiki-dropdown-item-icon svg {
2096
- width: 16px;
2097
- height: 16px;
2098
- fill: currentColor;
2099
- }
2100
-
2101
- .neiki-dropdown-item-danger {
2102
- color: var(--neiki-danger-color) !important;
2103
- }
2104
-
2105
- .neiki-dropdown-item-danger:hover {
2106
- background: rgba(220, 53, 69, 0.1);
2107
- }
2108
-
2109
- /* Autosave badge in More menu */
2110
- .neiki-autosave-badge {
2111
- font-size: 12px;
2112
- font-weight: 600;
2113
- color: var(--neiki-text-muted);
2114
- padding: 0 4px;
2115
- }
2116
-
2117
- .neiki-autosave-badge.active {
2118
- color: var(--neiki-success-color);
2119
- }
2120
-
2121
- /* ============================================
2122
- Preview Modal
2123
- ============================================ */
2124
- .neiki-preview-overlay {
2125
- position: fixed;
2126
- inset: 0;
2127
- background: rgba(0, 0, 0, 0.6);
2128
- z-index: 100000;
2129
- display: flex;
2130
- align-items: center;
2131
- justify-content: center;
2132
- padding: 30px;
2133
- animation: neiki-fade-in 0.2s ease;
2134
- }
2135
-
2136
- .neiki-preview-modal {
2137
- background: var(--neiki-bg-primary);
2138
- border-radius: 12px;
2139
- width: 100%;
2140
- max-width: 900px;
2141
- max-height: 90vh;
2142
- display: flex;
2143
- flex-direction: column;
2144
- overflow: hidden;
2145
- box-shadow: 0 25px 60px rgba(0, 0, 0, 0.3);
2146
- animation: neiki-modal-in 0.2s ease;
2147
- }
2148
-
2149
- .neiki-preview-header {
2150
- display: flex;
2151
- align-items: center;
2152
- justify-content: space-between;
2153
- padding: 14px 20px;
2154
- background: var(--neiki-bg-secondary);
2155
- border-bottom: 1px solid var(--neiki-border-color);
2156
- font-weight: 600;
2157
- font-size: 14px;
2158
- color: var(--neiki-text-primary);
2159
- }
2160
-
2161
- .neiki-preview-close {
2162
- width: 32px;
2163
- height: 32px;
2164
- display: flex;
2165
- align-items: center;
2166
- justify-content: center;
2167
- background: transparent;
2168
- border: none;
2169
- border-radius: 4px;
2170
- cursor: pointer;
2171
- color: var(--neiki-text-muted);
2172
- transition: background 0.15s;
2173
- }
2174
-
2175
- .neiki-preview-close:hover {
2176
- background: var(--neiki-bg-hover);
2177
- color: var(--neiki-text-primary);
2178
- }
2179
-
2180
- .neiki-preview-close svg {
2181
- width: 18px;
2182
- height: 18px;
2183
- fill: currentColor;
2184
- }
2185
-
2186
- .neiki-preview-body {
2187
- flex: 1;
2188
- overflow: auto;
2189
- padding: 30px;
2190
- color: var(--neiki-text-primary);
2191
- font-size: 15px;
2192
- line-height: 1.7;
2193
- }
2194
-
2195
- .neiki-preview-body img {
2196
- max-width: 100%;
2197
- }
2198
-
2199
- .neiki-preview-body table {
2200
- border-collapse: collapse;
2201
- width: 100%;
2202
- }
2203
-
2204
- .neiki-preview-body table td,
2205
- .neiki-preview-body table th {
2206
- border: 1px solid var(--neiki-border-color);
2207
- padding: 8px 12px;
2208
- }
2209
-
2210
- /* Autosave status in statusbar */
2211
- .neiki-statusbar-autosave {
2212
- font-style: italic;
2213
- color: var(--neiki-success-color);
2214
- font-size: 11px;
2215
- }
1
+ /**
2
+ * NeikiEditor - Production-Ready WYSIWYG Rich Text Editor
3
+ * CSS Stylesheet
4
+ * Version: 2.9.3
5
+ */
6
+
7
+ /* ============================================
8
+ CSS Custom Properties (Light/Dark Themes)
9
+ ============================================ */
10
+ :root {
11
+ /* Light Theme (default) */
12
+ --neiki-bg-primary: #ffffff;
13
+ --neiki-bg-secondary: #f8f9fa;
14
+ --neiki-bg-tertiary: #e9ecef;
15
+ --neiki-bg-hover: #dee2e6;
16
+ --neiki-bg-active: #ced4da;
17
+ --neiki-border-color: #dee2e6;
18
+ --neiki-border-color-dark: #adb5bd;
19
+ --neiki-text-primary: #212529;
20
+ --neiki-text-secondary: #495057;
21
+ --neiki-text-muted: #6c757d;
22
+ --neiki-accent-color: #0d6efd;
23
+ --neiki-accent-hover: #0b5ed7;
24
+ --neiki-danger-color: #dc3545;
25
+ --neiki-success-color: #198754;
26
+ --neiki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
27
+ --neiki-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
28
+ --neiki-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
29
+ --neiki-editor-bg: #ffffff;
30
+ --neiki-toolbar-bg: #f8f9fa;
31
+ --neiki-statusbar-bg: #f8f9fa;
32
+ --neiki-modal-overlay: rgba(0, 0, 0, 0.5);
33
+ --neiki-scrollbar-thumb: #ced4da;
34
+ --neiki-scrollbar-track: #f8f9fa;
35
+ --neiki-selection-bg: #b3d7ff;
36
+ --neiki-highlight-color: #fff3cd;
37
+ --neiki-table-border: #dee2e6;
38
+ }
39
+
40
+ /* Dark Theme */
41
+ .neiki-editor.neiki-dark {
42
+ --neiki-bg-primary: #1e1e1e;
43
+ --neiki-bg-secondary: #252526;
44
+ --neiki-bg-tertiary: #2d2d30;
45
+ --neiki-bg-hover: #3e3e42;
46
+ --neiki-bg-active: #505050;
47
+ --neiki-border-color: #3e3e42;
48
+ --neiki-border-color-dark: #505050;
49
+ --neiki-text-primary: #d4d4d4;
50
+ --neiki-text-secondary: #a0a0a0;
51
+ --neiki-text-muted: #808080;
52
+ --neiki-accent-color: #4fc3f7;
53
+ --neiki-accent-hover: #29b6f6;
54
+ --neiki-danger-color: #f44336;
55
+ --neiki-success-color: #4caf50;
56
+ --neiki-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
57
+ --neiki-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
58
+ --neiki-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.4);
59
+ --neiki-editor-bg: #1e1e1e;
60
+ --neiki-toolbar-bg: #252526;
61
+ --neiki-statusbar-bg: #252526;
62
+ --neiki-modal-overlay: rgba(0, 0, 0, 0.7);
63
+ --neiki-scrollbar-thumb: #505050;
64
+ --neiki-scrollbar-track: #2d2d30;
65
+ --neiki-selection-bg: #264f78;
66
+ --neiki-highlight-color: #5c4d00;
67
+ --neiki-table-border: #3e3e42;
68
+ }
69
+
70
+ /* ============================================
71
+ Base Editor Container
72
+ ============================================ */
73
+ .neiki-editor {
74
+ display: flex;
75
+ flex-direction: column;
76
+ width: 100%;
77
+ height: 100%;
78
+ min-height: 400px;
79
+ background: var(--neiki-bg-primary);
80
+ border: 1px solid var(--neiki-border-color);
81
+ border-radius: 8px;
82
+ overflow: hidden;
83
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
84
+ font-size: 14px;
85
+ color: var(--neiki-text-primary);
86
+ box-shadow: var(--neiki-shadow-md);
87
+ }
88
+
89
+ .neiki-editor * {
90
+ box-sizing: border-box;
91
+ }
92
+
93
+ /* Fullscreen Mode */
94
+ .neiki-editor.neiki-fullscreen {
95
+ position: fixed !important;
96
+ top: 0 !important;
97
+ left: 0 !important;
98
+ right: 0 !important;
99
+ bottom: 0 !important;
100
+ width: 100vw !important;
101
+ height: 100vh !important;
102
+ z-index: 999999 !important;
103
+ border-radius: 0 !important;
104
+ border: none !important;
105
+ }
106
+
107
+ /* ============================================
108
+ Toolbar
109
+ ============================================ */
110
+ .neiki-toolbar {
111
+ display: flex;
112
+ flex-wrap: wrap;
113
+ align-items: center;
114
+ gap: 2px;
115
+ padding: 6px 8px;
116
+ background: var(--neiki-toolbar-bg);
117
+ border-bottom: 1px solid var(--neiki-border-color);
118
+ min-height: 44px;
119
+ }
120
+
121
+ /* Sticky toolbar when editor has no max height (page-flow mode) */
122
+ .neiki-editor.neiki-sticky-toolbar {
123
+ overflow: visible;
124
+ }
125
+
126
+ .neiki-editor.neiki-sticky-toolbar .neiki-toolbar {
127
+ position: sticky;
128
+ top: 0;
129
+ z-index: 100;
130
+ border-radius: 8px 8px 0 0;
131
+ }
132
+
133
+ .neiki-toolbar-group {
134
+ display: inline-flex;
135
+ align-items: center;
136
+ gap: 2px;
137
+ padding: 0 4px;
138
+ flex-wrap: nowrap;
139
+ }
140
+
141
+ .neiki-toolbar-group:not(:last-child) {
142
+ border-right: 1px solid var(--neiki-border-color);
143
+ padding-right: 8px;
144
+ margin-right: 4px;
145
+ }
146
+
147
+ .neiki-toolbar-divider {
148
+ width: 1px;
149
+ height: 24px;
150
+ background: var(--neiki-border-color);
151
+ margin: 0 4px;
152
+ }
153
+
154
+ /* Toolbar Buttons */
155
+ .neiki-btn,
156
+ .neiki-toolbar-btn {
157
+ position: relative;
158
+ display: inline-flex;
159
+ align-items: center;
160
+ justify-content: center;
161
+ width: 32px;
162
+ height: 32px;
163
+ padding: 0;
164
+ background: transparent;
165
+ border: 1px solid transparent;
166
+ border-radius: 4px;
167
+ cursor: pointer;
168
+ color: var(--neiki-text-secondary);
169
+ transition: all 0.15s ease;
170
+ position: relative;
171
+ }
172
+
173
+ .neiki-btn:hover,
174
+ .neiki-toolbar-btn:hover {
175
+ background: var(--neiki-bg-hover);
176
+ color: var(--neiki-text-primary);
177
+ }
178
+
179
+ .neiki-btn:active,
180
+ .neiki-toolbar-btn:active {
181
+ background: var(--neiki-bg-active);
182
+ }
183
+
184
+ .neiki-btn.active,
185
+ .neiki-toolbar-btn.active {
186
+ background: var(--neiki-bg-active);
187
+ color: var(--neiki-accent-color);
188
+ border-color: var(--neiki-accent-color);
189
+ }
190
+
191
+ .neiki-btn:disabled,
192
+ .neiki-toolbar-btn:disabled {
193
+ opacity: 0.4;
194
+ cursor: not-allowed;
195
+ }
196
+
197
+ .neiki-btn svg,
198
+ .neiki-toolbar-btn svg {
199
+ width: 18px;
200
+ height: 18px;
201
+ fill: currentColor;
202
+ pointer-events: none;
203
+ }
204
+
205
+ /* Toolbar Selects */
206
+ .neiki-select {
207
+ height: 32px;
208
+ padding: 0 28px 0 10px;
209
+ background: var(--neiki-bg-primary);
210
+ border: 1px solid var(--neiki-border-color);
211
+ border-radius: 4px;
212
+ color: var(--neiki-text-primary);
213
+ font-size: 13px;
214
+ cursor: pointer;
215
+ appearance: none;
216
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
217
+ background-repeat: no-repeat;
218
+ background-position: right 8px center;
219
+ min-width: 100px;
220
+ }
221
+
222
+ .neiki-select:hover {
223
+ border-color: var(--neiki-border-color-dark);
224
+ }
225
+
226
+ .neiki-select:focus {
227
+ outline: none;
228
+ border-color: var(--neiki-accent-color);
229
+ box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.15);
230
+ }
231
+
232
+ /* Color Picker Button */
233
+ .neiki-color-btn {
234
+ position: relative;
235
+ width: 36px;
236
+ }
237
+
238
+ .neiki-color-btn .neiki-color-indicator {
239
+ position: absolute;
240
+ bottom: 4px;
241
+ left: 50%;
242
+ transform: translateX(-50%);
243
+ width: 16px;
244
+ height: 3px;
245
+ border-radius: 1px;
246
+ background: currentColor;
247
+ }
248
+
249
+ /* Checkbox Toggle */
250
+ .neiki-checkbox-wrapper {
251
+ display: flex;
252
+ align-items: center;
253
+ gap: 6px;
254
+ padding: 0 8px;
255
+ height: 32px;
256
+ font-size: 12px;
257
+ color: var(--neiki-text-secondary);
258
+ cursor: pointer;
259
+ user-select: none;
260
+ }
261
+
262
+ .neiki-checkbox {
263
+ width: 16px;
264
+ height: 16px;
265
+ accent-color: var(--neiki-accent-color);
266
+ cursor: pointer;
267
+ }
268
+
269
+ /* ============================================
270
+ Editor Content Area
271
+ ============================================ */
272
+ .neiki-editor-wrapper,
273
+ .neiki-content-wrapper {
274
+ flex: 1;
275
+ display: flex;
276
+ flex-direction: column;
277
+ overflow: hidden;
278
+ position: relative;
279
+ }
280
+
281
+ .neiki-content {
282
+ flex: 1;
283
+ padding: 20px 24px;
284
+ background: var(--neiki-editor-bg);
285
+ overflow-y: auto;
286
+ outline: none;
287
+ line-height: 1.6;
288
+ color: var(--neiki-text-primary);
289
+ min-height: 200px;
290
+ }
291
+
292
+ .neiki-content:focus {
293
+ outline: none;
294
+ }
295
+
296
+ /* Placeholder */
297
+ .neiki-content:empty::before {
298
+ content: attr(data-placeholder);
299
+ color: var(--neiki-text-muted);
300
+ font-style: italic;
301
+ pointer-events: none;
302
+ }
303
+
304
+ .neiki-content.neiki-drag-over {
305
+ border: 2px dashed var(--neiki-accent-color);
306
+ background: rgba(13, 110, 253, 0.05);
307
+ }
308
+
309
+ .neiki-content.neiki-drag-over::after {
310
+ content: 'Drop images here';
311
+ position: absolute;
312
+ top: 50%;
313
+ left: 50%;
314
+ transform: translate(-50%, -50%);
315
+ color: var(--neiki-accent-color);
316
+ font-weight: 600;
317
+ font-size: 16px;
318
+ pointer-events: none;
319
+ z-index: 10;
320
+ }
321
+
322
+ /* Focus state for editor container - disabled */
323
+ /* .neiki-editor.neiki-focused removed */
324
+
325
+ /* Disabled state */
326
+ .neiki-editor.neiki-disabled {
327
+ opacity: 0.6;
328
+ pointer-events: none;
329
+ }
330
+
331
+ /* Content Scrollbar */
332
+ .neiki-content::-webkit-scrollbar {
333
+ width: 10px;
334
+ }
335
+
336
+ .neiki-content::-webkit-scrollbar-track {
337
+ background: var(--neiki-scrollbar-track);
338
+ }
339
+
340
+ .neiki-content::-webkit-scrollbar-thumb {
341
+ background: var(--neiki-scrollbar-thumb);
342
+ border-radius: 5px;
343
+ }
344
+
345
+ .neiki-content::-webkit-scrollbar-thumb:hover {
346
+ background: var(--neiki-border-color-dark);
347
+ }
348
+
349
+ /* Content Typography */
350
+ .neiki-content p {
351
+ margin: 0 0 1em 0;
352
+ }
353
+
354
+ .neiki-content h1 {
355
+ font-size: 2em;
356
+ font-weight: 700;
357
+ margin: 0 0 0.5em 0;
358
+ }
359
+
360
+ .neiki-content h2 {
361
+ font-size: 1.5em;
362
+ font-weight: 600;
363
+ margin: 0 0 0.5em 0;
364
+ }
365
+
366
+ .neiki-content h3 {
367
+ font-size: 1.25em;
368
+ font-weight: 600;
369
+ margin: 0 0 0.5em 0;
370
+ }
371
+
372
+ .neiki-content h4 {
373
+ font-size: 1.1em;
374
+ font-weight: 600;
375
+ margin: 0 0 0.5em 0;
376
+ }
377
+
378
+ .neiki-content h5 {
379
+ font-size: 1em;
380
+ font-weight: 600;
381
+ margin: 0 0 0.5em 0;
382
+ }
383
+
384
+ .neiki-content h6 {
385
+ font-size: 0.9em;
386
+ font-weight: 600;
387
+ margin: 0 0 0.5em 0;
388
+ }
389
+
390
+ .neiki-content ul,
391
+ .neiki-content ol {
392
+ margin: 0 0 1em 0;
393
+ padding-left: 2em;
394
+ }
395
+
396
+ .neiki-content li {
397
+ margin-bottom: 0.25em;
398
+ }
399
+
400
+ .neiki-content blockquote {
401
+ margin: 0 0 1em 0;
402
+ padding: 10px 20px;
403
+ border-left: 4px solid var(--neiki-accent-color);
404
+ background: var(--neiki-bg-secondary);
405
+ font-style: italic;
406
+ }
407
+
408
+ .neiki-content pre {
409
+ margin: 0 0 1em 0;
410
+ padding: 16px;
411
+ background: var(--neiki-bg-tertiary);
412
+ border-radius: 4px;
413
+ overflow-x: auto;
414
+ font-family: 'Consolas', 'Monaco', monospace;
415
+ font-size: 13px;
416
+ }
417
+
418
+ .neiki-content code {
419
+ padding: 2px 6px;
420
+ background: var(--neiki-bg-tertiary);
421
+ border-radius: 3px;
422
+ font-family: 'Consolas', 'Monaco', monospace;
423
+ font-size: 0.9em;
424
+ }
425
+
426
+ .neiki-content a {
427
+ color: var(--neiki-accent-color);
428
+ text-decoration: underline;
429
+ }
430
+
431
+ .neiki-content a:hover {
432
+ color: var(--neiki-accent-hover);
433
+ }
434
+
435
+ .neiki-content img {
436
+ max-width: 100%;
437
+ height: auto;
438
+ border-radius: 4px;
439
+ cursor: pointer;
440
+ }
441
+
442
+ .neiki-content img.neiki-selected {
443
+ outline: 2px solid var(--neiki-accent-color);
444
+ outline-offset: 2px;
445
+ }
446
+
447
+ /* Search Highlight */
448
+ .neiki-highlight {
449
+ background: var(--neiki-highlight-color);
450
+ padding: 1px 0;
451
+ }
452
+
453
+ .neiki-highlight-current {
454
+ background: #ffc107;
455
+ outline: 2px solid #ff9800;
456
+ }
457
+
458
+ /* ============================================
459
+ Tables
460
+ ============================================ */
461
+ .neiki-content table,
462
+ .neiki-table {
463
+ width: 100%;
464
+ border-collapse: collapse;
465
+ margin: 1em 0;
466
+ table-layout: fixed;
467
+ }
468
+
469
+ .neiki-content table td,
470
+ .neiki-content table th {
471
+ border: 1px solid var(--neiki-table-border);
472
+ padding: 8px 12px;
473
+ min-width: 50px;
474
+ vertical-align: top;
475
+ position: relative;
476
+ }
477
+
478
+ .neiki-content table th {
479
+ background: var(--neiki-bg-secondary);
480
+ font-weight: 600;
481
+ }
482
+
483
+ .neiki-content table td:hover,
484
+ .neiki-content table th:hover {
485
+ background: var(--neiki-bg-hover);
486
+ }
487
+
488
+ .neiki-content table td.neiki-cell-selected,
489
+ .neiki-content table th.neiki-cell-selected {
490
+ background: var(--neiki-selection-bg);
491
+ }
492
+
493
+ /* Table Resize Handle */
494
+ .neiki-table-resize-handle {
495
+ position: absolute;
496
+ top: 0;
497
+ right: -3px;
498
+ width: 6px;
499
+ height: 100%;
500
+ cursor: col-resize;
501
+ z-index: 10;
502
+ }
503
+
504
+ .neiki-table-resize-handle:hover {
505
+ background: var(--neiki-accent-color);
506
+ }
507
+
508
+ /* ============================================
509
+ Status Bar
510
+ ============================================ */
511
+ .neiki-statusbar {
512
+ display: flex;
513
+ justify-content: space-between;
514
+ align-items: center;
515
+ padding: 6px 12px;
516
+ background: var(--neiki-statusbar-bg);
517
+ border-top: 1px solid var(--neiki-border-color);
518
+ font-size: 12px;
519
+ color: var(--neiki-text-muted);
520
+ }
521
+
522
+ .neiki-statusbar-left,
523
+ .neiki-statusbar-right {
524
+ display: flex;
525
+ align-items: center;
526
+ gap: 16px;
527
+ }
528
+
529
+ .neiki-statusbar-item {
530
+ display: flex;
531
+ align-items: center;
532
+ gap: 4px;
533
+ }
534
+
535
+ .neiki-statusbar-block {
536
+ font-family: 'Consolas', 'Monaco', monospace;
537
+ font-size: 11px;
538
+ padding: 2px 6px;
539
+ background: var(--neiki-bg-tertiary);
540
+ border-radius: 3px;
541
+ color: var(--neiki-accent-color);
542
+ font-weight: 600;
543
+ border: 1px solid var(--neiki-border-color);
544
+ }
545
+
546
+ /* ============================================
547
+ Dropdowns & Popups
548
+ ============================================ */
549
+ .neiki-dropdown {
550
+ position: absolute;
551
+ top: 100%;
552
+ left: 0;
553
+ z-index: 1000;
554
+ min-width: 180px;
555
+ background: var(--neiki-bg-primary);
556
+ border: 1px solid var(--neiki-border-color);
557
+ border-radius: 6px;
558
+ box-shadow: var(--neiki-shadow-lg);
559
+ padding: 4px;
560
+ margin-top: 4px;
561
+ }
562
+
563
+ /* Remove the .show requirement - JS adds/removes element directly */
564
+
565
+ .neiki-dropdown-item {
566
+ display: flex;
567
+ align-items: center;
568
+ gap: 6px;
569
+ padding: 7px 10px;
570
+ border-radius: 4px;
571
+ cursor: pointer;
572
+ color: var(--neiki-text-primary);
573
+ font-size: 13px;
574
+ transition: background 0.1s;
575
+ }
576
+
577
+ .neiki-dropdown-item:hover {
578
+ background: var(--neiki-bg-hover);
579
+ }
580
+
581
+ .neiki-dropdown-item.active {
582
+ background: var(--neiki-bg-active);
583
+ color: var(--neiki-accent-color);
584
+ }
585
+
586
+ .neiki-dropdown-divider {
587
+ height: 1px;
588
+ background: var(--neiki-border-color);
589
+ margin: 4px 0;
590
+ }
591
+
592
+ /* ============================================
593
+ Color Picker
594
+ ============================================ */
595
+ .neiki-color-picker {
596
+ position: absolute;
597
+ top: 100%;
598
+ left: 0;
599
+ z-index: 1000;
600
+ background: var(--neiki-bg-primary);
601
+ border: 1px solid var(--neiki-border-color);
602
+ border-radius: 8px;
603
+ box-shadow: var(--neiki-shadow-lg);
604
+ padding: 8px;
605
+ margin-top: 4px;
606
+ display: flex;
607
+ flex-direction: column;
608
+ gap: 6px;
609
+ }
610
+
611
+ .neiki-color-grid {
612
+ display: grid;
613
+ grid-template-columns: repeat(10, 1fr);
614
+ gap: 2px;
615
+ }
616
+
617
+ .neiki-color-custom {
618
+ display: flex;
619
+ align-items: center;
620
+ gap: 6px;
621
+ padding-top: 6px;
622
+ border-top: 1px solid var(--neiki-border-color);
623
+ }
624
+
625
+ .neiki-color-custom-input {
626
+ -webkit-appearance: none;
627
+ -moz-appearance: none;
628
+ appearance: none;
629
+ width: 28px;
630
+ height: 28px;
631
+ border: 1px solid var(--neiki-border-color);
632
+ border-radius: 4px;
633
+ padding: 2px;
634
+ cursor: pointer;
635
+ background: transparent;
636
+ }
637
+
638
+ .neiki-color-custom-input::-webkit-color-swatch-wrapper {
639
+ padding: 0;
640
+ }
641
+
642
+ .neiki-color-custom-input::-webkit-color-swatch {
643
+ border: none;
644
+ border-radius: 2px;
645
+ }
646
+
647
+ .neiki-color-custom-input::-moz-color-swatch {
648
+ border: none;
649
+ border-radius: 2px;
650
+ }
651
+
652
+ .neiki-color-hex-input {
653
+ flex: 1;
654
+ height: 28px;
655
+ padding: 0 8px;
656
+ border: 1px solid var(--neiki-border-color);
657
+ border-radius: 4px;
658
+ font-size: 12px;
659
+ font-family: monospace;
660
+ background: var(--neiki-bg-secondary);
661
+ color: var(--neiki-text-primary);
662
+ outline: none;
663
+ }
664
+
665
+ .neiki-color-hex-input:focus {
666
+ border-color: var(--neiki-accent-color);
667
+ box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.15);
668
+ }
669
+
670
+ .neiki-color-apply-btn {
671
+ height: 28px;
672
+ padding: 0 10px;
673
+ border: none;
674
+ border-radius: 4px;
675
+ font-size: 12px;
676
+ font-weight: 500;
677
+ background: var(--neiki-accent-color);
678
+ color: #fff;
679
+ cursor: pointer;
680
+ transition: background 0.15s;
681
+ }
682
+
683
+ .neiki-color-apply-btn:hover {
684
+ background: var(--neiki-accent-hover);
685
+ }
686
+
687
+ .neiki-color-swatch {
688
+ width: 22px;
689
+ height: 22px;
690
+ border-radius: 3px;
691
+ cursor: pointer;
692
+ border: 1px solid var(--neiki-border-color);
693
+ transition: transform 0.1s;
694
+ }
695
+
696
+ .neiki-color-swatch:hover {
697
+ transform: scale(1.2);
698
+ z-index: 1;
699
+ }
700
+
701
+ .neiki-color-swatch.neiki-color-reset {
702
+ background: white;
703
+ position: relative;
704
+ overflow: hidden;
705
+ border: 1px solid #ccc;
706
+ }
707
+
708
+ .neiki-color-swatch.neiki-color-reset::after {
709
+ content: '';
710
+ position: absolute;
711
+ top: 50%;
712
+ left: -2px;
713
+ right: -2px;
714
+ height: 2px;
715
+ background: #e53935;
716
+ transform: rotate(-45deg);
717
+ transform-origin: center;
718
+ pointer-events: none;
719
+ }
720
+
721
+ .neiki-color-picker-label {
722
+ font-size: 11px;
723
+ font-weight: 600;
724
+ color: var(--neiki-text-muted);
725
+ text-transform: uppercase;
726
+ margin-bottom: 8px;
727
+ }
728
+
729
+ /* Emoji Picker */
730
+ .neiki-emoji-picker {
731
+ position: absolute;
732
+ top: 100%;
733
+ left: 0;
734
+ z-index: 1000;
735
+ width: 280px;
736
+ max-width: calc(100vw - 16px);
737
+ max-height: 250px;
738
+ overflow-y: auto;
739
+ background: var(--neiki-bg-primary);
740
+ border: 1px solid var(--neiki-border-color);
741
+ border-radius: 8px;
742
+ box-shadow: var(--neiki-shadow-lg);
743
+ padding: 8px;
744
+ margin-top: 4px;
745
+ display: grid;
746
+ grid-template-columns: repeat(10, 1fr);
747
+ gap: 2px;
748
+ }
749
+
750
+ .neiki-emoji-item {
751
+ display: flex;
752
+ align-items: center;
753
+ justify-content: center;
754
+ width: 24px;
755
+ height: 24px;
756
+ font-size: 18px;
757
+ cursor: pointer;
758
+ border-radius: 4px;
759
+ transition: background 0.15s, transform 0.1s;
760
+ }
761
+
762
+ .neiki-emoji-item:hover {
763
+ background: var(--neiki-bg-hover);
764
+ transform: scale(1.2);
765
+ }
766
+
767
+ /* Special Characters Picker */
768
+ .neiki-special-picker {
769
+ position: absolute;
770
+ top: 100%;
771
+ left: 0;
772
+ z-index: 1000;
773
+ width: 320px;
774
+ max-width: calc(100vw - 16px);
775
+ max-height: 280px;
776
+ overflow-y: auto;
777
+ background: var(--neiki-bg-primary);
778
+ border: 1px solid var(--neiki-border-color);
779
+ border-radius: 8px;
780
+ box-shadow: var(--neiki-shadow-lg);
781
+ padding: 8px;
782
+ margin-top: 4px;
783
+ display: grid;
784
+ grid-template-columns: repeat(8, 1fr);
785
+ gap: 4px;
786
+ }
787
+
788
+ .neiki-special-item {
789
+ display: flex;
790
+ align-items: center;
791
+ justify-content: center;
792
+ width: 32px;
793
+ height: 32px;
794
+ font-size: 18px;
795
+ cursor: pointer;
796
+ border-radius: 4px;
797
+ border: 1px solid var(--neiki-border-color);
798
+ background: var(--neiki-bg-secondary);
799
+ transition: all 0.15s;
800
+ }
801
+
802
+ .neiki-special-item:hover {
803
+ background: var(--neiki-accent-color);
804
+ color: white;
805
+ border-color: var(--neiki-accent-color);
806
+ transform: scale(1.1);
807
+ }
808
+
809
+ /* Find & Replace Highlights */
810
+ .neiki-highlight-find {
811
+ background: #ffeb3b;
812
+ padding: 1px 0;
813
+ border-radius: 2px;
814
+ }
815
+
816
+ .neiki-highlight-current {
817
+ background: #ff9800;
818
+ outline: 2px solid #e65100;
819
+ }
820
+
821
+ .neiki-color-presets {
822
+ display: grid;
823
+ grid-template-columns: repeat(5, 1fr);
824
+ gap: 6px;
825
+ margin-bottom: 12px;
826
+ }
827
+
828
+ .neiki-color-preset {
829
+ width: 32px;
830
+ height: 32px;
831
+ border-radius: 4px;
832
+ border: 2px solid transparent;
833
+ cursor: pointer;
834
+ transition: transform 0.1s, border-color 0.1s;
835
+ }
836
+
837
+ .neiki-color-preset:hover {
838
+ transform: scale(1.1);
839
+ }
840
+
841
+ .neiki-color-preset.active {
842
+ border-color: var(--neiki-accent-color);
843
+ }
844
+
845
+ .neiki-color-preset.neiki-color-reset {
846
+ background: linear-gradient(45deg, #fff 45%, #ff0000 45%, #ff0000 55%, #fff 55%);
847
+ border: 1px solid var(--neiki-border-color);
848
+ }
849
+
850
+ .neiki-color-custom {
851
+ display: flex;
852
+ align-items: center;
853
+ gap: 8px;
854
+ padding-top: 8px;
855
+ border-top: 1px solid var(--neiki-border-color);
856
+ }
857
+
858
+ .neiki-color-custom input[type="color"] {
859
+ width: 40px;
860
+ height: 32px;
861
+ padding: 0;
862
+ border: 1px solid var(--neiki-border-color);
863
+ border-radius: 4px;
864
+ cursor: pointer;
865
+ }
866
+
867
+ .neiki-color-custom input[type="text"] {
868
+ flex: 1;
869
+ height: 32px;
870
+ padding: 0 8px;
871
+ border: 1px solid var(--neiki-border-color);
872
+ border-radius: 4px;
873
+ background: var(--neiki-bg-primary);
874
+ color: var(--neiki-text-primary);
875
+ font-size: 12px;
876
+ font-family: monospace;
877
+ }
878
+
879
+ /* ============================================
880
+ Table Picker
881
+ ============================================ */
882
+ .neiki-table-picker {
883
+ position: absolute;
884
+ top: 100%;
885
+ left: 0;
886
+ z-index: 1000;
887
+ background: var(--neiki-bg-primary);
888
+ border: 1px solid var(--neiki-border-color);
889
+ border-radius: 8px;
890
+ box-shadow: var(--neiki-shadow-lg);
891
+ padding: 12px;
892
+ display: none;
893
+ }
894
+
895
+ .neiki-table-picker.show {
896
+ display: block;
897
+ }
898
+
899
+ .neiki-table-picker-label {
900
+ font-size: 12px;
901
+ color: var(--neiki-text-secondary);
902
+ margin-bottom: 8px;
903
+ text-align: center;
904
+ }
905
+
906
+ .neiki-table-picker-grid {
907
+ display: grid;
908
+ grid-template-columns: repeat(10, 20px);
909
+ gap: 2px;
910
+ }
911
+
912
+ .neiki-table-picker-cell {
913
+ width: 20px;
914
+ height: 20px;
915
+ border: 1px solid var(--neiki-border-color);
916
+ border-radius: 2px;
917
+ background: var(--neiki-bg-primary);
918
+ cursor: pointer;
919
+ transition: background 0.1s;
920
+ }
921
+
922
+ .neiki-table-picker-cell:hover,
923
+ .neiki-table-picker-cell.active {
924
+ background: var(--neiki-accent-color);
925
+ border-color: var(--neiki-accent-color);
926
+ }
927
+
928
+ /* ============================================
929
+ Special Characters Picker (duplicate removed)
930
+ ============================================ */
931
+ .neiki-special-chars {
932
+ position: absolute;
933
+ top: 100%;
934
+ left: 0;
935
+ z-index: 1000;
936
+ width: 280px;
937
+ max-height: 300px;
938
+ background: var(--neiki-bg-primary);
939
+ border: 1px solid var(--neiki-border-color);
940
+ border-radius: 8px;
941
+ box-shadow: var(--neiki-shadow-lg);
942
+ display: none;
943
+ overflow: hidden;
944
+ }
945
+
946
+ .neiki-special-chars.show {
947
+ display: flex;
948
+ flex-direction: column;
949
+ }
950
+
951
+ .neiki-special-chars-grid {
952
+ display: grid;
953
+ grid-template-columns: repeat(10, 1fr);
954
+ gap: 2px;
955
+ padding: 8px;
956
+ overflow-y: auto;
957
+ }
958
+
959
+ .neiki-special-char-item {
960
+ display: flex;
961
+ align-items: center;
962
+ justify-content: center;
963
+ width: 24px;
964
+ height: 24px;
965
+ font-size: 16px;
966
+ border-radius: 4px;
967
+ cursor: pointer;
968
+ transition: background 0.1s;
969
+ }
970
+
971
+ .neiki-special-char-item:hover {
972
+ background: var(--neiki-bg-hover);
973
+ }
974
+
975
+ /* ============================================
976
+ Modals
977
+ ============================================ */
978
+ .neiki-modal-overlay {
979
+ position: fixed;
980
+ top: 0;
981
+ left: 0;
982
+ right: 0;
983
+ bottom: 0;
984
+ background: var(--neiki-modal-overlay);
985
+ z-index: 10000;
986
+ display: flex;
987
+ align-items: center;
988
+ justify-content: center;
989
+ opacity: 0;
990
+ visibility: hidden;
991
+ transition: opacity 0.2s, visibility 0.2s;
992
+ }
993
+
994
+ .neiki-modal-overlay.active {
995
+ opacity: 1;
996
+ visibility: visible;
997
+ }
998
+
999
+ .neiki-modal {
1000
+ background: var(--neiki-bg-primary);
1001
+ border-radius: 12px;
1002
+ box-shadow: var(--neiki-shadow-lg);
1003
+ width: 100%;
1004
+ max-width: 440px;
1005
+ max-height: 90vh;
1006
+ overflow: hidden;
1007
+ animation: neiki-modal-in 0.2s ease;
1008
+ }
1009
+
1010
+ .neiki-modal-wide {
1011
+ max-width: 520px;
1012
+ }
1013
+
1014
+ .neiki-modal-header {
1015
+ display: flex;
1016
+ align-items: center;
1017
+ justify-content: space-between;
1018
+ padding: 16px 20px;
1019
+ border-bottom: 1px solid var(--neiki-border-color);
1020
+ }
1021
+
1022
+ .neiki-modal-title {
1023
+ font-size: 16px;
1024
+ font-weight: 600;
1025
+ color: var(--neiki-text-primary);
1026
+ margin: 0;
1027
+ }
1028
+
1029
+ .neiki-modal-close {
1030
+ width: 32px;
1031
+ height: 32px;
1032
+ display: flex;
1033
+ align-items: center;
1034
+ justify-content: center;
1035
+ background: transparent;
1036
+ border: none;
1037
+ border-radius: 4px;
1038
+ cursor: pointer;
1039
+ color: var(--neiki-text-muted);
1040
+ transition: background 0.15s;
1041
+ }
1042
+
1043
+ .neiki-modal-close:hover {
1044
+ background: var(--neiki-bg-hover);
1045
+ color: var(--neiki-text-primary);
1046
+ }
1047
+
1048
+ .neiki-modal-body {
1049
+ padding: 20px;
1050
+ overflow-y: auto;
1051
+ }
1052
+
1053
+ .neiki-modal h3,
1054
+ .neiki-modal-header h3 {
1055
+ color: #000000;
1056
+ margin: 0;
1057
+ }
1058
+
1059
+ .neiki-dark .neiki-modal h3,
1060
+ .neiki-dark .neiki-modal-header h3 {
1061
+ color: var(--neiki-text-primary);
1062
+ }
1063
+
1064
+ .neiki-modal-footer {
1065
+ display: flex;
1066
+ justify-content: flex-end;
1067
+ gap: 10px;
1068
+ padding: 16px 20px;
1069
+ border-top: 1px solid var(--neiki-border-color);
1070
+ }
1071
+
1072
+ .neiki-modal-footer .neiki-btn {
1073
+ width: auto;
1074
+ height: 38px;
1075
+ padding: 0 16px;
1076
+ font-size: 14px;
1077
+ font-weight: 500;
1078
+ border-radius: 6px;
1079
+ }
1080
+
1081
+ /* Form Elements */
1082
+ .neiki-form-group {
1083
+ margin-bottom: 16px;
1084
+ }
1085
+
1086
+ .neiki-form-group:last-child {
1087
+ margin-bottom: 0;
1088
+ }
1089
+
1090
+ .neiki-form-label {
1091
+ display: block;
1092
+ margin-bottom: 6px;
1093
+ font-size: 13px;
1094
+ font-weight: 500;
1095
+ color: var(--neiki-text-secondary);
1096
+ }
1097
+
1098
+ .neiki-form-input,
1099
+ .neiki-input {
1100
+ width: 100%;
1101
+ height: 40px;
1102
+ padding: 0 12px;
1103
+ border: 1px solid var(--neiki-border-color);
1104
+ border-radius: 6px;
1105
+ background: var(--neiki-bg-primary);
1106
+ color: var(--neiki-text-primary);
1107
+ font-size: 14px;
1108
+ transition: border-color 0.15s;
1109
+ }
1110
+
1111
+ .neiki-form-input:focus,
1112
+ .neiki-input:focus {
1113
+ outline: none;
1114
+ border-color: var(--neiki-accent-color);
1115
+ box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.15);
1116
+ }
1117
+
1118
+ .neiki-form-input::placeholder,
1119
+ .neiki-input::placeholder {
1120
+ color: var(--neiki-text-muted);
1121
+ }
1122
+
1123
+ .neiki-input[type="file"] {
1124
+ display: flex;
1125
+ align-items: center;
1126
+ padding: 0;
1127
+ cursor: pointer;
1128
+ }
1129
+
1130
+ .neiki-input[type="file"]::file-selector-button {
1131
+ height: 100%;
1132
+ padding: 0 14px;
1133
+ margin-right: 12px;
1134
+ border: none;
1135
+ border-right: 1px solid var(--neiki-border-color);
1136
+ background: var(--neiki-bg-tertiary, var(--neiki-bg-hover));
1137
+ color: var(--neiki-text-primary);
1138
+ font-size: 13px;
1139
+ font-weight: 500;
1140
+ cursor: pointer;
1141
+ border-radius: 5px 0 0 5px;
1142
+ }
1143
+
1144
+ .neiki-form-row {
1145
+ display: flex;
1146
+ gap: 16px;
1147
+ }
1148
+
1149
+ .neiki-form-divider {
1150
+ display: flex;
1151
+ align-items: center;
1152
+ margin: 16px 0;
1153
+ text-align: center;
1154
+ position: relative;
1155
+ }
1156
+
1157
+ .neiki-form-divider::before {
1158
+ content: '';
1159
+ flex: 1;
1160
+ height: 1px;
1161
+ background: var(--neiki-border-color);
1162
+ margin-right: 12px;
1163
+ }
1164
+
1165
+ .neiki-form-divider::after {
1166
+ content: '';
1167
+ flex: 1;
1168
+ height: 1px;
1169
+ background: var(--neiki-border-color);
1170
+ margin-left: 12px;
1171
+ }
1172
+
1173
+ .neiki-form-divider span {
1174
+ color: var(--neiki-text-muted);
1175
+ font-size: 12px;
1176
+ font-weight: 500;
1177
+ text-transform: uppercase;
1178
+ }
1179
+
1180
+ .neiki-form-group label {
1181
+ display: block;
1182
+ margin-bottom: 6px;
1183
+ font-size: 13px;
1184
+ font-weight: 500;
1185
+ color: var(--neiki-text-secondary);
1186
+ }
1187
+
1188
+ .neiki-form-textarea {
1189
+ width: 100%;
1190
+ min-height: 120px;
1191
+ padding: 12px;
1192
+ border: 1px solid var(--neiki-border-color);
1193
+ border-radius: 6px;
1194
+ background: var(--neiki-bg-primary);
1195
+ color: var(--neiki-text-primary);
1196
+ font-size: 14px;
1197
+ font-family: inherit;
1198
+ resize: vertical;
1199
+ transition: border-color 0.15s;
1200
+ }
1201
+
1202
+ .neiki-form-textarea:focus {
1203
+ outline: none;
1204
+ border-color: var(--neiki-accent-color);
1205
+ box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.15);
1206
+ }
1207
+
1208
+ /* Buttons */
1209
+ .neiki-button {
1210
+ display: inline-flex;
1211
+ align-items: center;
1212
+ justify-content: center;
1213
+ gap: 6px;
1214
+ height: 38px;
1215
+ padding: 0 16px;
1216
+ border: 1px solid transparent;
1217
+ border-radius: 6px;
1218
+ font-size: 14px;
1219
+ font-weight: 500;
1220
+ cursor: pointer;
1221
+ transition: all 0.15s;
1222
+ }
1223
+
1224
+ .neiki-button-primary,
1225
+ .neiki-btn-primary {
1226
+ background: var(--neiki-accent-color);
1227
+ color: #fff;
1228
+ }
1229
+
1230
+ .neiki-button-primary:hover,
1231
+ .neiki-btn-primary:hover {
1232
+ background: var(--neiki-accent-hover);
1233
+ }
1234
+
1235
+ .neiki-button-secondary,
1236
+ .neiki-btn-secondary {
1237
+ background: var(--neiki-bg-secondary);
1238
+ color: var(--neiki-text-primary);
1239
+ border-color: var(--neiki-border-color);
1240
+ }
1241
+
1242
+ .neiki-btn-primary,
1243
+ .neiki-btn-secondary {
1244
+ display: inline-flex;
1245
+ align-items: center;
1246
+ justify-content: center;
1247
+ height: 38px;
1248
+ padding: 0 16px;
1249
+ border: 1px solid transparent;
1250
+ border-radius: 6px;
1251
+ font-size: 14px;
1252
+ font-weight: 500;
1253
+ cursor: pointer;
1254
+ transition: all 0.15s;
1255
+ }
1256
+
1257
+ .neiki-btn-secondary {
1258
+ border-color: var(--neiki-border-color);
1259
+ }
1260
+
1261
+ .neiki-btn-secondary:hover {
1262
+ background: var(--neiki-bg-hover);
1263
+ }
1264
+
1265
+ .neiki-button-secondary:hover {
1266
+ background: var(--neiki-bg-hover);
1267
+ }
1268
+
1269
+ .neiki-button-danger {
1270
+ background: var(--neiki-danger-color);
1271
+ color: #fff;
1272
+ }
1273
+
1274
+ .neiki-button-danger:hover {
1275
+ opacity: 0.9;
1276
+ }
1277
+
1278
+ /* ============================================
1279
+ Find & Replace Panel
1280
+ ============================================ */
1281
+ .neiki-find-replace {
1282
+ position: absolute;
1283
+ top: 0;
1284
+ right: 0;
1285
+ z-index: 100;
1286
+ width: 360px;
1287
+ background: var(--neiki-bg-primary);
1288
+ border: 1px solid var(--neiki-border-color);
1289
+ border-radius: 0 0 0 8px;
1290
+ box-shadow: var(--neiki-shadow-lg);
1291
+ display: none;
1292
+ }
1293
+
1294
+ .neiki-find-replace.show {
1295
+ display: block;
1296
+ }
1297
+
1298
+ .neiki-find-replace-header {
1299
+ display: flex;
1300
+ align-items: center;
1301
+ justify-content: space-between;
1302
+ padding: 10px 12px;
1303
+ border-bottom: 1px solid var(--neiki-border-color);
1304
+ }
1305
+
1306
+ .neiki-find-replace-title {
1307
+ font-size: 13px;
1308
+ font-weight: 600;
1309
+ color: var(--neiki-text-primary);
1310
+ }
1311
+
1312
+ .neiki-find-replace-body {
1313
+ padding: 12px;
1314
+ }
1315
+
1316
+ .neiki-find-replace-row {
1317
+ display: flex;
1318
+ gap: 8px;
1319
+ margin-bottom: 10px;
1320
+ }
1321
+
1322
+ .neiki-find-replace-row:last-child {
1323
+ margin-bottom: 0;
1324
+ }
1325
+
1326
+ .neiki-find-replace-input {
1327
+ flex: 1;
1328
+ height: 32px;
1329
+ padding: 0 10px;
1330
+ border: 1px solid var(--neiki-border-color);
1331
+ border-radius: 4px;
1332
+ background: var(--neiki-bg-primary);
1333
+ color: var(--neiki-text-primary);
1334
+ font-size: 13px;
1335
+ }
1336
+
1337
+ .neiki-find-replace-input:focus {
1338
+ outline: none;
1339
+ border-color: var(--neiki-accent-color);
1340
+ }
1341
+
1342
+ .neiki-find-replace-options {
1343
+ display: flex;
1344
+ align-items: center;
1345
+ gap: 12px;
1346
+ margin-bottom: 10px;
1347
+ }
1348
+
1349
+ .neiki-find-replace-option {
1350
+ display: flex;
1351
+ align-items: center;
1352
+ gap: 4px;
1353
+ font-size: 12px;
1354
+ color: var(--neiki-text-secondary);
1355
+ cursor: pointer;
1356
+ }
1357
+
1358
+ .neiki-find-replace-option input {
1359
+ accent-color: var(--neiki-accent-color);
1360
+ }
1361
+
1362
+ .neiki-find-replace-actions {
1363
+ display: flex;
1364
+ gap: 6px;
1365
+ flex-wrap: wrap;
1366
+ }
1367
+
1368
+ .neiki-find-replace-btn {
1369
+ height: 28px;
1370
+ padding: 0 10px;
1371
+ font-size: 12px;
1372
+ border-radius: 4px;
1373
+ }
1374
+
1375
+ .neiki-find-replace-count {
1376
+ font-size: 12px;
1377
+ color: var(--neiki-text-muted);
1378
+ margin-left: auto;
1379
+ }
1380
+
1381
+ /* ============================================
1382
+ HTML Code View
1383
+ ============================================ */
1384
+ .neiki-code-view {
1385
+ position: absolute;
1386
+ top: 0;
1387
+ left: 0;
1388
+ right: 0;
1389
+ bottom: 0;
1390
+ z-index: 50;
1391
+ background: var(--neiki-bg-primary);
1392
+ display: none;
1393
+ flex-direction: column;
1394
+ }
1395
+
1396
+ .neiki-code-view.show {
1397
+ display: flex;
1398
+ }
1399
+
1400
+ .neiki-code-view-header {
1401
+ display: flex;
1402
+ align-items: center;
1403
+ justify-content: space-between;
1404
+ padding: 8px 16px;
1405
+ background: var(--neiki-bg-secondary);
1406
+ border-bottom: 1px solid var(--neiki-border-color);
1407
+ flex-shrink: 0;
1408
+ }
1409
+
1410
+ .neiki-code-view-title {
1411
+ font-size: 13px;
1412
+ font-weight: 600;
1413
+ color: var(--neiki-text-primary);
1414
+ }
1415
+
1416
+ .neiki-code-view-textarea {
1417
+ flex: 1;
1418
+ width: 100%;
1419
+ padding: 16px;
1420
+ border: none;
1421
+ background: var(--neiki-bg-primary);
1422
+ color: var(--neiki-text-primary);
1423
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
1424
+ font-size: 13px;
1425
+ line-height: 1.5;
1426
+ resize: none;
1427
+ }
1428
+
1429
+ .neiki-code-view-textarea:focus {
1430
+ outline: none;
1431
+ }
1432
+
1433
+ .neiki-code-view-apply {
1434
+ width: auto !important;
1435
+ padding: 0 12px !important;
1436
+ display: inline-flex;
1437
+ align-items: center;
1438
+ gap: 4px;
1439
+ height: 30px;
1440
+ font-size: 12px;
1441
+ background: var(--neiki-accent-color) !important;
1442
+ color: white !important;
1443
+ border-radius: 5px;
1444
+ }
1445
+
1446
+ .neiki-code-view-apply:hover {
1447
+ background: var(--neiki-accent-hover) !important;
1448
+ color: white !important;
1449
+ }
1450
+
1451
+ .neiki-code-view-apply svg {
1452
+ width: 14px !important;
1453
+ height: 14px !important;
1454
+ }
1455
+
1456
+ /* ============================================
1457
+ Context Menu
1458
+ ============================================ */
1459
+ .neiki-context-menu {
1460
+ position: fixed;
1461
+ z-index: 10001;
1462
+ min-width: 180px;
1463
+ background: var(--neiki-bg-primary);
1464
+ border: 1px solid var(--neiki-border-color);
1465
+ border-radius: 8px;
1466
+ box-shadow: var(--neiki-shadow-lg);
1467
+ padding: 4px;
1468
+ display: none;
1469
+ }
1470
+
1471
+ .neiki-context-menu.show {
1472
+ display: block;
1473
+ }
1474
+
1475
+ .neiki-context-item,
1476
+ .neiki-context-menu-item {
1477
+ display: flex;
1478
+ align-items: center;
1479
+ gap: 10px;
1480
+ padding: 8px 12px;
1481
+ border-radius: 4px;
1482
+ cursor: pointer;
1483
+ color: var(--neiki-text-primary);
1484
+ font-size: 13px;
1485
+ transition: background 0.1s;
1486
+ }
1487
+
1488
+ .neiki-context-item:hover,
1489
+ .neiki-context-menu-item:hover {
1490
+ background: var(--neiki-bg-hover);
1491
+ }
1492
+
1493
+ .neiki-context-item.neiki-context-danger,
1494
+ .neiki-context-menu-item.danger {
1495
+ color: var(--neiki-danger-color);
1496
+ }
1497
+
1498
+ .neiki-context-item svg,
1499
+ .neiki-context-menu-item svg {
1500
+ width: 16px;
1501
+ height: 16px;
1502
+ fill: currentColor;
1503
+ }
1504
+
1505
+ .neiki-context-divider,
1506
+ .neiki-context-menu-divider {
1507
+ height: 1px;
1508
+ background: var(--neiki-border-color);
1509
+ margin: 4px 0;
1510
+ }
1511
+
1512
+ /* ============================================
1513
+ Floating Selection Toolbar
1514
+ ============================================ */
1515
+ .neiki-floating-toolbar {
1516
+ position: absolute;
1517
+ z-index: 1000;
1518
+ display: none;
1519
+ background: var(--neiki-bg-primary);
1520
+ border: 1px solid var(--neiki-border-color);
1521
+ border-radius: 8px;
1522
+ box-shadow: var(--neiki-shadow-lg);
1523
+ padding: 4px;
1524
+ }
1525
+
1526
+ .neiki-floating-toolbar.show {
1527
+ display: flex;
1528
+ align-items: center;
1529
+ gap: 2px;
1530
+ }
1531
+
1532
+ .neiki-floating-btn {
1533
+ width: 32px;
1534
+ height: 32px;
1535
+ border: none;
1536
+ background: var(--neiki-bg-primary);
1537
+ color: var(--neiki-text-primary);
1538
+ border-radius: 6px;
1539
+ cursor: pointer;
1540
+ display: flex;
1541
+ align-items: center;
1542
+ justify-content: center;
1543
+ transition: all 0.15s;
1544
+ }
1545
+
1546
+ .neiki-floating-btn:hover {
1547
+ background: var(--neiki-bg-hover);
1548
+ color: var(--neiki-accent-color);
1549
+ }
1550
+
1551
+ .neiki-floating-btn:active {
1552
+ background: var(--neiki-bg-active);
1553
+ }
1554
+
1555
+ .neiki-floating-btn svg {
1556
+ width: 16px;
1557
+ height: 16px;
1558
+ fill: currentColor;
1559
+ }
1560
+
1561
+ .neiki-floating-toolbar .neiki-btn {
1562
+ width: 28px;
1563
+ height: 28px;
1564
+ }
1565
+
1566
+ .neiki-floating-toolbar .neiki-btn svg {
1567
+ width: 14px;
1568
+ height: 14px;
1569
+ }
1570
+
1571
+ .neiki-floating-divider {
1572
+ width: 1px;
1573
+ height: 20px;
1574
+ background: var(--neiki-border-color);
1575
+ margin: 0 2px;
1576
+ }
1577
+
1578
+ .neiki-floating-move-btn svg {
1579
+ width: 16px;
1580
+ height: 16px;
1581
+ }
1582
+
1583
+ /* ============================================
1584
+ Tooltips
1585
+ ============================================ */
1586
+ [data-tooltip] {
1587
+ position: relative;
1588
+ }
1589
+
1590
+ [data-tooltip]::after {
1591
+ content: attr(data-tooltip);
1592
+ position: absolute;
1593
+ bottom: 100%;
1594
+ left: 50%;
1595
+ transform: translateX(-50%);
1596
+ padding: 6px 10px;
1597
+ background: var(--neiki-text-primary);
1598
+ color: var(--neiki-bg-primary);
1599
+ font-size: 11px;
1600
+ font-weight: 500;
1601
+ white-space: nowrap;
1602
+ border-radius: 4px;
1603
+ opacity: 0;
1604
+ visibility: hidden;
1605
+ transition: opacity 0.15s, visibility 0.15s;
1606
+ pointer-events: none;
1607
+ z-index: 10002;
1608
+ margin-bottom: 6px;
1609
+ }
1610
+
1611
+ [data-tooltip]:hover::after {
1612
+ opacity: 1;
1613
+ visibility: visible;
1614
+ }
1615
+
1616
+ /* ============================================
1617
+ Drag & Drop Overlay
1618
+ ============================================ */
1619
+ .neiki-drop-overlay {
1620
+ position: absolute;
1621
+ top: 0;
1622
+ left: 0;
1623
+ right: 0;
1624
+ bottom: 0;
1625
+ background: rgba(13, 110, 253, 0.1);
1626
+ border: 3px dashed var(--neiki-accent-color);
1627
+ border-radius: 8px;
1628
+ display: none;
1629
+ align-items: center;
1630
+ justify-content: center;
1631
+ z-index: 100;
1632
+ pointer-events: none;
1633
+ }
1634
+
1635
+ .neiki-drop-overlay.show {
1636
+ display: flex;
1637
+ }
1638
+
1639
+ .neiki-drop-overlay-text {
1640
+ font-size: 18px;
1641
+ font-weight: 600;
1642
+ color: var(--neiki-accent-color);
1643
+ }
1644
+
1645
+ /* ============================================
1646
+ Image Resize Handles
1647
+ ============================================ */
1648
+ .neiki-img-resizable {
1649
+ display: inline-block;
1650
+ position: relative;
1651
+ outline: 2px solid var(--neiki-accent-color);
1652
+ outline-offset: 2px;
1653
+ border-radius: 4px;
1654
+ line-height: 0;
1655
+ }
1656
+
1657
+ .neiki-img-resizable img {
1658
+ display: block;
1659
+ max-width: 100%;
1660
+ }
1661
+
1662
+ .neiki-img-resize-handle {
1663
+ position: absolute;
1664
+ width: 12px;
1665
+ height: 12px;
1666
+ background: var(--neiki-accent-color);
1667
+ border: 2px solid #fff;
1668
+ border-radius: 2px;
1669
+ z-index: 10;
1670
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
1671
+ }
1672
+
1673
+ .neiki-img-resize-handle.nw { top: -6px; left: -6px; cursor: nw-resize; }
1674
+ .neiki-img-resize-handle.ne { top: -6px; right: -6px; cursor: ne-resize; }
1675
+ .neiki-img-resize-handle.sw { bottom: -6px; left: -6px; cursor: sw-resize; }
1676
+ .neiki-img-resize-handle.se { bottom: -6px; right: -6px; cursor: se-resize; }
1677
+
1678
+ .neiki-img-size-label {
1679
+ position: absolute;
1680
+ bottom: -32px;
1681
+ left: 50%;
1682
+ transform: translateX(-50%);
1683
+ background: var(--neiki-text-primary);
1684
+ color: var(--neiki-bg-primary);
1685
+ font-size: 13px;
1686
+ line-height: 1.4;
1687
+ font-weight: 600;
1688
+ padding: 4px 12px;
1689
+ border-radius: 6px;
1690
+ white-space: nowrap;
1691
+ pointer-events: none;
1692
+ z-index: 10;
1693
+ opacity: 0.9;
1694
+ }
1695
+
1696
+ /* Touch-friendly resize handles */
1697
+ @media (pointer: coarse) {
1698
+ .neiki-img-resize-handle {
1699
+ width: 20px;
1700
+ height: 20px;
1701
+ }
1702
+ .neiki-img-resize-handle.nw { top: -10px; left: -10px; }
1703
+ .neiki-img-resize-handle.ne { top: -10px; right: -10px; }
1704
+ .neiki-img-resize-handle.sw { bottom: -10px; left: -10px; }
1705
+ .neiki-img-resize-handle.se { bottom: -10px; right: -10px; }
1706
+ }
1707
+
1708
+ /* ============================================
1709
+ Image Toolbar (replace, delete, drag)
1710
+ ============================================ */
1711
+ .neiki-img-toolbar {
1712
+ position: absolute;
1713
+ left: 50%;
1714
+ transform: translateX(-50%);
1715
+ display: flex;
1716
+ align-items: center;
1717
+ gap: 2px;
1718
+ padding: 4px;
1719
+ background: var(--neiki-bg-primary);
1720
+ border: 1px solid var(--neiki-border-color);
1721
+ border-radius: 6px;
1722
+ box-shadow: var(--neiki-shadow-md);
1723
+ z-index: 20;
1724
+ white-space: nowrap;
1725
+ }
1726
+
1727
+ .neiki-img-toolbar-btn {
1728
+ display: inline-flex;
1729
+ align-items: center;
1730
+ justify-content: center;
1731
+ width: 30px;
1732
+ height: 30px;
1733
+ border: none;
1734
+ border-radius: 4px;
1735
+ background: transparent;
1736
+ color: var(--neiki-text-secondary);
1737
+ cursor: pointer;
1738
+ transition: all 0.15s;
1739
+ }
1740
+
1741
+ .neiki-img-toolbar-btn:hover {
1742
+ background: var(--neiki-bg-hover);
1743
+ color: var(--neiki-accent-color);
1744
+ }
1745
+
1746
+ .neiki-img-toolbar-btn-danger:hover {
1747
+ background: #fee2e2;
1748
+ color: #dc2626;
1749
+ }
1750
+
1751
+ .neiki-editor.neiki-dark .neiki-img-toolbar-btn-danger:hover {
1752
+ background: #451a1a;
1753
+ color: #f87171;
1754
+ }
1755
+
1756
+ .neiki-img-toolbar-btn svg {
1757
+ width: 16px;
1758
+ height: 16px;
1759
+ fill: currentColor;
1760
+ }
1761
+
1762
+ .neiki-img-toolbar-separator {
1763
+ width: 1px;
1764
+ height: 20px;
1765
+ background: var(--neiki-border-color);
1766
+ margin: 0 2px;
1767
+ }
1768
+
1769
+ .neiki-img-drag-handle {
1770
+ cursor: grab;
1771
+ }
1772
+
1773
+ .neiki-img-drag-handle:active {
1774
+ cursor: grabbing;
1775
+ }
1776
+
1777
+ /* ============================================
1778
+ Table Column Resize Handle
1779
+ ============================================ */
1780
+ .neiki-table-col-resize-handle {
1781
+ position: absolute;
1782
+ width: 6px;
1783
+ cursor: col-resize;
1784
+ z-index: 10;
1785
+ background: transparent;
1786
+ transition: background 0.1s;
1787
+ }
1788
+
1789
+ .neiki-table-col-resize-handle:hover,
1790
+ .neiki-table-col-resize-handle:active {
1791
+ background: var(--neiki-accent-color);
1792
+ opacity: 0.6;
1793
+ border-radius: 3px;
1794
+ }
1795
+
1796
+ /* ============================================
1797
+ Block Drag & Drop
1798
+ ============================================ */
1799
+ .neiki-block-grip {
1800
+ position: absolute;
1801
+ width: 22px;
1802
+ height: 22px;
1803
+ display: flex;
1804
+ align-items: center;
1805
+ justify-content: center;
1806
+ cursor: grab;
1807
+ color: var(--neiki-text-muted);
1808
+ opacity: 0;
1809
+ transition: opacity 0.15s, color 0.15s;
1810
+ border-radius: 4px;
1811
+ z-index: 5;
1812
+ user-select: none;
1813
+ }
1814
+
1815
+ .neiki-content:hover .neiki-block-grip {
1816
+ opacity: 0.5;
1817
+ }
1818
+
1819
+ .neiki-block-grip:hover {
1820
+ opacity: 1 !important;
1821
+ color: var(--neiki-text-primary);
1822
+ background: var(--neiki-bg-hover);
1823
+ }
1824
+
1825
+ .neiki-block-grip:active {
1826
+ cursor: grabbing;
1827
+ }
1828
+
1829
+ .neiki-block-grip svg {
1830
+ width: 14px;
1831
+ height: 14px;
1832
+ fill: currentColor;
1833
+ pointer-events: none;
1834
+ }
1835
+
1836
+ .neiki-block-ghost {
1837
+ position: fixed;
1838
+ z-index: 100000;
1839
+ pointer-events: none;
1840
+ opacity: 0.7;
1841
+ background: var(--neiki-bg-primary);
1842
+ border: 2px solid var(--neiki-accent-color);
1843
+ border-radius: 6px;
1844
+ padding: 8px 12px;
1845
+ box-shadow: var(--neiki-shadow-lg);
1846
+ max-height: 120px;
1847
+ overflow: hidden;
1848
+ }
1849
+
1850
+ .neiki-block-placeholder {
1851
+ border: 2px dashed var(--neiki-accent-color);
1852
+ border-radius: 6px;
1853
+ background: rgba(13, 110, 253, 0.05);
1854
+ margin: 2px 0;
1855
+ transition: height 0.15s ease;
1856
+ }
1857
+
1858
+ /* ============================================
1859
+ Print Styles
1860
+ ============================================ */
1861
+ @media print {
1862
+ .neiki-editor {
1863
+ border: none !important;
1864
+ box-shadow: none !important;
1865
+ }
1866
+
1867
+ .neiki-toolbar,
1868
+ .neiki-statusbar,
1869
+ .neiki-floating-toolbar,
1870
+ .neiki-find-replace,
1871
+ .neiki-code-view-header,
1872
+ .neiki-block-grip,
1873
+ .neiki-img-resize-handle,
1874
+ .neiki-img-size-label,
1875
+ .neiki-img-toolbar,
1876
+ .neiki-table-col-resize-handle {
1877
+ display: none !important;
1878
+ }
1879
+
1880
+ .neiki-content {
1881
+ padding: 0 !important;
1882
+ overflow: visible !important;
1883
+ }
1884
+
1885
+ .neiki-editor-wrapper {
1886
+ overflow: visible !important;
1887
+ }
1888
+ }
1889
+
1890
+ /* ============================================
1891
+ Responsive Adjustments
1892
+ ============================================ */
1893
+ @media (max-width: 768px) {
1894
+ .neiki-toolbar {
1895
+ padding: 4px;
1896
+ gap: 1px;
1897
+ }
1898
+
1899
+ .neiki-toolbar-group {
1900
+ padding: 0 2px;
1901
+ }
1902
+
1903
+ .neiki-toolbar-group:not(:last-child) {
1904
+ padding-right: 4px;
1905
+ margin-right: 2px;
1906
+ }
1907
+
1908
+ .neiki-btn {
1909
+ width: 28px;
1910
+ height: 28px;
1911
+ }
1912
+
1913
+ .neiki-btn svg {
1914
+ width: 16px;
1915
+ height: 16px;
1916
+ }
1917
+
1918
+ .neiki-select {
1919
+ height: 28px;
1920
+ min-width: 80px;
1921
+ font-size: 12px;
1922
+ padding: 0 24px 0 8px;
1923
+ }
1924
+
1925
+ .neiki-content {
1926
+ padding: 12px 16px;
1927
+ }
1928
+
1929
+ .neiki-statusbar {
1930
+ padding: 4px 8px;
1931
+ font-size: 11px;
1932
+ }
1933
+
1934
+ .neiki-modal {
1935
+ width: calc(100% - 20px);
1936
+ max-width: none;
1937
+ margin: 10px;
1938
+ max-height: calc(100vh - 40px);
1939
+ border-radius: 10px;
1940
+ }
1941
+
1942
+ .neiki-modal-overlay {
1943
+ padding: 10px;
1944
+ }
1945
+
1946
+ .neiki-modal-header {
1947
+ padding: 12px 16px;
1948
+ }
1949
+
1950
+ .neiki-modal-body {
1951
+ padding: 16px;
1952
+ max-height: calc(100vh - 160px);
1953
+ overflow-y: auto;
1954
+ -webkit-overflow-scrolling: touch;
1955
+ }
1956
+
1957
+ .neiki-modal-footer {
1958
+ padding: 12px 16px;
1959
+ }
1960
+
1961
+ .neiki-modal-footer .neiki-btn {
1962
+ height: 36px;
1963
+ padding: 0 14px;
1964
+ font-size: 13px;
1965
+ }
1966
+
1967
+ .neiki-form-row {
1968
+ flex-direction: column;
1969
+ gap: 12px;
1970
+ }
1971
+
1972
+ .neiki-form-input,
1973
+ .neiki-input {
1974
+ height: 38px;
1975
+ font-size: 16px; /* Prevents iOS zoom on focus */
1976
+ }
1977
+
1978
+ .neiki-find-replace {
1979
+ width: 100%;
1980
+ border-radius: 0;
1981
+ }
1982
+
1983
+ .neiki-checkbox-wrapper {
1984
+ padding: 0 4px;
1985
+ font-size: 11px;
1986
+ }
1987
+
1988
+ .neiki-color-picker {
1989
+ left: auto;
1990
+ right: 0;
1991
+ }
1992
+ }
1993
+
1994
+ @media (max-width: 480px) {
1995
+ .neiki-toolbar-group:not(:last-child) {
1996
+ border-right: none;
1997
+ padding-right: 2px;
1998
+ margin-right: 0;
1999
+ }
2000
+
2001
+ .neiki-select {
2002
+ min-width: 60px;
2003
+ }
2004
+
2005
+ .neiki-statusbar-left,
2006
+ .neiki-statusbar-right {
2007
+ gap: 8px;
2008
+ }
2009
+
2010
+ .neiki-img-toolbar {
2011
+ padding: 3px;
2012
+ gap: 1px;
2013
+ border-radius: 5px;
2014
+ left: 0;
2015
+ transform: none;
2016
+ max-width: calc(100vw - 20px);
2017
+ }
2018
+
2019
+ .neiki-img-toolbar-btn {
2020
+ width: 26px;
2021
+ height: 26px;
2022
+ }
2023
+
2024
+ .neiki-img-toolbar-btn svg {
2025
+ width: 14px;
2026
+ height: 14px;
2027
+ }
2028
+
2029
+ .neiki-img-toolbar-separator {
2030
+ height: 16px;
2031
+ margin: 0 1px;
2032
+ }
2033
+ }
2034
+
2035
+ /* ============================================
2036
+ Animations
2037
+ ============================================ */
2038
+ @keyframes neiki-fade-in {
2039
+ from {
2040
+ opacity: 0;
2041
+ transform: translateY(-10px);
2042
+ }
2043
+ to {
2044
+ opacity: 1;
2045
+ transform: translateY(0);
2046
+ }
2047
+ }
2048
+
2049
+ .neiki-dropdown.show,
2050
+ .neiki-color-picker.show,
2051
+ .neiki-table-picker.show,
2052
+ .neiki-emoji-picker.show,
2053
+ .neiki-special-chars.show {
2054
+ animation: neiki-fade-in 0.15s ease;
2055
+ }
2056
+
2057
+ @keyframes neiki-modal-in {
2058
+ from {
2059
+ opacity: 0;
2060
+ transform: scale(0.95);
2061
+ }
2062
+ to {
2063
+ opacity: 1;
2064
+ transform: scale(1);
2065
+ }
2066
+ }
2067
+
2068
+ .neiki-modal-overlay.show .neiki-modal {
2069
+ animation: neiki-modal-in 0.2s ease;
2070
+ }
2071
+
2072
+ /* ============================================
2073
+ Font Size Widget
2074
+ ============================================ */
2075
+ .neiki-fontsize-widget {
2076
+ display: inline-flex;
2077
+ align-items: center;
2078
+ position: relative;
2079
+ height: 32px;
2080
+ border: 1px solid var(--neiki-border-color);
2081
+ border-radius: 4px;
2082
+ overflow: visible;
2083
+ background: var(--neiki-bg-primary);
2084
+ }
2085
+
2086
+ .neiki-fontsize-btn {
2087
+ display: flex;
2088
+ align-items: center;
2089
+ justify-content: center;
2090
+ width: 26px;
2091
+ height: 30px;
2092
+ background: transparent;
2093
+ border: none;
2094
+ cursor: pointer;
2095
+ color: var(--neiki-text-secondary);
2096
+ transition: background 0.15s, color 0.15s;
2097
+ padding: 0;
2098
+ }
2099
+
2100
+ .neiki-fontsize-btn:hover {
2101
+ background: var(--neiki-bg-hover);
2102
+ color: var(--neiki-text-primary);
2103
+ }
2104
+
2105
+ .neiki-fontsize-input {
2106
+ width: 38px;
2107
+ height: 30px;
2108
+ text-align: center;
2109
+ border: none;
2110
+ border-left: 1px solid var(--neiki-border-color);
2111
+ border-right: 1px solid var(--neiki-border-color);
2112
+ background: var(--neiki-bg-primary);
2113
+ color: var(--neiki-text-primary);
2114
+ font-size: 13px;
2115
+ outline: none;
2116
+ -moz-appearance: textfield;
2117
+ appearance: textfield;
2118
+ padding: 0;
2119
+ }
2120
+
2121
+ .neiki-fontsize-input::-webkit-outer-spin-button,
2122
+ .neiki-fontsize-input::-webkit-inner-spin-button {
2123
+ -webkit-appearance: none;
2124
+ margin: 0;
2125
+ }
2126
+
2127
+ .neiki-fontsize-dropdown {
2128
+ display: none;
2129
+ position: absolute;
2130
+ top: 100%;
2131
+ left: 0;
2132
+ z-index: 1000;
2133
+ min-width: 70px;
2134
+ max-height: 240px;
2135
+ overflow-y: auto;
2136
+ background: var(--neiki-bg-primary);
2137
+ border: 1px solid var(--neiki-border-color);
2138
+ border-radius: 6px;
2139
+ box-shadow: var(--neiki-shadow-lg);
2140
+ padding: 4px;
2141
+ margin-top: 4px;
2142
+ }
2143
+
2144
+ .neiki-fontsize-dropdown.show {
2145
+ display: block;
2146
+ }
2147
+
2148
+ .neiki-fontsize-dropdown-item {
2149
+ padding: 6px 12px;
2150
+ font-size: 13px;
2151
+ cursor: pointer;
2152
+ border-radius: 4px;
2153
+ color: var(--neiki-text-primary);
2154
+ text-align: center;
2155
+ transition: background 0.1s;
2156
+ }
2157
+
2158
+ .neiki-fontsize-dropdown-item:hover {
2159
+ background: var(--neiki-bg-hover);
2160
+ }
2161
+
2162
+ /* ============================================
2163
+ Insert Dropdown Button
2164
+ ============================================ */
2165
+ .neiki-insert-dropdown-btn {
2166
+ width: auto !important;
2167
+ padding: 0 8px !important;
2168
+ gap: 4px;
2169
+ font-size: 13px;
2170
+ font-weight: 500;
2171
+ }
2172
+
2173
+ .neiki-insert-label {
2174
+ font-size: 13px;
2175
+ pointer-events: none;
2176
+ }
2177
+
2178
+ .neiki-chevron {
2179
+ display: inline-flex;
2180
+ pointer-events: none;
2181
+ }
2182
+
2183
+ .neiki-chevron svg {
2184
+ width: 14px;
2185
+ height: 14px;
2186
+ }
2187
+
2188
+ .neiki-insert-dropdown {
2189
+ display: none;
2190
+ position: absolute;
2191
+ top: 100%;
2192
+ left: 0;
2193
+ z-index: 1000;
2194
+ min-width: 160px;
2195
+ max-width: calc(100vw - 16px);
2196
+ background: var(--neiki-bg-primary);
2197
+ border: 1px solid var(--neiki-border-color);
2198
+ border-radius: 6px;
2199
+ box-shadow: var(--neiki-shadow-lg);
2200
+ padding: 4px;
2201
+ margin-top: 4px;
2202
+ }
2203
+
2204
+ .neiki-insert-dropdown.show {
2205
+ display: block;
2206
+ animation: neiki-fade-in 0.15s ease;
2207
+ }
2208
+
2209
+ /* ============================================
2210
+ More Menu (⋯) Dropdown
2211
+ ============================================ */
2212
+ .neiki-more-btn {
2213
+ position: relative;
2214
+ }
2215
+
2216
+ .neiki-more-dropdown {
2217
+ display: none;
2218
+ position: absolute;
2219
+ top: 100%;
2220
+ right: 0;
2221
+ z-index: 1000;
2222
+ min-width: 140px;
2223
+ max-width: 170px;
2224
+ background: var(--neiki-bg-primary);
2225
+ border: 1px solid var(--neiki-border-color);
2226
+ border-radius: 6px;
2227
+ box-shadow: var(--neiki-shadow-lg);
2228
+ padding: 4px;
2229
+ margin-top: 4px;
2230
+ }
2231
+
2232
+ .neiki-more-dropdown.show {
2233
+ display: block;
2234
+ animation: neiki-fade-in 0.15s ease;
2235
+ }
2236
+
2237
+ /* Czech language - wider dropdown for longer labels */
2238
+ .neiki-lang-cs .neiki-more-dropdown {
2239
+ min-width: 165px;
2240
+ }
2241
+
2242
+ /* Dropdown item with icon */
2243
+ .neiki-dropdown-item-icon {
2244
+ display: inline-flex;
2245
+ align-items: center;
2246
+ justify-content: center;
2247
+ width: 18px;
2248
+ height: 18px;
2249
+ flex-shrink: 0;
2250
+ }
2251
+
2252
+ .neiki-dropdown-item-icon svg {
2253
+ width: 16px;
2254
+ height: 16px;
2255
+ fill: currentColor;
2256
+ }
2257
+
2258
+ .neiki-dropdown-item-danger {
2259
+ color: var(--neiki-danger-color) !important;
2260
+ }
2261
+
2262
+ .neiki-dropdown-item-danger:hover {
2263
+ background: rgba(220, 53, 69, 0.1);
2264
+ }
2265
+
2266
+ /* Autosave badge in More menu */
2267
+ .neiki-autosave-badge {
2268
+ font-size: 12px;
2269
+ font-weight: 600;
2270
+ color: var(--neiki-text-muted);
2271
+ padding: 0 4px;
2272
+ }
2273
+
2274
+ .neiki-autosave-badge.active {
2275
+ color: var(--neiki-success-color);
2276
+ }
2277
+
2278
+ /* ============================================
2279
+ Preview Modal
2280
+ ============================================ */
2281
+ .neiki-preview-overlay {
2282
+ position: fixed;
2283
+ inset: 0;
2284
+ background: rgba(0, 0, 0, 0.6);
2285
+ z-index: 100000;
2286
+ display: flex;
2287
+ align-items: center;
2288
+ justify-content: center;
2289
+ padding: 30px;
2290
+ animation: neiki-fade-in 0.2s ease;
2291
+ }
2292
+
2293
+ .neiki-preview-modal {
2294
+ background: var(--neiki-bg-primary);
2295
+ border-radius: 12px;
2296
+ width: 100%;
2297
+ max-width: 900px;
2298
+ max-height: 90vh;
2299
+ display: flex;
2300
+ flex-direction: column;
2301
+ overflow: hidden;
2302
+ box-shadow: 0 25px 60px rgba(0, 0, 0, 0.3);
2303
+ animation: neiki-modal-in 0.2s ease;
2304
+ }
2305
+
2306
+ .neiki-preview-header {
2307
+ display: flex;
2308
+ align-items: center;
2309
+ justify-content: space-between;
2310
+ padding: 14px 20px;
2311
+ background: var(--neiki-bg-secondary);
2312
+ border-bottom: 1px solid var(--neiki-border-color);
2313
+ font-weight: 600;
2314
+ font-size: 14px;
2315
+ color: var(--neiki-text-primary);
2316
+ }
2317
+
2318
+ .neiki-preview-close {
2319
+ width: 32px;
2320
+ height: 32px;
2321
+ display: flex;
2322
+ align-items: center;
2323
+ justify-content: center;
2324
+ background: transparent;
2325
+ border: none;
2326
+ border-radius: 4px;
2327
+ cursor: pointer;
2328
+ color: var(--neiki-text-muted);
2329
+ transition: background 0.15s;
2330
+ }
2331
+
2332
+ .neiki-preview-close:hover {
2333
+ background: var(--neiki-bg-hover);
2334
+ color: var(--neiki-text-primary);
2335
+ }
2336
+
2337
+ .neiki-preview-close svg {
2338
+ width: 18px;
2339
+ height: 18px;
2340
+ fill: currentColor;
2341
+ }
2342
+
2343
+ .neiki-preview-body {
2344
+ flex: 1;
2345
+ overflow: auto;
2346
+ padding: 30px;
2347
+ color: var(--neiki-text-primary);
2348
+ font-size: 15px;
2349
+ line-height: 1.7;
2350
+ }
2351
+
2352
+ .neiki-preview-body img {
2353
+ max-width: 100%;
2354
+ }
2355
+
2356
+ .neiki-preview-body table {
2357
+ border-collapse: collapse;
2358
+ width: 100%;
2359
+ }
2360
+
2361
+ .neiki-preview-body table td,
2362
+ .neiki-preview-body table th {
2363
+ border: 1px solid var(--neiki-border-color);
2364
+ padding: 8px 12px;
2365
+ }
2366
+
2367
+ /* Autosave status in statusbar */
2368
+ .neiki-statusbar-autosave {
2369
+ font-style: italic;
2370
+ color: var(--neiki-success-color);
2371
+ font-size: 11px;
2372
+ }