autumnnote 2.0.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 (64) hide show
  1. package/README.md +72 -5
  2. package/dist/autumnnote.cjs +20 -20
  3. package/dist/autumnnote.css +1 -1
  4. package/dist/autumnnote.es.js +661 -798
  5. package/dist/autumnnote.es.js.map +1 -1
  6. package/dist/autumnnote.min.js +20 -20
  7. package/dist/autumnnote.umd.js +20 -20
  8. package/dist/autumnnote.umd.js.map +1 -1
  9. package/dist/icon-data-V0Xqv-wX.js +255 -0
  10. package/dist/icon-data-V0Xqv-wX.js.map +1 -0
  11. package/package.json +13 -4
  12. package/types/index.d.ts +8 -0
  13. package/src/js/Context.js +0 -854
  14. package/src/js/core/detectLang.js +0 -98
  15. package/src/js/core/dom.js +0 -372
  16. package/src/js/core/env.js +0 -25
  17. package/src/js/core/key.js +0 -66
  18. package/src/js/core/lists.js +0 -121
  19. package/src/js/core/markdown.js +0 -695
  20. package/src/js/core/range.js +0 -194
  21. package/src/js/core/sanitise.js +0 -231
  22. package/src/js/editing/History.js +0 -266
  23. package/src/js/editing/Style.js +0 -812
  24. package/src/js/editing/Table.js +0 -105
  25. package/src/js/editing/Typing.js +0 -397
  26. package/src/js/index.js +0 -193
  27. package/src/js/index.umd.js +0 -17
  28. package/src/js/module/AutoSaveRestore.js +0 -125
  29. package/src/js/module/BaseDialog.js +0 -133
  30. package/src/js/module/BaseMediaTooltip.js +0 -142
  31. package/src/js/module/BaseResizer.js +0 -312
  32. package/src/js/module/BubbleToolbar.js +0 -483
  33. package/src/js/module/Buttons.js +0 -399
  34. package/src/js/module/Clipboard.js +0 -579
  35. package/src/js/module/CodeTooltip.js +0 -493
  36. package/src/js/module/Codeview.js +0 -125
  37. package/src/js/module/ContextMenu.js +0 -621
  38. package/src/js/module/Editor.js +0 -747
  39. package/src/js/module/EmojiDialog.js +0 -254
  40. package/src/js/module/FindReplace.js +0 -512
  41. package/src/js/module/Fullscreen.js +0 -80
  42. package/src/js/module/IconDialog.js +0 -618
  43. package/src/js/module/ImageCropOverlay.js +0 -586
  44. package/src/js/module/ImageDialog.js +0 -193
  45. package/src/js/module/ImageResizer.js +0 -42
  46. package/src/js/module/ImageTooltip.js +0 -285
  47. package/src/js/module/LinkDialog.js +0 -145
  48. package/src/js/module/LinkTooltip.js +0 -250
  49. package/src/js/module/MarkdownShortcuts.js +0 -250
  50. package/src/js/module/Mention.js +0 -365
  51. package/src/js/module/Placeholder.js +0 -51
  52. package/src/js/module/ShortcutsDialog.js +0 -111
  53. package/src/js/module/SlashMenu.js +0 -376
  54. package/src/js/module/Statusbar.js +0 -246
  55. package/src/js/module/TableTooltip.js +0 -1521
  56. package/src/js/module/Toolbar.js +0 -750
  57. package/src/js/module/VideoDialog.js +0 -193
  58. package/src/js/module/VideoResizer.js +0 -66
  59. package/src/js/module/VideoTooltip.js +0 -248
  60. package/src/js/module/emoji-data.js +0 -496
  61. package/src/js/renderer.js +0 -120
  62. package/src/js/settings.js +0 -214
  63. package/src/styles/_variables.scss +0 -48
  64. package/src/styles/autumnnote.scss +0 -2866
