@inkami/blx 0.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +98 -0
  2. package/dist/attributed-string/attributed-string.d.ts +37 -0
  3. package/dist/attributed-string/index.d.ts +2 -0
  4. package/dist/attributed-string/types.d.ts +13 -0
  5. package/dist/autocomplete/autocomplete-menu.d.ts +24 -0
  6. package/dist/autocomplete/index.d.ts +2 -0
  7. package/dist/autocomplete/types.d.ts +29 -0
  8. package/dist/blob-store/index.d.ts +32 -0
  9. package/dist/blob-store/types.d.ts +24 -0
  10. package/dist/block/block-controller.d.ts +205 -0
  11. package/dist/block/index.d.ts +2 -0
  12. package/dist/block/types.d.ts +15 -0
  13. package/dist/block-action-menu/block-action-menu.d.ts +62 -0
  14. package/dist/block-action-menu/index.d.ts +2 -0
  15. package/dist/block-context-menu/block-context-menu.d.ts +33 -0
  16. package/dist/block-context-menu/index.d.ts +2 -0
  17. package/dist/blx.js +16245 -0
  18. package/dist/blx.js.map +1 -0
  19. package/dist/caret/custom-caret.d.ts +30 -0
  20. package/dist/clipboard/clipboard-manager.d.ts +28 -0
  21. package/dist/clipboard/index.d.ts +2 -0
  22. package/dist/clipboard/paste-parser.d.ts +30 -0
  23. package/dist/commands/command-registry.d.ts +26 -0
  24. package/dist/commands/index.d.ts +2 -0
  25. package/dist/crdt/automerge-sync.d.ts +157 -0
  26. package/dist/crdt/crdt-log.d.ts +57 -0
  27. package/dist/crdt/index.d.ts +8 -0
  28. package/dist/crdt/remote-cursor-renderer.d.ts +28 -0
  29. package/dist/crdt/replay-ui.d.ts +34 -0
  30. package/dist/crdt/types.d.ts +47 -0
  31. package/dist/date-picker/agenda-utils.d.ts +37 -0
  32. package/dist/date-picker/date-parser.d.ts +25 -0
  33. package/dist/date-picker/date-picker.d.ts +115 -0
  34. package/dist/date-picker/index.d.ts +6 -0
  35. package/dist/drag-handle/drag-handle.d.ts +105 -0
  36. package/dist/drag-handle/index.d.ts +1 -0
  37. package/dist/editor.d.ts +864 -0
  38. package/dist/emoji-picker/emoji-data.d.ts +22 -0
  39. package/dist/emoji-picker/emoji-picker.d.ts +43 -0
  40. package/dist/emoji-picker/index.d.ts +3 -0
  41. package/dist/event-bus/event-bus.d.ts +14 -0
  42. package/dist/event-bus/index.d.ts +2 -0
  43. package/dist/event-bus/types.d.ts +320 -0
  44. package/dist/fold/fold-manager.d.ts +27 -0
  45. package/dist/fold/index.d.ts +2 -0
  46. package/dist/grapheme.d.ts +28 -0
  47. package/dist/index.d.ts +62 -0
  48. package/dist/inline-toolbar/highlight-picker.d.ts +41 -0
  49. package/dist/inline-toolbar/index.d.ts +5 -0
  50. package/dist/inline-toolbar/inline-toolbar.d.ts +97 -0
  51. package/dist/inline-toolbar/link-popover.d.ts +24 -0
  52. package/dist/keybindings/defaults.d.ts +2 -0
  53. package/dist/keybindings/index.d.ts +4 -0
  54. package/dist/keybindings/key-matcher.d.ts +41 -0
  55. package/dist/keybindings/types.d.ts +6 -0
  56. package/dist/keybindings/vim.d.ts +2 -0
  57. package/dist/markdown/block-shortcuts.d.ts +35 -0
  58. package/dist/markdown/emoticon-substitutions.d.ts +22 -0
  59. package/dist/markdown/export.d.ts +5 -0
  60. package/dist/markdown/index.d.ts +4 -0
  61. package/dist/markdown/inline-shortcuts.d.ts +13 -0
  62. package/dist/markdown/types.d.ts +29 -0
  63. package/dist/plugins/blockquote.d.ts +6 -0
  64. package/dist/plugins/checklist.d.ts +18 -0
  65. package/dist/plugins/code.d.ts +50 -0
  66. package/dist/plugins/excalidraw.d.ts +26 -0
  67. package/dist/plugins/heading.d.ts +20 -0
  68. package/dist/plugins/horizontal-rule.d.ts +5 -0
  69. package/dist/plugins/image.d.ts +19 -0
  70. package/dist/plugins/index.d.ts +28 -0
  71. package/dist/plugins/list.d.ts +18 -0
  72. package/dist/plugins/mermaid.d.ts +11 -0
  73. package/dist/plugins/paragraph.d.ts +18 -0
  74. package/dist/plugins/prism-loader.d.ts +16 -0
  75. package/dist/plugins/render-utils.d.ts +43 -0
  76. package/dist/plugins/table.d.ts +22 -0
  77. package/dist/plugins/youtube.d.ts +21 -0
  78. package/dist/schema/index.d.ts +2 -0
  79. package/dist/schema/schema-registry.d.ts +35 -0
  80. package/dist/schema/types.d.ts +67 -0
  81. package/dist/search/index.d.ts +4 -0
  82. package/dist/search/search-engine.d.ts +39 -0
  83. package/dist/search/search-ui.d.ts +59 -0
  84. package/dist/selection/index.d.ts +3 -0
  85. package/dist/selection/selection-manager.d.ts +41 -0
  86. package/dist/selection/types.d.ts +20 -0
  87. package/dist/slash-menu/index.d.ts +2 -0
  88. package/dist/slash-menu/slash-menu.d.ts +27 -0
  89. package/dist/table-of-contents/index.d.ts +1 -0
  90. package/dist/table-of-contents/table-of-contents.d.ts +74 -0
  91. package/dist/transaction/index.d.ts +2 -0
  92. package/dist/transaction/transaction.d.ts +29 -0
  93. package/dist/transaction/types.d.ts +40 -0
  94. package/dist/types.d.ts +21 -0
  95. package/dist/ui/context-menu.d.ts +103 -0
  96. package/dist/ui/dismiss.d.ts +33 -0
  97. package/dist/ui/dropdown.d.ts +81 -0
  98. package/dist/ui/floating-scroll-manager.d.ts +50 -0
  99. package/dist/ui/index.d.ts +18 -0
  100. package/dist/ui/modal.d.ts +109 -0
  101. package/dist/ui/popover.d.ts +59 -0
  102. package/dist/ui/position-fixed.d.ts +35 -0
  103. package/dist/ui/toast.d.ts +60 -0
  104. package/dist/ui/tooltip.d.ts +64 -0
  105. package/dist/undo/index.d.ts +5 -0
  106. package/dist/undo/jump-list.d.ts +37 -0
  107. package/dist/undo/types.d.ts +49 -0
  108. package/dist/undo/undo-manager.d.ts +47 -0
  109. package/dist/util/icons.d.ts +13 -0
  110. package/dist/util/id.d.ts +10 -0
  111. package/dist/viewport/block-viewport.d.ts +106 -0
  112. package/dist/viewport/index.d.ts +2 -0
  113. package/package.json +66 -0
  114. package/style.css +4670 -0
