clay-server 2.5.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/bin/claude-relay.js +6 -0
  2. package/bin/cli.js +77 -11
  3. package/lib/cli-sessions.js +2 -7
  4. package/lib/config.js +86 -7
  5. package/lib/daemon.js +279 -6
  6. package/lib/ipc.js +12 -0
  7. package/lib/notes.js +4 -3
  8. package/lib/project.js +1174 -28
  9. package/lib/public/app.js +879 -31
  10. package/lib/public/css/diff.css +15 -4
  11. package/lib/public/css/filebrowser.css +363 -3
  12. package/lib/public/css/icon-strip.css +317 -1
  13. package/lib/public/css/input.css +127 -50
  14. package/lib/public/css/loop.css +780 -0
  15. package/lib/public/css/messages.css +1 -1
  16. package/lib/public/css/mobile-nav.css +6 -2
  17. package/lib/public/css/rewind.css +23 -0
  18. package/lib/public/css/server-settings.css +67 -20
  19. package/lib/public/css/sidebar.css +10 -4
  20. package/lib/public/css/skills.css +789 -0
  21. package/lib/public/css/sticky-notes.css +486 -0
  22. package/lib/public/css/title-bar.css +157 -7
  23. package/lib/public/index.html +366 -55
  24. package/lib/public/modules/diff.js +3 -3
  25. package/lib/public/modules/filebrowser.js +169 -45
  26. package/lib/public/modules/input.js +123 -56
  27. package/lib/public/modules/project-settings.js +906 -0
  28. package/lib/public/modules/qrcode.js +23 -26
  29. package/lib/public/modules/server-settings.js +449 -53
  30. package/lib/public/modules/sidebar.js +732 -1
  31. package/lib/public/modules/skills.js +794 -0
  32. package/lib/public/modules/sticky-notes.js +617 -52
  33. package/lib/public/modules/terminal.js +7 -0
  34. package/lib/public/modules/theme.js +9 -19
  35. package/lib/public/modules/tools.js +16 -2
  36. package/lib/public/style.css +2 -0
  37. package/lib/sdk-bridge.js +46 -7
  38. package/lib/server.js +305 -1
  39. package/lib/sessions.js +11 -5
  40. package/lib/utils.js +18 -0
  41. package/package.json +3 -2
@@ -53,6 +53,8 @@
53
53
  .sticky-notes-count.hidden { display: none; }
54
54
 
55
55
  /* --- Individual note --- */
