@leftoff/cli 0.0.0-stage → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/CHANGELOG.md +564 -0
  3. package/LICENSE.md +9 -0
  4. package/README.md +28 -2
  5. package/assets/sample-transcript.jsonl +12 -0
  6. package/bin/checkpoints.js +7 -0
  7. package/bin/leftoff.js +585 -0
  8. package/hooks/README.md +22 -0
  9. package/hooks/settings-hooks.example.json +82 -0
  10. package/mod/.claude-plugin/plugin.json +15 -0
  11. package/mod/hooks/core.js +1397 -0
  12. package/mod/hooks/hooks.json +4 -0
  13. package/mod/hooks/register.js +1006 -0
  14. package/package.json +45 -4
  15. package/templates/agent-feed-worker/README.md +45 -0
  16. package/templates/agent-feed-worker/src/index.js +69 -0
  17. package/templates/agent-feed-worker/wrangler.toml +20 -0
  18. package/ui/app.css +1282 -0
  19. package/ui/app.js +2979 -0
  20. package/ui/apple-touch-icon.png +0 -0
  21. package/ui/changelog-md.js +64 -0
  22. package/ui/favicon-32.png +0 -0
  23. package/ui/favicon-badge-32.png +0 -0
  24. package/ui/favicon-badge.svg +1 -0
  25. package/ui/favicon.ico +0 -0
  26. package/ui/favicon.svg +1 -0
  27. package/ui/go.js +68 -0
  28. package/ui/icon-192.png +0 -0
  29. package/ui/icon-512.png +0 -0
  30. package/ui/icon-maskable-512.png +0 -0
  31. package/ui/icons.js +41 -0
  32. package/ui/index.html +55 -0
  33. package/ui/manifest.webmanifest +37 -0
  34. package/ui/needs.js +197 -0
  35. package/ui/offline.css +11 -0
  36. package/ui/offline.html +24 -0
  37. package/ui/pair.html +31 -0
  38. package/ui/picker.js +294 -0
  39. package/ui/relay-client.js +187 -0
  40. package/ui/relay-crypto.js +155 -0
  41. package/ui/relay-pair.js +48 -0
  42. package/ui/repos.js +167 -0
  43. package/ui/settings-nav.js +23 -0
  44. package/ui/summary-examples.js +66 -0
  45. package/ui/sw.js +34 -0
  46. package/ui/theme.js +41 -0
  47. package/ui/vendor/LUCIDE-LICENSE.txt +45 -0
