viveworker 0.7.0 → 0.8.1

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 (54) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/README.md +115 -4
  3. package/package.json +13 -3
  4. package/plugins/viveworker-control-plane/.codex-plugin/plugin.json +49 -0
  5. package/plugins/viveworker-control-plane/.mcp.json +11 -0
  6. package/plugins/viveworker-control-plane/assets/viveworker-logo-v2.png +0 -0
  7. package/plugins/viveworker-control-plane/assets/viveworker-logo-v2.svg +39 -0
  8. package/plugins/viveworker-control-plane/skills/viveworker-control-plane/SKILL.md +83 -0
  9. package/scripts/lib/markdown-render.mjs +128 -1
  10. package/scripts/lib/remote-pairing/README.md +164 -0
  11. package/scripts/lib/remote-pairing/_browser-bundle-entry.mjs +86 -0
  12. package/scripts/lib/remote-pairing/audit.mjs +122 -0
  13. package/scripts/lib/remote-pairing/bridge-relay-client.mjs +737 -0
  14. package/scripts/lib/remote-pairing/control.mjs +156 -0
  15. package/scripts/lib/remote-pairing/envelope.mjs +224 -0
  16. package/scripts/lib/remote-pairing/http-dispatch.mjs +530 -0
  17. package/scripts/lib/remote-pairing/keys-core.mjs +110 -0
  18. package/scripts/lib/remote-pairing/keys.mjs +181 -0
  19. package/scripts/lib/remote-pairing/noise.mjs +436 -0
  20. package/scripts/lib/remote-pairing/orchestrator.mjs +356 -0
  21. package/scripts/lib/remote-pairing/pairings.mjs +446 -0
  22. package/scripts/lib/remote-pairing/rpc.mjs +381 -0
  23. package/scripts/mcp-server.mjs +891 -0
  24. package/scripts/moltbook-scout-auto.sh +16 -8
  25. package/scripts/share-cli.mjs +14 -130
  26. package/scripts/stats-cli.mjs +683 -0
  27. package/scripts/viveworker-bridge.mjs +1676 -127
  28. package/scripts/viveworker.mjs +289 -7
  29. package/skills/viveworker-control-plane/SKILL.md +104 -0
  30. package/skills/viveworker-control-plane/agents/openai.yaml +12 -0
  31. package/templates/CLAUDE.viveworker.md +67 -0
  32. package/web/app.css +683 -9
  33. package/web/app.js +1780 -187
  34. package/web/build-id.js +1 -0
  35. package/web/i18n.js +187 -9
  36. package/web/icons/apple-touch-icon.png +0 -0
  37. package/web/icons/viveworker-icon-192.png +0 -0
  38. package/web/icons/viveworker-icon-512.png +0 -0
  39. package/web/icons/viveworker-v-pulse.svg +16 -1
  40. package/web/index.html +32 -2
  41. package/web/remote-pairing/api-router.js +873 -0
  42. package/web/remote-pairing/keys.js +237 -0
  43. package/web/remote-pairing/pairing-state.js +313 -0
  44. package/web/remote-pairing/rpc-client.js +765 -0
  45. package/web/remote-pairing/transport.js +804 -0
  46. package/web/remote-pairing/wake.js +149 -0
  47. package/web/remote-pairing-test.html +400 -0
  48. package/web/remote-pairing.bundle.js +3 -0
  49. package/web/remote-pairing.bundle.js.LEGAL.txt +15 -0
  50. package/web/remote-pairing.bundle.js.map +7 -0
  51. package/web/sw.js +190 -20
  52. package/web/icons/viveworker-beacon-v.svg +0 -19
  53. package/web/icons/viveworker-icon-1024.png +0 -0
  54. package/web/icons/viveworker-v-check.svg +0 -19