@@ -1,2866 +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
- }
1394
-
1395
- // Corners
1396
- .an-resize-nw { top: -4px; left: -4px; cursor: nw-resize; }
1397
- .an-resize-ne { top: -4px; right: -4px; cursor: ne-resize; }
1398
- .an-resize-se { bottom: -4px; right: -4px; cursor: se-resize; }
1399
- .an-resize-sw { bottom: -4px; left: -4px; cursor: sw-resize; }
1400
-
1401
- // Edge midpoints
1402
- .an-resize-n { top: -4px; left: calc(50% - 4px); cursor: n-resize; }
1403
- .an-resize-e { top: calc(50% - 4px); right: -4px; cursor: e-resize; }
1404
- .an-resize-s { bottom: -4px; left: calc(50% - 4px); cursor: s-resize; }
1405
- .an-resize-w { top: calc(50% - 4px); left: -4px; cursor: w-resize; }
1406
- }
1407
-
1408
- // ---------------------------------------------------------------------------
1409
- // Image crop overlay
1410
- // ---------------------------------------------------------------------------
1411
-
1412
- // The scrim and crop box are appended to <body> and positioned fixed, so they
1413
- // live outside .an-container. All styles are standalone (no SCSS nesting).
1414
-
1415
- .an-crop-scrim {
1416
- // Inline styles handle position/z-index/background for performance;
1417
- // clip-path is updated by JS every frame so we only declare the transition.
1418
- transition: clip-path 0s; // disable transition — updated synchronously on drag
1419
- }
1420
-
1421
- .an-crop-box {
1422
- // Core layout & interaction via inline styles in JS (position changes every drag frame).
1423
- // Only declare the animated ring so it stays in sync with $an-primary.
1424
- outline: none !important;
1425
-
1426
- // Subtle inner shadow that frames the "live" area
1427
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45),
1428
- inset 0 0 0 1px rgba(255, 255, 255, 0.25);
1429
- }
1430
-
1431
- .an-crop-handle {
1432
- // Inline styles handle size/position; declare hover highlight only.
1433
- &:hover, &:active {
1434
- background: #74affa !important; // $an-primary lightened ~14%
1435
- }
1436
- }
1437
-
1438
- .an-crop-toolbar {
1439
- // Inline styles handle position; add a subtle entrance animation.
1440
- animation: an-crop-toolbar-in 0.12s ease;
1441
- }
1442
-
1443
- @keyframes an-crop-toolbar-in {
1444
- from { opacity: 0; transform: translateY(4px); }
1445
- to { opacity: 1; transform: translateY(0); }
1446
- }
1447
-
1448
- // Hide canvas-based crop overlay when printing
1449
- @media print {
1450
- .an-crop-scrim,
1451
- .an-crop-box,
1452
- .an-crop-toolbar {
1453
- display: none !important;
1454
- }
1455
- }
1456
-
1457
- // ---------------------------------------------------------------------------
1458
- // Video resize overlay
1459
- // ---------------------------------------------------------------------------
1460
-
1461
- $an-video-accent: #8b5cf6; // violet-500
1462
-
1463
- .an-video-resizer {
1464
- position: absolute;
1465
- z-index: 10000;
1466
- box-sizing: border-box;
1467
- border: 2px solid $an-video-accent;
1468
- pointer-events: none;
1469
-
1470
- .an-resize-handle {
1471
- position: absolute;
1472
- width: 8px;
1473
- height: 8px;
1474
- background: $an-video-accent;
1475
- border: 1px solid #fff;
1476
- border-radius: 1px;
1477
- box-sizing: border-box;
1478
- pointer-events: all;
1479
- }
1480
-
1481
- // Corners
1482
- .an-resize-nw { top: -4px; left: -4px; cursor: nw-resize; }
1483
- .an-resize-ne { top: -4px; right: -4px; cursor: ne-resize; }
1484
- .an-resize-se { bottom: -4px; right: -4px; cursor: se-resize; }
1485
- .an-resize-sw { bottom: -4px; left: -4px; cursor: sw-resize; }
1486
-
1487
- // Edge midpoints
1488
- .an-resize-n { top: -4px; left: calc(50% - 4px); cursor: n-resize; }
1489
- .an-resize-e { top: calc(50% - 4px); right: -4px; cursor: e-resize; }
1490
- .an-resize-s { bottom: -4px; left: calc(50% - 4px); cursor: s-resize; }
1491
- .an-resize-w { top: calc(50% - 4px); left: -4px; cursor: w-resize; }
1492
- }
1493
-
1494
- // .an-video-selected is applied by VideoResizer for JS state tracking.
1495
- // Visual selection is handled entirely by the .an-video-resizer overlay,
1496
- // so no CSS outline is needed here (two visible frames would appear otherwise).
1497
-
1498
- // ---------------------------------------------------------------------------
1499
- // Icon dialog
1500
- // ---------------------------------------------------------------------------
1501
-
1502
- // Wider box override
1503
- .an-icon-box {
1504
- width: min(596px, 95vw);
1505
- gap: 0;
1506
- padding: 20px;
1507
- }
1508
-
1509
- // Title row with close button
1510
- .an-icon-title-row {
1511
- display: flex;
1512
- align-items: center;
1513
- justify-content: space-between;
1514
- margin-bottom: 14px;
1515
-
1516
- .an-dialog-title {
1517
- margin: 0;
1518
- }
1519
- }
1520
-
1521
- // Icon + title grouped together (used in emoji/icon/find dialogs)
1522
- .an-dialog-title-group {
1523
- display: flex;
1524
- align-items: center;
1525
- gap: 10px;
1526
- }
1527
-
1528
- // Small icon variant for dialogs with title-row layout
1529
- .an-dialog-icon--sm {
1530
- width: 32px;
1531
- height: 32px;
1532
- border-radius: 8px;
1533
- background: rgba($an-primary, 0.1);
1534
- color: $an-primary;
1535
- display: flex;
1536
- align-items: center;
1537
- justify-content: center;
1538
- flex-shrink: 0;
1539
-
1540
- svg { display: block; stroke: currentColor; }
1541
- }
1542
-
1543
- .an-icon-close {
1544
- display: flex;
1545
- align-items: center;
1546
- justify-content: center;
1547
- width: 26px;
1548
- height: 26px;
1549
- padding: 0;
1550
- font-size: 18px;
1551
- line-height: 1;
1552
- background: none;
1553
- border: none;
1554
- border-radius: $an-radius-sm;
1555
- cursor: pointer;
1556
- color: $an-muted;
1557
- flex-shrink: 0;
1558
-
1559
- &:hover {
1560
- background: $an-bg-btn-hover;
1561
- color: $an-text;
1562
- }
1563
- }
1564
-
1565
- // Search
1566
- .an-icon-search {
1567
- width: 100%;
1568
- margin-bottom: 10px;
1569
- box-sizing: border-box;
1570
- }
1571
-
1572
- // Category tabs
1573
- .an-icon-cats {
1574
- display: flex;
1575
- flex-wrap: wrap;
1576
- gap: 4px;
1577
- margin-bottom: 10px;
1578
- }
1579
-
1580
- .an-icon-cat {
1581
- height: 26px;
1582
- padding: 0 10px;
1583
- font-size: 12px;
1584
- font-family: $an-font-family;
1585
- background: none;
1586
- border: 1px solid $an-border;
1587
- border-radius: 13px;
1588
- cursor: pointer;
1589
- color: $an-muted;
1590
- white-space: nowrap;
1591
- transition: background $an-transition, color $an-transition, border-color $an-transition;
1592
-
1593
- &:hover {
1594
- background: $an-bg-btn-hover;
1595
- color: $an-text;
1596
- }
1597
-
1598
- &.active {
1599
- background: $an-primary;
1600
- border-color: $an-primary;
1601
- color: #fff;
1602
- }
1603
- }
1604
-
1605
- // Icon grid
1606
- .an-icon-grid {
1607
- display: grid;
1608
- grid-template-columns: repeat(auto-fill, 56px);
1609
- gap: 3px;
1610
- height: 256px;
1611
- overflow-y: auto;
1612
- margin-bottom: 10px;
1613
- padding: 4px;
1614
- border: 1px solid $an-border;
1615
- border-radius: $an-radius;
1616
- background: $an-bg;
1617
- scrollbar-width: thin;
1618
- scrollbar-color: $an-border transparent;
1619
-
1620
- &::-webkit-scrollbar { width: 6px; }
1621
- &::-webkit-scrollbar-track { background: transparent; }
1622
- &::-webkit-scrollbar-thumb { background: $an-border; border-radius: 3px; }
1623
- }
1624
-
1625
- .an-icon-cell {
1626
- display: flex;
1627
- flex-direction: column;
1628
- align-items: center;
1629
- justify-content: center;
1630
- gap: 3px;
1631
- width: 56px;
1632
- height: 52px;
1633
- padding: 0;
1634
- border: 1px solid transparent;
1635
- border-radius: $an-radius-sm;
1636
- background: none;
1637
- cursor: pointer;
1638
- font-family: $an-font-family;
1639
- font-size: 10px;
1640
- color: $an-muted;
1641
- transition: background $an-transition, border-color $an-transition;
1642
- overflow: hidden;
1643
- box-sizing: border-box;
1644
-
1645
- i {
1646
- font-size: 17px;
1647
- color: $an-text;
1648
- line-height: 1;
1649
- pointer-events: none;
1650
- }
1651
-
1652
- span {
1653
- overflow: hidden;
1654
- text-overflow: ellipsis;
1655
- white-space: nowrap;
1656
- max-width: 52px;
1657
- pointer-events: none;
1658
- }
1659
-
1660
- &:hover {
1661
- background: $an-bg-btn-hover;
1662
- border-color: $an-border;
1663
- }
1664
-
1665
- &.active {
1666
- background: rgba($an-primary, 0.1);
1667
- border-color: $an-primary;
1668
- color: $an-primary;
1669
-
1670
- i { color: $an-primary; }
1671
- }
1672
- }
1673
-
1674
- // Empty state
1675
- .an-icon-empty {
1676
- grid-column: 1 / -1;
1677
- padding: 24px 0;
1678
- text-align: center;
1679
- color: $an-muted;
1680
- font-size: 13px;
1681
- }
1682
-
1683
- // Options row
1684
- .an-icon-options {
1685
- display: flex;
1686
- align-items: center;
1687
- flex-wrap: wrap;
1688
- gap: 6px 10px;
1689
- margin-bottom: 10px;
1690
-
1691
- .an-label {
1692
- margin: 0;
1693
- font-size: 12px;
1694
- white-space: nowrap;
1695
- }
1696
- }
1697
-
1698
- .an-icon-option-select {
1699
- height: $an-btn-height;
1700
- padding: 0 6px;
1701
- font-size: 12px;
1702
- width: auto;
1703
- }
1704
-
1705
- .an-icon-color {
1706
- width: 32px;
1707
- height: $an-btn-height;
1708
- padding: 2px;
1709
- border: 1px solid $an-border;
1710
- border-radius: $an-radius-sm;
1711
- cursor: pointer;
1712
- background: none;
1713
- }
1714
-
1715
- .an-icon-use-color {
1716
- display: flex;
1717
- align-items: center;
1718
- gap: 4px;
1719
- font-size: 12px;
1720
- margin: 0;
1721
- cursor: pointer;
1722
-
1723
- input[type='checkbox'] {
1724
- cursor: pointer;
1725
- }
1726
- }
1727
-
1728
- // Preview
1729
- .an-icon-preview {
1730
- display: flex;
1731
- flex-direction: column;
1732
- align-items: center;
1733
- justify-content: center;
1734
- gap: 6px;
1735
- min-height: 72px;
1736
- margin-bottom: 14px;
1737
- padding: 10px 12px;
1738
- border: 1px solid $an-border;
1739
- border-radius: $an-radius;
1740
- background: $an-bg-toolbar;
1741
-
1742
- i {
1743
- line-height: 1;
1744
- }
1745
-
1746
- .an-icon-preview-hint {
1747
- font-size: 12px;
1748
- color: $an-muted;
1749
- }
1750
- }
1751
-
1752
- .an-icon-preview-name {
1753
- font-size: 12px;
1754
- color: $an-muted;
1755
- font-family: monospace;
1756
- }
1757
-
1758
- // ---------------------------------------------------------------------------
1759
- // Emoji dialog
1760
- // ---------------------------------------------------------------------------
1761
-
1762
- .an-emoji-box {
1763
- width: min(520px, 95vw);
1764
- gap: 0;
1765
- padding: 20px;
1766
- }
1767
-
1768
- .an-emoji-grid {
1769
- display: grid;
1770
- grid-template-columns: repeat(auto-fill, 42px);
1771
- gap: 2px;
1772
- height: 288px;
1773
- overflow-y: auto;
1774
- margin-bottom: 10px;
1775
- padding: 4px;
1776
- border: 1px solid $an-border;
1777
- border-radius: $an-radius;
1778
- scrollbar-width: thin;
1779
- scrollbar-color: $an-border transparent;
1780
-
1781
- &::-webkit-scrollbar { width: 6px; }
1782
- &::-webkit-scrollbar-track { background: transparent; }
1783
- &::-webkit-scrollbar-thumb { background: $an-border; border-radius: 3px; }
1784
- }
1785
-
1786
- .an-emoji-cell {
1787
- width: 42px;
1788
- height: 42px;
1789
- padding: 0;
1790
- display: flex;
1791
- align-items: center;
1792
- justify-content: center;
1793
- font-size: 22px;
1794
- line-height: 1;
1795
- border: 1px solid transparent;
1796
- border-radius: $an-radius-sm;
1797
- background: none;
1798
- cursor: pointer;
1799
- transition: background $an-transition, border-color $an-transition;
1800
-
1801
- &:hover {
1802
- background: $an-bg-btn-hover;
1803
- border-color: $an-border;
1804
- }
1805
-
1806
- &:active {
1807
- background: $an-bg-btn-active;
1808
- }
1809
- }
1810
-
1811
- // =============================================================================
1812
- // Sticky toolbar
1813
- // =============================================================================
1814
-
1815
- .an-sticky-toolbar {
1816
- overflow: visible;
1817
-
1818
- .an-toolbar {
1819
- position: sticky;
1820
- top: var(--an-sticky-top, 0px);
1821
- z-index: 100;
1822
- border-radius: $an-radius $an-radius 0 0;
1823
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10);
1824
- }
1825
- }
1826
-
1827
- // =============================================================================
1828
- // Image caption — figure / figcaption
1829
- // =============================================================================
1830
-
1831
- .an-editable {
1832
- figure.an-figure {
1833
- display: inline-block;
1834
- max-width: 100%;
1835
- margin: 0.75em 0;
1836
- text-align: center;
1837
-
1838
- img {
1839
- display: block;
1840
- max-width: 100%;
1841
- margin: 0 auto; // Centers img when figure uses fit-content or explicit width
1842
- }
1843
- }
1844
-
1845
- figcaption.an-figcaption {
1846
- font-size: 0.85em;
1847
- font-style: italic;
1848
- color: $an-muted;
1849
- padding: 4px 0 2px;
1850
- text-align: center;
1851
- line-height: 1.4;
1852
- min-width: 60px;
1853
- outline: none;
1854
-
1855
- &:focus {
1856
- background: rgba($an-primary, 0.06);
1857
- border-radius: 2px;
1858
- }
1859
- }
1860
- }
1861
-
1862
- // =============================================================================
1863
- // Keyboard shortcuts dialog
1864
- // =============================================================================
1865
-
1866
- .an-shortcuts-box {
1867
- width: min(480px, 95vw);
1868
- max-height: 80vh;
1869
- overflow-y: auto;
1870
- }
1871
-
1872
- .an-shortcuts-cat {
1873
- font-size: 11px;
1874
- font-weight: 600;
1875
- text-transform: uppercase;
1876
- letter-spacing: 0.06em;
1877
- color: $an-muted;
1878
- padding: 8px 0 4px;
1879
- border-bottom: 1px solid $an-border;
1880
- margin-bottom: 2px;
1881
-
1882
- & + .an-shortcuts-table + & {
1883
- margin-top: 10px;
1884
- }
1885
- }
1886
-
1887
- .an-shortcuts-table {
1888
- display: flex;
1889
- flex-direction: column;
1890
- }
1891
-
1892
- .an-shortcuts-row {
1893
- display: flex;
1894
- align-items: center;
1895
- justify-content: space-between;
1896
- padding: 5px 4px;
1897
- border-radius: $an-radius-sm;
1898
-
1899
- &:hover { background: $an-bg-btn-hover; }
1900
- }
1901
-
1902
- .an-shortcuts-key {
1903
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
1904
- font-size: 12px;
1905
- color: $an-text;
1906
- background: $an-bg-toolbar;
1907
- border: 1px solid $an-border;
1908
- border-bottom-width: 2px;
1909
- border-radius: $an-radius-sm;
1910
- padding: 2px 8px;
1911
- white-space: nowrap;
1912
- flex-shrink: 0;
1913
- }
1914
-
1915
- .an-shortcuts-action {
1916
- font-size: 13px;
1917
- color: $an-text;
1918
- flex: 1;
1919
- padding-left: 14px;
1920
- }
1921
-
1922
- // =============================================================================
1923
- // Code block language selector (inside CodeTooltip)
1924
- // =============================================================================
1925
-
1926
- .an-code-lang-select {
1927
- height: 22px;
1928
- padding: 0 20px 0 6px;
1929
- border: 1px solid $an-border;
1930
- border-radius: $an-radius-sm;
1931
- font-family: inherit;
1932
- font-size: 11px;
1933
- color: $an-text;
1934
- 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;
1935
- background-size: 6px 4px;
1936
- appearance: none;
1937
- -webkit-appearance: none;
1938
- cursor: pointer;
1939
-
1940
- &:focus { outline: none; border-color: $an-primary; }
1941
- &:hover { border-color: $an-primary; }
1942
- }
1943
-
1944
- // =============================================================================
1945
- // Dark theme — apply via options: { theme: 'dark' }
1946
- // =============================================================================
1947
-
1948
- .an-theme-dark {
1949
- border-color: #3f3f5f;
1950
- background: #1e1e2e;
1951
- color: #cdd6f4;
1952
-
1953
- &.an-focused {
1954
- border-color: #89b4fa;
1955
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.2);
1956
- }
1957
-
1958
- .an-toolbar {
1959
- background: #181825;
1960
- border-color: #3f3f5f;
1961
- }
1962
-
1963
- .an-btn {
1964
- color: #cdd6f4;
1965
-
1966
- &:hover {
1967
- background: #2a2a3e;
1968
- border-color: #3f3f5f;
1969
- color: #cdd6f4;
1970
-
1971
- svg { stroke: #cdd6f4; }
1972
- }
1973
-
1974
- &.active {
1975
- background: #1a3a5c;
1976
- border-color: #89b4fa;
1977
- color: #89b4fa;
1978
-
1979
- svg { stroke: #89b4fa; }
1980
- }
1981
-
1982
- &.an-btn-primary {
1983
- background: #3b5bdb;
1984
- border-color: #3b5bdb;
1985
- color: #fff;
1986
- }
1987
- }
1988
-
1989
- .an-select {
1990
- background-color: #1e1e2e;
1991
- border-color: #3f3f5f;
1992
- color: #cdd6f4;
1993
-
1994
- &:hover, &:focus { border-color: #89b4fa; }
1995
- }
1996
-
1997
- .an-editable {
1998
- background: #1e1e2e;
1999
- color: #cdd6f4;
2000
-
2001
- a { color: #89b4fa; }
2002
-
2003
- blockquote {
2004
- border-color: #3f3f5f;
2005
- color: #a6adc8;
2006
- }
2007
-
2008
- pre:not([class*='language-']),
2009
- code:not([class*='language-']) {
2010
- background: #313244;
2011
- color: #cdd6f4;
2012
- }
2013
-
2014
- pre:not([class*='language-']) > code { background: transparent; }
2015
-
2016
- .an-code-line-numbers::before {
2017
- background: rgba(255, 255, 255, 0.05);
2018
- border-right-color: rgba(255, 255, 255, 0.1);
2019
- }
2020
-
2021
- hr { border-color: #3f3f5f; }
2022
-
2023
- table, .an-table {
2024
- td, th { border-color: #3f3f5f; }
2025
- th { background: #313244; }
2026
- }
2027
-
2028
- &.an-placeholder::before { color: #6c7086; }
2029
-
2030
- figcaption.an-figcaption { color: #6c7086; }
2031
- }
2032
-
2033
- .an-statusbar {
2034
- background: #181825;
2035
- border-color: #3f3f5f;
2036
- color: #6c7086;
2037
- }
2038
-
2039
- .an-link-tooltip,
2040
- .an-contextmenu {
2041
- background: #24273a;
2042
- border-color: #3f3f5f;
2043
- color: #cdd6f4;
2044
- }
2045
-
2046
- .an-link-tooltip-url { color: #89b4fa; }
2047
-
2048
- .an-link-tooltip-btn {
2049
- color: #a6adc8;
2050
-
2051
- &:hover {
2052
- background: #2a2a3e;
2053
- color: #cdd6f4;
2054
- }
2055
- }
2056
-
2057
- .an-dialog-overlay { background: rgba(0, 0, 0, 0.65); }
2058
-
2059
- .an-dialog-box {
2060
- background: #24273a;
2061
- color: #cdd6f4;
2062
- border: 1px solid #3f3f5f;
2063
- }
2064
-
2065
- .an-dialog-title { color: #cdd6f4; }
2066
-
2067
- .an-dialog-icon,
2068
- .an-dialog-icon--sm {
2069
- background: rgba(#818cf8, 0.15);
2070
- color: #818cf8;
2071
- }
2072
-
2073
- .an-fr-icon-btn {
2074
- color: #a6adc8;
2075
- &:hover { background: #313244; color: #cdd6f4; border-color: #45475a; }
2076
- &.an-fr-icon-btn--active { background: rgba(#818cf8, 0.15); color: #818cf8; border-color: rgba(#818cf8, 0.3); }
2077
- }
2078
-
2079
- .an-fr-counter { color: #6c7086; }
2080
-
2081
- .an-label { color: #cdd6f4; }
2082
-
2083
- .an-input {
2084
- background: #313244;
2085
- border-color: #3f3f5f;
2086
- color: #cdd6f4;
2087
-
2088
- &:focus {
2089
- border-color: #89b4fa;
2090
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.15);
2091
- }
2092
- }
2093
-
2094
- .an-shortcuts-key {
2095
- background: #313244;
2096
- border-color: #3f3f5f;
2097
- color: #cdd6f4;
2098
- }
2099
-
2100
- .an-shortcuts-action { color: #cdd6f4; }
2101
- .an-shortcuts-row:hover { background: #2a2a3e; }
2102
-
2103
- .an-shortcuts-cat {
2104
- border-color: #3f3f5f;
2105
- color: #a6adc8;
2106
- }
2107
-
2108
- .an-code-lang-select {
2109
- background-color: #24273a;
2110
- border-color: #3f3f5f;
2111
- color: #cdd6f4;
2112
- }
2113
-
2114
- .an-color-popup,
2115
- .an-table-picker-popup,
2116
- .an-size-popover,
2117
- .an-cell-shade-popover {
2118
- background: #24273a;
2119
- border-color: #3f3f5f;
2120
- color: #cdd6f4;
2121
- }
2122
-
2123
- .an-cell-shade-popover .an-shade-no-color {
2124
- border-color: #3f3f5f;
2125
- color: #a6adc8;
2126
-
2127
- &:hover {
2128
- background: #313244;
2129
- color: #cdd6f4;
2130
- }
2131
- }
2132
-
2133
- .an-link-tooltip-btn--active {
2134
- background: rgba(#6366f1, 0.2) !important;
2135
- color: #818cf8 !important;
2136
- svg { stroke: #818cf8; }
2137
- }
2138
-
2139
- .an-cell-selected {
2140
- background-color: rgba(#6366f1, 0.25) !important;
2141
- outline-color: #6366f1;
2142
- }
2143
-
2144
- .an-table-cell {
2145
- background: #24273a;
2146
- border-color: #3f3f5f;
2147
-
2148
- &.active {
2149
- background: rgba(99, 102, 241, 0.3);
2150
- border-color: #6366f1;
2151
- }
2152
- }
2153
-
2154
- // Color popup children
2155
- .an-color-custom {
2156
- border-top-color: #3f3f5f;
2157
- color: #cdd6f4;
2158
- }
2159
-
2160
- .an-color-arrow:hover { border-left-color: #45475a; }
2161
-
2162
- .an-table-label { color: #6c7086; }
2163
- .an-context-table-grid-panel { border-top-color: #3f3f5f; }
2164
-
2165
- .an-context-item { color: #cdd6f4; }
2166
- .an-context-sep { background: #3f3f5f; }
2167
-
2168
- .an-context-color-swatch {
2169
- border-color: rgba(255, 255, 255, 0.15);
2170
- &:hover { border-color: rgba(255, 255, 255, 0.5); }
2171
- }
2172
-
2173
- .an-context-color-none {
2174
- background: #1e1e2e !important;
2175
- color: #888;
2176
- &:hover { color: #ccc; }
2177
- }
2178
-
2179
- .an-context-color-custom {
2180
- input[type='color'] { border-color: #3f3f5f; }
2181
- }
2182
-
2183
- .an-icon-cat {
2184
- border-color: #3f3f5f;
2185
- color: #a6adc8;
2186
-
2187
- &.active {
2188
- background: #3b5bdb;
2189
- border-color: #3b5bdb;
2190
- color: #fff;
2191
- }
2192
- }
2193
-
2194
- .an-icon-search {
2195
- border-color: #3f3f5f;
2196
- background: #313244;
2197
- color: #cdd6f4;
2198
- }
2199
-
2200
- .an-icon-cell {
2201
- color: #a6adc8;
2202
-
2203
- i { color: #cdd6f4; }
2204
-
2205
- &:hover { background: #2a2a3e; border-color: #45475a; }
2206
-
2207
- &.active {
2208
- background: rgba(#818cf8, 0.15);
2209
- border-color: #818cf8;
2210
- color: #818cf8;
2211
- i { color: #818cf8; }
2212
- }
2213
- }
2214
-
2215
- .an-icon-close {
2216
- color: #a6adc8;
2217
-
2218
- &:hover {
2219
- background: #2a2a3e;
2220
- color: #cdd6f4;
2221
- }
2222
- }
2223
-
2224
- // Emoji dialog
2225
- .an-emoji-box { background: #1e1e2e; border-color: #45475a; }
2226
-
2227
- .an-emoji-cell {
2228
- color: inherit;
2229
- &:hover { background: #313244; }
2230
- }
2231
-
2232
- .an-emoji-grid {
2233
- scrollbar-color: #45475a transparent;
2234
- }
2235
-
2236
- // Icon dialog
2237
- .an-icon-box { background: #1e1e2e; border-color: #45475a; }
2238
-
2239
- .an-icon-grid { background: #181825; border-color: #45475a; }
2240
-
2241
- .an-icon-options {
2242
- background: #181825;
2243
- border-color: #45475a;
2244
- }
2245
-
2246
- .an-icon-preview {
2247
- background: #181825;
2248
- border-color: #45475a;
2249
- color: #cdd6f4;
2250
-
2251
- .an-icon-preview-empty { color: #6c7086; }
2252
- }
2253
-
2254
- .an-icon-option-select {
2255
- background: #313244;
2256
- border-color: #45475a;
2257
- color: #cdd6f4;
2258
- }
2259
-
2260
- .an-icon-empty { color: #6c7086; }
2261
-
2262
- // Bubble toolbar color picker
2263
- .an-bubble-color-picker {
2264
- background: #24273a;
2265
- border-color: #3f3f5f;
2266
-
2267
- .an-context-color-custom {
2268
- border-color: #3f3f5f;
2269
- color: #a6adc8;
2270
- }
2271
- }
2272
-
2273
- // Table tooltip (extends link-tooltip dark rules)
2274
- .an-table-tooltip { background: #24273a; border-color: #3f3f5f; }
2275
-
2276
- // Find & Replace floating panel box
2277
- .an-fr-box { background: #1e1e2e; border-color: #45475a; }
2278
- }
2279
-
2280
-
2281
- // =============================================================================
2282
- // Toolbar overflow modes
2283
- // =============================================================================
2284
-
2285
- // Default: flex-wrap:wrap (already set on .an-toolbar).
2286
- // When toolbarOverflow:'scroll', the consumer adds .an-toolbar-overflow-scroll
2287
- // to the container; toolbar becomes a single horizontally scrollable row.
2288
- .an-toolbar-overflow-scroll {
2289
- .an-toolbar {
2290
- flex-wrap: nowrap;
2291
- overflow-x: auto;
2292
- scrollbar-width: thin;
2293
-
2294
- // WebKit scrollbar - kept minimal
2295
- &::-webkit-scrollbar {
2296
- height: 4px;
2297
- }
2298
- &::-webkit-scrollbar-thumb {
2299
- background: $an-border;
2300
- border-radius: 2px;
2301
- }
2302
- }
2303
- }
2304
-
2305
- // =============================================================================
2306
- // Responsive — mobile / small-viewport toolbar
2307
- // =============================================================================
2308
- //
2309
- // On screens ≤ 640 px the default flex-wrap:wrap behaviour creates a multi-row
2310
- // toolbar that pushes the editable area too far down. We switch automatically
2311
- // to a single horizontally-scrollable row (same as toolbarOverflow:'scroll'),
2312
- // hide the scrollbar track, and compact the dropdown selects.
2313
-
2314
- @media (max-width: 640px) {
2315
- .an-toolbar {
2316
- flex-wrap: nowrap;
2317
- overflow-x: auto;
2318
- // Hide scrollbar visually — users swipe naturally on touch devices
2319
- scrollbar-width: none;
2320
- -ms-overflow-style: none;
2321
-
2322
- &::-webkit-scrollbar { display: none; }
2323
- }
2324
-
2325
- // Compact dropdown selects to save horizontal real-estate on small screens
2326
- .an-select {
2327
- min-width: 72px;
2328
- max-width: 90px;
2329
- font-size: 11px;
2330
- }
2331
-
2332
- .an-select-style { min-width: 62px; max-width: 76px; }
2333
- .an-select-narrow { min-width: 50px; max-width: 66px; }
2334
- }
2335
-
2336
- // =============================================================================
2337
- // RTL support
2338
- // =============================================================================
2339
-
2340
- .an-dir-rtl {
2341
- .an-toolbar {
2342
- direction: rtl;
2343
- }
2344
- }
2345
-
2346
- .an-editable[dir='rtl'] {
2347
- text-align: right;
2348
- }
2349
-
2350
- // =============================================================================
2351
- // Status-bar count warnings
2352
- // =============================================================================
2353
-
2354
- .an-count-warn {
2355
- color: #f59e0b; // amber-400 — approaching limit
2356
- font-weight: 600;
2357
- }
2358
-
2359
- .an-count-exceeded {
2360
- color: #ef4444; // red-500 — over limit
2361
- font-weight: 700;
2362
- }
2363
-
2364
- // =============================================================================
2365
- // Checklist (task list)
2366
- // =============================================================================
2367
-
2368
- .an-editable {
2369
- ul.an-checklist {
2370
- list-style: none;
2371
- padding-left: 0;
2372
- margin: 0.5em 0;
2373
-
2374
- li {
2375
- // Use padding-left + absolute checkbox so text is a normal inline flow
2376
- // (not an anonymous flex item). This ensures font-size, line-height and
2377
- // all inline formats are identical to regular paragraph text.
2378
- position: relative;
2379
- padding-left: 22px;
2380
- padding-top: 1px;
2381
- padding-bottom: 1px;
2382
- min-height: 1.4em;
2383
- line-height: inherit;
2384
- font-size: inherit;
2385
- font-family: inherit;
2386
-
2387
- input[type='checkbox'] {
2388
- position: absolute;
2389
- left: 0;
2390
- top: 0.25em;
2391
- width: 14px;
2392
- height: 14px;
2393
- margin: 0;
2394
- cursor: pointer;
2395
- accent-color: $an-primary;
2396
- }
2397
-
2398
- // Checked item: dim + strike-through the text node
2399
- &:has(input[type='checkbox']:checked) {
2400
- color: $an-muted;
2401
- text-decoration: line-through;
2402
- }
2403
- }
2404
- }
2405
- }
2406
-
2407
- .an-theme-dark .an-editable ul.an-checklist li:has(input[type='checkbox']:checked) {
2408
- color: $an-dark-muted;
2409
- }
2410
-
2411
- // =============================================================================
2412
- // Auto theme — mirrors dark theme when OS prefers dark and no explicit theme set
2413
- // =============================================================================
2414
-
2415
- @media (prefers-color-scheme: dark) {
2416
- .an-theme-auto {
2417
- border-color: #3f3f5f;
2418
- background: #1e1e2e;
2419
- color: #cdd6f4;
2420
-
2421
- &.an-focused {
2422
- border-color: #89b4fa;
2423
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.2);
2424
- }
2425
-
2426
- .an-toolbar {
2427
- background: #181825;
2428
- border-color: #3f3f5f;
2429
- }
2430
-
2431
- .an-btn {
2432
- color: #cdd6f4;
2433
-
2434
- &:hover {
2435
- background: #2a2a3e;
2436
- border-color: #3f3f5f;
2437
- color: #cdd6f4;
2438
-
2439
- svg { stroke: #cdd6f4; }
2440
- }
2441
-
2442
- &.active {
2443
- background: #1a3a5c;
2444
- border-color: #89b4fa;
2445
- color: #89b4fa;
2446
-
2447
- svg { stroke: #89b4fa; }
2448
- }
2449
-
2450
- &.an-btn-primary {
2451
- background: #3b5bdb;
2452
- border-color: #3b5bdb;
2453
- color: #fff;
2454
- }
2455
- }
2456
-
2457
- .an-select {
2458
- background-color: #1e1e2e;
2459
- border-color: #3f3f5f;
2460
- color: #cdd6f4;
2461
-
2462
- &:hover, &:focus { border-color: #89b4fa; }
2463
- }
2464
-
2465
- .an-editable {
2466
- background: #1e1e2e;
2467
- color: #cdd6f4;
2468
-
2469
- a { color: #89b4fa; }
2470
-
2471
- blockquote {
2472
- border-color: #3f3f5f;
2473
- color: #a6adc8;
2474
- }
2475
-
2476
- pre:not([class*='language-']),
2477
- code:not([class*='language-']) {
2478
- background: #313244;
2479
- color: #cdd6f4;
2480
- }
2481
-
2482
- pre:not([class*='language-']) > code { background: transparent; }
2483
-
2484
- hr { border-color: #3f3f5f; }
2485
-
2486
- table, .an-table {
2487
- td, th { border-color: #3f3f5f; }
2488
- th { background: #313244; }
2489
- }
2490
-
2491
- &.an-placeholder::before { color: #6c7086; }
2492
-
2493
- figcaption.an-figcaption { color: #6c7086; }
2494
- }
2495
-
2496
- .an-statusbar {
2497
- background: #181825;
2498
- border-color: #3f3f5f;
2499
- color: #6c7086;
2500
- }
2501
-
2502
- .an-link-tooltip,
2503
- .an-contextmenu {
2504
- background: #24273a;
2505
- border-color: #3f3f5f;
2506
- color: #cdd6f4;
2507
- }
2508
-
2509
- .an-link-tooltip-url { color: #89b4fa; }
2510
-
2511
- .an-link-tooltip-btn {
2512
- color: #a6adc8;
2513
-
2514
- &:hover {
2515
- background: #2a2a3e;
2516
- color: #cdd6f4;
2517
- }
2518
- }
2519
-
2520
- .an-dialog-overlay { background: rgba(0, 0, 0, 0.65); }
2521
-
2522
- .an-dialog-box {
2523
- background: #24273a;
2524
- color: #cdd6f4;
2525
- border: 1px solid #3f3f5f;
2526
- }
2527
-
2528
- .an-dialog-title { color: #cdd6f4; }
2529
-
2530
- .an-input {
2531
- background: #313244;
2532
- border-color: #3f3f5f;
2533
- color: #cdd6f4;
2534
-
2535
- &:focus {
2536
- border-color: #89b4fa;
2537
- box-shadow: 0 0 0 3px rgba(#89b4fa, 0.15);
2538
- }
2539
- }
2540
-
2541
- .an-color-popup,
2542
- .an-table-picker-popup,
2543
- .an-size-popover,
2544
- .an-cell-shade-popover {
2545
- background: #24273a;
2546
- border-color: #3f3f5f;
2547
- color: #cdd6f4;
2548
- }
2549
-
2550
- .an-context-color-swatch {
2551
- border-color: rgba(255, 255, 255, 0.15);
2552
- &:hover { border-color: rgba(255, 255, 255, 0.5); }
2553
- }
2554
-
2555
- .an-label { color: #cdd6f4; }
2556
- }
2557
-
2558
- .an-theme-auto .an-editable ul.an-checklist li:has(input[type='checkbox']:checked) {
2559
- color: $an-dark-muted;
2560
- }
2561
- }
2562
-
2563
- // =============================================================================
2564
- // Print styles
2565
- // =============================================================================
2566
-
2567
- @media print {
2568
- .an-container {
2569
- border: none;
2570
- box-shadow: none;
2571
- contain: none; // allow natural page flow when printing
2572
- }
2573
-
2574
- .an-toolbar,
2575
- .an-statusbar {
2576
- display: none !important;
2577
- }
2578
-
2579
- .an-editable {
2580
- overflow: visible;
2581
- height: auto !important;
2582
- max-height: none !important;
2583
- padding: 0;
2584
- color: #000;
2585
- background: #fff;
2586
- }
2587
-
2588
- .an-video-wrapper .an-video-shield {
2589
- display: none; // allow clicking embedded media when printing is unlikely
2590
- }
2591
-
2592
- .an-image-resizer,
2593
- .an-video-resizer {
2594
- display: none !important;
2595
- }
2596
- }
2597
-
2598
- // =============================================================================
2599
- // Auto-save restore banner (#2)
2600
- // =============================================================================
2601
-
2602
- .an-asr-banner {
2603
- display: flex;
2604
- align-items: center;
2605
- gap: 8px;
2606
- padding: 8px 12px;
2607
- background: #eff6ff;
2608
- border-bottom: 1px solid #bfdbfe;
2609
- font-size: 13px;
2610
- color: #1e40af;
2611
- flex-wrap: wrap;
2612
-
2613
- .an-theme-dark & {
2614
- background: #1e3a5f;
2615
- border-bottom-color: #1e4d8c;
2616
- color: #93c5fd;
2617
- }
2618
- }
2619
-
2620
- .an-asr-msg {
2621
- flex: 1;
2622
- min-width: 0;
2623
- }
2624
-
2625
- .an-asr-btn-restore {
2626
- padding: 3px 10px;
2627
- font-size: 12px;
2628
- font-weight: 600;
2629
- background: $an-primary;
2630
- color: #fff;
2631
- border: none;
2632
- border-radius: $an-radius-sm;
2633
- cursor: pointer;
2634
- line-height: 1.5;
2635
-
2636
- &:hover {
2637
- background: $an-primary-hover;
2638
- }
2639
- }
2640
-
2641
- .an-asr-btn-discard {
2642
- padding: 3px 10px;
2643
- font-size: 12px;
2644
- background: transparent;
2645
- color: $an-muted;
2646
- border: 1px solid $an-border;
2647
- border-radius: $an-radius-sm;
2648
- cursor: pointer;
2649
- line-height: 1.5;
2650
-
2651
- &:hover {
2652
- background: $an-bg-btn-hover;
2653
- }
2654
- }
2655
-
2656
- // =============================================================================
2657
- // Bubble toolbar (#4)
2658
- // =============================================================================
2659
-
2660
- .an-bubble-toolbar {
2661
- display: none;
2662
- position: fixed;
2663
- z-index: 10040;
2664
- background: $an-bg;
2665
- border: 1px solid $an-border;
2666
- border-radius: 8px;
2667
- padding: 4px 6px;
2668
- gap: 2px;
2669
- box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
2670
- align-items: center;
2671
- animation: an-bubble-in 0.1s ease;
2672
- pointer-events: auto;
2673
- user-select: none;
2674
-
2675
- .an-theme-dark & {
2676
- background: #24273a;
2677
- border-color: #3f3f5f;
2678
- }
2679
- }
2680
-
2681
- @keyframes an-bubble-in {
2682
- from { opacity: 0; transform: translateY(4px); }
2683
- to { opacity: 1; transform: translateY(0); }
2684
- }
2685
-
2686
- .an-bubble-btn {
2687
- display: flex;
2688
- align-items: center;
2689
- justify-content: center;
2690
- width: 28px;
2691
- height: 28px;
2692
- padding: 0;
2693
- background: transparent;
2694
- border: none;
2695
- border-radius: 5px;
2696
- color: $an-text;
2697
- cursor: pointer;
2698
- transition: background $an-transition, color $an-transition;
2699
-
2700
- svg {
2701
- pointer-events: none;
2702
- stroke: currentColor;
2703
- }
2704
-
2705
- &:hover {
2706
- background: $an-bg-btn-hover;
2707
- color: $an-text;
2708
- }
2709
-
2710
- &.an-active {
2711
- background: $an-bg-btn-active;
2712
- color: $an-primary;
2713
- }
2714
-
2715
- // Color variant: SVG stacked above a thin color-indicator strip
2716
- &.an-bubble-btn--color {
2717
- flex-direction: column;
2718
- gap: 1px;
2719
- padding: 4px 0 3px;
2720
-
2721
- .an-bubble-btn-svg {
2722
- display: flex;
2723
- align-items: center;
2724
- justify-content: center;
2725
- line-height: 0;
2726
-
2727
- svg { display: block; }
2728
- }
2729
-
2730
- .an-bubble-color-strip {
2731
- display: block;
2732
- width: 14px;
2733
- height: 3px;
2734
- border-radius: 1px;
2735
- pointer-events: none;
2736
- }
2737
- }
2738
-
2739
- .an-theme-dark & {
2740
- color: #cdd6f4;
2741
-
2742
- &:hover {
2743
- background: #313244;
2744
- }
2745
-
2746
- &.an-active {
2747
- background: #1e3a5f;
2748
- color: #93c5fd;
2749
- }
2750
- }
2751
- }
2752
-
2753
- // Bubble toolbar — color picker popup
2754
- .an-bubble-color-picker {
2755
- position: fixed;
2756
- z-index: 10041;
2757
- background: $an-bg;
2758
- border: 1px solid $an-border;
2759
- border-radius: 8px;
2760
- box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
2761
- padding: 4px 0;
2762
- min-width: 160px;
2763
-
2764
- .an-theme-dark & {
2765
- background: #24273a;
2766
- border-color: #3f3f5f;
2767
- }
2768
- }
2769
-
2770
- // =============================================================================
2771
- // @mention dropdown + chip (#5)
2772
- // =============================================================================
2773
-
2774
- .an-mention-dropdown {
2775
- display: none;
2776
- position: fixed;
2777
- z-index: 9998;
2778
- background: $an-bg;
2779
- border: 1px solid $an-border;
2780
- border-radius: $an-radius;
2781
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
2782
- min-width: 180px;
2783
- max-width: 280px;
2784
- max-height: 240px;
2785
- overflow-y: auto;
2786
- padding: 4px 0;
2787
- }
2788
-
2789
- .an-mention-item {
2790
- display: flex;
2791
- align-items: center;
2792
- gap: 8px;
2793
- padding: 6px 12px;
2794
- cursor: pointer;
2795
- font-size: 13px;
2796
- color: $an-text;
2797
- transition: background $an-transition;
2798
-
2799
- &:hover,
2800
- &.an-mention-active {
2801
- background: $an-bg-btn-hover;
2802
- }
2803
- }
2804
-
2805
- .an-mention-avatar {
2806
- width: 24px;
2807
- height: 24px;
2808
- border-radius: 50%;
2809
- object-fit: cover;
2810
- flex-shrink: 0;
2811
- }
2812
-
2813
- // Mention chip — inserted inline in the editor content
2814
- .an-mention {
2815
- display: inline;
2816
- background: #eff6ff;
2817
- color: $an-primary;
2818
- border-radius: 3px;
2819
- padding: 0 3px;
2820
- font-weight: 500;
2821
- cursor: default;
2822
- user-select: all;
2823
-
2824
- .an-theme-dark & {
2825
- background: #1e3a5f;
2826
- color: #93c5fd;
2827
- }
2828
- }
2829
-
2830
- // =============================================================================
2831
- // "/" command palette
2832
- // =============================================================================
2833
-
2834
- .an-slash-menu {
2835
- display: none;
2836
- position: fixed;
2837
- z-index: 9998;
2838
- background: $an-bg;
2839
- border: 1px solid $an-border;
2840
- border-radius: $an-radius;
2841
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
2842
- min-width: 180px;
2843
- max-width: 260px;
2844
- max-height: 260px;
2845
- overflow-y: auto;
2846
- padding: 4px 0;
2847
- }
2848
-
2849
- .an-slash-menu-item {
2850
- padding: 6px 12px;
2851
- cursor: pointer;
2852
- font-size: 13px;
2853
- color: $an-text;
2854
- transition: background $an-transition;
2855
-
2856
- &:hover,
2857
- &.an-slash-menu-active {
2858
- background: $an-bg-btn-hover;
2859
- }
2860
- }
2861
-
2862
- .an-slash-menu-empty {
2863
- padding: 6px 12px;
2864
- font-size: 13px;
2865
- color: $an-muted;
2866
- }