floatnote 1.0.0 → 1.0.5

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 (68) hide show
  1. package/bin/floatnote.js +16 -0
  2. package/package.json +13 -5
  3. package/.beads/config.json +0 -6
  4. package/.beads/issues/floatnote-1.md +0 -21
  5. package/.beads/issues/floatnote-10.md +0 -28
  6. package/.beads/issues/floatnote-11.md +0 -36
  7. package/.beads/issues/floatnote-12.md +0 -25
  8. package/.beads/issues/floatnote-13.md +0 -37
  9. package/.beads/issues/floatnote-14.md +0 -22
  10. package/.beads/issues/floatnote-15.md +0 -22
  11. package/.beads/issues/floatnote-16.md +0 -20
  12. package/.beads/issues/floatnote-17.md +0 -20
  13. package/.beads/issues/floatnote-18.md +0 -21
  14. package/.beads/issues/floatnote-19.md +0 -19
  15. package/.beads/issues/floatnote-2.md +0 -32
  16. package/.beads/issues/floatnote-20.md +0 -22
  17. package/.beads/issues/floatnote-3.md +0 -50
  18. package/.beads/issues/floatnote-4.md +0 -31
  19. package/.beads/issues/floatnote-5.md +0 -28
  20. package/.beads/issues/floatnote-6.md +0 -30
  21. package/.beads/issues/floatnote-7.md +0 -38
  22. package/.beads/issues/floatnote-8.md +0 -29
  23. package/.beads/issues/floatnote-9.md +0 -32
  24. package/CLAUDE.md +0 -61
  25. package/coverage/base.css +0 -224
  26. package/coverage/bin/floatnote.js.html +0 -739
  27. package/coverage/bin/index.html +0 -116
  28. package/coverage/block-navigation.js +0 -87
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +0 -131
  31. package/coverage/lcov-report/base.css +0 -224
  32. package/coverage/lcov-report/bin/floatnote.js.html +0 -739
  33. package/coverage/lcov-report/bin/index.html +0 -116
  34. package/coverage/lcov-report/block-navigation.js +0 -87
  35. package/coverage/lcov-report/favicon.png +0 -0
  36. package/coverage/lcov-report/index.html +0 -131
  37. package/coverage/lcov-report/prettify.css +0 -1
  38. package/coverage/lcov-report/prettify.js +0 -2
  39. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  40. package/coverage/lcov-report/sorter.js +0 -210
  41. package/coverage/lcov-report/src/index.html +0 -146
  42. package/coverage/lcov-report/src/main.js.html +0 -1483
  43. package/coverage/lcov-report/src/preload.js.html +0 -361
  44. package/coverage/lcov-report/src/renderer.js.html +0 -8767
  45. package/coverage/lcov.info +0 -3273
  46. package/coverage/prettify.css +0 -1
  47. package/coverage/prettify.js +0 -2
  48. package/coverage/sort-arrow-sprite.png +0 -0
  49. package/coverage/sorter.js +0 -210
  50. package/coverage/src/index.html +0 -146
  51. package/coverage/src/main.js.html +0 -1483
  52. package/coverage/src/preload.js.html +0 -361
  53. package/coverage/src/renderer.js.html +0 -8767
  54. package/jest.config.js +0 -48
  55. package/src/icon-template.png +0 -0
  56. package/src/index.html +0 -296
  57. package/src/main.js +0 -494
  58. package/src/preload.js +0 -96
  59. package/src/renderer.js +0 -3203
  60. package/src/styles.css +0 -1448
  61. package/tests/cli/floatnote.test.js +0 -167
  62. package/tests/main/main.test.js +0 -287
  63. package/tests/mocks/electron.js +0 -126
  64. package/tests/mocks/fs.js +0 -17
  65. package/tests/preload/preload.test.js +0 -218
  66. package/tests/renderer/history.test.js +0 -234
  67. package/tests/renderer/notes.test.js +0 -262
  68. package/tests/renderer/settings.test.js +0 -178