package/style.css ADDED
@@ -0,0 +1,4670 @@
1
+ /* ── Theme variables ────────────────────────────────────────── */
2
+
3
+ .blx-editor {
4
+ --blx-font-sans: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
5
+ --blx-font-mono: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Menlo, Consolas, monospace;
6
+
7
+ /* CJK font fallback stack */
8
+ --blx-font-cjk: "Noto Sans CJK SC", "Noto Sans SC", "PingFang SC",
9
+ "Hiragino Sans", "Microsoft YaHei", "Malgun Gothic", sans-serif;
10
+
11
+ /* CJK-appropriate line height (slightly taller than Latin) */
12
+ --blx-lh-cjk: 1.7;
13
+
14
+ --blx-font-base-size: 0.975rem;
15
+
16
+ /* ── Golden ratio typographic scale (H1–H4) ───────────────
17
+ Font sizes: step = √φ ≈ 1.272, so each level = prev × 1.272
18
+ Line heights: inversely proportional — larger text, tighter leading
19
+ lh = 1 + (0.618 / φ^(step/2))
20
+ This keeps body text airy (1.618) and H1 tight (1.300) */
21
+
22
+ /* Font size scale */
23
+ --blx-font-scale-1: calc(var(--blx-font-base-size) * 2.058); /* H1: φ^1.5 */
24
+ --blx-font-scale-2: calc(var(--blx-font-base-size) * 1.618); /* H2: φ */
25
+ --blx-font-scale-3: calc(var(--blx-font-base-size) * 1.272); /* H3: √φ */
26
+ --blx-font-scale-4: calc(var(--blx-font-base-size) * 1.0); /* H4: 1 */
27
+
28
+ /* Line height scale (inverse golden — tighter as text grows) */
29
+ --blx-lh-body: 1.618;
30
+ --blx-lh-1: 1.300;
31
+ --blx-lh-2: 1.382;
32
+ --blx-lh-3: 1.486;
33
+ --blx-lh-4: 1.618;
34
+
35
+ --blx-bg: #f5f5f3;
36
+ --blx-surface: #ffffff;
37
+ --blx-text: #404550;
38
+ --blx-text-heading: #3b4255;
39
+ --blx-text-muted: #8a8f9a;
40
+ --blx-text-faint: #b0b5bf;
41
+ --blx-text-icon: #7c8394;
42
+ --blx-accent: #4285f4;
43
+ --blx-caret-color: var(--blx-accent);
44
+ --blx-accent-hover: #3370d4;
45
+ --blx-accent-bg: rgba(66, 133, 244, 0.10);
46
+ --blx-accent-bg-hover: rgba(66, 133, 244, 0.15);
47
+ --blx-accent-muted: rgba(66, 133, 244, 0.45);
48
+ --blx-visual-select-bg: rgba(16, 185, 129, 0.14);
49
+ --blx-border: rgba(0, 0, 0, 0.06);
50
+ --blx-border-input: rgba(0, 0, 0, 0.10);
51
+ --blx-shadow: 0 4px 20px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.02);
52
+ --blx-inline-code-bg: rgba(0, 0, 0, 0.06);
53
+ --blx-hr: #e0e0dd;
54
+ --blx-danger: #dc3545;
55
+ --blx-focus-bg: rgba(255, 255, 255, 0.45);
56
+ --blx-hover-bg: rgba(0, 0, 0, 0.05);
57
+ --blx-selected-bg: rgba(0, 0, 0, 0.04);
58
+ --blx-selection-bg: rgba(66, 133, 244, 0.2);
59
+ --blx-btn-secondary-bg: rgba(0, 0, 0, 0.05);
60
+ --blx-btn-secondary-bg-hover: rgba(0, 0, 0, 0.08);
61
+ --blx-btn-secondary-text: #666;
62
+ --blx-checklist-checked-color: #7c8394;
63
+ --blx-placeholder-color: #b0b5bf;
64
+ --blx-description-color: #9da3b0;
65
+ --blx-emoji-name-color: #9399a6;
66
+ --blx-toolbar-sep: rgba(0, 0, 0, 0.1);
67
+ --blx-link-underline: rgba(66, 133, 244, 0.35);
68
+ --blx-scrollbar-thumb: rgba(0, 0, 0, 0.12);
69
+ --blx-menu-highlight: rgba(0, 0, 0, 0.07);
70
+
71
+ /* Agenda state colors */
72
+ --blx-agenda-overdue: #c5303e;
73
+ --blx-agenda-overdue-bg: rgba(197, 48, 62, 0.08);
74
+ --blx-agenda-today: #c27022;
75
+ --blx-agenda-today-bg: rgba(194, 112, 34, 0.08);
76
+ --blx-agenda-upcoming: var(--blx-text-muted);
77
+ --blx-agenda-upcoming-bg: rgba(0, 0, 0, 0.03);
78
+ --blx-agenda-future: var(--blx-text-faint);
79
+ --blx-agenda-future-bg: rgba(0, 0, 0, 0.02);
80
+
81
+ /* Highlight colors */
82
+ --blx-highlight-yellow: rgba(255, 235, 100, 0.50);
83
+ --blx-highlight-green: rgba(100, 220, 130, 0.40);
84
+ --blx-highlight-blue: rgba(120, 195, 255, 0.40);
85
+ --blx-highlight-pink: rgba(255, 140, 170, 0.40);
86
+ --blx-highlight-orange: rgba(255, 185, 80, 0.40);
87
+ --blx-highlight-purple: rgba(190, 140, 255, 0.40);
88
+
89
+ /* Widget design tokens */
90
+ --blx-widget-surface: var(--blx-surface);
91
+ --blx-widget-shadow: var(--blx-shadow);
92
+ --blx-widget-border: var(--blx-border);
93
+ --blx-widget-radius: 8px;
94
+ --blx-widget-text: var(--blx-text);
95
+ --blx-widget-text-muted: var(--blx-text-muted);
96
+ --blx-widget-anim-duration: 0.15s;
97
+ --blx-widget-anim-curve: cubic-bezier(0.16, 1, 0.3, 1);
98
+ --blx-widget-anim-exit-curve: ease-out;
99
+ --blx-widget-anim-exit-duration: 0.1s;
100
+ }
101
+
102
+ /* System dark: applies when OS is dark AND no manual override to light */
103
+ @media (prefers-color-scheme: dark) {
104
+ .blx-editor:not([data-blx-theme="light"]) {
105
+ --blx-bg: #1a1a22;
106
+ --blx-surface: #252530;
107
+ --blx-text: #d0d4dc;
108
+ --blx-text-heading: #e2e5eb;
109
+ --blx-text-muted: #6b7080;
110
+ --blx-text-faint: #555a68;
111
+ --blx-text-icon: #7c8394;
112
+ --blx-accent: #6ea8fe;
113
+ --blx-accent-hover: #5a96ec;
114
+ --blx-accent-bg: rgba(110, 168, 254, 0.12);
115
+ --blx-accent-bg-hover: rgba(110, 168, 254, 0.18);
116
+ --blx-accent-muted: rgba(110, 168, 254, 0.45);
117
+ --blx-visual-select-bg: rgba(16, 185, 129, 0.18);
118
+ --blx-border: rgba(255, 255, 255, 0.08);
119
+ --blx-border-input: rgba(255, 255, 255, 0.12);
120
+ --blx-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.04);
121
+ --blx-inline-code-bg: rgba(255, 255, 255, 0.08);
122
+ --blx-hr: #3a3a45;
123
+ --blx-danger: #f87171;
124
+ --blx-focus-bg: rgba(255, 255, 255, 0.04);
125
+ --blx-hover-bg: rgba(255, 255, 255, 0.06);
126
+ --blx-selected-bg: rgba(255, 255, 255, 0.06);
127
+ --blx-selection-bg: rgba(110, 168, 254, 0.2);
128
+ --blx-btn-secondary-bg: rgba(255, 255, 255, 0.06);
129
+ --blx-btn-secondary-bg-hover: rgba(255, 255, 255, 0.10);
130
+ --blx-btn-secondary-text: #9da3b0;
131
+ --blx-checklist-checked-color: #6b7080;
132
+ --blx-placeholder-color: #555a68;
133
+ --blx-description-color: #6b7080;
134
+ --blx-emoji-name-color: #6b7080;
135
+ --blx-toolbar-sep: rgba(255, 255, 255, 0.1);
136
+ --blx-link-underline: rgba(110, 168, 254, 0.35);
137
+ --blx-scrollbar-thumb: rgba(255, 255, 255, 0.12);
138
+ --blx-menu-highlight: rgba(255, 255, 255, 0.09);
139
+
140
+ --blx-agenda-overdue: #f87171;
141
+ --blx-agenda-overdue-bg: rgba(248, 113, 113, 0.10);
142
+ --blx-agenda-today: #f0a050;
143
+ --blx-agenda-today-bg: rgba(240, 160, 80, 0.10);
144
+ --blx-agenda-upcoming: var(--blx-text-muted);
145
+ --blx-agenda-upcoming-bg: rgba(255, 255, 255, 0.04);
146
+ --blx-agenda-future: var(--blx-text-faint);
147
+ --blx-agenda-future-bg: rgba(255, 255, 255, 0.03);
148
+
149
+ --blx-highlight-yellow: rgba(255, 235, 100, 0.22);
150
+ --blx-highlight-green: rgba(100, 220, 130, 0.20);
151
+ --blx-highlight-blue: rgba(120, 195, 255, 0.20);
152
+ --blx-highlight-pink: rgba(255, 140, 170, 0.20);
153
+ --blx-highlight-orange: rgba(255, 185, 80, 0.20);
154
+ --blx-highlight-purple: rgba(190, 140, 255, 0.20);
155
+ }
156
+ }
157
+
158
+ /* Manual dark: applies when explicitly set via API */
159
+ .blx-editor[data-blx-theme="dark"] {
160
+ --blx-bg: #1a1a22;
161
+ --blx-surface: #252530;
162
+ --blx-text: #d0d4dc;
163
+ --blx-text-heading: #e2e5eb;
164
+ --blx-text-muted: #6b7080;
165
+ --blx-text-faint: #555a68;
166
+ --blx-text-icon: #7c8394;
167
+ --blx-accent: #6ea8fe;
168
+ --blx-accent-hover: #5a96ec;
169
+ --blx-accent-bg: rgba(110, 168, 254, 0.12);
170
+ --blx-accent-bg-hover: rgba(110, 168, 254, 0.18);
171
+ --blx-accent-muted: rgba(110, 168, 254, 0.45);
172
+ --blx-visual-select-bg: rgba(16, 185, 129, 0.18);
173
+ --blx-border: rgba(255, 255, 255, 0.08);
174
+ --blx-border-input: rgba(255, 255, 255, 0.12);
175
+ --blx-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.04);
176
+ --blx-inline-code-bg: rgba(255, 255, 255, 0.08);
177
+ --blx-hr: #3a3a45;
178
+ --blx-danger: #f87171;
179
+ --blx-focus-bg: rgba(255, 255, 255, 0.04);
180
+ --blx-hover-bg: rgba(255, 255, 255, 0.06);
181
+ --blx-selected-bg: rgba(255, 255, 255, 0.06);
182
+ --blx-selection-bg: rgba(110, 168, 254, 0.2);
183
+ --blx-btn-secondary-bg: rgba(255, 255, 255, 0.06);
184
+ --blx-btn-secondary-bg-hover: rgba(255, 255, 255, 0.10);
185
+ --blx-btn-secondary-text: #9da3b0;
186
+ --blx-checklist-checked-color: #6b7080;
187
+ --blx-placeholder-color: #555a68;
188
+ --blx-description-color: #6b7080;
189
+ --blx-emoji-name-color: #6b7080;
190
+ --blx-toolbar-sep: rgba(255, 255, 255, 0.1);
191
+ --blx-link-underline: rgba(110, 168, 254, 0.35);
192
+ --blx-scrollbar-thumb: rgba(255, 255, 255, 0.12);
193
+ --blx-menu-highlight: rgba(255, 255, 255, 0.08);
194
+
195
+ --blx-agenda-overdue: #f87171;
196
+ --blx-agenda-overdue-bg: rgba(248, 113, 113, 0.10);
197
+ --blx-agenda-today: #f0a050;
198
+ --blx-agenda-today-bg: rgba(240, 160, 80, 0.10);
199
+ --blx-agenda-upcoming: var(--blx-text-muted);
200
+ --blx-agenda-upcoming-bg: rgba(255, 255, 255, 0.04);
201
+ --blx-agenda-future: var(--blx-text-faint);
202
+ --blx-agenda-future-bg: rgba(255, 255, 255, 0.03);
203
+
204
+ --blx-highlight-yellow: rgba(255, 235, 100, 0.22);
205
+ --blx-highlight-green: rgba(100, 220, 130, 0.20);
206
+ --blx-highlight-blue: rgba(120, 195, 255, 0.20);
207
+ --blx-highlight-pink: rgba(255, 140, 170, 0.20);
208
+ --blx-highlight-orange: rgba(255, 185, 80, 0.20);
209
+ --blx-highlight-purple: rgba(190, 140, 255, 0.20);
210
+ }
211
+
212
+ .blx-editor {
213
+ position: relative;
214
+ color: var(--blx-text);
215
+ font-family: var(--blx-font-sans);
216
+ --blx-gutter: 64px;
217
+ overflow: visible;
218
+ display: flex;
219
+ flex-direction: column;
220
+ min-height: 100%;
221
+ width: 100%;
222
+ }
223
+
224
+ /* ── Content column (centered within the full-width editor) ──── */
225
+
226
+ .blx-content {
227
+ position: relative;
228
+ box-sizing: border-box;
229
+ padding-inline: var(--blx-gutter);
230
+ max-width: var(--blx-content-max-width, none);
231
+ margin-inline: auto;
232
+ min-width: calc(var(--blx-gutter) + 120px);
233
+ min-height: 100%;
234
+ width: 100%;
235
+ display: flex;
236
+ flex-direction: column;
237
+ }
238
+
239
+ .blx-blocks {
240
+ flex: 1;
241
+ }
242
+
243
+ .blx-editor:focus-within {
244
+ outline: none;
245
+ }
246
+
247
+ /* ── Gutter (widget rail) ───────────────────────────────────── */
248
+
249
+ .blx-gutter {
250
+ position: absolute;
251
+ top: 0;
252
+ inset-inline-start: 0;
253
+ bottom: 0;
254
+ width: var(--blx-gutter);
255
+ pointer-events: none;
256
+ }
257
+
258
+ .blx-drag-handle,
259
+ .blx-action-btn {
260
+ pointer-events: auto;
261
+ }
262
+
263
+ /* ── Blocks ──────────────────────────────────────────────────── */
264
+
265
+ .blx-block {
266
+ position: relative;
267
+ /* Creates a Block Formatting Context so that child margins (e.g. heading
268
+ margin-top) are contained within this element instead of collapsing
269
+ through it. This is critical for the virtual viewport: offsetHeight
270
+ must capture the full visual space so height caching and scroll
271
+ compensation work correctly during mount/unmount cycles. */
272
+ display: flow-root;
273
+ }
274
+
275
+ /* Disable browser scroll anchoring on block containers — we manage scroll
276
+ compensation manually in BlockViewport.handleIntersection. Without this,
277
+ the browser's anchoring fights our scrollBy() calls and causes jitter. */
278
+ .blx-block {
279
+ overflow-anchor: none;
280
+ }
281
+
282
+ /* Ejected blocks: content stays in the DOM but the browser skips painting.
283
+ Height is preserved via an explicit inline style set in ejectContent()
284
+ because contain-intrinsic-size auto only remembers the last rendered size
285
+ for content-visibility: auto, NOT hidden — using hidden without an
286
+ explicit height collapses the block to 0px and destroys scroll position. */
287
+ .blx-block-ejected {
288
+ content-visibility: hidden;
289
+ }
290
+
291
+ .blx-block [contenteditable="true"] {
292
+ outline: none;
293
+ border: none;
294
+ padding: 3px 6px;
295
+ border-radius: 5px;
296
+ transition: background-color 0.35s ease;
297
+ caret-color: transparent;
298
+ }
299
+
300
+ .blx-block [contenteditable="true"]:focus {
301
+ background-color: var(--blx-focus-bg);
302
+ }
303
+
304
+ /* Table cells are contenteditable but should not inherit block-level CE styles */
305
+ .blx-table-cell[contenteditable="true"] {
306
+ border: 1px solid var(--blx-border-input);
307
+ border-radius: 0;
308
+ padding: 6px 10px;
309
+ transition: none;
310
+ }
311
+
312
+ .blx-table-cell[contenteditable="true"]:focus {
313
+ background-color: transparent;
314
+ }
315
+
316
+ .blx-block-focused {
317
+ /* handled by the contenteditable :focus above */
318
+ }
319
+
320
+ /* ── Paragraph ───────────────────────────────────────────────── */
321
+
322
+ .blx-paragraph {
323
+ font-size: var(--blx-font-base-size);
324
+ line-height: var(--blx-lh-body);
325
+ margin: 1px 0;
326
+ min-height: 1.7em;
327
+ letter-spacing: -0.008em;
328
+ word-spacing: 0.02em;
329
+ }
330
+
331
+ /* ── Headings ────────────────────────────────────────────────── */
332
+
333
+ .blx-heading {
334
+ font-weight: 600;
335
+ color: var(--blx-text-heading);
336
+ margin: 20px 0 2px;
337
+ min-height: 1.2em;
338
+ letter-spacing: -0.02em;
339
+ }
340
+
341
+ .blx-heading-1 {
342
+ font-size: var(--blx-font-scale-1);
343
+ line-height: var(--blx-lh-1);
344
+ margin-top: 32px;
345
+ font-weight: 650;
346
+ letter-spacing: -0.022em;
347
+ }
348
+
349
+ .blx-heading-2 {
350
+ font-size: var(--blx-font-scale-2);
351
+ line-height: var(--blx-lh-2);
352
+ margin-top: 28px;
353
+ letter-spacing: -0.018em;
354
+ }
355
+
356
+ .blx-heading-3 {
357
+ font-size: var(--blx-font-scale-3);
358
+ line-height: var(--blx-lh-3);
359
+ letter-spacing: -0.014em;
360
+ }
361
+
362
+ .blx-heading-4 {
363
+ font-size: var(--blx-font-scale-4);
364
+ line-height: var(--blx-lh-4);
365
+ font-weight: 580;
366
+ }
367
+
368
+ /* ── Heading Task Status ─────────────────────────────────────── */
369
+
370
+ .blx-heading-wrapper {
371
+ display: flex;
372
+ align-items: center;
373
+ gap: 8px;
374
+ margin-top: 20px; /* matches base heading margin — keeps spacing when heading margin is zeroed */
375
+ }
376
+
377
+ /* Transfer heading margin-top to wrapper so flex centering aligns with text, not margin-box */
378
+ .blx-heading-wrapper > .blx-heading {
379
+ margin-top: 0;
380
+ }
381
+ .blx-heading-wrapper:has(.blx-heading-1) { margin-top: 32px; }
382
+ .blx-heading-wrapper:has(.blx-heading-2) { margin-top: 28px; }
383
+
384
+ .blx-heading-task-indicator {
385
+ flex-shrink: 0;
386
+ width: var(--_indicator-size, 18px);
387
+ height: var(--_indicator-size, 18px);
388
+ border-radius: 50%;
389
+ border: 1.5px solid var(--blx-text-faint);
390
+ background: transparent;
391
+ cursor: pointer;
392
+ padding: 0;
393
+ position: relative;
394
+ transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
395
+ -webkit-tap-highlight-color: transparent;
396
+ -webkit-user-select: none;
397
+ user-select: none;
398
+ }
399
+
400
+ /* Expand touch target to 44px on coarse pointer (mobile) */
401
+ @media (pointer: coarse) {
402
+ .blx-heading-task-indicator::before {
403
+ content: "";
404
+ position: absolute;
405
+ top: 50%; left: 50%;
406
+ min-width: 44px;
407
+ min-height: 44px;
408
+ transform: translate(-50%, -50%);
409
+ }
410
+ }
411
+
412
+ /* Per-level indicator size — proportional to heading */
413
+ .blx-heading-wrapper:has(.blx-heading-1) .blx-heading-task-indicator { --_indicator-size: 22px; }
414
+ .blx-heading-wrapper:has(.blx-heading-2) .blx-heading-task-indicator { --_indicator-size: 18px; }
415
+ .blx-heading-wrapper:has(.blx-heading-3) .blx-heading-task-indicator { --_indicator-size: 15px; }
416
+ .blx-heading-wrapper:has(.blx-heading-4) .blx-heading-task-indicator { --_indicator-size: 13px; }
417
+
418
+ .blx-heading-task-indicator::after {
419
+ content: "";
420
+ position: absolute;
421
+ inset: 0;
422
+ display: block;
423
+ }
424
+
425
+ /* Todo: open circle — ready to start */
426
+ .blx-heading-task-indicator.blx-task-todo {
427
+ border-color: var(--blx-text-faint);
428
+ }
429
+
430
+ .blx-heading-task-indicator.blx-task-todo:hover {
431
+ border-color: var(--blx-accent);
432
+ box-shadow: 0 0 0 3px var(--blx-accent-bg);
433
+ }
434
+
435
+ /* In Progress: accent-bordered circle with centered accent dot */
436
+ .blx-heading-task-indicator.blx-task-in-progress {
437
+ border-color: var(--blx-accent);
438
+ background: var(--blx-accent-bg);
439
+ }
440
+
441
+ .blx-heading-task-indicator.blx-task-in-progress::after {
442
+ width: 33%;
443
+ height: 33%;
444
+ border-radius: 50%;
445
+ background: var(--blx-accent);
446
+ top: 50%;
447
+ left: 50%;
448
+ transform: translate(-50%, -50%);
449
+ }
450
+
451
+ .blx-heading-task-indicator.blx-task-in-progress:hover {
452
+ background: var(--blx-accent-bg-hover);
453
+ box-shadow: 0 0 0 3px var(--blx-accent-bg);
454
+ }
455
+
456
+ /* Done: green filled circle with a checkmark */
457
+ .blx-heading-task-indicator.blx-task-done {
458
+ --_done: #34a853;
459
+ border-color: var(--_done);
460
+ background: var(--_done);
461
+ }
462
+
463
+ .blx-heading-task-indicator.blx-task-done::after {
464
+ /* CSS checkmark — scales with indicator */
465
+ width: 28%;
466
+ height: 45%;
467
+ border-right: 1.5px solid #fff;
468
+ border-bottom: 1.5px solid #fff;
469
+ top: 45%;
470
+ left: 50%;
471
+ transform: translate(-50%, -55%) rotate(40deg);
472
+ }
473
+
474
+ .blx-heading-task-indicator.blx-task-done:hover {
475
+ --_done: #2d9249;
476
+ box-shadow: 0 0 0 3px rgba(52, 168, 83, 0.15);
477
+ }
478
+
479
+ /* Done heading text: completed feel without dulling */
480
+ .blx-heading-task-done {
481
+ color: var(--blx-text-muted);
482
+ }
483
+
484
+ @media (prefers-color-scheme: dark) {
485
+ .blx-editor:not([data-blx-theme="light"]) .blx-heading-task-indicator.blx-task-done {
486
+ --_done: #4eca6a;
487
+ }
488
+ .blx-editor:not([data-blx-theme="light"]) .blx-heading-task-indicator.blx-task-done:hover {
489
+ --_done: #43b85e;
490
+ box-shadow: 0 0 0 3px rgba(78, 202, 106, 0.15);
491
+ }
492
+ }
493
+
494
+ .blx-editor[data-blx-theme="dark"] .blx-heading-task-indicator.blx-task-done {
495
+ --_done: #4eca6a;
496
+ }
497
+
498
+ .blx-editor[data-blx-theme="dark"] .blx-heading-task-indicator.blx-task-done:hover {
499
+ --_done: #43b85e;
500
+ box-shadow: 0 0 0 3px rgba(78, 202, 106, 0.15);
501
+ }
502
+
503
+ /* ── Lists ───────────────────────────────────────────────────── */
504
+
505
+ .blx-list {
506
+ margin: 1px 0;
507
+ padding-inline-start: 24px;
508
+ }
509
+
510
+ .blx-list li {
511
+ font-size: var(--blx-font-base-size);
512
+ line-height: var(--blx-lh-body);
513
+ min-height: 1.7em;
514
+ letter-spacing: -0.008em;
515
+ word-spacing: 0.02em;
516
+ }
517
+
518
+ .blx-list-ordered {
519
+ list-style-type: decimal;
520
+ }
521
+
522
+ .blx-list-unordered {
523
+ list-style-type: disc;
524
+ }
525
+
526
+ .blx-list li::marker {
527
+ color: var(--blx-text-faint);
528
+ }
529
+
530
+ /* ── Task Lists ──────────────────────────────────────────────── */
531
+
532
+ .blx-checklist {
533
+ margin: 1px 0;
534
+ padding-inline-start: 6px;
535
+ list-style: none;
536
+ }
537
+
538
+ .blx-checklist-item {
539
+ display: flex;
540
+ align-items: flex-start;
541
+ gap: 8px;
542
+ font-size: var(--blx-font-base-size);
543
+ line-height: var(--blx-lh-body);
544
+ min-height: 1.7em;
545
+ letter-spacing: -0.008em;
546
+ word-spacing: 0.02em;
547
+ transition: opacity 0.2s ease, color 0.2s ease;
548
+ }
549
+
550
+ .blx-checklist-checkbox {
551
+ font-size: inherit;
552
+ --_line: calc(1em * var(--blx-lh-body));
553
+ --_check-size: calc(var(--_line) * 0.7);
554
+ width: var(--_check-size);
555
+ height: var(--_check-size);
556
+ cursor: pointer;
557
+ flex-shrink: 0;
558
+ margin-top: calc((var(--_line) - var(--_check-size)) / 2 + 3px);
559
+ border-radius: 3px;
560
+ border: 1.5px solid var(--blx-text-faint);
561
+ appearance: none;
562
+ -webkit-appearance: none;
563
+ background-color: transparent;
564
+ transition: all 0.15s ease;
565
+ }
566
+
567
+ .blx-checklist-checkbox:hover {
568
+ border-color: var(--blx-accent);
569
+ background-color: var(--blx-accent-bg);
570
+ }
571
+
572
+ .blx-checklist-checkbox:checked {
573
+ background-color: var(--blx-accent);
574
+ border-color: var(--blx-accent);
575
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='white' d='M13.5 3.5L6 11l-3.5-3.5L1 9l5 5 9-9z'/%3E%3C/svg%3E");
576
+ background-size: calc(var(--_check-size) * 0.75);
577
+ background-position: center;
578
+ background-repeat: no-repeat;
579
+ }
580
+
581
+ .blx-checklist-content {
582
+ flex: 1;
583
+ outline: none;
584
+ }
585
+
586
+ .blx-checklist-checked {
587
+ opacity: 0.5;
588
+ }
589
+
590
+ .blx-checklist-checked .blx-checklist-content {
591
+ text-decoration: line-through;
592
+ color: var(--blx-checklist-checked-color);
593
+ }
594
+
595
+ /* ── Agenda Badges & Labels ──────────────────────────────────── */
596
+
597
+ /* Right-aligned chip badge for blocks with agenda dates */
598
+ .blx-agenda-badge {
599
+ display: inline-flex;
600
+ align-items: center;
601
+ gap: 3px;
602
+ margin-left: auto;
603
+ flex-shrink: 0;
604
+ font-family: var(--blx-font-sans);
605
+ font-size: 0.66rem;
606
+ font-weight: 550;
607
+ letter-spacing: 0.01em;
608
+ line-height: 1;
609
+ color: var(--blx-agenda-future);
610
+ background: var(--blx-agenda-future-bg);
611
+ padding: 3px 8px;
612
+ border-radius: 4px;
613
+ cursor: pointer;
614
+ user-select: none;
615
+ white-space: nowrap;
616
+ transition: filter 0.15s ease;
617
+ }
618
+
619
+ .blx-agenda-badge:hover {
620
+ filter: brightness(0.95);
621
+ }
622
+
623
+ /* Agenda label for task headings — stacks above the heading row. */
624
+ .blx-heading-wrapper:has(.blx-agenda-label) {
625
+ flex-wrap: wrap;
626
+ row-gap: 0;
627
+ column-gap: 8px;
628
+ }
629
+
630
+ .blx-agenda-label {
631
+ display: flex;
632
+ align-items: center;
633
+ flex-basis: 100%; /* Forces label onto its own row above the heading */
634
+ line-height: 1;
635
+ color: var(--blx-agenda-future);
636
+ cursor: pointer;
637
+ user-select: none;
638
+ margin-bottom: 2px;
639
+ margin-left: 28px; /* Align with heading text past indicator */
640
+ }
641
+
642
+ .blx-agenda-label-text {
643
+ display: inline-flex;
644
+ align-items: center;
645
+ gap: 4px;
646
+ font-family: var(--blx-font-sans);
647
+ font-size: 0.65rem;
648
+ font-weight: 550;
649
+ letter-spacing: 0.01em;
650
+ line-height: 1;
651
+ color: inherit;
652
+ padding: 2px 7px;
653
+ border-radius: 3px;
654
+ background: var(--blx-agenda-future-bg);
655
+ transition: color 0.15s ease, background 0.15s ease;
656
+ }
657
+
658
+ /* ── Recurrence indicator ────────────────────────────────────── */
659
+
660
+ .blx-agenda-recurrence {
661
+ display: inline-flex;
662
+ align-items: center;
663
+ opacity: 0.45;
664
+ flex-shrink: 0;
665
+ line-height: 0;
666
+ }
667
+
668
+ .blx-agenda-recurrence svg {
669
+ width: 1em;
670
+ height: 1em;
671
+ }
672
+
673
+ .blx-agenda-badge:hover .blx-agenda-recurrence,
674
+ .blx-agenda-label:hover .blx-agenda-recurrence {
675
+ opacity: 0.7;
676
+ }
677
+
678
+ /* ── Agenda state colors ─────────────────────────────────────── */
679
+
680
+ .blx-agenda-overdue {
681
+ color: var(--blx-agenda-overdue);
682
+ }
683
+
684
+ .blx-agenda-badge.blx-agenda-overdue {
685
+ background: var(--blx-agenda-overdue-bg);
686
+ }
687
+
688
+ .blx-agenda-label.blx-agenda-overdue .blx-agenda-label-text {
689
+ background: var(--blx-agenda-overdue-bg);
690
+ }
691
+
692
+ .blx-agenda-today {
693
+ color: var(--blx-agenda-today);
694
+ }
695
+
696
+ .blx-agenda-badge.blx-agenda-today {
697
+ background: var(--blx-agenda-today-bg);
698
+ }
699
+
700
+ .blx-agenda-label.blx-agenda-today .blx-agenda-label-text {
701
+ background: var(--blx-agenda-today-bg);
702
+ }
703
+
704
+ .blx-agenda-tomorrow {
705
+ color: var(--blx-agenda-today);
706
+ }
707
+
708
+ .blx-agenda-badge.blx-agenda-tomorrow {
709
+ background: var(--blx-agenda-today-bg);
710
+ }
711
+
712
+ .blx-agenda-label.blx-agenda-tomorrow .blx-agenda-label-text {
713
+ background: var(--blx-agenda-today-bg);
714
+ }
715
+
716
+ .blx-agenda-upcoming {
717
+ color: var(--blx-agenda-upcoming);
718
+ }
719
+
720
+ .blx-agenda-badge.blx-agenda-upcoming {
721
+ background: var(--blx-agenda-upcoming-bg);
722
+ }
723
+
724
+ .blx-agenda-future {
725
+ color: var(--blx-agenda-future);
726
+ }
727
+
728
+ .blx-agenda-badge.blx-agenda-future {
729
+ background: var(--blx-agenda-future-bg);
730
+ }
731
+
732
+ /* Past event — muted, informational */
733
+ .blx-agenda-past {
734
+ color: var(--blx-agenda-future);
735
+ }
736
+
737
+ .blx-agenda-badge.blx-agenda-past {
738
+ background: var(--blx-agenda-future-bg);
739
+ }
740
+
741
+ /* Ongoing scheduled item — still active */
742
+ .blx-agenda-ongoing {
743
+ color: var(--blx-agenda-upcoming);
744
+ }
745
+
746
+ .blx-agenda-badge.blx-agenda-ongoing {
747
+ background: var(--blx-agenda-upcoming-bg);
748
+ }
749
+
750
+ /* Completed task: muted + strikethrough */
751
+ .blx-agenda-done {
752
+ text-decoration: line-through;
753
+ opacity: 0.45;
754
+ }
755
+
756
+ /* ── Date Picker ────────────────────────────────────────────── */
757
+
758
+ .blx-date-picker {
759
+ position: fixed;
760
+ z-index: 1000;
761
+ background: var(--blx-surface, #ffffff);
762
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
763
+ border-radius: 10px;
764
+ padding: 10px;
765
+ box-shadow:
766
+ 0 4px 20px rgba(0, 0, 0, 0.08),
767
+ 0 0 0 1px rgba(0, 0, 0, 0.02);
768
+ width: 252px;
769
+ font-family: var(--blx-font-sans, "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
770
+ font-size: 0.8rem;
771
+ color: var(--blx-text, #404550);
772
+ animation: blx-date-picker-in var(--blx-widget-anim-duration, 0.15s) var(--blx-widget-anim-curve, cubic-bezier(0.16, 1, 0.3, 1));
773
+ }
774
+
775
+ @keyframes blx-date-picker-in {
776
+ from {
777
+ opacity: 0;
778
+ transform: translateY(-4px) scale(0.98);
779
+ }
780
+ to {
781
+ opacity: 1;
782
+ transform: translateY(0) scale(1);
783
+ }
784
+ }
785
+
786
+ /* Calendar month header */
787
+ .blx-date-picker-header {
788
+ display: flex;
789
+ align-items: center;
790
+ justify-content: space-between;
791
+ margin-bottom: 6px;
792
+ }
793
+
794
+ .blx-date-picker-month {
795
+ font-weight: 600;
796
+ font-size: 0.8rem;
797
+ color: var(--blx-text, #404550);
798
+ }
799
+
800
+ .blx-date-picker-nav {
801
+ display: flex;
802
+ align-items: center;
803
+ justify-content: center;
804
+ width: 26px;
805
+ height: 26px;
806
+ border: none;
807
+ background: transparent;
808
+ color: var(--blx-text-muted, #8a8f9a);
809
+ cursor: pointer;
810
+ font-size: 14px;
811
+ border-radius: 6px;
812
+ font-family: inherit;
813
+ transition: background 0.1s ease, color 0.1s ease;
814
+ }
815
+
816
+ .blx-date-picker-nav:hover {
817
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.05));
818
+ color: var(--blx-text, #404550);
819
+ }
820
+
821
+ /* Day-of-week headers */
822
+ .blx-date-picker-dow {
823
+ display: grid;
824
+ grid-template-columns: repeat(7, 1fr);
825
+ text-align: center;
826
+ font-size: 0.65rem;
827
+ font-weight: 550;
828
+ letter-spacing: 0.03em;
829
+ text-transform: uppercase;
830
+ color: var(--blx-text-faint, #b0b5bf);
831
+ margin-bottom: 4px;
832
+ padding-bottom: 4px;
833
+ }
834
+
835
+ /* Calendar grid */
836
+ .blx-date-picker-grid {
837
+ display: grid;
838
+ grid-template-columns: repeat(7, 1fr);
839
+ gap: 2px;
840
+ }
841
+
842
+ .blx-date-picker-pad {
843
+ /* Empty spacer for days before the 1st */
844
+ }
845
+
846
+ /* Individual day cell */
847
+ .blx-date-picker-day {
848
+ aspect-ratio: 1;
849
+ display: flex;
850
+ align-items: center;
851
+ justify-content: center;
852
+ border: none;
853
+ background: transparent;
854
+ color: var(--blx-text, #404550);
855
+ cursor: pointer;
856
+ border-radius: 6px;
857
+ font-size: 0.75rem;
858
+ font-weight: 450;
859
+ font-family: inherit;
860
+ transition: background 0.1s ease, color 0.1s ease;
861
+ }
862
+
863
+ .blx-date-picker-day:hover {
864
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.05));
865
+ }
866
+
867
+ /* Today's date: accent ring */
868
+ .blx-date-picker-today {
869
+ font-weight: 650;
870
+ color: var(--blx-accent, #4285f4);
871
+ box-shadow: inset 0 0 0 1.5px var(--blx-accent, #4285f4);
872
+ }
873
+
874
+ /* Selected date: solid accent fill */
875
+ .blx-date-picker-selected {
876
+ background: var(--blx-accent, #4285f4);
877
+ color: #fff;
878
+ font-weight: 600;
879
+ }
880
+
881
+ .blx-date-picker-selected:hover {
882
+ background: var(--blx-accent-hover, #3370d4);
883
+ }
884
+
885
+ /* Today + selected: fill wins, no ring */
886
+ .blx-date-picker-selected.blx-date-picker-today {
887
+ box-shadow: none;
888
+ color: #fff;
889
+ }
890
+
891
+ /* Remove date button */
892
+ .blx-date-picker-remove {
893
+ display: block;
894
+ width: 100%;
895
+ margin-top: 6px;
896
+ padding: 5px 8px;
897
+ border: none;
898
+ border-top: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
899
+ padding-top: 10px;
900
+ background: transparent;
901
+ color: var(--blx-danger, #dc3545);
902
+ cursor: pointer;
903
+ font-size: 0.7rem;
904
+ font-weight: 500;
905
+ text-align: center;
906
+ border-radius: 0;
907
+ font-family: inherit;
908
+ transition: color 0.1s ease;
909
+ }
910
+
911
+ .blx-date-picker-remove:hover {
912
+ color: var(--blx-danger, #dc3545);
913
+ filter: brightness(1.15);
914
+ }
915
+
916
+ /* ── Date picker suggestions (@ natural language search) ─────── */
917
+
918
+ .blx-date-picker-suggestions {
919
+ display: flex;
920
+ flex-direction: column;
921
+ padding: 4px;
922
+ }
923
+
924
+ .blx-date-picker-suggestion-item {
925
+ display: flex;
926
+ justify-content: space-between;
927
+ align-items: center;
928
+ padding: 6px 8px;
929
+ border: none;
930
+ background: none;
931
+ cursor: pointer;
932
+ font-size: 0.8rem;
933
+ color: var(--blx-text, #404550);
934
+ text-align: left;
935
+ width: 100%;
936
+ border-radius: 6px;
937
+ gap: 12px;
938
+ }
939
+
940
+ .blx-date-picker-suggestion-item:hover,
941
+ .blx-date-picker-suggestion-selected {
942
+ background: var(--blx-accent-bg, rgba(66, 133, 244, 0.10));
943
+ }
944
+
945
+ .blx-date-picker-suggestion-label {
946
+ font-weight: 500;
947
+ }
948
+
949
+ .blx-date-picker-suggestion-date {
950
+ font-size: 0.75rem;
951
+ color: var(--blx-muted, #9ca3af);
952
+ white-space: nowrap;
953
+ }
954
+
955
+ .blx-date-picker-suggestion-empty {
956
+ padding: 12px 8px;
957
+ font-size: 0.8rem;
958
+ color: var(--blx-muted, #9ca3af);
959
+ text-align: center;
960
+ }
961
+
962
+ /* ── Date picker: role tabs ──────────────────────────────────── */
963
+
964
+ .blx-date-picker-roles {
965
+ display: flex;
966
+ gap: 2px;
967
+ margin-bottom: 8px;
968
+ padding: 2px;
969
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.04));
970
+ border-radius: 8px;
971
+ }
972
+
973
+ .blx-date-picker-role-tab {
974
+ flex: 1 1 0;
975
+ padding: 4px 8px;
976
+ border: none;
977
+ border-radius: 6px;
978
+ background: transparent;
979
+ color: var(--blx-text-muted, #8a8f9a);
980
+ cursor: pointer;
981
+ font-size: 0.7rem;
982
+ font-weight: 550;
983
+ font-family: inherit;
984
+ text-align: center;
985
+ transition: background 0.12s ease, color 0.12s ease;
986
+ }
987
+
988
+ .blx-date-picker-role-tab:hover:not(:disabled) {
989
+ color: var(--blx-text, #404550);
990
+ }
991
+
992
+ .blx-date-picker-role-active {
993
+ background: var(--blx-surface, #ffffff);
994
+ color: var(--blx-text, #404550);
995
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
996
+ }
997
+
998
+ .blx-date-picker-role-disabled {
999
+ opacity: 0.35;
1000
+ cursor: not-allowed;
1001
+ }
1002
+
1003
+ /* ── Date picker: calendar section wrapper ───────────────────── */
1004
+
1005
+ .blx-date-picker-calendar-section {
1006
+ /* wrapper for collapsing calendar when repeat config is shown */
1007
+ }
1008
+
1009
+ /* ── Date picker: footer bar (repeat toggle + confirm/cancel) ── */
1010
+
1011
+ .blx-date-picker-footer {
1012
+ display: flex;
1013
+ align-items: center;
1014
+ gap: 6px;
1015
+ padding-top: 8px;
1016
+ margin-top: 4px;
1017
+ border-top: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1018
+ }
1019
+
1020
+ .blx-date-picker-footer-spacer {
1021
+ flex: 1;
1022
+ }
1023
+
1024
+ .blx-date-picker-confirm-btn {
1025
+ display: flex;
1026
+ align-items: center;
1027
+ justify-content: center;
1028
+ width: 28px;
1029
+ height: 26px;
1030
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1031
+ border-radius: 6px;
1032
+ background: transparent;
1033
+ cursor: pointer;
1034
+ font-family: inherit;
1035
+ transition: background 0.1s ease, border-color 0.1s ease, color 0.1s ease, opacity 0.1s ease;
1036
+ }
1037
+
1038
+ .blx-date-picker-confirm-btn:disabled {
1039
+ opacity: 0.3;
1040
+ cursor: not-allowed;
1041
+ }
1042
+
1043
+ .blx-date-picker-tick {
1044
+ color: var(--blx-success, #22c55e);
1045
+ }
1046
+
1047
+ .blx-date-picker-tick:hover:not(:disabled) {
1048
+ background: rgba(34, 197, 94, 0.1);
1049
+ border-color: var(--blx-success, #22c55e);
1050
+ }
1051
+
1052
+ .blx-date-picker-cross {
1053
+ color: var(--blx-text-muted, #8a8f9a);
1054
+ }
1055
+
1056
+ .blx-date-picker-cross:hover {
1057
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.05));
1058
+ color: var(--blx-danger, #dc3545);
1059
+ }
1060
+
1061
+ /* ── Date picker: repeat toggle (in footer) ──────────────────── */
1062
+
1063
+ .blx-date-picker-repeat-toggle {
1064
+ display: flex;
1065
+ align-items: center;
1066
+ gap: 5px;
1067
+ padding: 4px 8px;
1068
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1069
+ border-radius: 6px;
1070
+ background: transparent;
1071
+ color: var(--blx-text-muted, #8a8f9a);
1072
+ cursor: pointer;
1073
+ font-size: 0.68rem;
1074
+ font-weight: 500;
1075
+ font-family: inherit;
1076
+ white-space: nowrap;
1077
+ transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
1078
+ }
1079
+
1080
+ .blx-date-picker-repeat-toggle:hover:not(:disabled) {
1081
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.05));
1082
+ color: var(--blx-text, #404550);
1083
+ }
1084
+
1085
+ .blx-date-picker-repeat-toggle:disabled {
1086
+ opacity: 0.3;
1087
+ cursor: not-allowed;
1088
+ }
1089
+
1090
+ .blx-date-picker-repeat-active {
1091
+ background: var(--blx-accent-bg, rgba(66, 133, 244, 0.10));
1092
+ color: var(--blx-accent, #4285f4);
1093
+ border-color: var(--blx-accent, #4285f4);
1094
+ }
1095
+
1096
+ .blx-date-picker-repeat-active:hover:not(:disabled) {
1097
+ background: var(--blx-accent-bg, rgba(66, 133, 244, 0.15));
1098
+ color: var(--blx-accent, #4285f4);
1099
+ }
1100
+
1101
+ /* ── Date picker: repeat config panel ────────────────────────── */
1102
+
1103
+ .blx-date-picker-repeat-config {
1104
+ padding: 10px;
1105
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.025));
1106
+ border-radius: 8px;
1107
+ }
1108
+
1109
+ /* Date chip — shows selected date in repeat view */
1110
+ .blx-date-picker-date-chip {
1111
+ display: flex;
1112
+ align-items: center;
1113
+ gap: 6px;
1114
+ width: 100%;
1115
+ padding: 6px 8px;
1116
+ margin-bottom: 10px;
1117
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1118
+ border-radius: 6px;
1119
+ background: var(--blx-surface, #ffffff);
1120
+ color: var(--blx-text, #404550);
1121
+ cursor: pointer;
1122
+ font-size: 0.75rem;
1123
+ font-weight: 550;
1124
+ font-family: inherit;
1125
+ text-align: left;
1126
+ transition: border-color 0.1s ease, box-shadow 0.1s ease;
1127
+ }
1128
+
1129
+ .blx-date-picker-date-chip:hover {
1130
+ border-color: var(--blx-accent, #4285f4);
1131
+ box-shadow: 0 0 0 1px var(--blx-accent-bg, rgba(66, 133, 244, 0.10));
1132
+ }
1133
+
1134
+ .blx-date-picker-date-chip svg {
1135
+ color: var(--blx-text-muted, #8a8f9a);
1136
+ flex-shrink: 0;
1137
+ }
1138
+
1139
+ .blx-date-picker-date-chip-edit {
1140
+ margin-left: auto;
1141
+ opacity: 0;
1142
+ transition: opacity 0.1s ease;
1143
+ }
1144
+
1145
+ .blx-date-picker-date-chip:hover .blx-date-picker-date-chip-edit {
1146
+ opacity: 0.6;
1147
+ }
1148
+
1149
+ .blx-date-picker-repeat-row {
1150
+ display: flex;
1151
+ align-items: center;
1152
+ gap: 6px;
1153
+ margin-bottom: 10px;
1154
+ }
1155
+
1156
+ .blx-date-picker-repeat-label {
1157
+ font-size: 0.75rem;
1158
+ font-weight: 500;
1159
+ color: var(--blx-text, #404550);
1160
+ white-space: nowrap;
1161
+ }
1162
+
1163
+ .blx-date-picker-repeat-num {
1164
+ width: 48px;
1165
+ padding: 5px 6px;
1166
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.1));
1167
+ border-radius: 6px;
1168
+ background: var(--blx-surface, #ffffff);
1169
+ color: var(--blx-text, #404550);
1170
+ font-size: 0.75rem;
1171
+ font-family: inherit;
1172
+ text-align: center;
1173
+ -moz-appearance: textfield;
1174
+ }
1175
+
1176
+ .blx-date-picker-repeat-num:focus {
1177
+ outline: none;
1178
+ border-color: var(--blx-accent, #4285f4);
1179
+ box-shadow: 0 0 0 2px var(--blx-accent-bg, rgba(66, 133, 244, 0.15));
1180
+ }
1181
+
1182
+ .blx-date-picker-repeat-num::-webkit-inner-spin-button,
1183
+ .blx-date-picker-repeat-num::-webkit-outer-spin-button {
1184
+ -webkit-appearance: none;
1185
+ margin: 0;
1186
+ }
1187
+
1188
+ .blx-date-picker-repeat-unit {
1189
+ flex: 1;
1190
+ padding: 5px 6px;
1191
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.1));
1192
+ border-radius: 6px;
1193
+ background: var(--blx-surface, #ffffff);
1194
+ color: var(--blx-text, #404550);
1195
+ font-size: 0.75rem;
1196
+ font-family: inherit;
1197
+ cursor: pointer;
1198
+ }
1199
+
1200
+ .blx-date-picker-repeat-unit:focus {
1201
+ outline: none;
1202
+ border-color: var(--blx-accent, #4285f4);
1203
+ box-shadow: 0 0 0 2px var(--blx-accent-bg, rgba(66, 133, 244, 0.15));
1204
+ }
1205
+
1206
+ .blx-date-picker-repeat-check {
1207
+ display: flex;
1208
+ align-items: center;
1209
+ gap: 6px;
1210
+ font-size: 0.7rem;
1211
+ color: var(--blx-text-muted, #8a8f9a);
1212
+ cursor: pointer;
1213
+ padding: 4px 0 0;
1214
+ }
1215
+
1216
+ .blx-date-picker-repeat-check input[type="checkbox"] {
1217
+ width: 14px;
1218
+ height: 14px;
1219
+ margin: 0;
1220
+ accent-color: var(--blx-accent, #4285f4);
1221
+ cursor: pointer;
1222
+ }
1223
+
1224
+ /* ── CJK Typography ──────────────────────────────────────────── */
1225
+
1226
+ /* CJK font fallback chain for text content */
1227
+ .blx-paragraph,
1228
+ .blx-heading,
1229
+ .blx-list li,
1230
+ .blx-checklist-content {
1231
+ font-family: var(--blx-font-sans), var(--blx-font-cjk);
1232
+ }
1233
+
1234
+ /* Progressive enhancement: CJK-Latin autospacing (Baseline Nov 2025) */
1235
+ .blx-paragraph,
1236
+ .blx-heading,
1237
+ .blx-list li,
1238
+ .blx-checklist-content {
1239
+ text-autospace: ideograph-alpha ideograph-numeric;
1240
+ }
1241
+
1242
+ /* ── Block content wrapper ───────────────────────────────────── */
1243
+
1244
+ .blx-block-content {
1245
+ position: relative;
1246
+ }
1247
+
1248
+ /* ── Code Block ──────────────────────────────────────────────── */
1249
+
1250
+ .blx-code-block {
1251
+ background: #1e1e2e;
1252
+ border-radius: 10px;
1253
+ margin: 10px;
1254
+ }
1255
+
1256
+ /* ── Language picker (Dropdown widget) ───────────────────────── */
1257
+
1258
+ .blx-code-lang-picker {
1259
+ position: absolute;
1260
+ top: 4px;
1261
+ right: 8px;
1262
+ z-index: 2;
1263
+ }
1264
+
1265
+ /* Code language dropdown — ghost button inside the always-dark code block */
1266
+ .blx-code-lang-dropdown.blx-dropdown-trigger {
1267
+ border: none;
1268
+ background: transparent;
1269
+ color: rgba(255, 255, 255, 0.25);
1270
+ font-size: 0.75rem;
1271
+ font-family: var(--blx-font-sans);
1272
+ font-weight: 500;
1273
+ padding: 3px 8px;
1274
+ transition: color 0.15s ease, background-color 0.15s ease;
1275
+ white-space: nowrap;
1276
+ letter-spacing: 0.01em;
1277
+ }
1278
+
1279
+ .blx-code-lang-dropdown.blx-dropdown-trigger:hover {
1280
+ background: rgba(255, 255, 255, 0.07);
1281
+ color: rgba(255, 255, 255, 0.7);
1282
+ }
1283
+
1284
+ .blx-code-lang-dropdown.blx-dropdown-trigger[aria-expanded="true"] {
1285
+ color: rgba(255, 255, 255, 0.85);
1286
+ background-color: rgba(255, 255, 255, 0.1);
1287
+ }
1288
+
1289
+ .blx-block-content:focus-within .blx-code-lang-dropdown.blx-dropdown-trigger {
1290
+ color: rgba(255, 255, 255, 0.45);
1291
+ }
1292
+
1293
+ .blx-code-pre {
1294
+ margin: 0;
1295
+ padding: 0;
1296
+ }
1297
+
1298
+ .blx-code-content {
1299
+ display: block;
1300
+ font-family: var(--blx-font-mono);
1301
+ font-size: 0.8rem;
1302
+ line-height: 1.6;
1303
+ color: #cdd6f4;
1304
+ white-space: pre;
1305
+ padding: 16px 18px;
1306
+ overflow-x: auto;
1307
+ min-height: 1.6em;
1308
+ tab-size: 2;
1309
+ }
1310
+
1311
+ .blx-code-block [contenteditable="true"]:focus {
1312
+ background-color: transparent;
1313
+ box-shadow: none;
1314
+ }
1315
+
1316
+ .blx-code-block [contenteditable="true"] {
1317
+ padding: 16px 18px;
1318
+ border-radius: 0;
1319
+ transition: none;
1320
+ }
1321
+
1322
+ /* Empty code block placeholder */
1323
+ .blx-code-content:empty::before {
1324
+ content: "Type code here...";
1325
+ color: #585b70;
1326
+ pointer-events: none;
1327
+ }
1328
+
1329
+ /* ── Prism token colors (Catppuccin Mocha-inspired) ──────────── */
1330
+
1331
+ .blx-code-content .token.comment,
1332
+ .blx-code-content .token.prolog,
1333
+ .blx-code-content .token.doctype,
1334
+ .blx-code-content .token.cdata {
1335
+ color: #6c7086;
1336
+ font-style: italic;
1337
+ }
1338
+
1339
+ .blx-code-content .token.punctuation {
1340
+ color: #bac2de;
1341
+ }
1342
+
1343
+ .blx-code-content .token.keyword,
1344
+ .blx-code-content .token.tag,
1345
+ .blx-code-content .token.boolean,
1346
+ .blx-code-content .token.important {
1347
+ color: #cba6f7;
1348
+ }
1349
+
1350
+ .blx-code-content .token.string,
1351
+ .blx-code-content .token.char,
1352
+ .blx-code-content .token.attr-value,
1353
+ .blx-code-content .token.regex {
1354
+ color: #a6e3a1;
1355
+ }
1356
+
1357
+ .blx-code-content .token.number {
1358
+ color: #fab387;
1359
+ }
1360
+
1361
+ .blx-code-content .token.function {
1362
+ color: #89b4fa;
1363
+ }
1364
+
1365
+ .blx-code-content .token.class-name,
1366
+ .blx-code-content .token.builtin {
1367
+ color: #f9e2af;
1368
+ }
1369
+
1370
+ .blx-code-content .token.property,
1371
+ .blx-code-content .token.constant,
1372
+ .blx-code-content .token.symbol {
1373
+ color: #f38ba8;
1374
+ }
1375
+
1376
+ .blx-code-content .token.operator,
1377
+ .blx-code-content .token.entity,
1378
+ .blx-code-content .token.url {
1379
+ color: #89dceb;
1380
+ }
1381
+
1382
+ .blx-code-content .token.attr-name {
1383
+ color: #f9e2af;
1384
+ }
1385
+
1386
+ .blx-code-content .token.selector {
1387
+ color: #a6e3a1;
1388
+ }
1389
+
1390
+ .blx-code-content .token.atrule {
1391
+ color: #cba6f7;
1392
+ }
1393
+
1394
+ .blx-code-content .token.inserted {
1395
+ color: #a6e3a1;
1396
+ }
1397
+
1398
+ .blx-code-content .token.deleted {
1399
+ color: #f38ba8;
1400
+ }
1401
+
1402
+ /* ── Inline Code ────────────────────────────────────────────── */
1403
+
1404
+ .blx-inline-code {
1405
+ font-family: var(--blx-font-mono);
1406
+ font-size: 0.9em;
1407
+ background-color: var(--blx-inline-code-bg);
1408
+ padding: 0.1em 0.3em;
1409
+ border-radius: 3px;
1410
+ }
1411
+
1412
+ /* ── Block References (inline pills) ─────────────────────────── */
1413
+
1414
+ .blx-block-ref {
1415
+ display: inline;
1416
+ background-color: var(--blx-accent-bg);
1417
+ color: var(--blx-accent);
1418
+ border-radius: 3px;
1419
+ padding: 0.05em 0.2em;
1420
+ cursor: pointer;
1421
+ transition: background-color 0.12s ease;
1422
+ }
1423
+
1424
+ .blx-block-ref:hover {
1425
+ background-color: var(--blx-accent-bg-hover);
1426
+ }
1427
+
1428
+ /* ── Base Menu (shared by SlashMenu, AutoComplete, BlockAction, Table) ── */
1429
+
1430
+ .blx-menu {
1431
+ position: fixed;
1432
+ z-index: 100;
1433
+ min-width: 220px;
1434
+ background: var(--blx-surface);
1435
+ border: 1px solid var(--blx-border);
1436
+ border-radius: 10px;
1437
+ box-shadow: var(--blx-shadow);
1438
+ padding: 6px 4px;
1439
+ max-height: 320px;
1440
+ overflow-y: auto;
1441
+ animation: blx-menu-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);
1442
+ }
1443
+
1444
+ @keyframes blx-menu-in {
1445
+ from {
1446
+ opacity: 0;
1447
+ transform: translateY(-6px);
1448
+ }
1449
+ to {
1450
+ opacity: 1;
1451
+ transform: translateY(0);
1452
+ }
1453
+ }
1454
+
1455
+ .blx-menu-item {
1456
+ display: flex;
1457
+ align-items: center;
1458
+ gap: 8px;
1459
+ width: 100%;
1460
+ text-align: start;
1461
+ padding: 7px 11px;
1462
+ border: none;
1463
+ background: none;
1464
+ border-radius: 7px;
1465
+ cursor: pointer;
1466
+ outline: none;
1467
+ transition: background-color 0.1s ease;
1468
+ }
1469
+
1470
+ .blx-menu-item-selected {
1471
+ background: var(--blx-menu-highlight, rgba(0, 0, 0, 0.06));
1472
+ }
1473
+
1474
+ .blx-menu-item-disabled {
1475
+ opacity: 0.35;
1476
+ pointer-events: none;
1477
+ cursor: default;
1478
+ }
1479
+
1480
+ .blx-menu-item-danger .blx-menu-label {
1481
+ color: var(--blx-danger);
1482
+ }
1483
+
1484
+ .blx-menu-icon {
1485
+ display: inline-flex;
1486
+ align-items: center;
1487
+ justify-content: center;
1488
+ width: 20px;
1489
+ height: 20px;
1490
+ flex-shrink: 0;
1491
+ color: var(--blx-text-icon);
1492
+ }
1493
+
1494
+ .blx-menu-text {
1495
+ display: flex;
1496
+ flex-direction: column;
1497
+ gap: 1px;
1498
+ min-width: 0;
1499
+ }
1500
+
1501
+ .blx-menu-label {
1502
+ font-size: 0.825rem;
1503
+ font-weight: 500;
1504
+ color: var(--blx-text);
1505
+ overflow: hidden;
1506
+ text-overflow: ellipsis;
1507
+ white-space: nowrap;
1508
+ }
1509
+
1510
+ .blx-menu-description {
1511
+ font-size: 0.7rem;
1512
+ color: var(--blx-description-color);
1513
+ }
1514
+
1515
+ .blx-menu-hint {
1516
+ margin-left: auto;
1517
+ padding-left: 12px;
1518
+ font-size: 0.75rem;
1519
+ color: var(--blx-text-faint);
1520
+ white-space: nowrap;
1521
+ flex-shrink: 0;
1522
+ letter-spacing: 0.02em;
1523
+ }
1524
+
1525
+ .blx-menu-sep {
1526
+ height: 1px;
1527
+ background: var(--blx-border);
1528
+ margin: 4px 6px;
1529
+ }
1530
+
1531
+ .blx-menu-empty {
1532
+ padding: 12px 11px;
1533
+ font-size: 0.775rem;
1534
+ color: var(--blx-text-muted);
1535
+ text-align: center;
1536
+ }
1537
+
1538
+ /* ── Thin scrollbars (shared by all scrollable widgets) ─────── */
1539
+
1540
+ .blx-menu,
1541
+ .blx-emoji-grid-browse,
1542
+ .kb-panel-body {
1543
+ scrollbar-width: thin;
1544
+ scrollbar-color: var(--blx-scrollbar-thumb) transparent;
1545
+ }
1546
+
1547
+ .blx-menu::-webkit-scrollbar,
1548
+ .blx-emoji-grid-browse::-webkit-scrollbar,
1549
+ .kb-panel-body::-webkit-scrollbar {
1550
+ width: 4px;
1551
+ height: 4px;
1552
+ }
1553
+
1554
+ .blx-menu::-webkit-scrollbar-track,
1555
+ .blx-emoji-grid-browse::-webkit-scrollbar-track,
1556
+ .kb-panel-body::-webkit-scrollbar-track {
1557
+ background: transparent;
1558
+ }
1559
+
1560
+ .blx-menu::-webkit-scrollbar-thumb,
1561
+ .blx-emoji-grid-browse::-webkit-scrollbar-thumb,
1562
+ .kb-panel-body::-webkit-scrollbar-thumb {
1563
+ background: var(--blx-scrollbar-thumb);
1564
+ border-radius: 2px;
1565
+ }
1566
+
1567
+ /* Code blocks are always dark (Catppuccin) — hardcoded thumb color */
1568
+ .blx-code-content {
1569
+ scrollbar-width: thin;
1570
+ scrollbar-color: rgba(255, 255, 255, 0.1) transparent;
1571
+ }
1572
+
1573
+ .blx-code-content::-webkit-scrollbar {
1574
+ width: 4px;
1575
+ height: 4px;
1576
+ }
1577
+
1578
+ .blx-code-content::-webkit-scrollbar-track {
1579
+ background: transparent;
1580
+ }
1581
+
1582
+ .blx-code-content::-webkit-scrollbar-thumb {
1583
+ background: rgba(255, 255, 255, 0.1);
1584
+ border-radius: 2px;
1585
+ }
1586
+
1587
+ /* ── Base Popover (shared by LinkPopover, HighlightPicker, InlineToolbar) ── */
1588
+
1589
+ .blx-popover {
1590
+ position: fixed;
1591
+ z-index: 110;
1592
+ background: var(--blx-surface);
1593
+ border: 1px solid var(--blx-border);
1594
+ border-radius: 8px;
1595
+ box-shadow: var(--blx-shadow);
1596
+ padding: 4px;
1597
+ animation: blx-popover-in 0.12s cubic-bezier(0.16, 1, 0.3, 1);
1598
+ }
1599
+
1600
+ @keyframes blx-popover-in {
1601
+ from {
1602
+ opacity: 0;
1603
+ transform: translateY(4px);
1604
+ }
1605
+ to {
1606
+ opacity: 1;
1607
+ transform: translateY(0);
1608
+ }
1609
+ }
1610
+
1611
+ /* ── Tooltip ──────────────────────────────────────────────────── */
1612
+ /*
1613
+ * Tooltip is appended to document.body — outside .blx-editor — so CSS
1614
+ * custom properties are specified with explicit fallbacks for light theme.
1615
+ * Dark-mode adaptation happens through the explicit @media block below.
1616
+ */
1617
+
1618
+ .blx-tooltip {
1619
+ position: fixed;
1620
+ z-index: 10000;
1621
+ padding: 6px 11px;
1622
+ border-radius: 7px;
1623
+ background: var(--blx-text, #404550);
1624
+ color: var(--blx-surface, #ffffff);
1625
+ font-family: var(--blx-font-sans, "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
1626
+ font-size: 0.75rem;
1627
+ font-weight: 500;
1628
+ line-height: 1.5;
1629
+ letter-spacing: 0.01em;
1630
+ pointer-events: none;
1631
+ white-space: nowrap;
1632
+ max-width: 260px;
1633
+ overflow: hidden;
1634
+ text-overflow: ellipsis;
1635
+ box-shadow:
1636
+ 0 1px 3px rgba(0, 0, 0, 0.12),
1637
+ 0 4px 12px rgba(0, 0, 0, 0.10),
1638
+ 0 0 0 1px rgba(0, 0, 0, 0.04);
1639
+ animation: blx-tooltip-in var(--blx-widget-anim-duration, 0.15s) var(--blx-widget-anim-curve, cubic-bezier(0.16, 1, 0.3, 1));
1640
+ }
1641
+
1642
+ /* Shortcut hint styling — lighter weight for key combos */
1643
+ .blx-tooltip kbd {
1644
+ font-family: var(--blx-font-sans, "Plus Jakarta Sans", -apple-system, sans-serif);
1645
+ font-size: 0.6875rem;
1646
+ font-weight: 400;
1647
+ opacity: 0.72;
1648
+ margin-inline-start: 6px;
1649
+ }
1650
+
1651
+ @keyframes blx-tooltip-in {
1652
+ from { opacity: 0; transform: scale(0.96) translateY(2px); }
1653
+ to { opacity: 1; transform: scale(1) translateY(0); }
1654
+ }
1655
+
1656
+ /* ── Toast ────────────────────────────────────────────────────── */
1657
+ /*
1658
+ * Toast is appended to document.body — CSS custom properties have fallbacks.
1659
+ */
1660
+
1661
+ .blx-toast-container {
1662
+ position: fixed;
1663
+ bottom: 24px;
1664
+ left: 50%;
1665
+ transform: translateX(-50%);
1666
+ z-index: 10001;
1667
+ display: flex;
1668
+ flex-direction: column;
1669
+ align-items: center;
1670
+ gap: 8px;
1671
+ pointer-events: none;
1672
+ }
1673
+
1674
+ .blx-toast {
1675
+ padding: 10px 20px;
1676
+ border-radius: var(--blx-widget-radius, 8px);
1677
+ background: var(--blx-text, #404550);
1678
+ color: var(--blx-surface, #ffffff);
1679
+ font-family: var(--blx-font-sans, "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
1680
+ font-size: 0.8rem;
1681
+ font-weight: 500;
1682
+ line-height: 1.45;
1683
+ letter-spacing: 0.005em;
1684
+ box-shadow:
1685
+ 0 4px 20px rgba(0, 0, 0, 0.08),
1686
+ 0 0 0 1px rgba(0, 0, 0, 0.03);
1687
+ pointer-events: auto;
1688
+ cursor: pointer;
1689
+ animation: blx-toast-in 0.2s ease;
1690
+ max-width: 400px;
1691
+ text-align: center;
1692
+ min-width: 160px;
1693
+ transition: opacity 0.12s ease;
1694
+ }
1695
+
1696
+ .blx-toast:hover {
1697
+ opacity: 0.88;
1698
+ }
1699
+
1700
+ .blx-toast-error {
1701
+ background: var(--blx-danger, #dc3545);
1702
+ color: #fff;
1703
+ }
1704
+
1705
+ .blx-toast-success {
1706
+ background: #16a34a;
1707
+ color: #fff;
1708
+ }
1709
+
1710
+ .blx-toast-exit {
1711
+ animation: blx-toast-out 0.15s ease forwards;
1712
+ }
1713
+
1714
+ @keyframes blx-toast-in {
1715
+ from { opacity: 0; transform: translateY(8px); }
1716
+ to { opacity: 1; transform: translateY(0); }
1717
+ }
1718
+
1719
+ @keyframes blx-toast-out {
1720
+ from { opacity: 1; transform: translateY(0); }
1721
+ to { opacity: 0; transform: translateY(6px); }
1722
+ }
1723
+
1724
+ /* ── Modal ────────────────────────────────────────────────────── */
1725
+ /*
1726
+ * Modal uses native <dialog> appended to document.body.
1727
+ * CSS custom properties have explicit fallbacks for light theme.
1728
+ */
1729
+
1730
+ .blx-modal {
1731
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1732
+ border-radius: 12px;
1733
+ background: var(--blx-widget-surface, var(--blx-surface, #ffffff));
1734
+ color: var(--blx-widget-text, var(--blx-text, #404550));
1735
+ box-shadow:
1736
+ 0 0 0 1px rgba(0, 0, 0, 0.02),
1737
+ 0 8px 24px rgba(0, 0, 0, 0.06),
1738
+ 0 24px 64px rgba(0, 0, 0, 0.1);
1739
+ padding: 0;
1740
+ max-width: 440px;
1741
+ width: 90vw;
1742
+ font-family: var(--blx-font-sans, "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
1743
+ animation: blx-modal-in 0.2s cubic-bezier(0.22, 1, 0.36, 1);
1744
+ }
1745
+
1746
+ .blx-modal::backdrop {
1747
+ background: rgba(0, 0, 0, 0.18);
1748
+ -webkit-backdrop-filter: blur(4px);
1749
+ backdrop-filter: blur(4px);
1750
+ animation: blx-modal-backdrop-in 0.15s ease-out;
1751
+ }
1752
+
1753
+ .blx-modal-header {
1754
+ padding: 20px 24px 14px;
1755
+ border-bottom: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1756
+ }
1757
+
1758
+ .blx-modal-header h3 {
1759
+ margin: 0;
1760
+ font-size: 0.9375rem;
1761
+ font-weight: 600;
1762
+ line-height: 1.3;
1763
+ letter-spacing: -0.015em;
1764
+ color: var(--blx-text-heading, #3b4255);
1765
+ }
1766
+
1767
+ .blx-modal-body {
1768
+ padding: 18px 24px;
1769
+ font-size: 0.8rem;
1770
+ line-height: 1.6;
1771
+ color: var(--blx-text, #404550);
1772
+ }
1773
+
1774
+ .blx-modal-footer {
1775
+ padding: 14px 24px 20px;
1776
+ display: flex;
1777
+ justify-content: flex-end;
1778
+ gap: 10px;
1779
+ border-top: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1780
+ }
1781
+
1782
+ .blx-modal-btn {
1783
+ display: inline-flex;
1784
+ align-items: center;
1785
+ justify-content: center;
1786
+ padding: 8px 18px;
1787
+ border-radius: 8px;
1788
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1789
+ background: var(--blx-widget-surface, var(--blx-surface, #ffffff));
1790
+ color: var(--blx-widget-text, var(--blx-text, #404550));
1791
+ font-size: 0.8rem;
1792
+ font-weight: 500;
1793
+ cursor: pointer;
1794
+ font-family: inherit;
1795
+ line-height: 1.4;
1796
+ min-width: 76px;
1797
+ transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
1798
+ }
1799
+
1800
+ .blx-modal-btn:hover {
1801
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.035));
1802
+ color: var(--blx-text, #404550);
1803
+ }
1804
+
1805
+ .blx-modal-btn:focus-visible {
1806
+ outline: none;
1807
+ box-shadow: 0 0 0 2px var(--blx-widget-surface, #fff), 0 0 0 4px var(--blx-accent, #4285f4);
1808
+ }
1809
+
1810
+ .blx-modal-btn-primary {
1811
+ background: var(--blx-accent, #4285f4);
1812
+ color: #fff;
1813
+ border-color: var(--blx-accent, #4285f4);
1814
+ font-weight: 500;
1815
+ }
1816
+
1817
+ .blx-modal-btn-primary:hover {
1818
+ opacity: 0.9;
1819
+ }
1820
+
1821
+ .blx-modal-btn-danger {
1822
+ background: transparent;
1823
+ color: var(--blx-danger, #dc3545);
1824
+ border-color: transparent;
1825
+ }
1826
+
1827
+ .blx-modal-btn-danger:hover {
1828
+ background: rgba(239, 68, 68, 0.08);
1829
+ color: var(--blx-danger, #dc3545);
1830
+ }
1831
+
1832
+ @keyframes blx-modal-in {
1833
+ from { opacity: 0; transform: translateY(-6px) scale(0.985); }
1834
+ to { opacity: 1; transform: translateY(0) scale(1); }
1835
+ }
1836
+
1837
+ @keyframes blx-modal-backdrop-in {
1838
+ from { opacity: 0; }
1839
+ to { opacity: 1; }
1840
+ }
1841
+
1842
+ /* ── Dropdown ─────────────────────────────────────────────────── */
1843
+ /*
1844
+ * Dropdown trigger is always inside .blx-editor and inherits CSS variables.
1845
+ * The menu (ContextMenu element) is appended inside .blx-editor too (see
1846
+ * Dropdown.attachTo), so it also has access to --blx-* variables via .blx-menu.
1847
+ */
1848
+
1849
+ .blx-dropdown-trigger {
1850
+ display: inline-flex;
1851
+ align-items: center;
1852
+ gap: 5px;
1853
+ padding: 5px 10px;
1854
+ border-radius: 6px;
1855
+ border: 1px solid var(--blx-border-input);
1856
+ background: var(--blx-surface);
1857
+ color: var(--blx-text);
1858
+ font-size: 0.8125rem;
1859
+ font-weight: 500;
1860
+ font-family: var(--blx-font-sans);
1861
+ cursor: pointer;
1862
+ line-height: 1.4;
1863
+ transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
1864
+ }
1865
+
1866
+ .blx-dropdown-trigger:hover {
1867
+ background: var(--blx-hover-bg);
1868
+ border-color: var(--blx-border-input);
1869
+ }
1870
+
1871
+ .blx-dropdown-trigger[aria-expanded="true"] {
1872
+ background: var(--blx-accent-bg);
1873
+ border-color: var(--blx-accent);
1874
+ color: var(--blx-accent);
1875
+ }
1876
+
1877
+ .blx-dropdown-trigger::after {
1878
+ content: "";
1879
+ display: inline-block;
1880
+ width: 0;
1881
+ height: 0;
1882
+ border-left: 3.5px solid transparent;
1883
+ border-right: 3.5px solid transparent;
1884
+ border-top: 3.5px solid currentColor;
1885
+ opacity: 0.5;
1886
+ margin-inline-start: 4px;
1887
+ flex-shrink: 0;
1888
+ transition: transform var(--blx-widget-anim-duration) var(--blx-widget-anim-curve);
1889
+ }
1890
+
1891
+ .blx-dropdown-trigger[aria-expanded="true"]::after {
1892
+ transform: rotate(180deg);
1893
+ opacity: 0.7;
1894
+ }
1895
+
1896
+ /* Dropdown menu — explicit fallbacks since menu may land on document.body
1897
+ * (outside .blx-editor) when closest() fails to find the editor root.
1898
+ * Same pattern as Tooltip/Toast: duplicate base .blx-menu surface styles. */
1899
+ .blx-dropdown-menu {
1900
+ min-width: 160px;
1901
+ background: var(--blx-surface, #ffffff);
1902
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
1903
+ border-radius: 10px;
1904
+ padding: 6px;
1905
+ box-shadow: var(--blx-shadow, 0 4px 20px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(0, 0, 0, 0.02));
1906
+ font-family: var(--blx-font-sans, "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);
1907
+ color: var(--blx-text, #404550);
1908
+ }
1909
+
1910
+ .blx-dropdown-menu .blx-menu-item {
1911
+ padding: 6px 10px;
1912
+ }
1913
+
1914
+ .blx-dropdown-menu .blx-menu-item-selected {
1915
+ background: var(--blx-menu-highlight, rgba(0, 0, 0, 0.06));
1916
+ }
1917
+
1918
+ .blx-dropdown-menu .blx-menu-label {
1919
+ font-size: 0.8rem;
1920
+ color: var(--blx-text, #404550);
1921
+ }
1922
+
1923
+ .blx-dropdown-check {
1924
+ color: var(--blx-accent, #4f7dff);
1925
+ }
1926
+
1927
+ /* ── Menu type overrides ──────────────────────────────────────── */
1928
+
1929
+ .blx-autocomplete-menu { max-width: 340px; max-height: 280px; }
1930
+ .blx-slash-menu { max-height: min(280px, 40vh); }
1931
+ .blx-slash-menu .blx-menu-item { flex-direction: column; align-items: flex-start; gap: 1px; }
1932
+ .blx-action-menu { z-index: 110; min-width: 180px; max-height: 360px; }
1933
+ .blx-action-menu .blx-menu-item { padding: 6px 10px; }
1934
+ .blx-action-menu .blx-menu-icon { width: 16px; height: 16px; }
1935
+ .blx-action-menu .blx-menu-label { font-weight: 450; font-family: var(--blx-font-sans); }
1936
+ .blx-context-menu { z-index: 120; min-width: 160px; max-height: 320px; }
1937
+ .blx-context-menu .blx-menu-item { padding: 6px 10px; }
1938
+ .blx-context-menu .blx-menu-icon { width: 16px; height: 16px; }
1939
+ .blx-context-menu .blx-menu-label { font-weight: 450; font-family: var(--blx-font-sans); }
1940
+
1941
+ /* ── Highlight / Text Marking ────────────────────────────────── */
1942
+
1943
+ .blx-highlight {
1944
+ border-radius: 2px;
1945
+ padding: 0.05em 0;
1946
+ }
1947
+
1948
+ .blx-highlight-yellow { background-color: var(--blx-highlight-yellow); }
1949
+ .blx-highlight-green { background-color: var(--blx-highlight-green); }
1950
+ .blx-highlight-blue { background-color: var(--blx-highlight-blue); }
1951
+ .blx-highlight-pink { background-color: var(--blx-highlight-pink); }
1952
+ .blx-highlight-orange { background-color: var(--blx-highlight-orange); }
1953
+ .blx-highlight-purple { background-color: var(--blx-highlight-purple); }
1954
+
1955
+ /* ── Highlight Picker ────────────────────────────────────────── */
1956
+
1957
+
1958
+ .blx-highlight-picker-row {
1959
+ display: flex;
1960
+ align-items: center;
1961
+ gap: 3px;
1962
+ }
1963
+
1964
+ .blx-highlight-swatch {
1965
+ width: 22px;
1966
+ height: 22px;
1967
+ border-radius: 50%;
1968
+ border: 2px solid transparent;
1969
+ cursor: pointer;
1970
+ transition: border-color 0.1s ease, transform 0.1s ease;
1971
+ display: inline-flex;
1972
+ align-items: center;
1973
+ justify-content: center;
1974
+ padding: 0;
1975
+ outline: none;
1976
+ }
1977
+
1978
+ .blx-highlight-swatch:hover {
1979
+ transform: scale(1.15);
1980
+ }
1981
+
1982
+ .blx-highlight-swatch-active {
1983
+ border-color: var(--blx-accent);
1984
+ }
1985
+
1986
+ .blx-highlight-swatch-yellow { background-color: var(--blx-highlight-yellow); }
1987
+ .blx-highlight-swatch-green { background-color: var(--blx-highlight-green); }
1988
+ .blx-highlight-swatch-blue { background-color: var(--blx-highlight-blue); }
1989
+ .blx-highlight-swatch-pink { background-color: var(--blx-highlight-pink); }
1990
+ .blx-highlight-swatch-orange { background-color: var(--blx-highlight-orange); }
1991
+ .blx-highlight-swatch-purple { background-color: var(--blx-highlight-purple); }
1992
+
1993
+ .blx-highlight-swatch-remove {
1994
+ background: var(--blx-btn-secondary-bg);
1995
+ color: var(--blx-text-muted);
1996
+ }
1997
+
1998
+ .blx-highlight-swatch-remove:hover {
1999
+ background: var(--blx-btn-secondary-bg-hover);
2000
+ color: var(--blx-text);
2001
+ }
2002
+
2003
+ /* Mobile: larger tap targets */
2004
+ @media (pointer: coarse) {
2005
+ .blx-highlight-swatch {
2006
+ width: 36px;
2007
+ height: 36px;
2008
+ }
2009
+
2010
+ .blx-highlight-picker {
2011
+ padding: 5px;
2012
+ }
2013
+
2014
+ .blx-highlight-picker-row {
2015
+ gap: 4px;
2016
+ }
2017
+ }
2018
+
2019
+ /* ── Drag Handle ─────────────────────────────────────────────── */
2020
+
2021
+ .blx-drag-handle {
2022
+ position: absolute;
2023
+ width: 24px;
2024
+ height: 24px;
2025
+ inset-inline-start: calc(var(--blx-gutter) - 26px);
2026
+ display: flex;
2027
+ align-items: center;
2028
+ justify-content: center;
2029
+ cursor: grab;
2030
+ opacity: 0;
2031
+ transform: translateX(-4px);
2032
+ transition: opacity 0.15s ease, transform 0.15s ease, top 0.1s ease, background-color 0.15s ease;
2033
+ border-radius: 5px;
2034
+ color: var(--blx-text-faint);
2035
+ user-select: none;
2036
+ touch-action: none;
2037
+ }
2038
+
2039
+ .blx-drag-handle:hover {
2040
+ background: var(--blx-hover-bg);
2041
+ color: var(--blx-text-icon);
2042
+ }
2043
+
2044
+ /* ── Block Action Button ─────────────────────────────────── */
2045
+
2046
+ .blx-action-btn {
2047
+ position: absolute;
2048
+ width: 24px;
2049
+ height: 24px;
2050
+ inset-inline-start: calc(var(--blx-gutter) - 52px);
2051
+ display: flex;
2052
+ align-items: center;
2053
+ justify-content: center;
2054
+ cursor: pointer;
2055
+ opacity: 0;
2056
+ transform: translateX(-4px);
2057
+ transition: opacity 0.15s ease, transform 0.15s ease, top 0.1s ease, background-color 0.15s ease;
2058
+ border-radius: 5px;
2059
+ color: var(--blx-text-faint);
2060
+ user-select: none;
2061
+ touch-action: manipulation;
2062
+ }
2063
+
2064
+ .blx-action-btn:hover {
2065
+ background: var(--blx-hover-bg);
2066
+ color: var(--blx-text-icon);
2067
+ }
2068
+
2069
+ /* ── Block Action Menu ───────────────────────────────────── */
2070
+
2071
+
2072
+ /* ── Mobile: larger tap targets and visible positioning ──── */
2073
+ @media (pointer: coarse) {
2074
+ .blx-editor {
2075
+ --blx-gutter: 104px;
2076
+ }
2077
+
2078
+ .blx-drag-handle {
2079
+ width: 44px;
2080
+ height: 44px;
2081
+ inset-inline-start: calc(var(--blx-gutter) - 46px);
2082
+ border-radius: 7px;
2083
+ }
2084
+
2085
+ .blx-action-btn {
2086
+ width: 44px;
2087
+ height: 44px;
2088
+ inset-inline-start: calc(var(--blx-gutter) - 92px);
2089
+ border-radius: 7px;
2090
+ }
2091
+ }
2092
+
2093
+ /* Small screens: compact gutter with tightly packed widgets */
2094
+ @media (max-width: 600px) {
2095
+ .blx-editor {
2096
+ --blx-gutter: 50px;
2097
+ }
2098
+
2099
+ .blx-drag-handle {
2100
+ inset-inline-start: calc(var(--blx-gutter) - 24px);
2101
+ }
2102
+
2103
+ .blx-action-btn {
2104
+ inset-inline-start: 1px;
2105
+ }
2106
+ }
2107
+
2108
+ .blx-block-dragging {
2109
+ opacity: 0 !important;
2110
+ pointer-events: none;
2111
+ }
2112
+
2113
+ .blx-block-shift {
2114
+ transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
2115
+ }
2116
+
2117
+ .blx-drag-ghost {
2118
+ position: fixed;
2119
+ z-index: 1000;
2120
+ pointer-events: none;
2121
+ opacity: 0.7;
2122
+ }
2123
+
2124
+ /* ── Horizontal Rule ─────────────────────────────────────────── */
2125
+
2126
+ .blx-horizontal-rule {
2127
+ padding: 16px 6px;
2128
+ cursor: default;
2129
+ }
2130
+
2131
+ .blx-hr {
2132
+ border: none;
2133
+ height: 1px;
2134
+ background: var(--blx-hr);
2135
+ margin: 0;
2136
+ }
2137
+
2138
+ /* ── Blockquote ────────────────────────────────────────────── */
2139
+
2140
+ /* Cancel default indent margin — blockquotes express depth via stacked borders */
2141
+ .blx-block:has(.blx-blockquote) {
2142
+ margin-inline-start: 0 !important;
2143
+ }
2144
+
2145
+ .blx-blockquote {
2146
+ --bq-line: 2px;
2147
+ --bq-gap: 12px;
2148
+ --bq-step: calc(var(--bq-line) + var(--bq-gap));
2149
+ --bq-full: calc(var(--bq-step) + 6px);
2150
+ margin: 0;
2151
+ padding: 0 0 0 var(--bq-step);
2152
+ border-left: none;
2153
+ color: var(--blx-text-muted);
2154
+ background: linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat 0 0 / var(--bq-line) 100%;
2155
+ }
2156
+
2157
+ .blx-blockquote p {
2158
+ margin: 0;
2159
+ }
2160
+
2161
+ /* Stacked left borders for nested blockquotes via indentLevel.
2162
+ --bq-full = bq-step + 6px contenteditable padding, used as the
2163
+ consistent spacing between all borders. */
2164
+ .blx-block[data-indent-level="1"] .blx-blockquote {
2165
+ padding-left: calc(var(--bq-full) + var(--bq-step));
2166
+ background:
2167
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat 0 0 / var(--bq-line) 100%,
2168
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat var(--bq-full) 0 / var(--bq-line) 100%;
2169
+ }
2170
+
2171
+ .blx-block[data-indent-level="2"] .blx-blockquote {
2172
+ padding-left: calc(var(--bq-full) * 2 + var(--bq-step));
2173
+ background:
2174
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat 0 0 / var(--bq-line) 100%,
2175
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat var(--bq-full) 0 / var(--bq-line) 100%,
2176
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat calc(var(--bq-full) * 2) 0 / var(--bq-line) 100%;
2177
+ }
2178
+
2179
+ .blx-block[data-indent-level="3"] .blx-blockquote {
2180
+ padding-left: calc(var(--bq-full) * 3 + var(--bq-step));
2181
+ background:
2182
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat 0 0 / var(--bq-line) 100%,
2183
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat var(--bq-full) 0 / var(--bq-line) 100%,
2184
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat calc(var(--bq-full) * 2) 0 / var(--bq-line) 100%,
2185
+ linear-gradient(var(--blx-accent-muted), var(--blx-accent-muted)) no-repeat calc(var(--bq-full) * 3) 0 / var(--bq-line) 100%;
2186
+ }
2187
+
2188
+ /* ── Block indentation / nesting ─────────────────────────────── */
2189
+
2190
+ .blx-block.blx-indent-animated {
2191
+ transition: margin-inline-start 0.15s ease;
2192
+ }
2193
+
2194
+ /* ── Block selection (Shift+Arrow multi-block) ──────────────── */
2195
+
2196
+ .blx-block-selected {
2197
+ background-color: var(--blx-accent-bg);
2198
+ border-radius: 0;
2199
+ }
2200
+
2201
+ /* First in contiguous group — round top corners */
2202
+ .blx-block-selected:not(.blx-block-selected + .blx-block-selected) {
2203
+ border-top-left-radius: 5px;
2204
+ border-top-right-radius: 5px;
2205
+ }
2206
+
2207
+ /* Last in contiguous group — round bottom corners */
2208
+ .blx-block-selected:not(:has(+ .blx-block-selected)) {
2209
+ border-bottom-left-radius: 5px;
2210
+ border-bottom-right-radius: 5px;
2211
+ }
2212
+
2213
+ .blx-block-selected [contenteditable] {
2214
+ background-color: transparent !important;
2215
+ box-shadow: none !important;
2216
+ }
2217
+
2218
+ /* Visual block mode uses a distinct teal highlight to differentiate from normal-mode selection */
2219
+ .blx-mode-visual-block .blx-block-selected {
2220
+ background-color: var(--blx-visual-select-bg);
2221
+ }
2222
+
2223
+ /* ── Focused non-text block (keyboard navigation) ────────────── */
2224
+
2225
+ .blx-block-focused {
2226
+ outline: 2px solid var(--blx-accent);
2227
+ outline-offset: 2px;
2228
+ border-radius: 6px;
2229
+ }
2230
+
2231
+ /* ── Selection highlighting ──────────────────────────────────── */
2232
+
2233
+ .blx-block ::selection {
2234
+ background-color: var(--blx-selection-bg);
2235
+ }
2236
+
2237
+ /* ── Slash command menu ──────────────────────────────────────── */
2238
+
2239
+
2240
+ /* ── Emoji picker ────────────────────────────────────────────── */
2241
+
2242
+ .blx-emoji-picker {
2243
+ position: fixed;
2244
+ z-index: 100;
2245
+ display: flex;
2246
+ flex-direction: column;
2247
+ gap: 4px;
2248
+ animation: blx-emoji-picker-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);
2249
+ }
2250
+
2251
+ @keyframes blx-emoji-picker-in {
2252
+ from {
2253
+ opacity: 0;
2254
+ transform: translateY(6px);
2255
+ }
2256
+ to {
2257
+ opacity: 1;
2258
+ transform: translateY(0);
2259
+ }
2260
+ }
2261
+
2262
+ /* ── Category tabs ── */
2263
+
2264
+ .blx-emoji-tabs {
2265
+ display: flex;
2266
+ gap: 1px;
2267
+ padding: 2px 3px;
2268
+ background: var(--blx-surface);
2269
+ border: 1px solid var(--blx-border);
2270
+ border-radius: 8px;
2271
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
2272
+ }
2273
+
2274
+ .blx-emoji-tab {
2275
+ flex: 1;
2276
+ padding: 4px 0;
2277
+ border: none;
2278
+ background: none;
2279
+ border-radius: 6px;
2280
+ cursor: pointer;
2281
+ font-size: 14px;
2282
+ line-height: 1;
2283
+ filter: grayscale(1);
2284
+ opacity: 0.5;
2285
+ transition: filter 0.12s ease, opacity 0.12s ease, background-color 0.12s ease;
2286
+ outline: none;
2287
+ }
2288
+
2289
+ .blx-emoji-tab:hover {
2290
+ filter: grayscale(0.3);
2291
+ opacity: 0.85;
2292
+ background: var(--blx-hover-bg);
2293
+ }
2294
+
2295
+ .blx-emoji-tab-active {
2296
+ filter: grayscale(0);
2297
+ opacity: 1;
2298
+ background: var(--blx-selected-bg);
2299
+ }
2300
+
2301
+ /* ── Emoji grid ── */
2302
+
2303
+ .blx-emoji-grid {
2304
+ display: grid;
2305
+ grid-template-columns: repeat(8, 1fr);
2306
+ gap: 1px;
2307
+ padding: 4px;
2308
+ position: relative;
2309
+ background: var(--blx-surface);
2310
+ border: 1px solid var(--blx-border);
2311
+ border-radius: 10px;
2312
+ box-shadow: var(--blx-shadow);
2313
+ }
2314
+
2315
+ .blx-emoji-grid-browse {
2316
+ max-height: 192px;
2317
+ overflow-y: auto;
2318
+ }
2319
+
2320
+ .blx-emoji-cell {
2321
+ display: flex;
2322
+ align-items: center;
2323
+ justify-content: center;
2324
+ width: 30px;
2325
+ height: 30px;
2326
+ border: none;
2327
+ background: none;
2328
+ border-radius: 6px;
2329
+ cursor: pointer;
2330
+ font-size: 18px;
2331
+ line-height: 1;
2332
+ padding: 0;
2333
+ transition: background-color 0.08s ease, transform 0.08s ease;
2334
+ outline: none;
2335
+ }
2336
+
2337
+ .blx-emoji-cell:hover {
2338
+ background: var(--blx-selected-bg);
2339
+ }
2340
+
2341
+ .blx-emoji-cell-selected {
2342
+ background: var(--blx-hover-bg);
2343
+ transform: scale(1.12);
2344
+ }
2345
+
2346
+ /* ── Tooltip ── */
2347
+
2348
+ .blx-emoji-tooltip {
2349
+ position: absolute;
2350
+ bottom: -22px;
2351
+ left: 50%;
2352
+ transform: translateX(-50%);
2353
+ font-size: 10px;
2354
+ color: var(--blx-text-muted);
2355
+ background: var(--blx-surface);
2356
+ border: 1px solid var(--blx-border);
2357
+ border-radius: 4px;
2358
+ padding: 1px 6px;
2359
+ white-space: nowrap;
2360
+ pointer-events: none;
2361
+ z-index: 1;
2362
+ }
2363
+
2364
+ /* ── Inline Toolbar ──────────────────────────────────────────── */
2365
+
2366
+ .blx-inline-toolbar {
2367
+ align-items: center;
2368
+ gap: 2px;
2369
+ padding: 3px;
2370
+ }
2371
+
2372
+ .blx-inline-toolbar-btn {
2373
+ display: inline-flex;
2374
+ align-items: center;
2375
+ justify-content: center;
2376
+ width: 28px;
2377
+ height: 28px;
2378
+ border: none;
2379
+ background: none;
2380
+ border-radius: 5px;
2381
+ cursor: pointer;
2382
+ color: var(--blx-text);
2383
+ font-size: 0.8rem;
2384
+ font-family: var(--blx-font-sans);
2385
+ transition: background-color 0.1s ease, color 0.1s ease;
2386
+ outline: none;
2387
+ }
2388
+
2389
+ .blx-inline-toolbar-btn:hover {
2390
+ background: var(--blx-hover-bg);
2391
+ }
2392
+
2393
+ .blx-inline-toolbar-btn-active {
2394
+ background: var(--blx-accent-bg);
2395
+ color: var(--blx-accent);
2396
+ }
2397
+
2398
+ .blx-inline-toolbar-btn-active:hover {
2399
+ background: var(--blx-accent-bg-hover);
2400
+ }
2401
+
2402
+ /* Button icon styles */
2403
+ .blx-inline-toolbar-icon-bold {
2404
+ font-weight: 700;
2405
+ }
2406
+
2407
+ .blx-inline-toolbar-icon-italic {
2408
+ font-style: italic;
2409
+ font-family: Georgia, "Times New Roman", serif;
2410
+ }
2411
+
2412
+ .blx-inline-toolbar-icon-underline {
2413
+ text-decoration: underline;
2414
+ text-underline-offset: 2px;
2415
+ }
2416
+
2417
+ .blx-inline-toolbar-icon-strikethrough {
2418
+ text-decoration: line-through;
2419
+ }
2420
+
2421
+ .blx-inline-toolbar-icon-code {
2422
+ font-family: var(--blx-font-mono);
2423
+ font-size: 0.7rem;
2424
+ }
2425
+
2426
+ /* Separator between built-in and plugin buttons */
2427
+ .blx-inline-toolbar-sep {
2428
+ width: 1px;
2429
+ height: 16px;
2430
+ background: var(--blx-toolbar-sep);
2431
+ margin: 0 2px;
2432
+ flex-shrink: 0;
2433
+ }
2434
+
2435
+ /* Mobile: larger tap targets (44px meets Apple HIG minimum) */
2436
+ @media (pointer: coarse) {
2437
+ .blx-inline-toolbar {
2438
+ gap: 1px;
2439
+ padding: 2px;
2440
+ }
2441
+
2442
+ .blx-inline-toolbar-btn {
2443
+ width: 44px;
2444
+ height: 44px;
2445
+ font-size: 0.95rem;
2446
+ border-radius: 7px;
2447
+ }
2448
+
2449
+ .blx-inline-toolbar-icon-code {
2450
+ font-size: 0.8rem;
2451
+ }
2452
+
2453
+ .blx-inline-toolbar-sep {
2454
+ height: 24px;
2455
+ margin: 0 1px;
2456
+ }
2457
+ }
2458
+
2459
+ /* ── Inline Links ────────────────────────────────────────────── */
2460
+
2461
+ .blx-link {
2462
+ color: var(--blx-accent);
2463
+ text-decoration: underline;
2464
+ text-decoration-color: var(--blx-link-underline);
2465
+ text-underline-offset: 2px;
2466
+ cursor: text;
2467
+ transition: text-decoration-color 0.15s ease;
2468
+ }
2469
+
2470
+ .blx-link:hover {
2471
+ text-decoration-color: var(--blx-accent);
2472
+ }
2473
+
2474
+ /* ── Link Popover ────────────────────────────────────────────── */
2475
+
2476
+
2477
+ .blx-link-popover-row {
2478
+ display: flex;
2479
+ align-items: center;
2480
+ gap: 4px;
2481
+ }
2482
+
2483
+ .blx-link-popover-input {
2484
+ font-family: var(--blx-font-sans);
2485
+ font-size: 0.8rem;
2486
+ padding: 5px 8px;
2487
+ border: 1px solid var(--blx-border-input);
2488
+ border-radius: 5px;
2489
+ outline: none;
2490
+ min-width: 220px;
2491
+ color: var(--blx-text);
2492
+ background: var(--blx-surface);
2493
+ transition: border-color 0.15s ease;
2494
+ }
2495
+
2496
+ .blx-link-popover-input:focus {
2497
+ border-color: var(--blx-accent);
2498
+ }
2499
+
2500
+ .blx-link-popover-btn {
2501
+ font-family: var(--blx-font-sans);
2502
+ font-size: 0.75rem;
2503
+ padding: 5px 10px;
2504
+ border: none;
2505
+ border-radius: 5px;
2506
+ cursor: pointer;
2507
+ font-weight: 500;
2508
+ transition: background-color 0.1s ease;
2509
+ }
2510
+
2511
+ .blx-link-popover-apply {
2512
+ background: var(--blx-accent);
2513
+ color: #fff;
2514
+ }
2515
+
2516
+ .blx-link-popover-apply:hover {
2517
+ background: var(--blx-accent-hover);
2518
+ }
2519
+
2520
+ .blx-link-popover-remove {
2521
+ background: var(--blx-btn-secondary-bg);
2522
+ color: var(--blx-btn-secondary-text);
2523
+ }
2524
+
2525
+ .blx-link-popover-remove:hover {
2526
+ background: var(--blx-btn-secondary-bg-hover);
2527
+ }
2528
+
2529
+ /* ── Empty block placeholder ─────────────────────────────────── */
2530
+
2531
+ .blx-empty[data-placeholder]:focus::before {
2532
+ content: attr(data-placeholder);
2533
+ color: var(--blx-placeholder-color);
2534
+ pointer-events: none;
2535
+ float: left;
2536
+ height: 0;
2537
+ }
2538
+
2539
+ /* RTL override: float: inline-start is Firefox-only; use explicit direction override */
2540
+ [dir="rtl"] .blx-empty[data-placeholder]:focus::before,
2541
+ .blx-empty[dir="rtl"][data-placeholder]:focus::before {
2542
+ float: right;
2543
+ }
2544
+
2545
+ /* ── Keybindings Panel ───────────────────────────────────────── */
2546
+
2547
+ .kb-panel-toggle {
2548
+ position: fixed;
2549
+ bottom: 24px;
2550
+ right: 24px;
2551
+ z-index: 200;
2552
+ width: 40px;
2553
+ height: 40px;
2554
+ border-radius: 10px;
2555
+ border: 1px solid rgba(0, 0, 0, 0.08);
2556
+ background: #ffffff;
2557
+ color: #666;
2558
+ display: flex;
2559
+ align-items: center;
2560
+ justify-content: center;
2561
+ cursor: pointer;
2562
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
2563
+ transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
2564
+ }
2565
+
2566
+ .kb-panel-toggle:hover {
2567
+ background: #f0f0ee;
2568
+ color: #404550;
2569
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
2570
+ transform: translateY(-1px);
2571
+ }
2572
+
2573
+ .kb-panel-toggle-active {
2574
+ background: #4285f4;
2575
+ color: #fff;
2576
+ border-color: transparent;
2577
+ }
2578
+
2579
+ .kb-panel-toggle-active:hover {
2580
+ background: #3370d4;
2581
+ color: #fff;
2582
+ }
2583
+
2584
+ /* Dark theme */
2585
+ .kb-panel-toggle[data-theme="dark"] {
2586
+ background: #252530;
2587
+ color: #9da3b0;
2588
+ border-color: rgba(255, 255, 255, 0.08);
2589
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2590
+ }
2591
+
2592
+ .kb-panel-toggle[data-theme="dark"]:hover {
2593
+ background: #303040;
2594
+ color: #d0d4dc;
2595
+ }
2596
+
2597
+ .kb-panel-toggle[data-theme="dark"].kb-panel-toggle-active {
2598
+ background: #6ea8fe;
2599
+ color: #1a1a22;
2600
+ }
2601
+
2602
+ @media (prefers-color-scheme: dark) {
2603
+ .kb-panel-toggle:not([data-theme="light"]) {
2604
+ background: #252530;
2605
+ color: #9da3b0;
2606
+ border-color: rgba(255, 255, 255, 0.08);
2607
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2608
+ }
2609
+
2610
+ .kb-panel-toggle:not([data-theme="light"]):hover {
2611
+ background: #303040;
2612
+ color: #d0d4dc;
2613
+ }
2614
+
2615
+ .kb-panel-toggle:not([data-theme="light"]).kb-panel-toggle-active {
2616
+ background: #6ea8fe;
2617
+ color: #1a1a22;
2618
+ }
2619
+ }
2620
+
2621
+ /* Overlay */
2622
+ .kb-panel-overlay {
2623
+ position: fixed;
2624
+ inset: 0;
2625
+ z-index: 210;
2626
+ background: rgba(0, 0, 0, 0.15);
2627
+ opacity: 0;
2628
+ pointer-events: none;
2629
+ transition: opacity 0.25s ease;
2630
+ }
2631
+
2632
+ .kb-panel-overlay-visible {
2633
+ opacity: 1;
2634
+ pointer-events: auto;
2635
+ }
2636
+
2637
+ @media (prefers-color-scheme: dark) {
2638
+ .kb-panel-overlay {
2639
+ background: rgba(0, 0, 0, 0.4);
2640
+ }
2641
+ }
2642
+
2643
+ /* Panel */
2644
+ .kb-panel {
2645
+ position: fixed;
2646
+ top: 0;
2647
+ right: 0;
2648
+ bottom: 0;
2649
+ z-index: 220;
2650
+ width: 380px;
2651
+ max-width: 90vw;
2652
+ background: #ffffff;
2653
+ border-inline-start: 1px solid rgba(0, 0, 0, 0.06);
2654
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.06);
2655
+ transform: translateX(100%);
2656
+ transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
2657
+ display: flex;
2658
+ flex-direction: column;
2659
+ font-family: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
2660
+ color: #404550;
2661
+ }
2662
+
2663
+ .kb-panel-open {
2664
+ transform: translateX(0);
2665
+ }
2666
+
2667
+ /* Dark theme */
2668
+ .kb-panel[data-theme="dark"] {
2669
+ background: #1e1e28;
2670
+ border-color: rgba(255, 255, 255, 0.06);
2671
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.3);
2672
+ color: #d0d4dc;
2673
+ }
2674
+
2675
+ @media (prefers-color-scheme: dark) {
2676
+ .kb-panel:not([data-theme="light"]) {
2677
+ background: #1e1e28;
2678
+ border-color: rgba(255, 255, 255, 0.06);
2679
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.3);
2680
+ color: #d0d4dc;
2681
+ }
2682
+ }
2683
+
2684
+ .kb-panel-header {
2685
+ display: flex;
2686
+ align-items: center;
2687
+ justify-content: space-between;
2688
+ padding: 20px 24px 16px;
2689
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
2690
+ flex-shrink: 0;
2691
+ }
2692
+
2693
+ .kb-panel[data-theme="dark"] .kb-panel-header {
2694
+ border-color: rgba(255, 255, 255, 0.06);
2695
+ }
2696
+
2697
+ @media (prefers-color-scheme: dark) {
2698
+ .kb-panel:not([data-theme="light"]) .kb-panel-header {
2699
+ border-color: rgba(255, 255, 255, 0.06);
2700
+ }
2701
+ }
2702
+
2703
+ .kb-panel-title {
2704
+ font-size: 1rem;
2705
+ font-weight: 600;
2706
+ letter-spacing: -0.01em;
2707
+ margin: 0;
2708
+ }
2709
+
2710
+ .kb-panel-close {
2711
+ background: none;
2712
+ border: none;
2713
+ font-size: 1.3rem;
2714
+ cursor: pointer;
2715
+ color: inherit;
2716
+ opacity: 0.4;
2717
+ padding: 4px 8px;
2718
+ border-radius: 6px;
2719
+ transition: opacity 0.12s ease, background-color 0.12s ease;
2720
+ line-height: 1;
2721
+ }
2722
+
2723
+ .kb-panel-close:hover {
2724
+ opacity: 0.8;
2725
+ background: rgba(0, 0, 0, 0.05);
2726
+ }
2727
+
2728
+ .kb-panel[data-theme="dark"] .kb-panel-close:hover {
2729
+ background: rgba(255, 255, 255, 0.06);
2730
+ }
2731
+
2732
+ @media (prefers-color-scheme: dark) {
2733
+ .kb-panel:not([data-theme="light"]) .kb-panel-close:hover {
2734
+ background: rgba(255, 255, 255, 0.06);
2735
+ }
2736
+ }
2737
+
2738
+ .kb-panel-body {
2739
+ flex: 1;
2740
+ overflow-y: auto;
2741
+ padding: 8px 24px 32px;
2742
+ }
2743
+
2744
+ .kb-section-title {
2745
+ font-size: 0.7rem;
2746
+ font-weight: 600;
2747
+ text-transform: uppercase;
2748
+ letter-spacing: 0.06em;
2749
+ color: #8a8f9a;
2750
+ margin: 20px 0 8px;
2751
+ }
2752
+
2753
+ .kb-panel[data-theme="dark"] .kb-section-title {
2754
+ color: #6b7080;
2755
+ }
2756
+
2757
+ @media (prefers-color-scheme: dark) {
2758
+ .kb-panel:not([data-theme="light"]) .kb-section-title {
2759
+ color: #6b7080;
2760
+ }
2761
+ }
2762
+
2763
+ .kb-table {
2764
+ width: 100%;
2765
+ border-collapse: collapse;
2766
+ }
2767
+
2768
+ .kb-table tr {
2769
+ border-bottom: 1px solid rgba(0, 0, 0, 0.04);
2770
+ }
2771
+
2772
+ .kb-panel[data-theme="dark"] .kb-table tr {
2773
+ border-color: rgba(255, 255, 255, 0.04);
2774
+ }
2775
+
2776
+ @media (prefers-color-scheme: dark) {
2777
+ .kb-panel:not([data-theme="light"]) .kb-table tr {
2778
+ border-color: rgba(255, 255, 255, 0.04);
2779
+ }
2780
+ }
2781
+
2782
+ .kb-table tr:last-child {
2783
+ border-bottom: none;
2784
+ }
2785
+
2786
+ .kb-key-cell {
2787
+ padding: 6px 12px 6px 0;
2788
+ white-space: nowrap;
2789
+ width: 1%;
2790
+ }
2791
+
2792
+ .kb-action-cell {
2793
+ padding: 6px 0;
2794
+ font-size: 0.8rem;
2795
+ color: #666;
2796
+ }
2797
+
2798
+ .kb-panel[data-theme="dark"] .kb-action-cell {
2799
+ color: #9da3b0;
2800
+ }
2801
+
2802
+ @media (prefers-color-scheme: dark) {
2803
+ .kb-panel:not([data-theme="light"]) .kb-action-cell {
2804
+ color: #9da3b0;
2805
+ }
2806
+ }
2807
+
2808
+ .kb-panel kbd {
2809
+ display: inline-block;
2810
+ font-family: "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
2811
+ font-size: 0.7rem;
2812
+ line-height: 1;
2813
+ padding: 3px 6px;
2814
+ border-radius: 4px;
2815
+ background: rgba(0, 0, 0, 0.05);
2816
+ border: 1px solid rgba(0, 0, 0, 0.08);
2817
+ color: #404550;
2818
+ min-width: 20px;
2819
+ text-align: center;
2820
+ }
2821
+
2822
+ .kb-panel[data-theme="dark"] kbd {
2823
+ background: rgba(255, 255, 255, 0.07);
2824
+ border-color: rgba(255, 255, 255, 0.1);
2825
+ color: #d0d4dc;
2826
+ }
2827
+
2828
+ @media (prefers-color-scheme: dark) {
2829
+ .kb-panel:not([data-theme="light"]) kbd {
2830
+ background: rgba(255, 255, 255, 0.07);
2831
+ border-color: rgba(255, 255, 255, 0.1);
2832
+ color: #d0d4dc;
2833
+ }
2834
+ }
2835
+
2836
+
2837
+ /* Mobile: full-width panel */
2838
+ @media (max-width: 480px) {
2839
+ .kb-panel {
2840
+ width: 100vw;
2841
+ max-width: 100vw;
2842
+ }
2843
+ }
2844
+
2845
+ /* ── YouTube Block ─────────────────────────────────────────────── */
2846
+
2847
+ .blx-youtube {
2848
+ margin: 8px 0;
2849
+ border-radius: 10px;
2850
+ overflow: hidden;
2851
+ }
2852
+
2853
+ .blx-youtube-placeholder {
2854
+ display: flex;
2855
+ align-items: center;
2856
+ gap: 10px;
2857
+ padding: 16px 20px;
2858
+ border: 1.5px dashed var(--blx-border-input);
2859
+ border-radius: 10px;
2860
+ background: var(--blx-selected-bg);
2861
+ transition: border-color 0.15s ease;
2862
+ }
2863
+
2864
+ .blx-youtube-placeholder:hover {
2865
+ border-color: var(--blx-accent);
2866
+ }
2867
+
2868
+ .blx-youtube-icon {
2869
+ font-size: 1.4rem;
2870
+ color: var(--blx-text-faint);
2871
+ flex-shrink: 0;
2872
+ }
2873
+
2874
+ .blx-youtube-input {
2875
+ flex: 1;
2876
+ min-width: 0;
2877
+ border: 1px solid var(--blx-border-input);
2878
+ border-radius: 6px;
2879
+ padding: 6px 10px;
2880
+ font-size: 0.85rem;
2881
+ font-family: var(--blx-font-sans);
2882
+ color: var(--blx-text);
2883
+ background: var(--blx-surface);
2884
+ outline: none;
2885
+ transition: border-color 0.15s ease;
2886
+ }
2887
+
2888
+ .blx-youtube-input:focus {
2889
+ border-color: var(--blx-accent);
2890
+ }
2891
+
2892
+ .blx-youtube-input-error {
2893
+ border-color: var(--blx-danger) !important;
2894
+ animation: blx-shake 0.3s ease;
2895
+ }
2896
+
2897
+ @keyframes blx-shake {
2898
+ 0%, 100% { transform: translateX(0); }
2899
+ 25% { transform: translateX(-4px); }
2900
+ 75% { transform: translateX(4px); }
2901
+ }
2902
+
2903
+ .blx-youtube-aspect {
2904
+ position: relative;
2905
+ width: 100%;
2906
+ padding-bottom: 56.25%; /* 16:9 */
2907
+ background: #000;
2908
+ border-radius: 10px;
2909
+ overflow: hidden;
2910
+ }
2911
+
2912
+ .blx-youtube-aspect iframe {
2913
+ position: absolute;
2914
+ top: 0;
2915
+ left: 0;
2916
+ width: 100%;
2917
+ height: 100%;
2918
+ border: none;
2919
+ }
2920
+
2921
+ /* ── Image Block ───────────────────────────────────────────────── */
2922
+
2923
+ .blx-image {
2924
+ margin: 8px 0;
2925
+ }
2926
+
2927
+ .blx-image-placeholder {
2928
+ display: flex;
2929
+ flex-direction: column;
2930
+ align-items: center;
2931
+ gap: 8px;
2932
+ padding: 28px 20px;
2933
+ border: 1.5px dashed var(--blx-border-input);
2934
+ border-radius: 10px;
2935
+ background: var(--blx-selected-bg);
2936
+ transition: border-color 0.15s ease;
2937
+ cursor: default;
2938
+ }
2939
+
2940
+ .blx-image-placeholder:hover {
2941
+ border-color: var(--blx-accent);
2942
+ }
2943
+
2944
+ .blx-image-icon {
2945
+ color: var(--blx-placeholder-color);
2946
+ line-height: 0;
2947
+ }
2948
+
2949
+ .blx-image-placeholder-label {
2950
+ font-size: 0.85rem;
2951
+ color: var(--blx-text-muted);
2952
+ }
2953
+
2954
+ .blx-image-actions {
2955
+ display: flex;
2956
+ align-items: center;
2957
+ gap: 10px;
2958
+ margin-top: 4px;
2959
+ }
2960
+
2961
+ .blx-image-upload-btn {
2962
+ display: inline-flex;
2963
+ align-items: center;
2964
+ gap: 4px;
2965
+ padding: 5px 12px;
2966
+ border: none;
2967
+ border-radius: 6px;
2968
+ background: var(--blx-accent);
2969
+ color: #fff;
2970
+ font-size: 0.8rem;
2971
+ font-family: var(--blx-font-sans);
2972
+ cursor: pointer;
2973
+ transition: background-color 0.15s ease;
2974
+ }
2975
+
2976
+ .blx-image-upload-btn:hover {
2977
+ background: var(--blx-accent-hover);
2978
+ }
2979
+
2980
+ .blx-image-url-input {
2981
+ min-width: 180px;
2982
+ border: 1px solid var(--blx-border-input);
2983
+ border-radius: 6px;
2984
+ padding: 5px 10px;
2985
+ font-size: 0.8rem;
2986
+ font-family: var(--blx-font-sans);
2987
+ color: var(--blx-text);
2988
+ background: var(--blx-surface);
2989
+ outline: none;
2990
+ transition: border-color 0.15s ease;
2991
+ }
2992
+
2993
+ .blx-image-url-input:focus {
2994
+ border-color: var(--blx-accent);
2995
+ }
2996
+
2997
+ .blx-image-figure {
2998
+ margin: 0;
2999
+ display: flex;
3000
+ flex-direction: column;
3001
+ align-items: center;
3002
+ }
3003
+
3004
+ .blx-image-container {
3005
+ position: relative;
3006
+ max-width: 100%;
3007
+ display: inline-block;
3008
+ }
3009
+
3010
+ .blx-image-img {
3011
+ display: block;
3012
+ max-width: 100%;
3013
+ height: auto;
3014
+ border-radius: 8px;
3015
+ }
3016
+
3017
+ .blx-image-resize-handle {
3018
+ position: absolute;
3019
+ right: -4px;
3020
+ top: 0;
3021
+ bottom: 0;
3022
+ width: 8px;
3023
+ cursor: ew-resize;
3024
+ opacity: 0;
3025
+ transition: opacity 0.15s ease;
3026
+ }
3027
+
3028
+ .blx-image-resize-handle::after {
3029
+ content: "";
3030
+ position: absolute;
3031
+ right: 2px;
3032
+ top: 50%;
3033
+ transform: translateY(-50%);
3034
+ width: 4px;
3035
+ height: 32px;
3036
+ border-radius: 2px;
3037
+ background: var(--blx-accent);
3038
+ }
3039
+
3040
+ .blx-image-container:hover .blx-image-resize-handle {
3041
+ opacity: 1;
3042
+ }
3043
+
3044
+ .blx-image-caption {
3045
+ margin-top: 6px;
3046
+ font-size: 0.8rem;
3047
+ color: var(--blx-text-muted);
3048
+ text-align: center;
3049
+ min-height: 1.4em;
3050
+ outline: none;
3051
+ max-width: 100%;
3052
+ }
3053
+
3054
+ .blx-image-caption:empty::before {
3055
+ content: attr(data-placeholder);
3056
+ color: var(--blx-placeholder-color);
3057
+ pointer-events: none;
3058
+ }
3059
+
3060
+ /* Placeholder highlighted when image is dragged over it */
3061
+ .blx-image-placeholder-dragover {
3062
+ border-color: var(--blx-accent) !important;
3063
+ background: var(--blx-accent-bg) !important;
3064
+ }
3065
+
3066
+ /* Drop zone shown between blocks when dragging an image file from OS */
3067
+ .blx-image-drop-zone {
3068
+ display: flex;
3069
+ align-items: center;
3070
+ justify-content: center;
3071
+ gap: 8px;
3072
+ padding: 16px;
3073
+ border: 1.5px dashed var(--blx-accent);
3074
+ border-radius: 10px;
3075
+ background: var(--blx-accent-bg);
3076
+ color: var(--blx-accent);
3077
+ font-size: 0.85rem;
3078
+ font-family: var(--blx-font-sans);
3079
+ pointer-events: none;
3080
+ animation: blx-drop-zone-pulse 1.5s ease-in-out infinite;
3081
+ }
3082
+
3083
+ @keyframes blx-drop-zone-pulse {
3084
+ 0%, 100% { opacity: 0.7; }
3085
+ 50% { opacity: 1; }
3086
+ }
3087
+
3088
+ /* Full-editor overlay when dragging unsupported files */
3089
+ .blx-drop-reject-overlay {
3090
+ position: absolute;
3091
+ inset: 0;
3092
+ z-index: 50;
3093
+ pointer-events: none;
3094
+
3095
+ /* Blur content so text reads clearly without needing shadows */
3096
+ background: transparent;
3097
+ backdrop-filter: blur(6px);
3098
+ -webkit-backdrop-filter: blur(6px);
3099
+
3100
+ /* Pill message anchored center-left */
3101
+ display: flex;
3102
+ align-items: center;
3103
+ justify-content: flex-start;
3104
+ padding-left: max(var(--blx-gutter, 64px), 24px);
3105
+
3106
+ animation: blx-reject-fade-in 0.15s ease-out both;
3107
+ }
3108
+
3109
+ @keyframes blx-reject-fade-in {
3110
+ from { opacity: 0; backdrop-filter: blur(0); }
3111
+ to { opacity: 1; backdrop-filter: blur(6px); }
3112
+ }
3113
+
3114
+
3115
+ /* Message text */
3116
+ .blx-drop-reject-msg {
3117
+ font-family: var(--blx-font-sans);
3118
+ font-size: 0.95rem;
3119
+ font-weight: 600;
3120
+ letter-spacing: 0.01em;
3121
+ color: var(--blx-text, #404550);
3122
+ white-space: nowrap;
3123
+ }
3124
+
3125
+
3126
+ /* Animated chevron nudging leftward */
3127
+ .blx-drop-reject-nudge {
3128
+ display: inline-flex;
3129
+ align-items: center;
3130
+ color: var(--blx-text-muted);
3131
+ margin-right: 4px;
3132
+ animation: blx-nudge-left 1s cubic-bezier(0.37, 0, 0.63, 1) infinite;
3133
+ }
3134
+
3135
+ @keyframes blx-nudge-left {
3136
+ 0%, 100% { transform: translateX(0); opacity: 0.5; }
3137
+ 50% { transform: translateX(-6px); opacity: 1; }
3138
+ }
3139
+
3140
+ /* ── Replay Bar ───────────────────────────────────────────────── */
3141
+
3142
+ .blx-replay-mode [contenteditable] {
3143
+ cursor: default;
3144
+ }
3145
+
3146
+ .blx-replay-bar {
3147
+ position: sticky;
3148
+ bottom: 0;
3149
+ left: 0;
3150
+ right: 0;
3151
+ z-index: 150;
3152
+ display: flex;
3153
+ align-items: center;
3154
+ gap: 12px;
3155
+ padding: 10px 16px;
3156
+ background: var(--blx-surface);
3157
+ border-top: 1px solid var(--blx-border-input);
3158
+ box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.06);
3159
+ animation: blx-replay-bar-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
3160
+ }
3161
+
3162
+ @keyframes blx-replay-bar-in {
3163
+ from {
3164
+ opacity: 0;
3165
+ transform: translateY(8px);
3166
+ }
3167
+ to {
3168
+ opacity: 1;
3169
+ transform: translateY(0);
3170
+ }
3171
+ }
3172
+
3173
+ .blx-replay-controls {
3174
+ display: flex;
3175
+ align-items: center;
3176
+ gap: 4px;
3177
+ flex-shrink: 0;
3178
+ }
3179
+
3180
+ .blx-replay-title {
3181
+ font-size: 0.72rem;
3182
+ font-weight: 600;
3183
+ text-transform: uppercase;
3184
+ letter-spacing: 0.06em;
3185
+ color: var(--blx-text-muted);
3186
+ margin-inline-end: 4px;
3187
+ user-select: none;
3188
+ }
3189
+
3190
+ .blx-replay-btn {
3191
+ display: inline-flex;
3192
+ align-items: center;
3193
+ justify-content: center;
3194
+ width: 28px;
3195
+ height: 28px;
3196
+ border: none;
3197
+ background: none;
3198
+ border-radius: 6px;
3199
+ cursor: pointer;
3200
+ color: var(--blx-text-muted);
3201
+ transition: background-color 0.1s ease, color 0.1s ease;
3202
+ }
3203
+
3204
+ .blx-replay-btn:hover:not(:disabled) {
3205
+ background: var(--blx-hover-bg);
3206
+ color: var(--blx-text);
3207
+ }
3208
+
3209
+ .blx-replay-btn:disabled {
3210
+ opacity: 0.35;
3211
+ cursor: default;
3212
+ }
3213
+
3214
+ .blx-replay-play-btn {
3215
+ width: 32px;
3216
+ height: 32px;
3217
+ border-radius: 50%;
3218
+ background: var(--blx-accent-bg);
3219
+ color: var(--blx-accent);
3220
+ }
3221
+
3222
+ .blx-replay-play-btn:hover:not(:disabled) {
3223
+ background: var(--blx-accent);
3224
+ color: #fff;
3225
+ }
3226
+
3227
+ .blx-replay-exit-btn {
3228
+ display: inline-flex;
3229
+ align-items: center;
3230
+ justify-content: center;
3231
+ width: 26px;
3232
+ height: 26px;
3233
+ border: none;
3234
+ background: none;
3235
+ border-radius: 6px;
3236
+ cursor: pointer;
3237
+ color: var(--blx-text-faint);
3238
+ margin-inline-end: 2px;
3239
+ transition: background-color 0.1s ease, color 0.1s ease;
3240
+ }
3241
+
3242
+ .blx-replay-exit-btn:hover {
3243
+ background: var(--blx-hover-bg);
3244
+ color: var(--blx-text);
3245
+ }
3246
+
3247
+ .blx-replay-slider-wrap {
3248
+ flex: 1;
3249
+ display: flex;
3250
+ align-items: center;
3251
+ gap: 10px;
3252
+ min-width: 0;
3253
+ }
3254
+
3255
+ .blx-replay-slider {
3256
+ flex: 1;
3257
+ min-width: 0;
3258
+ height: 4px;
3259
+ -webkit-appearance: none;
3260
+ appearance: none;
3261
+ background: var(--blx-border-input);
3262
+ border-radius: 2px;
3263
+ outline: none;
3264
+ cursor: pointer;
3265
+ transition: background-color 0.15s ease;
3266
+ }
3267
+
3268
+ .blx-replay-slider::-webkit-slider-thumb {
3269
+ -webkit-appearance: none;
3270
+ appearance: none;
3271
+ width: 14px;
3272
+ height: 14px;
3273
+ border-radius: 50%;
3274
+ background: var(--blx-accent);
3275
+ border: 2px solid var(--blx-surface);
3276
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
3277
+ cursor: grab;
3278
+ transition: transform 0.1s ease, box-shadow 0.1s ease;
3279
+ }
3280
+
3281
+ .blx-replay-slider::-webkit-slider-thumb:hover {
3282
+ transform: scale(1.2);
3283
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
3284
+ }
3285
+
3286
+ .blx-replay-slider::-webkit-slider-thumb:active {
3287
+ cursor: grabbing;
3288
+ transform: scale(1.1);
3289
+ }
3290
+
3291
+ .blx-replay-slider::-moz-range-thumb {
3292
+ width: 14px;
3293
+ height: 14px;
3294
+ border-radius: 50%;
3295
+ background: var(--blx-accent);
3296
+ border: 2px solid var(--blx-surface);
3297
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
3298
+ cursor: grab;
3299
+ }
3300
+
3301
+ .blx-replay-pos {
3302
+ font-size: 0.75rem;
3303
+ font-variant-numeric: tabular-nums;
3304
+ color: var(--blx-text-muted);
3305
+ white-space: nowrap;
3306
+ min-width: 60px;
3307
+ text-align: right;
3308
+ user-select: none;
3309
+ }
3310
+
3311
+ /* Mobile: bigger touch targets */
3312
+ @media (pointer: coarse) {
3313
+ .blx-replay-btn {
3314
+ width: 40px;
3315
+ height: 40px;
3316
+ }
3317
+
3318
+ .blx-replay-play-btn {
3319
+ width: 44px;
3320
+ height: 44px;
3321
+ }
3322
+
3323
+ .blx-replay-exit-btn {
3324
+ width: 36px;
3325
+ height: 36px;
3326
+ }
3327
+
3328
+ .blx-replay-slider {
3329
+ height: 6px;
3330
+ }
3331
+
3332
+ .blx-replay-slider::-webkit-slider-thumb {
3333
+ width: 20px;
3334
+ height: 20px;
3335
+ }
3336
+
3337
+ .blx-replay-slider::-moz-range-thumb {
3338
+ width: 20px;
3339
+ height: 20px;
3340
+ }
3341
+ }
3342
+
3343
+ /* ── Remote Cursors (Multiplayer — Overlay) ──────────────────── */
3344
+
3345
+ /* Overlay container: sits on top of the editor, pointer-transparent */
3346
+ .blx-remote-cursor-overlay {
3347
+ position: absolute;
3348
+ inset: 0;
3349
+ pointer-events: none;
3350
+ z-index: 5;
3351
+ overflow: visible;
3352
+ }
3353
+
3354
+ /* Caret line — absolutely positioned thin bar (steady when idle) */
3355
+ .blx-remote-cursor {
3356
+ position: absolute;
3357
+ width: 0;
3358
+ border-inline-start: 2px solid var(--blx-remote-cursor-color, currentColor);
3359
+ pointer-events: none;
3360
+ user-select: none;
3361
+ }
3362
+
3363
+ /* Active cursor: blink animation + label visible */
3364
+ .blx-remote-cursor--active {
3365
+ animation: blx-remote-cursor-blink 1.1s step-end infinite;
3366
+ }
3367
+
3368
+ @keyframes blx-remote-cursor-blink {
3369
+ 0%, 100% { opacity: 1; }
3370
+ 50% { opacity: 0.3; }
3371
+ }
3372
+
3373
+ /* Safety net: hide label on idle cursors (renderer already omits it) */
3374
+ .blx-remote-cursor:not(.blx-remote-cursor--active) .blx-remote-cursor-label {
3375
+ display: none;
3376
+ }
3377
+
3378
+ /* Name label floats above the caret */
3379
+ .blx-remote-cursor-label {
3380
+ position: absolute;
3381
+ bottom: 100%;
3382
+ inset-inline-start: -1px;
3383
+ font-size: 0.6rem;
3384
+ font-weight: 600;
3385
+ font-family: var(--blx-font-sans);
3386
+ letter-spacing: 0.02em;
3387
+ line-height: 1;
3388
+ padding: 2px 5px;
3389
+ border-radius: 3px 3px 3px 0;
3390
+ color: #fff;
3391
+ white-space: nowrap;
3392
+ pointer-events: none;
3393
+ user-select: none;
3394
+ opacity: 0.9;
3395
+ z-index: 10;
3396
+ animation: blx-remote-label-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
3397
+ }
3398
+
3399
+ @keyframes blx-remote-label-in {
3400
+ from {
3401
+ opacity: 0;
3402
+ transform: translateY(2px);
3403
+ }
3404
+ to {
3405
+ opacity: 0.9;
3406
+ transform: translateY(0);
3407
+ }
3408
+ }
3409
+
3410
+ /* Selection highlight — semi-transparent rectangle per line fragment.
3411
+ getClientRects() returns tight glyph rects — pad vertically to match
3412
+ the native browser selection feel. */
3413
+ .blx-remote-cursor-selection {
3414
+ position: absolute;
3415
+ opacity: 0.18;
3416
+ pointer-events: none;
3417
+ user-select: none;
3418
+ border-radius: 2px;
3419
+ margin-top: -2px;
3420
+ padding-bottom: 4px;
3421
+ }
3422
+
3423
+ /* Block selection border — left bar indicator for multi-block selections */
3424
+ .blx-remote-block-border {
3425
+ position: absolute;
3426
+ width: 3px;
3427
+ border-radius: 1.5px;
3428
+ pointer-events: none;
3429
+ user-select: none;
3430
+ opacity: 0.6;
3431
+ }
3432
+
3433
+ /* During replay, don't blink — just show steady cursors */
3434
+ .blx-replay-mode .blx-remote-cursor {
3435
+ animation: none;
3436
+ opacity: 1;
3437
+ }
3438
+
3439
+ /* ── Replay Toggle Button ──────────────────────────────────────── */
3440
+
3441
+ .blx-replay-toggle-btn {
3442
+ position: fixed;
3443
+ bottom: 20px;
3444
+ right: 20px;
3445
+ z-index: 100;
3446
+ display: flex;
3447
+ align-items: center;
3448
+ justify-content: center;
3449
+ width: 40px;
3450
+ height: 40px;
3451
+ border: 1px solid var(--blx-border-input);
3452
+ background: var(--blx-surface);
3453
+ border-radius: 50%;
3454
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
3455
+ cursor: pointer;
3456
+ color: var(--blx-text-muted);
3457
+ transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
3458
+ }
3459
+
3460
+ .blx-replay-toggle-btn:hover {
3461
+ background: var(--blx-accent-bg);
3462
+ color: var(--blx-accent);
3463
+ border-color: var(--blx-accent);
3464
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
3465
+ transform: scale(1.05);
3466
+ }
3467
+
3468
+ .blx-replay-mode .blx-replay-toggle-btn {
3469
+ display: none;
3470
+ }
3471
+
3472
+ /* ── Search Panel ──────────────────────────────────────────────── */
3473
+
3474
+ .blx-search-panel {
3475
+ position: fixed;
3476
+ top: 8px;
3477
+ right: 8px;
3478
+ z-index: 200;
3479
+ display: flex;
3480
+ flex-direction: row;
3481
+ align-items: flex-start;
3482
+ gap: 4px;
3483
+ padding: 6px 8px;
3484
+ background: var(--blx-surface);
3485
+ border: 1px solid var(--blx-border);
3486
+ border-radius: 10px;
3487
+ box-shadow: var(--blx-shadow);
3488
+ animation: blx-search-panel-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);
3489
+ }
3490
+
3491
+ @keyframes blx-search-panel-in {
3492
+ from {
3493
+ opacity: 0;
3494
+ transform: translateY(-8px);
3495
+ }
3496
+ to {
3497
+ opacity: 1;
3498
+ transform: translateY(0);
3499
+ }
3500
+ }
3501
+
3502
+ /* Expand/collapse chevron */
3503
+ .blx-search-expand-btn {
3504
+ display: inline-flex;
3505
+ align-items: center;
3506
+ justify-content: center;
3507
+ flex-shrink: 0;
3508
+ width: 22px;
3509
+ height: 28px;
3510
+ border: none;
3511
+ border-radius: 4px;
3512
+ background: transparent;
3513
+ color: var(--blx-text-faint);
3514
+ cursor: pointer;
3515
+ transition: color 0.1s ease, transform 0.15s ease;
3516
+ padding: 0;
3517
+ }
3518
+
3519
+ .blx-search-expand-btn svg {
3520
+ transform: rotate(-90deg);
3521
+ transition: transform 0.15s cubic-bezier(0.16, 1, 0.3, 1);
3522
+ }
3523
+
3524
+ .blx-search-expand-btn:hover {
3525
+ color: var(--blx-text);
3526
+ }
3527
+
3528
+ .blx-search-expand-btn-active svg {
3529
+ transform: rotate(0deg);
3530
+ }
3531
+
3532
+ /* Body: stacks search + replace rows */
3533
+ .blx-search-body {
3534
+ display: flex;
3535
+ flex-direction: column;
3536
+ gap: 4px;
3537
+ }
3538
+
3539
+ .blx-search-row {
3540
+ display: flex;
3541
+ align-items: center;
3542
+ gap: 6px;
3543
+ }
3544
+
3545
+ .blx-search-input-wrap {
3546
+ display: flex;
3547
+ align-items: center;
3548
+ border: 1px solid var(--blx-border-input);
3549
+ border-radius: 6px;
3550
+ background: var(--blx-surface);
3551
+ padding: 0 4px 0 0;
3552
+ transition: border-color 0.15s ease;
3553
+ }
3554
+
3555
+ .blx-search-input-wrap:focus-within {
3556
+ border-color: var(--blx-accent);
3557
+ }
3558
+
3559
+ .blx-search-input {
3560
+ min-width: 180px;
3561
+ border: none;
3562
+ padding: 5px 8px;
3563
+ font-size: 0.8rem;
3564
+ font-family: var(--blx-font-sans);
3565
+ color: var(--blx-text);
3566
+ background: transparent;
3567
+ outline: none;
3568
+ }
3569
+
3570
+ .blx-search-option-btn {
3571
+ display: inline-flex;
3572
+ align-items: center;
3573
+ justify-content: center;
3574
+ width: 24px;
3575
+ height: 24px;
3576
+ border: none;
3577
+ border-radius: 4px;
3578
+ background: transparent;
3579
+ color: var(--blx-text-faint);
3580
+ font-size: 0.7rem;
3581
+ font-family: var(--blx-font-mono);
3582
+ font-weight: 600;
3583
+ cursor: pointer;
3584
+ transition: background-color 0.1s ease, color 0.1s ease;
3585
+ }
3586
+
3587
+ .blx-search-option-btn:hover {
3588
+ background: var(--blx-hover-bg);
3589
+ color: var(--blx-text);
3590
+ }
3591
+
3592
+ .blx-search-option-btn-active {
3593
+ background: var(--blx-accent-bg);
3594
+ color: var(--blx-accent);
3595
+ }
3596
+
3597
+ .blx-search-count {
3598
+ font-size: 0.75rem;
3599
+ color: var(--blx-text-muted);
3600
+ white-space: nowrap;
3601
+ min-width: 60px;
3602
+ text-align: center;
3603
+ }
3604
+
3605
+ .blx-search-nav-btn {
3606
+ display: inline-flex;
3607
+ align-items: center;
3608
+ justify-content: center;
3609
+ width: 26px;
3610
+ height: 26px;
3611
+ border: none;
3612
+ border-radius: 5px;
3613
+ background: transparent;
3614
+ color: var(--blx-text-muted);
3615
+ font-size: 0.85rem;
3616
+ cursor: pointer;
3617
+ transition: background-color 0.1s ease;
3618
+ }
3619
+
3620
+ .blx-search-nav-btn:hover {
3621
+ background: var(--blx-hover-bg);
3622
+ color: var(--blx-text);
3623
+ }
3624
+
3625
+ .blx-search-close-btn {
3626
+ display: inline-flex;
3627
+ align-items: center;
3628
+ justify-content: center;
3629
+ width: 26px;
3630
+ height: 26px;
3631
+ border: none;
3632
+ border-radius: 5px;
3633
+ background: transparent;
3634
+ color: var(--blx-text-muted);
3635
+ font-size: 1rem;
3636
+ cursor: pointer;
3637
+ transition: background-color 0.1s ease;
3638
+ }
3639
+
3640
+ .blx-search-close-btn:hover {
3641
+ background: var(--blx-hover-bg);
3642
+ color: var(--blx-text);
3643
+ }
3644
+
3645
+ /* Replace row: hidden by default, shown via JS class toggle */
3646
+ .blx-search-replace-row {
3647
+ display: none;
3648
+ align-items: center;
3649
+ gap: 6px;
3650
+ }
3651
+
3652
+ .blx-search-replace-row-visible {
3653
+ display: flex;
3654
+ }
3655
+
3656
+ .blx-search-replace-input {
3657
+ flex: 1;
3658
+ min-width: 0;
3659
+ border: none;
3660
+ padding: 5px 8px;
3661
+ font-size: 0.8rem;
3662
+ font-family: var(--blx-font-sans);
3663
+ color: var(--blx-text);
3664
+ background: transparent;
3665
+ outline: none;
3666
+ }
3667
+
3668
+ .blx-search-replace-btn {
3669
+ padding: 4px 10px;
3670
+ border: 1px solid var(--blx-border-input);
3671
+ border-radius: 5px;
3672
+ background: var(--blx-surface);
3673
+ color: var(--blx-text);
3674
+ font-size: 0.75rem;
3675
+ font-family: var(--blx-font-sans);
3676
+ cursor: pointer;
3677
+ white-space: nowrap;
3678
+ transition: background-color 0.1s ease, border-color 0.1s ease;
3679
+ }
3680
+
3681
+ .blx-search-replace-btn:hover {
3682
+ background: var(--blx-hover-bg);
3683
+ border-color: var(--blx-accent);
3684
+ }
3685
+
3686
+ /* Search match highlights */
3687
+ mark.blx-search-match {
3688
+ background-color: var(--blx-search-match-bg, rgba(255, 200, 0, 0.3));
3689
+ color: inherit;
3690
+ border-radius: 2px;
3691
+ padding: 0;
3692
+ }
3693
+
3694
+ mark.blx-search-highlight {
3695
+ background-color: var(--blx-search-highlight-bg, rgba(255, 160, 0, 0.6));
3696
+ color: inherit;
3697
+ border-radius: 2px;
3698
+ outline: 2px solid var(--blx-accent);
3699
+ outline-offset: 1px;
3700
+ padding: 0;
3701
+ }
3702
+
3703
+ /* Mobile: touch targets */
3704
+ @media (pointer: coarse) {
3705
+ .blx-search-nav-btn,
3706
+ .blx-search-close-btn {
3707
+ width: 44px;
3708
+ height: 44px;
3709
+ }
3710
+
3711
+ .blx-search-option-btn {
3712
+ width: 36px;
3713
+ height: 36px;
3714
+ }
3715
+ }
3716
+
3717
+ /* ── Table of Contents ──────────────────────────────────────── */
3718
+
3719
+ .blx-toc {
3720
+ position: fixed;
3721
+ right: 0;
3722
+ top: 0;
3723
+ bottom: 0;
3724
+ /* 40px left padding creates invisible hover zone so user doesn't need to
3725
+ precisely target the thin minimap lines to trigger the TOC */
3726
+ padding-left: 40px;
3727
+ pointer-events: auto;
3728
+ z-index: 50;
3729
+ }
3730
+
3731
+ .blx-toc-empty {
3732
+ display: none;
3733
+ }
3734
+
3735
+ /* ── Sticky track — vertically centered, right-aligned ── */
3736
+
3737
+ .blx-toc-track {
3738
+ position: absolute;
3739
+ right: 0;
3740
+ top: 50%;
3741
+ transform: translateY(-50%);
3742
+ display: flex;
3743
+ flex-direction: column;
3744
+ align-items: flex-end;
3745
+ padding: 12px 8px 12px 0;
3746
+ max-height: 70vh;
3747
+ overflow: visible;
3748
+ }
3749
+
3750
+ /* ── ToC Entry (button) ── */
3751
+
3752
+ .blx-toc-entry {
3753
+ position: relative;
3754
+ display: flex;
3755
+ align-items: center;
3756
+ justify-content: flex-end;
3757
+ gap: 0;
3758
+ width: auto;
3759
+ border: none;
3760
+ background: none;
3761
+ /* vertical padding is set dynamically by JS for uniform spacing */
3762
+ padding: 0;
3763
+ cursor: pointer;
3764
+ outline: none;
3765
+ flex-shrink: 0;
3766
+ /* Allow label to expand leftward on hover */
3767
+ white-space: nowrap;
3768
+ /* Ensure generous hit area centered around the line */
3769
+ min-height: 14px;
3770
+ }
3771
+
3772
+ /* Invisible hit-target extension — makes thin lines easier to click */
3773
+ .blx-toc-entry::after {
3774
+ content: "";
3775
+ position: absolute;
3776
+ inset: -6px -8px;
3777
+ }
3778
+
3779
+ .blx-toc-entry:focus-visible {
3780
+ outline: 2px solid var(--blx-accent);
3781
+ outline-offset: 2px;
3782
+ border-radius: 3px;
3783
+ }
3784
+
3785
+ /* ── ToC Line (minimap bar) ── */
3786
+
3787
+ .blx-toc-line {
3788
+ flex-shrink: 0;
3789
+ display: block;
3790
+ border-radius: 99px;
3791
+ background: var(--blx-text-faint);
3792
+ /* width, height, opacity set by JS magnification */
3793
+ width: 16px;
3794
+ height: 2.5px;
3795
+ opacity: 0.45;
3796
+ transition: width 0.2s cubic-bezier(0.16, 1, 0.3, 1),
3797
+ height 0.2s cubic-bezier(0.16, 1, 0.3, 1),
3798
+ opacity 0.2s ease,
3799
+ background-color 0.2s ease;
3800
+ }
3801
+
3802
+ /* Active heading — accent color line */
3803
+ .blx-toc-entry-active .blx-toc-line {
3804
+ background: var(--blx-accent);
3805
+ }
3806
+
3807
+ /* ── ToC Label (heading title — hidden until individual entry hover) ── */
3808
+
3809
+ .blx-toc-label {
3810
+ position: absolute;
3811
+ right: calc(100% + 6px);
3812
+ top: 50%;
3813
+ transform: translateY(-50%);
3814
+ max-width: 0;
3815
+ overflow: hidden;
3816
+ font-size: 0.7rem;
3817
+ font-family: var(--blx-font-sans);
3818
+ font-weight: 450;
3819
+ color: var(--blx-text-muted);
3820
+ white-space: nowrap;
3821
+ text-overflow: ellipsis;
3822
+ text-align: end;
3823
+ opacity: 0;
3824
+ padding-inline-end: 0;
3825
+ pointer-events: none;
3826
+ border-radius: 4px;
3827
+ /* background set dynamically by JS based on browse factor (Gaussian distance to cursor) */
3828
+ transition: max-width 0.25s cubic-bezier(0.16, 1, 0.3, 1),
3829
+ opacity 0.2s ease,
3830
+ padding-inline-end 0.2s ease,
3831
+ background 0.15s ease;
3832
+ }
3833
+
3834
+ /* Reveal label on the entry nearest to cursor (driven by JS, matches click target) */
3835
+ .blx-toc-entry-browsed .blx-toc-label {
3836
+ max-width: 180px;
3837
+ opacity: 1;
3838
+ padding: 2px 8px 2px 6px;
3839
+ background: var(--blx-surface, #ffffff);
3840
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
3841
+ }
3842
+
3843
+ .blx-toc-entry-active .blx-toc-label {
3844
+ color: var(--blx-accent);
3845
+ font-weight: 550;
3846
+ }
3847
+
3848
+ /* ── ToC Emoji — sits between label and line ── */
3849
+
3850
+ .blx-toc-emoji {
3851
+ flex-shrink: 0;
3852
+ font-size: 0;
3853
+ line-height: 1;
3854
+ filter: grayscale(1);
3855
+ opacity: 0;
3856
+ margin-inline-end: 0;
3857
+ transition: font-size 0.2s cubic-bezier(0.16, 1, 0.3, 1),
3858
+ opacity 0.2s ease,
3859
+ filter 0.2s ease,
3860
+ margin-inline-end 0.2s ease;
3861
+ }
3862
+
3863
+ /* When TOC is hovered, show emoji faintly */
3864
+ .blx-toc-hovered .blx-toc-emoji {
3865
+ font-size: 0.6rem;
3866
+ opacity: 0.25;
3867
+ margin-inline-end: 3px;
3868
+ }
3869
+
3870
+ /* Hide emoji on browsed entry (label is visible instead) */
3871
+ .blx-toc-entry-browsed .blx-toc-emoji {
3872
+ font-size: 0;
3873
+ opacity: 0;
3874
+ margin-inline-end: 0;
3875
+ }
3876
+
3877
+ /* ── ToC navigation pulse — confirms which heading was jumped to ── */
3878
+
3879
+ @keyframes blx-toc-pulse {
3880
+ 0% { background-color: transparent; }
3881
+ 15% { background-color: var(--blx-accent-faint, rgba(59, 130, 246, 0.1)); }
3882
+ 100% { background-color: transparent; }
3883
+ }
3884
+
3885
+ .blx-toc-pulse {
3886
+ animation: blx-toc-pulse 1.2s ease-out;
3887
+ border-radius: 4px;
3888
+ }
3889
+
3890
+ /* ── Responsive: hide on small screens and touch devices ── */
3891
+
3892
+ @media (max-width: 900px) {
3893
+ .blx-toc {
3894
+ display: none;
3895
+ }
3896
+ }
3897
+
3898
+ @media (pointer: coarse) {
3899
+ .blx-toc {
3900
+ display: none;
3901
+ }
3902
+ }
3903
+
3904
+ /* ── Table ─────────────────────────────────────────────────── */
3905
+
3906
+ .blx-table-wrapper {
3907
+ position: relative;
3908
+ margin: 8px 0;
3909
+ outline: none;
3910
+ }
3911
+
3912
+ .blx-table-inner {
3913
+ overflow: visible;
3914
+ position: relative;
3915
+ }
3916
+
3917
+ .blx-table {
3918
+ width: 100%;
3919
+ border-collapse: collapse;
3920
+ border: 1px solid var(--blx-border-input);
3921
+ font-size: var(--blx-font-base-size);
3922
+ line-height: var(--blx-lh-body);
3923
+ table-layout: fixed;
3924
+ }
3925
+
3926
+ .blx-table-row {
3927
+ border-bottom: 1px solid var(--blx-border-input);
3928
+ }
3929
+
3930
+ .blx-table-row:last-child {
3931
+ border-bottom: none;
3932
+ }
3933
+
3934
+ .blx-table-cell {
3935
+ border: 1px solid var(--blx-border-input);
3936
+ border-radius: 0;
3937
+ padding: 6px 10px;
3938
+ min-width: 60px;
3939
+ min-height: 1.5em;
3940
+ vertical-align: top;
3941
+ outline: none;
3942
+ word-wrap: break-word;
3943
+ }
3944
+
3945
+ .blx-table-row:first-child .blx-table-cell {
3946
+ font-weight: 600;
3947
+ background: var(--blx-hover-bg);
3948
+ }
3949
+
3950
+ .blx-table-cell:focus {
3951
+ outline: 2px solid var(--blx-accent);
3952
+ outline-offset: -2px;
3953
+ border-radius: 0;
3954
+ z-index: 2;
3955
+ position: relative;
3956
+ }
3957
+
3958
+ /* ── Table selection overlay ──────────────────────────────── */
3959
+
3960
+ .blx-table-selection-overlay {
3961
+ position: absolute;
3962
+ box-sizing: border-box;
3963
+ border: 2px solid var(--blx-accent);
3964
+ background: var(--blx-selection-bg);
3965
+ pointer-events: none;
3966
+ z-index: 1;
3967
+ display: none;
3968
+ }
3969
+
3970
+ /* ── Table focus handles (edge/corner drag targets) ───────── */
3971
+
3972
+ .blx-table-focus-handle {
3973
+ position: absolute;
3974
+ pointer-events: auto;
3975
+ z-index: 3;
3976
+ background: transparent;
3977
+ }
3978
+
3979
+ .blx-table-focus-handle-top,
3980
+ .blx-table-focus-handle-bottom {
3981
+ cursor: ns-resize;
3982
+ }
3983
+
3984
+ .blx-table-focus-handle-left,
3985
+ .blx-table-focus-handle-right {
3986
+ cursor: ew-resize;
3987
+ }
3988
+
3989
+ .blx-table-focus-handle-top-left,
3990
+ .blx-table-focus-handle-bottom-right {
3991
+ cursor: nwse-resize;
3992
+ }
3993
+
3994
+ .blx-table-focus-handle-top-right,
3995
+ .blx-table-focus-handle-bottom-left {
3996
+ cursor: nesw-resize;
3997
+ }
3998
+
3999
+ /* ── Table row / column pill widgets ──────────────────────── */
4000
+
4001
+ .blx-table-row-widget,
4002
+ .blx-table-col-widget,
4003
+ .blx-table-add-row-widget,
4004
+ .blx-table-add-col-widget {
4005
+ position: absolute;
4006
+ display: flex;
4007
+ align-items: center;
4008
+ justify-content: center;
4009
+ gap: 1.5px;
4010
+ border: none;
4011
+ border-radius: 3px;
4012
+ background: var(--blx-accent);
4013
+ cursor: pointer;
4014
+ padding: 0;
4015
+ opacity: 0;
4016
+ pointer-events: none;
4017
+ transition: opacity 0.12s ease;
4018
+ z-index: 4;
4019
+ }
4020
+
4021
+ .blx-table-widget-dot {
4022
+ width: 2px;
4023
+ height: 2px;
4024
+ border-radius: 50%;
4025
+ background: #fff;
4026
+ flex-shrink: 0;
4027
+ }
4028
+
4029
+ .blx-table-row-widget.blx-table-widget-visible,
4030
+ .blx-table-col-widget.blx-table-widget-visible,
4031
+ .blx-table-row-widget.blx-table-widget-active,
4032
+ .blx-table-col-widget.blx-table-widget-active,
4033
+ .blx-table-add-row-widget.blx-table-widget-visible,
4034
+ .blx-table-add-col-widget.blx-table-widget-visible {
4035
+ opacity: 1;
4036
+ pointer-events: auto;
4037
+ }
4038
+
4039
+ .blx-table-row-widget:hover,
4040
+ .blx-table-col-widget:hover,
4041
+ .blx-table-add-row-widget:hover,
4042
+ .blx-table-add-col-widget:hover {
4043
+ background: var(--blx-accent-hover);
4044
+ }
4045
+
4046
+ /* Row widget: vertical dots, centered on the table's left border */
4047
+ .blx-table-row-widget {
4048
+ left: 0;
4049
+ width: 10px;
4050
+ height: 14px;
4051
+ flex-direction: column;
4052
+ transform: translate(-50%, -50%);
4053
+ }
4054
+
4055
+ /* Column widget: horizontal dots, centered on the table's top border */
4056
+ .blx-table-col-widget {
4057
+ top: 0;
4058
+ width: 14px;
4059
+ height: 10px;
4060
+ flex-direction: row;
4061
+ transform: translate(-50%, -50%);
4062
+ }
4063
+
4064
+ /* Add-row widget: + centered on the table's bottom border */
4065
+ .blx-table-add-row-widget {
4066
+ bottom: 0;
4067
+ left: 50%;
4068
+ width: 14px;
4069
+ height: 10px;
4070
+ color: #fff;
4071
+ font-size: 12px;
4072
+ font-weight: 900;
4073
+ line-height: 1;
4074
+ transform: translate(-50%, 50%);
4075
+ }
4076
+
4077
+ /* Add-col widget: + centered on the table's right border */
4078
+ .blx-table-add-col-widget {
4079
+ right: 0;
4080
+ top: 50%;
4081
+ width: 10px;
4082
+ height: 14px;
4083
+ color: #fff;
4084
+ font-size: 12px;
4085
+ font-weight: 900;
4086
+ line-height: 1;
4087
+ transform: translate(50%, -50%);
4088
+ }
4089
+
4090
+ /* ── Table column resize handles ────────────────────────── */
4091
+
4092
+ .blx-table-col-resize {
4093
+ position: absolute;
4094
+ cursor: col-resize;
4095
+ z-index: 4;
4096
+ background: transparent;
4097
+ }
4098
+
4099
+ .blx-table-col-resize:hover {
4100
+ background: var(--blx-accent);
4101
+ opacity: 0.3;
4102
+ }
4103
+
4104
+ /* ── Table context menu ──────────────────────────────────── */
4105
+
4106
+ .blx-table-context-menu {
4107
+ min-width: 160px;
4108
+ }
4109
+
4110
+ /* ── Reduced motion ──────────────────────────────────────── */
4111
+
4112
+ @media (prefers-reduced-motion: reduce) {
4113
+ .blx-menu,
4114
+ .blx-popover,
4115
+ .blx-tooltip,
4116
+ .blx-toast,
4117
+ .blx-modal,
4118
+ .blx-dropdown-menu {
4119
+ animation-duration: 0.01ms !important;
4120
+ transition-duration: 0.01ms !important;
4121
+ }
4122
+
4123
+ .blx-caret {
4124
+ animation: none !important;
4125
+ transition: none !important;
4126
+ }
4127
+ }
4128
+
4129
+ /* ── Fold visibility ────────────────────────────────────────────── */
4130
+
4131
+ /* Blocks hidden by a heading fold. Uses a class instead of inline
4132
+ style.display so it doesn't interfere with plugin-set inline
4133
+ display values (e.g. display:flex for agenda badges). */
4134
+ .blx-fold-hidden {
4135
+ display: none !important;
4136
+ }
4137
+
4138
+ /* ── Heading fold indicator ─────────────────────────────────────── */
4139
+
4140
+ /* Clickable bar below folded headings: ▸ icon + dashed line.
4141
+ Hidden by default, shown when block has .blx-heading-folded. */
4142
+ .blx-fold-indicator {
4143
+ display: none;
4144
+ align-items: center;
4145
+ gap: 6px;
4146
+ margin: 4px 6px 0;
4147
+ padding: 2px 0;
4148
+ cursor: pointer;
4149
+ color: var(--blx-text-faint);
4150
+ opacity: 0.3;
4151
+ transition: opacity 0.15s ease;
4152
+ user-select: none;
4153
+ }
4154
+
4155
+ .blx-fold-indicator::before {
4156
+ content: "▸";
4157
+ flex-shrink: 0;
4158
+ font-size: 10px;
4159
+ line-height: 1;
4160
+ }
4161
+
4162
+ .blx-fold-indicator::after {
4163
+ content: "";
4164
+ flex: 1;
4165
+ height: 0;
4166
+ border-bottom: 1.5px dashed currentColor;
4167
+ }
4168
+
4169
+ .blx-heading-folded > .blx-fold-indicator {
4170
+ display: flex;
4171
+ }
4172
+
4173
+ .blx-fold-indicator:hover {
4174
+ opacity: 0.6;
4175
+ }
4176
+
4177
+ /* ── Fold animation ────────────────────────────────────────────── */
4178
+
4179
+ /* Blocks appearing after an unfold — subtle slide-in */
4180
+ .blx-fold-revealed {
4181
+ animation: blx-fold-reveal 0.2s var(--blx-widget-anim-curve) both;
4182
+ }
4183
+
4184
+ @keyframes blx-fold-reveal {
4185
+ from {
4186
+ opacity: 0;
4187
+ transform: translateY(-6px);
4188
+ }
4189
+ to {
4190
+ opacity: 1;
4191
+ transform: none;
4192
+ }
4193
+ }
4194
+
4195
+ /* ── Custom Caret ─────────────────────────────────────────── */
4196
+
4197
+ @keyframes blx-caret-blink {
4198
+ 0%, 100% { opacity: 1; }
4199
+ 50% { opacity: 0; }
4200
+ }
4201
+
4202
+
4203
+ .blx-caret {
4204
+ position: fixed;
4205
+ width: 2px;
4206
+ border-radius: 1px;
4207
+ background: var(--blx-caret-color, var(--blx-accent));
4208
+ pointer-events: none;
4209
+ transform-origin: bottom center;
4210
+ z-index: var(--blx-caret-z-index, 20);
4211
+
4212
+ /* Smooth motion for nearby moves */
4213
+ transition:
4214
+ top 0.12s cubic-bezier(0.25, 0.46, 0.45, 0.94),
4215
+ left 0.12s cubic-bezier(0.25, 0.46, 0.45, 0.94),
4216
+ height 0.08s ease,
4217
+ opacity 0.05s ease;
4218
+
4219
+ /* Blink (default state) */
4220
+ animation: blx-caret-blink 1.1s ease-in-out infinite;
4221
+ }
4222
+
4223
+ /* While user is actively typing/moving — blink paused, caret solid, no slide */
4224
+ .blx-caret--active {
4225
+ animation: none;
4226
+ opacity: 1;
4227
+ transition: none;
4228
+ }
4229
+
4230
+ /* Snap: disable transition for this frame */
4231
+ .blx-caret--no-transition {
4232
+ transition: none;
4233
+ }
4234
+
4235
+ /* Motion trail for cross-block jumps — caret slides from old to new position */
4236
+ .blx-caret--trailing {
4237
+ transition:
4238
+ transform 0.15s cubic-bezier(0.16, 1, 0.3, 1),
4239
+ opacity 0.15s cubic-bezier(0.16, 1, 0.3, 1),
4240
+ mask-image 0.15s cubic-bezier(0.16, 1, 0.3, 1),
4241
+ -webkit-mask-image 0.15s cubic-bezier(0.16, 1, 0.3, 1);
4242
+ animation: none;
4243
+ }
4244
+
4245
+ /* Hidden state — !important needed to beat CSS animation cascade */
4246
+ .blx-caret--hidden {
4247
+ opacity: 0 !important;
4248
+ animation: none !important;
4249
+ transition: none !important;
4250
+ }
4251
+
4252
+ /* ── Mermaid Diagram Block ─────────────────────────────────────── */
4253
+
4254
+ .blx-mermaid {
4255
+ border-radius: 10px;
4256
+ margin: 10px;
4257
+ }
4258
+
4259
+ /* Code area — hidden when not editing */
4260
+ .blx-mermaid:not(.blx-mermaid--editing) .blx-mermaid-code {
4261
+ display: none;
4262
+ }
4263
+
4264
+ .blx-mermaid-code {
4265
+ background: #1e1e2e;
4266
+ border-radius: 10px 10px 0 0;
4267
+ position: relative;
4268
+ }
4269
+
4270
+ .blx-mermaid-label {
4271
+ position: absolute;
4272
+ top: 4px;
4273
+ right: 8px;
4274
+ z-index: 2;
4275
+ color: rgba(255, 255, 255, 0.25);
4276
+ font-size: 0.75rem;
4277
+ font-family: var(--blx-font-sans);
4278
+ font-weight: 500;
4279
+ padding: 3px 8px;
4280
+ user-select: none;
4281
+ }
4282
+
4283
+ .blx-mermaid-pre {
4284
+ margin: 0;
4285
+ padding: 0;
4286
+ }
4287
+
4288
+ .blx-mermaid-content {
4289
+ display: block;
4290
+ font-family: var(--blx-font-mono);
4291
+ font-size: 0.8rem;
4292
+ line-height: 1.6;
4293
+ color: #cdd6f4;
4294
+ white-space: pre;
4295
+ padding: 16px 18px;
4296
+ overflow-x: auto;
4297
+ min-height: 1.6em;
4298
+ tab-size: 2;
4299
+ }
4300
+
4301
+ .blx-mermaid [contenteditable="true"] {
4302
+ padding: 16px 18px;
4303
+ border-radius: 0;
4304
+ transition: none;
4305
+ }
4306
+
4307
+ .blx-mermaid [contenteditable="true"]:focus,
4308
+ .blx-mermaid-content:focus {
4309
+ background-color: transparent;
4310
+ box-shadow: none;
4311
+ outline: none;
4312
+ }
4313
+
4314
+ /* Empty mermaid placeholder */
4315
+ .blx-mermaid-content:empty::before {
4316
+ content: "Type mermaid diagram syntax…";
4317
+ color: #585b70;
4318
+ pointer-events: none;
4319
+ }
4320
+
4321
+ /* Preview area */
4322
+ .blx-mermaid-preview {
4323
+ min-height: 60px;
4324
+ padding: 1rem;
4325
+ display: flex;
4326
+ flex-direction: column;
4327
+ align-items: center;
4328
+ justify-content: center;
4329
+ border: 1.5px solid var(--blx-border-input);
4330
+ border-radius: 10px;
4331
+ background: var(--blx-surface);
4332
+ transition: border-color 0.15s ease;
4333
+ }
4334
+
4335
+ .blx-mermaid--editing .blx-mermaid-preview {
4336
+ border-top-left-radius: 0;
4337
+ border-top-right-radius: 0;
4338
+ border-top: none;
4339
+ }
4340
+
4341
+ .blx-mermaid:not(.blx-mermaid--editing) .blx-mermaid-preview {
4342
+ cursor: pointer;
4343
+ }
4344
+
4345
+ .blx-mermaid:not(.blx-mermaid--editing) .blx-mermaid-preview:hover {
4346
+ border-color: var(--blx-accent);
4347
+ }
4348
+
4349
+ .blx-mermaid-diagram {
4350
+ width: 100%;
4351
+ max-height: 600px;
4352
+ overflow: auto;
4353
+ }
4354
+
4355
+ .blx-mermaid-preview svg,
4356
+ .blx-mermaid-diagram svg {
4357
+ max-width: 100%;
4358
+ height: auto;
4359
+ display: block;
4360
+ }
4361
+
4362
+ .blx-mermaid-preview.blx-mermaid-empty {
4363
+ padding: 2rem;
4364
+ color: var(--blx-placeholder-color);
4365
+ font-size: 0.85rem;
4366
+ }
4367
+
4368
+ .blx-mermaid-preview.blx-mermaid-empty::before {
4369
+ content: "Mermaid diagram preview";
4370
+ }
4371
+
4372
+ .blx-mermaid-error {
4373
+ color: var(--blx-danger, #e64553);
4374
+ font-size: 0.8rem;
4375
+ font-family: var(--blx-font-mono);
4376
+ max-height: 3em;
4377
+ overflow: hidden;
4378
+ text-overflow: ellipsis;
4379
+ }
4380
+
4381
+ .blx-mermaid-error:empty {
4382
+ display: none;
4383
+ }
4384
+
4385
+ .blx-mermaid-diagram:empty + .blx-mermaid-error:empty {
4386
+ display: none;
4387
+ }
4388
+
4389
+ /* ── Excalidraw Block ──────────────────────────────────────────── */
4390
+
4391
+ .blx-excalidraw {
4392
+ margin: 10px;
4393
+ }
4394
+
4395
+ .blx-excalidraw-placeholder {
4396
+ display: flex;
4397
+ flex-direction: column;
4398
+ align-items: center;
4399
+ gap: 10px;
4400
+ padding: 32px 24px;
4401
+ border: 1.5px dashed var(--blx-border-input);
4402
+ border-radius: 10px;
4403
+ background: var(--blx-selected-bg);
4404
+ transition: border-color 0.15s ease, background-color 0.15s ease;
4405
+ cursor: pointer;
4406
+ }
4407
+
4408
+ .blx-excalidraw-placeholder:hover {
4409
+ border-color: var(--blx-accent);
4410
+ background: var(--blx-accent-bg);
4411
+ }
4412
+
4413
+ .blx-excalidraw-icon {
4414
+ color: var(--blx-text-faint);
4415
+ line-height: 0;
4416
+ }
4417
+
4418
+ .blx-excalidraw-placeholder:hover .blx-excalidraw-icon {
4419
+ color: var(--blx-accent);
4420
+ }
4421
+
4422
+ .blx-excalidraw-placeholder-label {
4423
+ font-size: 0.8rem;
4424
+ font-family: var(--blx-font-sans);
4425
+ color: var(--blx-text-muted);
4426
+ letter-spacing: -0.01em;
4427
+ }
4428
+
4429
+ .blx-excalidraw-create-btn {
4430
+ display: inline-flex;
4431
+ align-items: center;
4432
+ justify-content: center;
4433
+ gap: 4px;
4434
+ padding: 6px 16px;
4435
+ border: none;
4436
+ border-radius: 8px;
4437
+ background: var(--blx-accent);
4438
+ color: #fff;
4439
+ font-size: 0.8rem;
4440
+ font-family: var(--blx-font-sans);
4441
+ font-weight: 500;
4442
+ line-height: 1.4;
4443
+ cursor: pointer;
4444
+ transition: opacity 0.12s ease;
4445
+ }
4446
+
4447
+ .blx-excalidraw-create-btn:hover {
4448
+ opacity: 0.9;
4449
+ }
4450
+
4451
+ /* Excalidraw figure with preview */
4452
+ .blx-excalidraw-figure {
4453
+ position: relative;
4454
+ display: flex;
4455
+ flex-direction: column;
4456
+ align-items: center;
4457
+ }
4458
+
4459
+ .blx-excalidraw-preview {
4460
+ width: 100%;
4461
+ display: flex;
4462
+ align-items: center;
4463
+ justify-content: center;
4464
+ border: 1.5px solid var(--blx-border-input);
4465
+ border-radius: 10px;
4466
+ overflow: hidden;
4467
+ background: var(--blx-surface);
4468
+ min-height: 100px;
4469
+ }
4470
+
4471
+ .blx-excalidraw-preview svg {
4472
+ max-width: 100%;
4473
+ height: auto;
4474
+ }
4475
+
4476
+ .blx-excalidraw-no-preview {
4477
+ display: flex;
4478
+ flex-direction: column;
4479
+ align-items: center;
4480
+ gap: 8px;
4481
+ padding: 2rem;
4482
+ color: var(--blx-placeholder-color);
4483
+ font-size: 0.85rem;
4484
+ }
4485
+
4486
+ /* Edit overlay on hover */
4487
+ .blx-excalidraw-edit-overlay {
4488
+ position: absolute;
4489
+ inset: 0;
4490
+ display: flex;
4491
+ align-items: center;
4492
+ justify-content: center;
4493
+ opacity: 0;
4494
+ transition: opacity 0.2s ease;
4495
+ background: rgba(0, 0, 0, 0.04);
4496
+ border-radius: 10px;
4497
+ cursor: pointer;
4498
+ }
4499
+
4500
+ .blx-excalidraw-figure:hover .blx-excalidraw-edit-overlay {
4501
+ opacity: 1;
4502
+ }
4503
+
4504
+ .blx-excalidraw-edit-btn {
4505
+ display: inline-flex;
4506
+ align-items: center;
4507
+ gap: 4px;
4508
+ padding: 6px 14px;
4509
+ border: none;
4510
+ border-radius: 6px;
4511
+ background: var(--blx-accent);
4512
+ color: #fff;
4513
+ font-size: 0.8rem;
4514
+ font-family: var(--blx-font-sans);
4515
+ cursor: pointer;
4516
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
4517
+ }
4518
+
4519
+ .blx-excalidraw-edit-btn:hover {
4520
+ background: var(--blx-accent-hover);
4521
+ }
4522
+
4523
+ /* ── Excalidraw Modal ──────────────────────────────────────────── */
4524
+
4525
+ .blx-excalidraw-modal {
4526
+ position: fixed;
4527
+ inset: 0;
4528
+ z-index: 10000;
4529
+ display: flex;
4530
+ align-items: center;
4531
+ justify-content: center;
4532
+ }
4533
+
4534
+ .blx-excalidraw-modal-backdrop {
4535
+ position: absolute;
4536
+ inset: 0;
4537
+ background: rgba(0, 0, 0, 0.18);
4538
+ -webkit-backdrop-filter: blur(4px);
4539
+ backdrop-filter: blur(4px);
4540
+ animation: blx-modal-backdrop-in 0.15s ease-out;
4541
+ }
4542
+
4543
+ .blx-excalidraw-modal-content {
4544
+ position: relative;
4545
+ width: min(90vw, 1400px);
4546
+ height: min(85vh, 900px);
4547
+ background: var(--blx-surface, #ffffff);
4548
+ border: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
4549
+ border-radius: 12px;
4550
+ display: flex;
4551
+ flex-direction: column;
4552
+ overflow: hidden;
4553
+ box-shadow:
4554
+ 0 0 0 1px rgba(0, 0, 0, 0.02),
4555
+ 0 8px 24px rgba(0, 0, 0, 0.06),
4556
+ 0 24px 64px rgba(0, 0, 0, 0.1);
4557
+ animation: blx-excalidraw-modal-in 0.2s cubic-bezier(0.22, 1, 0.36, 1);
4558
+ }
4559
+
4560
+ @keyframes blx-excalidraw-modal-in {
4561
+ from { opacity: 0; transform: translateY(-6px); }
4562
+ to { opacity: 1; transform: translateY(0); }
4563
+ }
4564
+
4565
+ .blx-excalidraw-modal-header {
4566
+ display: flex;
4567
+ align-items: center;
4568
+ justify-content: space-between;
4569
+ padding: 13px 16px 13px 20px;
4570
+ border-bottom: 1px solid var(--blx-border, rgba(0, 0, 0, 0.06));
4571
+ flex-shrink: 0;
4572
+ }
4573
+
4574
+ .blx-excalidraw-modal-title {
4575
+ font-size: 0.9375rem;
4576
+ font-weight: 500;
4577
+ font-family: var(--ws-font-display, var(--blx-font-sans));
4578
+ letter-spacing: -0.01em;
4579
+ line-height: 1;
4580
+ color: var(--blx-text-heading, #3b4255);
4581
+ margin: 0;
4582
+ }
4583
+
4584
+ .blx-excalidraw-modal-close {
4585
+ width: 28px;
4586
+ height: 28px;
4587
+ display: flex;
4588
+ align-items: center;
4589
+ justify-content: center;
4590
+ border: none;
4591
+ border-radius: 6px;
4592
+ background: transparent;
4593
+ color: var(--blx-text-faint, #b0b5bf);
4594
+ cursor: pointer;
4595
+ transition: background 0.12s ease, color 0.12s ease;
4596
+ margin-right: -4px;
4597
+ }
4598
+
4599
+ .blx-excalidraw-modal-close:hover {
4600
+ background: var(--blx-hover-bg, rgba(0, 0, 0, 0.035));
4601
+ color: var(--blx-text-muted, #8a8f9a);
4602
+ }
4603
+
4604
+ .blx-excalidraw-modal-close:focus-visible {
4605
+ outline: none;
4606
+ box-shadow: 0 0 0 2px var(--blx-surface, #fff), 0 0 0 4px var(--blx-accent, #4285f4);
4607
+ }
4608
+
4609
+ .blx-excalidraw-modal-close svg {
4610
+ width: 14px;
4611
+ height: 14px;
4612
+ }
4613
+
4614
+ .blx-excalidraw-modal-body {
4615
+ flex: 1;
4616
+ overflow: hidden;
4617
+ }
4618
+
4619
+ /* Hide library sidebar trigger — no official prop yet */
4620
+ .blx-excalidraw-modal-body .excalidraw .sidebar-trigger {
4621
+ display: none !important;
4622
+ }
4623
+
4624
+ /* Excalidraw renders dialogs (help, etc.) as portals on document.body —
4625
+ they need a higher z-index than our modal (10000) */
4626
+ .excalidraw-modal-container {
4627
+ z-index: 10001 !important;
4628
+ }
4629
+
4630
+ /* Dark mode adjustments */
4631
+ [data-blx-theme="dark"] .blx-excalidraw-edit-overlay {
4632
+ background: rgba(255, 255, 255, 0.04);
4633
+ }
4634
+
4635
+ [data-blx-theme="dark"] .blx-excalidraw-modal-content,
4636
+ [data-theme="dark"] .blx-excalidraw-modal-content {
4637
+ background: #1e1e2e;
4638
+ border-color: rgba(255, 255, 255, 0.08);
4639
+ box-shadow:
4640
+ 0 0 0 1px rgba(255, 255, 255, 0.06),
4641
+ 0 8px 24px rgba(0, 0, 0, 0.2),
4642
+ 0 24px 64px rgba(0, 0, 0, 0.35);
4643
+ }
4644
+
4645
+ [data-blx-theme="dark"] .blx-excalidraw-modal-header,
4646
+ [data-theme="dark"] .blx-excalidraw-modal-header {
4647
+ border-bottom-color: #313244;
4648
+ }
4649
+
4650
+ [data-blx-theme="dark"] .blx-excalidraw-modal-backdrop,
4651
+ [data-theme="dark"] .blx-excalidraw-modal-backdrop {
4652
+ background: rgba(0, 0, 0, 0.45);
4653
+ }
4654
+
4655
+ @media (prefers-color-scheme: dark) {
4656
+ :root:not([data-theme="light"]):not([data-blx-theme="light"]) .blx-excalidraw-modal-content {
4657
+ background: #1e1e2e;
4658
+ border-color: rgba(255, 255, 255, 0.08);
4659
+ box-shadow:
4660
+ 0 0 0 1px rgba(255, 255, 255, 0.06),
4661
+ 0 8px 24px rgba(0, 0, 0, 0.2),
4662
+ 0 24px 64px rgba(0, 0, 0, 0.35);
4663
+ }
4664
+ :root:not([data-theme="light"]):not([data-blx-theme="light"]) .blx-excalidraw-modal-header {
4665
+ border-bottom-color: #313244;
4666
+ }
4667
+ :root:not([data-theme="light"]):not([data-blx-theme="light"]) .blx-excalidraw-modal-backdrop {
4668
+ background: rgba(0, 0, 0, 0.45);
4669
+ }
4670
+ }