joplin-plugin-explorer 1.6.1 → 1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,846 +1,868 @@
1
- html, body {
2
- height: 100%;
3
- margin: 0;
4
- padding: 0;
5
- overflow: hidden;
6
- }
7
-
8
- #notes-in-list-root {
9
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
10
- font-size: 13px;
11
- color: var(--joplin-color);
12
- background-color: var(--joplin-background-color);
13
- height: 100vh;
14
- display: flex;
15
- flex-direction: column;
16
- user-select: none;
17
- overflow: hidden;
18
- }
19
-
20
- /* Toolbar */
21
- .toolbar {
22
- display: flex;
23
- gap: 4px;
24
- padding: 6px 8px;
25
- border-bottom: 1px solid var(--joplin-divider-color, #ddd);
26
- align-items: center;
27
- flex-shrink: 0;
28
- }
29
-
30
- .toolbar button {
31
- background: var(--joplin-background-color3, #f0f0f0);
32
- border: 1px solid var(--joplin-divider-color, #ccc);
33
- border-radius: 4px;
34
- padding: 4px 8px;
35
- cursor: pointer;
36
- color: var(--joplin-color);
37
- font-size: 12px;
38
- white-space: nowrap;
39
- flex-shrink: 0;
40
- line-height: 1.2;
41
- }
42
-
43
- .toolbar button:hover {
44
- background: var(--joplin-background-color-hover3, #e0e0e0);
45
- }
46
-
47
- .toolbar button:active {
48
- opacity: 0.7;
49
- }
50
-
51
- #btn-sort {
52
- min-width: 76px;
53
- text-align: center;
54
- }
55
-
56
- /* Search bar */
57
- .search-bar {
58
- padding: 4px 8px;
59
- border-bottom: 1px solid var(--joplin-divider-color, #ddd);
60
- flex-shrink: 0;
61
- }
62
-
63
- #search-input {
64
- width: 100%;
65
- box-sizing: border-box;
66
- padding: 5px 8px;
67
- border: 1px solid var(--joplin-divider-color, #ccc);
68
- border-radius: 4px;
69
- background: var(--joplin-background-color, #fff);
70
- color: var(--joplin-color);
71
- font-size: 12px;
72
- outline: none;
73
- }
74
-
75
- #search-input:focus {
76
- border-color: var(--joplin-color2, #4a9cf5);
77
- }
78
-
79
- /* Tree container */
80
- #tree-container {
81
- flex: 1;
82
- overflow-y: scroll;
83
- padding: 4px 0;
84
- }
85
-
86
- #tree-container::-webkit-scrollbar {
87
- width: 8px;
88
- }
89
-
90
- #tree-container::-webkit-scrollbar-track {
91
- background: transparent;
92
- }
93
-
94
- #tree-container::-webkit-scrollbar-thumb {
95
- background: var(--joplin-color-faded, #888);
96
- border-radius: 4px;
97
- }
98
-
99
- #tree-container::-webkit-scrollbar-thumb:hover {
100
- background: var(--joplin-color, #555);
101
- }
102
-
103
- /* Tree items */
104
- .tree-item {
105
- display: flex;
106
- align-items: center;
107
- padding: 3px 8px;
108
- cursor: pointer;
109
- gap: 5px;
110
- border-radius: 3px;
111
- margin: 1px 4px;
112
- min-height: 24px;
113
- }
114
-
115
- .tree-item:hover {
116
- background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
117
- }
118
-
119
- .tree-item.note.selected {
120
- background: var(--joplin-selected-color, rgba(74, 156, 245, 0.2));
121
- }
122
-
123
- /* Toggle arrow */
124
- .toggle {
125
- width: 14px;
126
- text-align: center;
127
- font-size: 9px;
128
- flex-shrink: 0;
129
- color: var(--joplin-color-faded, #888);
130
- transition: transform 0.15s;
131
- }
132
-
133
- /* Icons */
134
- .icon {
135
- flex-shrink: 0;
136
- font-size: 14px;
137
- width: 18px;
138
- text-align: center;
139
- }
140
-
141
- .custom-icon {
142
- display: block;
143
- width: 16px;
144
- height: 16px;
145
- object-fit: contain;
146
- margin: 0 auto;
147
- }
148
-
149
- /* Label */
150
- .label {
151
- flex: 1;
152
- overflow: hidden;
153
- text-overflow: ellipsis;
154
- white-space: nowrap;
155
- }
156
-
157
- /* Note count badge */
158
- .count {
159
- color: var(--joplin-color-faded, #888);
160
- font-size: 10px;
161
- flex-shrink: 0;
162
- background: var(--joplin-background-color3, rgba(100,100,100,0.1));
163
- border-radius: 8px;
164
- padding: 0 5px;
165
- min-width: 16px;
166
- text-align: center;
167
- line-height: 16px;
168
- }
169
-
170
- /* Collapsed children */
171
- .children.collapsed {
172
- display: none;
173
- }
174
-
175
- /* Open/closed icon variants: both are in the DOM, the .collapsed class on
176
- the folder row / pinned header picks which one shows. This lets the
177
- webview toggle folders without a backend re-render. */
178
- .tree-item.folder.collapsed .icon-when-open { display: none; }
179
- .tree-item.folder:not(.collapsed) .icon-when-collapsed { display: none; }
180
- .pinned-section-header.collapsed .icon-when-open { display: none; }
181
- .pinned-section-header:not(.collapsed) .icon-when-collapsed { display: none; }
182
-
183
- /* Folder styling */
184
- .folder .label {
185
- font-weight: 600;
186
- }
187
-
188
- /* Note styling */
189
- .note .label {
190
- font-weight: normal;
191
- }
192
-
193
- .note .icon {
194
- font-size: 12px;
195
- }
196
-
197
- /* Bottom bar (sync) */
198
- .bottom-bar {
199
- display: flex;
200
- padding: 6px 8px;
201
- border-top: 1px solid var(--joplin-divider-color, #ddd);
202
- flex-shrink: 0;
203
- }
204
-
205
- .bottom-bar button {
206
- flex: 1;
207
- background: var(--joplin-background-color3, #f0f0f0);
208
- border: 1px solid var(--joplin-divider-color, #ccc);
209
- border-radius: 4px;
210
- padding: 5px 10px;
211
- cursor: pointer;
212
- color: var(--joplin-color);
213
- font-size: 12px;
214
- }
215
-
216
- .bottom-bar button:hover {
217
- background: var(--joplin-background-color-hover3, #e0e0e0);
218
- }
219
-
220
- .bottom-bar button:active {
221
- opacity: 0.7;
222
- }
223
-
224
- .bottom-bar button:disabled,
225
- .bottom-bar button.syncing {
226
- opacity: 0.5;
227
- cursor: not-allowed;
228
- }
229
-
230
- .bottom-bar button.sync-done {
231
- color: #27ae60;
232
- opacity: 1;
233
- cursor: default;
234
- }
235
-
236
- .bottom-bar button.sync-error {
237
- color: #e74c3c;
238
- opacity: 1;
239
- cursor: default;
240
- }
241
-
242
- /* Context menu */
243
- .context-menu {
244
- position: fixed;
245
- background: var(--joplin-background-color, #fff);
246
- border: 1px solid var(--joplin-divider-color, #ccc);
247
- border-radius: 6px;
248
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
249
- padding: 4px 0;
250
- min-width: 160px;
251
- z-index: 9999;
252
- font-size: 12px;
253
- }
254
-
255
- .ctx-item {
256
- padding: 6px 14px;
257
- cursor: pointer;
258
- color: var(--joplin-color);
259
- }
260
-
261
- /* Fixed-width icon slot so emoji of different widths don't skew the labels */
262
- .ctx-icon {
263
- display: inline-block;
264
- width: 20px;
265
- text-align: center;
266
- margin-right: 5px;
267
- }
268
-
269
- .ctx-item:hover {
270
- background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
271
- }
272
-
273
- .ctx-danger {
274
- color: #e74c3c;
275
- }
276
-
277
- .ctx-danger:hover {
278
- background: rgba(231, 76, 60, 0.1);
279
- }
280
-
281
- /* Drill-in submenu (the narrow panel webview clips flyouts) */
282
- /* Drill row is flex so the arrow can sit vertically centered at the right. */
283
- .ctx-drill {
284
- display: flex;
285
- align-items: center;
286
- }
287
- /* True geometric triangle: a zero-size box whose left border forms a solid
288
- right-pointing arrow. No font glyph involved, so flex centering is exact —
289
- the glyph-baseline guesswork of ▶/▸ goes away entirely. */
290
- .ctx-sub-arrow {
291
- margin-left: auto;
292
- width: 0;
293
- height: 0;
294
- font-size: 0; /* hide the ▶ text content itself */
295
- color: transparent;
296
- border-top: 4px solid transparent;
297
- border-bottom: 4px solid transparent;
298
- border-left: 5px solid var(--joplin-color, #ccc);
299
- opacity: 0.7;
300
- box-sizing: content-box;
301
- }
302
- .ctx-back {
303
- color: var(--joplin-color-faded, #888);
304
- font-weight: 600;
305
- }
306
-
307
- .ctx-sep {
308
- height: 1px;
309
- background: var(--joplin-divider-color, #ddd);
310
- margin: 4px 0;
311
- }
312
-
313
- /* Hover preview tooltip */
314
- #note-preview {
315
- position: fixed;
316
- max-width: 260px;
317
- z-index: 9998;
318
- background: var(--joplin-background-color, #fff);
319
- border: 1px solid var(--joplin-divider-color, #ccc);
320
- border-radius: 6px;
321
- box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
322
- padding: 8px 10px;
323
- font-size: 12px;
324
- pointer-events: none;
325
- }
326
- .note-preview-title {
327
- font-weight: 600;
328
- margin-bottom: 2px;
329
- }
330
- .note-preview-meta {
331
- color: var(--joplin-color-faded, #888);
332
- font-size: 10px;
333
- margin-bottom: 5px;
334
- }
335
- .note-preview-body {
336
- color: var(--joplin-color, #ddd);
337
- opacity: 0.85;
338
- line-height: 1.45;
339
- word-break: break-word;
340
- }
341
-
342
- /* ---- unified section chrome ----
343
- * One soft line ABOVE each section header plus breathing room; bodies draw
344
- * no borders at all, so no state combination can double up lines. */
345
- .pinned-section-header,
346
- .smart-section-header,
347
- .trash-section-header,
348
- .tags-section-header {
349
- display: flex;
350
- align-items: center;
351
- padding: 4px 8px;
352
- gap: 5px;
353
- /* --sec-gap: sectionSpacing setting, set inline on the root (#9) */
354
- margin: var(--sec-gap, 5px) 4px 1px;
355
- min-height: 24px;
356
- padding: 3px 8px;
357
- border-top: 1px solid rgba(127, 127, 127, 0.22);
358
- border-radius: 0 0 3px 3px;
359
- cursor: pointer;
360
- user-select: none;
361
- color: var(--joplin-color-faded, #888);
362
- font-weight: 600;
363
- font-size: 13px;
364
- letter-spacing: 0.4px;
365
- }
366
- /* Arrow position mode (toggleArrowPosition setting, root data-arrow-pos).
367
- * "right": chevrons sit right after the text everywhere - section headers,
368
- * section rows AND notebook tree folders - with counts on the right edge.
369
- * "left": no overrides, everything keeps the classic leading arrow. */
370
- [data-arrow-pos="right"] .pinned-section-header .label,
371
- [data-arrow-pos="right"] .smart-section-header .label,
372
- [data-arrow-pos="right"] .trash-section-header .label,
373
- [data-arrow-pos="right"] .tags-section-header .label,
374
- [data-arrow-pos="right"] .tree-item.folder .label {
375
- flex: 0 1 auto;
376
- }
377
- [data-arrow-pos="right"] .pinned-section-header .toggle,
378
- [data-arrow-pos="right"] .smart-section-header .toggle,
379
- [data-arrow-pos="right"] .trash-section-header .toggle,
380
- [data-arrow-pos="right"] .tags-section-header .toggle,
381
- [data-arrow-pos="right"] .tree-item.folder .toggle {
382
- order: 3;
383
- width: auto;
384
- margin-left: 2px;
385
- font-size: 8px;
386
- opacity: 0.75;
387
- }
388
- [data-arrow-pos="right"] .pinned-section-header .count,
389
- [data-arrow-pos="right"] .smart-section-header .count,
390
- [data-arrow-pos="right"] .trash-section-header .count,
391
- [data-arrow-pos="right"] .tags-section-header .count,
392
- [data-arrow-pos="right"] .tree-item.folder .count {
393
- order: 4; /* after the chevron (order 3): text › ......... count */
394
- margin-left: auto;
395
- }
396
- .pinned-section-header .icon,
397
- .smart-section-header .icon,
398
- .trash-section-header .icon,
399
- .tags-section-header .icon {
400
- font-size: 12px;
401
- opacity: 0.85;
402
- }
403
- .pinned-section-header:hover,
404
- .smart-section-header:hover,
405
- .trash-section-header:hover,
406
- .tags-section-header:hover {
407
- background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.12));
408
- }
409
- /* The notebook tree has no header row - its wrapper draws the same
410
- * section-opening line as the headers do. */
411
- #main-tree {
412
- margin: var(--sec-gap, 5px) 4px 1px;
413
- padding-top: 4px;
414
- border-top: 1px solid rgba(127, 127, 127, 0.22);
415
- }
416
- /* #main-tree already carries the 4px side margins; zero the rows' own so
417
- * tree counts land on the same right edge as section header counts
418
- * (they were 4px further left - measured, not eyeballed). */
419
- #main-tree .tree-item {
420
- margin-left: 0;
421
- margin-right: 0;
422
- }
423
-
424
- /* Expand animation: children fade/slide in when the USER toggles a section
425
- * or folder (JS adds .anim-expand only on interactive expands, so panel
426
- * re-renders don't flash). */
427
- @keyframes sectionExpand {
428
- from { opacity: 0; transform: translateY(-4px); }
429
- to { opacity: 1; transform: none; }
430
- }
431
- .anim-expand { animation: sectionExpand 0.16s ease-out; }
432
-
433
- /* Whichever section comes first sits right under the search bar's own
434
- * border - no extra line there. */
435
- #tree-container > div:first-child {
436
- border-top: none;
437
- margin-top: 0;
438
- padding-top: 4px;
439
- }
440
-
441
- .pinned-section-body.collapsed {
442
- display: none;
443
- }
444
-
445
- .pinned-item {
446
- padding-left: 26px !important;
447
- }
448
-
449
- /* (Section rows are .tree-item.folder too - covered by the arrow-position
450
- * rules above.) */
451
-
452
- /* ---- tags section (tags as folders) ---- */
453
- .tags-section-body.collapsed { display: none; }
454
- /* Smart folders sit right under the pinned body, whose border-bottom
455
- * already draws the divider - a border-top here doubled the line. The
456
- * section closes with its own bottom divider before the tree instead. */
457
- .smart-section-body.collapsed { display: none; }
458
- /* Empty smart folder: keeps its folder shape (arrow included) but dimmed,
459
- * and clicking it does nothing (no children container exists). */
460
- .smart-folder.smart-empty { opacity: 0.45; }
461
- .smart-folder.smart-empty:hover { background: none; cursor: default; }
462
- .smart-children.collapsed { display: none; }
463
- .trash-children.collapsed { display: none; }
464
- /* Rows swept out of view when an ancestor trash folder is collapsed */
465
- .trash-hidden { display: none; }
466
- /* Rows carry inline padding (depth-based); containers only need hide/show */
467
- .trash-folder-children.collapsed { display: none; }
468
- .trash-note .label { opacity: 0.75; }
469
- .tag-folder { padding-left: 26px !important; }
470
- .tag-children { }
471
- .tag-children.collapsed { display: none; }
472
- .tag-children .tree-item.note { padding-left: 44px !important; }
473
- .tag-empty {
474
- padding: 2px 8px 2px 44px;
475
- color: var(--joplin-color-faded, #888);
476
- font-size: 11px;
477
- }
478
-
479
- /* Empty drop zone — sticky at bottom of scroll viewport */
480
- .drop-zone-empty {
481
- position: sticky;
482
- bottom: 0;
483
- height: 32px;
484
- flex-shrink: 0;
485
- opacity: 0;
486
- pointer-events: none;
487
- transition: opacity 0.15s;
488
- }
489
-
490
- /* Only show during drag (activated by JS class on tree-container) */
491
- #tree-container.dragging-active .drop-zone-empty {
492
- opacity: 1;
493
- pointer-events: auto;
494
- border: 2px dashed var(--joplin-color2, #4a9cf5);
495
- border-radius: 6px;
496
- margin: 4px 8px;
497
- text-align: center;
498
- line-height: 28px;
499
- font-size: 11px;
500
- color: var(--joplin-color2, #4a9cf5);
501
- /* Solid panel base under the blue tint - the zone floats (sticky) above
502
- * tree rows, so a translucent-only background let them bleed through. */
503
- background: linear-gradient(rgba(74, 156, 245, 0.15), rgba(74, 156, 245, 0.15)),
504
- var(--joplin-background-color, #1e1e1e);
505
- box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.25);
506
- z-index: 10;
507
- }
508
-
509
- /* Temporary drop target when the pinned section is empty (#13): sticky so
510
- * it stays visible however far the tree is scrolled (same pattern as the
511
- * drop-zone-empty bar). */
512
- #pinned-drop-ph {
513
- position: sticky;
514
- top: 0;
515
- z-index: 10;
516
- justify-content: center;
517
- border: 2px dashed var(--joplin-color2, #4a9cf5);
518
- border-radius: 6px;
519
- margin: 4px 8px;
520
- padding: 6px 8px;
521
- color: var(--joplin-color2, #4a9cf5);
522
- font-size: 12px;
523
- background: linear-gradient(rgba(74, 156, 245, 0.15), rgba(74, 156, 245, 0.15)),
524
- var(--joplin-background-color, #1e1e1e);
525
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
526
- }
527
-
528
- /* Pinned section accepts drops during drag — outline doesn't affect layout */
529
- #tree-container.dragging-active .pinned-section-header {
530
- outline: 2px dashed var(--joplin-color2, #4a9cf5);
531
- outline-offset: -2px;
532
- }
533
-
534
- /* Drag & Drop */
535
- .tree-item.dragging {
536
- opacity: 0.35;
537
- filter: grayscale(30%);
538
- }
539
-
540
- .tree-item.drop-target {
541
- background: var(--joplin-selected-color, rgba(74, 156, 245, 0.28));
542
- outline: 2px solid var(--joplin-color2, #4a9cf5);
543
- outline-offset: -2px;
544
- border-radius: 4px;
545
- box-shadow: 0 0 0 2px rgba(74, 156, 245, 0.15);
546
- }
547
-
548
- /* Horizontal insertion bar (above/below) — position:relative only when active */
549
- .tree-item.drop-above,
550
- .tree-item.drop-below {
551
- position: relative;
552
- }
553
-
554
- .tree-item.drop-above::before,
555
- .tree-item.drop-below::before {
556
- content: '';
557
- position: absolute;
558
- left: 4px;
559
- right: 4px;
560
- height: 3px;
561
- background: var(--joplin-color2, #4a9cf5);
562
- border-radius: 2px;
563
- box-shadow: 0 0 4px rgba(74, 156, 245, 0.6);
564
- pointer-events: none;
565
- z-index: 5;
566
- }
567
-
568
- .tree-item.drop-above::before {
569
- top: -2px;
570
- }
571
-
572
- .tree-item.drop-below::before {
573
- bottom: -2px;
574
- }
575
-
576
- /* Dropping into empty area -> create new notebook */
577
- #tree-container.drop-empty {
578
- box-shadow: inset 0 0 0 2px var(--joplin-color2, #4a9cf5);
579
- background: rgba(74, 156, 245, 0.06);
580
- }
581
-
582
-
583
- #search-results {
584
- flex: 1;
585
- overflow-y: scroll;
586
- padding: 4px 0;
587
- }
588
-
589
- #search-results::-webkit-scrollbar {
590
- width: 8px;
591
- }
592
-
593
- #search-results::-webkit-scrollbar-track {
594
- background: transparent;
595
- }
596
-
597
- #search-results::-webkit-scrollbar-thumb {
598
- background: var(--joplin-color-faded, #888);
599
- border-radius: 4px;
600
- }
601
-
602
- /* Search results */
603
- .search-status {
604
- padding: 8px 12px;
605
- font-size: 11px;
606
- color: var(--joplin-color-faded, #888);
607
- border-bottom: 1px solid var(--joplin-divider-color, #eee);
608
- }
609
-
610
- .search-result-item {
611
- display: flex;
612
- align-items: flex-start;
613
- padding: 8px 10px;
614
- gap: 8px;
615
- min-height: auto;
616
- margin: 0; /* override .tree-item margin for note items in search results */
617
- border-radius: 0;
618
- }
619
-
620
- .search-result-item .icon {
621
- flex-shrink: 0;
622
- font-size: 12px;
623
- width: 18px;
624
- text-align: center;
625
- line-height: 16.8px; /* match .search-result-title 12px * 1.4 */
626
- }
627
-
628
- .search-result-content {
629
- flex: 1;
630
- min-width: 0;
631
- overflow: hidden;
632
- }
633
-
634
- .search-result-title {
635
- font-weight: 600;
636
- font-size: 12px;
637
- line-height: 1.4;
638
- white-space: nowrap;
639
- overflow: hidden;
640
- text-overflow: ellipsis;
641
- }
642
-
643
- .search-result-folder {
644
- font-size: 10px;
645
- color: var(--joplin-color-faded, #999);
646
- margin-top: 1px;
647
- }
648
-
649
- .search-result-snippet {
650
- font-size: 11px;
651
- color: var(--joplin-color-faded, #777);
652
- margin-top: 3px;
653
- line-height: 1.4;
654
- display: -webkit-box;
655
- -webkit-line-clamp: 2;
656
- -webkit-box-orient: vertical;
657
- overflow: hidden;
658
- word-break: break-all;
659
- }
660
-
661
- /* Search section headers */
662
- .search-section-header {
663
- padding: 6px 10px;
664
- font-size: 11px;
665
- font-weight: 700;
666
- color: var(--joplin-color-faded, #888);
667
- background: var(--joplin-background-color3, rgba(100, 100, 100, 0.06));
668
- border-bottom: 1px solid var(--joplin-divider-color, #eee);
669
- text-transform: uppercase;
670
- letter-spacing: 0.5px;
671
- cursor: pointer;
672
- user-select: none;
673
- }
674
-
675
- .search-section-header:hover {
676
- background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.12));
677
- }
678
-
679
- .section-toggle {
680
- display: inline-block;
681
- font-size: 9px;
682
- width: 12px;
683
- text-align: center;
684
- transition: transform 0.15s;
685
- }
686
-
687
- .search-section-body.collapsed {
688
- display: none;
689
- }
690
-
691
- /* Tag items in search results */
692
- .search-tag-item {
693
- cursor: pointer;
694
- }
695
-
696
- .search-tag-item:hover {
697
- background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
698
- }
699
-
700
- .tag-expand-arrow {
701
- flex-shrink: 0;
702
- font-size: 9px;
703
- color: var(--joplin-color-faded, #888);
704
- transition: transform 0.15s;
705
- margin-right: 4px;
706
- }
707
-
708
- .tag-expand-arrow.expanded {
709
- transform: rotate(90deg);
710
- }
711
-
712
- .tag-notes-container {
713
- padding-left: 16px;
714
- border-left: 2px solid var(--joplin-divider-color, #eee);
715
- margin-left: 18px;
716
- }
717
-
718
- /* Folder items in search results */
719
- .search-folder-item {
720
- cursor: pointer;
721
- }
722
-
723
- .search-folder-item:hover {
724
- background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
725
- }
726
-
727
- /* Flash highlight when locating a folder from search */
728
- @keyframes locate-pulse {
729
- 0% { background: rgba(74, 156, 245, 0.5); }
730
- 100% { background: transparent; }
731
- }
732
-
733
- .tree-item.locate-flash {
734
- animation: locate-pulse 1.5s ease-out;
735
- border-radius: 4px;
736
- }
737
-
738
- /* Inline input dialog */
739
- .inline-input-overlay {
740
- position: fixed;
741
- top: 0; left: 0; right: 0; bottom: 0;
742
- background: rgba(0, 0, 0, 0.3);
743
- display: flex;
744
- align-items: center;
745
- justify-content: center;
746
- z-index: 10000;
747
- }
748
-
749
- .inline-input-dialog {
750
- background: var(--joplin-background-color, #fff);
751
- border: 1px solid var(--joplin-divider-color, #ccc);
752
- border-radius: 8px;
753
- padding: 16px;
754
- min-width: 240px;
755
- max-width: 90%;
756
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
757
- }
758
-
759
- .inline-input-label {
760
- font-size: 12px;
761
- margin-bottom: 8px;
762
- color: var(--joplin-color);
763
- }
764
-
765
- .inline-input-field {
766
- width: 100%;
767
- box-sizing: border-box;
768
- padding: 6px 8px;
769
- border: 1px solid var(--joplin-divider-color, #ccc);
770
- border-radius: 4px;
771
- background: var(--joplin-background-color, #fff);
772
- color: var(--joplin-color);
773
- font-size: 13px;
774
- outline: none;
775
- }
776
-
777
- .inline-input-field:focus {
778
- border-color: var(--joplin-color2, #4a9cf5);
779
- }
780
-
781
- .inline-input-buttons {
782
- display: flex;
783
- gap: 8px;
784
- margin-top: 12px;
785
- justify-content: flex-end;
786
- }
787
-
788
- .inline-input-buttons button {
789
- padding: 5px 16px;
790
- border: 1px solid var(--joplin-divider-color, #ccc);
791
- border-radius: 4px;
792
- cursor: pointer;
793
- font-size: 12px;
794
- color: var(--joplin-color);
795
- background: var(--joplin-background-color3, #f0f0f0);
796
- }
797
-
798
- .inline-input-ok {
799
- background: #1a73e8 !important;
800
- color: #fff !important;
801
- border-color: #1a73e8 !important;
802
- }
803
-
804
- .inline-input-buttons button:hover {
805
- opacity: 0.85;
806
- }
807
-
808
- mark.search-highlight {
809
- background: rgba(255, 213, 0, 0.4);
810
- color: inherit;
811
- padding: 0 1px;
812
- border-radius: 2px;
813
- }
814
-
815
- /* ---- Note-row badges: checkbox progress pie + published link ---- */
816
- /* Hug the badges to the title text instead of the row's right edge. */
817
- .tree-item.note .label { flex: 0 1 auto; }
818
- .todo-pie, .shared-badge {
819
- flex-shrink: 0;
820
- display: inline-flex;
821
- align-items: center;
822
- }
823
- .todo-pie svg, .shared-badge svg { display: block; }
824
- /* Same box metrics as .count (min-width 16 + 5px side padding) so the
825
- pie centers exactly where count digits center. */
826
- .todo-pie {
827
- color: var(--joplin-color-faded, #888);
828
- margin-left: auto;
829
- min-width: 16px;
830
- padding: 0 5px;
831
- justify-content: center;
832
- }
833
- .todo-pie .pie-ring { fill: none; stroke: currentColor; stroke-width: 1.5; opacity: 0.55; }
834
- .todo-pie .pie-fill { fill: currentColor; opacity: 0.8; }
835
- .shared-badge {
836
- color: var(--joplin-color-faded, #999);
837
- opacity: 0.75;
838
- cursor: pointer;
839
- padding: 2px;
840
- border-radius: 3px;
841
- }
842
- .shared-badge:hover {
843
- opacity: 1;
844
- color: inherit;
845
- background: rgba(127, 127, 127, 0.25);
846
- }
1
+ html, body {
2
+ height: 100%;
3
+ margin: 0;
4
+ padding: 0;
5
+ overflow: hidden;
6
+ }
7
+
8
+ #notes-in-list-root {
9
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
10
+ font-size: 13px;
11
+ color: var(--joplin-color);
12
+ background-color: var(--joplin-background-color);
13
+ height: 100vh;
14
+ display: flex;
15
+ flex-direction: column;
16
+ user-select: none;
17
+ overflow: hidden;
18
+ }
19
+
20
+ /* Toolbar */
21
+ .toolbar {
22
+ display: flex;
23
+ gap: 4px;
24
+ padding: 6px 8px;
25
+ border-bottom: 1px solid var(--joplin-divider-color, #ddd);
26
+ align-items: center;
27
+ flex-shrink: 0;
28
+ }
29
+
30
+ .toolbar button {
31
+ background: var(--joplin-background-color3, #f0f0f0);
32
+ border: 1px solid var(--joplin-divider-color, #ccc);
33
+ border-radius: 4px;
34
+ padding: 4px 8px;
35
+ cursor: pointer;
36
+ color: var(--joplin-color);
37
+ font-size: 12px;
38
+ white-space: nowrap;
39
+ flex-shrink: 0;
40
+ line-height: 1.2;
41
+ }
42
+
43
+ .toolbar button:hover {
44
+ background: var(--joplin-background-color-hover3, #e0e0e0);
45
+ }
46
+
47
+ .toolbar button:active {
48
+ opacity: 0.7;
49
+ }
50
+
51
+ #btn-sort {
52
+ min-width: 76px;
53
+ text-align: center;
54
+ }
55
+
56
+ /* Search bar */
57
+ .search-bar {
58
+ padding: 4px 8px;
59
+ border-bottom: 1px solid var(--joplin-divider-color, #ddd);
60
+ flex-shrink: 0;
61
+ }
62
+
63
+ #search-input {
64
+ width: 100%;
65
+ box-sizing: border-box;
66
+ padding: 5px 8px;
67
+ border: 1px solid var(--joplin-divider-color, #ccc);
68
+ border-radius: 4px;
69
+ background: var(--joplin-background-color, #fff);
70
+ color: var(--joplin-color);
71
+ font-size: 12px;
72
+ outline: none;
73
+ }
74
+
75
+ #search-input:focus {
76
+ border-color: var(--joplin-url-color, #4a9cf5);
77
+ box-shadow: 0 0 0 2px var(--joplin-selected-color, rgba(74, 156, 245, 0.2));
78
+ }
79
+
80
+ /* Tree container */
81
+ #tree-container {
82
+ flex: 1;
83
+ overflow-y: scroll;
84
+ padding: 4px 0;
85
+ }
86
+
87
+ #tree-container::-webkit-scrollbar {
88
+ width: 8px;
89
+ }
90
+
91
+ #tree-container::-webkit-scrollbar-track {
92
+ background: transparent;
93
+ }
94
+
95
+ #tree-container::-webkit-scrollbar-thumb {
96
+ background: var(--joplin-color-faded, #888);
97
+ border-radius: 4px;
98
+ }
99
+
100
+ #tree-container::-webkit-scrollbar-thumb:hover {
101
+ background: var(--joplin-color, #555);
102
+ }
103
+
104
+ /* Tree items */
105
+ .tree-item {
106
+ display: flex;
107
+ align-items: center;
108
+ padding: 3px 8px;
109
+ cursor: pointer;
110
+ gap: 5px;
111
+ border-radius: 3px;
112
+ margin: 1px 4px;
113
+ min-height: 24px;
114
+ }
115
+
116
+ .tree-item:hover {
117
+ background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
118
+ }
119
+
120
+ .tree-item.note.selected {
121
+ background: var(--joplin-selected-color, rgba(74, 156, 245, 0.2));
122
+ }
123
+
124
+ /* Toggle arrow */
125
+ .toggle {
126
+ width: 14px;
127
+ text-align: center;
128
+ font-size: 9px;
129
+ flex-shrink: 0;
130
+ color: var(--joplin-color-faded, #888);
131
+ transition: transform 0.15s;
132
+ }
133
+
134
+ /* Icons */
135
+ .icon {
136
+ flex-shrink: 0;
137
+ font-size: 14px;
138
+ width: 18px;
139
+ text-align: center;
140
+ }
141
+
142
+ .custom-icon {
143
+ display: block;
144
+ width: 16px;
145
+ height: 16px;
146
+ object-fit: contain;
147
+ margin: 0 auto;
148
+ }
149
+
150
+ /* Label */
151
+ .label {
152
+ flex: 1;
153
+ overflow: hidden;
154
+ text-overflow: ellipsis;
155
+ white-space: nowrap;
156
+ }
157
+
158
+ /* Note count badge */
159
+ .count {
160
+ color: var(--joplin-color-faded, #888);
161
+ font-size: 10px;
162
+ flex-shrink: 0;
163
+ background: var(--joplin-background-color3, rgba(100,100,100,0.1));
164
+ border-radius: 8px;
165
+ padding: 0 5px;
166
+ min-width: 16px;
167
+ text-align: center;
168
+ line-height: 16px;
169
+ }
170
+
171
+ /* Collapsed children */
172
+ .children.collapsed {
173
+ display: none;
174
+ }
175
+
176
+ /* Open/closed icon variants: both are in the DOM, the .collapsed class on
177
+ the folder row / pinned header picks which one shows. This lets the
178
+ webview toggle folders without a backend re-render. */
179
+ .tree-item.folder.collapsed .icon-when-open { display: none; }
180
+ .tree-item.folder:not(.collapsed) .icon-when-collapsed { display: none; }
181
+ .pinned-section-header.collapsed .icon-when-open { display: none; }
182
+ .pinned-section-header:not(.collapsed) .icon-when-collapsed { display: none; }
183
+
184
+ /* Folder styling */
185
+ .folder .label {
186
+ font-weight: 600;
187
+ }
188
+
189
+ /* Note styling */
190
+ .note .label {
191
+ font-weight: normal;
192
+ }
193
+
194
+ .note .icon {
195
+ font-size: 12px;
196
+ }
197
+
198
+ /* Bottom bar (sync) */
199
+ .bottom-bar {
200
+ display: flex;
201
+ padding: 6px 8px;
202
+ border-top: 1px solid var(--joplin-divider-color, #ddd);
203
+ flex-shrink: 0;
204
+ }
205
+
206
+ .bottom-bar button {
207
+ flex: 1;
208
+ background: var(--joplin-background-color3, #f0f0f0);
209
+ border: 1px solid var(--joplin-divider-color, #ccc);
210
+ border-radius: 4px;
211
+ padding: 5px 10px;
212
+ cursor: pointer;
213
+ color: var(--joplin-color);
214
+ font-size: 12px;
215
+ }
216
+
217
+ .bottom-bar button:hover {
218
+ background: var(--joplin-background-color-hover3, #e0e0e0);
219
+ }
220
+
221
+ .bottom-bar button:active {
222
+ opacity: 0.7;
223
+ }
224
+
225
+ .bottom-bar button:disabled,
226
+ .bottom-bar button.syncing {
227
+ opacity: 0.5;
228
+ cursor: not-allowed;
229
+ }
230
+
231
+ .bottom-bar button.sync-done {
232
+ color: #27ae60;
233
+ opacity: 1;
234
+ cursor: default;
235
+ }
236
+
237
+ .bottom-bar button.sync-error {
238
+ color: #e74c3c;
239
+ opacity: 1;
240
+ cursor: default;
241
+ }
242
+
243
+ /* Context menu */
244
+ .context-menu {
245
+ position: fixed;
246
+ background: var(--joplin-background-color, #fff);
247
+ border: 1px solid var(--joplin-divider-color, #ccc);
248
+ border-radius: 6px;
249
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
250
+ padding: 4px 0;
251
+ min-width: 160px;
252
+ z-index: 9999;
253
+ font-size: 12px;
254
+ }
255
+
256
+ .ctx-item {
257
+ padding: 6px 14px;
258
+ cursor: pointer;
259
+ color: var(--joplin-color);
260
+ }
261
+
262
+ /* Fixed-width icon slot so emoji of different widths don't skew the labels */
263
+ .ctx-icon {
264
+ display: inline-block;
265
+ width: 20px;
266
+ text-align: center;
267
+ margin-right: 5px;
268
+ }
269
+
270
+ .ctx-item:hover {
271
+ background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
272
+ }
273
+
274
+ .ctx-danger {
275
+ color: #e74c3c;
276
+ }
277
+
278
+ .ctx-danger:hover {
279
+ background: rgba(231, 76, 60, 0.1);
280
+ }
281
+
282
+ /* Drill-in submenu (the narrow panel webview clips flyouts) */
283
+ /* Drill row is flex so the arrow can sit vertically centered at the right. */
284
+ .ctx-drill {
285
+ display: flex;
286
+ align-items: center;
287
+ }
288
+ /* True geometric triangle: a zero-size box whose left border forms a solid
289
+ right-pointing arrow. No font glyph involved, so flex centering is exact —
290
+ the glyph-baseline guesswork of ▶/▸ goes away entirely. */
291
+ .ctx-sub-arrow {
292
+ margin-left: auto;
293
+ width: 0;
294
+ height: 0;
295
+ font-size: 0; /* hide the ▶ text content itself */
296
+ color: transparent;
297
+ border-top: 4px solid transparent;
298
+ border-bottom: 4px solid transparent;
299
+ border-left: 5px solid var(--joplin-color, #ccc);
300
+ opacity: 0.7;
301
+ box-sizing: content-box;
302
+ }
303
+ .ctx-back {
304
+ color: var(--joplin-color-faded, #888);
305
+ font-weight: 600;
306
+ }
307
+
308
+ .ctx-sep {
309
+ height: 1px;
310
+ background: var(--joplin-divider-color, #ddd);
311
+ margin: 4px 0;
312
+ }
313
+
314
+ /* Hover preview tooltip */
315
+ #note-preview {
316
+ position: fixed;
317
+ max-width: 260px;
318
+ z-index: 9998;
319
+ background: var(--joplin-background-color, #fff);
320
+ border: 1px solid var(--joplin-divider-color, #ccc);
321
+ border-radius: 6px;
322
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
323
+ padding: 8px 10px;
324
+ font-size: 12px;
325
+ pointer-events: none;
326
+ }
327
+ .note-preview-title {
328
+ font-weight: 600;
329
+ margin-bottom: 2px;
330
+ }
331
+ .note-preview-meta {
332
+ color: var(--joplin-color-faded, #888);
333
+ font-size: 10px;
334
+ margin-bottom: 5px;
335
+ }
336
+ .note-preview-body {
337
+ color: var(--joplin-color, #ddd);
338
+ opacity: 0.85;
339
+ line-height: 1.45;
340
+ word-break: break-word;
341
+ }
342
+
343
+ /* ---- unified section chrome ----
344
+ * One soft line ABOVE each section header plus breathing room; bodies draw
345
+ * no borders at all, so no state combination can double up lines. */
346
+ .pinned-section-header,
347
+ .smart-section-header,
348
+ .trash-section-header,
349
+ .tree-section-header,
350
+ .tags-section-header {
351
+ display: flex;
352
+ align-items: center;
353
+ padding: 4px 8px;
354
+ gap: 5px;
355
+ /* --sec-gap: sectionSpacing setting, set inline on the root (#9) */
356
+ margin: var(--sec-gap, 5px) 4px 1px;
357
+ min-height: 24px;
358
+ padding: 3px 8px;
359
+ border-top: 1px solid rgba(127, 127, 127, 0.22);
360
+ border-radius: 0 0 3px 3px;
361
+ cursor: pointer;
362
+ user-select: none;
363
+ color: var(--joplin-color-faded, #888);
364
+ font-weight: 600;
365
+ font-size: 13px;
366
+ letter-spacing: 0.4px;
367
+ /* Section pinning (#31): headers stick to the top of the scroll container so
368
+ * Pinned / Smart / Tags / Trash stay reachable without scrolling the whole
369
+ * tree. Needs an opaque background - rows would otherwise show through - and
370
+ * a z-index above tree rows but below the drop-zone hints (z-index 10).
371
+ * The negative top cancels --sec-gap so the header parks flush, not gapped. */
372
+ position: sticky;
373
+ top: calc(var(--sec-gap, 5px) * -1);
374
+ z-index: 6;
375
+ background: var(--joplin-background-color, #1e1e1e);
376
+ }
377
+ /* Arrow position mode (toggleArrowPosition setting, root data-arrow-pos).
378
+ * "right": chevrons sit right after the text everywhere - section headers,
379
+ * section rows AND notebook tree folders - with counts on the right edge.
380
+ * "left": no overrides, everything keeps the classic leading arrow. */
381
+ [data-arrow-pos="right"] .pinned-section-header .label,
382
+ [data-arrow-pos="right"] .smart-section-header .label,
383
+ [data-arrow-pos="right"] .trash-section-header .label,
384
+ [data-arrow-pos="right"] .tree-section-header .label,
385
+ [data-arrow-pos="right"] .tags-section-header .label,
386
+ [data-arrow-pos="right"] .tree-item.folder .label {
387
+ flex: 0 1 auto;
388
+ }
389
+ [data-arrow-pos="right"] .pinned-section-header .toggle,
390
+ [data-arrow-pos="right"] .smart-section-header .toggle,
391
+ [data-arrow-pos="right"] .trash-section-header .toggle,
392
+ [data-arrow-pos="right"] .tree-section-header .toggle,
393
+ [data-arrow-pos="right"] .tags-section-header .toggle,
394
+ [data-arrow-pos="right"] .tree-item.folder .toggle {
395
+ order: 3;
396
+ width: auto;
397
+ margin-left: 2px;
398
+ font-size: 8px;
399
+ opacity: 0.75;
400
+ }
401
+ [data-arrow-pos="right"] .pinned-section-header .count,
402
+ [data-arrow-pos="right"] .smart-section-header .count,
403
+ [data-arrow-pos="right"] .trash-section-header .count,
404
+ [data-arrow-pos="right"] .tree-section-header .count,
405
+ [data-arrow-pos="right"] .tags-section-header .count,
406
+ [data-arrow-pos="right"] .tree-item.folder .count {
407
+ order: 4; /* after the chevron (order 3): text › ......... count */
408
+ margin-left: auto;
409
+ }
410
+ .pinned-section-header .icon,
411
+ .smart-section-header .icon,
412
+ .trash-section-header .icon,
413
+ .tree-section-header .icon,
414
+ .tags-section-header .icon {
415
+ font-size: 12px;
416
+ opacity: 0.85;
417
+ }
418
+ .pinned-section-header:hover,
419
+ .smart-section-header:hover,
420
+ .trash-section-header:hover,
421
+ .tree-section-header:hover,
422
+ .tags-section-header:hover {
423
+ /* Layered over the opaque base: the hover tint is translucent, and these
424
+ * headers are sticky, so tree rows would otherwise scroll through them. */
425
+ background:
426
+ linear-gradient(var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.12)),
427
+ var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.12))),
428
+ var(--joplin-background-color, #1e1e1e);
429
+ }
430
+ /* The notebooks section now has a real header (#31), which draws the
431
+ * section-opening line and the top gap - the wrapper must not repeat them. */
432
+ #main-tree {
433
+ margin: 0 4px 1px;
434
+ padding-top: 2px;
435
+ }
436
+ #main-tree.collapsed { display: none; }
437
+ /* #main-tree already carries the 4px side margins; zero the rows' own so
438
+ * tree counts land on the same right edge as section header counts
439
+ * (they were 4px further left - measured, not eyeballed). */
440
+ #main-tree .tree-item {
441
+ margin-left: 0;
442
+ margin-right: 0;
443
+ }
444
+
445
+ /* Expand animation: children fade/slide in when the USER toggles a section
446
+ * or folder (JS adds .anim-expand only on interactive expands, so panel
447
+ * re-renders don't flash). */
448
+ @keyframes sectionExpand {
449
+ from { opacity: 0; transform: translateY(-4px); }
450
+ to { opacity: 1; transform: none; }
451
+ }
452
+ .anim-expand { animation: sectionExpand 0.16s ease-out; }
453
+
454
+ /* Whichever section comes first sits right under the search bar's own
455
+ * border - no extra line there. */
456
+ #tree-container > div:first-child {
457
+ border-top: none;
458
+ margin-top: 0;
459
+ padding-top: 4px;
460
+ }
461
+
462
+ .pinned-section-body.collapsed {
463
+ display: none;
464
+ }
465
+
466
+ .pinned-item {
467
+ padding-left: 26px !important;
468
+ }
469
+
470
+ /* (Section rows are .tree-item.folder too - covered by the arrow-position
471
+ * rules above.) */
472
+
473
+ /* ---- tags section (tags as folders) ---- */
474
+ .tags-section-body.collapsed { display: none; }
475
+ /* Smart folders sit right under the pinned body, whose border-bottom
476
+ * already draws the divider - a border-top here doubled the line. The
477
+ * section closes with its own bottom divider before the tree instead. */
478
+ .smart-section-body.collapsed { display: none; }
479
+ /* Empty smart folder: keeps its folder shape (arrow included) but dimmed,
480
+ * and clicking it does nothing (no children container exists). */
481
+ .smart-folder.smart-empty { opacity: 0.45; }
482
+ .smart-folder.smart-empty:hover { background: none; cursor: default; }
483
+ .smart-children.collapsed { display: none; }
484
+ .trash-children.collapsed { display: none; }
485
+ /* Rows swept out of view when an ancestor trash folder is collapsed */
486
+ .trash-hidden { display: none; }
487
+ /* Rows carry inline padding (depth-based); containers only need hide/show */
488
+ .trash-folder-children.collapsed { display: none; }
489
+ .trash-note .label { opacity: 0.75; }
490
+ .tag-folder { padding-left: 26px !important; }
491
+ .tag-children { }
492
+ .tag-children.collapsed { display: none; }
493
+ .tag-children .tree-item.note { padding-left: 44px !important; }
494
+ .tag-empty {
495
+ padding: 2px 8px 2px 44px;
496
+ color: var(--joplin-color-faded, #888);
497
+ font-size: 11px;
498
+ }
499
+
500
+ /* Empty drop zone — sticky at bottom of scroll viewport */
501
+ .drop-zone-empty {
502
+ position: sticky;
503
+ bottom: 0;
504
+ height: 32px;
505
+ flex-shrink: 0;
506
+ opacity: 0;
507
+ pointer-events: none;
508
+ transition: opacity 0.15s;
509
+ }
510
+
511
+ /* Only show during drag (activated by JS class on tree-container) */
512
+ #tree-container.dragging-active .drop-zone-empty {
513
+ opacity: 1;
514
+ pointer-events: auto;
515
+ border: 2px dashed var(--joplin-url-color, #4a9cf5);
516
+ border-radius: 6px;
517
+ margin: 4px 8px;
518
+ text-align: center;
519
+ line-height: 28px;
520
+ font-size: 11px;
521
+ color: var(--joplin-url-color, #4a9cf5);
522
+ /* Solid panel base under the blue tint - the zone floats (sticky) above
523
+ * tree rows, so a translucent-only background let them bleed through. */
524
+ background: linear-gradient(rgba(74, 156, 245, 0.15), rgba(74, 156, 245, 0.15)),
525
+ var(--joplin-background-color, #1e1e1e);
526
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.25);
527
+ z-index: 10;
528
+ }
529
+
530
+ /* Temporary drop target when the pinned section is empty (#13): sticky so
531
+ * it stays visible however far the tree is scrolled (same pattern as the
532
+ * drop-zone-empty bar). */
533
+ #pinned-drop-ph {
534
+ position: sticky;
535
+ top: 0;
536
+ z-index: 10;
537
+ justify-content: center;
538
+ border: 2px dashed var(--joplin-url-color, #4a9cf5);
539
+ border-radius: 6px;
540
+ margin: 4px 8px;
541
+ padding: 6px 8px;
542
+ color: var(--joplin-url-color, #4a9cf5);
543
+ font-size: 12px;
544
+ background: linear-gradient(rgba(74, 156, 245, 0.15), rgba(74, 156, 245, 0.15)),
545
+ var(--joplin-background-color, #1e1e1e);
546
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
547
+ }
548
+
549
+ /* Pinned section accepts drops during drag — outline doesn't affect layout */
550
+ #tree-container.dragging-active .pinned-section-header {
551
+ outline: 2px dashed var(--joplin-url-color, #4a9cf5);
552
+ outline-offset: -2px;
553
+ }
554
+
555
+ /* Drag & Drop */
556
+ .tree-item.dragging {
557
+ opacity: 0.35;
558
+ filter: grayscale(30%);
559
+ }
560
+
561
+ .tree-item.drop-target {
562
+ background: var(--joplin-selected-color, rgba(74, 156, 245, 0.28));
563
+ outline: 2px solid var(--joplin-url-color, #4a9cf5);
564
+ outline-offset: -2px;
565
+ border-radius: 4px;
566
+ box-shadow: 0 0 0 2px rgba(74, 156, 245, 0.15);
567
+ }
568
+
569
+ /* Horizontal insertion bar (above/below) — position:relative only when active */
570
+ .tree-item.drop-above,
571
+ .tree-item.drop-below {
572
+ position: relative;
573
+ }
574
+
575
+ .tree-item.drop-above::before,
576
+ .tree-item.drop-below::before {
577
+ content: '';
578
+ position: absolute;
579
+ left: 4px;
580
+ right: 4px;
581
+ height: 3px;
582
+ background: var(--joplin-url-color, #4a9cf5);
583
+ border-radius: 2px;
584
+ box-shadow: 0 0 4px rgba(74, 156, 245, 0.6);
585
+ pointer-events: none;
586
+ z-index: 5;
587
+ }
588
+
589
+ .tree-item.drop-above::before {
590
+ top: -2px;
591
+ }
592
+
593
+ .tree-item.drop-below::before {
594
+ bottom: -2px;
595
+ }
596
+
597
+ /* Dropping into empty area -> create new notebook */
598
+ #tree-container.drop-empty {
599
+ box-shadow: inset 0 0 0 2px var(--joplin-url-color, #4a9cf5);
600
+ background: rgba(74, 156, 245, 0.06);
601
+ }
602
+
603
+
604
+ #search-results {
605
+ flex: 1;
606
+ overflow-y: scroll;
607
+ padding: 4px 0;
608
+ }
609
+
610
+ #search-results::-webkit-scrollbar {
611
+ width: 8px;
612
+ }
613
+
614
+ #search-results::-webkit-scrollbar-track {
615
+ background: transparent;
616
+ }
617
+
618
+ #search-results::-webkit-scrollbar-thumb {
619
+ background: var(--joplin-color-faded, #888);
620
+ border-radius: 4px;
621
+ }
622
+
623
+ /* Search results */
624
+ .search-status {
625
+ padding: 8px 12px;
626
+ font-size: 11px;
627
+ color: var(--joplin-color-faded, #888);
628
+ border-bottom: 1px solid var(--joplin-divider-color, #eee);
629
+ }
630
+
631
+ .search-result-item {
632
+ display: flex;
633
+ align-items: flex-start;
634
+ padding: 8px 10px;
635
+ gap: 8px;
636
+ min-height: auto;
637
+ margin: 0; /* override .tree-item margin for note items in search results */
638
+ border-radius: 0;
639
+ }
640
+
641
+ .search-result-item .icon {
642
+ flex-shrink: 0;
643
+ font-size: 12px;
644
+ width: 18px;
645
+ text-align: center;
646
+ line-height: 16.8px; /* match .search-result-title 12px * 1.4 */
647
+ }
648
+
649
+ .search-result-content {
650
+ flex: 1;
651
+ min-width: 0;
652
+ overflow: hidden;
653
+ }
654
+
655
+ .search-result-title {
656
+ font-weight: 600;
657
+ font-size: 12px;
658
+ line-height: 1.4;
659
+ white-space: nowrap;
660
+ overflow: hidden;
661
+ text-overflow: ellipsis;
662
+ }
663
+
664
+ .search-result-folder {
665
+ font-size: 10px;
666
+ color: var(--joplin-color-faded, #999);
667
+ margin-top: 1px;
668
+ }
669
+
670
+ .search-result-snippet {
671
+ font-size: 11px;
672
+ color: var(--joplin-color-faded, #777);
673
+ margin-top: 3px;
674
+ line-height: 1.4;
675
+ display: -webkit-box;
676
+ -webkit-line-clamp: 2;
677
+ -webkit-box-orient: vertical;
678
+ overflow: hidden;
679
+ word-break: break-all;
680
+ }
681
+
682
+ /* Search section headers */
683
+ .search-section-header {
684
+ padding: 6px 10px;
685
+ font-size: 11px;
686
+ font-weight: 700;
687
+ color: var(--joplin-color-faded, #888);
688
+ background: var(--joplin-background-color3, rgba(100, 100, 100, 0.06));
689
+ border-bottom: 1px solid var(--joplin-divider-color, #eee);
690
+ text-transform: uppercase;
691
+ letter-spacing: 0.5px;
692
+ cursor: pointer;
693
+ user-select: none;
694
+ }
695
+
696
+ .search-section-header:hover {
697
+ background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.12));
698
+ }
699
+
700
+ .section-toggle {
701
+ display: inline-block;
702
+ font-size: 9px;
703
+ width: 12px;
704
+ text-align: center;
705
+ transition: transform 0.15s;
706
+ }
707
+
708
+ .search-section-body.collapsed {
709
+ display: none;
710
+ }
711
+
712
+ /* Tag items in search results */
713
+ .search-tag-item {
714
+ cursor: pointer;
715
+ }
716
+
717
+ .search-tag-item:hover {
718
+ background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
719
+ }
720
+
721
+ .tag-expand-arrow {
722
+ flex-shrink: 0;
723
+ font-size: 9px;
724
+ color: var(--joplin-color-faded, #888);
725
+ transition: transform 0.15s;
726
+ margin-right: 4px;
727
+ }
728
+
729
+ .tag-expand-arrow.expanded {
730
+ transform: rotate(90deg);
731
+ }
732
+
733
+ .tag-notes-container {
734
+ padding-left: 16px;
735
+ border-left: 2px solid var(--joplin-divider-color, #eee);
736
+ margin-left: 18px;
737
+ }
738
+
739
+ /* Folder items in search results */
740
+ .search-folder-item {
741
+ cursor: pointer;
742
+ }
743
+
744
+ .search-folder-item:hover {
745
+ background: var(--joplin-background-color-hover3, rgba(100, 100, 100, 0.1));
746
+ }
747
+
748
+ /* Flash highlight when locating a folder from search */
749
+ @keyframes locate-pulse {
750
+ 0% { background: rgba(74, 156, 245, 0.5); }
751
+ 100% { background: transparent; }
752
+ }
753
+
754
+ .tree-item.locate-flash {
755
+ animation: locate-pulse 1.5s ease-out;
756
+ border-radius: 4px;
757
+ }
758
+
759
+ /* Inline input dialog */
760
+ .inline-input-overlay {
761
+ position: fixed;
762
+ top: 0; left: 0; right: 0; bottom: 0;
763
+ background: rgba(0, 0, 0, 0.3);
764
+ display: flex;
765
+ align-items: center;
766
+ justify-content: center;
767
+ z-index: 10000;
768
+ }
769
+
770
+ .inline-input-dialog {
771
+ background: var(--joplin-background-color, #fff);
772
+ border: 1px solid var(--joplin-divider-color, #ccc);
773
+ border-radius: 8px;
774
+ padding: 16px;
775
+ min-width: 240px;
776
+ max-width: 90%;
777
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
778
+ }
779
+
780
+ .inline-input-label {
781
+ font-size: 12px;
782
+ margin-bottom: 8px;
783
+ color: var(--joplin-color);
784
+ }
785
+
786
+ .inline-input-field {
787
+ width: 100%;
788
+ box-sizing: border-box;
789
+ padding: 6px 8px;
790
+ border: 1px solid var(--joplin-divider-color, #ccc);
791
+ border-radius: 4px;
792
+ background: var(--joplin-background-color, #fff);
793
+ color: var(--joplin-color);
794
+ font-size: 13px;
795
+ outline: none;
796
+ }
797
+
798
+ .inline-input-field:focus {
799
+ border-color: var(--joplin-url-color, #4a9cf5);
800
+ box-shadow: 0 0 0 2px var(--joplin-selected-color, rgba(74, 156, 245, 0.2));
801
+ }
802
+
803
+ .inline-input-buttons {
804
+ display: flex;
805
+ gap: 8px;
806
+ margin-top: 12px;
807
+ justify-content: flex-end;
808
+ }
809
+
810
+ .inline-input-buttons button {
811
+ padding: 5px 16px;
812
+ border: 1px solid var(--joplin-divider-color, #ccc);
813
+ border-radius: 4px;
814
+ cursor: pointer;
815
+ font-size: 12px;
816
+ color: var(--joplin-color);
817
+ background: var(--joplin-background-color3, #f0f0f0);
818
+ }
819
+
820
+ .inline-input-ok {
821
+ background: #1a73e8 !important;
822
+ color: #fff !important;
823
+ border-color: #1a73e8 !important;
824
+ }
825
+
826
+ .inline-input-buttons button:hover {
827
+ opacity: 0.85;
828
+ }
829
+
830
+ mark.search-highlight {
831
+ background: rgba(255, 213, 0, 0.4);
832
+ color: inherit;
833
+ padding: 0 1px;
834
+ border-radius: 2px;
835
+ }
836
+
837
+ /* ---- Note-row badges: checkbox progress pie + published link ---- */
838
+ /* Hug the badges to the title text instead of the row's right edge. */
839
+ .tree-item.note .label { flex: 0 1 auto; }
840
+ .todo-pie, .shared-badge {
841
+ flex-shrink: 0;
842
+ display: inline-flex;
843
+ align-items: center;
844
+ }
845
+ .todo-pie svg, .shared-badge svg { display: block; }
846
+ /* Same box metrics as .count (min-width 16 + 5px side padding) so the
847
+ pie centers exactly where count digits center. */
848
+ .todo-pie {
849
+ color: var(--joplin-color-faded, #888);
850
+ margin-left: auto;
851
+ min-width: 16px;
852
+ padding: 0 5px;
853
+ justify-content: center;
854
+ }
855
+ .todo-pie .pie-ring { fill: none; stroke: currentColor; stroke-width: 1.5; opacity: 0.55; }
856
+ .todo-pie .pie-fill { fill: currentColor; opacity: 0.8; }
857
+ .shared-badge {
858
+ color: var(--joplin-color-faded, #999);
859
+ opacity: 0.75;
860
+ cursor: pointer;
861
+ padding: 2px;
862
+ border-radius: 3px;
863
+ }
864
+ .shared-badge:hover {
865
+ opacity: 1;
866
+ color: inherit;
867
+ background: rgba(127, 127, 127, 0.25);
868
+ }