package/ui/app.css ADDED
@@ -0,0 +1,1282 @@
1
+ :root, [data-theme="dark"] {
2
+ color-scheme: dark;
3
+ --bg: #0d1016;
4
+ --bg2: #121620;
5
+ --card: #161b26;
6
+ --card2: #1b2130;
7
+ --card-end: #141925;
8
+ --line: #252d3d;
9
+ --line-strong: #3a4560;
10
+ --text: #e6e9f0;
11
+ --text2: #cfd5e2;
12
+ --muted: #8b93a7;
13
+ --faint: #5c6478;
14
+ --accent: #7c9cff;
15
+ --on-accent: #0b0f1a;
16
+ --green: #4fd1a0;
17
+ --yellow: #f2c45a;
18
+ --cyan: #5cc8e8;
19
+ --red: #ff6b7a;
20
+ --gray: #7d8597;
21
+ --you: #ffc2c8;
22
+ --tint-green: rgba(79,209,160,.1);
23
+ --tint-yellow: rgba(242,196,90,.1);
24
+ --tint-cyan: rgba(92,200,232,.1);
25
+ --tint-red: rgba(255,107,122,.12);
26
+ --tint-accent: rgba(124,156,255,.1);
27
+ --tint-gray: rgba(125,133,151,.12);
28
+ --machine: #b9c6ff;
29
+ --machine-remote: #f0cf8a;
30
+ --header-bg: rgba(13,16,22,.86);
31
+ --subtle: rgba(255,255,255,.02);
32
+ --field: #0d1016;
33
+ --focus: rgba(124,156,255,.35);
34
+ --card-shadow: none;
35
+ --toast-shadow: 0 10px 30px rgba(0,0,0,.4);
36
+ --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%238b93a7' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
37
+ --radius: 14px;
38
+ --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
39
+ }
40
+ /* Light: a paper-white page with cool-gray structure, not an inverted dark.
41
+ Status colors are deepened so text on their tints passes contrast. */
42
+ [data-theme="light"] {
43
+ color-scheme: light;
44
+ --bg: #f5f6f9;
45
+ --bg2: #eceef3;
46
+ --card: #ffffff;
47
+ --card2: #f1f3f8;
48
+ --card-end: #fbfcfe;
49
+ --line: #e1e5ed;
50
+ --line-strong: #c7cedb;
51
+ --text: #161a24;
52
+ --text2: #343b4c;
53
+ --muted: #5b6478;
54
+ --faint: #8790a3;
55
+ --accent: #4560e6;
56
+ --on-accent: #ffffff;
57
+ --green: #0f8a63;
58
+ --yellow: #a86a0c;
59
+ --cyan: #0b7ea3;
60
+ --red: #d2364c;
61
+ --gray: #687185;
62
+ --you: #b4233a;
63
+ --tint-green: rgba(15,138,99,.1);
64
+ --tint-yellow: rgba(214,150,30,.14);
65
+ --tint-cyan: rgba(11,126,163,.1);
66
+ --tint-red: rgba(210,54,76,.1);
67
+ --tint-accent: rgba(69,96,230,.1);
68
+ --tint-gray: rgba(104,113,133,.12);
69
+ --machine: #3a52c9;
70
+ --machine-remote: #8a5a08;
71
+ --header-bg: rgba(255,255,255,.86);
72
+ --subtle: #f8f9fc;
73
+ --field: #ffffff;
74
+ --focus: rgba(69,96,230,.25);
75
+ --card-shadow: 0 1px 2px rgba(22,26,36,.04), 0 2px 8px rgba(22,26,36,.04);
76
+ --toast-shadow: 0 10px 30px rgba(22,26,36,.16);
77
+ --chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%235b6478' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
78
+ }
79
+ * { box-sizing: border-box; }
80
+ html, body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
81
+ a { color: inherit; text-decoration: none; }
82
+ button { font: inherit; color: inherit; }
83
+ code, .mono { font-family: var(--mono); font-size: 12.5px; }
84
+
85
+ /* header */
86
+ .brand { display: flex; align-items: center; gap: 9px; font-weight: 650; font-size: 15.5px; letter-spacing: .1px; }
87
+ .logo { width: 22px; height: 22px; color: var(--accent); }
88
+
89
+ main { max-width: 1320px; margin: 0 auto; padding: 26px 28px 80px; }
90
+ h1 { font-size: 22px; margin: 0; font-weight: 650; letter-spacing: -.2px; }
91
+ h2 { font-size: 13px; text-transform: uppercase; letter-spacing: .9px; color: var(--muted); font-weight: 600; margin: 30px 0 12px; display: flex; align-items: center; gap: 10px; }
92
+ h2 .count { color: var(--faint); font-weight: 500; }
93
+ .pagehead { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 6px; }
94
+ .pagehead .sub { color: var(--muted); }
95
+ .pagehead .actions { margin-left: auto; display: flex; gap: 8px; }
96
+
97
+ /* summary strip */
98
+ .stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin: 18px 0 4px; }
99
+ .stat { background: var(--card); box-shadow: var(--card-shadow); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; text-align: left; cursor: pointer; font: inherit; color: inherit; transition: border-color .15s, background .15s; }
100
+ .stat:hover { border-color: var(--line-strong); }
101
+ .stat.on { border-color: var(--accent); background: var(--card2); }
102
+ .stat .n { font-size: 22px; font-weight: 650; }
103
+ .stat .k { color: var(--muted); font-size: 12px; display: flex; align-items: center; gap: 6px; }
104
+
105
+ /* cards */
106
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); gap: 14px; align-items: start; }
107
+ .card { background: linear-gradient(180deg, var(--card) 0%, var(--card-end) 100%); box-shadow: var(--card-shadow); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 16px 12px; display: flex; flex-direction: column; gap: 10px; position: relative; transition: border-color .15s, transform .15s; }
108
+ .card:hover { border-color: var(--line-strong); }
109
+ .card.needs_input { border-color: color-mix(in srgb, var(--red) 45%, transparent); box-shadow: 0 0 0 1px var(--tint-red) inset, var(--card-shadow); }
110
+ .card .row1 { display: flex; align-items: flex-start; gap: 10px; }
111
+ .card .title { font-size: 15px; font-weight: 600; line-height: 1.35; flex: 1; }
112
+ .card .title a:hover { text-decoration: underline; text-decoration-color: var(--faint); }
113
+ .card .title input { width: 100%; background: var(--bg); border: 1px solid var(--accent); border-radius: 6px; color: var(--text); padding: 3px 6px; font: inherit; }
114
+ .mt { margin-top: 20px; }
115
+ .icon { background: none; border: 0; color: var(--faint); cursor: pointer; padding: 0 4px; margin-left: 4px; font-size: 13px; opacity: 0; transition: opacity .15s; }
116
+ .card:hover .icon { opacity: 1; }
117
+ .icon:hover { color: var(--text); }
118
+ .card .pin { color: var(--yellow); font-size: 13px; }
119
+ .meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; color: var(--muted); font-size: 12.5px; }
120
+ .chip { display: inline-flex; align-items: center; gap: 5px; background: var(--bg2); border: 1px solid var(--line); border-radius: 999px; padding: 1px 9px; font-size: 12px; color: var(--muted); }
121
+ .chip.mono { font-family: var(--mono); font-size: 11.5px; }
122
+ .pill { display: inline-flex; align-items: center; gap: 6px; border-radius: 999px; padding: 2px 9px 2px 8px; font-size: 11.5px; font-weight: 600; letter-spacing: .2px; white-space: nowrap; }
123
+ .pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
124
+ .s-active { color: var(--green); background: var(--tint-green); }
125
+ .s-waiting { color: var(--yellow); background: var(--tint-yellow); }
126
+ .s-background { color: var(--cyan); background: var(--tint-cyan); }
127
+ .s-needs_input { color: var(--red); background: var(--tint-red); }
128
+ .s-dormant { color: var(--accent); background: var(--tint-accent); }
129
+ .s-stale, .s-ended { color: var(--gray); background: var(--tint-gray); }
130
+ .s-active::before { animation: pulse 1.6s ease-in-out infinite; }
131
+ @keyframes pulse { 50% { opacity: .35; } }
132
+
133
+ .cp { background: var(--subtle); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; display: grid; grid-template-columns: 78px 1fr; gap: 3px 10px; font-size: 13px; }
134
+ .cp dt { color: var(--faint); font-size: 11.5px; text-transform: uppercase; letter-spacing: .6px; padding-top: 2px; }
135
+ .cp dd { margin: 0; color: var(--text2); }
136
+ .cp dd.next { color: var(--text); font-weight: 500; }
137
+ .cp dd.you { color: var(--you); }
138
+ .cp .when { grid-column: 1 / -1; color: var(--faint); font-size: 11.5px; margin-top: 3px; }
139
+ .nocp { color: var(--faint); font-size: 13px; font-style: italic; padding: 4px 0; }
140
+
141
+ .actions-row { display: flex; gap: 6px; flex-wrap: wrap; margin-top: auto; padding-top: 2px; }
142
+ .btn { background: var(--bg2); border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px; font-size: 12.5px; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
143
+ .btn:hover { color: var(--text); border-color: var(--line-strong); }
144
+ .btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
145
+ .btn.primary:hover { filter: brightness(1.08); color: var(--on-accent); }
146
+ .btn:disabled { opacity: .55; cursor: progress; }
147
+
148
+ .empty { border: 1px dashed var(--line); border-radius: var(--radius); padding: 38px; text-align: center; color: var(--muted); }
149
+ .empty code { background: var(--bg2); padding: 2px 6px; border-radius: 6px; }
150
+
151
+ /* session view */
152
+ .back { color: var(--muted); font-size: 13px; display: inline-block; margin-bottom: 12px; }
153
+ .back:hover { color: var(--text); }
154
+ .facts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 18px 0; }
155
+ .fact { background: var(--card); box-shadow: var(--card-shadow); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; min-width: 0; }
156
+ .fact .k { color: var(--faint); font-size: 11.5px; text-transform: uppercase; letter-spacing: .6px; }
157
+ .fact .v { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
158
+ .strip { display: flex; gap: 3px; margin: 8px 0 4px; flex-wrap: wrap; }
159
+ .strip span { font-size: 11px; padding: 2px 8px; border-radius: 6px; }
160
+ .timeline { position: relative; margin-left: 8px; padding-left: 22px; border-left: 2px solid var(--line); }
161
+ .tl-item { position: relative; margin-bottom: 16px; }
162
+ .tl-item::before { content: ""; position: absolute; left: -29px; top: 14px; width: 12px; height: 12px; border-radius: 50%; background: var(--bg); border: 2px solid var(--accent); }
163
+ .tl-item.manual::before { border-color: var(--green); }
164
+ .tl-item.session_end::before, .tl-item.clear::before { border-color: var(--gray); }
165
+ .tl-head { display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 12.5px; margin-bottom: 6px; }
166
+ .tl-head .t { color: var(--text); font-weight: 600; }
167
+ .trig { font-size: 11px; padding: 1px 8px; border-radius: 6px; background: var(--card2); color: var(--muted); border: 1px solid var(--line); }
168
+ .files { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
169
+ .note { color: var(--yellow); font-size: 12.5px; margin-top: 6px; }
170
+ .tl-title { color: var(--text); font-weight: 600; }
171
+
172
+ /* digest */
173
+ .digest-wrap { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 22px; margin-top: 18px; }
174
+ .dates { display: flex; flex-direction: column; gap: 4px; }
175
+ .dates a { padding: 7px 12px; border-radius: 8px; color: var(--muted); font-family: var(--mono); font-size: 12.5px; }
176
+ .dates a.on, .dates a:hover { background: var(--card2); color: var(--text); }
177
+ .md { background: var(--card); box-shadow: var(--card-shadow); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px 28px; max-width: 860px; }
178
+ .md h1 { font-size: 21px; margin-bottom: 4px; }
179
+ .md h2 { margin: 22px 0 8px; }
180
+ .md ul { margin: 0; padding-left: 18px; }
181
+ .md li { margin: 9px 0; color: var(--text2); }
182
+ .md li .sub { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }
183
+ .md p { color: var(--text2); }
184
+ .md strong { color: var(--text); }
185
+ .md code { background: var(--bg2); padding: 1px 5px; border-radius: 5px; }
186
+
187
+ /* settings */
188
+ .form { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; max-width: 640px; display: grid; grid-template-columns: 200px 1fr; gap: 14px 18px; align-items: center; margin-top: 18px; }
189
+ .form label { color: var(--muted); }
190
+ /* Inputs and selects share one box: same height, padding, border and focus
191
+ ring. Selects drop the native arrow for a chevron inset like the time
192
+ input's clock icon, so the right edges line up. */
193
+ .form input { background: var(--field); border: 1px solid var(--line); color: var(--text); border-radius: 8px; height: 36px; padding: 0 12px; font: inherit; width: 100%; line-height: 34px; transition: border-color .15s, box-shadow .15s; }
194
+ .form input::placeholder { color: var(--faint); }
195
+ .form input:hover { border-color: var(--line-strong); }
196
+ .form input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
197
+ .form input[type=time]::-webkit-calendar-picker-indicator { opacity: .6; cursor: pointer; margin-right: -2px; }
198
+ .form input[type=time]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
199
+ .form .hint { grid-column: 2; color: var(--faint); font-size: 12px; margin-top: -8px; }
200
+ .form .full { grid-column: 1 / -1; display: flex; gap: 8px; justify-content: flex-end; }
201
+ .form .section { grid-column: 1 / -1; color: var(--faint); font-size: 11.5px; text-transform: uppercase; letter-spacing: .8px; font-weight: 600; padding-top: 6px; border-top: 1px solid var(--line); margin-top: 4px; }
202
+ .form .section:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
203
+ .form .keyrow { display: flex; gap: 8px; align-items: center; }
204
+ .form .keyrow input { flex: 1; }
205
+ .keystate { font-size: 12px; white-space: nowrap; }
206
+ .keystate.ok { color: var(--green); }
207
+ .keystate.no { color: var(--yellow); }
208
+ .form [hidden] { display: none !important; }
209
+
210
+ .toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--card2); border: 1px solid var(--line-strong); color: var(--text); padding: 10px 16px; border-radius: 10px; opacity: 0; transition: opacity .2s, transform .2s; pointer-events: none; font-size: 13px; box-shadow: var(--toast-shadow); }
211
+ .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
212
+
213
+ @media (max-width: 900px) {
214
+ main { padding: 18px 16px 60px; }
215
+ .stats { grid-template-columns: repeat(2, 1fr); }
216
+ .pagehead { flex-wrap: wrap; }
217
+ .pagehead .actions { margin-left: 0; }
218
+ .facts { grid-template-columns: repeat(2, 1fr); }
219
+ .digest-wrap { grid-template-columns: minmax(0, 1fr); }
220
+ .grid { grid-template-columns: 1fr; }
221
+ }
222
+
223
+ .chip.machine { color: var(--machine); border-color: color-mix(in srgb, var(--accent) 35%, transparent); background: var(--tint-accent); }
224
+ .chip.machine.remote { color: var(--machine-remote); border-color: color-mix(in srgb, var(--yellow) 35%, transparent); background: var(--tint-yellow); }
225
+ .ro { color: var(--faint); font-size: 12px; align-self: center; margin-left: 4px; }
226
+ .dates a .m { color: var(--faint); font-size: 11px; margin-left: 6px; }
227
+ .cp code { background: var(--bg); border: 1px solid var(--line); padding: 0 5px; border-radius: 5px; font-size: 11.5px; }
228
+ .striplabel { color: var(--faint); font-size: 11.5px; text-transform: uppercase; letter-spacing: .6px; margin-top: 4px; }
229
+
230
+ /* theme switch: three icon segments in the header */
231
+ .theme { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg2); border: 1px solid var(--line); border-radius: 9px; flex: none; }
232
+ .theme button { display: grid; place-items: center; width: 28px; height: 24px; border: 0; border-radius: 7px; background: none; color: var(--faint); cursor: pointer; padding: 0; }
233
+ .theme button:hover { color: var(--text); }
234
+ .theme button[aria-pressed="true"] { background: var(--card); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 0 0 1px var(--line); }
235
+ .theme svg { width: 15px; height: 15px; }
236
+ .theme button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
237
+ .form .theme { justify-self: start; }
238
+ .form .theme button { width: auto; height: 28px; padding: 0 10px; gap: 6px; display: inline-flex; align-items: center; font-size: 12.5px; }
239
+
240
+ /* notices above the board */
241
+ .banner { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 16px; padding: 11px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--card); color: var(--text2); font-size: 13px; box-shadow: var(--card-shadow); }
242
+ .banner b { color: var(--text); font-weight: 600; }
243
+ .banner code { font-family: var(--mono); font-size: 12px; background: var(--bg2); border: 1px solid var(--line); border-radius: 6px; padding: 1px 6px; }
244
+ .banner.warn { border-color: color-mix(in srgb, var(--yellow) 40%, transparent); background: var(--tint-yellow); }
245
+ .banner.info { border-color: color-mix(in srgb, var(--accent) 40%, transparent); background: var(--tint-accent); }
246
+ .banner .grow { flex: 1; }
247
+ .banner .btn { padding: 4px 10px; font-size: 12.5px; }
248
+
249
+ /* version badge + What's new */
250
+ .tabs a { position: relative; }
251
+ .wn { display: grid; gap: 14px; margin-top: 16px; max-width: 820px; }
252
+ .wn-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 20px 10px; box-shadow: var(--card-shadow); }
253
+ .wn-card.is-new { border-color: color-mix(in srgb, var(--accent) 45%, transparent); box-shadow: 0 0 0 1px var(--tint-accent) inset, var(--card-shadow); }
254
+ .wn-card.coming { border-style: dashed; }
255
+ .wn-card header { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
256
+ .wn-ver { font: 700 17px/1.2 var(--mono); color: var(--text); }
257
+ .wn-date { color: var(--faint); font-size: 12.5px; }
258
+ .pill.new { color: var(--on-accent); background: var(--accent); }
259
+ .pill.here { color: var(--muted); background: var(--tint-gray); }
260
+ .pill.soon { color: var(--accent); background: var(--tint-accent); }
261
+ .wn-sec { margin: 12px 0 4px; font-size: 11.5px; text-transform: uppercase; letter-spacing: .8px; color: var(--faint); font-weight: 600; }
262
+ .wn-sec.s-added { color: var(--green); }
263
+ .wn-sec.s-changed { color: var(--yellow); }
264
+ .wn-sec.s-fixed { color: var(--cyan); }
265
+ .wn-card ul { margin: 0 0 6px; padding-left: 18px; }
266
+ .wn-card li { margin: 5px 0; color: var(--text2); line-height: 1.55; }
267
+ .wn-card li > ul { margin: 2px 0 0; padding-left: 16px; }
268
+ .wn-card li li { margin: 3px 0; font-size: .94em; }
269
+ .wn-card a { overflow-wrap: anywhere; }
270
+ .wn-card code, .form code, .hint code { font-family: var(--mono); font-size: 12px; background: var(--bg2); border: 1px solid var(--line); border-radius: 5px; padding: 0 5px; }
271
+ .wn-card a { color: var(--accent); }
272
+ .banner ul.incoming { margin: 6px 0 0; padding-left: 18px; color: var(--text2); }
273
+ .banner ul.incoming li { margin: 2px 0; }
274
+ .banner code.cmd { font-size: 12.5px; padding: 4px 8px; }
275
+ .btn.x { padding: 4px 8px; line-height: 1; }
276
+ .form label.check { display: flex; gap: 8px; align-items: center; color: var(--text2); }
277
+ .form label.check input { width: auto; height: auto; }
278
+ .wn + .banner { margin-top: 14px; }
279
+ .form .hint a { color: var(--accent); text-decoration: none; }
280
+ .form .hint a:hover { text-decoration: underline; }
281
+
282
+ /* Settings → Remote access, and the remote sign-in screen */
283
+ .form .remote-urls { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; }
284
+ .form .remote-urls .chip { color: var(--text2); }
285
+ .form .hint code, .empty.login code { font-family: var(--mono); font-size: 11.5px; background: var(--bg2); border: 1px solid var(--line); border-radius: 6px; padding: 1px 5px; color: var(--text2); }
286
+ .form .remote-actions { justify-content: flex-start; flex-wrap: wrap; grid-column: 2; }
287
+ .form .remote-link { grid-column: 2; flex-direction: column; align-items: flex-start; gap: 4px; margin-top: -6px; font-size: 12px; }
288
+ .form .remote-link code.link { font-family: var(--mono); font-size: 11.5px; color: var(--text2); background: var(--bg2); border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; overflow-wrap: anywhere; user-select: all; width: 100%; }
289
+ .form .remote-link .faint { color: var(--faint); }
290
+ .btn.sm { padding: 2px 9px; font-size: 12px; }
291
+ .empty.login { max-width: 520px; margin: 40px auto; }
292
+ .empty.login .login-title { font-size: 17px; font-weight: 600; color: var(--text); margin-bottom: 10px; }
293
+ .empty.login p { margin: 8px 0; }
294
+ .empty.login .warn { color: var(--yellow); }
295
+ @media (max-width: 640px) { .form { grid-template-columns: 1fr; } .form .hint, .form .remote-actions, .form .remote-link { grid-column: 1; } .form .hint { margin-top: -10px; } }
296
+
297
+ /* v0.4: open/closed dot and Go */
298
+ .live { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin: 0 8px 1px 0; vertical-align: middle; flex: none; background: var(--faint); box-shadow: 0 0 0 3px var(--tint-gray); }
299
+ .live.open { background: var(--green); box-shadow: 0 0 0 3px var(--tint-green); }
300
+ .live.closed { background: transparent; border: 1.5px solid var(--gray); box-shadow: none; width: 8px; height: 8px; }
301
+ .live.unknown { opacity: .6; }
302
+ .livenote.open { color: var(--green); font-weight: 600; }
303
+ .livenote.closed { color: var(--gray); }
304
+ .card.is-closed .title a { color: var(--muted); }
305
+ .btn.go { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); font-weight: 600; }
306
+ .btn.go:hover { background: var(--tint-accent); color: var(--accent); border-color: var(--accent); }
307
+ .btn.go:disabled { color: var(--faint); border-color: var(--line); background: var(--bg2); font-weight: 500; cursor: not-allowed; opacity: .7; }
308
+
309
+ /* Go feedback (v0.4.1) */
310
+ .btn.go.busy { opacity: 1; cursor: progress; border-style: dashed; }
311
+ .btn.go.done { opacity: 1; color: var(--green, #2fbf71); border-color: currentColor; }
312
+ .btn.go.failed { opacity: 1; color: var(--red, #e5484d); border-color: currentColor; }
313
+
314
+ /* repo chips (v0.4.2): one row under the stats; scrolls sideways on a phone */
315
+ .repos { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; position: relative; min-width: 0; }
316
+ .repos .track { display: flex; gap: 6px; overflow-x: auto; flex-wrap: nowrap; min-width: 0; flex: 0 1 auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding: 2px 1px; mask-image: linear-gradient(to right, #000 calc(100% - 18px), transparent); }
317
+ .repos .track::-webkit-scrollbar { display: none; }
318
+ .rchip { flex: none; display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; background: var(--card); border: 1px solid var(--line); border-radius: 999px; padding: 4px 6px 4px 11px; font: 500 12.5px/1.3 var(--mono); color: var(--text2); cursor: pointer; box-shadow: var(--card-shadow); transition: border-color .15s, background .15s, color .15s; list-style: none; user-select: none; }
319
+ .rchip.all { font-family: inherit; }
320
+ .rchip:hover { border-color: var(--line-strong); color: var(--text); }
321
+ .rchip.on { border-color: var(--accent); background: var(--tint-accent); color: var(--text); }
322
+ .rchip .rc { min-width: 20px; text-align: center; font: 600 11px/1 var(--mono); color: var(--muted); background: var(--bg2); border-radius: 999px; padding: 3px 6px; }
323
+ .rchip.on .rc { color: var(--on-accent); background: var(--accent); }
324
+ .rchip.zero:not(.on) { color: var(--faint); }
325
+ .rchip:focus-visible, .repomore summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
326
+ .repomore { flex: none; position: relative; }
327
+ .repomore summary { font-family: inherit; }
328
+ .repomore summary::-webkit-details-marker { display: none; }
329
+ .repomore[open] summary { border-color: var(--line-strong); }
330
+ .repomore .menu { position: absolute; z-index: 6; top: calc(100% + 6px); right: 0; width: min(300px, calc(100vw - 32px)); background: var(--card); border: 1px solid var(--line-strong); border-radius: 12px; box-shadow: var(--toast-shadow); padding: 8px; }
331
+ .repomore .morefilter { width: 100%; background: var(--field); border: 1px solid var(--line); border-radius: 8px; padding: 7px 9px; color: var(--text); font: inherit; outline: none; }
332
+ .repomore .morefilter:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
333
+ .repomore .opts { max-height: 280px; overflow-y: auto; margin-top: 6px; display: grid; gap: 2px; }
334
+ .repomore .opt { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; text-align: left; background: none; border: 0; border-radius: 7px; padding: 6px 8px; font: 12.5px/1.3 var(--mono); color: var(--text2); cursor: pointer; }
335
+ .repomore .opt:hover { background: var(--bg2); color: var(--text); }
336
+ .repomore .opt.on { background: var(--tint-accent); color: var(--text); }
337
+ .repomore .opt .rc { color: var(--faint); font-size: 11px; }
338
+ .repomore .opt[hidden] { display: none; }
339
+ .chip.repo-link { cursor: pointer; font: inherit; font-family: var(--mono); font-size: 11.5px; }
340
+ .chip.repo-link:hover { color: var(--text); border-color: var(--line-strong); }
341
+ .linkish { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; }
342
+ .linkish:hover { text-decoration: underline; }
343
+ .digest-repos { margin: 0 0 14px; }
344
+ .md li[hidden], .md ul[hidden], .md h2[hidden] { display: none; }
345
+
346
+ @media (max-width: 640px) {
347
+ main { padding: 16px 14px 60px; }
348
+ .stats { gap: 8px; }
349
+ .pagehead .actions { flex-wrap: wrap; }
350
+ }
351
+ .digest-meta { color: var(--faint); font-size: 12.5px; margin: -2px 0 12px; }
352
+ @media (max-width: 640px) {
353
+ /* the five status counts as one compact row that scrolls, not a 3-row grid */
354
+ .stats { display: flex; overflow-x: auto; scrollbar-width: none; gap: 8px; margin: 14px -14px 0; padding: 2px 14px; }
355
+ .stats::-webkit-scrollbar { display: none; }
356
+ .stat { flex: none; min-width: 104px; padding: 8px 12px; border-radius: 10px; }
357
+ .stat .n { font-size: 18px; line-height: 1.2; }
358
+ }
359
+
360
+ /* Settings → Digest (0.4.3) */
361
+ .timerow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
362
+ .timerow .zone { color: var(--muted); font-size: 12.5px; }
363
+ .hint.warnish { color: var(--yellow); }
364
+ .days { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
365
+ .days .day { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: var(--field); color: var(--muted); font-weight: 600; font-size: 12.5px; cursor: pointer; padding: 0; }
366
+ .days .day[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
367
+ .days .day:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
368
+ .days .presets { margin-left: 6px; color: var(--faint); font-size: 12.5px; }
369
+
370
+ /* the whole card opens the session (0.4.3) */
371
+ .card[data-href] { cursor: pointer; }
372
+ .card[data-href]:hover { border-color: var(--line-strong); transform: translateY(-1px); }
373
+ .card:focus-within { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
374
+ .card .cplink { align-self: flex-start; color: var(--accent); font-size: 12.5px; font-weight: 500; margin-top: -4px; }
375
+ .card .cplink:hover, .card .cplink:focus-visible { text-decoration: underline; }
376
+ .card .cplink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
377
+ .card dl, .card .meta, .card .nocp { cursor: pointer; }
378
+
379
+ /* nav and button icons (0.4.3, Lucide) */
380
+ .ic { width: 15px; height: 15px; flex: none; }
381
+ .tabs a { display: inline-flex; align-items: center; gap: 7px; }
382
+ .tabs a .ic { opacity: .85; }
383
+ .tabs a.on .ic { opacity: 1; color: var(--accent); }
384
+ .tabs .lbl-short { display: none; }
385
+ .btn { display: inline-flex; align-items: center; gap: 7px; }
386
+ .btn .ic { width: 14px; height: 14px; }
387
+ @media (max-width: 640px) {
388
+ /* phone: five equal tabs, icon over a short label, never wrapping or scrolling */
389
+ }
390
+
391
+ /* Settings → model cards (0.4.3) */
392
+ .models { display: grid; gap: 8px; }
393
+ .mcard { display: flex; align-items: flex-start; gap: 12px; padding: 11px 13px; border: 1px solid var(--line); border-radius: 12px; background: var(--field); cursor: pointer; transition: border-color .15s, background .15s; }
394
+ .mcard:hover { border-color: var(--line-strong); }
395
+ .mcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
396
+ .mcard.on { border-color: var(--accent); background: var(--tint-accent); }
397
+ .mcard .dot { flex: none; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line-strong); margin-top: 2px; }
398
+ .mcard.on .dot { border-color: var(--accent); background: radial-gradient(var(--accent) 0 4px, transparent 5px); }
399
+ .mcard .mmain { flex: 1; min-width: 0; display: grid; gap: 2px; }
400
+ .mcard .mname { font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
401
+ .mcard .mnote { color: var(--text2); font-size: 13px; }
402
+ .mcard .mhint { color: var(--faint); font-size: 12px; font-family: var(--mono); }
403
+ .mcard .mside { flex: none; align-self: center; }
404
+ .mcard.needs-dl:not(.on) .mname { color: var(--text2); }
405
+ .badge { display: inline-flex; align-items: center; gap: 4px; font: 600 11px/1 inherit; padding: 4px 8px; border-radius: 999px; background: var(--bg2); color: var(--muted); border: 1px solid var(--line); white-space: nowrap; }
406
+ .badge.ok { color: var(--green); background: var(--tint-green); border-color: transparent; }
407
+ .badge.acc { color: var(--accent); background: var(--tint-accent); border-color: transparent; }
408
+ .btn.small { padding: 5px 10px; font-size: 12.5px; }
409
+ .pull { margin-top: 6px; display: grid; gap: 5px; }
410
+ .pull.err { color: var(--red); font-size: 12.5px; }
411
+ .pbar { height: 6px; border-radius: 999px; background: var(--bg2); overflow: hidden; border: 1px solid var(--line); }
412
+ .pbar i { display: block; height: 100%; background: var(--accent); transition: width .3s; }
413
+ .ptext { color: var(--muted); font-size: 12px; font-family: var(--mono); }
414
+ .mstatus { font-size: 12.5px; padding: 8px 11px; border-radius: 10px; }
415
+ .mstatus.ok { color: var(--green); background: var(--tint-green); }
416
+ .mstatus.warn { color: var(--yellow); background: var(--tint-yellow); }
417
+ .models details.other summary { cursor: pointer; color: var(--muted); font-size: 12.5px; padding: 4px 0; }
418
+ .models details.other input { width: 100%; margin-top: 6px; }
419
+ .models details.other .hint { display: block; margin-top: 4px; color: var(--faint); font-size: 12px; }
420
+ @media (max-width: 640px) { .mcard { flex-wrap: wrap; } .mcard .mside { width: 100%; padding-left: 28px; } }
421
+
422
+ /* timeline filter bar (0.4.3) */
423
+ .tlbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
424
+ .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
425
+ .pillx { display: inline-flex; align-items: center; gap: 6px; border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); background: var(--tint-accent); color: var(--text); border-radius: 999px; padding: 4px 11px; font-size: 12.5px; cursor: pointer; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
426
+ .pillx:hover { border-color: var(--accent); }
427
+ .seg { display: inline-flex; padding: 2px; gap: 2px; background: var(--bg2); border: 1px solid var(--line); border-radius: 9px; margin-left: auto; }
428
+ .seg button { border: 0; background: none; color: var(--muted); padding: 4px 10px; border-radius: 7px; font-size: 12.5px; cursor: pointer; }
429
+ .seg button[aria-pressed="true"] { background: var(--card); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 0 0 1px var(--line); }
430
+ @media (max-width: 640px) { .seg { margin-left: 0; } .tlbar lo-select { max-width: 100%; } }
431
+ .form { max-width: 760px; }
432
+ .timerow input { width: auto; flex: none; }
433
+ .form label[data-row="model"] { align-self: start; padding-top: 10px; }
434
+
435
+ /* Needs you (0.4.4): nav tab + count, the strip, card badge, answer controls */
436
+ .tabs a#needsTab { position: relative; }
437
+ .navcount { min-width: 17px; height: 17px; padding: 0 5px; border-radius: 9px; background: var(--red); color: #fff; font-size: 11px; font-weight: 700; line-height: 17px; text-align: center; }
438
+ .tabs a#needsTab.has-needs .ic { color: var(--red); opacity: 1; }
439
+ .needs-strip { margin: 4px 0 18px; border: 1px solid color-mix(in srgb, var(--red) 40%, var(--line)); background: linear-gradient(180deg, var(--tint-red), transparent 70%), var(--card); border-radius: var(--radius); padding: 12px 14px 14px; }
440
+ .needs-strip.one { margin-top: 16px; }
441
+ .needs-strip.quiet { border-color: var(--line); background: var(--card); }
442
+ .needs-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
443
+ .needs-head h2 { margin: 0; font-size: 15px; color: var(--red); }
444
+ .needs-strip.quiet .needs-head h2 { color: var(--text); }
445
+ .needs-head .count { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 10px; background: var(--red); color: #fff; font-size: 12px; text-align: center; margin-left: 4px; }
446
+ .needs-head .sub { color: var(--muted); font-size: 12.5px; }
447
+ .needs-list { display: grid; gap: 10px; }
448
+ .need { border: 1px solid var(--line); border-radius: 12px; background: var(--card); padding: 10px 12px; display: grid; gap: 8px; min-width: 0; }
449
+ .need.blocking { border-color: color-mix(in srgb, var(--red) 45%, var(--line)); }
450
+ .need.k-reply { border-style: dashed; }
451
+ .need-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; }
452
+ .need-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--yellow); flex: none; }
453
+ .need.blocking .need-dot { background: var(--red); box-shadow: 0 0 0 3px var(--tint-red); animation: needpulse 2s ease-in-out infinite; }
454
+ @keyframes needpulse { 50% { box-shadow: 0 0 0 6px transparent; } }
455
+ @media (prefers-reduced-motion: reduce) { .need.blocking .need-dot { animation: none; } }
456
+ .need-title { font-weight: 600; color: var(--text); }
457
+ .need-title:hover { text-decoration: underline; }
458
+ .need-kind { color: var(--red); font-weight: 600; font-size: 12px; }
459
+ .need.k-reply .need-kind { color: var(--yellow); }
460
+ .need-wait { margin-left: auto; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
461
+ .need-what { display: flex; gap: 8px; align-items: baseline; min-width: 0; flex-wrap: wrap; }
462
+ .need-what .verb { font-weight: 600; font-size: 13px; color: var(--text2); flex: none; }
463
+ .need-what code { font-family: var(--mono); font-size: 12.5px; background: var(--field); border: 1px solid var(--line); border-radius: 6px; padding: 3px 7px; white-space: pre-wrap; word-break: break-word; min-width: 0; max-height: 9em; overflow: auto; }
464
+ .need-note { color: var(--muted); font-size: 12.5px; }
465
+ .need-note.warn { color: var(--yellow); }
466
+ .need-note.ok { color: var(--green); }
467
+ .need-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
468
+ .btn.allow { background: var(--green); border-color: var(--green); color: var(--on-accent); font-weight: 600; }
469
+ [data-theme="light"] .btn.allow { color: #fff; }
470
+ .btn.allow:hover { filter: brightness(1.08); }
471
+ .btn.deny { color: var(--red); border-color: color-mix(in srgb, var(--red) 40%, var(--line)); }
472
+ .btn.deny:hover { background: var(--tint-red); }
473
+ .btn[disabled] { opacity: .5; cursor: not-allowed; }
474
+ .deny-form { display: flex; gap: 6px; flex-wrap: wrap; }
475
+ .deny-form[hidden] { display: none; }
476
+ .deny-form input, .need .qother, .reply-text { flex: 1 1 220px; min-width: 0; background: var(--field); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 7px 9px; font: inherit; font-size: 13px; }
477
+ .deny-form input:focus, .need .qother:focus, .reply-text:focus { outline: 2px solid var(--focus); border-color: var(--accent); }
478
+ .need-q { display: grid; gap: 6px; }
479
+ .need-q .qtext { font-size: 13.5px; font-weight: 500; }
480
+ .need-q .qhead { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-right: 8px; }
481
+ .need-q .opts { display: flex; gap: 6px; flex-wrap: wrap; }
482
+ .btn.opt { flex-direction: column; align-items: flex-start; gap: 1px; text-align: left; }
483
+ .btn.opt small { color: var(--muted); font-size: 11.5px; font-weight: 400; }
484
+ .btn.opt[aria-pressed="true"] { border-color: var(--accent); background: var(--tint-accent); }
485
+ .need-question { margin: 0; padding: 6px 10px; border-left: 3px solid var(--yellow); background: var(--subtle); color: var(--text2); font-size: 13.5px; white-space: pre-wrap; }
486
+ .reply-row { display: flex; gap: 6px; align-items: flex-end; flex-wrap: wrap; }
487
+ .reply-text { resize: vertical; min-height: 38px; }
488
+ .need-badge { display: flex; gap: 8px; align-items: baseline; font-size: 12.5px; padding: 6px 9px; border-radius: 8px; background: var(--tint-yellow); min-width: 0; }
489
+ .need-badge.blocking { background: var(--tint-red); }
490
+ .need-badge .nb-k { font-weight: 700; color: var(--yellow); flex: none; }
491
+ .need-badge.blocking .nb-k { color: var(--red); }
492
+ .need-badge .nb-t { color: var(--text2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; font-family: var(--mono); font-size: 12px; }
493
+ .need-badge .nb-w { margin-left: auto; color: var(--muted); flex: none; }
494
+ .card.needs-you { border-color: color-mix(in srgb, var(--red) 55%, transparent); }
495
+ .recent { margin-top: 18px; }
496
+ .recent summary { cursor: pointer; font-weight: 600; font-size: 14px; }
497
+ .answered, .recent ul { list-style: none; padding: 0; margin: 8px 0; display: grid; gap: 6px; }
498
+ .answered li, .recent li { display: flex; gap: 8px; flex-wrap: wrap; align-items: baseline; font-size: 13px; padding: 7px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); }
499
+ .answered .t, .recent .t { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
500
+ .answered .where, .recent .where { color: var(--muted); font-size: 12px; margin-left: auto; }
501
+ .recent .out-answered { color: var(--green); font-weight: 600; }
502
+ .recent .out-gone, .recent .out-expired { color: var(--muted); font-weight: 600; }
503
+ .recent .what { font-family: var(--mono); font-size: 12px; color: var(--text2); word-break: break-word; }
504
+ .form .warnbox { grid-column: 1 / -1; border: 1px solid color-mix(in srgb, var(--yellow) 45%, transparent); background: var(--tint-yellow); border-radius: 10px; padding: 9px 12px; font-size: 13px; }
505
+ @media (max-width: 640px) {
506
+ .needs-strip { padding: 10px; margin-left: -4px; margin-right: -4px; }
507
+ .need-actions .btn, .deny-form .btn { flex: 1 1 auto; justify-content: center; }
508
+ .need-wait { margin-left: 0; }
509
+ .answered .where, .recent .where { margin-left: 0; width: 100%; }
510
+ }
511
+ .tabs a { white-space: nowrap; }
512
+ .recent .hint { color: var(--muted); font-size: 12px; margin-top: 4px; }
513
+
514
+ /* ---------------------------------------------------------------- v0.4.6 */
515
+ /* Safe areas (viewport-fit=cover): notches and the home indicator, in the
516
+ iPhone home-screen app and in landscape Safari. */
517
+ .top { padding-left: max(28px, env(safe-area-inset-left)); padding-right: max(28px, env(safe-area-inset-right)); padding-top: max(12px, env(safe-area-inset-top)); }
518
+ main { padding-left: max(28px, env(safe-area-inset-left)); padding-right: max(28px, env(safe-area-inset-right)); padding-bottom: max(80px, calc(env(safe-area-inset-bottom) + 40px)); }
519
+ .toast { bottom: max(24px, calc(env(safe-area-inset-bottom) + 12px)); }
520
+ @media (max-width: 900px) { .top { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); } main { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); } }
521
+ @media (max-width: 640px) { .top { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); padding-top: max(10px, env(safe-area-inset-top)); } main { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); } }
522
+ /* No rubber-band reveal of a white page behind the dark board in the app. */
523
+ html { background: var(--bg); }
524
+
525
+ /* Sign in: the typed code (the home-screen app's way in). */
526
+ .empty.login .codeform { display: grid; grid-template-columns: 1fr auto; gap: 8px 10px; align-items: center; margin: 14px 0 6px; }
527
+ .empty.login .codeform label { grid-column: 1 / -1; color: var(--muted); font-size: 13px; }
528
+ .empty.login .codeform input { height: 48px; font: 600 22px/46px var(--mono); letter-spacing: 3px; text-transform: uppercase; text-align: center; background: var(--field); color: var(--text); border: 1px solid var(--line-strong); border-radius: 10px; padding: 0 12px; min-width: 0; }
529
+ .empty.login .codeform input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
530
+ .empty.login .codeform .btn { height: 48px; padding: 0 18px; }
531
+ .empty.login .codeerr { grid-column: 1 / -1; font-size: 13px; }
532
+
533
+ /* Settings → Remote access: the QR code, the link, the code, the countdown. */
534
+ .form .signin { grid-column: 1 / -1; display: flex; gap: 18px; align-items: flex-start; justify-content: flex-start; border: 1px solid var(--line); background: var(--subtle); border-radius: 12px; padding: 14px; flex-wrap: wrap; }
535
+ .form .signin .qr { background: #fff; padding: 8px; border-radius: 10px; line-height: 0; flex: none; }
536
+ .form .signin .qr img { width: 220px; height: 220px; image-rendering: pixelated; display: block; }
537
+ .form .signin .signin-text { flex: 1; min-width: 220px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; font-size: 13px; }
538
+ .form .signin code.link { font-family: var(--mono); font-size: 11.5px; color: var(--text2); background: var(--bg2); border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; overflow-wrap: anywhere; user-select: all; width: 100%; }
539
+ .form .signin .faint { color: var(--faint); }
540
+ .form .signin .gap { margin-top: 8px; }
541
+ .form .signin .code-big { font: 700 30px/1.1 var(--mono); letter-spacing: 4px; color: var(--text); user-select: all; }
542
+ .form .signin .expiry { color: var(--muted); font-variant-numeric: tabular-nums; }
543
+ .form .signin.expired .qr, .form .signin.expired .code-big { opacity: .25; }
544
+ .form .howto { font-size: 13px; color: var(--text2); }
545
+ .form .howto .steps { margin: 0; padding-left: 18px; display: grid; gap: 4px; }
546
+ .form .howto .faint { color: var(--faint); }
547
+
548
+ /* Settings → Summaries. */
549
+ .form .lengths { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
550
+ .form .lenopt { position: relative; display: flex; flex-direction: column; gap: 2px; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px 10px 34px; cursor: pointer; background: var(--subtle); color: var(--text2); }
551
+ .form .lenopt input { position: absolute; left: 11px; top: 12px; width: 16px; height: 16px; margin: 0; accent-color: var(--accent); }
552
+ .form .lenopt:has(input:checked) { border-color: var(--accent); background: var(--tint-accent); }
553
+ .form .lenopt:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--focus); }
554
+ .form .lenopt .lo-t { color: var(--text); font-weight: 600; }
555
+ .form .lenopt .lo-rec { font-size: 11px; font-weight: 500; color: var(--accent); }
556
+ .form .lenopt .lo-a { color: var(--faint); font-size: 11.5px; font-family: var(--mono); }
557
+ .form .lenopt .lo-b { font-size: 12px; color: var(--muted); }
558
+ .form .len-example { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; background: var(--card2); font-size: 13px; }
559
+ .form .len-example .ex-head { color: var(--muted); font-size: 12px; margin-bottom: 8px; }
560
+ .form .len-example .ex-head .faint { color: var(--faint); }
561
+ @media (max-width: 640px) { .form .lengths { grid-template-columns: 1fr; } .form .signin .qr img { width: 200px; height: 200px; } }
562
+
563
+ /* A checkpoint's informative / long sections. */
564
+ .cp-more { margin-top: 8px; font-size: 13px; }
565
+ .cp-more > summary { cursor: pointer; color: var(--muted); font-size: 12.5px; list-style: none; }
566
+ .cp-more > summary::-webkit-details-marker { display: none; }
567
+ .cp-more > summary::before { content: '▸ '; color: var(--faint); }
568
+ .cp-more[open] > summary::before { content: '▾ '; }
569
+ .cpx { display: grid; gap: 10px; margin-top: 8px; }
570
+ .cpx .cpx-h { color: var(--faint); font-size: 11px; text-transform: uppercase; letter-spacing: .6px; font-weight: 600; margin-bottom: 2px; }
571
+ .cpx ul, .cpx ol { margin: 0; padding-left: 18px; color: var(--text2); }
572
+ .cpx li { margin: 2px 0; }
573
+ .cpx p { margin: 0; color: var(--text2); }
574
+ .cpx code { font-family: var(--mono); font-size: 12px; background: var(--bg2); border: 1px solid var(--line); border-radius: 5px; padding: 0 4px; }
575
+
576
+ /* ⌘↵ hint on a Needs-you submit button. */
577
+ .kbd-hint { margin-left: 6px; font-size: 11px; opacity: .65; font-family: var(--mono); }
578
+ @media (hover: none) { .kbd-hint { display: none; } }
579
+
580
+ /* A card never sets the grid's width: long file paths and code in the
581
+ informative/long sections wrap instead of pushing the board sideways on a phone. */
582
+ .grid > * { min-width: 0; }
583
+ @media (max-width: 900px) { .grid { grid-template-columns: minmax(0, 1fr); } }
584
+ .cp dd, .cpx li, .cpx p, .cpx code { overflow-wrap: anywhere; }
585
+ /* Same for Settings: one column on a phone that no field can widen. */
586
+ .form > * { min-width: 0; }
587
+ @media (max-width: 640px) { .form { grid-template-columns: minmax(0, 1fr); } }
588
+ .models { grid-template-columns: minmax(0, 1fr); }
589
+ .models > *, .mcard .mmain { min-width: 0; }
590
+ .mstatus, .mcard .mnote, .mcard .mhint { overflow-wrap: anywhere; }
591
+
592
+ /* Restore after a restart (v0.4.7). */
593
+ .banner.restore.open { display: block; }
594
+ .banner.restore .rs-head { display: flex; align-items: flex-start; gap: 10px; }
595
+ .banner.restore .rs-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 6px; margin: 10px 0; max-height: 360px; overflow: auto; }
596
+ .banner.restore .rs-row { display: flex; gap: 9px; align-items: flex-start; padding: 7px 9px; border: 1px solid var(--line); border-radius: 9px; background: var(--card); cursor: pointer; min-width: 0; }
597
+ .banner.restore .rs-row input { margin: 2px 0 0; accent-color: var(--accent); flex: none; width: 16px; height: 16px; }
598
+ .banner.restore .rs-main { display: flex; flex-direction: column; min-width: 0; }
599
+ .banner.restore .rs-t { color: var(--text); font-weight: 600; overflow-wrap: anywhere; }
600
+ .banner.restore .rs-m { color: var(--muted); font-size: 12px; overflow-wrap: anywhere; }
601
+ .banner.restore .rs-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
602
+ .banner.restore .rs-note { color: var(--muted); font-size: 12px; }
603
+ .banner .rs-cmds { margin: 8px 0 0; padding: 8px 10px; background: var(--bg2); border: 1px solid var(--line); border-radius: 8px; font: 12px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text2); }
604
+ .banner.restore .rs-result { margin: 10px 0 0; }
605
+
606
+ /* v0.4.8: empty sessions (no prompt yet) fold into one row under the board */
607
+ .emptyfold { border: 1px dashed var(--line-strong); border-radius: var(--radius); padding: 0; background: transparent; }
608
+ .emptyfold > summary { list-style: none; cursor: pointer; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; padding: 10px 14px; color: var(--muted); font-size: 13px; }
609
+ .emptyfold > summary::-webkit-details-marker { display: none; }
610
+ .emptyfold > summary::before { content: '▸'; display: inline-block; width: 10px; transition: transform .15s; }
611
+ .emptyfold[open] > summary::before { transform: rotate(90deg); }
612
+ .emptyfold > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius); }
613
+ .emptyfold .ef-n { font-weight: 600; color: var(--text); }
614
+ .emptyfold .ef-hint { font-size: 12px; opacity: .8; }
615
+ .emptyfold > .grid { padding: 0 14px 14px; }
616
+ .emptyfold .card { opacity: .85; }
617
+
618
+
619
+ /* Catch me up (v0.5.0): the picker and the recap. Everything wraps; nothing
620
+ is wider than the phone (no sideways scroll). */
621
+ .cu-picker { background: var(--card); box-shadow: var(--card-shadow); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 20px; margin-top: 16px; display: grid; gap: 12px; max-width: 1080px; }
622
+ .cu-row { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 12px; align-items: start; }
623
+ .cu-k { color: var(--muted); font-size: 12.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .5px; padding-top: 7px; }
624
+ .cu-wins, .cu-repos { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-width: 0; }
625
+ .cu-win { border: 1px solid var(--line); background: var(--field); color: var(--text2); border-radius: 999px; padding: 6px 12px; font: inherit; font-size: 13px; cursor: pointer; }
626
+ .cu-win[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
627
+ .cu-win:focus-visible, .cu-repo:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
628
+ .cu-winline { color: var(--muted); font-size: 12.5px; }
629
+ .cu-custom { display: flex; flex-wrap: wrap; gap: 10px; }
630
+ .cu-custom label { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: 13px; }
631
+ .cu-custom input { background: var(--field); color: var(--text); border: 1px solid var(--line-strong); border-radius: 8px; padding: 5px 8px; font: inherit; max-width: 100%; }
632
+ .cu-repo { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px 4px 8px; background: var(--field); cursor: pointer; font-size: 13px; color: var(--muted); max-width: 100%; }
633
+ .cu-repo.on { color: var(--text); border-color: color-mix(in srgb, var(--accent) 55%, transparent); background: var(--tint-accent); }
634
+ .cu-repo input { margin: 0; accent-color: var(--accent); }
635
+ .cu-repo .rl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
636
+ .cu-repo .rc { color: var(--faint); font-family: var(--mono); font-size: 11.5px; }
637
+ .cu-needdot { width: 7px; height: 7px; border-radius: 50%; background: var(--red); flex: none; }
638
+ .cu-go > div:last-child { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
639
+ .cu-wait { font-size: 12.5px; }
640
+ .cu-err { color: var(--red); font-size: 13px; }
641
+ .cu-list a { display: flex; flex-direction: column; gap: 1px; font-family: inherit; font-size: 13px; }
642
+ .cu-list a .m { margin-left: 0; }
643
+ .md.cu { min-width: 0; }
644
+ .cu-summary { margin: 6px 0 4px; padding-left: 20px; }
645
+ .cu-summary li { margin: 7px 0; color: var(--text); }
646
+ .md.cu h2 { display: flex; align-items: baseline; gap: 6px; border-top: 1px solid var(--line); padding-top: 16px; }
647
+ .md.cu h2:first-of-type { border-top: 0; }
648
+ .cu-needs { display: grid; gap: 10px; margin: 6px 0 4px; }
649
+ .cu-s { padding: 12px 0 14px; border-bottom: 1px dashed var(--line); min-width: 0; }
650
+ .cu-s:last-child { border-bottom: 0; }
651
+ .cu-sh { display: flex; align-items: center; gap: 8px; min-width: 0; }
652
+ .cu-st { font-weight: 600; font-size: 15px; color: var(--text); overflow-wrap: anywhere; }
653
+ .cu-line { color: var(--faint); font-family: var(--mono); font-size: 11.5px; margin: 2px 0 8px; overflow-wrap: anywhere; }
654
+ .cu-dl { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 5px 12px; margin: 0 0 10px; }
655
+ .cu-dl dt { color: var(--muted); font-size: 12.5px; padding-top: 1px; }
656
+ .cu-dl dd { margin: 0; color: var(--text2); overflow-wrap: anywhere; min-width: 0; }
657
+ .cu-dl dd ul { margin: 2px 0 0; padding-left: 16px; }
658
+ .cu-dl dd li { margin: 3px 0; }
659
+ .cu-need { color: var(--red); font-weight: 500; }
660
+ .cu-s .actions-row { display: flex; flex-wrap: wrap; gap: 8px; }
661
+ @media (max-width: 900px) {
662
+ .cu-list { flex-direction: row; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 0 16px 2px; }
663
+ .cu-list::-webkit-scrollbar { display: none; }
664
+ .cu-list a { flex: none; }
665
+ }
666
+ @media (max-width: 640px) {
667
+ .cu-picker { padding: 14px; }
668
+ .cu-row { grid-template-columns: minmax(0, 1fr); gap: 6px; }
669
+ .cu-k { padding-top: 0; }
670
+ .cu-k:empty { display: none; }
671
+ .cu-list { margin: 0 -14px; padding: 0 14px 2px; }
672
+ .md.cu { padding: 16px; }
673
+ .cu-dl { grid-template-columns: minmax(0, 1fr); gap: 2px; }
674
+ .cu-dl dt { margin-top: 6px; font-weight: 600; font-size: 11.5px; text-transform: uppercase; letter-spacing: .4px; }
675
+ .cu-s .actions-row .btn { flex: 1 1 auto; justify-content: center; }
676
+ }
677
+
678
+ /* ------------------------------------------------------------ lists (v0.5.1) */
679
+ .listchips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
680
+ .chip.listchip { color: var(--text2); max-width: 100%; }
681
+ .chip.listchip .ic { width: 13px; height: 13px; color: var(--green); flex: none; }
682
+ .chip.listchip .ln { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--muted); }
683
+ .chip.listchip.done { opacity: .7; }
684
+ .chip.listhint { background: var(--tint-accent); border-color: transparent; color: var(--text2); max-width: 100%; }
685
+ .chip.listhint .linkish { font-weight: 600; color: var(--accent); }
686
+ .chip.listhint .x { margin-left: 2px; padding: 0 2px; line-height: 1; color: var(--muted); }
687
+ .linkish { background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; font: inherit; }
688
+ .helpq { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; border: 1px solid var(--line-strong); background: var(--bg2); color: var(--muted); font-size: 12px; font-weight: 700; cursor: pointer; vertical-align: middle; margin-left: 6px; padding: 0; text-transform: none; letter-spacing: 0; }
689
+ .helpq:hover, .helpq[aria-expanded="true"] { color: var(--accent); border-color: var(--accent); }
690
+ .lists { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 360px), 1fr)); gap: 14px; }
691
+ .lists.one { grid-template-columns: minmax(0, 720px); }
692
+ .listcard { background: linear-gradient(180deg, var(--card) 0%, var(--card-end) 100%); box-shadow: var(--card-shadow); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px 12px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
693
+ .listcard.archived { opacity: .7; }
694
+ .listcard .lhead { display: flex; align-items: center; gap: 8px; min-width: 0; }
695
+ .listcard .lname { font-weight: 600; font-size: 15px; min-width: 0; overflow-wrap: anywhere; }
696
+ .listcard .lprog { margin-left: auto; font-family: var(--mono); font-size: 12.5px; color: var(--muted); white-space: nowrap; }
697
+ .listcard.complete .lprog { color: var(--green); }
698
+ .listcard progress.bar { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 4px; border: 0; border-radius: 4px; background: var(--bg2); overflow: hidden; color: var(--green); }
699
+ .listcard progress.bar::-webkit-progress-bar { background: var(--bg2); border-radius: 4px; }
700
+ .listcard progress.bar::-webkit-progress-value { background: var(--green); border-radius: 4px; transition: width .2s; }
701
+ .listcard progress.bar::-moz-progress-bar { background: var(--green); border-radius: 4px; }
702
+ .checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
703
+ .checklist li label { display: grid; grid-template-columns: 22px 22px minmax(0, 1fr); align-items: start; gap: 4px; padding: 5px 4px; border-radius: 8px; cursor: pointer; }
704
+ .checklist li label:hover { background: var(--subtle); }
705
+ .checklist input[type=checkbox] { width: 17px; height: 17px; margin: 2px 0 0; accent-color: var(--green); cursor: pointer; }
706
+ .checklist input[disabled] { cursor: not-allowed; }
707
+ .checklist .n { color: var(--faint); font-family: var(--mono); font-size: 12px; padding-top: 1px; text-align: right; padding-right: 4px; }
708
+ .checklist .t { overflow-wrap: anywhere; min-width: 0; }
709
+ .checklist li.done .t { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--faint); }
710
+ .checklist li.more { padding: 2px 0 0 30px; font-size: 12.5px; }
711
+ .checklist li.more a { color: var(--accent); }
712
+ .addform { display: flex; gap: 6px; }
713
+ .addform input { flex: 1; min-width: 0; background: var(--field); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 6px 10px; font: inherit; font-size: 13.5px; }
714
+ .addform input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
715
+ .addform .btn .ic { width: 14px; height: 14px; }
716
+ .lfoot { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; color: var(--muted); font-size: 12px; min-width: 0; }
717
+ .lfoot a { color: var(--accent); overflow-wrap: anywhere; }
718
+ .lfoot .linkish { margin-left: auto; font-size: 12px; }
719
+ .lfoot .mono { flex-basis: 100%; overflow-wrap: anywhere; font-size: 11px; }
720
+ .lhelp { background: var(--tint-accent); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 18px; margin: 0 0 18px; max-width: 760px; }
721
+ .lhelp h3 { margin: 0 0 6px; font-size: 15px; }
722
+ .lhelp ol { margin: 0 0 8px; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
723
+ .lhelp p { margin: 0; font-size: 13px; }
724
+ .slists .lists { margin-bottom: 12px; }
725
+ .lfind { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 4px 0 10px; font-size: 12.5px; }
726
+ .lfound { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin: 0 0 10px; display: flex; flex-direction: column; gap: 6px; max-width: 760px; min-width: 0; }
727
+ .lfound.hint { border-color: var(--accent); background: var(--tint-accent); }
728
+ .lfound.err, .lfound.none { color: var(--muted); }
729
+ .lfound .row { display: flex; gap: 8px; flex-wrap: wrap; }
730
+ .lfound .preview { margin: 0; padding-left: 22px; font-size: 13px; color: var(--text2); }
731
+ .lfound .preview li { overflow-wrap: anywhere; }
732
+ .lfound .preview li.done { text-decoration: line-through; color: var(--muted); }
733
+ .banner.info { background: var(--tint-yellow); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; margin: 0 0 14px; font-size: 13px; color: var(--text2); }
734
+ .tabs a#listsTab { position: relative; }
735
+ .cu-lists { margin-bottom: 8px; }
736
+ @media (max-width: 640px) {
737
+ .lists { grid-template-columns: minmax(0, 1fr); }
738
+ .listcard { padding: 12px 12px 10px; }
739
+ }
740
+ #listsCount { background: var(--green); color: var(--on-accent); }
741
+ .chip.listhint .icon.x { opacity: .75; font-size: 15px; margin-left: 4px; }
742
+ .listcard .icon { opacity: .6; }
743
+ .listcard:hover .icon, .listcard .icon:focus-visible { opacity: 1; }
744
+ @media (hover: none) { .listcard .icon { opacity: 1; } }
745
+
746
+ /* sync and other machines (v0.5.2) */
747
+ .syncnow, .ststatus, .backup, .joinline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; min-width: 0; }
748
+ .syncnow .chip.mono, .backup .chip.mono { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
749
+ .chip.ok { color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, transparent); background: var(--tint-green); }
750
+ .chip.warn { color: var(--yellow); border-color: color-mix(in srgb, var(--yellow) 45%, transparent); background: var(--tint-yellow); }
751
+ .chip .ico, .okbox .ico { width: 13px; height: 13px; }
752
+ .joinline code.cmd { font-family: var(--mono); font-size: 12px; background: var(--bg2); border: 1px solid var(--line); border-radius: 6px; padding: 3px 8px; overflow-wrap: anywhere; min-width: 0; }
753
+ .btn.danger { color: var(--red); border-color: color-mix(in srgb, var(--red) 50%, transparent); }
754
+ .wizard { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; background: var(--subtle); display: flex; flex-direction: column; gap: 12px; min-width: 0; width: 100%; }
755
+ .form .full .wizard { justify-content: flex-start; }
756
+ .wizard p { margin: 0; color: var(--text2); }
757
+ .wizard .hint { margin: 0; }
758
+ .wsteps { display: flex; flex-wrap: wrap; gap: 6px 14px; list-style: none; padding: 0; margin: 0; font-size: 12px; color: var(--faint); counter-reset: ws; }
759
+ .wsteps li { counter-increment: ws; }
760
+ .wsteps li::before { content: counter(ws) ". "; }
761
+ .wsteps li.now { color: var(--accent); font-weight: 600; }
762
+ .wsteps li.done { color: var(--green); }
763
+ .wpicks { display: grid; gap: 8px; }
764
+ .wpick { text-align: left; display: flex; flex-direction: column; gap: 3px; border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; background: var(--card); color: var(--text); font: inherit; cursor: pointer; min-width: 0; }
765
+ .wpick:hover { border-color: var(--line-strong); }
766
+ .wpick.on { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
767
+ .wpick b { font-weight: 600; display: flex; gap: 6px; align-items: center; }
768
+ .wpick .mono { font-family: var(--mono); font-size: 12px; color: var(--text2); overflow-wrap: anywhere; }
769
+ .wpick .tradeoff { font-size: 12px; color: var(--muted); }
770
+ .wpick .join { font-size: 12px; color: var(--green); }
771
+ .wpick.other { cursor: default; }
772
+ .wpick.other input { margin: 2px 0; }
773
+ .wplan { margin: 0; padding-left: 18px; color: var(--text2); font-size: 13px; display: grid; gap: 4px; }
774
+ .wizard .mono { font-family: var(--mono); font-size: 12.5px; overflow-wrap: anywhere; }
775
+ .wactions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }
776
+ .wmoving { display: flex; gap: 10px; align-items: center; }
777
+ .spin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line-strong); border-top-color: var(--accent); animation: spin .8s linear infinite; flex: none; }
778
+ @keyframes spin { to { transform: rotate(360deg); } }
779
+ @media (prefers-reduced-motion: reduce) { .spin { animation: none; } }
780
+ .okbox { display: flex; gap: 8px; align-items: center; border: 1px solid color-mix(in srgb, var(--green) 40%, transparent); background: var(--tint-green); border-radius: 10px; padding: 9px 12px; font-size: 13px; flex-wrap: wrap; }
781
+ .wizard .warnbox { border: 1px solid color-mix(in srgb, var(--yellow) 45%, transparent); background: var(--tint-yellow); border-radius: 10px; padding: 9px 12px; font-size: 13px; }
782
+ .peers { display: grid; gap: 8px; min-width: 0; }
783
+ .peer { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; min-width: 0; }
784
+ .peer .chip { max-width: 100%; white-space: normal; }
785
+ .peer .fp { font-family: var(--mono); font-size: 11px; color: var(--faint); }
786
+ .go-off { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; min-width: 0; }
787
+ .go-off .why { font-size: 12px; color: var(--faint); }
788
+ @media (max-width: 640px) { .form .syncnow, .form .joinline, .form .backup, .form .peers { grid-column: 1; } }
789
+
790
+ /* Easy Syncthing (v0.5.3) */
791
+ .stwrap { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
792
+ .stwrap .wizard { margin-top: 2px; }
793
+ .stactions { display: flex; flex-wrap: wrap; gap: 8px; }
794
+ .stpeers { display: flex; flex-direction: column; gap: 6px; }
795
+ .stpeer { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
796
+ .stlog { margin: 0; max-height: 180px; overflow: auto; font-family: var(--mono); font-size: 11.5px; line-height: 1.45; background: var(--bg2); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; color: var(--text2); white-space: pre-wrap; overflow-wrap: anywhere; }
797
+ .stdirs { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; color: var(--text2); font-size: 13px; }
798
+ .stcode { width: 100%; box-sizing: border-box; font-family: var(--mono); font-size: 13px; resize: vertical; min-height: 64px; }
799
+ .stlabel { font-size: 12px; color: var(--muted); margin-bottom: -6px; }
800
+ .stwrap input.mono { width: 100%; box-sizing: border-box; font-family: var(--mono); font-size: 13px; }
801
+ .stpair .joinline code.cmd { font-size: 12.5px; }
802
+ .wizard progress.bar { width: 100%; }
803
+ .faint { color: var(--faint); }
804
+ .protect { border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; background: var(--card); font-size: 13px; min-width: 0; }
805
+ .protect summary { cursor: pointer; font-weight: 600; display: flex; gap: 6px; align-items: center; list-style: none; }
806
+ .protect summary::-webkit-details-marker { display: none; }
807
+ .protect summary::after { content: '▸'; margin-left: auto; color: var(--faint); }
808
+ .protect[open] summary::after { content: '▾'; }
809
+ .protect summary .ico { width: 14px; height: 14px; color: var(--green); }
810
+ .protect ul { margin: 8px 0 6px; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; color: var(--text2); }
811
+ .protect a { font-size: 12.5px; }
812
+ .form label.toplabel { align-self: start; padding-top: 6px; }
813
+ .protect a { color: var(--accent); }
814
+
815
+ /* External agents (v0.5.4): a feed shows as a machine chip; its sessions are read-only. */
816
+ .chip.machine.agent { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 12%, transparent); font-weight: 600; }
817
+ .chip.machine.agent.stale { opacity: .75; border-style: dashed; }
818
+ .card.agentcard { border-left: 3px solid color-mix(in srgb, var(--accent) 55%, transparent); }
819
+ .card.agentcard .ro, .cu-s .ro { color: var(--faint); font-size: 12px; }
820
+ .plain { white-space: pre-wrap; overflow-wrap: anywhere; }
821
+ .need.k-agent .agent-needs { margin: 6px 0 8px; padding-left: 18px; display: grid; gap: 4px; }
822
+ .need.k-agent .agent-needs li { white-space: pre-wrap; overflow-wrap: anywhere; }
823
+ .need.k-agent .need-head { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; min-width: 0; }
824
+ .need-badge.k-agent { border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
825
+ .agent-links { padding-left: 18px; display: grid; gap: 6px; }
826
+ .agent-links li { overflow-wrap: anywhere; }
827
+ .agent-cps { display: grid; gap: 10px; }
828
+ .agent-cps .cpcard { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 14px; min-width: 0; }
829
+ .agent-cps .cphead { margin-bottom: 4px; font-size: 12px; }
830
+ .listcard.readonly input[type=checkbox] { cursor: default; }
831
+ .listcard .lhead .chip.machine.agent { margin-left: auto; font-size: 11px; }
832
+ #agentsBox { display: contents; }
833
+ .form .agents { display: grid; gap: 10px; justify-content: stretch; flex-direction: column; }
834
+ .agentrow { border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; display: grid; gap: 6px; min-width: 0; }
835
+ .agentrow .ah, .agentadd .ah { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
836
+ .agentrow .as { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; min-width: 0; overflow-wrap: anywhere; }
837
+ .agentrow .as .faint { flex-basis: 100%; font-size: 12px; }
838
+ .agentrow .am { font-size: 12px; overflow-wrap: anywhere; min-width: 0; }
839
+ .agentrow .row, .agentadd .row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
840
+ .agentrow .chip { max-width: 100%; white-space: normal; }
841
+ .agent-details summary { cursor: pointer; font-size: 12px; color: var(--muted); }
842
+ .agent-details ul { margin: 4px 0 0; padding-left: 18px; font-size: 12px; }
843
+ .form .agentadd { display: grid; gap: 10px; justify-content: stretch; border: 1px dashed var(--line); border-radius: var(--radius); padding: 12px; }
844
+ .agentadd .agrid { display: grid; grid-template-columns: 90px 1fr; gap: 8px 12px; align-items: center; min-width: 0; }
845
+ .agentadd .agrid input { min-width: 0; width: 100%; }
846
+ .agentadd .row .faint { font-size: 12px; flex: 1 1 220px; }
847
+ @media (max-width: 640px) {
848
+ .agentadd .agrid { grid-template-columns: 1fr; }
849
+ }
850
+ .form .full.hint, .form .full.nocp { display: block; }
851
+ .need.k-agent { border-style: dashed; }
852
+
853
+ /* v0.5.5: a Mac that knocked without the pairing proof; the join's "If it's stuck" */
854
+ .stknock { margin: 8px 0; }
855
+ .stknock p { margin: 0 0 6px; }
856
+ .stknock .muted { color: var(--muted, inherit); opacity: .75; font-size: 12px; }
857
+ .stknock .wactions { margin-top: 6px; }
858
+ .ststuck { margin-top: 10px; }
859
+ .ststuck p { margin: 0 0 4px; }
860
+ .ststuck ol { margin: 4px 0 4px 18px; padding: 0; }
861
+
862
+ /* v0.5.7: nothing scrolls sideways on a phone.
863
+ The Digest tab was 860px wide on an iPhone: its grid column was 1fr, whose
864
+ minimum is the card's min-content, and the card's min-content was the repo
865
+ chips laid end to end (a scrolling row still counts its full width there) and
866
+ long unbroken paths, URLs and branch names in the text. The page then scrolled,
867
+ and iOS's text autosizing blew the past-digests list up to huge monospace. */
868
+ html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
869
+ main { overflow-wrap: anywhere; min-width: 0; }
870
+ main pre { max-width: 100%; overflow-x: auto; }
871
+ main img, main video { max-width: 100%; height: auto; }
872
+ .btn, .tabs a, .pill, .rchip, .seg button { overflow-wrap: normal; }
873
+ .pagehead > div:first-child { min-width: 0; }
874
+ .chip { max-width: 100%; min-width: 0; }
875
+ .digest-wrap > * { min-width: 0; }
876
+ .md { min-width: 0; overflow-wrap: anywhere; }
877
+ .md code { overflow-wrap: anywhere; word-break: break-word; }
878
+ .md .where { color: var(--muted); font-family: var(--mono); font-size: 12px; }
879
+ .md li .sub .k { color: var(--faint); font-weight: 600; font-size: 11.5px; text-transform: uppercase; letter-spacing: .4px; margin-right: 2px; }
880
+ .dates a .d-short { display: none; }
881
+ .rchip .rl { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
882
+ .tlbar > * { min-width: 0; }
883
+ .tl-head { flex-wrap: wrap; row-gap: 4px; min-width: 0; }
884
+ .need-head > * { min-width: 0; }
885
+ .need-head .need-title { max-width: calc(100% - 20px); } /* stays beside its dot when it wraps */
886
+ @media (max-width: 900px) {
887
+ /* past digests: one compact row that scrolls on its own, like Catch me up's */
888
+ .digest-dates { flex-direction: row; gap: 6px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin: 0 -16px; padding: 0 16px 2px; }
889
+ .digest-dates::-webkit-scrollbar { display: none; }
890
+ .digest-dates a { flex: none; display: flex; flex-direction: column; gap: 1px; padding: 6px 11px; font-family: inherit; font-size: 13px; line-height: 1.3; border: 1px solid var(--line); background: var(--card); }
891
+ .digest-dates a.on { border-color: var(--accent); background: var(--tint-accent); }
892
+ .digest-dates a .d-iso { display: none; }
893
+ .digest-dates a .d-short { display: inline; }
894
+ .digest-dates a .m { margin-left: 0; font-size: 11.5px; }
895
+ .digest-wrap { gap: 12px; margin-top: 12px; }
896
+ }
897
+ @media (max-width: 640px) {
898
+ .digest-dates { margin: 0 -14px; padding: 0 14px 2px; }
899
+ .md { padding: 16px 16px 18px; }
900
+ .md h1 { font-size: 19px; line-height: 1.3; }
901
+ .md h2 { font-size: 15.5px; margin: 18px 0 6px; }
902
+ .md ul { padding-left: 16px; }
903
+ .md li { margin: 12px 0; }
904
+ .md li .sub { font-size: 13px; line-height: 1.45; margin-top: 3px; }
905
+ .tlsel, .tlbar lo-select { width: 100%; }
906
+ }
907
+
908
+ /* ------------------------------------------------------------ spaces (v0.5.8) */
909
+ .chip.space { color: var(--text2); border-color: color-mix(in srgb, var(--green, #3fb27f) 40%, transparent); background: color-mix(in srgb, var(--green, #3fb27f) 10%, transparent); font-weight: 600; letter-spacing: .01em; max-width: 14em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: inline-block; vertical-align: middle; }
910
+ .spacetabs { margin: 12px 0 0; min-width: 0; }
911
+ .spacetabs .track { display: inline-flex; gap: 2px; padding: 3px; border-radius: 10px; background: var(--bg2); border: 1px solid var(--line); max-width: 100%; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
912
+ .spacetabs .track::-webkit-scrollbar { display: none; }
913
+ .stab { flex: none; display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent; color: var(--muted); font: 600 13px/1.2 inherit; font-family: inherit; padding: 6px 12px; border-radius: 7px; cursor: pointer; white-space: nowrap; }
914
+ .stab:hover { color: var(--text); }
915
+ .stab.on { background: var(--card); color: var(--text); box-shadow: var(--card-shadow); }
916
+ .stab .rc { font: 600 11px/1 var(--mono); color: var(--faint); }
917
+ .stab.on .rc { color: var(--accent); }
918
+ .stab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
919
+ .stab .sl { max-width: 12em; overflow: hidden; text-overflow: ellipsis; }
920
+ .digest-repos { margin-top: 8px; }
921
+ .md section[hidden], .md h3[hidden] { display: none; }
922
+ .md section.space-sec { border-top: 1px solid var(--line); margin-top: 18px; padding-top: 4px; }
923
+ .md section.space-sec:first-of-type { border-top: 0; margin-top: 6px; }
924
+ .md .space-head { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; margin: 14px 0 4px; }
925
+ .md .space-head h2 { margin: 0; font-size: 19px; }
926
+ .md h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: 16px 0 6px; }
927
+ .standup-btn { white-space: nowrap; }
928
+ .standup-out { border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg2); padding: 8px 10px 10px; margin: 8px 0 4px; display: grid; gap: 6px; }
929
+ .standup-out .so-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); }
930
+ .standup-out .so-head .ok { color: var(--green, #3fb27f); display: inline-flex; align-items: center; gap: 5px; font-weight: 600; }
931
+ .standup-out textarea { width: 100%; box-sizing: border-box; resize: vertical; font: 12.5px/1.45 var(--mono); color: var(--text); background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; white-space: pre-wrap; overflow-wrap: anywhere; }
932
+ .digest-hint, .digest-also { font-size: 12.5px; color: var(--muted); margin: -4px 0 10px; }
933
+ .spacepick { display: flex; align-items: center; gap: 8px 10px; flex-wrap: wrap; margin: 10px 0 2px; font-size: 13px; min-width: 0; }
934
+ .spacepick label { font-weight: 600; color: var(--muted); }
935
+ .spacepick lo-select { max-width: 100%; min-width: 200px; }
936
+ .spacepick .lo-sel-btn { height: 32px; font-size: 13px; }
937
+ .spacepick .faint { flex: 1 1 14em; min-width: 0; }
938
+ .form .spaces { display: grid; gap: 8px; min-width: 0; }
939
+ .form .sp-sub { font-weight: 600; font-size: 13px; color: var(--text2); display: flex; flex-wrap: wrap; gap: 4px 8px; }
940
+ .form .sp-sub .faint { font-weight: 400; }
941
+ .sprow { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; border: 1px solid var(--line); border-radius: var(--radius); padding: 8px 10px; min-width: 0; }
942
+ .sprow .sp-name { display: flex; align-items: center; gap: 6px 8px; flex-wrap: wrap; min-width: 0; overflow-wrap: anywhere; }
943
+ .sprow .sp-name .chip { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
944
+ .sprow .sp-pick { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
945
+ .sprow lo-select { max-width: 100%; min-width: 0; }
946
+ .sprow .lo-sel-btn { height: 32px; font-size: 13px; min-width: 150px; }
947
+ .spq { border: 1px solid var(--line); background: var(--field); color: var(--text2); border-radius: 999px; padding: 5px 12px; font: 600 12.5px/1.2 inherit; font-family: inherit; cursor: pointer; }
948
+ .spq[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
949
+ .spq:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
950
+ .sprow.spadd { border-style: dashed; justify-content: flex-start; }
951
+ .sprow.spadd lo-combo { flex: 1 1 12em; min-width: 0; }
952
+ .sprow.spadd .lo-combo-input { height: 32px; font-size: 13px; }
953
+ .sprow.spadd > lo-select { flex: 0 1 auto; }
954
+ @media (max-width: 600px) {
955
+ .md .space-head .standup-btn { flex: 1 1 auto; justify-content: center; }
956
+ .sprow { padding: 8px; }
957
+ .sprow .sp-pick { width: 100%; }
958
+ .sprow .sp-pick .spsel { flex: 1 1 8em; }
959
+ }
960
+ .md .space-head h2 { text-transform: none; letter-spacing: 0; color: var(--text); }
961
+ .form .hint.sp-explain { margin-top: 0; }
962
+ #spacesBox { display: contents; }
963
+ .form .spaces { justify-content: stretch; grid-template-columns: minmax(0, 1fr); }
964
+
965
+ /* ------------------------------------------------------------ dropdowns (v0.5.9)
966
+ <lo-select> and <lo-combo> (ui/picker.js) replace every native select and
967
+ datalist. The closed control matches the text fields; the menu is a card. */
968
+ lo-select, lo-combo { display: inline-block; position: relative; min-width: 0; max-width: 100%; vertical-align: middle; }
969
+ lo-select > option, lo-combo > option { display: none; }
970
+ .lo-sel-btn { display: flex; align-items: center; gap: 8px; width: 100%; min-width: 0; height: 36px; padding: 0 10px 0 12px; background: var(--field); color: var(--text); border: 1px solid var(--line); border-radius: 8px; font: inherit; font-size: 14px; text-align: left; cursor: pointer; transition: border-color .15s, box-shadow .15s, background .15s; }
971
+ .lo-sel-btn:hover { border-color: var(--line-strong); }
972
+ .lo-sel-btn:focus-visible, lo-select.open .lo-sel-btn { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
973
+ .lo-sel-btn:disabled { opacity: .55; cursor: default; }
974
+ .lo-sel-val { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: normal; }
975
+ .lo-chev { width: 16px; height: 16px; flex: none; color: var(--muted); transition: transform .15s; }
976
+ lo-select.open .lo-chev, lo-combo.open .lo-chev { transform: rotate(180deg); }
977
+ .form lo-select, .form lo-combo { width: 100%; }
978
+ /* the header's compact form (the board's machine filter) */
979
+ lo-select.btn { padding: 0; border: 0; background: none; height: auto; }
980
+ lo-select.btn .lo-sel-btn { height: 32px; padding: 0 8px 0 12px; background: var(--card); border-radius: 9px; font-size: 13px; font-weight: 500; color: var(--text2); box-shadow: var(--card-shadow); }
981
+ lo-combo { display: inline-flex; align-items: center; }
982
+ lo-combo .lo-combo-input { flex: 1; min-width: 0; height: 36px; padding: 0 34px 0 12px; background: var(--field); color: var(--text); border: 1px solid var(--line); border-radius: 8px; font: inherit; font-size: 14px; transition: border-color .15s, box-shadow .15s; }
983
+ lo-combo .lo-combo-input::placeholder { color: var(--faint); }
984
+ lo-combo .lo-combo-input:hover { border-color: var(--line-strong); }
985
+ lo-combo .lo-combo-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
986
+ .lo-combo-btn { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; display: grid; place-items: center; border: 0; background: none; color: var(--muted); border-radius: 6px; cursor: pointer; padding: 0; }
987
+ .lo-combo-btn:hover { background: var(--bg2); color: var(--text); }
988
+ .lo-menu { position: fixed; z-index: 60; display: flex; flex-direction: column; background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 12px 32px rgba(15, 20, 35, .16), 0 2px 6px rgba(15, 20, 35, .08); padding: 5px; overflow: hidden; font-size: 14px; overflow-wrap: normal; animation: lo-in .12s ease-out; }
989
+ [data-theme="dark"] .lo-menu, :root:not([data-theme="light"]) .lo-menu { box-shadow: 0 14px 36px rgba(0, 0, 0, .5), 0 2px 6px rgba(0, 0, 0, .3); background: var(--card2); }
990
+ @keyframes lo-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
991
+ .lo-menu.up { animation-name: lo-in-up; }
992
+ @keyframes lo-in-up { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
993
+ .lo-list { overflow-y: auto; overscroll-behavior: contain; min-height: 0; flex: 1; }
994
+ .lo-opt { display: flex; align-items: center; gap: 8px; padding: 7px 10px 7px 8px; border-radius: 8px; cursor: pointer; color: var(--text2); line-height: 1.3; user-select: none; }
995
+ .lo-opt.active { background: var(--bg2); color: var(--text); }
996
+ [data-theme="dark"] .lo-opt.active, :root:not([data-theme="light"]) .lo-opt.active { background: var(--line); }
997
+ .lo-opt.sel { color: var(--text); font-weight: 600; }
998
+ .lo-check { width: 15px; height: 15px; flex: none; color: var(--accent); visibility: hidden; }
999
+ .lo-opt.sel .lo-check { visibility: visible; }
1000
+ .lo-opt-text { display: flex; flex-direction: column; min-width: 0; }
1001
+ .lo-opt-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1002
+ .lo-opt-sub { font-size: 12px; color: var(--faint); font-weight: 400; font-family: var(--mono); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1003
+ .lo-opt mark { background: none; color: var(--accent); font-weight: 700; }
1004
+ .lo-empty { padding: 10px 12px; color: var(--faint); }
1005
+ .lo-filter-wrap { padding: 2px 2px 6px; }
1006
+ .lo-filter { width: 100%; height: 32px; padding: 0 10px; background: var(--field); color: var(--text); border: 1px solid var(--line); border-radius: 8px; font: inherit; font-size: 13.5px; }
1007
+ .lo-filter:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
1008
+ /* phone (<600px): a select's menu is a bottom sheet; a combo's is full width */
1009
+ .lo-backdrop { position: fixed; inset: 0; z-index: 59; background: rgba(10, 12, 20, .32); animation: lo-fade .15s ease-out; }
1010
+ @keyframes lo-fade { from { opacity: 0; } to { opacity: 1; } }
1011
+ .lo-menu.sheet { left: 0; right: 0; bottom: 0; top: auto; width: auto; border-radius: 16px 16px 0 0; border-bottom: 0; padding: 4px 8px max(12px, env(safe-area-inset-bottom)); animation: lo-up .2s ease-out; }
1012
+ @keyframes lo-up { from { transform: translateY(24px); opacity: .4; } to { transform: none; opacity: 1; } }
1013
+ .lo-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 6px 8px; border-bottom: 1px solid var(--line); margin-bottom: 6px; font-weight: 600; color: var(--text); }
1014
+ .lo-sheet-head span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1015
+ .lo-sheet-done { border: 0; background: none; color: var(--accent); font: inherit; font-weight: 600; padding: 4px 6px; cursor: pointer; }
1016
+ .lo-menu.sheet .lo-opt { padding: 12px 10px 12px 8px; font-size: 16px; }
1017
+ .lo-menu.sheet .lo-filter { height: 38px; font-size: 16px; }
1018
+ .lo-menu.wide .lo-opt { padding: 10px 10px 10px 8px; }
1019
+ @media (max-width: 640px) { lo-combo .lo-combo-input { font-size: 16px; } }
1020
+ .tlbar lo-select { min-width: 220px; max-width: min(420px, 100%); }
1021
+ .tlbar .lo-sel-btn { height: 32px; font-size: 13px; border-radius: 9px; }
1022
+ @media (max-width: 640px) { .sprow .lo-sel-btn, .spacepick .lo-sel-btn, .tlbar .lo-sel-btn { height: 38px; font-size: 14px; } .sprow.spadd .lo-combo-input { font-size: 16px; height: 38px; } .spacepick lo-select { min-width: 0; flex: 1 1 12em; } }
1023
+
1024
+ /* ------------------------------------------------------------ Settings (v0.5.9)
1025
+ Desktop (≥900px): a sidebar of sections, one section on the right.
1026
+ Phone: a grouped list (iOS Settings style) that drills into a section. */
1027
+ .settings { display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: 28px; align-items: start; }
1028
+ .set-nav { position: sticky; top: 74px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
1029
+ .set-navhead h1 { margin: 0 0 2px 4px; }
1030
+ .set-search { position: relative; }
1031
+ .set-search .ic { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--faint); pointer-events: none; }
1032
+ .set-search input { width: 100%; height: 34px; padding: 0 10px 0 32px; background: var(--field); color: var(--text); border: 1px solid var(--line); border-radius: 9px; font: inherit; font-size: 13.5px; }
1033
+ .set-search input::placeholder { color: var(--faint); }
1034
+ .set-search input:hover { border-color: var(--line-strong); }
1035
+ .set-search input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
1036
+ .set-nav ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
1037
+ .set-nav li[hidden] { display: none; }
1038
+ .set-nav a { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 8px; color: var(--muted); font-weight: 500; text-decoration: none; min-width: 0; }
1039
+ .set-nav a .ic { width: 17px; height: 17px; flex: none; opacity: .85; }
1040
+ .set-nav a:hover { color: var(--text); background: var(--bg2); }
1041
+ .set-nav a.on { color: var(--text); background: var(--card2); }
1042
+ .set-nav a.on .ic { opacity: 1; color: var(--accent); }
1043
+ .set-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: normal; }
1044
+ .set-chev { display: none; }
1045
+ .sdot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--accent); font-size: 0; color: transparent; overflow: hidden; }
1046
+ .sdot.warn { background: var(--yellow); box-shadow: 0 0 0 3px var(--tint-yellow); }
1047
+ .sdot.info { background: var(--accent); box-shadow: 0 0 0 3px var(--tint-accent); }
1048
+ .sdot[hidden] { display: none; }
1049
+ .set-nomatch { margin: 2px 6px; color: var(--faint); font-size: 12.5px; }
1050
+ .set-main { min-width: 0; max-width: 760px; }
1051
+ .set-head { margin-bottom: 14px; }
1052
+ .set-head h2 { margin: 2px 0 2px; font-size: 22px; text-transform: none; letter-spacing: normal; color: var(--text); font-weight: 650; }
1053
+ .set-head .sub { color: var(--muted); }
1054
+ .set-back { display: none; }
1055
+ .settings .form { max-width: none; }
1056
+ .set-pane { display: contents; }
1057
+ .set-pane[hidden] { display: none; }
1058
+ .form .section.dup { display: none; }
1059
+ .form .set-pane > .section:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
1060
+ .form .set-save { align-items: center; justify-content: flex-end; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 14px; }
1061
+ .form .set-save .faint { color: var(--faint); font-size: 12px; margin-right: auto; }
1062
+ .form .set-empty, .form .set-link { grid-column: 1 / -1; margin-top: 0; }
1063
+ .form .aboutline { display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap; }
1064
+ .form .aboutline a { color: var(--accent); text-decoration: none; }
1065
+ .form .aboutline a:hover { text-decoration: underline; }
1066
+ .set-hit { background: var(--tint-yellow); border-radius: 4px; box-shadow: 0 0 0 3px var(--tint-yellow); }
1067
+ @media (max-width: 899.98px) {
1068
+ .settings { display: block; }
1069
+ .set-nav { position: static; gap: 12px; }
1070
+ .set-navhead h1 { margin: 0; }
1071
+ .settings.has-sec .set-nav { display: none; }
1072
+ .settings.no-sec .set-main { display: none; }
1073
+ .set-nav ul { gap: 0; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; box-shadow: var(--card-shadow); }
1074
+ .set-nav li:not([hidden]) ~ li:not([hidden]) a { border-top: 1px solid var(--line); }
1075
+ .set-nav a { padding: 13px 14px; border-radius: 0; color: var(--text); font-size: 16px; gap: 12px; }
1076
+ .set-nav a .ic { width: 20px; height: 20px; color: var(--accent); opacity: 1; }
1077
+ .set-nav a.on { background: none; }
1078
+ .set-nav a:active { background: var(--bg2); }
1079
+ .set-chev { display: block; color: var(--faint); width: 17px !important; height: 17px !important; }
1080
+ .set-search input { height: 40px; font-size: 16px; border-radius: 11px; }
1081
+ .set-back { display: inline-flex; align-items: center; gap: 2px; margin: 0 0 6px -6px; padding: 4px 6px; color: var(--accent); font-weight: 500; text-decoration: none; border-radius: 8px; }
1082
+ .set-back .ic { width: 20px; height: 20px; }
1083
+ .set-head h2 { font-size: 24px; }
1084
+ .set-main { max-width: none; }
1085
+ }
1086
+ .form .sprow lo-select, .form .sprow lo-combo { width: auto; }
1087
+ @media (max-width: 640px) { .sprow .lo-sel-btn { min-width: 0; } .sprow .sp-pick lo-select { flex: 1 1 8em; } .sprow.spadd lo-combo { flex: 1 1 100%; } .sprow.spadd > lo-select { flex: 1 1 8em; } }
1088
+
1089
+ /* ------------------------------------------------------------ the top bar (v0.5.9)
1090
+ One calm row from 900px up: logo, the five main tabs, then search (⌘K),
1091
+ this Mac's status, What's new and Settings as icons. Nothing wraps or is
1092
+ cut off at 900px. Under 900px: the logo row with the same icons, and the
1093
+ five tabs below it (icon over a short label under 640px). */
1094
+ .top { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 18px; min-height: 56px; padding: 10px 28px; background: var(--header-bg); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border-bottom: 1px solid var(--line); }
1095
+ .brand { display: flex; align-items: center; gap: 9px; font-weight: 650; font-size: 15.5px; letter-spacing: .1px; flex: none; color: var(--text); text-decoration: none; }
1096
+ .tabs { display: flex; align-items: center; gap: 2px; min-width: 0; }
1097
+ .tabs a { position: relative; display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 11px; border-radius: 9px; color: var(--muted); font-weight: 500; white-space: nowrap; text-decoration: none; transition: color .15s, background .15s; }
1098
+ .tabs a .ic, .topright .ic { width: 16px; height: 16px; flex: none; }
1099
+ .tabs a .ic { opacity: .85; }
1100
+ .tabs a:hover { color: var(--text); background: var(--bg2); }
1101
+ .tabs a.on { color: var(--text); background: var(--card2); box-shadow: inset 0 0 0 1px var(--line); }
1102
+ .tabs a.on .ic { opacity: 1; color: var(--accent); }
1103
+ .tabs .lbl-short { display: none; }
1104
+ .navcount { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--red); color: #fff; font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; }
1105
+ .topright { margin-left: auto; display: flex; align-items: center; gap: 6px; flex: none; }
1106
+ .searchbtn { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 6px 0 11px; min-width: 170px; background: var(--bg2); border: 1px solid var(--line); border-radius: 10px; color: var(--faint); font: inherit; font-size: 13.5px; cursor: pointer; transition: border-color .15s, color .15s; margin-right: 6px; }
1107
+ .searchbtn:hover { border-color: var(--line-strong); color: var(--muted); }
1108
+ .searchbtn .sb-lbl { flex: 1; text-align: left; }
1109
+ .sb-kbd, .cmdk kbd { font: 600 11px/1 var(--mono); color: var(--muted); background: var(--card); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 6px; padding: 3px 6px; white-space: nowrap; }
1110
+ .health { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; border: 1px solid transparent; border-radius: 9px; background: none; color: var(--muted); font: inherit; font-size: 13px; white-space: nowrap; cursor: pointer; max-width: 180px; }
1111
+ .health:hover, .health[aria-expanded="true"] { background: var(--bg2); color: var(--text); }
1112
+ .health .label { overflow: hidden; text-overflow: ellipsis; }
1113
+ .health .dot, .statuspop .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gray); flex: none; }
1114
+ .health.up .dot, .statuspop .dot.up { background: var(--green); box-shadow: 0 0 0 3px var(--tint-green); }
1115
+ .health.down .dot, .statuspop .dot.down { background: var(--red); }
1116
+ .iconbtn { position: relative; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; color: var(--muted); text-decoration: none; transition: color .15s, background .15s; }
1117
+ .iconbtn .ic { width: 17px; height: 17px; }
1118
+ .iconbtn:hover { color: var(--text); background: var(--bg2); }
1119
+ .iconbtn.on { color: var(--accent); background: var(--card2); box-shadow: inset 0 0 0 1px var(--line); }
1120
+ .newdot, .topdot { position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--header-bg); }
1121
+ .topdot.warn { background: var(--yellow); }
1122
+ .newdot[hidden], .topdot[hidden] { display: none; }
1123
+ .searchbtn:focus-visible, .health:focus-visible, .iconbtn:focus-visible, .tabs a:focus-visible, .brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1124
+ /* the status popover */
1125
+ .statuspop { position: fixed; z-index: 40; width: 320px; max-width: calc(100vw - 16px); background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 16px 40px rgba(15, 20, 35, .18), 0 2px 6px rgba(15, 20, 35, .08); padding: 12px; font-size: 13.5px; animation: lo-in .12s ease-out; }
1126
+ [data-theme="dark"] .statuspop { background: var(--card2); box-shadow: 0 16px 40px rgba(0, 0, 0, .5); }
1127
+ .statuspop[hidden] { display: none; }
1128
+ .sp-head { display: flex; align-items: center; gap: 8px; padding: 2px 4px 10px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
1129
+ .sp-head .faint { color: var(--faint); margin-left: auto; font-size: 12px; }
1130
+ .sp-row { display: flex; align-items: baseline; gap: 12px; padding: 6px 4px; }
1131
+ .sp-k { width: 80px; flex: none; color: var(--faint); font-size: 12.5px; }
1132
+ .sp-v { min-width: 0; color: var(--text2); overflow-wrap: anywhere; }
1133
+ .sp-v a, .statuspop a { color: var(--accent); text-decoration: none; }
1134
+ .sp-v a:hover { text-decoration: underline; }
1135
+ .sp-v.warnish a { color: var(--yellow); }
1136
+ .sp-v .faint { color: var(--faint); }
1137
+ .sp-theme { align-items: center; border-top: 1px solid var(--line); margin-top: 6px; padding-top: 10px; }
1138
+ .statuspop .theme button { width: auto; height: 26px; padding: 0 9px; gap: 5px; display: inline-flex; align-items: center; font-size: 12px; }
1139
+ .sp-links { display: flex; gap: 6px; border-top: 1px solid var(--line); margin-top: 8px; padding-top: 10px; }
1140
+ .sp-links a { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 32px; border-radius: 8px; background: var(--bg2); color: var(--text2); font-weight: 500; }
1141
+ .sp-links a:hover { color: var(--text); text-decoration: none; }
1142
+ /* ⌘K search */
1143
+ .cmdk { position: fixed; inset: 0; z-index: 50; background: rgba(10, 12, 20, .38); display: flex; justify-content: center; align-items: flex-start; padding: 12vh 16px 16px; animation: lo-fade .12s ease-out; }
1144
+ .cmdk[hidden] { display: none; }
1145
+ html.cmdk-open { overflow: hidden; }
1146
+ .cmdk-panel { width: 100%; max-width: 640px; max-height: 70vh; display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 24px 60px rgba(10, 15, 30, .3); overflow: hidden; animation: lo-in .14s ease-out; }
1147
+ [data-theme="dark"] .cmdk-panel { background: var(--card2); }
1148
+ .cmdk-field { display: flex; align-items: center; gap: 10px; padding: 0 12px 0 16px; border-bottom: 1px solid var(--line); }
1149
+ .cmdk-field .ic { width: 18px; height: 18px; color: var(--faint); flex: none; }
1150
+ .cmdk-field input { flex: 1; min-width: 0; height: 54px; border: 0; background: none; color: var(--text); font: inherit; font-size: 17px; outline: none; }
1151
+ .cmdk-field input::placeholder { color: var(--faint); }
1152
+ .cmdk-field input::-webkit-search-cancel-button { display: none; }
1153
+ .cmdk-esc { font: 600 11px/1 var(--mono); color: var(--muted); background: var(--bg2); border: 1px solid var(--line); border-radius: 6px; padding: 4px 7px; cursor: pointer; }
1154
+ .cmdk-list { overflow-y: auto; overscroll-behavior: contain; padding: 6px; min-height: 0; flex: 1; }
1155
+ .cmdk-group { padding: 10px 10px 4px; font-size: 11.5px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; color: var(--faint); }
1156
+ .cmdk-opt { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 9px; color: var(--text2); text-decoration: none; min-width: 0; }
1157
+ .cmdk-opt .ic { width: 16px; height: 16px; color: var(--faint); }
1158
+ .cmdk-opt.active { background: var(--bg2); color: var(--text); }
1159
+ [data-theme="dark"] .cmdk-opt.active { background: var(--line); }
1160
+ .cmdk-opt.active .ic { color: var(--accent); }
1161
+ .co-text { display: flex; flex-direction: column; min-width: 0; }
1162
+ .co-title, .co-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; overflow-wrap: normal; }
1163
+ .co-title { font-weight: 500; }
1164
+ .co-sub { font-size: 12px; color: var(--faint); }
1165
+ .cmdk-note { padding: 14px 12px; color: var(--faint); font-size: 13px; }
1166
+ .cmdk-foot { display: flex; gap: 16px; padding: 8px 14px; border-top: 1px solid var(--line); color: var(--faint); font-size: 12px; }
1167
+ .cmdk-foot kbd { margin-right: 3px; padding: 2px 5px; }
1168
+ /* 900–1099px: the search button shrinks to its key, the status to its dot */
1169
+ @media (min-width: 900px) and (max-width: 1099.98px) {
1170
+ .top { gap: 12px; }
1171
+ .tabs a { padding: 0 9px; }
1172
+ .searchbtn { min-width: 0; padding: 0 6px 0 9px; }
1173
+ .searchbtn .sb-lbl { display: none; }
1174
+ .health .label { display: none; }
1175
+ .health { padding: 0 9px; }
1176
+ }
1177
+ @media (min-width: 1400px) { .searchbtn { min-width: 220px; } }
1178
+ /* phone and narrow windows: the logo row with the icons, the tabs below */
1179
+ @media (max-width: 899.98px) {
1180
+ .top { flex-wrap: wrap; row-gap: 8px; column-gap: 8px; padding-top: max(10px, env(safe-area-inset-top)); padding-bottom: 6px; }
1181
+ .brand { order: 1; }
1182
+ .topright { order: 2; gap: 2px; }
1183
+ .tabs { order: 3; flex: 1 1 100%; justify-content: flex-start; }
1184
+ .searchbtn { min-width: 0; width: 38px; height: 38px; padding: 0; justify-content: center; margin-right: 0; background: none; border-color: transparent; color: var(--muted); }
1185
+ .searchbtn .sb-lbl, .searchbtn .sb-kbd { display: none; }
1186
+ .searchbtn .ic { width: 18px; height: 18px; }
1187
+ .health { height: 38px; padding: 0 10px; }
1188
+ .health .label { display: none; }
1189
+ .iconbtn { width: 38px; height: 38px; }
1190
+ .iconbtn .ic { width: 19px; height: 19px; }
1191
+ .newdot, .topdot { top: 7px; right: 7px; }
1192
+ .cmdk { padding: 0; align-items: stretch; background: var(--bg); }
1193
+ .cmdk-panel { max-width: none; max-height: none; height: 100%; border-radius: 0; border: 0; box-shadow: none; }
1194
+ .cmdk-field { padding-top: env(safe-area-inset-top); }
1195
+ .cmdk-field input { font-size: 17px; }
1196
+ .cmdk-foot { display: none; }
1197
+ .cmdk-opt { padding: 11px 10px; }
1198
+ }
1199
+ @media (max-width: 639.98px) {
1200
+ .tabs { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 2px; margin: 0 -6px; }
1201
+ .tabs a { flex-direction: column; justify-content: center; gap: 3px; height: auto; padding: 6px 2px 5px; font-size: 11px; line-height: 1.1; text-align: center; }
1202
+ .tabs a .ic { width: 19px; height: 19px; }
1203
+ .tabs a.on { box-shadow: none; }
1204
+ .tabs #needsTab .lbl { display: none; }
1205
+ .tabs #needsTab .lbl-short { display: inline; }
1206
+ .navcount { position: absolute; top: 1px; right: calc(50% - 22px); min-width: 15px; height: 15px; line-height: 15px; font-size: 10px; padding: 0 4px; box-shadow: 0 0 0 2px var(--header-bg); }
1207
+ }
1208
+ .top { padding-left: max(28px, env(safe-area-inset-left)); padding-right: max(28px, env(safe-area-inset-right)); }
1209
+ @media (max-width: 899.98px) { .top { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(12px, env(safe-area-inset-right)); } }
1210
+ @media (max-width: 639.98px) { .top { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(8px, env(safe-area-inset-right)); } }
1211
+
1212
+ /* Settings between 900 and 1180px: the sidebar takes room, so labels sit above their fields instead of in a 200px column (the checkpoint length cards were three words wide at 900). */
1213
+ @media (min-width: 900px) and (max-width: 1179.98px) {
1214
+ .settings .form { grid-template-columns: minmax(0, 1fr); gap: 8px 18px; }
1215
+ .settings .form > label:not(.check) { margin-top: 8px; }
1216
+ .settings .form > label:first-child { margin-top: 0; }
1217
+ .settings .form .hint, .settings .form .remote-actions, .settings .form .remote-link, .settings .form .syncnow, .settings .form .joinline, .settings .form .backup, .settings .form .peers { grid-column: 1; }
1218
+ .settings .form .hint { margin-top: -4px; }
1219
+ }
1220
+
1221
+ /* Use from anywhere (v0.6.0) */
1222
+ .form .anyuser { display: flex; align-items: center; gap: 6px; min-width: 0; flex-wrap: wrap; }
1223
+ .form .anyuser input { width: 12em; max-width: 100%; flex: 0 1 auto; }
1224
+ .form .anyuser .mono { font-family: var(--mono); font-size: 13px; }
1225
+ .form .signup { display: flex; flex-direction: column; align-items: stretch; gap: 8px; min-width: 0; max-width: 26em; }
1226
+ .form .signup .anyuser input { flex: 1 1 8em; width: auto; }
1227
+ .form .signup > input[type="email"] { width: 100%; }
1228
+ .form .signup .remote-actions { grid-column: auto; margin: 2px 0 0; }
1229
+ .form .signup .hint { margin: 0; }
1230
+ .form .signup-wait { display: flex; flex-direction: column; gap: 6px; min-width: 0; max-width: 30em; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--card, transparent); overflow-wrap: anywhere; }
1231
+ .form .signup-wait .sw-head { display: flex; align-items: center; gap: 8px; }
1232
+ .form .signup-wait .remote-actions { grid-column: auto; margin: 4px 0 0; align-items: center; gap: 10px; }
1233
+ .form .relaystat { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
1234
+ .form .relaystat .hint { margin: 0; overflow-wrap: anywhere; }
1235
+ .form .devlist { display: grid; gap: 8px; min-width: 0; }
1236
+ .form .dev { display: flex; align-items: center; gap: 10px; border: 1px solid var(--line); background: var(--subtle); border-radius: 10px; padding: 10px 12px; min-width: 0; }
1237
+ .form .dev-main { flex: 1; min-width: 0; overflow-wrap: anywhere; }
1238
+ .form .dev-main .faint { color: var(--faint); font-size: 12.5px; margin-top: 2px; }
1239
+ .btn.danger { color: var(--red); }
1240
+ .form .signin .code-big.long { font-size: 20px; letter-spacing: 2px; overflow-wrap: anywhere; }
1241
+ .warnish { color: var(--yellow); }
1242
+ .sp-macs .macswitch { flex-wrap: wrap; max-width: 100%; }
1243
+ .macswitch button { width: auto; padding: 0 10px; gap: 6px; display: inline-flex; align-items: center; font: inherit; font-size: 12.5px; }
1244
+ .macswitch button:disabled { opacity: .5; cursor: default; }
1245
+ .mdot { width: 7px; height: 7px; border-radius: 50%; background: var(--gray); flex: none; }
1246
+ .mdot.on { background: var(--green); }
1247
+ .relay-screen { position: fixed; inset: 0; z-index: 1000; background: var(--bg); display: grid; place-items: start center; padding: max(40px, env(safe-area-inset-top)) 18px 24px; overflow: auto; }
1248
+ .relay-card, .pairbox { width: 100%; max-width: 440px; }
1249
+ .relay-card h1, .pairbox h1 { font-size: 24px; line-height: 1.2; margin: 6px 0 12px; letter-spacing: -.02em; color: var(--text); }
1250
+ .relay-card p, .pairbox p { color: var(--muted); line-height: 1.5; }
1251
+ .relay-logo { font-weight: 700; color: var(--accent); letter-spacing: -.01em; }
1252
+ body.pairpage { background: var(--bg); color: var(--text); margin: 0; }
1253
+ .pairbox { margin: 0 auto; padding: max(40px, env(safe-area-inset-top)) 18px 32px; box-sizing: border-box; }
1254
+ .pairbox form { display: grid; gap: 8px; margin: 18px 0 6px; }
1255
+ .pairbox label { font-size: 13px; color: var(--muted); margin-top: 6px; }
1256
+ .pairbox input { font: inherit; font-size: 17px; padding: 11px 12px; border-radius: 10px; border: 1px solid var(--line-strong); background: var(--field); color: var(--text); width: 100%; box-sizing: border-box; min-width: 0; }
1257
+ .pairbox input.mono { font-family: var(--mono); letter-spacing: 1px; }
1258
+ .pairbox .btn { margin-top: 10px; justify-content: center; padding: 12px; font-size: 16px; }
1259
+ .pairbox .hint { font-size: 13px; color: var(--faint); }
1260
+ .pmsg { min-height: 1.4em; margin: 10px 0; }
1261
+ .pmsg.bad { color: var(--red); }
1262
+ .pmsg.ok { color: var(--green); }
1263
+ .statuspop .sp-theme .theme, .statuspop .macswitch { min-width: 0; flex: 0 1 auto; flex-wrap: wrap; }
1264
+ @media (max-width: 600px) { .statuspop .sp-k { width: 64px; } .statuspop .theme button { padding: 0 7px; } }
1265
+
1266
+ /* 0.6.3: iOS Safari zooms the page when a focused field's text is under 16px.
1267
+ On touch and small screens every text field is at least 16px, with padding
1268
+ trimmed where the bigger text would make a row taller. Fields that are
1269
+ already bigger (the sign-in code, search, pairing) keep their size. Page
1270
+ zoom itself stays on (no maximum-scale / user-scalable in the viewport).
1271
+ :where() keeps the catch-all at zero specificity so the bigger ones below win.
1272
+ test/unit/ui-ios-zoom.test.mjs guards this block. */
1273
+ @media (hover: none), (max-width: 700px) {
1274
+ :where(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]):not([type=file]):not([type=hidden]),
1275
+ textarea, select, [contenteditable]:not([contenteditable=false])) { font-size: 16px !important; }
1276
+ .empty.login .codeform input { font-size: 22px !important; }
1277
+ .cmdk-field input, .pairbox input { font-size: 17px !important; }
1278
+ .addform input { padding: 5px 10px; }
1279
+ .deny-form input, .need .qother, .reply-text { padding: 6px 9px; }
1280
+ .card .title input { padding: 2px 6px; }
1281
+ .standup-out textarea { line-height: 1.4; }
1282
+ }