@linxin666/dsh-remote-web-ui 0.3.6 → 0.3.9

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 (238) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +77 -468
  3. package/README.zh.md +83 -113
  4. package/lib/client.js +955 -203
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +1136 -1466
  7. package/lib/types/client/FooterRemoteEntry.d.ts +6 -7
  8. package/lib/types/client/FooterRemoteEntry.d.ts.map +1 -1
  9. package/lib/types/client/FooterRemoteEntry.js +1 -1
  10. package/lib/types/client/RemoteEntry.d.ts +7 -4
  11. package/lib/types/client/RemoteEntry.d.ts.map +1 -1
  12. package/lib/types/client/RemoteEntry.js +7 -10
  13. package/lib/types/client/RemotePanel.d.ts +2 -2
  14. package/lib/types/client/RemotePanel.d.ts.map +1 -1
  15. package/lib/types/client/RemotePanel.js +2 -2
  16. package/lib/types/client/RemoteSettingsCard.d.ts +9 -5
  17. package/lib/types/client/RemoteSettingsCard.d.ts.map +1 -1
  18. package/lib/types/client/RemoteSettingsCard.js +56 -3
  19. package/lib/types/client/deep-link.d.ts +10 -13
  20. package/lib/types/client/deep-link.d.ts.map +1 -1
  21. package/lib/types/client/deep-link.js +14 -74
  22. package/lib/types/client/index.d.ts +2 -6
  23. package/lib/types/client/index.d.ts.map +1 -1
  24. package/lib/types/client/index.js +73 -39
  25. package/lib/types/client/locales.d.ts +26 -12
  26. package/lib/types/client/locales.d.ts.map +1 -1
  27. package/lib/types/client/locales.js +36 -22
  28. package/lib/types/client/mobile-adapt.d.ts +40 -0
  29. package/lib/types/client/mobile-adapt.d.ts.map +1 -0
  30. package/lib/types/client/mobile-adapt.js +967 -0
  31. package/lib/types/client/pair-api.d.ts +24 -6
  32. package/lib/types/client/pair-api.d.ts.map +1 -1
  33. package/lib/types/client/pair-api.js +9 -14
  34. package/lib/types/client/remote-channel.d.ts +3 -0
  35. package/lib/types/client/remote-channel.d.ts.map +1 -1
  36. package/lib/types/client/remote-channel.js +35 -3
  37. package/lib/types/client/settings-form.d.ts +35 -43
  38. package/lib/types/client/settings-form.d.ts.map +1 -1
  39. package/lib/types/client/settings-form.js +60 -53
  40. package/lib/types/firewall.d.ts +75 -0
  41. package/lib/types/firewall.d.ts.map +1 -0
  42. package/lib/types/firewall.js +184 -0
  43. package/lib/types/gate.d.ts +11 -5
  44. package/lib/types/gate.d.ts.map +1 -1
  45. package/lib/types/gate.js +11 -5
  46. package/lib/types/index.d.ts +39 -10
  47. package/lib/types/index.d.ts.map +1 -1
  48. package/lib/types/index.js +206 -58
  49. package/lib/types/inner-auth.d.ts +32 -0
  50. package/lib/types/inner-auth.d.ts.map +1 -0
  51. package/lib/types/inner-auth.js +72 -0
  52. package/lib/types/lan-bind-plan.d.ts +55 -0
  53. package/lib/types/lan-bind-plan.d.ts.map +1 -0
  54. package/lib/types/lan-bind-plan.js +60 -0
  55. package/lib/types/lan-bind.d.ts +69 -0
  56. package/lib/types/lan-bind.d.ts.map +1 -0
  57. package/lib/types/lan-bind.js +128 -0
  58. package/lib/types/loopback-proxy.d.ts +9 -2
  59. package/lib/types/loopback-proxy.d.ts.map +1 -1
  60. package/lib/types/loopback-proxy.js +24 -2
  61. package/lib/types/pairing.d.ts +15 -3
  62. package/lib/types/pairing.d.ts.map +1 -1
  63. package/lib/types/pairing.js +20 -6
  64. package/lib/types/remote-api.d.ts +30 -13
  65. package/lib/types/remote-api.d.ts.map +1 -1
  66. package/lib/types/remote-api.js +55 -42
  67. package/lib/types/remote-channel-boot.d.ts +21 -2
  68. package/lib/types/remote-channel-boot.d.ts.map +1 -1
  69. package/lib/types/remote-channel-boot.js +65 -3
  70. package/lib/types/remote-channel-rules.d.ts +8 -0
  71. package/lib/types/remote-channel-rules.d.ts.map +1 -1
  72. package/lib/types/remote-channel-rules.js +9 -2
  73. package/lib/types/remote-methods.d.ts +45 -11
  74. package/lib/types/remote-methods.d.ts.map +1 -1
  75. package/lib/types/remote-methods.js +56 -27
  76. package/lib/types/remote-presence-pet.d.ts +51 -0
  77. package/lib/types/remote-presence-pet.d.ts.map +1 -0
  78. package/lib/types/remote-presence-pet.js +101 -0
  79. package/lib/types/routes.d.ts +76 -4
  80. package/lib/types/routes.d.ts.map +1 -1
  81. package/lib/types/routes.js +336 -19
  82. package/lib/types/tunnel.d.ts.map +1 -1
  83. package/lib/types/tunnel.js +7 -1
  84. package/package.json +20 -18
  85. package/src/client/FooterRemoteEntry.tsx +9 -10
  86. package/src/client/RemoteEntry.tsx +13 -14
  87. package/src/client/RemotePanel.tsx +5 -16
  88. package/src/client/RemoteSettingsCard.tsx +72 -13
  89. package/src/client/deep-link.ts +14 -75
  90. package/src/client/index.ts +77 -39
  91. package/src/client/locales.ts +36 -22
  92. package/src/client/mobile-adapt.ts +913 -0
  93. package/src/client/pair-api.ts +26 -15
  94. package/src/client/remote-channel.ts +31 -3
  95. package/src/client/settings-form.ts +78 -92
  96. package/src/dsh-home.ts +1 -1
  97. package/src/firewall.ts +230 -0
  98. package/src/gate.ts +11 -5
  99. package/src/index.ts +235 -65
  100. package/src/inner-auth.ts +85 -0
  101. package/src/lan-bind-plan.ts +81 -0
  102. package/src/lan-bind.ts +145 -0
  103. package/src/loopback-proxy.ts +34 -0
  104. package/src/pairing.persist.test.ts +1 -1
  105. package/src/pairing.ts +20 -6
  106. package/src/remote-api.ts +67 -45
  107. package/src/remote-channel-boot.ts +70 -3
  108. package/src/remote-channel-rules.ts +17 -2
  109. package/src/remote-methods.ts +58 -27
  110. package/src/remote-presence-pet.ts +129 -0
  111. package/src/routes.ts +358 -19
  112. package/src/tunnel.ts +7 -1
  113. package/assets/apple-touch-icon.png +0 -0
  114. package/assets/mobile-icon-192.png +0 -0
  115. package/assets/mobile-icon-512.png +0 -0
  116. package/assets/mobile-service-worker.js +0 -63
  117. package/lib/mobile.js +0 -17658
  118. package/lib/mobile.js.map +0 -1
  119. package/lib/types/mobile/PairRequiredView.d.ts +0 -7
  120. package/lib/types/mobile/PairRequiredView.d.ts.map +0 -1
  121. package/lib/types/mobile/PairRequiredView.js +0 -28
  122. package/lib/types/mobile/PairRequiredView.test.d.ts +0 -2
  123. package/lib/types/mobile/PairRequiredView.test.d.ts.map +0 -1
  124. package/lib/types/mobile/PairRequiredView.test.js +0 -24
  125. package/lib/types/mobile/api.d.ts +0 -145
  126. package/lib/types/mobile/api.d.ts.map +0 -1
  127. package/lib/types/mobile/api.js +0 -103
  128. package/lib/types/mobile/index.d.ts +0 -10
  129. package/lib/types/mobile/index.d.ts.map +0 -1
  130. package/lib/types/mobile/index.js +0 -38
  131. package/lib/types/mobile/markdown.d.ts +0 -34
  132. package/lib/types/mobile/markdown.d.ts.map +0 -1
  133. package/lib/types/mobile/markdown.js +0 -285
  134. package/lib/types/mobile/markdown.test.d.ts +0 -2
  135. package/lib/types/mobile/markdown.test.d.ts.map +0 -1
  136. package/lib/types/mobile/markdown.test.js +0 -79
  137. package/lib/types/mobile/messages.d.ts +0 -149
  138. package/lib/types/mobile/messages.d.ts.map +0 -1
  139. package/lib/types/mobile/messages.js +0 -561
  140. package/lib/types/mobile/messages.test.d.ts +0 -2
  141. package/lib/types/mobile/messages.test.d.ts.map +0 -1
  142. package/lib/types/mobile/messages.test.js +0 -356
  143. package/lib/types/mobile/mobile-styles.d.ts +0 -6
  144. package/lib/types/mobile/mobile-styles.d.ts.map +0 -1
  145. package/lib/types/mobile/mobile-styles.js +0 -1438
  146. package/lib/types/mobile/mobile-theme.d.ts +0 -22
  147. package/lib/types/mobile/mobile-theme.d.ts.map +0 -1
  148. package/lib/types/mobile/mobile-theme.js +0 -70
  149. package/lib/types/mobile/mobile-theme.test.d.ts +0 -2
  150. package/lib/types/mobile/mobile-theme.test.d.ts.map +0 -1
  151. package/lib/types/mobile/mobile-theme.test.js +0 -71
  152. package/lib/types/mobile/mux.d.ts +0 -128
  153. package/lib/types/mobile/mux.d.ts.map +0 -1
  154. package/lib/types/mobile/mux.js +0 -305
  155. package/lib/types/mobile/mux.test.d.ts +0 -2
  156. package/lib/types/mobile/mux.test.d.ts.map +0 -1
  157. package/lib/types/mobile/mux.test.js +0 -267
  158. package/lib/types/mobile/pairing.d.ts +0 -31
  159. package/lib/types/mobile/pairing.d.ts.map +0 -1
  160. package/lib/types/mobile/pairing.js +0 -62
  161. package/lib/types/mobile/rpc.d.ts +0 -38
  162. package/lib/types/mobile/rpc.d.ts.map +0 -1
  163. package/lib/types/mobile/rpc.js +0 -83
  164. package/lib/types/mobile/theme-toggle.d.ts +0 -12
  165. package/lib/types/mobile/theme-toggle.d.ts.map +0 -1
  166. package/lib/types/mobile/theme-toggle.js +0 -26
  167. package/lib/types/mobile/views/App.d.ts +0 -57
  168. package/lib/types/mobile/views/App.d.ts.map +0 -1
  169. package/lib/types/mobile/views/App.js +0 -150
  170. package/lib/types/mobile/views/App.test.d.ts +0 -2
  171. package/lib/types/mobile/views/App.test.d.ts.map +0 -1
  172. package/lib/types/mobile/views/App.test.js +0 -52
  173. package/lib/types/mobile/views/ChatView.d.ts +0 -63
  174. package/lib/types/mobile/views/ChatView.d.ts.map +0 -1
  175. package/lib/types/mobile/views/ChatView.js +0 -821
  176. package/lib/types/mobile/views/ChatView.stream.test.d.ts +0 -2
  177. package/lib/types/mobile/views/ChatView.stream.test.d.ts.map +0 -1
  178. package/lib/types/mobile/views/ChatView.stream.test.js +0 -236
  179. package/lib/types/mobile/views/ChatView.test.d.ts +0 -2
  180. package/lib/types/mobile/views/ChatView.test.d.ts.map +0 -1
  181. package/lib/types/mobile/views/ChatView.test.js +0 -718
  182. package/lib/types/mobile/views/SessionListView.d.ts +0 -27
  183. package/lib/types/mobile/views/SessionListView.d.ts.map +0 -1
  184. package/lib/types/mobile/views/SessionListView.js +0 -139
  185. package/lib/types/mobile/views/SessionListView.test.d.ts +0 -2
  186. package/lib/types/mobile/views/SessionListView.test.d.ts.map +0 -1
  187. package/lib/types/mobile/views/SessionListView.test.js +0 -167
  188. package/lib/types/mobile/views/WorkspaceView.d.ts +0 -21
  189. package/lib/types/mobile/views/WorkspaceView.d.ts.map +0 -1
  190. package/lib/types/mobile/views/WorkspaceView.js +0 -93
  191. package/lib/types/mobile/views/WorkspaceView.test.d.ts +0 -2
  192. package/lib/types/mobile/views/WorkspaceView.test.d.ts.map +0 -1
  193. package/lib/types/mobile/views/WorkspaceView.test.js +0 -183
  194. package/lib/types/mobile-api.d.ts +0 -65
  195. package/lib/types/mobile-api.d.ts.map +0 -1
  196. package/lib/types/mobile-api.js +0 -404
  197. package/lib/types/mobile-pending.d.ts +0 -38
  198. package/lib/types/mobile-pending.d.ts.map +0 -1
  199. package/lib/types/mobile-pending.js +0 -59
  200. package/lib/types/mobile-pwa.d.ts +0 -6
  201. package/lib/types/mobile-pwa.d.ts.map +0 -1
  202. package/lib/types/mobile-pwa.js +0 -17
  203. package/lib/types/mobile-routes.d.ts +0 -13
  204. package/lib/types/mobile-routes.d.ts.map +0 -1
  205. package/lib/types/mobile-routes.js +0 -217
  206. package/lib/types/paired-model-catalog.d.ts +0 -17
  207. package/lib/types/paired-model-catalog.d.ts.map +0 -1
  208. package/lib/types/paired-model-catalog.js +0 -311
  209. package/src/mobile/PairRequiredView.test.tsx +0 -28
  210. package/src/mobile/PairRequiredView.tsx +0 -58
  211. package/src/mobile/api.ts +0 -229
  212. package/src/mobile/index.tsx +0 -41
  213. package/src/mobile/markdown.test.ts +0 -91
  214. package/src/mobile/markdown.ts +0 -291
  215. package/src/mobile/messages.test.ts +0 -402
  216. package/src/mobile/messages.ts +0 -685
  217. package/src/mobile/mobile-styles.ts +0 -1439
  218. package/src/mobile/mobile-theme.test.ts +0 -84
  219. package/src/mobile/mobile-theme.ts +0 -76
  220. package/src/mobile/mux.test.ts +0 -314
  221. package/src/mobile/mux.ts +0 -336
  222. package/src/mobile/pairing.ts +0 -77
  223. package/src/mobile/rpc.ts +0 -90
  224. package/src/mobile/theme-toggle.tsx +0 -47
  225. package/src/mobile/views/App.test.tsx +0 -62
  226. package/src/mobile/views/App.tsx +0 -213
  227. package/src/mobile/views/ChatView.stream.test.tsx +0 -268
  228. package/src/mobile/views/ChatView.test.tsx +0 -816
  229. package/src/mobile/views/ChatView.tsx +0 -1342
  230. package/src/mobile/views/SessionListView.test.tsx +0 -207
  231. package/src/mobile/views/SessionListView.tsx +0 -244
  232. package/src/mobile/views/WorkspaceView.test.tsx +0 -227
  233. package/src/mobile/views/WorkspaceView.tsx +0 -245
  234. package/src/mobile-api.ts +0 -418
  235. package/src/mobile-pending.ts +0 -88
  236. package/src/mobile-pwa.ts +0 -19
  237. package/src/mobile-routes.ts +0 -231
  238. package/src/paired-model-catalog.ts +0 -272