56
+ .sticky-note.hidden { display: none; }
57
+
56
58
  .sticky-note {
57
59
  position: absolute;
58
60
  pointer-events: auto;
@@ -154,6 +156,23 @@
154
156
  .dark-theme .sticky-note[data-color="orange"] .sticky-note-header button { color: #F0D0A8; }
155
157
  .dark-theme .sticky-note[data-color="purple"] .sticky-note-header button { color: #D8B8F0; }
156
158
 
159
+ /* --- Placeholder for empty contenteditable --- */
160
+ .sticky-note-rendered.is-empty::before {
161
+ content: "Click to start writing...";
162
+ color: rgba(0, 0, 0, 0.3);
163
+ font-style: italic;
164
+ font-size: 12px;
165
+ pointer-events: none;
166
+ }
167
+ .dark-theme .sticky-note-rendered.is-empty::before {
168
+ color: rgba(255, 255, 255, 0.25);
169
+ }
170
+
171
+ /* Contenteditable focus outline */
172
+ .sticky-note-rendered:focus {
173
+ outline: none;
174
+ }
175
+
157
176
  /* --- Body (textarea) --- */
158
177
  .sticky-note-body {
159
178
  flex: 1;
@@ -207,6 +226,7 @@
207
226
  line-height: 1.5;
208
227
  cursor: text;
209
228
  word-break: break-word;
229
+ user-select: text;
210
230
  color: inherit;
211
231
  }
212
232
 
@@ -349,10 +369,476 @@
349
369
  .sticky-note-color-dot[data-color="orange"] { background: #FFA726; }
350
370
  .sticky-note-color-dot[data-color="purple"] { background: #AB47BC; }
351
371
 
372
+ /* --- Format toolbar (WYSIWYG selection popup) --- */
373
+ .sn-format-toolbar {
374
+ position: fixed;
375
+ display: flex;
376
+ gap: 2px;
377
+ padding: 4px 5px;
378
+ background: var(--bg-alt);
379
+ border: 1px solid var(--border);
380
+ border-radius: 8px;
381
+ box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.35);
382
+ z-index: 300;
383
+ animation: snToolbarAppear 0.12s ease-out;
384
+ }
385
+
386
+ .sn-format-toolbar::after {
387
+ content: "";
388
+ position: absolute;
389
+ bottom: -5px;
390
+ left: 50%;
391
+ transform: translateX(-50%);
392
+ border: 5px solid transparent;
393
+ border-top-color: var(--bg-alt);
394
+ border-bottom: none;
395
+ }
396
+
397
+ @keyframes snToolbarAppear {
398
+ from { opacity: 0; transform: translateY(4px); }
399
+ to { opacity: 1; transform: translateY(0); }
400
+ }
401
+
402
+ .sn-fmt-btn {
403
+ display: flex;
404
+ align-items: center;
405
+ justify-content: center;
406
+ min-width: 28px;
407
+ height: 26px;
408
+ border: none;
409
+ background: none;
410
+ border-radius: 5px;
411
+ cursor: pointer;
412
+ font-family: "Pretendard", system-ui, sans-serif;
413
+ font-size: 13px;
414
+ font-weight: 600;
415
+ color: var(--text-secondary);
416
+ padding: 0 6px;
417
+ transition: background 0.1s, color 0.1s;
418
+ }
419
+
420
+ .sn-fmt-btn:hover {
421
+ background: rgba(var(--overlay-rgb), 0.1);
422
+ color: var(--text);
423
+ }
424
+
425
+ /* --- MD toggle button --- */
426
+ .sn-md-label {
427
+ font-family: "Roboto Mono", monospace;
428
+ font-size: 9px;
429
+ font-weight: 700;
430
+ letter-spacing: 0.5px;
431
+ line-height: 1;
432
+ }
433
+ .sticky-note-md-btn.active {
434
+ opacity: 1 !important;
435
+ background: rgba(0, 0, 0, 0.12) !important;
436
+ border-radius: 4px;
437
+ }
438
+ .dark-theme .sticky-note-md-btn.active {
439
+ background: rgba(255, 255, 255, 0.15) !important;
440
+ }
441
+
442
+ .sn-fmt-bold { font-weight: 800; }
443
+ .sn-fmt-italic { font-style: italic; }
444
+ .sn-fmt-strike { text-decoration: line-through; }
445
+ .sn-fmt-code .lucide { width: 14px; height: 14px; }
446
+
447
+ /* --- Note flash animation (when clicking from archive) --- */
448
+ @keyframes noteFlash {
449
+ 0%, 100% { box-shadow: 0 2px 12px rgba(var(--shadow-rgb), 0.12); }
450
+ 30% { box-shadow: 0 0 0 3px var(--accent), 0 4px 20px rgba(var(--shadow-rgb), 0.3); }
451
+ 60% { box-shadow: 0 0 0 3px var(--accent), 0 4px 20px rgba(var(--shadow-rgb), 0.3); }
452
+ }
453
+ .sticky-note.note-flash {
454
+ animation: noteFlash 0.6s ease;
455
+ }
456
+
457
+ /* ==========================================================================
458
+ Notes Archive View
459
+ ========================================================================== */
460
+
461
+ /* Hide messages and input when archive is open */
462
+ #messages.hidden { display: none; }
463
+ #input-area.hidden { display: none; }
464
+ .title-bar-content.hidden { display: none !important; }
465
+
466
+ #notes-archive {
467
+ position: absolute;
468
+ inset: 0;
469
+ z-index: 40;
470
+ background: var(--bg);
471
+ display: flex;
472
+ flex-direction: column;
473
+ overflow: hidden;
474
+ }
475
+
476
+ #notes-archive.hidden { display: none; }
477
+
478
+ /* --- Archive header --- */
479
+ .notes-archive-header {
480
+ display: flex;
481
+ align-items: center;
482
+ justify-content: space-between;
483
+ padding: 20px 28px 16px;
484
+ flex-shrink: 0;
485
+ border-bottom: 1px solid var(--border-subtle);
486
+ }
487
+
488
+ .notes-archive-title-wrap {
489
+ display: flex;
490
+ align-items: center;
491
+ gap: 10px;
492
+ }
493
+
494
+ .notes-archive-title-wrap .lucide {
495
+ width: 22px;
496
+ height: 22px;
497
+ color: var(--accent);
498
+ }
499
+
500
+ .notes-archive-title-wrap h2 {
501
+ font-family: "Pretendard", system-ui, sans-serif;
502
+ font-size: 18px;
503
+ font-weight: 700;
504
+ color: var(--text);
505
+ margin: 0;
506
+ }
507
+
508
+ .notes-archive-count {
509
+ font-size: 13px;
510
+ font-weight: 500;
511
+ color: var(--text-dimmer);
512
+ margin-left: 2px;
513
+ }
514
+
515
+ .notes-archive-close {
516
+ display: flex;
517
+ align-items: center;
518
+ justify-content: center;
519
+ width: 32px;
520
+ height: 32px;
521
+ border: 1px solid var(--border);
522
+ border-radius: 8px;
523
+ background: none;
524
+ color: var(--text-muted);
525
+ cursor: pointer;
526
+ transition: background 0.15s, color 0.15s, border-color 0.15s;
527
+ }
528
+
529
+ .notes-archive-close .lucide { width: 16px; height: 16px; }
530
+ .notes-archive-close:hover { background: rgba(var(--overlay-rgb), 0.06); color: var(--text); border-color: var(--text-dimmer); }
531
+
532
+ /* --- Archive grid --- */
533
+ .notes-archive-grid {
534
+ flex: 1;
535
+ overflow-y: auto;
536
+ padding: 20px 28px 40px;
537
+ display: grid;
538
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
539
+ gap: 12px;
540
+ align-content: start;
541
+ }
542
+
543
+ /* --- Empty state --- */
544
+ .notes-archive-empty {
545
+ grid-column: 1 / -1;
546
+ display: flex;
547
+ flex-direction: column;
548
+ align-items: center;
549
+ justify-content: center;
550
+ padding: 80px 20px;
551
+ color: var(--text-dimmer);
552
+ text-align: center;
553
+ }
554
+
555
+ .notes-archive-empty .lucide {
556
+ width: 48px;
557
+ height: 48px;
558
+ margin-bottom: 16px;
559
+ opacity: 0.3;
560
+ }
561
+
562
+ .notes-archive-empty p {
563
+ margin: 0;
564
+ font-size: 15px;
565
+ font-weight: 600;
566
+ color: var(--text-muted);
567
+ }
568
+
569
+ .notes-archive-empty-sub {
570
+ font-size: 13px !important;
571
+ font-weight: 400 !important;
572
+ color: var(--text-dimmer) !important;
573
+ margin-top: 6px !important;
574
+ display: flex;
575
+ align-items: center;
576
+ gap: 4px;
577
+ }
578
+
579
+ .notes-archive-empty-sub .lucide {
580
+ width: 14px;
581
+ height: 14px;
582
+ margin: 0;
583
+ display: inline;
584
+ opacity: 0.6;
585
+ }
586
+
587
+ /* --- Archive card --- */
588
+ .notes-archive-card {
589
+ position: relative;
590
+ border-radius: 8px;
591
+ overflow: hidden;
592
+ cursor: pointer;
593
+ display: flex;
594
+ flex-direction: column;
595
+ min-height: 80px;
596
+ max-height: 200px;
597
+ transition: transform 0.15s, box-shadow 0.15s;
598
+ box-shadow: 0 1px 4px rgba(var(--shadow-rgb), 0.1);
599
+ }
600
+
601
+ .notes-archive-card:hover {
602
+ transform: translateY(-2px);
603
+ box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.18);
604
+ }
605
+
606
+ /* Card colors (light) */
607
+ .notes-archive-card[data-color="yellow"] { background: #FFF9C4; border: 1px solid #EFD74E; }
608
+ .notes-archive-card[data-color="blue"] { background: #BBDEFB; border: 1px solid #64B5F6; }
609
+ .notes-archive-card[data-color="green"] { background: #C8E6C9; border: 1px solid #66BB6A; }
610
+ .notes-archive-card[data-color="pink"] { background: #F8BBD0; border: 1px solid #F06292; }
611
+ .notes-archive-card[data-color="orange"] { background: #FFE0B2; border: 1px solid #FFA726; }
612
+ .notes-archive-card[data-color="purple"] { background: #E1BEE7; border: 1px solid #AB47BC; }
613
+
614
+ /* Card colors (dark) */
615
+ .dark-theme .notes-archive-card[data-color="yellow"] { background: #3D3A1E; border-color: #8B7E2A; }
616
+ .dark-theme .notes-archive-card[data-color="blue"] { background: #1A2A3D; border-color: #3A7BD5; }
617
+ .dark-theme .notes-archive-card[data-color="green"] { background: #1A2D1A; border-color: #4A8F4A; }
618
+ .dark-theme .notes-archive-card[data-color="pink"] { background: #3D1A2A; border-color: #C44A72; }
619
+ .dark-theme .notes-archive-card[data-color="orange"] { background: #3D2A1A; border-color: #C47A3A; }
620
+ .dark-theme .notes-archive-card[data-color="purple"] { background: #2A1A3D; border-color: #8A4AAA; }
621
+
622
+ /* Archived (hidden from canvas) cards — dimmed with indicator */
623
+ .notes-archive-card.archived {
624
+ opacity: 0.55;
625
+ }
626
+ .notes-archive-card.archived:hover {
627
+ opacity: 0.85;
628
+ }
629
+
630
+ /* --- Card header --- */
631
+ .notes-archive-card-header {
632
+ display: flex;
633
+ align-items: center;
634
+ gap: 6px;
635
+ padding: 10px 10px 0;
636
+ flex-shrink: 0;
637
+ }
638
+
639
+ .notes-archive-card-title {
640
+ flex: 1;
641
+ font-size: 13px;
642
+ font-weight: 700;
643
+ line-height: 1.3;
644
+ overflow: hidden;
645
+ text-overflow: ellipsis;
646
+ white-space: nowrap;
647
+ min-width: 0;
648
+ }
649
+
650
+ /* Title text colors (light) */
651
+ .notes-archive-card[data-color="yellow"] .notes-archive-card-title { color: #6D5E00; }
652
+ .notes-archive-card[data-color="blue"] .notes-archive-card-title { color: #0D47A1; }
653
+ .notes-archive-card[data-color="green"] .notes-archive-card-title { color: #1B5E20; }
654
+ .notes-archive-card[data-color="pink"] .notes-archive-card-title { color: #880E4F; }
655
+ .notes-archive-card[data-color="orange"] .notes-archive-card-title { color: #E65100; }
656
+ .notes-archive-card[data-color="purple"] .notes-archive-card-title { color: #4A148C; }
657
+
658
+ /* Title text colors (dark) */
659
+ .dark-theme .notes-archive-card[data-color="yellow"] .notes-archive-card-title { color: #E8E0A8; }
660
+ .dark-theme .notes-archive-card[data-color="blue"] .notes-archive-card-title { color: #B0D4F1; }
661
+ .dark-theme .notes-archive-card[data-color="green"] .notes-archive-card-title { color: #B0D8B0; }
662
+ .dark-theme .notes-archive-card[data-color="pink"] .notes-archive-card-title { color: #F0B8CC; }
663
+ .dark-theme .notes-archive-card[data-color="orange"] .notes-archive-card-title { color: #F0D0A8; }
664
+ .dark-theme .notes-archive-card[data-color="purple"] .notes-archive-card-title { color: #D8B8F0; }
665
+
666
+ /* --- Delete button --- */
667
+ .notes-archive-card-delete {
668
+ display: flex;
669
+ align-items: center;
670
+ justify-content: center;
671
+ width: 24px;
672
+ height: 24px;
673
+ border: none;
674
+ background: none;
675
+ border-radius: 6px;
676
+ cursor: pointer;
677
+ opacity: 0;
678
+ flex-shrink: 0;
679
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
680
+ color: inherit;
681
+ }
682
+
683
+ .notes-archive-card-delete .lucide { width: 14px; height: 14px; }
684
+ .notes-archive-card:hover .notes-archive-card-delete { opacity: 0.5; }
685
+ .notes-archive-card-delete:hover { opacity: 1 !important; background: rgba(0,0,0,0.08); }
686
+
687
+ /* --- Restore button (archived cards) --- */
688
+ .notes-archive-card-restore {
689
+ display: flex;
690
+ align-items: center;
691
+ gap: 4px;
692
+ height: 24px;
693
+ border: none;
694
+ background: rgba(0, 0, 0, 0.06);
695
+ border-radius: 6px;
696
+ cursor: pointer;
697
+ flex-shrink: 0;
698
+ padding: 0 8px;
699
+ font-family: "Pretendard", system-ui, sans-serif;
700
+ font-size: 11px;
701
+ font-weight: 600;
702
+ color: inherit;
703
+ opacity: 0.6;
704
+ transition: opacity 0.15s, background 0.15s;
705
+ }
706
+ .notes-archive-card-restore .lucide { width: 12px; height: 12px; }
707
+ .notes-archive-card-restore:hover { opacity: 1; background: rgba(0, 0, 0, 0.1); }
708
+ .dark-theme .notes-archive-card-restore { background: rgba(255, 255, 255, 0.08); }
709
+ .dark-theme .notes-archive-card-restore:hover { background: rgba(255, 255, 255, 0.14); }
710
+
711
+ /* Confirm-delete state: red trash */
712
+ .notes-archive-card.confirm-delete .notes-archive-card-delete {
713
+ opacity: 1 !important;
714
+ color: #E53935;
715
+ background: rgba(229, 57, 53, 0.12);
716
+ }
717
+
718
+ /* Deleting animation */
719
+ .notes-archive-card.deleting {
720
+ opacity: 0;
721
+ transform: scale(0.9);
722
+ transition: opacity 0.2s, transform 0.2s;
723
+ pointer-events: none;
724
+ }
725
+
726
+ /* --- Card body --- */
727
+ .notes-archive-card-body {
728
+ flex: 1;
729
+ padding: 4px 10px 10px;
730
+ font-size: 12px;
731
+ line-height: 1.5;
732
+ overflow: hidden;
733
+ min-height: 0;
734
+ word-break: break-word;
735
+ }
736
+
737
+ /* Body text colors (light) */
738
+ .notes-archive-card[data-color="yellow"] .notes-archive-card-body { color: #5D4E00; }
739
+ .notes-archive-card[data-color="blue"] .notes-archive-card-body { color: #0D47A1; }
740
+ .notes-archive-card[data-color="green"] .notes-archive-card-body { color: #1B5E20; }
741
+ .notes-archive-card[data-color="pink"] .notes-archive-card-body { color: #880E4F; }
742
+ .notes-archive-card[data-color="orange"] .notes-archive-card-body { color: #E65100; }
743
+ .notes-archive-card[data-color="purple"] .notes-archive-card-body { color: #4A148C; }
744
+
745
+ /* Body text colors (dark) */
746
+ .dark-theme .notes-archive-card[data-color="yellow"] .notes-archive-card-body { color: #E8E0A8; }
747
+ .dark-theme .notes-archive-card[data-color="blue"] .notes-archive-card-body { color: #B0D4F1; }
748
+ .dark-theme .notes-archive-card[data-color="green"] .notes-archive-card-body { color: #B0D8B0; }
749
+ .dark-theme .notes-archive-card[data-color="pink"] .notes-archive-card-body { color: #F0B8CC; }
750
+ .dark-theme .notes-archive-card[data-color="orange"] .notes-archive-card-body { color: #F0D0A8; }
751
+ .dark-theme .notes-archive-card[data-color="purple"] .notes-archive-card-body { color: #D8B8F0; }
752
+
753
+ .notes-archive-card-body code {
754
+ font-family: "Roboto Mono", monospace;
755
+ font-size: 11px;
756
+ padding: 1px 3px;
757
+ border-radius: 3px;
758
+ background: rgba(0,0,0,0.06);
759
+ }
760
+ .dark-theme .notes-archive-card-body code {
761
+ background: rgba(255,255,255,0.08);
762
+ }
763
+
764
+ /* --- Sidebar button active state --- */
765
+ #sticky-notes-sidebar-btn.active {
766
+ background: var(--sidebar-active);
767
+ color: var(--text);
768
+ font-weight: 600;
769
+ }
770
+
771
+ /* ==========================================================================
772
+ Onboarding beacon (first-time discovery hint)
773
+ ========================================================================== */
774
+
775
+ /* Pulsing glow on the title bar button */
776
+ @keyframes snOnboardingPulse {
777
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb, 99, 102, 241), 0.5); }
778
+ 50% { box-shadow: 0 0 0 6px rgba(var(--accent-rgb, 99, 102, 241), 0); }
779
+ }
780
+
781
+ #sticky-notes-toggle-btn.sn-onboarding-pulse {
782
+ animation: snOnboardingPulse 2s ease-in-out infinite;
783
+ color: var(--accent) !important;
784
+ border-color: var(--accent) !important;
785
+ }
786
+
787
+ /* Tooltip bubble */
788
+ .sn-onboarding-tooltip {
789
+ position: fixed;
790
+ display: flex;
791
+ align-items: center;
792
+ gap: 8px;
793
+ padding: 8px 12px;
794
+ background: var(--code-bg);
795
+ color: var(--text);
796
+ border: 1px solid var(--border);
797
+ border-radius: 8px;
798
+ font-size: 13px;
799
+ font-weight: 500;
800
+ white-space: nowrap;
801
+ box-shadow: 0 4px 16px rgba(var(--shadow-rgb), 0.4);
802
+ z-index: 1000;
803
+ pointer-events: none;
804
+ transform: translateX(-50%);
805
+ animation: snOnboardingAppear 0.3s ease-out;
806
+ }
807
+
808
+ .sn-onboarding-tooltip::before {
809
+ content: "";
810
+ position: absolute;
811
+ top: -6px;
812
+ left: 50%;
813
+ transform: translateX(-50%);
814
+ border: 6px solid transparent;
815
+ border-bottom-color: var(--code-bg);
816
+ border-top: none;
817
+ }
818
+
819
+ @keyframes snOnboardingAppear {
820
+ from { opacity: 0; transform: translateX(-50%) translateY(-4px); }
821
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
822
+ }
823
+
824
+ .sn-onboarding-tooltip.sn-onboarding-fade-out {
825
+ opacity: 0;
826
+ transition: opacity 0.3s;
827
+ }
828
+
352
829
  /* --- Mobile: hide entirely --- */
353
830
  @media (max-width: 768px) {
354
831
  #sticky-notes-container,
355
832
  #sticky-notes-toggle-btn {
356
833
  display: none !important;
357
834
  }
835
+
836
+ .notes-archive-grid {
837
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
838
+ padding: 12px 16px 32px;
839
+ }
840
+
841
+ .notes-archive-header {
842
+ padding: 16px 16px 12px;
843
+ }
358
844
  }
@@ -66,6 +66,89 @@
66
66
 
67
67
  #server-settings-btn.active { color: var(--text); }
68
68
 
69
+ /* --- Theme toggle pill switch (light/dark) --- */
70
+ .theme-toggle {
71
+ display: flex;
72
+ align-items: center;
73
+ cursor: pointer;
74
+ -webkit-app-region: no-drag;
75
+ }
76
+
77
+ .theme-toggle input[type="checkbox"] {
78
+ position: absolute;
79
+ opacity: 0;
80
+ width: 0;
81
+ height: 0;
82
+ pointer-events: none;
83
+ }
84
+
85
+ .theme-toggle-track {
86
+ position: relative;
87
+ width: 46px;
88
+ height: 22px;
89
+ border-radius: 11px;
90
+ background: var(--border);
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: space-between;
94
+ padding: 0 4px;
95
+ box-sizing: border-box;
96
+ transition: background 0.3s;
97
+ }
98
+
99
+ .theme-toggle-track:hover {
100
+ background: var(--border-subtle);
101
+ }
102
+ .dark-theme .theme-toggle-track:hover {
103
+ background: var(--text-dimmer);
104
+ }
105
+
106
+ .theme-toggle-icon {
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ width: 14px;
111
+ height: 14px;
112
+ z-index: 2;
113
+ position: relative;
114
+ transition: color 0.25s;
115
+ }
116
+
117
+ .theme-toggle-icon .lucide {
118
+ width: 11px;
119
+ height: 11px;
120
+ }
121
+
122
+ .theme-toggle-thumb {
123
+ position: absolute;
124
+ top: 2px;
125
+ left: 2px;
126
+ width: 18px;
127
+ height: 18px;
128
+ border-radius: 50%;
129
+ background: var(--text-muted);
130
+ transition: left 0.25s cubic-bezier(0.4, 0, 0.2, 1), background 0.25s;
131
+ z-index: 1;
132
+ }
133
+
134
+ /* Dark mode (unchecked) — thumb LEFT on sun */
135
+ .theme-toggle-sun { color: var(--bg); } /* dark icon on lighter thumb */
136
+ .theme-toggle-moon { color: var(--text-muted); } /* light icon on dark track */
137
+
138
+ /* Light mode (checked) — thumb RIGHT on moon */
139
+ .theme-toggle input:checked ~ .theme-toggle-track .theme-toggle-thumb {
140
+ left: 24px;
141
+ background: var(--bg-alt);
142
+ }
143
+
144
+ .theme-toggle input:checked ~ .theme-toggle-track .theme-toggle-sun {
145
+ color: var(--text-muted); /* darker icon on light track */
146
+ }
147
+
148
+ .theme-toggle input:checked ~ .theme-toggle-track .theme-toggle-moon {
149
+ color: var(--text-dimmer); /* darker icon on light thumb */
150
+ }
151
+
69
152
  /* Debug button in top bar */
70
153
  .top-bar-actions #debug-menu-wrap { position: relative; }
71
154
  .top-bar-actions #debug-menu-wrap.hidden { display: none; }
@@ -73,9 +156,6 @@
73
156
  .top-bar-actions #debug-btn:hover { opacity: 1; background: var(--error-8); }
74
157
  .top-bar-actions #debug-btn.active { opacity: 1; background: var(--error-12); }
75
158
 
76
- /* QR/Share button in top bar */
77
- .top-bar-actions #qr-btn.active { color: var(--text); background: rgba(var(--overlay-rgb),0.06); }
78
-
79
159
  /* ==========================================================================
80
160
  Title Bar — split into sidebar-column and main-column sections
81
161
  ========================================================================== */
@@ -91,15 +171,84 @@
91
171
  border-bottom: 1px solid var(--border-subtle);
92
172
  }
93
173
 
94
- .title-bar-project-name {
174
+ .title-bar-project-dropdown {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 6px;
95
178
  width: 100%;
96
- font-family: "Nunito", sans-serif;
97
- font-size: 15px;
179
+ min-width: 0;
180
+ background: none;
181
+ border: none;
182
+ padding: 4px 8px;
183
+ margin: -4px -8px;
184
+ border-radius: 6px;
185
+ cursor: pointer;
186
+ transition: background 0.15s;
187
+ font-family: inherit;
188
+ }
189
+
190
+ .title-bar-project-dropdown:hover {
191
+ background: rgba(var(--overlay-rgb), 0.06);
192
+ }
193
+
194
+ .title-bar-project-icon {
195
+ display: none;
196
+ font-size: 18px;
197
+ line-height: 1;
198
+ flex-shrink: 0;
199
+ }
200
+
201
+ .title-bar-project-icon.has-icon {
202
+ display: inline-flex;
203
+ align-items: center;
204
+ }
205
+
206
+ .title-bar-project-icon .emoji {
207
+ width: 18px;
208
+ height: 18px;
209
+ vertical-align: middle;
210
+ filter:
211
+ drop-shadow(1px 0 0 rgba(0,0,0,0.18))
212
+ drop-shadow(-1px 0 0 rgba(0,0,0,0.18))
213
+ drop-shadow(0 1px 0 rgba(0,0,0,0.18))
214
+ drop-shadow(0 -1px 0 rgba(0,0,0,0.18));
215
+ }
216
+
217
+ .title-bar-project-name {
218
+ font-family: "Pretendard", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
219
+ font-size: 17px;
98
220
  font-weight: 800;
99
221
  color: var(--text);
100
222
  overflow: hidden;
101
223
  text-overflow: ellipsis;
102
224
  white-space: nowrap;
225
+ min-width: 0;
226
+ }
227
+
228
+ .title-bar-chevron {
229
+ width: 14px;
230
+ height: 14px;
231
+ flex-shrink: 0;
232
+ color: var(--text-secondary);
233
+ transition: transform 0.2s;
234
+ }
235
+
236
+ .title-bar-project-dropdown.open .title-bar-chevron {
237
+ transform: rotate(180deg);
238
+ }
239
+
240
+ .project-rename-input {
241
+ width: 100%;
242
+ font-family: "Pretendard", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
243
+ font-size: 17px;
244
+ font-weight: 800;
245
+ color: var(--text);
246
+ background: var(--bg-alt);
247
+ border: 1px solid var(--accent);
248
+ border-radius: 4px;
249
+ padding: 1px 4px;
250
+ outline: none;
251
+ min-width: 0;
103
252
  }
104
253
 
105
254
  /* --- Content section (inside #main-column) --- */
@@ -108,7 +257,6 @@
108
257
  height: 48px;
109
258
  display: flex;
110
259
  align-items: center;
111
- justify-content: space-between;
112
260
  padding: 0 16px;
113
261
  min-width: 0;
114
262
  border-bottom: 1px solid var(--border-subtle);
@@ -125,9 +273,11 @@
125
273
  .title-bar-content .status {
126
274
  display: flex;
127
275
  align-items: center;
276
+ justify-content: flex-end;
128
277
  gap: 6px;
129
278
  font-size: 12px;
130
279
  color: var(--text-muted);
280
+ flex: 1;
131
281
  flex-shrink: 0;
132
282
  }
133
283