autumnnote 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +72 -5
  2. package/dist/autumnnote.cjs +20 -20
  3. package/dist/autumnnote.es.js +385 -619
  4. package/dist/autumnnote.es.js.map +1 -1
  5. package/dist/autumnnote.min.js +20 -20
  6. package/dist/autumnnote.umd.js +20 -20
  7. package/dist/autumnnote.umd.js.map +1 -1
  8. package/dist/icon-data-V0Xqv-wX.js +255 -0
  9. package/dist/icon-data-V0Xqv-wX.js.map +1 -0
  10. package/package.json +12 -3
  11. package/types/index.d.ts +8 -0
  12. package/src/js/Context.js +0 -854
  13. package/src/js/core/detectLang.js +0 -98
  14. package/src/js/core/dom.js +0 -372
  15. package/src/js/core/env.js +0 -38
  16. package/src/js/core/key.js +0 -66
  17. package/src/js/core/lists.js +0 -121
  18. package/src/js/core/markdown.js +0 -695
  19. package/src/js/core/range.js +0 -194
  20. package/src/js/core/sanitise.js +0 -304
  21. package/src/js/editing/History.js +0 -266
  22. package/src/js/editing/Style.js +0 -812
  23. package/src/js/editing/Table.js +0 -105
  24. package/src/js/editing/Typing.js +0 -397
  25. package/src/js/index.js +0 -193
  26. package/src/js/index.umd.js +0 -17
  27. package/src/js/module/AutoSaveRestore.js +0 -125
  28. package/src/js/module/BaseDialog.js +0 -133
  29. package/src/js/module/BaseMediaTooltip.js +0 -142
  30. package/src/js/module/BaseResizer.js +0 -322
  31. package/src/js/module/BubbleToolbar.js +0 -483
  32. package/src/js/module/Buttons.js +0 -399
  33. package/src/js/module/Clipboard.js +0 -579
  34. package/src/js/module/CodeTooltip.js +0 -493
  35. package/src/js/module/Codeview.js +0 -125
  36. package/src/js/module/ContextMenu.js +0 -621
  37. package/src/js/module/Editor.js +0 -747
  38. package/src/js/module/EmojiDialog.js +0 -254
  39. package/src/js/module/FindReplace.js +0 -512
  40. package/src/js/module/Fullscreen.js +0 -80
  41. package/src/js/module/IconDialog.js +0 -618
  42. package/src/js/module/ImageCropOverlay.js +0 -586
  43. package/src/js/module/ImageDialog.js +0 -193
  44. package/src/js/module/ImageResizer.js +0 -42
  45. package/src/js/module/ImageTooltip.js +0 -285
  46. package/src/js/module/LinkDialog.js +0 -145
  47. package/src/js/module/LinkTooltip.js +0 -250
  48. package/src/js/module/MarkdownShortcuts.js +0 -250
  49. package/src/js/module/Mention.js +0 -365
  50. package/src/js/module/Placeholder.js +0 -51
  51. package/src/js/module/ShortcutsDialog.js +0 -111
  52. package/src/js/module/SlashMenu.js +0 -376
  53. package/src/js/module/Statusbar.js +0 -246
  54. package/src/js/module/TableTooltip.js +0 -1392
  55. package/src/js/module/Toolbar.js +0 -855
  56. package/src/js/module/VideoDialog.js +0 -193
  57. package/src/js/module/VideoResizer.js +0 -66
  58. package/src/js/module/VideoTooltip.js +0 -248
  59. package/src/js/module/emoji-data.js +0 -496
  60. package/src/js/module/table-grid.js +0 -102
  61. package/src/js/module/table-icons.js +0 -33
  62. package/src/js/renderer.js +0 -120
  63. package/src/js/settings.js +0 -214
  64. package/src/styles/_variables.scss +0 -48
  65. package/src/styles/autumnnote.scss +0 -2877