@@ -1,1438 +0,0 @@
1
- /**
2
- * Mobile surface stylesheet, shipped as a string and injected at boot (the
3
- * standalone page has no CSS-module pipeline).
4
- */
5
- export const mobileCss = `/* Mobile surface chrome: standalone stylesheet (no main-UI design tokens —
6
- this page boots without the shell). Light-first palette; the dark palette
7
- applies only when the header toggle sets [data-theme='dark']. */
8
-
9
- :root {
10
- --m-bg: #f3f5f9;
11
- --m-bg-raised: #ffffff;
12
- --m-bg-input: #ffffff;
13
- --m-border: #dfe4ec;
14
- --m-text: #1c2333;
15
- --m-text-secondary: #4d5768;
16
- --m-text-tertiary: #8b95a7;
17
- --m-accent: #2f6fed;
18
- --m-accent-soft: rgba(47, 111, 237, 0.12);
19
- --m-danger: #d64545;
20
- --m-success: #1e9e6a;
21
- --m-radius: 12px;
22
- --m-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
23
- --m-shadow-raise: 0 6px 20px rgba(16, 24, 40, 0.1);
24
- --m-backdrop: rgba(15, 23, 42, 0.4);
25
- }
26
-
27
- :root[data-theme='dark'] {
28
- --m-bg: #111418;
29
- --m-bg-raised: #1a1f26;
30
- --m-bg-input: #20262e;
31
- --m-border: #2b333d;
32
- --m-text: #e8eaed;
33
- --m-text-secondary: #9aa3ad;
34
- --m-text-tertiary: #6b747f;
35
- --m-accent: #4f8cff;
36
- --m-accent-soft: rgba(79, 140, 255, 0.14);
37
- --m-danger: #e5534b;
38
- --m-success: #3fb68b;
39
- --m-radius: 12px;
40
- --m-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
41
- --m-shadow-raise: 0 6px 20px rgba(0, 0, 0, 0.4);
42
- --m-backdrop: rgba(0, 0, 0, 0.55);
43
- }
44
-
45
- * {
46
- box-sizing: border-box;
47
- }
48
-
49
- html,
50
- body {
51
- margin: 0;
52
- padding: 0;
53
- height: 100%;
54
- background: var(--m-bg);
55
- color: var(--m-text);
56
- font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Noto Sans SC', 'Segoe UI', sans-serif;
57
- font-size: 15px;
58
- line-height: 1.5;
59
- -webkit-text-size-adjust: 100%;
60
- }
61
-
62
- /* The app fills exactly one viewport: the page itself never scrolls, each
63
- view owns its scroll region (chat history, session lists) and the chat
64
- composer stays pinned to the bottom of the screen. */
65
- #root {
66
- height: 100dvh;
67
- display: flex;
68
- flex-direction: column;
69
- overflow: hidden;
70
- }
71
-
72
- .mobile {
73
- min-height: 0;
74
- flex: 1;
75
- display: flex;
76
- flex-direction: column;
77
- overflow: hidden;
78
- }
79
-
80
- /* ── header ─────────────────────────────────────────────────────────── */
81
-
82
- .mobile-header {
83
- position: sticky;
84
- top: 0;
85
- z-index: 10;
86
- flex-shrink: 0;
87
- display: flex;
88
- align-items: center;
89
- gap: 8px;
90
- padding: calc(env(safe-area-inset-top, 0px) + 12px) 16px 10px;
91
- background: color-mix(in srgb, var(--m-bg) 88%, transparent);
92
- backdrop-filter: blur(10px);
93
- border-bottom: 1px solid var(--m-border);
94
- }
95
-
96
- .mobile-title {
97
- margin: 0;
98
- font-size: 17px;
99
- font-weight: 600;
100
- }
101
-
102
- .mobile-titleInline {
103
- flex: 1;
104
- overflow: hidden;
105
- text-overflow: ellipsis;
106
- white-space: nowrap;
107
- }
108
-
109
- .mobile-back {
110
- flex: none;
111
- width: 32px;
112
- height: 32px;
113
- border: none;
114
- border-radius: 50%;
115
- background: transparent;
116
- color: var(--m-text);
117
- font-size: 22px;
118
- line-height: 1;
119
- cursor: pointer;
120
- transition: background-color 0.12s ease, box-shadow 0.12s ease;
121
- }
122
-
123
- .mobile-back:active {
124
- background: var(--m-bg-raised);
125
- }
126
-
127
- .mobile-back:focus-visible {
128
- outline: none;
129
- box-shadow: 0 0 0 2px var(--m-bg), 0 0 0 4px var(--m-accent);
130
- }
131
-
132
- .mobile-theme-toggle {
133
- flex: none;
134
- margin-left: auto;
135
- width: 32px;
136
- height: 32px;
137
- display: inline-flex;
138
- align-items: center;
139
- justify-content: center;
140
- border: none;
141
- border-radius: 50%;
142
- background: transparent;
143
- color: var(--m-text-secondary);
144
- cursor: pointer;
145
- transition: background-color 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
146
- }
147
-
148
- .mobile-theme-toggle:active {
149
- background: var(--m-bg-raised);
150
- }
151
-
152
- .mobile-theme-toggle:focus-visible {
153
- outline: none;
154
- box-shadow: 0 0 0 2px var(--m-bg), 0 0 0 4px var(--m-accent);
155
- }
156
-
157
- .mobile-theme-toggle svg {
158
- width: 18px;
159
- height: 18px;
160
- }
161
-
162
- /* ── lists ───────────────────────────────────────────────────────────── */
163
-
164
- .mobile-list {
165
- flex: 1;
166
- min-height: 0;
167
- overflow-y: auto;
168
- list-style: none;
169
- margin: 0;
170
- padding: 8px 0 calc(env(safe-area-inset-bottom, 0px) + 16px);
171
- }
172
-
173
- .mobile-row {
174
- display: flex;
175
- align-items: center;
176
- gap: 10px;
177
- width: calc(100% - 24px);
178
- margin: 0 12px 8px;
179
- padding: 13px 14px;
180
- border: 1px solid var(--m-border);
181
- border-radius: 14px;
182
- background: var(--m-bg-raised);
183
- box-shadow: var(--m-shadow);
184
- color: var(--m-text);
185
- text-align: left;
186
- cursor: pointer;
187
- }
188
-
189
- .mobile-row:active {
190
- background: color-mix(in srgb, var(--m-text) 5%, var(--m-bg-raised));
191
- }
192
-
193
- .mobile-rowMain {
194
- flex: 1;
195
- min-width: 0;
196
- display: flex;
197
- align-items: baseline;
198
- gap: 8px;
199
- }
200
-
201
- .mobile-rowTitle {
202
- flex: 1;
203
- min-width: 0;
204
- overflow: hidden;
205
- text-overflow: ellipsis;
206
- white-space: nowrap;
207
- font-size: 15px;
208
- }
209
-
210
- .mobile-rowMeta {
211
- flex: none;
212
- color: var(--m-text-tertiary);
213
- font-size: 12px;
214
- }
215
-
216
- .mobile-chevron {
217
- flex: none;
218
- color: var(--m-text-tertiary);
219
- font-size: 18px;
220
- }
221
-
222
- .mobile-live {
223
- margin-left: 6px;
224
- color: var(--m-success);
225
- font-size: 10px;
226
- vertical-align: middle;
227
- }
228
-
229
- /* ── empty / error states ────────────────────────────────────────────── */
230
-
231
- .mobile-empty {
232
- flex: 1;
233
- display: flex;
234
- flex-direction: column;
235
- align-items: center;
236
- justify-content: center;
237
- gap: 12px;
238
- padding: 32px;
239
- }
240
-
241
- .mobile-muted {
242
- margin: 0;
243
- color: var(--m-text-tertiary);
244
- }
245
-
246
- .mobile-error {
247
- margin: 0;
248
- color: var(--m-danger);
249
- }
250
-
251
- .mobile-pad {
252
- padding: 8px 16px;
253
- }
254
-
255
- .mobile-create {
256
- display: grid;
257
- gap: 8px;
258
- }
259
-
260
- .mobile-preset {
261
- display: grid;
262
- gap: 4px;
263
- }
264
-
265
- .mobile-presetLabel {
266
- color: var(--m-text-secondary);
267
- font-size: 13px;
268
- font-weight: 600;
269
- }
270
-
271
- .mobile-presetSelect {
272
- width: 100%;
273
- height: 40px;
274
- padding: 0 36px 0 12px;
275
- border: 1px solid var(--m-border);
276
- border-radius: 10px;
277
- background: var(--m-bg-input);
278
- color: var(--m-text);
279
- font: inherit;
280
- }
281
-
282
- .mobile-presetSelect:disabled {
283
- opacity: 0.6;
284
- }
285
-
286
- .mobile-presetDescription {
287
- margin: 0;
288
- color: var(--m-text-tertiary);
289
- font-size: 12px;
290
- }
291
-
292
- /* ── buttons ─────────────────────────────────────────────────────────── */
293
-
294
- .mobile-button {
295
- height: 38px;
296
- padding: 0 18px;
297
- border: 1px solid var(--m-border);
298
- border-radius: 10px;
299
- background: var(--m-bg-raised);
300
- color: var(--m-text);
301
- font-size: 14px;
302
- cursor: pointer;
303
- }
304
-
305
- .mobile-button:disabled {
306
- opacity: 0.5;
307
- }
308
-
309
- .mobile-block {
310
- display: block;
311
- width: calc(100% - 32px);
312
- margin: 4px 16px;
313
- }
314
-
315
- /* Primary action (create session): accent fill, readable on both themes. */
316
- .mobile-new {
317
- display: block;
318
- width: 100%;
319
- height: 44px;
320
- border: none;
321
- border-radius: 12px;
322
- background: linear-gradient(135deg, var(--m-accent) 0%, #4c8dff 100%);
323
- color: #fff;
324
- font-size: 15px;
325
- font-weight: 600;
326
- cursor: pointer;
327
- box-shadow: 0 2px 8px rgba(47, 111, 237, 0.3);
328
- }
329
-
330
- .mobile-new:active {
331
- opacity: 0.88;
332
- }
333
-
334
- .mobile-new:disabled {
335
- opacity: 0.6;
336
- }
337
-
338
- .mobile-hint {
339
- display: block;
340
- margin-top: 2px;
341
- color: var(--m-text-tertiary);
342
- font-size: 12px;
343
- }
344
-
345
- /* ── chat ────────────────────────────────────────────────────────────── */
346
-
347
- .chat {
348
- flex: 1;
349
- display: flex;
350
- flex-direction: column;
351
- min-height: 0;
352
- }
353
-
354
- .chat-scroll {
355
- flex: 1;
356
- overflow-y: auto;
357
- padding: 12px 14px calc(env(safe-area-inset-bottom, 0px) + 12px);
358
- display: flex;
359
- flex-direction: column;
360
- gap: 10px;
361
- }
362
-
363
- .chat-msg {
364
- max-width: 88%;
365
- padding: 10px 12px;
366
- border-radius: var(--m-radius);
367
- font-size: 14.5px;
368
- line-height: 1.55;
369
- overflow-wrap: break-word;
370
- white-space: pre-wrap;
371
- }
372
-
373
- .chat-msg-user {
374
- align-self: flex-end;
375
- background: linear-gradient(135deg, var(--m-accent) 0%, #4c8dff 100%);
376
- color: #fff;
377
- border-bottom-right-radius: 4px;
378
- box-shadow: 0 1px 3px rgba(47, 111, 237, 0.28);
379
- }
380
-
381
- .chat-msg-assistant {
382
- align-self: flex-start;
383
- background: var(--m-bg-raised);
384
- border: 1px solid var(--m-border);
385
- border-bottom-left-radius: 4px;
386
- box-shadow: var(--m-shadow);
387
- }
388
-
389
- .chat-msg-pending .chat-msg-text::after {
390
- content: '▍';
391
- animation: chat-blink 1s steps(2) infinite;
392
- }
393
-
394
- @keyframes chat-blink {
395
- 50% {
396
- opacity: 0;
397
- }
398
- }
399
-
400
- .chat-msg-failed {
401
- border-color: var(--m-danger);
402
- }
403
-
404
- .chat-msg-failtag {
405
- display: inline-block;
406
- margin-top: 6px;
407
- padding: 1px 8px;
408
- border: 1px solid var(--m-danger);
409
- border-radius: 999px;
410
- color: var(--m-danger);
411
- font-size: 11px;
412
- }
413
-
414
- .chat-msg-time {
415
- display: block;
416
- margin-top: 4px;
417
- color: var(--m-text-tertiary);
418
- font-size: 10.5px;
419
- line-height: 1.2;
420
- }
421
-
422
- .chat-msg-toggle {
423
- display: block;
424
- margin-top: 8px;
425
- padding: 4px 0;
426
- border: none;
427
- background: transparent;
428
- color: var(--m-accent);
429
- font-size: 13px;
430
- cursor: pointer;
431
- }
432
-
433
- /* Assistant markdown content (GFM subset; renderer in markdown.ts). */
434
- .chat-md {
435
- white-space: normal;
436
- }
437
- .chat-md-collapsed {
438
- max-height: 45vh;
439
- overflow: hidden;
440
- position: relative;
441
- }
442
- .chat-md-collapsed::after {
443
- content: '';
444
- position: absolute;
445
- left: 0;
446
- right: 0;
447
- bottom: 0;
448
- height: 28px;
449
- background: linear-gradient(transparent, var(--m-bg-raised));
450
- pointer-events: none;
451
- }
452
- .chat-md-body p { margin: 0 0 8px; }
453
- .chat-md-body p:last-child { margin-bottom: 0; }
454
- .chat-md-body h1, .chat-md-body h2, .chat-md-body h3,
455
- .chat-md-body h4, .chat-md-body h5, .chat-md-body h6 {
456
- margin: 12px 0 6px;
457
- font-weight: 650;
458
- line-height: 1.3;
459
- }
460
- .chat-md-body h1 { font-size: 1.35em; }
461
- .chat-md-body h2 { font-size: 1.25em; }
462
- .chat-md-body h3 { font-size: 1.15em; }
463
- .chat-md-body h4, .chat-md-body h5, .chat-md-body h6 { font-size: 1.05em; }
464
- .chat-md-body code {
465
- font-family: var(--m-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
466
- font-size: 0.9em;
467
- background: var(--m-accent-soft);
468
- padding: 1px 5px;
469
- border-radius: 4px;
470
- }
471
- .chat-md-body pre {
472
- margin: 8px 0;
473
- padding: 10px;
474
- background: #101726;
475
- color: #dbe4f5;
476
- border-radius: 8px;
477
- overflow-x: auto;
478
- font-size: 12.5px;
479
- line-height: 1.5;
480
- }
481
- .chat-md-body pre code {
482
- background: transparent;
483
- padding: 0;
484
- color: inherit;
485
- }
486
- .chat-md-body ul, .chat-md-body ol { margin: 4px 0 8px; padding-left: 22px; }
487
- .chat-md-body li { margin: 2px 0; }
488
- .chat-md-body blockquote {
489
- margin: 8px 0;
490
- padding: 4px 10px;
491
- border-left: 3px solid var(--m-accent);
492
- background: var(--m-accent-soft);
493
- border-radius: 0 6px 6px 0;
494
- color: var(--m-text-secondary);
495
- }
496
- .chat-md-body table {
497
- margin: 8px 0;
498
- border-collapse: collapse;
499
- display: block;
500
- overflow-x: auto;
501
- font-size: 13px;
502
- }
503
- .chat-md-body th, .chat-md-body td {
504
- border: 1px solid var(--m-border);
505
- padding: 4px 8px;
506
- }
507
- .chat-md-body th { background: var(--m-accent-soft); }
508
- .chat-md-body a { color: var(--m-accent); }
509
- .chat-md-body hr { border: none; border-top: 1px solid var(--m-border); margin: 10px 0; }
510
- .chat-md-body img { max-width: 100%; border-radius: 8px; }
511
-
512
- /* ── message disclosures (reasoning / tools) ─────────────────────────── */
513
-
514
- .chat-disclosure {
515
- margin-bottom: 8px;
516
- border: 1px solid var(--m-border);
517
- border-radius: 10px;
518
- background: color-mix(in srgb, var(--m-bg) 55%, transparent);
519
- overflow: hidden;
520
- }
521
-
522
- .chat-disclosure-head {
523
- display: flex;
524
- align-items: center;
525
- gap: 6px;
526
- width: 100%;
527
- padding: 7px 10px;
528
- border: none;
529
- background: transparent;
530
- color: var(--m-text);
531
- font-size: 12.5px;
532
- text-align: left;
533
- cursor: pointer;
534
- white-space: nowrap;
535
- }
536
-
537
- .chat-disclosure-caret {
538
- flex: none;
539
- color: var(--m-text-tertiary);
540
- font-size: 14px;
541
- line-height: 1;
542
- transition: transform 0.15s ease;
543
- }
544
-
545
- .chat-disclosure-open .chat-disclosure-caret {
546
- transform: rotate(90deg);
547
- }
548
-
549
- .chat-disclosure-label {
550
- flex: none;
551
- color: var(--m-text-secondary);
552
- }
553
-
554
- .chat-reasoning[data-pending] .chat-disclosure-label {
555
- color: var(--m-accent);
556
- }
557
-
558
- .chat-disclosure-summary {
559
- flex: 1;
560
- min-width: 0;
561
- overflow: hidden;
562
- text-overflow: ellipsis;
563
- color: var(--m-text-tertiary);
564
- font-size: 12px;
565
- }
566
-
567
- .chat-disclosure-count {
568
- flex: none;
569
- color: var(--m-text-tertiary);
570
- font-size: 11px;
571
- }
572
-
573
- .chat-disclosure-body {
574
- padding: 8px 10px 10px;
575
- border-top: 1px dashed var(--m-border);
576
- color: var(--m-text-secondary);
577
- font-size: 12.5px;
578
- line-height: 1.6;
579
- overflow-wrap: break-word;
580
- white-space: pre-wrap;
581
- max-height: 40vh;
582
- overflow-y: auto;
583
- }
584
-
585
- .chat-tools-body {
586
- display: flex;
587
- flex-direction: column;
588
- gap: 8px;
589
- }
590
-
591
- .chat-tool-card {
592
- display: flex;
593
- flex-direction: column;
594
- gap: 4px;
595
- padding: 6px 8px;
596
- border: 1px solid var(--m-border);
597
- border-radius: 8px;
598
- background: var(--m-bg-raised);
599
- }
600
-
601
- .chat-tool-pills {
602
- display: flex;
603
- gap: 4px;
604
- flex-wrap: wrap;
605
- align-items: center;
606
- }
607
-
608
- .chat-tool-pill {
609
- display: inline-block;
610
- padding: 1px 7px;
611
- border-radius: 999px;
612
- background: var(--m-accent-soft);
613
- color: var(--m-accent);
614
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
615
- font-size: 11px;
616
- font-weight: 600;
617
- white-space: nowrap;
618
- }
619
-
620
- .chat-tool-args {
621
- margin: 0;
622
- padding: 6px 8px;
623
- border-radius: 6px;
624
- background: var(--m-bg-input);
625
- color: var(--m-text-secondary);
626
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
627
- font-size: 11px;
628
- line-height: 1.5;
629
- overflow-wrap: break-word;
630
- white-space: pre-wrap;
631
- max-height: 200px;
632
- overflow-y: auto;
633
- }
634
-
635
- /* ── turn status indicator (#1017) ───────────────────────────────────── */
636
-
637
- .chat-turn-status {
638
- display: flex;
639
- align-items: center;
640
- gap: 6px;
641
- padding: 10px 16px;
642
- color: var(--m-accent);
643
- font-size: 13px;
644
- font-weight: 600;
645
- background: linear-gradient(
646
- 90deg,
647
- var(--m-accent) 0%,
648
- color-mix(in srgb, var(--m-accent) 60%, #ffffff) 50%,
649
- var(--m-accent) 100%
650
- );
651
- background-size: 200% 100%;
652
- background-clip: text;
653
- -webkit-background-clip: text;
654
- -webkit-text-fill-color: transparent;
655
- animation: dsh-shimmer 1.8s linear infinite;
656
- }
657
-
658
- .chat-turn-dots {
659
- display: inline-flex;
660
- gap: 3px;
661
- }
662
-
663
- .chat-turn-dots span {
664
- display: inline-block;
665
- width: 5px;
666
- height: 5px;
667
- border-radius: 50%;
668
- background: var(--m-accent);
669
- animation: dsh-dot-bounce 1.2s ease-in-out infinite;
670
- }
671
-
672
- .chat-turn-dots span:nth-child(2) {
673
- animation-delay: 0.15s;
674
- }
675
-
676
- .chat-turn-dots span:nth-child(3) {
677
- animation-delay: 0.3s;
678
- }
679
-
680
- @keyframes dsh-shimmer {
681
- from { background-position: 200% 0; }
682
- to { background-position: -200% 0; }
683
- }
684
-
685
- @keyframes dsh-dot-bounce {
686
- 0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
687
- 40% { transform: translateY(-4px); opacity: 1; }
688
- }
689
-
690
- /* ── approval panel (#1025) ──────────────────────────────────────────── */
691
-
692
- .chat-approval-panel {
693
- margin: 8px 12px;
694
- padding: 10px 12px;
695
- border: 1px solid var(--m-accent);
696
- border-radius: var(--m-radius);
697
- background: var(--m-bg-raised);
698
- box-shadow: var(--m-shadow);
699
- }
700
-
701
- .chat-approval-header {
702
- display: flex;
703
- align-items: center;
704
- gap: 8px;
705
- margin-bottom: 8px;
706
- }
707
-
708
- .chat-approval-reason {
709
- color: var(--m-text-secondary);
710
- font-size: 12.5px;
711
- }
712
-
713
- .chat-approval-error {
714
- margin: 4px 0;
715
- color: var(--m-danger);
716
- font-size: 12px;
717
- }
718
-
719
- .chat-approval-actions {
720
- display: flex;
721
- gap: 8px;
722
- }
723
-
724
- .chat-approval-allow {
725
- flex: 1;
726
- height: 34px;
727
- border: none;
728
- border-radius: 8px;
729
- background: var(--m-accent);
730
- color: #fff;
731
- font: inherit;
732
- font-size: 13px;
733
- font-weight: 600;
734
- cursor: pointer;
735
- }
736
-
737
- .chat-approval-allow:disabled {
738
- opacity: 0.6;
739
- }
740
-
741
- .chat-approval-reject {
742
- flex: 1;
743
- height: 34px;
744
- border: 1px solid var(--m-border);
745
- border-radius: 8px;
746
- background: var(--m-bg-raised);
747
- color: var(--m-text);
748
- font: inherit;
749
- font-size: 13px;
750
- cursor: pointer;
751
- }
752
-
753
- .chat-approval-reject:disabled {
754
- opacity: 0.6;
755
- }
756
-
757
- /* ── question panel (#1025) ──────────────────────────────────────────── */
758
-
759
- .chat-question-panel {
760
- margin: 8px 12px;
761
- padding: 10px 12px;
762
- border: 1px solid var(--m-accent);
763
- border-radius: var(--m-radius);
764
- background: var(--m-bg-raised);
765
- box-shadow: var(--m-shadow);
766
- display: flex;
767
- flex-direction: column;
768
- gap: 10px;
769
- }
770
-
771
- .chat-question-group {
772
- display: flex;
773
- flex-direction: column;
774
- gap: 6px;
775
- }
776
-
777
- .chat-question-header {
778
- font-size: 14px;
779
- font-weight: 600;
780
- color: var(--m-text);
781
- }
782
-
783
- .chat-question-text {
784
- font-size: 13px;
785
- color: var(--m-text);
786
- line-height: 1.5;
787
- }
788
-
789
- .chat-question-detail {
790
- font-size: 12px;
791
- color: var(--m-text-secondary);
792
- line-height: 1.5;
793
- }
794
-
795
- .chat-question-options {
796
- display: flex;
797
- flex-direction: column;
798
- gap: 4px;
799
- }
800
-
801
- .chat-question-option {
802
- display: flex;
803
- align-items: flex-start;
804
- gap: 8px;
805
- padding: 8px 10px;
806
- border: 1px solid var(--m-border);
807
- border-radius: 8px;
808
- cursor: pointer;
809
- font-size: 13px;
810
- transition: border-color 0.12s, background 0.12s;
811
- }
812
-
813
- .chat-question-option input {
814
- margin: 2px 0 0;
815
- flex: none;
816
- }
817
-
818
- .chat-question-option-selected {
819
- border-color: var(--m-accent);
820
- background: var(--m-accent-soft);
821
- }
822
-
823
- .chat-question-option-label {
824
- color: var(--m-text);
825
- font-weight: 500;
826
- }
827
-
828
- .chat-question-option-desc {
829
- display: block;
830
- color: var(--m-text-tertiary);
831
- font-size: 12px;
832
- }
833
-
834
- .chat-question-custom {
835
- width: 100%;
836
- min-height: 40px;
837
- box-sizing: border-box;
838
- padding: 8px 10px;
839
- border: 1px solid var(--m-border);
840
- border-radius: 8px;
841
- background: var(--m-bg-input);
842
- color: var(--m-text);
843
- font: inherit;
844
- font-size: 13px;
845
- resize: vertical;
846
- outline: none;
847
- }
848
-
849
- .chat-question-custom:focus-visible {
850
- border-color: var(--m-accent);
851
- }
852
-
853
- .chat-question-submit {
854
- height: 36px;
855
- border: none;
856
- border-radius: 8px;
857
- background: var(--m-accent);
858
- color: #fff;
859
- font: inherit;
860
- font-size: 13px;
861
- font-weight: 600;
862
- cursor: pointer;
863
- }
864
-
865
- .chat-question-submit:disabled {
866
- opacity: 0.6;
867
- }
868
-
869
-
870
- /* ── composer toolbar (model / permission chips) ─────────────────────── */
871
-
872
- .chat-tools {
873
- display: flex;
874
- gap: 8px;
875
- padding: 6px 12px 0;
876
- }
877
-
878
- .chat-chip {
879
- flex: 1;
880
- min-width: 0;
881
- display: flex;
882
- align-items: center;
883
- gap: 6px;
884
- height: 32px;
885
- padding: 0 10px;
886
- border: 1px solid var(--m-border);
887
- border-radius: 999px;
888
- background: var(--m-bg-raised);
889
- box-shadow: var(--m-shadow);
890
- color: var(--m-text);
891
- font-size: 12px;
892
- cursor: pointer;
893
- }
894
-
895
- .chat-chip:active {
896
- border-color: var(--m-accent);
897
- background: var(--m-accent-soft);
898
- }
899
-
900
- .chat-chip-label {
901
- flex: none;
902
- color: var(--m-text-tertiary);
903
- }
904
-
905
- .chat-chip-value {
906
- flex: 1;
907
- min-width: 0;
908
- overflow: hidden;
909
- text-overflow: ellipsis;
910
- white-space: nowrap;
911
- }
912
-
913
- .chat-chip-chevron {
914
- flex: none;
915
- color: var(--m-text-tertiary);
916
- font-size: 14px;
917
- }
918
-
919
- /* ── bottom sheets ───────────────────────────────────────────────────── */
920
-
921
- .sheet-backdrop {
922
- position: fixed;
923
- inset: 0;
924
- z-index: 50;
925
- display: flex;
926
- flex-direction: column;
927
- justify-content: flex-end;
928
- background: var(--m-backdrop);
929
- animation: sheet-fade 0.18s ease;
930
- }
931
-
932
- @keyframes sheet-fade {
933
- from {
934
- opacity: 0;
935
- }
936
- to {
937
- opacity: 1;
938
- }
939
- }
940
-
941
- .sheet {
942
- max-height: 74dvh;
943
- display: flex;
944
- flex-direction: column;
945
- background: var(--m-bg-raised);
946
- border: 1px solid var(--m-border);
947
- border-bottom: none;
948
- border-radius: 16px 16px 0 0;
949
- box-shadow: var(--m-shadow-raise);
950
- padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
951
- animation: sheet-up 0.22s ease;
952
- }
953
-
954
- @keyframes sheet-up {
955
- from {
956
- transform: translateY(40px);
957
- opacity: 0.6;
958
- }
959
- to {
960
- transform: translateY(0);
961
- opacity: 1;
962
- }
963
- }
964
-
965
- .sheet-handle {
966
- flex: none;
967
- align-self: center;
968
- width: 36px;
969
- height: 4px;
970
- margin: 8px 0 4px;
971
- border-radius: 999px;
972
- background: var(--m-border);
973
- }
974
-
975
- .sheet-title {
976
- flex: none;
977
- padding: 6px 16px 10px;
978
- font-size: 15px;
979
- font-weight: 600;
980
- }
981
-
982
- .sheet-body {
983
- flex: 1;
984
- min-height: 0;
985
- overflow-y: auto;
986
- padding: 0 12px 8px;
987
- }
988
-
989
- .sheet-status {
990
- padding: 18px 8px;
991
- color: var(--m-text-tertiary);
992
- font-size: 13px;
993
- text-align: center;
994
- display: flex;
995
- flex-direction: column;
996
- align-items: center;
997
- gap: 8px;
998
- }
999
-
1000
- .sheet-status-error {
1001
- color: var(--m-danger);
1002
- }
1003
-
1004
- .sheet-hint {
1005
- margin: 0;
1006
- color: var(--m-text-secondary);
1007
- font-size: 12px;
1008
- line-height: 1.5;
1009
- max-width: 32em;
1010
- }
1011
-
1012
- .sheet-error {
1013
- margin: 0 0 8px;
1014
- color: var(--m-danger);
1015
- font-size: 12.5px;
1016
- }
1017
-
1018
- .sheet-section {
1019
- margin-bottom: 14px;
1020
- }
1021
-
1022
- .sheet-section-title {
1023
- padding: 4px 8px 6px;
1024
- color: var(--m-text-tertiary);
1025
- font-size: 12px;
1026
- font-weight: 600;
1027
- }
1028
-
1029
- .sheet-option {
1030
- display: flex;
1031
- align-items: center;
1032
- gap: 10px;
1033
- width: 100%;
1034
- padding: 10px 12px;
1035
- border: 1px solid transparent;
1036
- border-radius: 10px;
1037
- background: transparent;
1038
- color: var(--m-text);
1039
- text-align: left;
1040
- cursor: pointer;
1041
- }
1042
-
1043
- .sheet-option:active {
1044
- background: var(--m-bg-input);
1045
- }
1046
-
1047
- .sheet-option-selected {
1048
- border-color: var(--m-accent);
1049
- background: color-mix(in srgb, var(--m-accent) 12%, transparent);
1050
- }
1051
-
1052
- .sheet-option:disabled {
1053
- opacity: 0.5;
1054
- }
1055
-
1056
- .sheet-option-copy {
1057
- flex: 1;
1058
- min-width: 0;
1059
- display: flex;
1060
- flex-direction: column;
1061
- gap: 2px;
1062
- }
1063
-
1064
- .sheet-option-title {
1065
- font-size: 14px;
1066
- }
1067
-
1068
- .sheet-option-desc {
1069
- color: var(--m-text-tertiary);
1070
- font-size: 12px;
1071
- line-height: 1.4;
1072
- }
1073
-
1074
- .sheet-option-check {
1075
- flex: none;
1076
- color: var(--m-accent);
1077
- font-size: 15px;
1078
- font-weight: 700;
1079
- }
1080
-
1081
- .sheet-confirm-desc {
1082
- margin: 0 4px 14px;
1083
- color: var(--m-text-secondary);
1084
- font-size: 13px;
1085
- line-height: 1.6;
1086
- }
1087
-
1088
- .sheet-confirm-actions {
1089
- display: flex;
1090
- gap: 10px;
1091
- padding: 4px;
1092
- }
1093
-
1094
- .sheet-confirm-actions .mobile-button {
1095
- flex: 1;
1096
- }
1097
-
1098
- .sheet-confirm-danger {
1099
- flex: 1;
1100
- height: 38px;
1101
- border: none;
1102
- border-radius: 10px;
1103
- background: var(--m-danger);
1104
- color: #fff;
1105
- font-size: 14px;
1106
- cursor: pointer;
1107
- }
1108
-
1109
- .sheet-confirm-danger:disabled {
1110
- opacity: 0.5;
1111
- }
1112
-
1113
- .chat-meta {
1114
- margin-top: 4px;
1115
- color: var(--m-text-tertiary);
1116
- font-size: 11px;
1117
- }
1118
-
1119
- .chat-typing {
1120
- color: var(--m-text-tertiary);
1121
- font-size: 13px;
1122
- padding: 4px 2px;
1123
- }
1124
-
1125
- .chat-inputbar {
1126
- display: flex;
1127
- gap: 8px;
1128
- padding: 10px 12px calc(env(safe-area-inset-bottom, 0px) + 10px);
1129
- border-top: 1px solid var(--m-border);
1130
- background: var(--m-bg);
1131
- }
1132
-
1133
- .chat-input {
1134
- flex: 1;
1135
- min-width: 0;
1136
- min-height: 40px;
1137
- max-height: 120px;
1138
- /* Grow with the content (still bounded by min/max-height); browsers
1139
- without field-sizing support ignore this line and keep the old size. */
1140
- field-sizing: content;
1141
- padding: 9px 12px;
1142
- border: 1px solid var(--m-border);
1143
- border-radius: 10px;
1144
- background: var(--m-bg-input);
1145
- color: var(--m-text);
1146
- font: inherit;
1147
- font-size: 14.5px;
1148
- resize: none;
1149
- outline: none;
1150
- }
1151
-
1152
- .chat-input:focus {
1153
- border-color: var(--m-accent);
1154
- }
1155
-
1156
- .chat-send {
1157
- flex: none;
1158
- align-self: flex-end;
1159
- height: 40px;
1160
- padding: 0 16px;
1161
- border: none;
1162
- border-radius: 10px;
1163
- background: var(--m-accent);
1164
- color: #fff;
1165
- font-size: 14px;
1166
- cursor: pointer;
1167
- }
1168
-
1169
- .chat-send:disabled {
1170
- opacity: 0.5;
1171
- }
1172
-
1173
- /* Running state: the primary button carries only the square stop icon, so
1174
- it centers the glyph instead of sizing to text. */
1175
- .chat-send-stop {
1176
- display: inline-flex;
1177
- align-items: center;
1178
- justify-content: center;
1179
- min-width: 44px;
1180
- padding: 0 12px;
1181
- }
1182
-
1183
- .chat-load-older {
1184
- align-self: center;
1185
- margin: 4px 0;
1186
- border: none;
1187
- background: transparent;
1188
- color: var(--m-text-secondary);
1189
- font-size: 13px;
1190
- cursor: pointer;
1191
- padding: 6px 10px;
1192
- }
1193
-
1194
- /* Touch surfaces have no hover, so keyboard focus must be fully visible.
1195
- One shared ring keeps every interactive control consistent and readable
1196
- on both palettes. */
1197
- .mobile-row:focus-visible,
1198
- .mobile-button:focus-visible,
1199
- .mobile-new:focus-visible,
1200
- .mobile-presetSelect:focus-visible,
1201
- .chat-send:focus-visible,
1202
- .chat-chip:focus-visible,
1203
- .chat-msg-toggle:focus-visible,
1204
- .chat-load-older:focus-visible,
1205
- .chat-disclosure-head:focus-visible,
1206
- .sheet-option:focus-visible,
1207
- .sheet-confirm-danger:focus-visible,
1208
- .sheet-toggle-switch:focus-visible,
1209
- .chat-input:focus-visible {
1210
- outline: none;
1211
- box-shadow: 0 0 0 2px var(--m-bg), 0 0 0 4px var(--m-accent);
1212
- }
1213
-
1214
- /* ── chat context usage chip (chat-tools row) ───────────────────────── */
1215
-
1216
- .chat-context {
1217
- flex: none;
1218
- align-self: center;
1219
- padding: 2px 10px;
1220
- border: 1px solid var(--m-border);
1221
- border-radius: 999px;
1222
- background: color-mix(in srgb, var(--m-text-tertiary) 10%, transparent);
1223
- color: var(--m-text-tertiary);
1224
- font-size: 11px;
1225
- line-height: 1.6;
1226
- white-space: nowrap;
1227
- }
1228
-
1229
- .chat-context-warn {
1230
- border-color: var(--m-danger);
1231
- background: color-mix(in srgb, var(--m-danger) 14%, transparent);
1232
- color: var(--m-danger);
1233
- }
1234
-
1235
- /* ── display sheet toggle rows ──────────────────────────────────────── */
1236
-
1237
- .sheet-toggle-row {
1238
- display: flex;
1239
- align-items: center;
1240
- gap: 12px;
1241
- padding: 12px 8px;
1242
- border-bottom: 1px solid var(--m-border);
1243
- }
1244
-
1245
- .sheet-toggle-row:last-child {
1246
- border-bottom: none;
1247
- }
1248
-
1249
- .sheet-toggle-copy {
1250
- flex: 1;
1251
- min-width: 0;
1252
- display: flex;
1253
- flex-direction: column;
1254
- gap: 2px;
1255
- }
1256
-
1257
- .sheet-toggle-title {
1258
- font-size: 14px;
1259
- }
1260
-
1261
- .sheet-toggle-desc {
1262
- color: var(--m-text-tertiary);
1263
- font-size: 12px;
1264
- line-height: 1.4;
1265
- }
1266
-
1267
- .sheet-toggle-switch {
1268
- position: relative;
1269
- flex: none;
1270
- width: 44px;
1271
- height: 26px;
1272
- border: none;
1273
- border-radius: 999px;
1274
- background: var(--m-border);
1275
- cursor: pointer;
1276
- transition: background-color 0.15s ease;
1277
- }
1278
-
1279
- .sheet-toggle-switch-on {
1280
- background: var(--m-accent);
1281
- }
1282
-
1283
- .sheet-toggle-switch-knob {
1284
- position: absolute;
1285
- top: 3px;
1286
- left: 3px;
1287
- width: 20px;
1288
- height: 20px;
1289
- border-radius: 50%;
1290
- background: #fff;
1291
- box-shadow: 0 1px 2px rgba(16, 24, 40, 0.2);
1292
- transition: transform 0.15s ease;
1293
- }
1294
-
1295
- .sheet-toggle-switch-on .sheet-toggle-switch-knob {
1296
- transform: translateX(18px);
1297
- }
1298
-
1299
- /* Accessibility: collapse every interaction/enter animation for
1300
- reduced-motion users; surface layout itself stays static. */
1301
- @media (prefers-reduced-motion: reduce) {
1302
- .mobile-theme-toggle,
1303
- .mobile-back,
1304
- .mobile-row,
1305
- .mobile-button,
1306
- .mobile-new,
1307
- .chat-send,
1308
- .chat-chip,
1309
- .chat-msg-toggle,
1310
- .chat-load-older,
1311
- .chat-disclosure-head,
1312
- .chat-disclosure-caret,
1313
- .chat-msg-pending .chat-msg-text::after,
1314
- .sheet-backdrop,
1315
- .sheet,
1316
- .sheet-option,
1317
- .sheet-confirm-danger,
1318
- .sheet-toggle-switch,
1319
- .sheet-toggle-switch-knob,
1320
- .chat-input,
1321
- .chat-turn-status,
1322
- .chat-turn-dots span {
1323
- animation: none;
1324
- transition: none;
1325
- }
1326
- .chat-turn-status {
1327
- background: none;
1328
- -webkit-text-fill-color: var(--m-accent);
1329
- }
1330
- }
1331
-
1332
- /* ── installed-app pairing ───────────────────────────────────────────── */
1333
-
1334
- .mobile-pair {
1335
- min-height: 100dvh;
1336
- display: grid;
1337
- place-items: center;
1338
- padding: 24px;
1339
- }
1340
-
1341
- .mobile-pairCard {
1342
- display: grid;
1343
- width: min(100%, 420px);
1344
- gap: 12px;
1345
- padding: 24px;
1346
- border: 1px solid var(--m-border);
1347
- border-radius: 12px;
1348
- background: var(--m-bg-raised);
1349
- box-shadow: var(--m-shadow-raise);
1350
- }
1351
-
1352
- .mobile-pairLabel {
1353
- color: var(--m-text-secondary);
1354
- font-size: 13px;
1355
- font-weight: 600;
1356
- }
1357
-
1358
- .mobile-pairInput {
1359
- width: 100%;
1360
- min-height: 42px;
1361
- box-sizing: border-box;
1362
- padding: 9px 12px;
1363
- border: 1px solid var(--m-border);
1364
- border-radius: 8px;
1365
- background: var(--m-bg-input);
1366
- color: var(--m-text);
1367
- font: inherit;
1368
- outline: none;
1369
- }
1370
-
1371
- .mobile-pairInput:focus-visible {
1372
- border-color: var(--m-accent);
1373
- box-shadow: 0 0 0 2px var(--m-bg), 0 0 0 4px var(--m-accent);
1374
- }
1375
-
1376
- .mobile-pairSubmit {
1377
- width: 100%;
1378
- }
1379
-
1380
- /* ── directory browser ─────────────────────────────────────────────── */
1381
-
1382
- .dir-browser {
1383
- display: flex;
1384
- flex-direction: column;
1385
- }
1386
-
1387
- .dir-crumbs {
1388
- display: flex;
1389
- align-items: center;
1390
- overflow-x: auto;
1391
- padding: 12px 16px;
1392
- background: var(--m-bg-raised);
1393
- border-bottom: 1px solid var(--m-border);
1394
- white-space: nowrap;
1395
- }
1396
-
1397
- .dir-crumbs::-webkit-scrollbar {
1398
- display: none;
1399
- }
1400
-
1401
- .dir-crumb {
1402
- border: none;
1403
- background: transparent;
1404
- padding: 4px 6px;
1405
- color: var(--m-text);
1406
- font-size: 14px;
1407
- cursor: pointer;
1408
- }
1409
-
1410
- .dir-crumb:active {
1411
- background: var(--m-bg-input);
1412
- border-radius: 4px;
1413
- }
1414
-
1415
- .dir-crumb-separator {
1416
- color: var(--m-text-tertiary);
1417
- margin: 0 4px;
1418
- font-size: 14px;
1419
- }
1420
-
1421
- .dir-entry {
1422
- padding-left: 16px;
1423
- }
1424
-
1425
- .dir-entry-hidden {
1426
- opacity: 0.5;
1427
- }
1428
-
1429
- .dir-select {
1430
- padding: 16px;
1431
- background: var(--m-bg);
1432
- border-top: 1px solid var(--m-border);
1433
- }
1434
-
1435
- .dir-empty {
1436
- padding: 40px 0;
1437
- }
1438
- `;