package/src/styles.css DELETED
@@ -1,1448 +0,0 @@
1
- * {
2
- margin: 0;
3
- padding: 0;
4
- box-sizing: border-box;
5
- }
6
-
7
- html, body {
8
- width: 100%;
9
- height: 100%;
10
- overflow: hidden;
11
- background: transparent;
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
- /* Disable text selection everywhere by default */
14
- -webkit-user-select: none;
15
- user-select: none;
16
- }
17
-
18
- /* Allow text selection in editable elements */
19
- input, textarea, [contenteditable="true"] {
20
- -webkit-user-select: text;
21
- user-select: text;
22
- }
23
-
24
- #app {
25
- width: 100%;
26
- height: 100%;
27
- position: relative;
28
- background: transparent;
29
- border-radius: 12px;
30
- overflow: hidden;
31
- border: 3px solid transparent;
32
- transition: border-color 0.2s ease, box-shadow 0.3s ease;
33
- }
34
-
35
- /* Light grey border when focused */
36
- #app.focused {
37
- border-color: rgba(160, 160, 160, 0.5);
38
- }
39
-
40
- /* Yellow border while resizing */
41
- #app.resizing {
42
- border-color: #facc15;
43
- box-shadow:
44
- 0 0 15px rgba(250, 204, 21, 0.4),
45
- 0 0 30px rgba(250, 204, 21, 0.2);
46
- }
47
-
48
- /* Background modes - only apply when focused */
49
- #app.bg-transparent {
50
- background: transparent;
51
- }
52
-
53
- #app.bg-blur {
54
- background: transparent;
55
- }
56
-
57
- #app.bg-dark {
58
- background: transparent;
59
- }
60
-
61
- /* Apply background only when focused */
62
- #app.focused.bg-blur {
63
- background: rgba(128, 128, 128, 0.3);
64
- backdrop-filter: blur(30px) saturate(180%);
65
- -webkit-backdrop-filter: blur(30px) saturate(180%);
66
- }
67
-
68
- #app.focused.bg-dark {
69
- background: rgba(20, 20, 20, 0.9);
70
- }
71
-
72
- /* Inactive background modes */
73
- #app.inactive-bg-blur:not(.focused) {
74
- background: rgba(128, 128, 128, 0.2);
75
- backdrop-filter: blur(20px) saturate(150%);
76
- -webkit-backdrop-filter: blur(20px) saturate(150%);
77
- }
78
-
79
- #app.inactive-bg-dark:not(.focused) {
80
- background: rgba(20, 20, 20, 0.7);
81
- }
82
-
83
- /* Pin bounce animation */
84
- @keyframes pin-bounce {
85
- 0% { transform: scale(1); }
86
- 25% { transform: scale(1.3); }
87
- 50% { transform: scale(0.9); }
88
- 75% { transform: scale(1.1); }
89
- 100% { transform: scale(1); }
90
- }
91
-
92
- .pin-toggle.animate .pin-icon {
93
- animation: pin-bounce 0.4s ease-out;
94
- }
95
-
96
- /* Drag handle - bar at top for moving window */
97
- #drag-handle {
98
- position: absolute;
99
- top: 0;
100
- left: 24px;
101
- right: 24px;
102
- height: 24px;
103
- -webkit-app-region: drag;
104
- cursor: move;
105
- z-index: 1000;
106
- background: transparent;
107
- transition: background 0.2s ease;
108
- }
109
-
110
- #drag-handle:hover {
111
- background: rgba(255, 255, 255, 0.15);
112
- }
113
-
114
- /* Toolbar - Apple-style floating bar (right aligned) */
115
- #toolbar {
116
- position: absolute;
117
- top: 12px;
118
- right: 12px;
119
- transform: translateY(-5px);
120
- display: flex;
121
- align-items: center;
122
- gap: 6px;
123
- padding: 6px 10px;
124
- background: rgba(40, 40, 40, 0.85);
125
- backdrop-filter: blur(20px) saturate(180%);
126
- -webkit-backdrop-filter: blur(20px) saturate(180%);
127
- border-radius: 12px;
128
- border: 1px solid rgba(255, 255, 255, 0.1);
129
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 1px rgba(255, 255, 255, 0.1) inset;
130
- z-index: 100;
131
- -webkit-app-region: drag;
132
- cursor: move;
133
- opacity: 0;
134
- pointer-events: none;
135
- transition: opacity 0.2s ease, transform 0.2s ease;
136
- }
137
-
138
- #app:hover #toolbar {
139
- opacity: 1;
140
- pointer-events: auto;
141
- transform: translateY(0);
142
- }
143
-
144
- /* Size toolbar - left aligned island */
145
- #size-toolbar {
146
- position: absolute;
147
- top: 12px;
148
- left: 12px;
149
- transform: translateY(-5px);
150
- display: flex;
151
- align-items: center;
152
- gap: 6px;
153
- padding: 6px 10px;
154
- background: rgba(40, 40, 40, 0.85);
155
- backdrop-filter: blur(20px) saturate(180%);
156
- -webkit-backdrop-filter: blur(20px) saturate(180%);
157
- border-radius: 12px;
158
- border: 1px solid rgba(255, 255, 255, 0.1);
159
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 1px rgba(255, 255, 255, 0.1) inset;
160
- z-index: 100;
161
- -webkit-app-region: drag;
162
- cursor: move;
163
- opacity: 0;
164
- pointer-events: none;
165
- transition: opacity 0.2s ease, transform 0.2s ease;
166
- }
167
-
168
- /* Size toolbar dropdown should open to the right, not left */
169
- #size-toolbar .dropdown-menu {
170
- left: 0;
171
- right: auto;
172
- }
173
-
174
- #app:hover #size-toolbar {
175
- opacity: 1;
176
- pointer-events: auto;
177
- transform: translateY(0);
178
- }
179
-
180
- .toolbar-group {
181
- display: flex;
182
- align-items: center;
183
- gap: 4px;
184
- -webkit-app-region: no-drag;
185
- }
186
-
187
- .toolbar-divider {
188
- width: 1px;
189
- height: 24px;
190
- background: rgba(255, 255, 255, 0.2);
191
- }
192
-
193
- .tool-btn {
194
- width: 32px;
195
- height: 32px;
196
- display: flex;
197
- align-items: center;
198
- justify-content: center;
199
- background: rgba(255, 255, 255, 0.1);
200
- border: none;
201
- border-radius: 6px;
202
- color: white;
203
- cursor: pointer;
204
- transition: background 0.15s ease;
205
- -webkit-app-region: no-drag;
206
- }
207
-
208
- .tool-btn:hover {
209
- background: rgba(255, 255, 255, 0.2);
210
- }
211
-
212
- .tool-btn.active {
213
- background: rgba(255, 255, 255, 0.25);
214
- }
215
-
216
- .tool-btn.danger {
217
- background: rgba(239, 68, 68, 0.3);
218
- }
219
-
220
- .tool-btn.danger:hover {
221
- background: rgba(239, 68, 68, 0.5);
222
- }
223
-
224
- /* Color swatch button */
225
- .color-swatch-btn {
226
- padding: 4px !important;
227
- }
228
-
229
- .current-color {
230
- width: 18px;
231
- height: 18px;
232
- border-radius: 50%;
233
- border: 2px solid rgba(255, 255, 255, 0.3);
234
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
235
- }
236
-
237
- /* Color dropdown grid */
238
- .color-dropdown {
239
- padding: 8px !important;
240
- }
241
-
242
- .color-grid {
243
- display: grid;
244
- grid-template-columns: repeat(4, 1fr);
245
- gap: 6px;
246
- }
247
-
248
- .color-grid .color-btn {
249
- width: 28px;
250
- height: 28px;
251
- border: 2px solid transparent;
252
- border-radius: 50%;
253
- cursor: pointer;
254
- transition: transform 0.15s ease, border-color 0.15s ease;
255
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
256
- }
257
-
258
- .color-grid .color-btn:hover {
259
- transform: scale(1.1);
260
- }
261
-
262
- .color-grid .color-btn.active {
263
- border-color: #facc15;
264
- box-shadow: 0 0 0 2px rgba(250, 204, 21, 0.3);
265
- }
266
-
267
- /* Stroke toggle button */
268
- .current-stroke {
269
- width: 8px;
270
- height: 8px;
271
- background: white;
272
- border-radius: 50%;
273
- }
274
-
275
- /* Stroke dropdown */
276
- .stroke-dropdown {
277
- min-width: 100px;
278
- }
279
-
280
- .stroke-option {
281
- display: flex;
282
- align-items: center;
283
- gap: 10px;
284
- width: 100%;
285
- padding: 8px 12px;
286
- background: transparent;
287
- border: none;
288
- border-radius: 6px;
289
- color: white;
290
- font-size: 12px;
291
- cursor: pointer;
292
- transition: background 0.15s ease;
293
- }
294
-
295
- .stroke-option:hover {
296
- background: rgba(255, 255, 255, 0.1);
297
- }
298
-
299
- .stroke-option.active {
300
- background: rgba(255, 255, 255, 0.08);
301
- }
302
-
303
- .stroke-option.active::after {
304
- content: '✓';
305
- margin-left: auto;
306
- color: #facc15;
307
- }
308
-
309
- .stroke-dot {
310
- background: white;
311
- border-radius: 50%;
312
- flex-shrink: 0;
313
- }
314
-
315
- /* Pin toggle */
316
- .pin-toggle {
317
- display: flex;
318
- align-items: center;
319
- justify-content: center;
320
- width: 32px;
321
- height: 32px;
322
- cursor: pointer;
323
- border-radius: 6px;
324
- transition: background 0.15s ease;
325
- -webkit-app-region: no-drag;
326
- }
327
-
328
- .pin-toggle:hover {
329
- background: rgba(255, 255, 255, 0.1);
330
- }
331
-
332
- .pin-toggle input {
333
- display: none;
334
- }
335
-
336
- .pin-toggle .pin-icon {
337
- color: rgba(255, 255, 255, 0.4);
338
- transition: color 0.15s ease, transform 0.15s ease;
339
- }
340
-
341
- .pin-toggle input:checked + .pin-icon {
342
- color: #facc15;
343
- transform: rotate(45deg);
344
- }
345
-
346
- .pin-toggle:hover .pin-icon {
347
- color: rgba(255, 255, 255, 0.7);
348
- }
349
-
350
- .pin-toggle input:checked:hover + .pin-icon {
351
- color: #fde047;
352
- }
353
-
354
- /* Dropdown container */
355
- .dropdown-container {
356
- position: relative;
357
- -webkit-app-region: no-drag;
358
- }
359
-
360
- .dropdown-menu {
361
- position: absolute;
362
- top: 100%;
363
- right: 0;
364
- margin-top: 4px;
365
- min-width: 120px;
366
- background: rgba(30, 30, 30, 0.95);
367
- backdrop-filter: blur(10px);
368
- -webkit-backdrop-filter: blur(10px);
369
- border-radius: 8px;
370
- border: 1px solid rgba(255, 255, 255, 0.15);
371
- padding: 4px;
372
- opacity: 0;
373
- visibility: hidden;
374
- transform: translateY(-4px);
375
- transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
376
- }
377
-
378
- .dropdown-container:hover .dropdown-menu {
379
- opacity: 1;
380
- visibility: visible;
381
- transform: translateY(0);
382
- }
383
-
384
- .dropdown-item {
385
- display: flex;
386
- align-items: center;
387
- gap: 8px;
388
- width: 100%;
389
- padding: 8px 10px;
390
- background: transparent;
391
- border: none;
392
- border-radius: 6px;
393
- color: white;
394
- font-size: 12px;
395
- cursor: pointer;
396
- transition: background 0.15s ease;
397
- }
398
-
399
- .dropdown-item:hover {
400
- background: rgba(255, 255, 255, 0.15);
401
- }
402
-
403
- .dropdown-item.active {
404
- background: rgba(255, 255, 255, 0.1);
405
- }
406
-
407
- .dropdown-item.active::after {
408
- content: '✓';
409
- margin-left: auto;
410
- color: #facc15;
411
- }
412
-
413
- .bg-preview {
414
- width: 16px;
415
- height: 16px;
416
- border-radius: 4px;
417
- border: 1px solid rgba(255, 255, 255, 0.3);
418
- }
419
-
420
- .bg-preview.transparent {
421
- background: linear-gradient(45deg, #666 25%, transparent 25%),
422
- linear-gradient(-45deg, #666 25%, transparent 25%),
423
- linear-gradient(45deg, transparent 75%, #666 75%),
424
- linear-gradient(-45deg, transparent 75%, #666 75%);
425
- background-size: 8px 8px;
426
- background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
427
- }
428
-
429
- .bg-preview.blur {
430
- background: rgba(255, 255, 255, 0.2);
431
- backdrop-filter: blur(4px);
432
- }
433
-
434
- .bg-preview.dark {
435
- background: rgba(30, 30, 30, 0.9);
436
- }
437
-
438
- /* Size dropdown */
439
- .size-label {
440
- font-weight: 600;
441
- font-size: 11px;
442
- }
443
-
444
- .size-desc {
445
- color: rgba(255, 255, 255, 0.5);
446
- font-size: 10px;
447
- }
448
-
449
- /* Drawing canvas - fully transparent */
450
- #draw-canvas {
451
- position: absolute;
452
- top: 0;
453
- left: 0;
454
- width: 100%;
455
- height: 100%;
456
- z-index: 1;
457
- background: transparent;
458
- }
459
-
460
- /* Text container */
461
- #text-container {
462
- position: absolute;
463
- top: 0;
464
- left: 0;
465
- width: 100%;
466
- height: 100%;
467
- pointer-events: none;
468
- z-index: 2;
469
- }
470
-
471
- /* Text items */
472
- .text-item {
473
- position: absolute;
474
- pointer-events: auto;
475
- min-width: 100px;
476
- padding: 6px 10px;
477
- padding-left: 28px;
478
- background: transparent;
479
- border: 2px solid transparent;
480
- border-radius: 6px;
481
- cursor: grab;
482
- transition: border-color 0.15s ease, background 0.15s ease;
483
- }
484
-
485
- .text-item:active {
486
- cursor: grabbing;
487
- }
488
-
489
- /* Text drag handle */
490
- .text-drag-handle {
491
- position: absolute;
492
- left: 4px;
493
- top: 50%;
494
- transform: translateY(-50%);
495
- width: 20px;
496
- height: 20px;
497
- display: flex;
498
- align-items: center;
499
- justify-content: center;
500
- color: rgba(255, 255, 255, 0.4);
501
- cursor: grab;
502
- border-radius: 4px;
503
- transition: color 0.15s ease, background 0.15s ease;
504
- }
505
-
506
- .text-drag-handle:hover {
507
- color: rgba(255, 255, 255, 0.8);
508
- background: rgba(255, 255, 255, 0.1);
509
- }
510
-
511
- .text-drag-handle:active {
512
- cursor: grabbing;
513
- }
514
-
515
- /* Only show text item borders when hovering the app or app is focused */
516
- /* Use subtle border for hover/select, yellow only during drag/resize */
517
- #app:hover .text-item:hover,
518
- #app:hover .text-item.selected,
519
- #app.focused .text-item:hover,
520
- #app.focused .text-item.selected {
521
- background: rgba(0, 0, 0, 0.2);
522
- border-color: rgba(255, 255, 255, 0.3);
523
- }
524
-
525
- /* Yellow border only during active drag or resize operations */
526
- .text-item.dragging,
527
- .text-item.resizing {
528
- border-color: #facc15 !important;
529
- box-shadow: 0 0 10px rgba(250, 204, 21, 0.3);
530
- }
531
-
532
- /* Text format bar */
533
- .text-format-bar {
534
- display: flex;
535
- gap: 2px;
536
- margin-bottom: 4px;
537
- opacity: 0;
538
- transition: opacity 0.15s ease;
539
- }
540
-
541
- .text-item.selected .text-format-bar,
542
- .text-item:hover .text-format-bar {
543
- opacity: 1;
544
- }
545
-
546
- .format-btn {
547
- width: 22px;
548
- height: 22px;
549
- display: flex;
550
- align-items: center;
551
- justify-content: center;
552
- background: rgba(255, 255, 255, 0.1);
553
- border: none;
554
- border-radius: 4px;
555
- color: rgba(255, 255, 255, 0.7);
556
- font-size: 12px;
557
- font-weight: bold;
558
- cursor: pointer;
559
- transition: background 0.15s ease, color 0.15s ease;
560
- }
561
-
562
- .format-btn:hover {
563
- background: rgba(255, 255, 255, 0.2);
564
- color: white;
565
- }
566
-
567
- .format-btn.active {
568
- background: rgba(59, 130, 246, 0.5);
569
- color: white;
570
- }
571
-
572
- .format-btn[data-format="italic"] {
573
- font-style: italic;
574
- }
575
-
576
- .format-btn[data-format="underline"] {
577
- text-decoration: underline;
578
- }
579
-
580
- .format-btn.delete-btn {
581
- color: #ef4444;
582
- margin-left: auto;
583
- }
584
-
585
- .format-btn.delete-btn:hover {
586
- background: rgba(239, 68, 68, 0.3);
587
- color: #ff6b6b;
588
- }
589
-
590
- /* Text input (contentEditable div) */
591
- .text-item .text-input {
592
- width: 100%;
593
- min-width: 150px;
594
- min-height: 20px;
595
- background: transparent;
596
- border: none;
597
- outline: none;
598
- color: white;
599
- font-size: 16px;
600
- font-family: inherit;
601
- overflow-wrap: break-word;
602
- word-wrap: break-word;
603
- white-space: pre-wrap;
604
- text-shadow:
605
- 0 1px 2px rgba(0, 0, 0, 0.9),
606
- 0 0 4px rgba(0, 0, 0, 0.7);
607
- }
608
-
609
- /* Placeholder for contentEditable */
610
- .text-item .text-input:empty::before {
611
- content: attr(data-placeholder);
612
- color: rgba(255, 255, 255, 0.5);
613
- pointer-events: none;
614
- }
615
-
616
- /* Rich text formatting styles */
617
- .text-item .text-input b,
618
- .text-item .text-input strong {
619
- font-weight: bold;
620
- }
621
-
622
- .text-item .text-input i,
623
- .text-item .text-input em {
624
- font-style: italic;
625
- }
626
-
627
- .text-item .text-input u {
628
- text-decoration: underline;
629
- }
630
-
631
- /* Resize handles - corners and edges */
632
- .resize-handle {
633
- position: absolute;
634
- background: transparent;
635
- z-index: 1001;
636
- -webkit-app-region: no-drag;
637
- }
638
-
639
- /* Corner handles */
640
- .resize-handle.se {
641
- right: 0;
642
- bottom: 0;
643
- width: 24px;
644
- height: 24px;
645
- cursor: se-resize;
646
- }
647
-
648
- .resize-handle.sw {
649
- left: 0;
650
- bottom: 0;
651
- width: 24px;
652
- height: 24px;
653
- cursor: sw-resize;
654
- }
655
-
656
- .resize-handle.ne {
657
- right: 0;
658
- top: 0;
659
- width: 24px;
660
- height: 24px;
661
- cursor: ne-resize;
662
- }
663
-
664
- .resize-handle.nw {
665
- left: 0;
666
- top: 0;
667
- width: 24px;
668
- height: 24px;
669
- cursor: nw-resize;
670
- }
671
-
672
- /* Edge handles */
673
- .resize-handle.n {
674
- top: 0;
675
- left: 24px;
676
- right: 24px;
677
- height: 8px;
678
- cursor: n-resize;
679
- }
680
-
681
- .resize-handle.s {
682
- bottom: 0;
683
- left: 24px;
684
- right: 24px;
685
- height: 8px;
686
- cursor: s-resize;
687
- }
688
-
689
- .resize-handle.e {
690
- right: 0;
691
- top: 24px;
692
- bottom: 24px;
693
- width: 8px;
694
- cursor: e-resize;
695
- }
696
-
697
- .resize-handle.w {
698
- left: 0;
699
- top: 24px;
700
- bottom: 24px;
701
- width: 8px;
702
- cursor: w-resize;
703
- }
704
-
705
- /* Hide focus border element - we use glow instead */
706
- #focus-border {
707
- display: none;
708
- }
709
-
710
- /* Zoom controls - bottom left */
711
- #zoom-controls {
712
- position: absolute;
713
- bottom: 12px;
714
- left: 12px;
715
- display: flex;
716
- align-items: center;
717
- gap: 4px;
718
- padding: 6px 10px;
719
- background: rgba(30, 30, 30, 0.9);
720
- backdrop-filter: blur(10px);
721
- -webkit-backdrop-filter: blur(10px);
722
- border-radius: 8px;
723
- border: 1px solid rgba(255, 255, 255, 0.15);
724
- z-index: 100;
725
- opacity: 0;
726
- transform: translateY(5px);
727
- transition: opacity 0.2s ease, transform 0.2s ease;
728
- }
729
-
730
- #app:hover #zoom-controls {
731
- opacity: 1;
732
- transform: translateY(0);
733
- }
734
-
735
- .zoom-btn {
736
- width: 26px;
737
- height: 26px;
738
- display: flex;
739
- align-items: center;
740
- justify-content: center;
741
- background: rgba(255, 255, 255, 0.1);
742
- border: none;
743
- border-radius: 4px;
744
- color: white;
745
- font-size: 16px;
746
- cursor: pointer;
747
- transition: background 0.15s ease;
748
- }
749
-
750
- .zoom-btn:hover {
751
- background: rgba(255, 255, 255, 0.2);
752
- }
753
-
754
- #zoom-indicator {
755
- color: rgba(255, 255, 255, 0.8);
756
- font-size: 12px;
757
- min-width: 40px;
758
- text-align: center;
759
- }
760
-
761
- /* Context menu */
762
- #context-menu {
763
- position: fixed;
764
- min-width: 120px;
765
- background: rgba(30, 30, 30, 0.95);
766
- backdrop-filter: blur(10px);
767
- -webkit-backdrop-filter: blur(10px);
768
- border-radius: 8px;
769
- border: 1px solid rgba(255, 255, 255, 0.15);
770
- padding: 4px;
771
- z-index: 10000;
772
- opacity: 0;
773
- visibility: hidden;
774
- transform: scale(0.95);
775
- transition: opacity 0.1s ease, transform 0.1s ease, visibility 0.1s;
776
- }
777
-
778
- #context-menu.visible {
779
- opacity: 1;
780
- visibility: visible;
781
- transform: scale(1);
782
- }
783
-
784
- .context-menu-item {
785
- display: flex;
786
- align-items: center;
787
- justify-content: space-between;
788
- width: 100%;
789
- padding: 8px 12px;
790
- background: transparent;
791
- border: none;
792
- border-radius: 6px;
793
- color: white;
794
- font-size: 13px;
795
- cursor: pointer;
796
- transition: background 0.15s ease;
797
- }
798
-
799
- .context-menu-item:hover {
800
- background: rgba(255, 255, 255, 0.15);
801
- }
802
-
803
- .context-menu-item .shortcut {
804
- color: rgba(255, 255, 255, 0.5);
805
- font-size: 11px;
806
- }
807
-
808
- .context-menu-item:disabled {
809
- cursor: not-allowed;
810
- }
811
-
812
- .context-menu-divider {
813
- height: 1px;
814
- background: rgba(255, 255, 255, 0.15);
815
- margin: 4px 0;
816
- }
817
-
818
- /* Paste overlay */
819
- .paste-overlay {
820
- position: absolute;
821
- background: rgba(30, 30, 30, 0.95);
822
- backdrop-filter: blur(10px);
823
- -webkit-backdrop-filter: blur(10px);
824
- border-radius: 12px;
825
- border: 2px solid rgba(59, 130, 246, 0.5);
826
- padding: 12px;
827
- z-index: 1000;
828
- cursor: pointer;
829
- transform: translate(-50%, -50%);
830
- max-width: 300px;
831
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
832
- animation: paste-overlay-in 0.2s ease-out;
833
- }
834
-
835
- @keyframes paste-overlay-in {
836
- from {
837
- opacity: 0;
838
- transform: translate(-50%, -50%) scale(0.9);
839
- }
840
- to {
841
- opacity: 1;
842
- transform: translate(-50%, -50%) scale(1);
843
- }
844
- }
845
-
846
- .paste-overlay:hover {
847
- border-color: rgba(59, 130, 246, 0.8);
848
- box-shadow: 0 8px 32px rgba(59, 130, 246, 0.2);
849
- }
850
-
851
- .paste-preview-image {
852
- max-width: 250px;
853
- max-height: 150px;
854
- border-radius: 8px;
855
- object-fit: contain;
856
- display: block;
857
- margin-bottom: 8px;
858
- }
859
-
860
- .paste-preview-text {
861
- max-width: 250px;
862
- max-height: 80px;
863
- overflow: hidden;
864
- color: rgba(255, 255, 255, 0.8);
865
- font-size: 12px;
866
- line-height: 1.4;
867
- margin-bottom: 8px;
868
- padding: 8px;
869
- background: rgba(255, 255, 255, 0.05);
870
- border-radius: 6px;
871
- white-space: pre-wrap;
872
- word-break: break-word;
873
- }
874
-
875
- .paste-label {
876
- display: flex;
877
- align-items: center;
878
- gap: 6px;
879
- color: white;
880
- font-size: 13px;
881
- font-weight: 500;
882
- }
883
-
884
- .paste-icon {
885
- font-size: 16px;
886
- }
887
-
888
- .paste-size {
889
- color: rgba(255, 255, 255, 0.5);
890
- font-size: 11px;
891
- margin-left: auto;
892
- }
893
-
894
- /* Pasted images */
895
- .pasted-image {
896
- position: absolute;
897
- cursor: grab;
898
- border: 2px solid transparent;
899
- border-radius: 8px;
900
- transition: border-color 0.15s ease;
901
- z-index: 5;
902
- }
903
-
904
- .pasted-image:hover,
905
- .pasted-image.selected {
906
- border-color: #3b82f6;
907
- }
908
-
909
- .pasted-image img {
910
- width: 100%;
911
- height: 100%;
912
- object-fit: contain;
913
- border-radius: 6px;
914
- pointer-events: none;
915
- }
916
-
917
- .pasted-image:active {
918
- cursor: grabbing;
919
- }
920
-
921
- .image-delete-btn {
922
- position: absolute;
923
- top: -10px;
924
- right: -10px;
925
- width: 24px;
926
- height: 24px;
927
- border-radius: 50%;
928
- background: #ef4444;
929
- border: 2px solid white;
930
- color: white;
931
- font-size: 12px;
932
- cursor: pointer;
933
- display: flex;
934
- align-items: center;
935
- justify-content: center;
936
- opacity: 0;
937
- transition: opacity 0.15s ease, transform 0.15s ease;
938
- z-index: 10;
939
- }
940
-
941
- .pasted-image:hover .image-delete-btn {
942
- opacity: 1;
943
- }
944
-
945
- .image-delete-btn:hover {
946
- transform: scale(1.1);
947
- background: #dc2626;
948
- }
949
-
950
- .image-resize-handle {
951
- position: absolute;
952
- bottom: -6px;
953
- right: -6px;
954
- width: 16px;
955
- height: 16px;
956
- background: #3b82f6;
957
- border: 2px solid white;
958
- border-radius: 4px;
959
- cursor: se-resize;
960
- opacity: 0;
961
- transition: opacity 0.15s ease;
962
- z-index: 10;
963
- }
964
-
965
- .pasted-image:hover .image-resize-handle {
966
- opacity: 1;
967
- }
968
-
969
- /* Text resize handle */
970
- .text-resize-handle {
971
- position: absolute;
972
- bottom: -4px;
973
- right: -4px;
974
- width: 14px;
975
- height: 14px;
976
- background: #3b82f6;
977
- border: 2px solid white;
978
- border-radius: 3px;
979
- cursor: se-resize;
980
- opacity: 0;
981
- transition: opacity 0.15s ease;
982
- z-index: 10;
983
- }
984
-
985
- .text-item:hover .text-resize-handle,
986
- .text-item.selected .text-resize-handle {
987
- opacity: 1;
988
- }
989
-
990
- .text-resize-handle:hover {
991
- background: #2563eb;
992
- }
993
-
994
- /* Settings panel */
995
- .settings-panel {
996
- position: absolute;
997
- top: 50%;
998
- left: 50%;
999
- transform: translate(-50%, -50%) scale(0.95);
1000
- width: 320px;
1001
- max-height: 80%;
1002
- background: rgba(30, 30, 30, 0.98);
1003
- backdrop-filter: blur(20px);
1004
- -webkit-backdrop-filter: blur(20px);
1005
- border-radius: 16px;
1006
- border: 1px solid rgba(255, 255, 255, 0.15);
1007
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
1008
- z-index: 10000;
1009
- opacity: 0;
1010
- visibility: hidden;
1011
- transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
1012
- overflow: hidden;
1013
- }
1014
-
1015
- .settings-panel.visible {
1016
- opacity: 1;
1017
- visibility: visible;
1018
- transform: translate(-50%, -50%) scale(1);
1019
- }
1020
-
1021
- .settings-header {
1022
- display: flex;
1023
- align-items: center;
1024
- justify-content: space-between;
1025
- padding: 16px 20px;
1026
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
1027
- }
1028
-
1029
- .settings-header h2 {
1030
- color: white;
1031
- font-size: 16px;
1032
- font-weight: 600;
1033
- margin: 0;
1034
- }
1035
-
1036
- .settings-close-btn {
1037
- width: 28px;
1038
- height: 28px;
1039
- display: flex;
1040
- align-items: center;
1041
- justify-content: center;
1042
- background: rgba(255, 255, 255, 0.1);
1043
- border: none;
1044
- border-radius: 6px;
1045
- color: rgba(255, 255, 255, 0.7);
1046
- font-size: 14px;
1047
- cursor: pointer;
1048
- transition: background 0.15s ease, color 0.15s ease;
1049
- }
1050
-
1051
- .settings-close-btn:hover {
1052
- background: rgba(255, 255, 255, 0.2);
1053
- color: white;
1054
- }
1055
-
1056
- .settings-content {
1057
- padding: 16px 20px;
1058
- overflow-y: auto;
1059
- max-height: calc(80vh - 60px);
1060
- }
1061
-
1062
- .settings-section {
1063
- margin-bottom: 20px;
1064
- }
1065
-
1066
- .settings-section:last-child {
1067
- margin-bottom: 0;
1068
- }
1069
-
1070
- .settings-section h3 {
1071
- color: rgba(255, 255, 255, 0.5);
1072
- font-size: 11px;
1073
- font-weight: 600;
1074
- text-transform: uppercase;
1075
- letter-spacing: 0.5px;
1076
- margin: 0 0 12px 0;
1077
- }
1078
-
1079
- .settings-toggle {
1080
- display: flex;
1081
- align-items: center;
1082
- justify-content: space-between;
1083
- padding: 10px 0;
1084
- cursor: pointer;
1085
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
1086
- }
1087
-
1088
- .settings-toggle:last-child {
1089
- border-bottom: none;
1090
- }
1091
-
1092
- .settings-toggle span:first-child {
1093
- color: white;
1094
- font-size: 14px;
1095
- }
1096
-
1097
- .settings-toggle input {
1098
- display: none;
1099
- }
1100
-
1101
- .toggle-slider {
1102
- width: 40px;
1103
- height: 24px;
1104
- background: rgba(255, 255, 255, 0.2);
1105
- border-radius: 12px;
1106
- position: relative;
1107
- transition: background 0.2s ease;
1108
- }
1109
-
1110
- .toggle-slider::after {
1111
- content: '';
1112
- position: absolute;
1113
- top: 2px;
1114
- left: 2px;
1115
- width: 20px;
1116
- height: 20px;
1117
- background: white;
1118
- border-radius: 50%;
1119
- transition: transform 0.2s ease;
1120
- }
1121
-
1122
- .settings-toggle input:checked + .toggle-slider {
1123
- background: #3b82f6;
1124
- }
1125
-
1126
- .settings-toggle input:checked + .toggle-slider::after {
1127
- transform: translateX(16px);
1128
- }
1129
-
1130
- .settings-btn {
1131
- width: 100%;
1132
- padding: 10px 16px;
1133
- margin-top: 10px;
1134
- background: rgba(59, 130, 246, 0.2);
1135
- border: 1px solid rgba(59, 130, 246, 0.4);
1136
- border-radius: 6px;
1137
- color: #3b82f6;
1138
- font-size: 14px;
1139
- cursor: pointer;
1140
- transition: all 0.15s ease;
1141
- }
1142
-
1143
- .settings-btn:hover {
1144
- background: rgba(59, 130, 246, 0.3);
1145
- border-color: rgba(59, 130, 246, 0.6);
1146
- }
1147
-
1148
- .settings-btn:active {
1149
- background: rgba(59, 130, 246, 0.4);
1150
- }
1151
-
1152
- .shortcuts-list {
1153
- display: flex;
1154
- flex-direction: column;
1155
- gap: 8px;
1156
- }
1157
-
1158
- .shortcut-item {
1159
- display: flex;
1160
- align-items: center;
1161
- justify-content: space-between;
1162
- padding: 6px 0;
1163
- }
1164
-
1165
- .shortcut-item span {
1166
- color: rgba(255, 255, 255, 0.8);
1167
- font-size: 13px;
1168
- }
1169
-
1170
- .shortcut-item kbd {
1171
- background: rgba(255, 255, 255, 0.1);
1172
- padding: 4px 8px;
1173
- border-radius: 4px;
1174
- font-family: -apple-system, BlinkMacSystemFont, sans-serif;
1175
- font-size: 11px;
1176
- color: rgba(255, 255, 255, 0.7);
1177
- border: 1px solid rgba(255, 255, 255, 0.1);
1178
- }
1179
-
1180
- /* Left edge resize handle */
1181
- #left-resize-handle {
1182
- position: fixed;
1183
- left: 0;
1184
- top: 0;
1185
- width: 6px;
1186
- height: 100%;
1187
- cursor: ew-resize;
1188
- z-index: 9999;
1189
- background: transparent;
1190
- transition: background 0.15s ease;
1191
- }
1192
-
1193
- #left-resize-handle:hover {
1194
- background: rgba(59, 130, 246, 0.5);
1195
- }
1196
-
1197
- #left-resize-handle:active {
1198
- background: rgba(59, 130, 246, 0.8);
1199
- }
1200
-
1201
- /* Disable pointer events on overlays while drawing */
1202
- #app.drawing .text-item,
1203
- #app.drawing .pasted-image,
1204
- #app.drawing #text-container {
1205
- pointer-events: none;
1206
- }
1207
-
1208
- /* Settings background options */
1209
- .settings-bg-options {
1210
- padding: 10px 0;
1211
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
1212
- }
1213
-
1214
- .settings-label {
1215
- color: white;
1216
- font-size: 14px;
1217
- display: block;
1218
- margin-bottom: 10px;
1219
- }
1220
-
1221
- .bg-option-group {
1222
- display: flex;
1223
- gap: 12px;
1224
- }
1225
-
1226
- .bg-option {
1227
- display: flex;
1228
- flex-direction: column;
1229
- align-items: center;
1230
- gap: 6px;
1231
- cursor: pointer;
1232
- }
1233
-
1234
- .bg-option input {
1235
- display: none;
1236
- }
1237
-
1238
- .bg-option-box {
1239
- width: 48px;
1240
- height: 32px;
1241
- border-radius: 6px;
1242
- border: 2px solid transparent;
1243
- transition: border-color 0.15s ease;
1244
- }
1245
-
1246
- .bg-option-box.transparent {
1247
- background: linear-gradient(45deg, #333 25%, transparent 25%),
1248
- linear-gradient(-45deg, #333 25%, transparent 25%),
1249
- linear-gradient(45deg, transparent 75%, #333 75%),
1250
- linear-gradient(-45deg, transparent 75%, #333 75%);
1251
- background-size: 8px 8px;
1252
- background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
1253
- background-color: #222;
1254
- }
1255
-
1256
- .bg-option-box.blur {
1257
- background: linear-gradient(135deg, rgba(100, 100, 100, 0.5), rgba(150, 150, 150, 0.3));
1258
- backdrop-filter: blur(4px);
1259
- }
1260
-
1261
- .bg-option-box.dark {
1262
- background: rgba(0, 0, 0, 0.7);
1263
- }
1264
-
1265
- .bg-option input:checked + .bg-option-box {
1266
- border-color: #3b82f6;
1267
- }
1268
-
1269
- .bg-option span:last-child {
1270
- color: rgba(255, 255, 255, 0.7);
1271
- font-size: 11px;
1272
- }
1273
-
1274
- /* Note indicator */
1275
- #note-indicator {
1276
- position: fixed;
1277
- bottom: 20px;
1278
- left: 50%;
1279
- transform: translateX(-50%);
1280
- background: rgba(0, 0, 0, 0.8);
1281
- color: white;
1282
- padding: 8px 16px;
1283
- border-radius: 20px;
1284
- font-size: 14px;
1285
- font-weight: 500;
1286
- opacity: 0;
1287
- visibility: hidden;
1288
- transition: opacity 0.3s ease, visibility 0.3s;
1289
- z-index: 9999;
1290
- pointer-events: none;
1291
- }
1292
-
1293
- #note-indicator.visible {
1294
- opacity: 1;
1295
- visibility: visible;
1296
- }
1297
-
1298
- /* Pagination island - right side */
1299
- #pagination-island {
1300
- position: absolute;
1301
- right: 12px;
1302
- bottom: 12px;
1303
- transform: translateY(5px);
1304
- display: flex;
1305
- align-items: center;
1306
- gap: 6px;
1307
- padding: 6px 10px;
1308
- background: rgba(40, 40, 40, 0.85);
1309
- backdrop-filter: blur(20px) saturate(180%);
1310
- -webkit-backdrop-filter: blur(20px) saturate(180%);
1311
- border-radius: 12px;
1312
- border: 1px solid rgba(255, 255, 255, 0.1);
1313
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 1px rgba(255, 255, 255, 0.1) inset;
1314
- opacity: 0;
1315
- visibility: hidden;
1316
- transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
1317
- z-index: 100;
1318
- }
1319
-
1320
- #app:hover #pagination-island,
1321
- #app.focused #pagination-island {
1322
- opacity: 1;
1323
- visibility: visible;
1324
- transform: translateY(0);
1325
- }
1326
-
1327
- .pagination-btn {
1328
- width: 28px;
1329
- height: 28px;
1330
- border: none;
1331
- background: rgba(255, 255, 255, 0.1);
1332
- color: white;
1333
- border-radius: 6px;
1334
- cursor: pointer;
1335
- display: flex;
1336
- align-items: center;
1337
- justify-content: center;
1338
- transition: background 0.15s ease;
1339
- }
1340
-
1341
- .pagination-btn:hover {
1342
- background: rgba(255, 255, 255, 0.2);
1343
- }
1344
-
1345
- .pagination-btn:active {
1346
- background: rgba(255, 255, 255, 0.25);
1347
- }
1348
-
1349
- .pagination-btn:disabled {
1350
- opacity: 0.3;
1351
- cursor: not-allowed;
1352
- background: rgba(255, 255, 255, 0.05);
1353
- }
1354
-
1355
- #note-counter {
1356
- color: white;
1357
- font-size: 13px;
1358
- font-weight: 500;
1359
- min-width: 36px;
1360
- text-align: center;
1361
- }
1362
-
1363
- /* Selection rectangle */
1364
- #selection-rect {
1365
- position: absolute;
1366
- border: 2px dashed #3b82f6;
1367
- background: rgba(59, 130, 246, 0.1);
1368
- pointer-events: none;
1369
- z-index: 500;
1370
- display: none;
1371
- }
1372
-
1373
- #selection-rect.active {
1374
- display: block;
1375
- }
1376
-
1377
- /* Settings slider */
1378
- .settings-slider {
1379
- display: flex;
1380
- align-items: center;
1381
- gap: 12px;
1382
- padding: 8px 0;
1383
- }
1384
-
1385
- .settings-slider .settings-label {
1386
- flex: 1;
1387
- margin-bottom: 0;
1388
- }
1389
-
1390
- .settings-slider input[type="range"] {
1391
- width: 100px;
1392
- height: 4px;
1393
- -webkit-appearance: none;
1394
- background: rgba(255, 255, 255, 0.2);
1395
- border-radius: 2px;
1396
- outline: none;
1397
- }
1398
-
1399
- .settings-slider input[type="range"]::-webkit-slider-thumb {
1400
- -webkit-appearance: none;
1401
- width: 14px;
1402
- height: 14px;
1403
- background: #3b82f6;
1404
- border-radius: 50%;
1405
- cursor: pointer;
1406
- transition: transform 0.1s ease;
1407
- }
1408
-
1409
- .settings-slider input[type="range"]::-webkit-slider-thumb:hover {
1410
- transform: scale(1.2);
1411
- }
1412
-
1413
- .slider-value {
1414
- color: rgba(255, 255, 255, 0.7);
1415
- font-size: 12px;
1416
- min-width: 40px;
1417
- text-align: right;
1418
- }
1419
-
1420
- /* Active/Inactive background classes with opacity support */
1421
- #app {
1422
- --bg-opacity: 1;
1423
- }
1424
-
1425
- #app[data-active-bg="blur"].focused {
1426
- background: rgba(255, 255, 255, calc(0.1 * var(--bg-opacity)));
1427
- backdrop-filter: blur(20px);
1428
- -webkit-backdrop-filter: blur(20px);
1429
- }
1430
-
1431
- #app[data-active-bg="dark"].focused {
1432
- background: rgba(30, 30, 30, calc(0.85 * var(--bg-opacity)));
1433
- }
1434
-
1435
- #app[data-inactive-bg="blur"]:not(.focused) {
1436
- background: rgba(255, 255, 255, calc(0.1 * var(--bg-opacity)));
1437
- backdrop-filter: blur(20px);
1438
- -webkit-backdrop-filter: blur(20px);
1439
- }
1440
-
1441
- #app[data-inactive-bg="dark"]:not(.focused) {
1442
- background: rgba(30, 30, 30, calc(0.85 * var(--bg-opacity)));
1443
- }
1444
-
1445
- /* Multi-selection highlight */
1446
- .multi-selected-stroke {
1447
- filter: drop-shadow(0 0 4px #3b82f6);
1448
- }