@@ -1,2877 +0,0 @@
1
- /**
2
- * autumnnote.scss — Main stylesheet for the AutumnNote editor
3
- * Inspired by Summernote — rewritten with cleaner, modern CSS
4
- */
5
-
6
- @use 'variables' as *;
7
-
8
- // =============================================================================
9
- // Container
10
- // =============================================================================
11
-
12
- .an-container {
13
- display: flex;
14
- flex-direction: column;
15
- position: relative;
16
- border: 1px solid $an-border;
17
- border-radius: $an-radius;
18
- font-family: $an-font-family;
19
- font-size: $an-font-size;
20
- box-sizing: border-box;
21
- background: $an-bg;
22
- // Prevent the container from participating in ancestor layout recalculations.
23
- // This limits reflow thrashing when editing large documents.
24
- contain: layout;
25
-
26
- *,
27
- *::before,
28
- *::after {
29
- box-sizing: border-box;
30
- }
31
-
32
- &.an-focused {
33
- border-color: var(--an-focus-color, #{$an-primary});
34
- // Fallback glow for browsers without color-mix() (pre-Chrome 111, Safari 15.3, Firefox 112).
35
- // Uses the static $an-primary value so --an-focus-color overrides are ignored in those browsers.
36
- box-shadow: 0 0 0 3px rgba($an-primary, 0.18);
37
- // Modern browsers get a fully themeable glow that respects --an-focus-color.
38
- @supports (color: color-mix(in srgb, red, blue)) {
39
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--an-focus-color, #{$an-primary}) 18%, transparent);
40
- }
41
- }
42
-
43
- &.an-disabled {
44
- // Hide toolbar only — read-only view has no editing controls.
45
- .an-toolbar {
46
- display: none;
47
- }
48
-
49
- // Allow the user to select and copy text but block actual editing.
50
- // Do NOT set pointer-events:none or user-select:none on the container —
51
- // that would prevent text selection inside the editable area.
52
- .an-editable {
53
- cursor: text;
54
- user-select: text;
55
- // No background change — keep the same appearance as editable mode
56
- // so read-only content looks identical to the live editor.
57
-
58
- // Block checklist checkbox interaction in read-only mode.
59
- // Keep opacity:1 so disabled checkboxes are still clearly visible.
60
- ul.an-checklist input[type='checkbox'] {
61
- pointer-events: none;
62
- cursor: default;
63
- opacity: 1;
64
- }
65
-
66
- // Prevent images from being dragged out.
67
- img {
68
- -webkit-user-drag: none;
69
- }
70
-
71
- // Prevent video wrapper itself from being dragged, but keep pointer-events
72
- // active so the video shield works and the iframe is visible/interactive.
73
- .an-video-wrapper {
74
- -webkit-user-drag: none;
75
- }
76
-
77
- // D-3: In read-only mode, disable the video shield so clicks reach the
78
- // underlying <iframe> / <video> and users can play videos normally.
79
- // The shield is only needed in edit mode to prevent accidental interaction.
80
- .an-video-wrapper .an-video-shield {
81
- pointer-events: none;
82
- }
83
- }
84
- }
85
-
86
- &.an-fullscreen {
87
- position: fixed;
88
- inset: 0;
89
- z-index: 9990;
90
- border-radius: 0;
91
- border: none;
92
-
93
- .an-editable {
94
- flex: 1;
95
- max-height: none !important;
96
- }
97
- }
98
- }
99
-
100
- @media (prefers-reduced-motion: reduce) {
101
- .an-container *,
102
- .an-dialog-overlay *,
103
- .an-slash-menu * {
104
- scroll-behavior: auto !important;
105
- animation-duration: 0.01ms !important;
106
- animation-iteration-count: 1 !important;
107
- transition-duration: 0.01ms !important;
108
- }
109
- }
110
-
111
- // =============================================================================
112
- // Toolbar
113
- // =============================================================================
114
-
115
- .an-toolbar {
116
- display: flex;
117
- flex-wrap: wrap;
118
- align-items: center;
119
- gap: $an-toolbar-gap;
120
- padding: $an-toolbar-pad;
121
- background: $an-bg-toolbar;
122
- border-bottom: 1px solid $an-border;
123
- user-select: none;
124
- // Round the top corners to match the container border-radius
125
- border-radius: $an-radius $an-radius 0 0;
126
- overflow-x: auto;
127
- scrollbar-width: none;
128
-
129
- &::-webkit-scrollbar {
130
- display: none;
131
- }
132
- }
133
-
134
- .an-btn-group {
135
- display: flex;
136
- align-items: center;
137
- gap: 2px;
138
-
139
- // Icon-only toolbar buttons should not have horizontal padding so all
140
- // buttons appear consistently square (min-width = height = $an-btn-height).
141
- // Dialog buttons (.an-dialog-actions .an-btn) keep their padding via the
142
- // lower-specificity .an-btn rule.
143
- > .an-btn { padding: 0; }
144
-
145
- // Separator between groups
146
- & + .an-btn-group {
147
- position: relative;
148
- padding-left: $an-toolbar-gap + 4px;
149
-
150
- &::before {
151
- content: '';
152
- position: absolute;
153
- left: 0;
154
- top: 15%;
155
- height: 70%;
156
- width: 1px;
157
- background: $an-border;
158
- }
159
- }
160
- }
161
-
162
- // Font-family (and generic) select dropdown in toolbar
163
- .an-select {
164
- height: $an-btn-height;
165
- padding: 0 24px 0 8px;
166
- background: $an-bg url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%236b7280'/%3E%3C/svg%3E") no-repeat right 7px center;
167
- background-size: 8px 5px;
168
- border: 1px solid $an-border;
169
- border-radius: $an-radius-sm;
170
- font-family: inherit;
171
- font-size: 12px;
172
- color: $an-text;
173
- cursor: pointer;
174
- appearance: none;
175
- -webkit-appearance: none;
176
- min-width: 110px;
177
- max-width: 160px;
178
- transition: border-color $an-transition, box-shadow $an-transition;
179
-
180
- &:hover {
181
- border-color: $an-primary;
182
- }
183
-
184
- &:focus {
185
- outline: none;
186
- border-color: $an-primary;
187
- box-shadow: 0 0 0 2px rgba($an-primary, 0.15);
188
- }
189
-
190
- option {
191
- font-size: 13px;
192
- }
193
- }
194
-
195
- // Narrow variant — used for short-value selects such as Line Height
196
- .an-select-narrow {
197
- min-width: 76px;
198
- max-width: 90px;
199
- padding-right: 20px;
200
- }
201
-
202
- // Paragraph-style variant — Normal/H1-H6/Quote/Code labels
203
- .an-select-style {
204
- min-width: 80px;
205
- max-width: 92px;
206
- padding-right: 20px;
207
- }
208
-
209
- // Table grid picker
210
- .an-table-picker-wrap {
211
- position: relative;
212
- display: inline-flex;
213
- }
214
-
215
- .an-table-picker-popup {
216
- display: none;
217
- position: fixed; // top/left set dynamically by JS — escapes overflow-clipping ancestors
218
- background: $an-bg;
219
- border: 1px solid $an-border;
220
- border-radius: 6px;
221
- padding: 8px;
222
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
223
- z-index: 1100;
224
- user-select: none;
225
- }
226
-
227
- .an-table-grid {
228
- display: grid;
229
- grid-template-columns: repeat(10, 18px);
230
- gap: 2px;
231
- }
232
-
233
- .an-table-cell {
234
- width: 18px;
235
- height: 18px;
236
- border: 1px solid $an-border;
237
- border-radius: 2px;
238
- cursor: pointer;
239
- background: $an-bg;
240
- transition: background $an-transition, border-color $an-transition;
241
-
242
- &.active {
243
- background: rgba($an-primary, 0.15);
244
- border-color: $an-primary;
245
- }
246
- }
247
-
248
- .an-table-label {
249
- margin-top: 6px;
250
- text-align: center;
251
- font-size: 12px;
252
- color: $an-muted;
253
- min-height: 16px;
254
- }
255
-
256
- // Context menu — inline table grid panel
257
- .an-context-table-grid-panel {
258
- padding: 6px 8px 8px;
259
- border-top: 1px solid $an-border;
260
- }
261
-
262
- // =============================================================================
263
- // Color picker (text color / highlight color) toolbar widget
264
- // =============================================================================
265
-
266
- .an-color-picker-wrap {
267
- position: relative;
268
- display: inline-flex;
269
- align-items: stretch;
270
- }
271
-
272
- // Left part: icon + color strip stacked vertically
273
- .an-color-btn {
274
- flex-direction: column !important;
275
- gap: 2px !important;
276
- padding: 4px 6px 3px !important;
277
- height: auto !important;
278
- min-height: $an-btn-height;
279
-
280
- .an-color-strip {
281
- display: block;
282
- width: 100%;
283
- min-width: 14px;
284
- height: 3px;
285
- border-radius: 1px;
286
- flex-shrink: 0;
287
- }
288
- }
289
-
290
- // Right part: small chevron arrow to open popup
291
- .an-color-arrow {
292
- padding: 0 3px !important;
293
- min-width: unset !important;
294
- border-left: 1px solid transparent;
295
-
296
- &:hover {
297
- border-left-color: $an-border;
298
- }
299
- }
300
-
301
- // Swatch popup panel
302
- .an-color-popup {
303
- position: fixed;
304
- // top / left are set dynamically by JS (getBoundingClientRect) so the popup
305
- // escapes overflow:hidden / overflow:auto ancestors (toolbar scroll mode, etc.)
306
- z-index: 1100;
307
- background: $an-bg;
308
- border: 1px solid $an-border;
309
- border-radius: 6px;
310
- padding: 8px;
311
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
312
- min-width: 184px;
313
- user-select: none;
314
- }
315
-
316
- .an-color-swatches {
317
- display: grid;
318
- grid-template-columns: repeat(8, 18px);
319
- gap: 3px;
320
- margin-bottom: 8px;
321
- }
322
-
323
- .an-color-swatch {
324
- width: 18px;
325
- height: 18px;
326
- border-radius: 2px;
327
- cursor: pointer;
328
- border: 1px solid rgba(0, 0, 0, 0.12);
329
- transition: transform 0.1s ease;
330
- position: relative;
331
-
332
- &:hover {
333
- transform: scale(1.25);
334
- z-index: 1;
335
- outline: 2px solid $an-primary;
336
- outline-offset: 1px;
337
- }
338
- }
339
-
340
- .an-color-custom {
341
- display: flex;
342
- align-items: center;
343
- gap: 8px;
344
- padding-top: 6px;
345
- border-top: 1px solid $an-border;
346
-
347
- input[type='color'] {
348
- width: 28px;
349
- height: 22px;
350
- padding: 1px 2px;
351
- border: 1px solid $an-border;
352
- border-radius: 3px;
353
- cursor: pointer;
354
- background: none;
355
- flex-shrink: 0;
356
- appearance: none;
357
- -webkit-appearance: none;
358
-
359
- &::-webkit-color-swatch-wrapper { padding: 0; }
360
- &::-webkit-color-swatch { border: none; border-radius: 2px; }
361
-
362
- &:hover {
363
- border-color: $an-primary;
364
- }
365
- }
366
-
367
- span {
368
- font-size: 11px;
369
- color: $an-muted;
370
- flex: 1;
371
- }
372
- }
373
-
374
- .an-btn {
375
- display: inline-flex;
376
- align-items: center;
377
- justify-content: center;
378
- height: $an-btn-height;
379
- min-width: $an-btn-height;
380
- padding: $an-btn-padding;
381
- background: transparent;
382
- border: 1px solid transparent;
383
- border-radius: $an-radius-sm;
384
- color: $an-text;
385
- font-family: inherit;
386
- font-size: 13px;
387
- line-height: 1;
388
- cursor: pointer;
389
- transition: background $an-transition, border-color $an-transition, color $an-transition;
390
- white-space: nowrap;
391
- text-decoration: none;
392
-
393
- // Make sure inline SVGs render cleanly
394
- svg {
395
- display: block;
396
- flex-shrink: 0;
397
- pointer-events: none;
398
- }
399
-
400
- &:hover {
401
- background: $an-bg-btn-hover;
402
- border-color: $an-border;
403
- color: $an-primary;
404
-
405
- svg {
406
- stroke: $an-primary;
407
- }
408
- }
409
-
410
- &:focus-visible {
411
- outline: 2px solid $an-primary;
412
- outline-offset: 1px;
413
- }
414
-
415
- &.active {
416
- background: $an-bg-btn-active;
417
- border-color: $an-primary;
418
- color: $an-primary-hover;
419
-
420
- svg {
421
- stroke: $an-primary-hover;
422
- }
423
- }
424
-
425
- &.an-btn-primary {
426
- background: $an-primary;
427
- border-color: $an-primary;
428
- color: #fff;
429
-
430
- svg { stroke: #fff; }
431
-
432
- &:hover {
433
- background: $an-primary-hover;
434
- border-color: $an-primary-hover;
435
- }
436
- }
437
- }
438
-
439
- // =============================================================================
440
- // Editable area
441
- // =============================================================================
442
-
443
- .an-editable {
444
- position: relative; // Establishes containing block for the ::before placeholder
445
- flex: 1;
446
- padding: $an-editable-pad;
447
- min-height: 0;
448
- outline: none;
449
-
450
-
451
- line-height: $an-line-height;
452
- color: $an-text;
453
- overflow-y: auto;
454
- word-break: break-word;
455
-
456
- // Placeholder — shown only when the editable is empty and not focused.
457
- // Uses position:absolute so it never shifts the cursor or block content,
458
- // and requires position:relative on this element (added above) so it is
459
- // scoped to the editable area and never overlaps the toolbar.
460
- &.an-placeholder:not(:focus)::before {
461
- content: attr(data-placeholder);
462
- color: $an-muted;
463
- pointer-events: none;
464
- position: absolute;
465
- top: 12px; // matches top padding from $an-editable-pad (12px 14px)
466
- left: 14px; // matches left padding
467
- right: 14px;
468
- }
469
-
470
- // Content styles
471
- p { margin: 0 0 0.75em; }
472
- h1, h2, h3, h4, h5, h6 { margin: 0.5em 0; line-height: 1.3; }
473
- h1 { font-size: 2em; }
474
- h2 { font-size: 1.5em; }
475
- h3 { font-size: 1.25em; }
476
- h4 { font-size: 1.1em; }
477
- h5 { font-size: 1em; }
478
- h6 { font-size: 0.875em; }
479
- ul, ol { margin: 0 0 0.75em 0; padding-left: 1.5em; list-style-position: inside; }
480
- li { margin-bottom: 0.25em; }
481
-
482
- // Loose lists (markdown paste wraps item text in <p>): keep the list marker
483
- // on the same line as the first paragraph (list-style-position: inside puts
484
- // it in the inline flow), and use tighter margins than standalone <p>.
485
- li > p {
486
- margin: 0 0 0.5em;
487
- &:first-child { display: inline; }
488
- &:last-child { margin-bottom: 0; }
489
- }
490
- li:has(> p) { margin-bottom: 0.6em; }
491
- blockquote {
492
- margin: 0.5em 0 0.5em 1em;
493
- padding: 0.5em 1em;
494
- border-left: 4px solid $an-border;
495
- color: $an-muted;
496
- }
497
- pre, code {
498
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
499
- font-size: 0.9em;
500
- background: $an-bg-toolbar;
501
- border-radius: $an-radius-sm;
502
- }
503
- pre { padding: 0.75em 1em; overflow-x: auto; }
504
- code { padding: 0.1em 0.3em; }
505
- // Inside <pre> the wrapper already paints the background — reset the inner
506
- // <code> so a plain (non-Prism) code fence isn't double-tinted.
507
- pre > code { background: transparent; padding: 0; }
508
-
509
- // Prism-highlighted blocks — <pre> gets class="language-*" mirrored from <code>
510
- // Set dark background here as fallback for before Prism CSS loads from CDN.
511
- pre[class*='language-'] {
512
- background: #2d2d2d;
513
- color: #ccc;
514
- border-radius: $an-radius-sm;
515
-
516
- > code[class*='language-'] {
517
- background: transparent;
518
- color: inherit;
519
- padding: 0;
520
- }
521
- }
522
-
523
- // Code block line numbers (toggled via CodeTooltip)
524
- .an-code-line-numbers {
525
- position: relative;
526
- padding-left: 3.5em !important;
527
-
528
- &::before {
529
- content: '';
530
- position: absolute;
531
- left: 0;
532
- top: 0;
533
- bottom: 0;
534
- width: 3em;
535
- background: rgba(0, 0, 0, 0.04);
536
- border-right: 1px solid rgba(0, 0, 0, 0.1);
537
- pointer-events: none;
538
- z-index: 0;
539
- }
540
- }
541
-
542
- a { color: $an-primary; }
543
- hr { border: none; border-top: 2px solid $an-border; margin: 1em 0; }
544
- img.an-image {
545
- max-width: 100%;
546
- height: auto;
547
- display: inline-block;
548
- }
549
-
550
- .an-video-wrapper {
551
- position: relative;
552
- display: block;
553
- max-width: 100%;
554
- margin: 4px 0;
555
-
556
- iframe,
557
- video {
558
- display: block;
559
- max-width: 100%;
560
- }
561
-
562
- // Transparent overlay that intercepts mouse events on <iframe> embeds.
563
- // iframes swallow all pointer events and prevent them from bubbling to the
564
- // editable area; the shield sits on top so clicks/contextmenu bubble normally.
565
- .an-video-shield {
566
- position: absolute;
567
- inset: 0;
568
- z-index: 2;
569
- cursor: default;
570
- pointer-events: all; // Explicitly block pointer events reaching the iframe
571
- }
572
- }
573
-
574
- // Ensure video shield stays effective even when a video copy moves outside
575
- // .an-editable temporarily (e.g. native drag-and-drop).
576
- // This global rule mirrors the scoped one above.
577
- @at-root .an-video-wrapper .an-video-shield {
578
- position: absolute;
579
- inset: 0;
580
- z-index: 2;
581
- cursor: default;
582
- pointer-events: all;
583
- }
584
-
585
- // Table styles — target both classed and unclassed tables
586
- table, .an-table {
587
- border-collapse: collapse;
588
- table-layout: fixed;
589
- width: 100%;
590
- margin: 0.75em 0;
591
-
592
- td, th {
593
- border: 1px solid $an-border;
594
- padding: 6px 10px;
595
- min-width: 40px;
596
- vertical-align: top;
597
- overflow-wrap: break-word;
598
- word-break: break-word;
599
- }
600
-
601
- th {
602
- background: $an-bg-toolbar;
603
- font-weight: 600;
604
-
605
- // Sort indicator — shows the active sorted column and direction
606
- &.an-sort-asc::after,
607
- &.an-sort-desc::after {
608
- display: inline-block;
609
- margin-left: 6px;
610
- font-size: 0.7em;
611
- opacity: 0.6;
612
- }
613
- &.an-sort-asc::after { content: '\25B2'; }
614
- &.an-sort-desc::after { content: '\25BC'; }
615
- }
616
- }
617
- }
618
-
619
- // ---------------------------------------------------------------------------
620
- // Link tooltip
621
- // ---------------------------------------------------------------------------
622
-
623
- .an-link-tooltip {
624
- position: fixed;
625
- z-index: 1300;
626
- display: flex;
627
- align-items: center;
628
- gap: 2px;
629
- height: 30px;
630
- padding: 0 6px;
631
- background: $an-bg;
632
- border: 1px solid $an-border;
633
- border-radius: $an-radius-sm;
634
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
635
- white-space: nowrap;
636
- pointer-events: all;
637
-
638
- // URL preview label
639
- .an-link-tooltip-url {
640
- max-width: 200px;
641
- overflow: hidden;
642
- text-overflow: ellipsis;
643
- white-space: nowrap;
644
- font-size: 12px;
645
- color: $an-primary;
646
- cursor: default;
647
- padding: 0 4px;
648
- }
649
-
650
- // Vertical divider
651
- .an-link-tooltip-sep {
652
- width: 1px;
653
- height: 18px;
654
- background: $an-border;
655
- flex-shrink: 0;
656
- margin: 0 2px;
657
- }
658
- }
659
-
660
- .an-link-tooltip-btn {
661
- display: flex;
662
- align-items: center;
663
- justify-content: center;
664
- width: 24px;
665
- height: 24px;
666
- padding: 0;
667
- border: none;
668
- border-radius: $an-radius-sm;
669
- background: transparent;
670
- color: $an-muted;
671
- cursor: pointer;
672
- flex-shrink: 0;
673
-
674
- svg { stroke: currentColor; display: block; }
675
-
676
- &:hover {
677
- background: $an-bg-btn-hover;
678
- color: $an-text;
679
- }
680
-
681
- &:active,
682
- &.an-link-tooltip-btn--copied {
683
- background: $an-bg-btn-active;
684
- color: $an-primary;
685
- }
686
-
687
- // Danger variant — used for Delete actions in image/video tooltips
688
- &.an-link-tooltip-btn--danger {
689
- color: #ef4444;
690
-
691
- svg { stroke: #ef4444; }
692
-
693
- &:hover {
694
- background: rgba(#ef4444, 0.08);
695
- color: #dc2626;
696
- svg { stroke: #dc2626; }
697
- }
698
- }
699
- }
700
-
701
- // Shared modifier classes for image and video tooltips
702
- // (re-use all .an-link-tooltip styles, only override the label colour)
703
- .an-image-tooltip .an-link-tooltip-url {
704
- color: $an-text;
705
- font-weight: 500;
706
- }
707
-
708
- .an-video-tooltip .an-link-tooltip-url {
709
- color: #7c3aed; // violet to match video accent
710
- font-weight: 500;
711
- }
712
-
713
- .an-table-tooltip .an-link-tooltip-url {
714
- color: #0369a1; // sky blue for table
715
- font-weight: 500;
716
- }
717
-
718
- .an-code-tooltip .an-link-tooltip-url {
719
- color: #059669; // emerald green for code
720
- font-weight: 500;
721
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
722
- font-size: 11px;
723
- letter-spacing: 0.02em;
724
- }
725
-
726
- // Color-strip variant for the cell shade button (mirrors .an-bubble-btn--color)
727
- .an-link-tooltip-btn--shade {
728
- flex-direction: column;
729
- gap: 1px;
730
- padding: 4px 0 3px;
731
- height: auto;
732
-
733
- .an-bubble-btn-svg {
734
- display: flex;
735
- align-items: center;
736
- justify-content: center;
737
- line-height: 0;
738
- svg { display: block; }
739
- }
740
-
741
- .an-link-tooltip-color-strip {
742
- display: block;
743
- width: 13px;
744
- height: 3px;
745
- border-radius: 1px;
746
- pointer-events: none;
747
- background: transparent;
748
- }
749
- }
750
-
751
- // Active state for toggle buttons in tooltips (e.g. Select Cells)
752
- .an-link-tooltip-btn--active {
753
- background: rgba(#3b82f6, 0.12) !important;
754
- color: #3b82f6 !important;
755
- svg { stroke: #3b82f6; }
756
- }
757
-
758
- // Cells highlighted when select mode is active
759
- .an-cell-selected {
760
- background-color: rgba(#3b82f6, 0.18) !important;
761
- outline: 2px solid #3b82f6;
762
- outline-offset: -2px;
763
- }
764
-
765
- // Cursor hint for all cells when select mode is on
766
- .an-table-select-mode td,
767
- .an-table-select-mode th {
768
- cursor: cell;
769
- }
770
-
771
- // Size popover (column width / row height)
772
- .an-size-popover {
773
- position: fixed;
774
- background: $an-bg;
775
- border: 1px solid $an-border;
776
- border-radius: 8px;
777
- padding: 12px 14px;
778
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
779
- z-index: 1200;
780
- min-width: 200px;
781
-
782
- .an-size-popover-title {
783
- font-size: 12px;
784
- font-weight: 600;
785
- color: $an-text;
786
- margin-bottom: 10px;
787
- }
788
-
789
- .an-size-popover-body {
790
- display: flex;
791
- align-items: center;
792
- gap: 6px;
793
- margin-bottom: 12px;
794
- }
795
-
796
- .an-size-input {
797
- width: 80px;
798
- height: 28px;
799
- padding: 0 8px;
800
- border: 1px solid $an-border;
801
- border-radius: $an-radius-sm;
802
- font-size: 13px;
803
- font-family: inherit;
804
- color: $an-text;
805
- outline: none;
806
-
807
- &:focus {
808
- border-color: $an-primary;
809
- box-shadow: 0 0 0 2px rgba($an-primary, 0.15);
810
- }
811
- }
812
-
813
- .an-size-unit {
814
- font-size: 12px;
815
- color: $an-muted;
816
- }
817
-
818
- .an-size-popover-actions {
819
- display: flex;
820
- justify-content: flex-end;
821
- gap: 6px;
822
- }
823
- }
824
-
825
- // =============================================================================
826
- // Cell shade popover
827
-
828
- .an-cell-shade-popover {
829
- position: fixed;
830
- z-index: 1200;
831
- background: $an-bg;
832
- border: 1px solid $an-border;
833
- border-radius: 8px;
834
- padding: 10px 10px 6px;
835
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
836
- min-width: 166px;
837
-
838
- .an-size-popover-title {
839
- font-size: 11px;
840
- font-weight: 600;
841
- color: $an-muted;
842
- text-transform: uppercase;
843
- letter-spacing: 0.5px;
844
- margin-bottom: 8px;
845
- }
846
-
847
- .an-shade-no-color {
848
- display: inline-flex;
849
- align-items: center;
850
- gap: 4px;
851
- padding: 3px 8px;
852
- font-size: 12px;
853
- color: $an-muted;
854
- background: transparent;
855
- border: 1px solid $an-border;
856
- border-radius: $an-radius-sm;
857
- cursor: pointer;
858
- font-family: inherit;
859
-
860
- &:hover {
861
- background: $an-bg-btn-hover;
862
- color: $an-text;
863
- }
864
- }
865
-
866
- .an-shade-color-input {
867
- width: 24px;
868
- height: 24px;
869
- padding: 0;
870
- border: 1px solid $an-border;
871
- border-radius: $an-radius-sm;
872
- cursor: pointer;
873
- background: transparent;
874
- }
875
- }
876
-
877
- // =============================================================================
878
- // Codeview textarea
879
- // =============================================================================
880
-
881
- .an-codeview {
882
- flex: 1;
883
- width: 100%;
884
- min-height: 200px;
885
- padding: $an-editable-pad;
886
- border: none;
887
- outline: none;
888
- resize: vertical;
889
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
890
- font-size: 13px;
891
- line-height: 1.5;
892
- background: #1e1e2e;
893
- color: #cdd6f4;
894
- }
895
-
896
- // =============================================================================
897
- // Statusbar
898
- // =============================================================================
899
-
900
- .an-statusbar {
901
- display: flex;
902
- align-items: center;
903
- justify-content: space-between;
904
- flex-shrink: 0;
905
- height: $an-statusbar-h;
906
- padding: 0 8px;
907
- background: $an-statusbar-bg;
908
- border-top: 1px solid $an-border;
909
- font-size: 11px;
910
- color: $an-muted;
911
- user-select: none;
912
- // Round the bottom corners to match the container border-radius
913
- border-radius: 0 0 $an-radius $an-radius;
914
- }
915
-
916
- // When there is no statusbar, the editable area is the last child — round its bottom corners
917
- .an-container > .an-editable:last-child {
918
- border-radius: 0 0 $an-radius $an-radius;
919
- }
920
-
921
- .an-status-info {
922
- display: flex;
923
- gap: 12px;
924
- }
925
-
926
- .an-resize-handle {
927
- width: 14px;
928
- height: 14px;
929
- cursor: ns-resize;
930
- background: repeating-linear-gradient(
931
- -45deg,
932
- $an-border,
933
- $an-border 1px,
934
- transparent 1px,
935
- transparent 3px
936
- );
937
- border-radius: 2px;
938
- flex-shrink: 0;
939
-
940
- &:hover {
941
- opacity: 0.7;
942
- }
943
- }
944
-
945
- // =============================================================================
946
- // Dialogs
947
- // =============================================================================
948
-
949
- .an-dialog-overlay {
950
- display: none; // toggled via JS
951
- position: fixed;
952
- inset: 0;
953
- z-index: $an-dialog-z;
954
- background: $an-dialog-bg;
955
- align-items: center;
956
- justify-content: center;
957
- }
958
-
959
- .an-dialog-box {
960
- background: $an-bg;
961
- border-radius: $an-dialog-radius;
962
- padding: 24px;
963
- width: min($an-dialog-width, 95vw);
964
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
965
- display: flex;
966
- flex-direction: column;
967
- gap: 10px;
968
- }
969
-
970
- .an-dialog-header {
971
- display: flex;
972
- align-items: center;
973
- gap: 12px;
974
- margin-bottom: 4px;
975
- }
976
-
977
- .an-dialog-icon {
978
- display: flex;
979
- align-items: center;
980
- justify-content: center;
981
- width: 38px;
982
- height: 38px;
983
- flex-shrink: 0;
984
- border-radius: 10px;
985
- background: rgba($an-primary, 0.1);
986
- color: $an-primary;
987
-
988
- svg { display: block; stroke: currentColor; }
989
- }
990
-
991
- .an-dialog-title {
992
- margin: 0;
993
- font-size: 16px;
994
- font-weight: 600;
995
- color: $an-text;
996
- }
997
-
998
- .an-dialog-actions {
999
- display: flex;
1000
- gap: 8px;
1001
- justify-content: flex-end;
1002
- margin-top: 6px;
1003
- }
1004
-
1005
- .an-dialog-hint {
1006
- margin: -4px 0 0;
1007
- font-size: 12px;
1008
- color: $an-muted;
1009
- min-height: 16px;
1010
- }
1011
-
1012
- .an-align-row {
1013
- display: flex;
1014
- flex-wrap: wrap;
1015
- gap: 12px;
1016
- margin-bottom: 10px;
1017
-
1018
- input[type='radio'] { accent-color: $an-primary; cursor: pointer; }
1019
-
1020
- .an-align-label {
1021
- font-size: 13px;
1022
- cursor: pointer;
1023
- user-select: none;
1024
- }
1025
- }
1026
-
1027
- .an-label {
1028
- display: block;
1029
- font-size: 13px;
1030
- font-weight: 500;
1031
- color: $an-text;
1032
- margin-bottom: 2px;
1033
-
1034
- &.an-label-inline {
1035
- display: flex;
1036
- align-items: center;
1037
- gap: 6px;
1038
- font-weight: normal;
1039
- cursor: pointer;
1040
- }
1041
- }
1042
-
1043
- // =============================================================================
1044
- // Find & Replace — floating panel
1045
- // =============================================================================
1046
-
1047
- .an-fr-dialog {
1048
- // Override centered-modal defaults: floating panel, no backdrop
1049
- background: transparent;
1050
- pointer-events: none;
1051
- align-items: flex-start;
1052
- justify-content: flex-end;
1053
- padding: 56px 16px 0 0;
1054
-
1055
- .an-fr-box {
1056
- pointer-events: auto;
1057
- width: 360px;
1058
- padding: 14px 16px 16px;
1059
- gap: 8px;
1060
- }
1061
- }
1062
-
1063
- .an-fr-header {
1064
- display: flex;
1065
- align-items: center;
1066
- justify-content: space-between;
1067
- margin-bottom: 2px;
1068
-
1069
- .an-dialog-title { margin: 0; font-size: 14px; }
1070
- }
1071
-
1072
- // Compact search bar: input + toggle buttons + counter in one row
1073
- .an-fr-search-bar {
1074
- display: flex;
1075
- align-items: center;
1076
- gap: 4px;
1077
-
1078
- .an-fr-input {
1079
- flex: 1;
1080
- min-width: 0;
1081
- padding: 6px 8px;
1082
- font-size: 13px;
1083
- }
1084
- }
1085
-
1086
- // Replace row
1087
- .an-fr-replace-row {
1088
- display: flex;
1089
- align-items: center;
1090
- gap: 6px;
1091
-
1092
- .an-fr-input {
1093
- flex: 1;
1094
- min-width: 0;
1095
- padding: 6px 8px;
1096
- font-size: 13px;
1097
- }
1098
-
1099
- .an-fr-replace-btn {
1100
- flex-shrink: 0;
1101
- padding: 5px 10px;
1102
- font-size: 12px;
1103
- white-space: nowrap;
1104
- }
1105
- }
1106
-
1107
- // Icon buttons (Aa, ↑, ↓)
1108
- .an-fr-icon-btn {
1109
- display: flex;
1110
- align-items: center;
1111
- justify-content: center;
1112
- flex-shrink: 0;
1113
- width: 28px;
1114
- height: 28px;
1115
- padding: 0;
1116
- font-size: 12px;
1117
- font-weight: 600;
1118
- font-family: inherit;
1119
- border: 1px solid transparent;
1120
- border-radius: $an-radius-sm;
1121
- background: transparent;
1122
- color: $an-muted;
1123
- cursor: pointer;
1124
-
1125
- svg { display: block; stroke: currentColor; }
1126
-
1127
- &:hover {
1128
- background: $an-bg-btn-hover;
1129
- color: $an-text;
1130
- border-color: $an-border;
1131
- }
1132
-
1133
- &.an-fr-icon-btn--active {
1134
- background: rgba($an-primary, 0.1);
1135
- color: $an-primary;
1136
- border-color: rgba($an-primary, 0.3);
1137
- }
1138
- }
1139
-
1140
- .an-fr-counter {
1141
- font-size: 11px;
1142
- color: $an-muted;
1143
- white-space: nowrap;
1144
- min-width: 36px;
1145
- text-align: right;
1146
- flex-shrink: 0;
1147
- }
1148
-
1149
- // =============================================================================
1150
-
1151
- .an-input {
1152
- width: 100%;
1153
- padding: 7px 10px;
1154
- border: 1px solid $an-border;
1155
- border-radius: $an-radius-sm;
1156
- font-family: inherit;
1157
- font-size: $an-font-size;
1158
- color: $an-text;
1159
- background: $an-bg;
1160
- outline: none;
1161
- transition: border-color $an-transition, box-shadow $an-transition;
1162
-
1163
- &:focus {
1164
- border-color: $an-primary;
1165
- box-shadow: 0 0 0 3px rgba($an-primary, 0.15);
1166
- }
1167
- }
1168
-
1169
- // ---------------------------------------------------------------------------
1170
- // Context menu
1171
- // ---------------------------------------------------------------------------
1172
-
1173
- .an-contextmenu {
1174
- position: fixed;
1175
- z-index: 10050;
1176
- background: $an-bg;
1177
- border: 1px solid $an-border;
1178
- border-radius: 8px;
1179
- box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
1180
- min-width: 180px;
1181
- padding: 5px 4px;
1182
- display: none;
1183
- user-select: none;
1184
- }
1185
-
1186
- .an-context-item {
1187
- display: flex;
1188
- align-items: center;
1189
- gap: 10px;
1190
- width: 100%;
1191
- text-align: left;
1192
- padding: 7px 14px;
1193
- background: transparent;
1194
- border: none;
1195
- border-radius: 5px;
1196
- font-size: 13px;
1197
- color: $an-text;
1198
- cursor: pointer;
1199
- transition: background 0.12s, color 0.12s;
1200
- line-height: 1.4;
1201
-
1202
- &:hover {
1203
- background: $an-primary;
1204
- color: #fff;
1205
-
1206
- .an-context-icon svg {
1207
- stroke: #fff;
1208
- }
1209
-
1210
- .an-context-chevron svg {
1211
- stroke: #fff;
1212
- }
1213
- }
1214
-
1215
- &:disabled {
1216
- opacity: 0.38;
1217
- cursor: default;
1218
- pointer-events: none;
1219
- }
1220
- }
1221
-
1222
- // Submenu entry — chevron on the right
1223
- .an-context-submenu {
1224
- .an-context-chevron {
1225
- display: flex;
1226
- align-items: center;
1227
- margin-left: auto;
1228
- color: $an-muted;
1229
- flex-shrink: 0;
1230
-
1231
- svg { display: block; }
1232
- }
1233
- }
1234
-
1235
- // Back-navigation header button
1236
- .an-context-back {
1237
- display: flex;
1238
- align-items: center;
1239
- gap: 8px;
1240
- width: 100%;
1241
- text-align: left;
1242
- padding: 6px 14px 8px;
1243
- background: transparent;
1244
- border: none;
1245
- border-bottom: 1px solid $an-border;
1246
- border-radius: 5px 5px 0 0;
1247
- font-size: 12px;
1248
- font-weight: 600;
1249
- color: $an-muted;
1250
- cursor: pointer;
1251
- margin-bottom: 3px;
1252
- transition: background 0.12s, color 0.12s;
1253
-
1254
- .an-context-icon svg { stroke: $an-muted; }
1255
-
1256
- &:hover {
1257
- background: $an-bg-btn-hover;
1258
- color: $an-text;
1259
- .an-context-icon svg { stroke: $an-text; }
1260
- }
1261
- }
1262
-
1263
- .an-context-icon {
1264
- display: flex;
1265
- align-items: center;
1266
- justify-content: center;
1267
- flex-shrink: 0;
1268
- width: 16px;
1269
- color: $an-muted;
1270
- transition: color 0.12s;
1271
-
1272
- svg {
1273
- display: block;
1274
- stroke: currentColor;
1275
- }
1276
- }
1277
-
1278
- .an-context-label {
1279
- flex: 1;
1280
- }
1281
-
1282
- .an-context-sep {
1283
- height: 1px;
1284
- margin: 5px 10px;
1285
- background: $an-border;
1286
- }
1287
-
1288
- // Color-strip variant — SVG stacked above a thin color bar (matches toolbar)
1289
- .an-context-icon--color {
1290
- flex-direction: column;
1291
- gap: 2px;
1292
- width: 16px;
1293
- align-items: center;
1294
-
1295
- .an-context-icon-svg {
1296
- display: flex;
1297
- align-items: center;
1298
- justify-content: center;
1299
- line-height: 0;
1300
- }
1301
- }
1302
-
1303
- .an-context-color-strip {
1304
- display: block;
1305
- width: 100%;
1306
- height: 3px;
1307
- border-radius: 1px;
1308
- flex-shrink: 0;
1309
- }
1310
-
1311
- // Color palette inside context menu
1312
- .an-context-color-palette {
1313
- display: flex;
1314
- flex-wrap: wrap;
1315
- gap: 3px;
1316
- padding: 6px 12px 2px;
1317
- }
1318
-
1319
- .an-context-color-swatch {
1320
- width: 15px;
1321
- height: 15px;
1322
- border-radius: 3px;
1323
- border: 1px solid rgba(0, 0, 0, 0.12);
1324
- cursor: pointer;
1325
- flex-shrink: 0;
1326
- position: relative;
1327
- transition: transform 0.1s;
1328
-
1329
- &:hover {
1330
- transform: scale(1.28);
1331
- z-index: 1;
1332
- border-color: rgba(0, 0, 0, 0.4);
1333
- }
1334
- }
1335
-
1336
- .an-context-color-none {
1337
- display: flex;
1338
- align-items: center;
1339
- justify-content: center;
1340
- background: #fff !important;
1341
- color: #999;
1342
-
1343
- svg { display: block; }
1344
-
1345
- &:hover { color: #333; }
1346
- }
1347
-
1348
- .an-context-color-custom {
1349
- display: flex;
1350
- align-items: center;
1351
- gap: 8px;
1352
- padding: 4px 12px 8px;
1353
- font-size: 12px;
1354
- color: $an-muted;
1355
- cursor: pointer;
1356
-
1357
- input[type='color'] {
1358
- width: 18px;
1359
- height: 18px;
1360
- padding: 0;
1361
- border: 1px solid $an-border;
1362
- border-radius: 3px;
1363
- cursor: pointer;
1364
- background: transparent;
1365
- -webkit-appearance: none;
1366
- appearance: none;
1367
- }
1368
-
1369
- span { flex: 1; }
1370
- &:hover span { color: $an-text; }
1371
- }
1372
-
1373
- // ---------------------------------------------------------------------------
1374
- // Image resize overlay
1375
- // ---------------------------------------------------------------------------
1376
-
1377
- .an-image-resizer {
1378
- position: absolute;
1379
- z-index: 10000;
1380
- box-sizing: border-box;
1381
- border: 2px solid $an-primary;
1382
- pointer-events: none;
1383
-
1384
- .an-resize-handle {
1385
- position: absolute;
1386
- width: 8px;
1387
- height: 8px;
1388
- background: $an-primary;
1389
- border: 1px solid #fff;
1390
- border-radius: 1px;
1391
- box-sizing: border-box;
1392
- pointer-events: all;
1393
- // Required for the pointerdown drag to survive on touch: without it the
1394
- // browser claims the gesture as a scroll and fires pointercancel.
1395
- touch-action: none;
1396
-
1397
- // 8px is below the ~44px recommended touch target, so widen the hit area
1398
- // with a transparent ::before rather than by enlarging the visible dot.
1399
- &::before {
1400
- content: '';
1401
- position: absolute;
1402
- inset: -10px;
1403
- }
1404
- }
1405
-
1406
- // Corners
1407
- .an-resize-nw { top: -4px; left: -4px; cursor: nw-resize; }
1408
- .an-resize-ne { top: -4px; right: -4px; cursor: ne-resize; }
1409
- .an-resize-se { bottom: -4px; right: -4px; cursor: se-resize; }
1410
- .an-resize-sw { bottom: -4px; left: -4px; cursor: sw-resize; }
1411
-
1412
- // Edge midpoints
1413
- .an-resize-n { top: -4px; left: calc(50% - 4px); cursor: n-resize; }
1414
- .an-resize-e { top: calc(50% - 4px); right: -4px; cursor: e-resize; }
1415
- .an-resize-s { bottom: -4px; left: calc(50% - 4px); cursor: s-resize; }
1416
- .an-resize-w { top: calc(50% - 4px); left: -4px; cursor: w-resize; }
1417
- }
1418
-
1419
- // ---------------------------------------------------------------------------
1420
- // Image crop overlay
1421
- // ---------------------------------------------------------------------------
1422
-
1423
- // The scrim and crop box are appended to <body> and positioned fixed, so they
1424
- // live outside .an-container. All styles are standalone (no SCSS nesting).
1425
-
1426
- .an-crop-scrim {
1427
- // Inline styles handle position/z-index/background for performance;
1428
- // clip-path is updated by JS every frame so we only declare the transition.
1429
- transition: clip-path 0s; // disable transition — updated synchronously on drag
1430
- }
1431
-
1432
- .an-crop-box {
1433
- // Core layout & interaction via inline styles in JS (position changes every drag frame).
1434
- // Only declare the animated ring so it stays in sync with $an-primary.
1435
- outline: none !important;
1436
-
1437
- // Subtle inner shadow that frames the "live" area
1438
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45),
1439
- inset 0 0 0 1px rgba(255, 255, 255, 0.25);
1440
- }
1441
-
1442
- .an-crop-handle {
1443
- // Inline styles handle size/position; declare hover highlight only.
1444
- &:hover, &:active {
1445
- background: #74affa !important; // $an-primary lightened ~14%
1446
- }
1447
- }
1448
-
1449
- .an-crop-toolbar {
1450
- // Inline styles handle position; add a subtle entrance animation.
1451
- animation: an-crop-toolbar-in 0.12s ease;
1452
- }
1453
-
1454
- @keyframes an-crop-toolbar-in {
1455
- from { opacity: 0; transform: translateY(4px); }
1456
- to { opacity: 1; transform: translateY(0); }
1457
- }
1458
-
1459
- // Hide canvas-based crop overlay when printing
1460
- @media print {
1461
- .an-crop-scrim,
1462
- .an-crop-box,
1463
- .an-crop-toolbar {
1464
- display: none !important;
1465
- }
1466
- }
1467
-
1468
- // ---------------------------------------------------------------------------
1469
- // Video resize overlay
1470
- // ---------------------------------------------------------------------------
1471
-
1472
- $an-video-accent: #8b5cf6; // violet-500
1473
-
1474
- .an-video-resizer {
1475
- position: absolute;
1476
- z-index: 10000;
1477
- box-sizing: border-box;
1478
- border: 2px solid $an-video-accent;
1479
- pointer-events: none;
1480
-
1481
- .an-resize-handle {
1482
- position: absolute;
1483
- width: 8px;
1484
- height: 8px;
1485
- background: $an-video-accent;
1486
- border: 1px solid #fff;
1487
- border-radius: 1px;
1488
- box-sizing: border-box;
1489
- pointer-events: all;
1490
- }
1491
-
1492
- // Corners
1493
- .an-resize-nw { top: -4px; left: -4px; cursor: nw-resize; }
1494
- .an-resize-ne { top: -4px; right: -4px; cursor: ne-resize; }
1495
- .an-resize-se { bottom: -4px; right: -4px; cursor: se-resize; }
1496
- .an-resize-sw { bottom: -4px; left: -4px; cursor: sw-resize; }
1497
-
1498
- // Edge midpoints
1499
- .an-resize-n { top: -4px; left: calc(50% - 4px); cursor: n-resize; }
1500
- .an-resize-e { top: calc(50% - 4px); right: -4px; cursor: e-resize; }
1501
- .an-resize-s { bottom: -4px; left: calc(50% - 4px); cursor: s-resize; }
1502
- .an-resize-w { top: calc(50% - 4px); left: -4px; cursor: w-resize; }
1503
- }
1504
-
1505
- // .an-video-selected is applied by VideoResizer for JS state tracking.
1506
- // Visual selection is handled entirely by the .an-video-resizer overlay,
1507
- // so no CSS outline is needed here (two visible frames would appear otherwise).
1508
-
1509
- // ---------------------------------------------------------------------------
1510
- // Icon dialog
1511
- // ---------------------------------------------------------------------------
1512
-
1513
- // Wider box override
1514
- .an-icon-box {
1515
- width: min(596px, 95vw);
1516
- gap: 0;
1517
- padding: 20px;
1518
- }
1519
-
1520
- // Title row with close button
1521
- .an-icon-title-row {
1522
- display: flex;
1523
- align-items: center;
1524
- justify-content: space-between;
1525
- margin-bottom: 14px;
1526
-
1527
- .an-dialog-title {
1528
- margin: 0;
1529
- }
1530
- }
1531
-
1532
- // Icon + title grouped together (used in emoji/icon/find dialogs)
1533
- .an-dialog-title-group {
1534
- display: flex;
1535
- align-items: center;
1536
- gap: 10px;
1537
- }
1538
-
1539
- // Small icon variant for dialogs with title-row layout
1540
- .an-dialog-icon--sm {
1541
- width: 32px;
1542
- height: 32px;
1543
- border-radius: 8px;
1544
- background: rgba($an-primary, 0.1);
1545
- color: $an-primary;
1546
- display: flex;
1547
- align-items: center;
1548
- justify-content: center;
1549
- flex-shrink: 0;
1550
-
1551
- svg { display: block; stroke: currentColor; }
1552
- }
1553
-
1554
- .an-icon-close {
1555
- display: flex;
1556
- align-items: center;
1557
- justify-content: center;
1558
- width: 26px;
1559
- height: 26px;
1560
- padding: 0;
1561
- font-size: 18px;
1562
- line-height: 1;
1563
- background: none;
1564
- border: none;
1565
- border-radius: $an-radius-sm;
1566
- cursor: pointer;
1567
- color: $an-muted;
1568
- flex-shrink: 0;
1569
-
1570
- &:hover {
1571
- background: $an-bg-btn-hover;
1572
- color: $an-text;
1573
- }
1574
- }
1575
-
1576
- // Search
1577
- .an-icon-search {
1578
- width: 100%;
1579
- margin-bottom: 10px;
1580
- box-sizing: border-box;
1581
- }
1582
-
1583
- // Category tabs
1584
- .an-icon-cats {
1585
- display: flex;
1586
- flex-wrap: wrap;
1587
- gap: 4px;
1588
- margin-bottom: 10px;
1589
- }
1590
-
1591
- .an-icon-cat {
1592
- height: 26px;
1593
- padding: 0 10px;
1594
- font-size: 12px;
1595
- font-family: $an-font-family;
1596
- background: none;
1597
- border: 1px solid $an-border;
1598
- border-radius: 13px;
1599
- cursor: pointer;
1600
- color: $an-muted;
1601
- white-space: nowrap;
1602
- transition: background $an-transition, color $an-transition, border-color $an-transition;
1603
-
1604
- &:hover {
1605
- background: $an-bg-btn-hover;
1606
- color: $an-text;
1607
- }
1608
-
1609
- &.active {
1610
- background: $an-primary;
1611
- border-color: $an-primary;
1612
- color: #fff;
1613
- }
1614
- }
1615
-
1616
- // Icon grid
1617
- .an-icon-grid {
1618
- display: grid;
1619
- grid-template-columns: repeat(auto-fill, 56px);
1620
- gap: 3px;
1621
- height: 256px;
1622
- overflow-y: auto;
1623
- margin-bottom: 10px;
1624
- padding: 4px;
1625
- border: 1px solid $an-border;
1626
- border-radius: $an-radius;
1627
- background: $an-bg;
1628
- scrollbar-width: thin;
1629
- scrollbar-color: $an-border transparent;
1630
-
1631
- &::-webkit-scrollbar { width: 6px; }
1632
- &::-webkit-scrollbar-track { background: transparent; }
1633
- &::-webkit-scrollbar-thumb { background: $an-border; border-radius: 3px; }
1634
- }
1635
-
1636
- .an-icon-cell {
1637
- display: flex;
1638
- flex-direction: column;
1639
- align-items: center;
1640
- justify-content: center;
1641
- gap: 3px;
1642
- width: 56px;
1643
- height: 52px;
1644
- padding: 0;
1645
- border: 1px solid transparent;
1646
- border-radius: $an-radius-sm;
1647
- background: none;
1648
- cursor: pointer;
1649
- font-family: $an-font-family;
1650
- font-size: 10px;
1651
- color: $an-muted;
1652
- transition: background $an-transition, border-color $an-transition;
1653
- overflow: hidden;
1654
- box-sizing: border-box;
1655
-
1656
- i {
1657
- font-size: 17px;
1658
- color: $an-text;
1659
- line-height: 1;
1660
- pointer-events: none;
1661
- }
1662
-
1663
- span {
1664
- overflow: hidden;
1665
- text-overflow: ellipsis;
1666
- white-space: nowrap;
1667
- max-width: 52px;
1668
- pointer-events: none;
1669
- }
1670
-
1671
- &:hover {
1672
- background: $an-bg-btn-hover;
1673
- border-color: $an-border;
1674
- }
1675
-
1676
- &.active {
1677
- background: rgba($an-primary, 0.1);
1678
- border-color: $an-primary;
1679
- color: $an-primary;
1680
-
1681
- i { color: $an-primary; }
1682
- }
1683
- }
1684
-
1685
- // Empty state
1686
- .an-icon-empty {
1687
- grid-column: 1 / -1;
1688
- padding: 24px 0;
1689
- text-align: center;
1690
- color: $an-muted;
1691
- font-size: 13px;
1692
- }
1693
-
1694
- // Options row
1695
- .an-icon-options {
1696
- display: flex;
1697
- align-items: center;
1698
- flex-wrap: wrap;
1699
- gap: 6px 10px;
1700
- margin-bottom: 10px;
1701
-
1702
- .an-label {
1703
- margin: 0;
1704
- font-size: 12px;
1705
- white-space: nowrap;
1706
- }
1707
- }
1708
-
1709
- .an-icon-option-select {
1710
- height: $an-btn-height;
1711
- padding: 0 6px;
1712
- font-size: 12px;
1713
- width: auto;
1714
- }
1715
-
1716
- .an-icon-color {
1717
- width: 32px;
1718
- height: $an-btn-height;
1719
- padding: 2px;
1720
- border: 1px solid $an-border;
1721
- border-radius: $an-radius-sm;
1722
- cursor: pointer;
1723
- background: none;
1724
- }
1725
-
1726
- .an-icon-use-color {
1727
- display: flex;
1728
- align-items: center;
1729
- gap: 4px;
1730
- font-size: 12px;
1731
- margin: 0;
1732
- cursor: pointer;
1733
-
1734
- input[type='checkbox'] {
1735
- cursor: pointer;
1736
- }
1737
- }
1738
-
1739
- // Preview
1740
- .an-icon-preview {
1741
- display: flex;
1742
- flex-direction: column;
1743
- align-items: center;
1744
- justify-content: center;
1745
- gap: 6px;
1746
- min-height: 72px;
1747
- margin-bottom: 14px;
1748
- padding: 10px 12px;
1749
- border: 1px solid $an-border;
1750
- border-radius: $an-radius;
1751
- background: $an-bg-toolbar;
1752
-
1753
- i {
1754
- line-height: 1;
1755
- }
1756
-
1757
- .an-icon-preview-hint {
1758
- font-size: 12px;
1759
- color: $an-muted;
1760
- }
1761
- }
1762
-
1763
- .an-icon-preview-name {
1764
- font-size: 12px;
1765
- color: $an-muted;
1766
- font-family: monospace;
1767
- }
1768
-
1769
- // ---------------------------------------------------------------------------
1770
- // Emoji dialog
1771
- // ---------------------------------------------------------------------------
1772
-
1773
- .an-emoji-box {
1774
- width: min(520px, 95vw);
1775
- gap: 0;
1776
- padding: 20px;
1777
- }
1778
-
1779
- .an-emoji-grid {
1780
- display: grid;
1781
- grid-template-columns: repeat(auto-fill, 42px);
1782
- gap: 2px;
1783
- height: 288px;
1784
- overflow-y: auto;
1785
- margin-bottom: 10px;
1786
- padding: 4px;
1787
- border: 1px solid $an-border;
1788
- border-radius: $an-radius;
1789
- scrollbar-width: thin;
1790
- scrollbar-color: $an-border transparent;
1791
-
1792
- &::-webkit-scrollbar { width: 6px; }
1793
- &::-webkit-scrollbar-track { background: transparent; }
1794
- &::-webkit-scrollbar-thumb { background: $an-border; border-radius: 3px; }
1795
- }
1796
-
1797
- .an-emoji-cell {
1798
- width: 42px;
1799
- height: 42px;
1800
- padding: 0;
1801
- display: flex;
1802
- align-items: center;
1803
- justify-content: center;
1804
- font-size: 22px;
1805
- line-height: 1;
1806
- border: 1px solid transparent;
1807
- border-radius: $an-radius-sm;
1808
- background: none;
1809
- cursor: pointer;
1810
- transition: background $an-transition, border-color $an-transition;
1811
-
1812
- &:hover {
1813
- background: $an-bg-btn-hover;
1814
- border-color: $an-border;
1815
- }
1816
-
1817
- &:active {
1818
- background: $an-bg-btn-active;
1819
- }
1820
- }
1821
-
1822
- // =============================================================================
1823
- // Sticky toolbar
1824
- // =============================================================================
1825
-
1826
- .an-sticky-toolbar {
1827
- overflow: visible;
1828
-
1829
- .an-toolbar {
1830
- position: sticky;
1831
- top: var(--an-sticky-top, 0px);
1832
- z-index: 100;
1833
- border-radius: $an-radius $an-radius 0 0;
1834
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
1835
- }
1836
- }
1837
-
1838
- // =============================================================================
1839
- // Image caption — figure / figcaption
1840
- // =============================================================================
1841
-
1842
- .an-editable {
1843
- figure.an-figure {
1844
- display: inline-block;
1845
- max-width: 100%;
1846
- margin: 0.75em 0;
1847
- text-align: center;
1848
-
1849
- img {
1850
- display: block;
1851
- max-width: 100%;
1852
- margin: 0 auto; // Centers img when figure uses fit-content or explicit width
1853
- }
1854
- }
1855
-
1856
- figcaption.an-figcaption {
1857
- font-size: 0.85em;
1858
- font-style: italic;
1859
- color: $an-muted;
1860
- padding: 4px 0 2px;
1861
- text-align: center;
1862
- line-height: 1.4;
1863
- min-width: 60px;
1864
- outline: none;
1865
-
1866
- &:focus {
1867
- background: rgba($an-primary, 0.06);
1868
- border-radius: 2px;
1869
- }
1870
- }
1871
- }
1872
-
1873
- // =============================================================================
1874
- // Keyboard shortcuts dialog
1875
- // =============================================================================
1876
-
1877
- .an-shortcuts-box {
1878
- width: min(480px, 95vw);
1879
- max-height: 80vh;
1880
- overflow-y: auto;
1881
- }
1882
-
1883
- .an-shortcuts-cat {
1884
- font-size: 11px;
1885
- font-weight: 600;
1886
- text-transform: uppercase;
1887
- letter-spacing: 0.06em;
1888
- color: $an-muted;
1889
- padding: 8px 0 4px;
1890
- border-bottom: 1px solid $an-border;
1891
- margin-bottom: 2px;
1892
-
1893
- & + .an-shortcuts-table + & {
1894
- margin-top: 10px;
1895
- }
1896
- }
1897
-
1898
- .an-shortcuts-table {
1899
- display: flex;
1900
- flex-direction: column;
1901
- }
1902
-
1903
- .an-shortcuts-row {
1904
- display: flex;
1905
- align-items: center;
1906
- justify-content: space-between;
1907
- padding: 5px 4px;
1908
- border-radius: $an-radius-sm;
1909
-
1910
- &:hover { background: $an-bg-btn-hover; }
1911
- }
1912
-
1913
- .an-shortcuts-key {
1914
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
1915
- font-size: 12px;
1916
- color: $an-text;
1917
- background: $an-bg-toolbar;
1918
- border: 1px solid $an-border;
1919
- border-bottom-width: 2px;
1920
- border-radius: $an-radius-sm;
1921
- padding: 2px 8px;
1922
- white-space: nowrap;
1923
- flex-shrink: 0;
1924
- }
1925
-
1926
- .an-shortcuts-action {
1927
- font-size: 13px;
1928
- color: $an-text;
1929
- flex: 1;
1930
- padding-left: 14px;
1931
- }
1932
-
1933
- // =============================================================================
1934
- // Code block language selector (inside CodeTooltip)
1935
- // =============================================================================
1936
-
1937
- .an-code-lang-select {
1938
- height: 22px;
1939
- padding: 0 20px 0 6px;
1940
- border: 1px solid $an-border;
1941
- border-radius: $an-radius-sm;
1942
- font-family: inherit;
1943
- font-size: 11px;
1944
- color: $an-text;
1945
- background: $an-bg url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%236b7280'/%3E%3C/svg%3E") no-repeat right 5px center;
1946
- background-size: 6px 4px;
1947
- appearance: none;
1948
- -webkit-appearance: none;
1949
- cursor: pointer;
1950
-
1951
- &:focus { outline: none; border-color: $an-primary; }
1952
- &:hover { border-color: $an-primary; }
1953
- }
1954
-
1955
- // =============================================================================
1956
- // Dark theme — apply via options: { theme: 'dark' }
1957
- // =============================================================================
1958
-
1959
- .an-theme-dark {
1960
- border-color: #3f3f5f;
1961
- background: #1e1e2e;
1962
- color: #cdd6f4;
1963
-
1964
- &.an-focused {
1965
- border-color: #89b4fa;
1966
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.2);
1967
- }
1968
-
1969
- .an-toolbar {
1970
- background: #181825;
1971
- border-color: #3f3f5f;
1972
- }
1973
-
1974
- .an-btn {
1975
- color: #cdd6f4;
1976
-
1977
- &:hover {
1978
- background: #2a2a3e;
1979
- border-color: #3f3f5f;
1980
- color: #cdd6f4;
1981
-
1982
- svg { stroke: #cdd6f4; }
1983
- }
1984
-
1985
- &.active {
1986
- background: #1a3a5c;
1987
- border-color: #89b4fa;
1988
- color: #89b4fa;
1989
-
1990
- svg { stroke: #89b4fa; }
1991
- }
1992
-
1993
- &.an-btn-primary {
1994
- background: #3b5bdb;
1995
- border-color: #3b5bdb;
1996
- color: #fff;
1997
- }
1998
- }
1999
-
2000
- .an-select {
2001
- background-color: #1e1e2e;
2002
- border-color: #3f3f5f;
2003
- color: #cdd6f4;
2004
-
2005
- &:hover, &:focus { border-color: #89b4fa; }
2006
- }
2007
-
2008
- .an-editable {
2009
- background: #1e1e2e;
2010
- color: #cdd6f4;
2011
-
2012
- a { color: #89b4fa; }
2013
-
2014
- blockquote {
2015
- border-color: #3f3f5f;
2016
- color: #a6adc8;
2017
- }
2018
-
2019
- pre:not([class*='language-']),
2020
- code:not([class*='language-']) {
2021
- background: #313244;
2022
- color: #cdd6f4;
2023
- }
2024
-
2025
- pre:not([class*='language-']) > code { background: transparent; }
2026
-
2027
- .an-code-line-numbers::before {
2028
- background: rgba(255, 255, 255, 0.05);
2029
- border-right-color: rgba(255, 255, 255, 0.1);
2030
- }
2031
-
2032
- hr { border-color: #3f3f5f; }
2033
-
2034
- table, .an-table {
2035
- td, th { border-color: #3f3f5f; }
2036
- th { background: #313244; }
2037
- }
2038
-
2039
- &.an-placeholder::before { color: #6c7086; }
2040
-
2041
- figcaption.an-figcaption { color: #6c7086; }
2042
- }
2043
-
2044
- .an-statusbar {
2045
- background: #181825;
2046
- border-color: #3f3f5f;
2047
- color: #6c7086;
2048
- }
2049
-
2050
- .an-link-tooltip,
2051
- .an-contextmenu {
2052
- background: #24273a;
2053
- border-color: #3f3f5f;
2054
- color: #cdd6f4;
2055
- }
2056
-
2057
- .an-link-tooltip-url { color: #89b4fa; }
2058
-
2059
- .an-link-tooltip-btn {
2060
- color: #a6adc8;
2061
-
2062
- &:hover {
2063
- background: #2a2a3e;
2064
- color: #cdd6f4;
2065
- }
2066
- }
2067
-
2068
- .an-dialog-overlay { background: rgba(0, 0, 0, 0.65); }
2069
-
2070
- .an-dialog-box {
2071
- background: #24273a;
2072
- color: #cdd6f4;
2073
- border: 1px solid #3f3f5f;
2074
- }
2075
-
2076
- .an-dialog-title { color: #cdd6f4; }
2077
-
2078
- .an-dialog-icon,
2079
- .an-dialog-icon--sm {
2080
- background: rgba(#818cf8, 0.15);
2081
- color: #818cf8;
2082
- }
2083
-
2084
- .an-fr-icon-btn {
2085
- color: #a6adc8;
2086
- &:hover { background: #313244; color: #cdd6f4; border-color: #45475a; }
2087
- &.an-fr-icon-btn--active { background: rgba(#818cf8, 0.15); color: #818cf8; border-color: rgba(#818cf8, 0.3); }
2088
- }
2089
-
2090
- .an-fr-counter { color: #6c7086; }
2091
-
2092
- .an-label { color: #cdd6f4; }
2093
-
2094
- .an-input {
2095
- background: #313244;
2096
- border-color: #3f3f5f;
2097
- color: #cdd6f4;
2098
-
2099
- &:focus {
2100
- border-color: #89b4fa;
2101
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.15);
2102
- }
2103
- }
2104
-
2105
- .an-shortcuts-key {
2106
- background: #313244;
2107
- border-color: #3f3f5f;
2108
- color: #cdd6f4;
2109
- }
2110
-
2111
- .an-shortcuts-action { color: #cdd6f4; }
2112
- .an-shortcuts-row:hover { background: #2a2a3e; }
2113
-
2114
- .an-shortcuts-cat {
2115
- border-color: #3f3f5f;
2116
- color: #a6adc8;
2117
- }
2118
-
2119
- .an-code-lang-select {
2120
- background-color: #24273a;
2121
- border-color: #3f3f5f;
2122
- color: #cdd6f4;
2123
- }
2124
-
2125
- .an-color-popup,
2126
- .an-table-picker-popup,
2127
- .an-size-popover,
2128
- .an-cell-shade-popover {
2129
- background: #24273a;
2130
- border-color: #3f3f5f;
2131
- color: #cdd6f4;
2132
- }
2133
-
2134
- .an-cell-shade-popover .an-shade-no-color {
2135
- border-color: #3f3f5f;
2136
- color: #a6adc8;
2137
-
2138
- &:hover {
2139
- background: #313244;
2140
- color: #cdd6f4;
2141
- }
2142
- }
2143
-
2144
- .an-link-tooltip-btn--active {
2145
- background: rgba(#6366f1, 0.2) !important;
2146
- color: #818cf8 !important;
2147
- svg { stroke: #818cf8; }
2148
- }
2149
-
2150
- .an-cell-selected {
2151
- background-color: rgba(#6366f1, 0.25) !important;
2152
- outline-color: #6366f1;
2153
- }
2154
-
2155
- .an-table-cell {
2156
- background: #24273a;
2157
- border-color: #3f3f5f;
2158
-
2159
- &.active {
2160
- background: rgba(99, 102, 241, 0.3);
2161
- border-color: #6366f1;
2162
- }
2163
- }
2164
-
2165
- // Color popup children
2166
- .an-color-custom {
2167
- border-top-color: #3f3f5f;
2168
- color: #cdd6f4;
2169
- }
2170
-
2171
- .an-color-arrow:hover { border-left-color: #45475a; }
2172
-
2173
- .an-table-label { color: #6c7086; }
2174
- .an-context-table-grid-panel { border-top-color: #3f3f5f; }
2175
-
2176
- .an-context-item { color: #cdd6f4; }
2177
- .an-context-sep { background: #3f3f5f; }
2178
-
2179
- .an-context-color-swatch {
2180
- border-color: rgba(255, 255, 255, 0.15);
2181
- &:hover { border-color: rgba(255, 255, 255, 0.5); }
2182
- }
2183
-
2184
- .an-context-color-none {
2185
- background: #1e1e2e !important;
2186
- color: #888;
2187
- &:hover { color: #ccc; }
2188
- }
2189
-
2190
- .an-context-color-custom {
2191
- input[type='color'] { border-color: #3f3f5f; }
2192
- }
2193
-
2194
- .an-icon-cat {
2195
- border-color: #3f3f5f;
2196
- color: #a6adc8;
2197
-
2198
- &.active {
2199
- background: #3b5bdb;
2200
- border-color: #3b5bdb;
2201
- color: #fff;
2202
- }
2203
- }
2204
-
2205
- .an-icon-search {
2206
- border-color: #3f3f5f;
2207
- background: #313244;
2208
- color: #cdd6f4;
2209
- }
2210
-
2211
- .an-icon-cell {
2212
- color: #a6adc8;
2213
-
2214
- i { color: #cdd6f4; }
2215
-
2216
- &:hover { background: #2a2a3e; border-color: #45475a; }
2217
-
2218
- &.active {
2219
- background: rgba(#818cf8, 0.15);
2220
- border-color: #818cf8;
2221
- color: #818cf8;
2222
- i { color: #818cf8; }
2223
- }
2224
- }
2225
-
2226
- .an-icon-close {
2227
- color: #a6adc8;
2228
-
2229
- &:hover {
2230
- background: #2a2a3e;
2231
- color: #cdd6f4;
2232
- }
2233
- }
2234
-
2235
- // Emoji dialog
2236
- .an-emoji-box { background: #1e1e2e; border-color: #45475a; }
2237
-
2238
- .an-emoji-cell {
2239
- color: inherit;
2240
- &:hover { background: #313244; }
2241
- }
2242
-
2243
- .an-emoji-grid {
2244
- scrollbar-color: #45475a transparent;
2245
- }
2246
-
2247
- // Icon dialog
2248
- .an-icon-box { background: #1e1e2e; border-color: #45475a; }
2249
-
2250
- .an-icon-grid { background: #181825; border-color: #45475a; }
2251
-
2252
- .an-icon-options {
2253
- background: #181825;
2254
- border-color: #45475a;
2255
- }
2256
-
2257
- .an-icon-preview {
2258
- background: #181825;
2259
- border-color: #45475a;
2260
- color: #cdd6f4;
2261
-
2262
- .an-icon-preview-empty { color: #6c7086; }
2263
- }
2264
-
2265
- .an-icon-option-select {
2266
- background: #313244;
2267
- border-color: #45475a;
2268
- color: #cdd6f4;
2269
- }
2270
-
2271
- .an-icon-empty { color: #6c7086; }
2272
-
2273
- // Bubble toolbar color picker
2274
- .an-bubble-color-picker {
2275
- background: #24273a;
2276
- border-color: #3f3f5f;
2277
-
2278
- .an-context-color-custom {
2279
- border-color: #3f3f5f;
2280
- color: #a6adc8;
2281
- }
2282
- }
2283
-
2284
- // Table tooltip (extends link-tooltip dark rules)
2285
- .an-table-tooltip { background: #24273a; border-color: #3f3f5f; }
2286
-
2287
- // Find & Replace floating panel box
2288
- .an-fr-box { background: #1e1e2e; border-color: #45475a; }
2289
- }
2290
-
2291
-
2292
- // =============================================================================
2293
- // Toolbar overflow modes
2294
- // =============================================================================
2295
-
2296
- // Default: flex-wrap:wrap (already set on .an-toolbar).
2297
- // When toolbarOverflow:'scroll', the consumer adds .an-toolbar-overflow-scroll
2298
- // to the container; toolbar becomes a single horizontally scrollable row.
2299
- .an-toolbar-overflow-scroll {
2300
- .an-toolbar {
2301
- flex-wrap: nowrap;
2302
- overflow-x: auto;
2303
- scrollbar-width: thin;
2304
-
2305
- // WebKit scrollbar - kept minimal
2306
- &::-webkit-scrollbar {
2307
- height: 4px;
2308
- }
2309
- &::-webkit-scrollbar-thumb {
2310
- background: $an-border;
2311
- border-radius: 2px;
2312
- }
2313
- }
2314
- }
2315
-
2316
- // =============================================================================
2317
- // Responsive — mobile / small-viewport toolbar
2318
- // =============================================================================
2319
- //
2320
- // On screens ≤ 640 px the default flex-wrap:wrap behaviour creates a multi-row
2321
- // toolbar that pushes the editable area too far down. We switch automatically
2322
- // to a single horizontally-scrollable row (same as toolbarOverflow:'scroll'),
2323
- // hide the scrollbar track, and compact the dropdown selects.
2324
-
2325
- @media (max-width: 640px) {
2326
- .an-toolbar {
2327
- flex-wrap: nowrap;
2328
- overflow-x: auto;
2329
- // Hide scrollbar visually — users swipe naturally on touch devices
2330
- scrollbar-width: none;
2331
- -ms-overflow-style: none;
2332
-
2333
- &::-webkit-scrollbar { display: none; }
2334
- }
2335
-
2336
- // Compact dropdown selects to save horizontal real-estate on small screens
2337
- .an-select {
2338
- min-width: 72px;
2339
- max-width: 90px;
2340
- font-size: 11px;
2341
- }
2342
-
2343
- .an-select-style { min-width: 62px; max-width: 76px; }
2344
- .an-select-narrow { min-width: 50px; max-width: 66px; }
2345
- }
2346
-
2347
- // =============================================================================
2348
- // RTL support
2349
- // =============================================================================
2350
-
2351
- .an-dir-rtl {
2352
- .an-toolbar {
2353
- direction: rtl;
2354
- }
2355
- }
2356
-
2357
- .an-editable[dir='rtl'] {
2358
- text-align: right;
2359
- }
2360
-
2361
- // =============================================================================
2362
- // Status-bar count warnings
2363
- // =============================================================================
2364
-
2365
- .an-count-warn {
2366
- color: #f59e0b; // amber-400 — approaching limit
2367
- font-weight: 600;
2368
- }
2369
-
2370
- .an-count-exceeded {
2371
- color: #ef4444; // red-500 — over limit
2372
- font-weight: 700;
2373
- }
2374
-
2375
- // =============================================================================
2376
- // Checklist (task list)
2377
- // =============================================================================
2378
-
2379
- .an-editable {
2380
- ul.an-checklist {
2381
- list-style: none;
2382
- padding-left: 0;
2383
- margin: 0.5em 0;
2384
-
2385
- li {
2386
- // Use padding-left + absolute checkbox so text is a normal inline flow
2387
- // (not an anonymous flex item). This ensures font-size, line-height and
2388
- // all inline formats are identical to regular paragraph text.
2389
- position: relative;
2390
- padding-left: 22px;
2391
- padding-top: 1px;
2392
- padding-bottom: 1px;
2393
- min-height: 1.4em;
2394
- line-height: inherit;
2395
- font-size: inherit;
2396
- font-family: inherit;
2397
-
2398
- input[type='checkbox'] {
2399
- position: absolute;
2400
- left: 0;
2401
- top: 0.25em;
2402
- width: 14px;
2403
- height: 14px;
2404
- margin: 0;
2405
- cursor: pointer;
2406
- accent-color: $an-primary;
2407
- }
2408
-
2409
- // Checked item: dim + strike-through the text node
2410
- &:has(input[type='checkbox']:checked) {
2411
- color: $an-muted;
2412
- text-decoration: line-through;
2413
- }
2414
- }
2415
- }
2416
- }
2417
-
2418
- .an-theme-dark .an-editable ul.an-checklist li:has(input[type='checkbox']:checked) {
2419
- color: $an-dark-muted;
2420
- }
2421
-
2422
- // =============================================================================
2423
- // Auto theme — mirrors dark theme when OS prefers dark and no explicit theme set
2424
- // =============================================================================
2425
-
2426
- @media (prefers-color-scheme: dark) {
2427
- .an-theme-auto {
2428
- border-color: #3f3f5f;
2429
- background: #1e1e2e;
2430
- color: #cdd6f4;
2431
-
2432
- &.an-focused {
2433
- border-color: #89b4fa;
2434
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.2);
2435
- }
2436
-
2437
- .an-toolbar {
2438
- background: #181825;
2439
- border-color: #3f3f5f;
2440
- }
2441
-
2442
- .an-btn {
2443
- color: #cdd6f4;
2444
-
2445
- &:hover {
2446
- background: #2a2a3e;
2447
- border-color: #3f3f5f;
2448
- color: #cdd6f4;
2449
-
2450
- svg { stroke: #cdd6f4; }
2451
- }
2452
-
2453
- &.active {
2454
- background: #1a3a5c;
2455
- border-color: #89b4fa;
2456
- color: #89b4fa;
2457
-
2458
- svg { stroke: #89b4fa; }
2459
- }
2460
-
2461
- &.an-btn-primary {
2462
- background: #3b5bdb;
2463
- border-color: #3b5bdb;
2464
- color: #fff;
2465
- }
2466
- }
2467
-
2468
- .an-select {
2469
- background-color: #1e1e2e;
2470
- border-color: #3f3f5f;
2471
- color: #cdd6f4;
2472
-
2473
- &:hover, &:focus { border-color: #89b4fa; }
2474
- }
2475
-
2476
- .an-editable {
2477
- background: #1e1e2e;
2478
- color: #cdd6f4;
2479
-
2480
- a { color: #89b4fa; }
2481
-
2482
- blockquote {
2483
- border-color: #3f3f5f;
2484
- color: #a6adc8;
2485
- }
2486
-
2487
- pre:not([class*='language-']),
2488
- code:not([class*='language-']) {
2489
- background: #313244;
2490
- color: #cdd6f4;
2491
- }
2492
-
2493
- pre:not([class*='language-']) > code { background: transparent; }
2494
-
2495
- hr { border-color: #3f3f5f; }
2496
-
2497
- table, .an-table {
2498
- td, th { border-color: #3f3f5f; }
2499
- th { background: #313244; }
2500
- }
2501
-
2502
- &.an-placeholder::before { color: #6c7086; }
2503
-
2504
- figcaption.an-figcaption { color: #6c7086; }
2505
- }
2506
-
2507
- .an-statusbar {
2508
- background: #181825;
2509
- border-color: #3f3f5f;
2510
- color: #6c7086;
2511
- }
2512
-
2513
- .an-link-tooltip,
2514
- .an-contextmenu {
2515
- background: #24273a;
2516
- border-color: #3f3f5f;
2517
- color: #cdd6f4;
2518
- }
2519
-
2520
- .an-link-tooltip-url { color: #89b4fa; }
2521
-
2522
- .an-link-tooltip-btn {
2523
- color: #a6adc8;
2524
-
2525
- &:hover {
2526
- background: #2a2a3e;
2527
- color: #cdd6f4;
2528
- }
2529
- }
2530
-
2531
- .an-dialog-overlay { background: rgba(0, 0, 0, 0.65); }
2532
-
2533
- .an-dialog-box {
2534
- background: #24273a;
2535
- color: #cdd6f4;
2536
- border: 1px solid #3f3f5f;
2537
- }
2538
-
2539
- .an-dialog-title { color: #cdd6f4; }
2540
-
2541
- .an-input {
2542
- background: #313244;
2543
- border-color: #3f3f5f;
2544
- color: #cdd6f4;
2545
-
2546
- &:focus {
2547
- border-color: #89b4fa;
2548
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.15);
2549
- }
2550
- }
2551
-
2552
- .an-color-popup,
2553
- .an-table-picker-popup,
2554
- .an-size-popover,
2555
- .an-cell-shade-popover {
2556
- background: #24273a;
2557
- border-color: #3f3f5f;
2558
- color: #cdd6f4;
2559
- }
2560
-
2561
- .an-context-color-swatch {
2562
- border-color: rgba(255, 255, 255, 0.15);
2563
- &:hover { border-color: rgba(255, 255, 255, 0.5); }
2564
- }
2565
-
2566
- .an-label { color: #cdd6f4; }
2567
- }
2568
-
2569
- .an-theme-auto .an-editable ul.an-checklist li:has(input[type='checkbox']:checked) {
2570
- color: $an-dark-muted;
2571
- }
2572
- }
2573
-
2574
- // =============================================================================
2575
- // Print styles
2576
- // =============================================================================
2577
-
2578
- @media print {
2579
- .an-container {
2580
- border: none;
2581
- box-shadow: none;
2582
- contain: none; // allow natural page flow when printing
2583
- }
2584
-
2585
- .an-toolbar,
2586
- .an-statusbar {
2587
- display: none !important;
2588
- }
2589
-
2590
- .an-editable {
2591
- overflow: visible;
2592
- height: auto !important;
2593
- max-height: none !important;
2594
- padding: 0;
2595
- color: #000;
2596
- background: #fff;
2597
- }
2598
-
2599
- .an-video-wrapper .an-video-shield {
2600
- display: none; // allow clicking embedded media when printing is unlikely
2601
- }
2602
-
2603
- .an-image-resizer,
2604
- .an-video-resizer {
2605
- display: none !important;
2606
- }
2607
- }
2608
-
2609
- // =============================================================================
2610
- // Auto-save restore banner (#2)
2611
- // =============================================================================
2612
-
2613
- .an-asr-banner {
2614
- display: flex;
2615
- align-items: center;
2616
- gap: 8px;
2617
- padding: 8px 12px;
2618
- background: #eff6ff;
2619
- border-bottom: 1px solid #bfdbfe;
2620
- font-size: 13px;
2621
- color: #1e40af;
2622
- flex-wrap: wrap;
2623
-
2624
- .an-theme-dark & {
2625
- background: #1e3a5f;
2626
- border-bottom-color: #1e4d8c;
2627
- color: #93c5fd;
2628
- }
2629
- }
2630
-
2631
- .an-asr-msg {
2632
- flex: 1;
2633
- min-width: 0;
2634
- }
2635
-
2636
- .an-asr-btn-restore {
2637
- padding: 3px 10px;
2638
- font-size: 12px;
2639
- font-weight: 600;
2640
- background: $an-primary;
2641
- color: #fff;
2642
- border: none;
2643
- border-radius: $an-radius-sm;
2644
- cursor: pointer;
2645
- line-height: 1.5;
2646
-
2647
- &:hover {
2648
- background: $an-primary-hover;
2649
- }
2650
- }
2651
-
2652
- .an-asr-btn-discard {
2653
- padding: 3px 10px;
2654
- font-size: 12px;
2655
- background: transparent;
2656
- color: $an-muted;
2657
- border: 1px solid $an-border;
2658
- border-radius: $an-radius-sm;
2659
- cursor: pointer;
2660
- line-height: 1.5;
2661
-
2662
- &:hover {
2663
- background: $an-bg-btn-hover;
2664
- }
2665
- }
2666
-
2667
- // =============================================================================
2668
- // Bubble toolbar (#4)
2669
- // =============================================================================
2670
-
2671
- .an-bubble-toolbar {
2672
- display: none;
2673
- position: fixed;
2674
- z-index: 10040;
2675
- background: $an-bg;
2676
- border: 1px solid $an-border;
2677
- border-radius: 8px;
2678
- padding: 4px 6px;
2679
- gap: 2px;
2680
- box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
2681
- align-items: center;
2682
- animation: an-bubble-in 0.1s ease;
2683
- pointer-events: auto;
2684
- user-select: none;
2685
-
2686
- .an-theme-dark & {
2687
- background: #24273a;
2688
- border-color: #3f3f5f;
2689
- }
2690
- }
2691
-
2692
- @keyframes an-bubble-in {
2693
- from { opacity: 0; transform: translateY(4px); }
2694
- to { opacity: 1; transform: translateY(0); }
2695
- }
2696
-
2697
- .an-bubble-btn {
2698
- display: flex;
2699
- align-items: center;
2700
- justify-content: center;
2701
- width: 28px;
2702
- height: 28px;
2703
- padding: 0;
2704
- background: transparent;
2705
- border: none;
2706
- border-radius: 5px;
2707
- color: $an-text;
2708
- cursor: pointer;
2709
- transition: background $an-transition, color $an-transition;
2710
-
2711
- svg {
2712
- pointer-events: none;
2713
- stroke: currentColor;
2714
- }
2715
-
2716
- &:hover {
2717
- background: $an-bg-btn-hover;
2718
- color: $an-text;
2719
- }
2720
-
2721
- &.an-active {
2722
- background: $an-bg-btn-active;
2723
- color: $an-primary;
2724
- }
2725
-
2726
- // Color variant: SVG stacked above a thin color-indicator strip
2727
- &.an-bubble-btn--color {
2728
- flex-direction: column;
2729
- gap: 1px;
2730
- padding: 4px 0 3px;
2731
-
2732
- .an-bubble-btn-svg {
2733
- display: flex;
2734
- align-items: center;
2735
- justify-content: center;
2736
- line-height: 0;
2737
-
2738
- svg { display: block; }
2739
- }
2740
-
2741
- .an-bubble-color-strip {
2742
- display: block;
2743
- width: 14px;
2744
- height: 3px;
2745
- border-radius: 1px;
2746
- pointer-events: none;
2747
- }
2748
- }
2749
-
2750
- .an-theme-dark & {
2751
- color: #cdd6f4;
2752
-
2753
- &:hover {
2754
- background: #313244;
2755
- }
2756
-
2757
- &.an-active {
2758
- background: #1e3a5f;
2759
- color: #93c5fd;
2760
- }
2761
- }
2762
- }
2763
-
2764
- // Bubble toolbar — color picker popup
2765
- .an-bubble-color-picker {
2766
- position: fixed;
2767
- z-index: 10041;
2768
- background: $an-bg;
2769
- border: 1px solid $an-border;
2770
- border-radius: 8px;
2771
- box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
2772
- padding: 4px 0;
2773
- min-width: 160px;
2774
-
2775
- .an-theme-dark & {
2776
- background: #24273a;
2777
- border-color: #3f3f5f;
2778
- }
2779
- }
2780
-
2781
- // =============================================================================
2782
- // @mention dropdown + chip (#5)
2783
- // =============================================================================
2784
-
2785
- .an-mention-dropdown {
2786
- display: none;
2787
- position: fixed;
2788
- z-index: 9998;
2789
- background: $an-bg;
2790
- border: 1px solid $an-border;
2791
- border-radius: $an-radius;
2792
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
2793
- min-width: 180px;
2794
- max-width: 280px;
2795
- max-height: 240px;
2796
- overflow-y: auto;
2797
- padding: 4px 0;
2798
- }
2799
-
2800
- .an-mention-item {
2801
- display: flex;
2802
- align-items: center;
2803
- gap: 8px;
2804
- padding: 6px 12px;
2805
- cursor: pointer;
2806
- font-size: 13px;
2807
- color: $an-text;
2808
- transition: background $an-transition;
2809
-
2810
- &:hover,
2811
- &.an-mention-active {
2812
- background: $an-bg-btn-hover;
2813
- }
2814
- }
2815
-
2816
- .an-mention-avatar {
2817
- width: 24px;
2818
- height: 24px;
2819
- border-radius: 50%;
2820
- object-fit: cover;
2821
- flex-shrink: 0;
2822
- }
2823
-
2824
- // Mention chip — inserted inline in the editor content
2825
- .an-mention {
2826
- display: inline;
2827
- background: #eff6ff;
2828
- color: $an-primary;
2829
- border-radius: 3px;
2830
- padding: 0 3px;
2831
- font-weight: 500;
2832
- cursor: default;
2833
- user-select: all;
2834
-
2835
- .an-theme-dark & {
2836
- background: #1e3a5f;
2837
- color: #93c5fd;
2838
- }
2839
- }
2840
-
2841
- // =============================================================================
2842
- // "/" command palette
2843
- // =============================================================================
2844
-
2845
- .an-slash-menu {
2846
- display: none;
2847
- position: fixed;
2848
- z-index: 9998;
2849
- background: $an-bg;
2850
- border: 1px solid $an-border;
2851
- border-radius: $an-radius;
2852
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
2853
- min-width: 180px;
2854
- max-width: 260px;
2855
- max-height: 260px;
2856
- overflow-y: auto;
2857
- padding: 4px 0;
2858
- }
2859
-
2860
- .an-slash-menu-item {
2861
- padding: 6px 12px;
2862
- cursor: pointer;
2863
- font-size: 13px;
2864
- color: $an-text;
2865
- transition: background $an-transition;
2866
-
2867
- &:hover,
2868
- &.an-slash-menu-active {
2869
- background: $an-bg-btn-hover;
2870
- }
2871
- }
2872
-
2873
- .an-slash-menu-empty {
2874
- padding: 6px 12px;
2875
- font-size: 13px;
2876
- color: $an-muted;
2877
- }