package/web/app.css CHANGED
@@ -1,5 +1,7 @@
1
1
  :root {
2
2
  color-scheme: dark;
3
+ --visual-viewport-left: 0px;
4
+ --visual-viewport-width: 100vw;
3
5
  --font-ui: "Avenir Next", "SF Pro Rounded", "SF Pro Text", "Helvetica Neue", sans-serif;
4
6
  --bg: #091015;
5
7
  --bg-soft: #0f1921;
@@ -36,7 +38,10 @@ html {
36
38
  width: 100%;
37
39
  max-width: 100%;
38
40
  overflow-x: hidden;
41
+ overscroll-behavior-x: none;
39
42
  background: var(--bg);
43
+ -webkit-text-size-adjust: 100%;
44
+ text-size-adjust: 100%;
40
45
  }
41
46
 
42
47
  body {
@@ -46,6 +51,7 @@ body {
46
51
  margin: 0;
47
52
  min-height: 100vh;
48
53
  overflow-x: hidden;
54
+ overscroll-behavior-x: none;
49
55
  font-family: var(--font-ui);
50
56
  color: var(--text);
51
57
  background:
@@ -59,7 +65,9 @@ a {
59
65
  }
60
66
 
61
67
  button,
62
- input {
68
+ input,
69
+ textarea,
70
+ select {
63
71
  font: inherit;
64
72
  }
65
73
 
@@ -69,15 +77,31 @@ code {
69
77
  background: rgba(156, 181, 197, 0.12);
70
78
  }
71
79
 
80
+ /*
81
+ * Reset the inline-`<code>` look when the element is wrapped by `<pre>`.
82
+ * Without this, a multi-line code block ends up with the per-`<code>`
83
+ * padding + rounded background applied to each visual line individually
84
+ * (the inline element is line-broken and the browser paints the background
85
+ * once per line), which made fenced code blocks look like a stack of
86
+ * inline code spans on the phone PWA.
87
+ */
88
+ pre code {
89
+ padding: 0;
90
+ border-radius: 0;
91
+ background: transparent;
92
+ }
93
+
72
94
  #app {
73
- width: 100%;
74
- max-width: 100%;
95
+ width: 100vw;
96
+ max-width: 100vw;
75
97
  min-width: 0;
98
+ overflow-x: clip;
76
99
  }
77
100
 
78
101
  .app-shell {
79
- width: 100%;
80
- max-width: 100%;
102
+ width: 100vw;
103
+ max-width: 100vw;
104
+ min-width: 0;
81
105
  min-height: 100vh;
82
106
  overflow-x: clip;
83
107
  padding:
@@ -87,6 +111,14 @@ code {
87
111
  1rem;
88
112
  }
89
113
 
114
+ @supports (width: 100dvw) {
115
+ #app,
116
+ .app-shell {
117
+ width: 100dvw;
118
+ max-width: 100dvw;
119
+ }
120
+ }
121
+
90
122
  .app-shell--mobile:not(.app-shell--detail)::after {
91
123
  content: "";
92
124
  position: fixed;
@@ -111,6 +143,9 @@ code {
111
143
  }
112
144
 
113
145
  .app-shell--detail {
146
+ width: 100%;
147
+ max-width: 100%;
148
+ min-width: 0;
114
149
  padding-bottom: max(1rem, env(safe-area-inset-bottom));
115
150
  }
116
151
 
@@ -418,6 +453,7 @@ code {
418
453
  .settings-stack,
419
454
  .stack,
420
455
  .choice-stack {
456
+ width: 100%;
421
457
  display: grid;
422
458
  gap: 1rem;
423
459
  min-width: 0;
@@ -442,6 +478,7 @@ code {
442
478
  }
443
479
 
444
480
  .screen-block--detail {
481
+ width: 100%;
445
482
  min-height: calc(100dvh - 8rem);
446
483
  }
447
484
 
@@ -968,6 +1005,58 @@ code {
968
1005
  overflow-wrap: anywhere;
969
1006
  }
970
1007
 
1008
+ .settings-row__value--enabled,
1009
+ .settings-info-row__value--enabled {
1010
+ display: inline-flex;
1011
+ align-items: center;
1012
+ justify-content: center;
1013
+ min-height: 1.62rem;
1014
+ padding: 0.16rem 0.52rem;
1015
+ border-radius: 999px;
1016
+ font-size: 0.74rem;
1017
+ font-weight: 800;
1018
+ letter-spacing: 0.04em;
1019
+ line-height: 1;
1020
+ text-transform: uppercase;
1021
+ white-space: nowrap;
1022
+ }
1023
+
1024
+ .settings-row__value--enabled,
1025
+ .settings-info-row__value--enabled {
1026
+ border: 1px solid rgba(112, 202, 157, 0.24);
1027
+ background: rgba(112, 202, 157, 0.12);
1028
+ color: rgba(185, 239, 208, 0.96);
1029
+ }
1030
+
1031
+ .settings-row__value--disabled,
1032
+ .settings-info-row__value--disabled {
1033
+ color: rgba(231, 243, 250, 0.68);
1034
+ }
1035
+
1036
+ .settings-row__value--attention,
1037
+ .settings-info-row__value--attention {
1038
+ display: inline-flex;
1039
+ align-items: center;
1040
+ justify-content: center;
1041
+ min-height: 1.62rem;
1042
+ padding: 0.16rem 0.52rem;
1043
+ border-radius: 999px;
1044
+ border: 1px solid rgba(240, 180, 40, 0.26);
1045
+ background: rgba(240, 180, 40, 0.11);
1046
+ color: rgba(255, 220, 140, 0.96);
1047
+ font-size: 0.74rem;
1048
+ font-weight: 800;
1049
+ letter-spacing: 0.04em;
1050
+ line-height: 1;
1051
+ text-transform: uppercase;
1052
+ white-space: nowrap;
1053
+ }
1054
+
1055
+ .settings-row__value--disconnected,
1056
+ .settings-info-row__value--disconnected {
1057
+ color: rgba(205, 220, 231, 0.54);
1058
+ }
1059
+
971
1060
  .settings-info-row--stacked .settings-info-row__value {
972
1061
  text-align: left;
973
1062
  }
@@ -1129,6 +1218,25 @@ code {
1129
1218
  white-space: nowrap;
1130
1219
  }
1131
1220
 
1221
+ .device-card__badges {
1222
+ display: inline-flex;
1223
+ flex-wrap: wrap;
1224
+ justify-content: flex-end;
1225
+ gap: 0.35rem;
1226
+ }
1227
+
1228
+ .device-card__badge--live {
1229
+ border-color: rgba(112, 202, 157, 0.28);
1230
+ background: rgba(112, 202, 157, 0.14);
1231
+ color: #c8f3d9;
1232
+ }
1233
+
1234
+ .device-card__badge--offline {
1235
+ border-color: rgba(156, 181, 197, 0.14);
1236
+ background: rgba(156, 181, 197, 0.1);
1237
+ color: var(--muted);
1238
+ }
1239
+
1132
1240
  .device-card__meta {
1133
1241
  margin-top: 0.85rem;
1134
1242
  display: grid;
@@ -1741,6 +1849,12 @@ code {
1741
1849
  }
1742
1850
 
1743
1851
  @media (max-width: 640px) {
1852
+ input,
1853
+ textarea,
1854
+ select {
1855
+ font-size: 16px;
1856
+ }
1857
+
1744
1858
  .wallet-step-card__header {
1745
1859
  flex-direction: column;
1746
1860
  }
@@ -2609,6 +2723,8 @@ code {
2609
2723
  }
2610
2724
 
2611
2725
  .detail-shell--mobile {
2726
+ width: 100%;
2727
+ max-width: 100%;
2612
2728
  display: grid;
2613
2729
  grid-template-rows: minmax(0, 1fr) auto;
2614
2730
  min-height: calc(100dvh - 5.6rem);
@@ -2622,6 +2738,8 @@ code {
2622
2738
  }
2623
2739
 
2624
2740
  .mobile-detail-screen {
2741
+ width: 100%;
2742
+ max-width: 100%;
2625
2743
  display: flex;
2626
2744
  flex-direction: column;
2627
2745
  gap: 0;
@@ -2629,8 +2747,11 @@ code {
2629
2747
  }
2630
2748
 
2631
2749
  .mobile-detail-scroll {
2750
+ width: 100%;
2751
+ max-width: 100%;
2632
2752
  min-height: 0;
2633
- overflow: auto;
2753
+ overflow-y: auto;
2754
+ overflow-x: hidden;
2634
2755
  -webkit-overflow-scrolling: touch;
2635
2756
  padding: 0 0.42rem 0.78rem;
2636
2757
  display: flex;
@@ -2644,6 +2765,10 @@ code {
2644
2765
  gap: 0.14rem;
2645
2766
  }
2646
2767
 
2768
+ .mobile-detail-screen--has-reply-dock .mobile-detail-scroll--detail {
2769
+ padding-bottom: calc(6rem + env(safe-area-inset-bottom));
2770
+ }
2771
+
2647
2772
  .detail-action-bar {
2648
2773
  display: grid;
2649
2774
  gap: 0.75rem;
@@ -2723,6 +2848,8 @@ code {
2723
2848
  .detail-body {
2724
2849
  overflow-wrap: anywhere;
2725
2850
  width: 100%;
2851
+ min-width: 0;
2852
+ max-width: 100%;
2726
2853
  }
2727
2854
 
2728
2855
  .detail-card--body .detail-body {
@@ -2738,6 +2865,8 @@ code {
2738
2865
  }
2739
2866
 
2740
2867
  .detail-body.markdown {
2868
+ min-width: 0;
2869
+ max-width: 100%;
2741
2870
  line-height: 1.62;
2742
2871
  color: #f3fbff;
2743
2872
  }
@@ -2777,6 +2906,7 @@ code {
2777
2906
  }
2778
2907
 
2779
2908
  .detail-body.markdown pre {
2909
+ max-width: 100%;
2780
2910
  overflow: auto;
2781
2911
  padding: 0.82rem 0.88rem;
2782
2912
  border: 1px solid var(--line);
@@ -2785,8 +2915,44 @@ code {
2785
2915
  }
2786
2916
 
2787
2917
  .detail-body.markdown table {
2918
+ max-width: 100%;
2788
2919
  display: block;
2789
2920
  overflow-x: auto;
2921
+ border-collapse: collapse;
2922
+ margin: 0.4rem 0 0.6rem;
2923
+ font-size: 0.92rem;
2924
+ line-height: 1.45;
2925
+ }
2926
+
2927
+ .detail-body.markdown table thead {
2928
+ background: rgba(255, 255, 255, 0.03);
2929
+ }
2930
+
2931
+ .detail-body.markdown table th,
2932
+ .detail-body.markdown table td {
2933
+ border: 1px solid rgba(156, 181, 197, 0.16);
2934
+ padding: 0.42rem 0.62rem;
2935
+ text-align: left;
2936
+ vertical-align: top;
2937
+ white-space: normal;
2938
+ word-break: break-word;
2939
+ }
2940
+
2941
+ .detail-body.markdown table th {
2942
+ font-weight: 600;
2943
+ color: var(--text);
2944
+ }
2945
+
2946
+ .detail-body.markdown table td {
2947
+ color: var(--muted);
2948
+ }
2949
+
2950
+ .detail-body.markdown table th code,
2951
+ .detail-body.markdown table td code {
2952
+ background: rgba(255, 255, 255, 0.05);
2953
+ padding: 0.05rem 0.32rem;
2954
+ border-radius: 6px;
2955
+ font-size: 0.86em;
2790
2956
  }
2791
2957
 
2792
2958
  .detail-card {
@@ -2803,10 +2969,17 @@ code {
2803
2969
  align-items: stretch;
2804
2970
  gap: 0.52rem;
2805
2971
  width: 100%;
2972
+ min-width: 0;
2973
+ max-width: 100%;
2806
2974
  align-self: start;
2807
2975
  padding: 0.68rem 0.78rem;
2808
2976
  }
2809
2977
 
2978
+ .detail-card > * {
2979
+ min-width: 0;
2980
+ max-width: 100%;
2981
+ }
2982
+
2810
2983
  .detail-card--mobile {
2811
2984
  padding: 0.42rem 0.5rem;
2812
2985
  gap: 0.4rem;
@@ -3417,6 +3590,8 @@ code {
3417
3590
  .reply-composer {
3418
3591
  display: grid;
3419
3592
  gap: 0.78rem;
3593
+ min-width: 0;
3594
+ max-width: 100%;
3420
3595
  }
3421
3596
 
3422
3597
  .reply-composer--readonly {
@@ -3425,6 +3600,8 @@ code {
3425
3600
  .reply-composer__copy {
3426
3601
  display: grid;
3427
3602
  gap: 0.34rem;
3603
+ min-width: 0;
3604
+ max-width: 100%;
3428
3605
  }
3429
3606
 
3430
3607
  .reply-composer__title {
@@ -3441,6 +3618,8 @@ code {
3441
3618
  .reply-composer__form {
3442
3619
  display: grid;
3443
3620
  gap: 0.8rem;
3621
+ min-width: 0;
3622
+ max-width: 100%;
3444
3623
  }
3445
3624
 
3446
3625
  .reply-composer__context {
@@ -3498,6 +3677,7 @@ code {
3498
3677
  }
3499
3678
  .reply-composer__textarea {
3500
3679
  width: 100%;
3680
+ min-width: 0;
3501
3681
  min-height: 14rem;
3502
3682
  padding: 0.85rem 0.95rem;
3503
3683
  border-radius: 14px;
@@ -3505,7 +3685,7 @@ code {
3505
3685
  background: rgba(7, 12, 16, 0.96);
3506
3686
  color: var(--text);
3507
3687
  font: inherit;
3508
- font-size: 1rem;
3688
+ font-size: max(1rem, 16px);
3509
3689
  line-height: 1.55;
3510
3690
  resize: vertical;
3511
3691
  }
@@ -3515,6 +3695,166 @@ code {
3515
3695
  border-color: var(--accent, #6ea8ff);
3516
3696
  }
3517
3697
 
3698
+ .reply-dock {
3699
+ position: fixed;
3700
+ left: calc(var(--visual-viewport-left, 0px) + max(1rem, env(safe-area-inset-left)));
3701
+ bottom: calc(0.88rem + env(safe-area-inset-bottom));
3702
+ z-index: 36;
3703
+ width: calc(var(--visual-viewport-width, 100vw) - max(1rem, env(safe-area-inset-left)) - max(1rem, env(safe-area-inset-right)));
3704
+ max-width: calc(var(--visual-viewport-width, 100vw) - max(1rem, env(safe-area-inset-left)) - max(1rem, env(safe-area-inset-right)));
3705
+ pointer-events: none;
3706
+ }
3707
+
3708
+ .reply-dock__button {
3709
+ width: 100%;
3710
+ min-height: 3.45rem;
3711
+ display: grid;
3712
+ align-content: center;
3713
+ justify-items: center;
3714
+ padding: 0.82rem 1rem;
3715
+ border: 1px solid rgba(156, 181, 197, 0.18);
3716
+ border-radius: 20px;
3717
+ background:
3718
+ linear-gradient(180deg, rgba(28, 42, 52, 0.96), rgba(17, 28, 36, 0.96)),
3719
+ rgba(20, 31, 40, 0.94);
3720
+ color: rgba(236, 248, 255, 0.94);
3721
+ box-shadow:
3722
+ 0 18px 44px rgba(0, 0, 0, 0.3),
3723
+ inset 0 1px 0 rgba(255, 255, 255, 0.08);
3724
+ pointer-events: auto;
3725
+ text-align: center;
3726
+ }
3727
+
3728
+ .reply-dock__label {
3729
+ font-size: 1rem;
3730
+ font-weight: 800;
3731
+ line-height: 1.2;
3732
+ }
3733
+
3734
+ .reply-dock__hint {
3735
+ color: rgba(244, 255, 248, 0.74);
3736
+ font-size: 0.78rem;
3737
+ font-weight: 650;
3738
+ line-height: 1.25;
3739
+ }
3740
+
3741
+ .reply-sheet-backdrop {
3742
+ position: fixed;
3743
+ top: 0;
3744
+ right: auto;
3745
+ bottom: 0;
3746
+ left: var(--visual-viewport-left, 0px);
3747
+ width: var(--visual-viewport-width, 100vw);
3748
+ max-width: var(--visual-viewport-width, 100vw);
3749
+ z-index: 44;
3750
+ background: rgba(2, 7, 10, 0.56);
3751
+ -webkit-backdrop-filter: blur(10px);
3752
+ backdrop-filter: blur(10px);
3753
+ animation: reply-sheet-backdrop-in 160ms ease-out both;
3754
+ }
3755
+
3756
+ .reply-sheet {
3757
+ position: fixed;
3758
+ left: var(--visual-viewport-left, 0px);
3759
+ right: auto;
3760
+ bottom: 0;
3761
+ z-index: 45;
3762
+ width: var(--visual-viewport-width, 100vw);
3763
+ min-width: 0;
3764
+ max-width: var(--visual-viewport-width, 100vw);
3765
+ max-height: min(82dvh, 42rem);
3766
+ display: grid;
3767
+ gap: 0.72rem;
3768
+ padding:
3769
+ 0.78rem
3770
+ max(0.9rem, env(safe-area-inset-right))
3771
+ calc(0.9rem + env(safe-area-inset-bottom))
3772
+ max(0.9rem, env(safe-area-inset-left));
3773
+ overflow-x: hidden;
3774
+ overflow-y: auto;
3775
+ -webkit-overflow-scrolling: touch;
3776
+ border: 1px solid rgba(156, 181, 197, 0.18);
3777
+ border-bottom: 0;
3778
+ border-radius: 28px 28px 0 0;
3779
+ background:
3780
+ linear-gradient(180deg, rgba(28, 42, 52, 0.98), rgba(13, 22, 29, 0.98)),
3781
+ var(--panel-strong);
3782
+ box-shadow: 0 -22px 58px rgba(0, 0, 0, 0.42);
3783
+ animation: reply-sheet-in 190ms cubic-bezier(0.2, 0.9, 0.24, 1) both;
3784
+ }
3785
+
3786
+ .reply-sheet > * {
3787
+ min-width: 0;
3788
+ max-width: 100%;
3789
+ }
3790
+
3791
+ .reply-sheet__handle {
3792
+ justify-self: center;
3793
+ width: 2.75rem;
3794
+ height: 0.28rem;
3795
+ border-radius: 999px;
3796
+ background: rgba(205, 220, 231, 0.28);
3797
+ }
3798
+
3799
+ .reply-sheet__close {
3800
+ position: absolute;
3801
+ top: 0.82rem;
3802
+ right: max(0.9rem, env(safe-area-inset-right));
3803
+ width: 2.45rem;
3804
+ height: 2.45rem;
3805
+ display: inline-flex;
3806
+ align-items: center;
3807
+ justify-content: center;
3808
+ border: 1px solid rgba(156, 181, 197, 0.16);
3809
+ border-radius: 999px;
3810
+ background: rgba(255, 255, 255, 0.06);
3811
+ color: rgba(236, 248, 255, 0.9);
3812
+ }
3813
+
3814
+ .reply-sheet__close span {
3815
+ display: block;
3816
+ transform: translateY(-0.03em);
3817
+ font-size: 1.45rem;
3818
+ line-height: 1;
3819
+ }
3820
+
3821
+ .reply-sheet .detail-card--reply {
3822
+ width: 100%;
3823
+ max-width: 100%;
3824
+ margin-top: 0;
3825
+ padding: 0.58rem 0 0;
3826
+ border: 0;
3827
+ border-radius: 0;
3828
+ background: transparent;
3829
+ box-shadow: none;
3830
+ }
3831
+
3832
+ .reply-sheet .reply-composer__description {
3833
+ padding: 0.5rem 0.12rem;
3834
+ }
3835
+
3836
+ .reply-sheet .reply-field__input {
3837
+ min-height: 9rem;
3838
+ }
3839
+
3840
+ @keyframes reply-sheet-in {
3841
+ from {
3842
+ transform: translateY(100%);
3843
+ }
3844
+ to {
3845
+ transform: translateY(0);
3846
+ }
3847
+ }
3848
+
3849
+ @keyframes reply-sheet-backdrop-in {
3850
+ from {
3851
+ opacity: 0;
3852
+ }
3853
+ to {
3854
+ opacity: 1;
3855
+ }
3856
+ }
3857
+
3518
3858
  .a2a-task-response {
3519
3859
  width: 100%;
3520
3860
  padding: 0.85rem 0.95rem;
@@ -3572,11 +3912,15 @@ code {
3572
3912
 
3573
3913
  .reply-field {
3574
3914
  gap: 0.5rem;
3915
+ min-width: 0;
3916
+ max-width: 100%;
3575
3917
  }
3576
3918
 
3577
3919
  .reply-field__shell {
3578
3920
  display: grid;
3579
3921
  gap: 0.52rem;
3922
+ min-width: 0;
3923
+ max-width: 100%;
3580
3924
  padding: 0.82rem 0.9rem 0.76rem;
3581
3925
  border-radius: 18px;
3582
3926
  border: 1px solid var(--line);
@@ -3586,6 +3930,7 @@ code {
3586
3930
  .reply-field__input {
3587
3931
  width: 100%;
3588
3932
  min-height: 7.4rem;
3933
+ min-width: 0;
3589
3934
  padding: 0;
3590
3935
  border-radius: 0;
3591
3936
  border: 0;
@@ -3593,6 +3938,7 @@ code {
3593
3938
  color: var(--text);
3594
3939
  resize: vertical;
3595
3940
  font: inherit;
3941
+ font-size: max(1rem, 16px);
3596
3942
  line-height: 1.58;
3597
3943
  }
3598
3944
 
@@ -3606,9 +3952,11 @@ code {
3606
3952
 
3607
3953
  .reply-field__toolbar {
3608
3954
  display: grid;
3609
- grid-template-columns: auto 1fr;
3955
+ grid-template-columns: auto minmax(0, 1fr);
3610
3956
  align-items: end;
3611
3957
  gap: 0.72rem;
3958
+ min-width: 0;
3959
+ max-width: 100%;
3612
3960
  }
3613
3961
 
3614
3962
  .reply-attachment-trigger {
@@ -3709,6 +4057,7 @@ code {
3709
4057
  align-items: center;
3710
4058
  gap: 0.62rem;
3711
4059
  min-width: 0;
4060
+ max-width: 100%;
3712
4061
  cursor: pointer;
3713
4062
  }
3714
4063
 
@@ -3852,7 +4201,12 @@ code {
3852
4201
  gap: 0.32rem;
3853
4202
  }
3854
4203
 
3855
- .reply-mode-switch--settings .reply-mode-switch__hint {
4204
+ .reply-mode-switch--settings > .reply-mode-switch__copy {
4205
+ grid-column: 1;
4206
+ grid-row: 1;
4207
+ }
4208
+
4209
+ .reply-mode-switch--settings > .reply-mode-switch__hint {
3856
4210
  grid-column: 1;
3857
4211
  grid-row: 1;
3858
4212
  }
@@ -4926,3 +5280,323 @@ button[aria-busy="true"]:not(.is-loading) {
4926
5280
  font-size: 0.85rem;
4927
5281
  color: #ff8a8a;
4928
5282
  }
5283
+
5284
+ /* ─── Remote connection settings ────────────────────────────────────── */
5285
+ .settings-remote-connection {
5286
+ display: grid;
5287
+ gap: 0.8rem;
5288
+ padding: 0.92rem 1rem 1rem;
5289
+ border: 1px solid rgba(112, 202, 157, 0.16);
5290
+ border-radius: 20px;
5291
+ background:
5292
+ linear-gradient(180deg, rgba(47, 143, 103, 0.12), rgba(22, 28, 35, 0.96)),
5293
+ rgba(22, 28, 35, 0.96);
5294
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.16);
5295
+ }
5296
+
5297
+ .settings-remote-connection__header {
5298
+ display: flex;
5299
+ align-items: flex-start;
5300
+ justify-content: space-between;
5301
+ gap: 0.8rem;
5302
+ }
5303
+
5304
+ .settings-remote-connection__copy {
5305
+ display: grid;
5306
+ gap: 0.32rem;
5307
+ min-width: 0;
5308
+ }
5309
+
5310
+ .settings-remote-connection__title {
5311
+ margin: 0;
5312
+ color: var(--text);
5313
+ font-size: 1rem;
5314
+ font-weight: 800;
5315
+ line-height: 1.25;
5316
+ }
5317
+
5318
+ .settings-remote-connection__trust {
5319
+ margin: 0;
5320
+ padding: 0 0.2rem;
5321
+ color: var(--muted);
5322
+ font-size: 0.83rem;
5323
+ line-height: 1.48;
5324
+ }
5325
+
5326
+ .settings-remote-status {
5327
+ display: inline-flex;
5328
+ align-items: center;
5329
+ justify-content: center;
5330
+ flex: 0 0 auto;
5331
+ min-height: 1.85rem;
5332
+ padding: 0.24rem 0.66rem;
5333
+ border-radius: 999px;
5334
+ font-size: 0.72rem;
5335
+ font-weight: 800;
5336
+ letter-spacing: 0.04em;
5337
+ text-transform: uppercase;
5338
+ white-space: nowrap;
5339
+ }
5340
+
5341
+ .settings-remote-status--success {
5342
+ background: rgba(112, 202, 157, 0.16);
5343
+ color: #b9efd0;
5344
+ }
5345
+
5346
+ .settings-remote-status--warning {
5347
+ background: rgba(210, 170, 99, 0.16);
5348
+ color: #f5ddb1;
5349
+ }
5350
+
5351
+ .settings-remote-status--muted {
5352
+ background: rgba(156, 181, 197, 0.12);
5353
+ color: var(--muted);
5354
+ }
5355
+
5356
+ .settings-remote-device-card {
5357
+ gap: 0.55rem;
5358
+ }
5359
+
5360
+ .settings-remote-device-hint {
5361
+ margin-top: 0.78rem;
5362
+ padding: 0;
5363
+ }
5364
+
5365
+ .settings-remote-audit-list {
5366
+ display: grid;
5367
+ gap: 0.55rem;
5368
+ }
5369
+
5370
+ .settings-remote-audit-item {
5371
+ display: grid;
5372
+ grid-template-columns: auto minmax(0, 1fr) auto;
5373
+ align-items: start;
5374
+ gap: 0.65rem;
5375
+ padding: 0.72rem 0.78rem;
5376
+ border: 1px solid rgba(156, 181, 197, 0.08);
5377
+ border-radius: 15px;
5378
+ background: rgba(14, 21, 27, 0.62);
5379
+ }
5380
+
5381
+ .settings-remote-audit-dot {
5382
+ width: 0.58rem;
5383
+ height: 0.58rem;
5384
+ margin-top: 0.32rem;
5385
+ border-radius: 999px;
5386
+ background: rgba(156, 181, 197, 0.44);
5387
+ box-shadow: 0 0 0 4px rgba(156, 181, 197, 0.08);
5388
+ }
5389
+
5390
+ .settings-remote-audit-dot--success {
5391
+ background: #70ca9d;
5392
+ box-shadow: 0 0 0 4px rgba(112, 202, 157, 0.12);
5393
+ }
5394
+
5395
+ .settings-remote-audit-dot--danger {
5396
+ background: #e98686;
5397
+ box-shadow: 0 0 0 4px rgba(233, 134, 134, 0.12);
5398
+ }
5399
+
5400
+ .settings-remote-audit-body {
5401
+ min-width: 0;
5402
+ }
5403
+
5404
+ .settings-remote-audit-title {
5405
+ margin: 0;
5406
+ color: rgba(231, 243, 250, 0.9);
5407
+ font-size: 0.86rem;
5408
+ font-weight: 760;
5409
+ line-height: 1.35;
5410
+ }
5411
+
5412
+ .settings-remote-audit-meta {
5413
+ margin: 0.18rem 0 0;
5414
+ color: var(--muted);
5415
+ font-size: 0.76rem;
5416
+ line-height: 1.42;
5417
+ overflow-wrap: anywhere;
5418
+ }
5419
+
5420
+ .settings-remote-audit-time {
5421
+ color: rgba(173, 194, 207, 0.72);
5422
+ font-size: 0.72rem;
5423
+ line-height: 1.35;
5424
+ white-space: nowrap;
5425
+ }
5426
+
5427
+ .settings-remote-details {
5428
+ padding: 0.92rem 1rem;
5429
+ border: 1px solid rgba(156, 181, 197, 0.08);
5430
+ border-radius: 18px;
5431
+ background: rgba(22, 28, 35, 0.78);
5432
+ }
5433
+
5434
+ .settings-remote-details summary {
5435
+ color: rgba(205, 220, 231, 0.72);
5436
+ font-size: 0.86rem;
5437
+ }
5438
+
5439
+ .settings-remote-details[open] summary {
5440
+ margin-bottom: 0.85rem;
5441
+ color: var(--text);
5442
+ }
5443
+
5444
+ .settings-input-row {
5445
+ display: flex;
5446
+ flex-wrap: wrap;
5447
+ gap: 0.5rem;
5448
+ align-items: center;
5449
+ }
5450
+
5451
+ .settings-input {
5452
+ flex: 1 1 0;
5453
+ min-width: 0;
5454
+ width: 100%;
5455
+ padding: 0.58rem 0.75rem;
5456
+ border-radius: 0.55rem;
5457
+ border: 1px solid var(--line-strong);
5458
+ background: rgba(7, 12, 16, 0.72);
5459
+ color: var(--text);
5460
+ font: inherit;
5461
+ line-height: 1.4;
5462
+ transition: border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
5463
+ }
5464
+
5465
+ .settings-input::placeholder {
5466
+ color: rgba(205, 220, 231, 0.38);
5467
+ }
5468
+
5469
+ .settings-input:focus {
5470
+ outline: none;
5471
+ border-color: rgba(112, 202, 157, 0.55);
5472
+ background: rgba(7, 12, 16, 0.92);
5473
+ box-shadow: 0 0 0 3px rgba(47, 143, 103, 0.22);
5474
+ }
5475
+
5476
+ .settings-input:disabled {
5477
+ opacity: 0.6;
5478
+ cursor: not-allowed;
5479
+ }
5480
+
5481
+ .settings-card {
5482
+ display: grid;
5483
+ gap: 0.6rem;
5484
+ padding: 0.85rem 1rem;
5485
+ border-radius: 14px;
5486
+ background: rgba(255, 255, 255, 0.03);
5487
+ border: 1px solid rgba(156, 181, 197, 0.16);
5488
+ }
5489
+
5490
+ .settings-card + .settings-card {
5491
+ margin-top: 0.55rem;
5492
+ }
5493
+
5494
+ .settings-card__header {
5495
+ display: flex;
5496
+ align-items: flex-start;
5497
+ justify-content: space-between;
5498
+ gap: 0.6rem;
5499
+ }
5500
+
5501
+ .settings-card__title {
5502
+ margin: 0;
5503
+ font-size: 0.95rem;
5504
+ font-weight: 600;
5505
+ color: var(--text);
5506
+ word-break: break-all;
5507
+ }
5508
+
5509
+ .settings-card__subtitle {
5510
+ margin: 0.15rem 0 0 0;
5511
+ font-size: 0.72rem;
5512
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
5513
+ color: var(--muted);
5514
+ word-break: break-all;
5515
+ }
5516
+
5517
+ .settings-card__badge {
5518
+ display: inline-flex;
5519
+ align-items: center;
5520
+ flex-shrink: 0;
5521
+ padding: 0.18rem 0.55rem;
5522
+ border-radius: 999px;
5523
+ font-size: 0.68rem;
5524
+ font-weight: 600;
5525
+ letter-spacing: 0.04em;
5526
+ text-transform: uppercase;
5527
+ }
5528
+
5529
+ .settings-card__badge--live {
5530
+ background: rgba(112, 202, 157, 0.18);
5531
+ color: #b5e6cc;
5532
+ }
5533
+
5534
+ .settings-card__badge--offline {
5535
+ background: rgba(156, 181, 197, 0.14);
5536
+ color: var(--muted);
5537
+ }
5538
+
5539
+ /* "This device" badge — accent border + indigo tint to draw the eye to the
5540
+ row representing the phone the user is currently looking at. Placed
5541
+ alongside the live/offline badge inside .settings-card__badges. */
5542
+ .settings-card__badge--self {
5543
+ background: rgba(120, 144, 240, 0.18);
5544
+ color: #c2cdfa;
5545
+ border: 1px solid rgba(120, 144, 240, 0.45);
5546
+ }
5547
+
5548
+ /* Container for stacked badges — vertical stack on mobile keeps each badge
5549
+ on its own line so labels stay legible regardless of width. */
5550
+ .settings-card__badges {
5551
+ display: inline-flex;
5552
+ flex-wrap: wrap;
5553
+ align-items: flex-end;
5554
+ justify-content: flex-end;
5555
+ gap: 0.35rem;
5556
+ }
5557
+
5558
+ /* Subtle frame upgrade for the "this device" pairing card so the user can
5559
+ spot themselves in the list at a glance. */
5560
+ .settings-card--self {
5561
+ border-color: rgba(120, 144, 240, 0.45);
5562
+ background: rgba(120, 144, 240, 0.07);
5563
+ }
5564
+
5565
+ .settings-card__rows {
5566
+ display: grid;
5567
+ grid-template-columns: max-content 1fr;
5568
+ column-gap: 0.85rem;
5569
+ row-gap: 0.25rem;
5570
+ margin: 0;
5571
+ }
5572
+
5573
+ .settings-card__rows > div {
5574
+ display: contents;
5575
+ }
5576
+
5577
+ .settings-card__rows dt {
5578
+ font-size: 0.7rem;
5579
+ font-weight: 600;
5580
+ letter-spacing: 0.04em;
5581
+ color: var(--muted);
5582
+ text-transform: uppercase;
5583
+ align-self: center;
5584
+ }
5585
+
5586
+ .settings-card__rows dd {
5587
+ margin: 0;
5588
+ font-size: 0.82rem;
5589
+ color: var(--text);
5590
+ align-self: center;
5591
+ }
5592
+
5593
+ .settings-card__actions {
5594
+ display: flex;
5595
+ justify-content: flex-end;
5596
+ gap: 0.5rem;
5597
+ margin-top: 0.15rem;
5598
+ }
5599
+
5600
+ .settings-page-copy.danger {
5601
+ color: #ff8a8a;
5602
+ }