sealkeep 0.9.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/ARCHITECTURE.md +163 -14
  2. package/CHANGELOG.md +252 -1
  3. package/CONTROL_PLANE.md +2 -2
  4. package/LICENSE +1 -1
  5. package/README.md +108 -22
  6. package/THIRD_PARTY.md +2 -2
  7. package/THREAT_MODEL.md +23 -4
  8. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/chunk-access.d.ts +26 -4
  9. package/dist/packages/sealkeep-crypto/src/chunk-access.js +219 -0
  10. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/envelope.d.ts +11 -1
  11. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/envelope.js +58 -21
  12. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/format.d.ts +2 -2
  13. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/index.d.ts +1 -0
  14. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/index.js +1 -0
  15. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/recipients.d.ts +1 -0
  16. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/recipients.js +53 -13
  17. package/dist/packages/sealkeep-crypto/src/squeeze.d.ts +6 -0
  18. package/dist/packages/sealkeep-crypto/src/squeeze.js +39 -0
  19. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/stream.d.ts +36 -3
  20. package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/stream.js +196 -37
  21. package/dist/site/index.html +1808 -1904
  22. package/dist/site/llms.txt +67 -0
  23. package/dist/site/trust/architecture-data-flow.html +53 -0
  24. package/dist/site/trust/audit-roadmap.html +37 -0
  25. package/dist/site/trust/deployment-responsibility.html +11 -0
  26. package/dist/site/trust/dpa-sample.html +30 -0
  27. package/dist/site/trust/release-provenance.html +21 -0
  28. package/dist/site/trust/subprocessors.html +15 -0
  29. package/dist/site/trust/threat-model.html +34 -0
  30. package/dist/site/trust/toms.html +41 -0
  31. package/dist/site/trust-document.css +32 -0
  32. package/dist/site/trust.html +73 -0
  33. package/dist/site/visual/assets/index-8Nxnkc7o.js +207 -0
  34. package/dist/site/visual/assets/index-oxLy1bpy.css +1 -0
  35. package/dist/site/visual/index.html +18 -0
  36. package/dist/site.zip +0 -0
  37. package/dist/src/activity.d.ts +9 -0
  38. package/dist/src/activity.js +90 -1
  39. package/dist/src/adapters.d.ts +175 -5
  40. package/dist/src/adapters.js +961 -73
  41. package/dist/src/agent-context.d.ts +135 -0
  42. package/dist/src/agent-context.js +1059 -0
  43. package/dist/src/archive-copies.d.ts +47 -0
  44. package/dist/src/archive-copies.js +179 -0
  45. package/dist/src/audit.d.ts +1 -1
  46. package/dist/src/audit.js +29 -4
  47. package/dist/src/autopilot.d.ts +52 -7
  48. package/dist/src/autopilot.js +143 -25
  49. package/dist/src/background-bandwidth.d.ts +46 -0
  50. package/dist/src/background-bandwidth.js +301 -0
  51. package/dist/src/background-cpu.d.ts +82 -0
  52. package/dist/src/background-cpu.js +212 -0
  53. package/dist/src/background-worker-error.d.ts +12 -0
  54. package/dist/src/background-worker-error.js +18 -0
  55. package/dist/src/branding.d.ts +24 -1
  56. package/dist/src/branding.js +31 -1
  57. package/dist/src/bridge.d.ts +233 -0
  58. package/dist/src/bridge.js +604 -0
  59. package/dist/src/byte-stream.d.ts +91 -0
  60. package/dist/src/byte-stream.js +385 -0
  61. package/dist/src/chunk-store.d.ts +41 -8
  62. package/dist/src/chunk-store.js +161 -65
  63. package/dist/src/cli.js +1698 -163
  64. package/dist/src/cloud.d.ts +841 -31
  65. package/dist/src/cloud.js +3196 -277
  66. package/dist/src/context-background.d.ts +37 -0
  67. package/dist/src/context-background.js +309 -0
  68. package/dist/src/context-drain-child.d.ts +1 -0
  69. package/dist/src/context-drain-child.js +98 -0
  70. package/dist/src/context-reader.d.ts +118 -0
  71. package/dist/src/context-reader.js +447 -0
  72. package/dist/src/control-plane/auth.d.ts +32 -4
  73. package/dist/src/control-plane/auth.js +85 -24
  74. package/dist/src/control-plane/server.js +19 -6
  75. package/dist/src/control-plane.d.ts +17 -1
  76. package/dist/src/control-plane.js +32 -6
  77. package/dist/src/crypto.d.ts +1 -1
  78. package/dist/src/crypto.js +5 -5
  79. package/dist/src/daemon-lease.d.ts +70 -0
  80. package/dist/src/daemon-lease.js +420 -0
  81. package/dist/src/daemon.d.ts +94 -1
  82. package/dist/src/daemon.js +1082 -105
  83. package/dist/src/darwin-service-policy.d.ts +41 -0
  84. package/dist/src/darwin-service-policy.js +60 -0
  85. package/dist/src/dashboard-cli.js +15 -15
  86. package/dist/src/device-authorization.d.ts +37 -0
  87. package/dist/src/device-authorization.js +199 -0
  88. package/dist/src/device-enrollment.d.ts +91 -0
  89. package/dist/src/device-enrollment.js +349 -0
  90. package/dist/src/disk.d.ts +17 -12
  91. package/dist/src/disk.js +43 -17
  92. package/dist/src/doctor.d.ts +35 -1
  93. package/dist/src/doctor.js +332 -41
  94. package/dist/src/durable-ticket-lock.d.ts +24 -0
  95. package/dist/src/durable-ticket-lock.js +232 -0
  96. package/dist/src/enroll.d.ts +1 -1
  97. package/dist/src/enroll.js +13 -7
  98. package/dist/src/env.d.ts +10 -1
  99. package/dist/src/env.js +11 -3
  100. package/dist/src/errors.d.ts +8 -8
  101. package/dist/src/errors.js +6 -6
  102. package/dist/src/flush.d.ts +12 -0
  103. package/dist/src/flush.js +37 -0
  104. package/dist/src/heartbeat.d.ts +86 -12
  105. package/dist/src/heartbeat.js +415 -29
  106. package/dist/src/index-background-watchdog.d.ts +1 -0
  107. package/dist/src/index-background-watchdog.js +94 -0
  108. package/dist/src/index-background-work.d.ts +21 -0
  109. package/dist/src/index-background-work.js +25 -0
  110. package/dist/src/index-background.d.ts +64 -0
  111. package/dist/src/index-background.js +394 -0
  112. package/dist/src/index-build-child.d.ts +1 -0
  113. package/dist/src/index-build-child.js +109 -0
  114. package/dist/src/index-manifest.d.ts +52 -0
  115. package/dist/src/index-manifest.js +444 -0
  116. package/dist/src/index-publication-proof.d.ts +84 -0
  117. package/dist/src/index-publication-proof.js +380 -0
  118. package/dist/src/index-publication-state.d.ts +149 -0
  119. package/dist/src/index-publication-state.js +696 -0
  120. package/dist/src/index-publication-verifier.d.ts +89 -0
  121. package/dist/src/index-publication-verifier.js +341 -0
  122. package/dist/src/index-publish.d.ts +62 -0
  123. package/dist/src/index-publish.js +540 -0
  124. package/dist/src/index-scratch-cleanup.d.ts +19 -0
  125. package/dist/src/index-scratch-cleanup.js +166 -0
  126. package/dist/src/index-segment-types.d.ts +132 -0
  127. package/dist/src/index-segment-types.js +21 -0
  128. package/dist/src/index-segments.d.ts +9 -0
  129. package/dist/src/index-segments.js +516 -0
  130. package/dist/src/index-store.d.ts +123 -0
  131. package/dist/src/index-store.js +495 -0
  132. package/dist/src/index-sync.d.ts +91 -15
  133. package/dist/src/index-sync.js +286 -53
  134. package/dist/src/index-upgrade-publication.d.ts +30 -0
  135. package/dist/src/index-upgrade-publication.js +179 -0
  136. package/dist/src/integration-manager.d.ts +32 -0
  137. package/dist/src/integration-manager.js +394 -0
  138. package/dist/src/leakscan.js +1 -1
  139. package/dist/src/local-api.d.ts +56 -15
  140. package/dist/src/local-api.js +4979 -541
  141. package/dist/src/machine-settings.d.ts +51 -0
  142. package/dist/src/machine-settings.js +166 -0
  143. package/dist/src/managed-chunks.d.ts +5 -2
  144. package/dist/src/managed-chunks.js +14 -14
  145. package/dist/src/mcp-install.d.ts +11 -9
  146. package/dist/src/mcp-install.js +73 -28
  147. package/dist/src/mcp-workspace.d.ts +18 -0
  148. package/dist/src/mcp-workspace.js +50 -0
  149. package/dist/src/mcp.js +294 -25
  150. package/dist/src/migrate.js +27 -21
  151. package/dist/src/notify.d.ts +1 -1
  152. package/dist/src/notify.js +5 -5
  153. package/dist/src/offload.d.ts +201 -14
  154. package/dist/src/offload.js +1848 -140
  155. package/dist/src/onboarding.d.ts +8 -1
  156. package/dist/src/onboarding.js +4 -4
  157. package/dist/src/packages.d.ts +2 -2
  158. package/dist/src/packages.js +10 -2
  159. package/dist/src/passkey.d.ts +0 -1
  160. package/dist/src/passkey.js +2 -7
  161. package/dist/src/password-lock.d.ts +2 -2
  162. package/dist/src/password-lock.js +6 -6
  163. package/dist/src/paths.d.ts +2 -0
  164. package/dist/src/paths.js +2 -0
  165. package/dist/src/presence.d.ts +86 -0
  166. package/dist/src/presence.js +240 -0
  167. package/dist/src/progress-deadline.d.ts +21 -0
  168. package/dist/src/progress-deadline.js +91 -0
  169. package/dist/src/project-repair.d.ts +55 -0
  170. package/dist/src/project-repair.js +131 -0
  171. package/dist/src/providers/gcs.d.ts +28 -7
  172. package/dist/src/providers/gcs.js +35 -24
  173. package/dist/src/providers/gdrive.d.ts +71 -8
  174. package/dist/src/providers/gdrive.js +223 -50
  175. package/dist/src/providers/index.d.ts +11 -3
  176. package/dist/src/providers/index.js +30 -10
  177. package/dist/src/providers/s3.d.ts +30 -8
  178. package/dist/src/providers/s3.js +41 -30
  179. package/dist/src/providers/safe-storage-fetch.d.ts +12 -0
  180. package/dist/src/providers/safe-storage-fetch.js +72 -0
  181. package/dist/src/queue.d.ts +136 -19
  182. package/dist/src/queue.js +862 -96
  183. package/dist/src/reclaim-transaction.d.ts +156 -0
  184. package/dist/src/reclaim-transaction.js +1027 -0
  185. package/dist/src/recovery-codes.d.ts +32 -0
  186. package/dist/src/recovery-codes.js +338 -0
  187. package/dist/src/recovery.js +12 -9
  188. package/dist/src/rehydrate.d.ts +25 -22
  189. package/dist/src/rehydrate.js +319 -23
  190. package/dist/src/restore.d.ts +57 -4
  191. package/dist/src/restore.js +272 -36
  192. package/dist/src/resume-stub.d.ts +92 -0
  193. package/dist/src/resume-stub.js +417 -0
  194. package/dist/src/retention.d.ts +98 -7
  195. package/dist/src/retention.js +1066 -62
  196. package/dist/src/rotate.js +3 -3
  197. package/dist/src/search.d.ts +566 -8
  198. package/dist/src/search.js +5940 -297
  199. package/dist/src/secrets.d.ts +51 -7
  200. package/dist/src/secrets.js +316 -24
  201. package/dist/src/service.d.ts +49 -11
  202. package/dist/src/service.js +776 -35
  203. package/dist/src/share.js +3 -3
  204. package/dist/src/shared-spaces.d.ts +98 -0
  205. package/dist/src/shared-spaces.js +214 -0
  206. package/dist/src/source-reader.d.ts +73 -0
  207. package/dist/src/source-reader.js +715 -0
  208. package/dist/src/spool.d.ts +1 -1
  209. package/dist/src/spool.js +1 -1
  210. package/dist/src/start-tui.js +2 -1
  211. package/dist/src/start.js +2 -2
  212. package/dist/src/storage-endpoint.d.ts +21 -0
  213. package/dist/src/storage-endpoint.js +122 -0
  214. package/dist/src/storage-setup.js +12 -12
  215. package/dist/src/storage-targets.d.ts +109 -6
  216. package/dist/src/storage-targets.js +975 -67
  217. package/dist/src/stream-to-cloud.d.ts +5 -1
  218. package/dist/src/stream-to-cloud.js +34 -14
  219. package/dist/src/sync-rules.d.ts +31 -6
  220. package/dist/src/sync-rules.js +153 -14
  221. package/dist/src/team-backfill-scheduling.d.ts +8 -0
  222. package/dist/src/team-backfill-scheduling.js +33 -0
  223. package/dist/src/team-backfill.d.ts +116 -0
  224. package/dist/src/team-backfill.js +1429 -0
  225. package/dist/src/team-index-cache.d.ts +16 -0
  226. package/dist/src/team-index-cache.js +152 -0
  227. package/dist/src/team-offboarding.d.ts +38 -0
  228. package/dist/src/team-offboarding.js +1043 -0
  229. package/dist/src/team-presence.d.ts +127 -0
  230. package/dist/src/team-presence.js +904 -0
  231. package/dist/src/team-publication-policy.d.ts +20 -0
  232. package/dist/src/team-publication-policy.js +140 -0
  233. package/dist/src/team-realtime.d.ts +68 -0
  234. package/dist/src/team-realtime.js +816 -0
  235. package/dist/src/team-source-facts-cache.d.ts +23 -0
  236. package/dist/src/team-source-facts-cache.js +255 -0
  237. package/dist/src/trash.d.ts +1 -1
  238. package/dist/src/trash.js +2 -2
  239. package/dist/src/tui.js +11 -12
  240. package/dist/src/types.d.ts +173 -7
  241. package/dist/src/types.js +20 -0
  242. package/dist/src/ui-server.d.ts +163 -35
  243. package/dist/src/ui-server.js +712 -72
  244. package/dist/src/ui.d.ts +1 -2
  245. package/dist/src/ui.js +1 -2
  246. package/dist/src/upload.d.ts +27 -0
  247. package/dist/src/upload.js +383 -43
  248. package/dist/src/vault.d.ts +226 -30
  249. package/dist/src/vault.js +1776 -192
  250. package/dist/src/watcher.d.ts +7 -1
  251. package/dist/src/watcher.js +198 -55
  252. package/dist/src/worker.d.ts +27 -3
  253. package/dist/src/worker.js +274 -55
  254. package/package.json +33 -12
  255. package/scripts/native-reboot-rehearsal.mjs +90 -0
  256. package/web/app.js +6032 -343
  257. package/web/bootstrap.js +17 -0
  258. package/web/index.html +255 -57
  259. package/web/rail.js +317 -40
  260. package/web/retention.html +2 -2
  261. package/web/rules-view.js +188 -16
  262. package/web/sessions-view.js +485 -62
  263. package/web/sessions.html +2 -2
  264. package/web/setup-api.js +152 -29
  265. package/web/setup-logic.js +68 -9
  266. package/web/setup.html +113 -44
  267. package/web/setup.js +604 -71
  268. package/web/style.css +513 -98
  269. package/dist/packages/vaultline-crypto/src/chunk-access.js +0 -93
  270. /package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/aead.d.ts +0 -0
  271. /package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/aead.js +0 -0
  272. /package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/format.js +0 -0
  273. /package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/sha256-stream.d.ts +0 -0
  274. /package/dist/packages/{vaultline-crypto → sealkeep-crypto}/src/sha256-stream.js +0 -0
package/web/style.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Vaultline dashboard.
2
+ * Sealkeep dashboard.
3
3
  *
4
4
  * Two worlds, one rule between them. Above the line is what you can still read:
5
5
  * source paths, agent names, sizes. Below it is what only you can open. The
@@ -11,16 +11,16 @@
11
11
 
12
12
  :root {
13
13
  /* @tokens:start — generated from design-system/tokens.css, do not edit here */
14
- --paper: #f4f4f3;
15
- --card: #fbfbfa;
16
- --ink: #111316;
17
- --soft: #5e646c;
18
- --rule: #dadcde;
19
- --seal: #101a3d;
20
- --seal-ink: #96a6e0;
21
- --live: #2a3fb0;
22
- --warn: #8c3220;
23
- --warn-bg: #f4e6e2;
14
+ --paper: #161311;
15
+ --card: #1e1a17;
16
+ --ink: #f0ede6;
17
+ --soft: #9a948a;
18
+ --rule: #2e2a24;
19
+ --seal: #100e0b;
20
+ --seal-ink: #e8c793;
21
+ --live: #e3a455;
22
+ --warn: #e06c4f;
23
+ --warn-bg: #33201a;
24
24
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, "Helvetica Neue", sans-serif;
25
25
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "DejaVu Sans Mono", Consolas, monospace;
26
26
  /* @tokens:end */
@@ -29,20 +29,26 @@
29
29
  resolve to the system's colours rather than a second palette. Kept outside
30
30
  the generated block on purpose — the token file describes the design
31
31
  system, this describes one surface's history. */
32
+ color-scheme: dark;
33
+
32
34
  /* Layout constants for this surface, not part of the shared palette. */
33
35
  --rail: 264px;
34
36
  --gap: 20px;
35
37
  --panel: var(--card);
36
- --rule-soft: #e6e7e9;
38
+ --rule-soft: #262220;
37
39
  --text: var(--ink);
38
40
  --text-2: var(--soft);
39
- --text-3: #8b9099;
41
+ --text-3: #6e6960;
40
42
  --signal: var(--live);
41
- --verified: var(--live);
42
- --held: var(--soft);
43
+ /* v2: `ok` is terminal-green, distinct from the amber accent — a verified
44
+ state and an interactive affordance must never share a colour. */
45
+ --verified: #4cbf7a;
46
+ --held: #c7a16b;
43
47
  --alert: var(--warn);
44
48
  --ink-2: var(--ink);
45
49
  --ink-3: var(--soft);
50
+ --rail-active: #26211c;
51
+ --rail-glyph: #6e6960;
46
52
  }
47
53
 
48
54
  /* ── Dark ─────────────────────────────────────────────── */
@@ -59,35 +65,15 @@
59
65
  * The rail is already near-black in both themes, which is what lets the dark
60
66
  * palette stay a change of ground rather than a redesign.
61
67
  */
62
- @media (prefers-color-scheme: dark) {
63
- :root {
64
- --paper: #0d0f11;
65
- --card: #14171a;
66
- --ink: #e7e9ec;
67
- --soft: #8d949c;
68
- --rule: #24282d;
69
- --seal: #111c44;
70
- --seal-ink: #a2b2ea;
71
- --live: #8195f2;
72
- --warn: #d97a62;
73
- --warn-bg: #2b1a16;
74
-
75
- --rule-soft: #1e2226;
76
- --text-3: #6f757d;
77
- --rail-active: #1c2024;
78
- --rail-glyph: #7d838b;
79
- }
80
-
81
- /* Form fields take an explicit ground so they are not blind on a dark page. */
82
- input[type="text"], input[type="number"], input[type="password"],
83
- input[type="search"], textarea, select {
84
- background: var(--card);
85
- border-color: var(--rule);
86
- color: var(--ink);
87
- }
88
- .check-fail { background: var(--warn-bg); }
89
- tbody tr:hover { background: rgba(129, 149, 242, 0.08); }
68
+ /* Sealkeep v2 is one committed dark look — no theme fork. Form fields take an
69
+ explicit ground so they never inherit a host colour. */
70
+ input[type="text"], input[type="number"], input[type="password"],
71
+ input[type="search"], textarea, select {
72
+ background: var(--card);
73
+ border-color: var(--rule);
74
+ color: var(--ink);
90
75
  }
76
+ tbody tr:hover { background: color-mix(in srgb, var(--live) 7%, transparent); }
91
77
 
92
78
  * { box-sizing: border-box; }
93
79
 
@@ -95,7 +81,7 @@ body {
95
81
  margin: 0;
96
82
  display: flex;
97
83
  min-height: 100vh;
98
- background: var(--paper);
84
+ background: radial-gradient(1100px 480px at 50% -120px, color-mix(in srgb, var(--live) 7%, var(--paper)) 0%, var(--paper) 62%) fixed, var(--paper);
99
85
  color: var(--text);
100
86
  font-family: var(--sans);
101
87
  font-size: 14px;
@@ -126,6 +112,8 @@ aside {
126
112
  font-weight: 700;
127
113
  }
128
114
  .brand span { color: var(--live); margin-right: 6px; }
115
+ .brand-block { display: grid; gap: 8px; }
116
+ .brand-block .surface-refresh { padding: 0 12px; }
129
117
 
130
118
  nav { display: grid; gap: 2px; }
131
119
  /* The Sessions entry is an anchor rather than a view button, so it inherits
@@ -184,6 +172,7 @@ main {
184
172
  }
185
173
 
186
174
  header { margin-bottom: 30px; }
175
+ .headline-row { display: flex; align-items: center; gap: 14px; }
187
176
 
188
177
  h1 {
189
178
  font-family: var(--mono);
@@ -193,6 +182,12 @@ h1 {
193
182
  font-weight: 700;
194
183
  margin: 0 0 8px;
195
184
  }
185
+ .headline-row h1 { margin-bottom: 8px; }
186
+ .surface-refresh { display: inline-flex; align-items: center; gap: 7px; color: var(--soft); font: 500 11px var(--mono); white-space: nowrap; }
187
+ .surface-refresh[hidden] { display: none; }
188
+ .surface-spinner { width: 11px; height: 11px; border: 1.5px solid var(--rule); border-top-color: var(--live); border-radius: 50%; animation: surface-spin .75s linear infinite; }
189
+ @keyframes surface-spin { to { transform: rotate(360deg); } }
190
+ @media (prefers-reduced-motion: reduce) { .surface-spinner { animation: pulse 1.1s ease-in-out infinite; } }
196
191
  .lede { margin: 0; color: var(--text-2); max-width: 62ch; }
197
192
 
198
193
  /* Section labels are "a rule plus a word": a short hairline in the accent, then
@@ -255,7 +250,7 @@ h2::before, h3::before {
255
250
 
256
251
  .metrics {
257
252
  display: grid;
258
- grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
253
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
259
254
  gap: var(--gap);
260
255
  }
261
256
  .metric {
@@ -318,18 +313,19 @@ td.muted { color: var(--text-3); }
318
313
  white-space: nowrap;
319
314
  border: 1px solid transparent;
320
315
  }
321
- .badge-verified { color: var(--verified); background: #e9f4ec; border-color: #c6e3d0; }
322
- .badge-local { color: var(--text-3); background: #f1efec; border-color: var(--rule); }
323
- .badge-held { color: var(--held); background: #fbf3e2; border-color: #eddcb6; }
324
- .badge-free { color: var(--signal); background: #eaf0ff; border-color: #c6d6ff; }
325
- .badge-alert { color: var(--alert); background: #fbeeeb; border-color: #eecabf; }
316
+ .badge-verified { color: color-mix(in srgb, var(--verified) 55%, var(--ink)); background: color-mix(in srgb, var(--verified) 10%, var(--card)); border-color: color-mix(in srgb, var(--verified) 26%, var(--card)); }
317
+ .badge-local { color: var(--text-3); background: color-mix(in srgb, var(--soft) 8%, var(--card)); border-color: var(--rule); }
318
+ .badge-held { color: var(--held); background: color-mix(in srgb, var(--held) 12%, var(--card)); border-color: color-mix(in srgb, var(--held) 30%, var(--card)); }
319
+ .badge-free { color: var(--signal); background: color-mix(in srgb, var(--signal) 9%, var(--card)); border-color: color-mix(in srgb, var(--signal) 24%, var(--card)); }
320
+ .badge-alert { color: var(--alert); background: color-mix(in srgb, var(--alert) 10%, var(--card)); border-color: color-mix(in srgb, var(--alert) 26%, var(--card)); }
326
321
 
327
322
  /* ── Checks ───────────────────────────────────────────── */
328
323
 
329
324
  .check {
330
325
  display: grid;
331
- grid-template-columns: 160px 1fr;
326
+ grid-template-columns: 160px minmax(0, 1fr) auto;
332
327
  gap: 16px;
328
+ align-items: center;
333
329
  padding: 13px 18px;
334
330
  border-bottom: 1px solid var(--rule-soft);
335
331
  border-left: 3px solid transparent;
@@ -338,6 +334,22 @@ td.muted { color: var(--text-3); }
338
334
  .check:last-child { border-bottom: 0; }
339
335
  .check strong { font: 600 12.5px var(--mono); }
340
336
  .check span { color: var(--text-2); }
337
+ .check .health-action {
338
+ justify-self: end;
339
+ white-space: nowrap;
340
+ }
341
+ .health-integrity-note {
342
+ display: block;
343
+ margin-top: 6px;
344
+ color: var(--text-3);
345
+ line-height: 1.5;
346
+ }
347
+ .health-actions {
348
+ display: flex;
349
+ justify-content: flex-end;
350
+ gap: 6px;
351
+ flex-wrap: wrap;
352
+ }
341
353
  .check-pass { border-left-color: var(--verified); }
342
354
  /* A warn is where inaction loses data — "if this machine is lost, the archives
343
355
  on it cannot be opened by anyone, including us". It was drawn in --held,
@@ -345,7 +357,7 @@ td.muted { color: var(--text-3); }
345
357
  needing attention looked like nothing was wrong. --warn is exactly what the
346
358
  design system reserves for this. */
347
359
  .check-warn { border-left-color: var(--warn); background: var(--warn-bg); }
348
- .check-fail { border-left-color: var(--alert); background: #fdf4f2; }
360
+ .check-fail { border-left-color: var(--alert); background: var(--warn-bg); }
349
361
 
350
362
  /* A failed job is the row in the queue that needs a person. It was rendered
351
363
  with a class no rule matched, so it read as ordinary text beside states that
@@ -370,18 +382,18 @@ td.muted { color: var(--text-3); }
370
382
 
371
383
  button.action {
372
384
  appearance: none;
373
- font: 600 13px var(--mono);
374
- padding: 9px 16px;
375
- border-radius: 3px;
376
- border: 1px solid var(--signal);
377
- background: transparent;
378
- color: var(--signal);
385
+ font: 600 13px var(--sans);
386
+ padding: 9px 18px;
387
+ border-radius: 10px;
388
+ border: 1px solid transparent;
389
+ background: var(--signal);
390
+ color: var(--paper);
379
391
  cursor: pointer;
380
- transition: background 120ms ease, color 120ms ease;
392
+ transition: filter 120ms ease;
381
393
  }
382
- button.action:hover { background: var(--signal); color: #fff; }
383
- button.action.danger { border-color: var(--alert); color: var(--alert); }
384
- button.action.danger:hover { background: var(--alert); color: #fff; }
394
+ button.action:hover { filter: brightness(1.08); }
395
+ button.action.danger { background: transparent; border-color: var(--alert); color: var(--alert); }
396
+ button.action.danger:hover { background: var(--alert); color: var(--paper); filter: none; }
385
397
  button.action:disabled { border-color: var(--rule); color: var(--text-3); cursor: not-allowed; background: transparent; }
386
398
 
387
399
  .row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
@@ -389,19 +401,44 @@ button.action:disabled { border-color: var(--rule); color: var(--text-3); cursor
389
401
  .actions { display: flex; gap: 10px; flex-wrap: wrap; }
390
402
  .note { font-size: 12.5px; color: var(--text-3); margin: 0; line-height: 1.6; }
391
403
  .pad { padding: 20px; display: grid; gap: 14px; }
404
+ .focus-target {
405
+ border-color: var(--signal) !important;
406
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--signal) 20%, transparent), 0 16px 44px #0005;
407
+ transition: border-color .2s, box-shadow .2s;
408
+ }
392
409
 
393
410
  /* ── Form fields: the settings screen is the first editable surface,
394
411
  so text/number/select/textarea inherit the token input's own look
395
412
  rather than the browser default. ───────────────────────────────── */
396
413
 
397
414
  .field { display: grid; gap: 6px; }
415
+ .automation-checks {
416
+ display: grid;
417
+ gap: 0;
418
+ margin: 4px 0 8px;
419
+ border-top: 1px solid var(--rule-soft);
420
+ border-bottom: 1px solid var(--rule-soft);
421
+ }
422
+ .automation-check {
423
+ display: grid;
424
+ grid-template-columns: minmax(140px, .7fr) minmax(210px, 1.3fr);
425
+ gap: 16px;
426
+ padding: 8px 0;
427
+ font: 12px/1.45 var(--mono);
428
+ }
429
+ .automation-check + .automation-check { border-top: 1px solid var(--rule-soft); }
430
+ .automation-check .label { color: var(--ink); }
431
+ .automation-check .value { color: var(--soft); }
432
+ .automation-check.good .value { color: var(--verified); }
433
+ .automation-check.warn .value { color: var(--warn); }
434
+ @media (max-width: 720px) {
435
+ .automation-check { grid-template-columns: 1fr; gap: 2px; }
436
+ }
398
437
  /* :not(.opt) rather than letting .opt override after the cascade: a checkbox
399
438
  row is a label too, and this keeps the two from fighting over specificity. */
400
439
  .field > label:not(.opt) {
401
440
  font-family: var(--mono);
402
- font-size: 11px;
403
- text-transform: uppercase;
404
- letter-spacing: 0.1em;
441
+ font-size: 12px;
405
442
  color: var(--text-3);
406
443
  font-weight: 600;
407
444
  }
@@ -411,8 +448,8 @@ input[type="text"], input[type="number"], input[type="password"], textarea, sele
411
448
  font: 13px var(--mono);
412
449
  padding: 9px 11px;
413
450
  border: 1px solid var(--rule);
414
- border-radius: 3px;
415
- background: #fff;
451
+ border-radius: 10px;
452
+ background: var(--card);
416
453
  color: var(--text);
417
454
  width: 100%;
418
455
  }
@@ -446,7 +483,7 @@ form h3:first-child { margin-top: 0; }
446
483
  .empty code, code {
447
484
  font-family: var(--mono);
448
485
  font-size: 12px;
449
- background: #efece7;
486
+ background: color-mix(in srgb, var(--soft) 10%, var(--card));
450
487
  border: 1px solid var(--rule);
451
488
  border-radius: 3px;
452
489
  padding: 2px 6px;
@@ -456,17 +493,7 @@ form h3:first-child { margin-top: 0; }
456
493
 
457
494
  .gate { max-width: 640px; }
458
495
  #token-form { display: flex; gap: 10px; flex-wrap: wrap; }
459
- #token-input {
460
- flex: 1;
461
- min-width: 240px;
462
- font: 13px var(--mono);
463
- padding: 10px 12px;
464
- border: 1px solid var(--rule);
465
- border-radius: 3px;
466
- background: #fff;
467
- color: var(--text);
468
- }
469
- #token-input:focus-visible, button:focus-visible, nav button:focus-visible,
496
+ button:focus-visible, nav button:focus-visible,
470
497
  input:focus-visible, textarea:focus-visible, select:focus-visible {
471
498
  outline: 2px solid var(--signal);
472
499
  outline-offset: 2px;
@@ -490,7 +517,7 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
490
517
  background: var(--text-3);
491
518
  }
492
519
  .pill.ok::before { background: var(--verified); }
493
- .pill.warn::before { background: var(--held); }
520
+ .pill.warn::before { background: var(--warn); }
494
521
  .pill.busy::before { background: var(--signal); animation: pulse 1.1s ease-in-out infinite; }
495
522
 
496
523
  @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@@ -602,6 +629,102 @@ footer b { font: 600 12.5px var(--mono); color: var(--text-2); display: block; m
602
629
  .acct-facts li.warn .dot { background: var(--warn); }
603
630
  .acct-facts b { color: var(--ink); font-weight: 600; }
604
631
 
632
+ /* ---- panel review pass (2026-08-24): both critics' directives ---- */
633
+
634
+ /* A button label is a word, never a column of letters. */
635
+ button.action { white-space: nowrap; }
636
+
637
+ /* The vault's action cell: one primary action plus an overflow menu. */
638
+ .actions-cell { white-space: nowrap; }
639
+ .actions-cell .rowmenu { display: inline-block; position: relative; margin-left: 6px; vertical-align: middle; }
640
+ .rowmenu > summary { list-style: none; cursor: pointer; border: 1px solid var(--rule); border-radius: 3px; padding: 4px 10px; font-family: var(--mono); font-size: 13px; user-select: none; }
641
+ .rowmenu > summary::-webkit-details-marker { display: none; }
642
+ .rowmenu[open] > summary { background: var(--panel); }
643
+ .rowmenu-list { position: absolute; right: 0; z-index: 30; margin-top: 4px; background: var(--panel); border: 1px solid var(--rule); border-radius: 3px; padding: 8px; display: flex; flex-direction: column; gap: 6px; min-width: 200px; box-shadow: 0 8px 24px rgba(20, 26, 34, 0.14); }
644
+ .rowmenu-list .act-note { max-width: 260px; white-space: normal; }
645
+ .archive-transfer { display: grid; grid-template-columns: repeat(3, minmax(160px, 1fr)); gap: 10px 12px; margin: 0 0 12px; padding: 14px; border: 1px solid color-mix(in srgb, var(--signal) 38%, var(--rule)); border-radius: 5px; background: color-mix(in srgb, var(--signal) 4%, var(--panel)); }
646
+ .archive-transfer select { width: 100%; min-width: 0; padding: 8px 9px; border: 1px solid var(--rule); border-radius: 3px; background: var(--panel); color: var(--ink); font: 600 12px var(--mono); }
647
+ .archive-transfer .action { margin: 0; }
648
+ .transfer-heading { grid-column: 1 / -1; display: flex; align-items: baseline; justify-content: space-between; gap: 18px; }
649
+ .transfer-heading strong { font: 650 14px var(--sans); color: var(--ink); }
650
+ .transfer-heading .note { text-align: right; }
651
+ .transfer-field { display: grid; gap: 5px; color: var(--text-3); font: 600 11px var(--mono); }
652
+ .archive-transfer > .note { grid-column: 1 / -1; }
653
+ .transfer-maintenance { grid-column: 1 / -1; margin-top: 2px; padding-top: 9px; border-top: 1px solid var(--rule); }
654
+ .transfer-maintenance summary { cursor: pointer; color: var(--text-3); font: 600 11px var(--mono); }
655
+ .transfer-maintenance[open] summary { color: var(--ink); }
656
+ .transfer-maintenance p { margin: 8px 0; max-width: 74ch; }
657
+ .transfer-maintenance .action { margin-right: 6px; }
658
+ .vault-table td:nth-child(5) .badge { margin: 2px 3px 2px 0; }
659
+ .vault-table td:nth-child(5) small { display: block; margin-top: 3px; }
660
+
661
+ /* Seven columns need a budget, not an improvisation per render. */
662
+ .vault-table { table-layout: fixed; width: 100%; }
663
+ .vault-table td { overflow: hidden; }
664
+ .vault-table .archive-size { white-space: nowrap; font-size: 12px; }
665
+ .vault-table th { overflow: hidden; text-overflow: ellipsis; }
666
+ /* The size column is deliberately two short lines. Letting its former long
667
+ label overflow a fixed 124px budget fused it with SESSION at laptop widths. */
668
+ .vault-table th.vault-size-heading { line-height: 1.35; vertical-align: bottom; white-space: normal; }
669
+ .vault-table th.vault-size-heading span { display: block; white-space: nowrap; }
670
+
671
+ /* Search, location and ordering for a 1,035-row vault. The location choices
672
+ wrap as one compact control instead of turning the library into five tabs. */
673
+ .vault-tools { display: grid; grid-template-columns: minmax(220px, 1fr) auto auto; gap: 10px 14px; align-items: center; padding: 12px; border-bottom: 1px solid var(--rule); background: color-mix(in srgb, var(--panel) 74%, transparent); }
674
+ .vault-find { margin: 0; }
675
+ .vault-find input { width: 100%; font-family: var(--mono); font-size: 13px; padding: 9px 12px; border: 1px solid var(--rule); border-radius: 3px; background: var(--panel); }
676
+ .vault-locations { display: flex; flex-wrap: wrap; gap: 4px; }
677
+ .vault-location { border: 1px solid var(--rule); border-radius: 999px; background: transparent; color: var(--text-2); padding: 6px 9px; font: 600 11px/1 var(--mono); cursor: pointer; white-space: nowrap; }
678
+ .vault-location:hover { color: var(--ink); border-color: var(--text-3); }
679
+ .vault-location.selected { color: var(--ink); border-color: var(--signal); background: color-mix(in srgb, var(--signal) 10%, var(--panel)); }
680
+ .vault-sort { color: var(--text-3); font: 600 11px var(--mono); white-space: nowrap; }
681
+ .vault-sort select { margin-left: 5px; border: 1px solid var(--rule); border-radius: 3px; background: var(--panel); color: var(--ink); padding: 7px 8px; font: 600 12px var(--mono); }
682
+ @media (max-width: 900px) {
683
+ .vault-tools { grid-template-columns: 1fr; align-items: stretch; }
684
+ .vault-sort select { width: calc(100% - 42px); }
685
+ .archive-transfer { grid-template-columns: 1fr; }
686
+ .transfer-heading { align-items: flex-start; flex-direction: column; gap: 5px; }
687
+ .transfer-heading .note { text-align: left; }
688
+ }
689
+ .vault-refresh { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; color: var(--text-3); font: 500 12px var(--mono); }
690
+ .vault-refresh::before { content: ""; width: 6px; height: 6px; flex: 0 0 6px; border-radius: 50%; background: var(--text-3); }
691
+ .vault-refresh.loading::before, .vault-refresh.updating::before, .vault-refresh.cached::before { background: var(--signal); animation: pulse 1.1s ease-in-out infinite; }
692
+ .vault-refresh.updated::before { background: var(--verified); }
693
+ .vault-refresh.failed::before { background: var(--warn); }
694
+
695
+ /* The card that says the truth about "off this machine" when nothing is. */
696
+ .metric.warn-card { border-color: color-mix(in srgb, var(--warn) 42%, var(--card)); background: color-mix(in srgb, var(--warn) 6%, var(--card)); }
697
+ .metric.warn-card b { color: var(--warn); }
698
+
699
+ /* The boundary strip: numbers first, caption second. */
700
+ .boundary b { color: var(--text-3); font-weight: 500; }
701
+ .boundary .side { color: inherit; font-weight: 600; }
702
+
703
+ /* Native fieldset chrome was the one stranger in the card language. */
704
+ fieldset { min-width: 0; border: 1px solid var(--rule); border-radius: 3px; padding: 14px 16px; margin: 0; }
705
+ #view-rules pre { max-width: 100%; white-space: pre-wrap; overflow-wrap: anywhere; }
706
+ #view-rules #copies-wrap { max-width: 100%; overflow-x: auto; }
707
+ legend { font-family: var(--mono); font-size: 13px; font-weight: 700; padding: 0 6px; }
708
+
709
+ /* A two-line rail fact keeps its bullet at the top, not floating mid-air. */
710
+ .acct-facts li { align-items: flex-start; }
711
+ .acct-facts li .dot { margin-top: 5px; }
712
+
713
+ /* Health's count means "things needing attention", not a neutral total. */
714
+ #count-health:not(:empty) { color: var(--warn); font-weight: 700; }
715
+
716
+ /* The ellipsis only engages when the name cannot wrap: the global td
717
+ word-break was breaking the filename INSIDE the truncating span. */
718
+ td.path .short { white-space: nowrap; }
719
+ /* Seven columns at ~700px cannot afford 18px side-padding per cell. */
720
+ .vault-table td, .vault-table th { padding-left: 10px; padding-right: 10px; }
721
+ /* The span's own cap must not exceed the column it lives in, or the cell
722
+ clips before the ellipsis can appear. */
723
+ .vault-table td.path .short { max-width: 100%; }
724
+ /* The overflow menu must escape its cell: td overflow-hidden was clipping the
725
+ open dropdown to a sliver. The actions column alone stays visible. */
726
+ .vault-table td.actions-cell { overflow: visible; position: relative; }
727
+
605
728
  /* ══ First run ═══════════════════════════════════════════════════════
606
729
  setup.html. Same rail, same rules, same two typefaces — a wizard that
607
730
  looked like a different product would undo the trust it exists to build.
@@ -625,11 +748,11 @@ h1:focus-visible { outline: 2px solid var(--signal); outline-offset: 4px; }
625
748
 
626
749
  nav.steps .step .glyph { font-variant-numeric: tabular-nums; width: 1.15em; text-align: center; }
627
750
  nav.steps .step.done .glyph { color: var(--verified); }
628
- nav.steps .step.current { background: var(--ink-2); color: #fff; }
751
+ nav.steps .step.current { background: var(--ink-2); color: var(--paper); }
629
752
  nav.steps .step.current .glyph { color: var(--signal); }
630
753
  nav.steps .step.locked { opacity: 0.42; cursor: default; }
631
754
  nav.steps .step.locked:hover { background: transparent; color: var(--soft); }
632
- nav.steps .step.locked.current:hover { background: var(--ink-2); color: #fff; }
755
+ nav.steps .step.locked.current:hover { background: var(--ink-2); color: var(--paper); }
633
756
 
634
757
  /* ── Screen one: one file's life, across the line ─────────── */
635
758
 
@@ -702,20 +825,25 @@ ul.plain b { color: var(--text); }
702
825
  }
703
826
  .wizfoot .note { max-width: 46ch; }
704
827
 
828
+ /* Every link is amber — the one interactive colour. Without this, anchors in
829
+ panel copy fall to the UA's dark blue, which vanishes on the v2 ground. */
830
+ a { color: var(--live); }
831
+ a:hover { color: color-mix(in srgb, var(--live) 80%, var(--ink)); }
832
+
705
833
  a.action {
706
834
  display: inline-block;
707
- font: 600 13px var(--mono);
708
- padding: 9px 16px;
709
- border-radius: 3px;
710
- border: 1px solid var(--signal);
711
- background: transparent;
712
- color: var(--signal);
835
+ font: 600 13px var(--sans);
836
+ padding: 9px 18px;
837
+ border-radius: 10px;
838
+ border: 1px solid transparent;
839
+ background: var(--signal);
840
+ color: var(--paper);
713
841
  text-decoration: none;
714
- transition: background 120ms ease, color 120ms ease;
842
+ transition: filter 120ms ease;
715
843
  }
716
- a.action:hover { background: var(--signal); color: #fff; }
717
- .action.primary { background: var(--signal); color: #fff; }
718
- .action.primary:hover { background: var(--ink-2); border-color: var(--ink-2); color: #fff; }
844
+ a.action:hover { filter: brightness(1.08); color: var(--paper); }
845
+ .action.primary { background: var(--signal); color: var(--paper); }
846
+ .action.primary:hover { filter: brightness(1.08); }
719
847
  /* A locked "Finish setup" is on screen the whole time someone is transcribing
720
848
  24 words, so it stays readable rather than fading to a hint of itself. */
721
849
  button.action.primary:disabled { background: var(--rule-soft); border-color: var(--rule); color: var(--text-2); }
@@ -736,7 +864,7 @@ button.action.primary:disabled { background: var(--rule-soft); border-color: var
736
864
  .agent-row input[type="checkbox"] { accent-color: var(--signal); width: 15px; height: 15px; flex-shrink: 0; }
737
865
  .agent-row input[type="checkbox"]:disabled + .agent-name { cursor: default; color: var(--text-2); }
738
866
  .agent-row.state-missing { opacity: 0.6; }
739
- .agent-row.state-unwritable { border-left: 3px solid var(--alert); padding-left: 15px; background: #fdf4f2; }
867
+ .agent-row.state-unwritable { border-left: 3px solid var(--alert); padding-left: 15px; background: var(--warn-bg); }
740
868
 
741
869
  /* ── Screen three: where archives go ──────────────────────── */
742
870
 
@@ -796,7 +924,8 @@ button.action.primary:disabled { background: var(--rule-soft); border-color: var
796
924
 
797
925
  @media print {
798
926
  aside, .wizfoot, .phrase-actions, #confirm-form, footer, main.wizard > .pill { display: none !important; }
799
- body { display: block; background: #fff; }
927
+ /* Physical paper, not the palette: print flips to dark-on-white. */
928
+ body { display: block; background: white; color: black; }
800
929
  main.wizard { padding: 0; max-width: none; }
801
930
  .phrase { break-inside: avoid; }
802
931
  }
@@ -807,17 +936,57 @@ button.action.primary:disabled { background: var(--rule-soft); border-color: var
807
936
 
808
937
  @media (max-width: 900px) {
809
938
  body { flex-direction: column; }
810
- aside { width: 100%; flex-direction: row; align-items: center; gap: 16px; padding: 12px 16px; overflow-x: auto; }
939
+ /* Tablet and phone share a two-row masthead: identity on top, the complete
940
+ navigation in its own horizontal scroller below. Keeping the account card
941
+ in the first row prevents its long fact sentences from flex-shrinking into
942
+ hundreds of wrapped lines and pushing the page heading below the fold. */
943
+ aside {
944
+ width: 100%; max-width: 100vw; min-width: 0;
945
+ display: grid;
946
+ grid-template-columns: auto minmax(0, 1fr);
947
+ grid-template-areas: "brand account" "nav nav";
948
+ align-items: center;
949
+ gap: 8px 14px;
950
+ padding: 10px 16px 8px;
951
+ overflow: hidden;
952
+ }
953
+ aside > .brand, aside > .brand-block { grid-area: brand; min-width: 0; }
954
+ aside > .acct {
955
+ grid-area: account;
956
+ min-width: 0;
957
+ display: flex;
958
+ align-items: center;
959
+ gap: 9px;
960
+ padding: 0;
961
+ border-bottom: 0;
962
+ }
963
+ /* Plan and account identity are useful in a compact header; detailed quota
964
+ facts remain available in Settings and must not consume the first viewport. */
965
+ aside > .acct .acct-meter,
966
+ aside > .acct .acct-usage,
967
+ aside > .acct .acct-facts,
968
+ aside > .acct .acct-door-slot { display: none; }
969
+ aside > .acct .acct-plan { flex: 0 0 auto; padding: 4px 8px; }
970
+ aside > .acct .acct-email { min-width: 0; max-width: 28ch; }
971
+ aside > nav {
972
+ grid-area: nav;
973
+ min-width: 0;
974
+ width: 100%;
975
+ overflow-x: auto;
976
+ scrollbar-width: thin;
977
+ }
811
978
  aside .privacy { display: none; }
812
979
  .brand { padding: 0; font-size: 17px; }
813
980
  nav { display: flex; gap: 4px; }
814
- nav button { padding: 8px 11px; font-size: 12.5px; }
981
+ nav button, nav a.navlink { flex: 0 0 auto; white-space: nowrap; padding: 8px 11px; font-size: 12.5px; }
815
982
  nav button .count { display: none; }
816
983
  main { padding: 26px 18px 40px; }
817
984
  h1 { font-size: 24px; }
818
985
  .boundary { font-size: 11px; gap: 8px; }
819
986
  .boundary .side { display: none; }
820
- .check { grid-template-columns: 1fr; gap: 4px; }
987
+ .check { grid-template-columns: 1fr; gap: 8px; }
988
+ .check .health-action { justify-self: start; margin-top: 2px; }
989
+ .health-actions { justify-content: flex-start; }
821
990
  .agent { grid-template-columns: 1fr; gap: 6px; }
822
991
  table { font-size: 12.5px; }
823
992
  th, td { padding: 10px 12px; }
@@ -919,7 +1088,7 @@ td .queued { color: var(--live); font-weight: 600; }
919
1088
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
920
1089
  }
921
1090
  .chip:hover { border-color: var(--signal); color: var(--text); }
922
- .chip.on { background: var(--signal); border-color: var(--signal); color: #fff; }
1091
+ .chip.on { background: var(--signal); border-color: var(--signal); color: var(--paper); }
923
1092
  .chip-sep { width: 1px; height: 18px; background: var(--rule); margin: 0 4px; }
924
1093
  .shown { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin: 4px 0 10px; }
925
1094
 
@@ -999,3 +1168,249 @@ td .queued { color: var(--live); font-weight: 600; }
999
1168
  color: var(--soft);
1000
1169
  white-space: nowrap;
1001
1170
  }
1171
+
1172
+ /* Rail: a storage destination this machine cannot reach yet, with the fix inline. */
1173
+ .rail-connect { color: var(--warn); text-decoration: underline; cursor: pointer; }
1174
+ #acct-escrow-text .rail-connect { display: inline-block; padding-block: 3px; }
1175
+
1176
+ /* Settings: storage destination rows — state, order, pins, connect. */
1177
+ .storage-target-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--rule); flex-wrap: wrap; }
1178
+ .storage-target-row:last-child { border-bottom: 0; }
1179
+ .storage-target-row .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
1180
+ .storage-target-row .dot.ok { background: var(--verified); }
1181
+ .storage-target-row .dot.warn { background: var(--warn); }
1182
+ .storage-target-row .target-name { min-width: 200px; }
1183
+ .storage-target-row .target-location { display: block; max-width: 34rem; margin-top: 3px; color: var(--text-3); font: 11px/1.35 var(--mono); overflow-wrap: anywhere; }
1184
+ .storage-target-row .target-capacity + .target-cap-manage { display: inline-flex; width: fit-content; margin-top: 7px; padding: 5px 9px; font-size: 11px; }
1185
+ .target-order button { border: 1px solid var(--rule); background: none; cursor: pointer; padding: 1px 7px; border-radius: 4px; color: inherit; }
1186
+ .target-order button:disabled { opacity: .3; cursor: default; }
1187
+ .target-pins { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
1188
+ .pin-chip { border: 1px solid var(--rule); border-radius: 10px; padding: 1px 8px; font-size: 12px; }
1189
+ .pin-chip button { border: 0; background: none; cursor: pointer; padding: 0 0 0 4px; color: inherit; }
1190
+ .pin-add { border: 1px dashed var(--rule); background: none; border-radius: 10px; padding: 1px 8px; font-size: 12px; cursor: pointer; color: inherit; }
1191
+ .target-connect { margin-left: auto; }
1192
+ .target-connection { flex: 1 0 100%; margin-left: 18px; padding: 2px 0 8px; }
1193
+ .target-connection-actions { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
1194
+ .target-connection-actions .target-connect { margin-left: 0; }
1195
+ .target-connection-form { margin-top: 10px; padding: 14px; border: 1px solid var(--rule); border-radius: 8px; background: color-mix(in srgb, var(--signal) 3%, var(--panel)); }
1196
+ .target-connection-form[hidden] { display: none; }
1197
+ .target-credential-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
1198
+ .target-credential-fields label { display: grid; gap: 5px; color: var(--text-2); font: 600 11px var(--mono); }
1199
+ .target-credential-fields .target-credential-wide, .target-credential-fields label:nth-child(3) { grid-column: 1 / -1; }
1200
+ .target-credential-fields input, .target-credential-fields textarea { width: 100%; }
1201
+ .target-connection-form .note { max-width: 72ch; margin: 10px 0; }
1202
+ @media (max-width: 720px) {
1203
+ .target-connection { margin-left: 0; }
1204
+ .target-credential-fields { grid-template-columns: 1fr; }
1205
+ .target-credential-fields label { grid-column: 1 !important; }
1206
+ .target-connection-actions { justify-content: flex-start; }
1207
+ }
1208
+
1209
+ /* Copies must read in full — a clipped place name marks nothing. */
1210
+ td .badge { white-space: normal; }
1211
+
1212
+ /* The revealed phrase: readable, selectable, visually distinct from inputs. */
1213
+ #reveal-phrase { width: 100%; font: 500 14px/1.6 var(--mono); padding: 10px 12px; border: 1px solid var(--warn); border-radius: 6px; background: var(--warn-bg); color: var(--ink); resize: none; }
1214
+
1215
+ /* A held-reason that cannot be read holds nothing. */
1216
+ td .hold-chip { white-space: normal; }
1217
+
1218
+ /* Live view: a session mirror growing in place. */
1219
+ .live-mirror { max-height: 60vh; overflow: auto; white-space: pre-wrap; word-break: break-word; font: 12px/1.6 var(--mono); background: var(--panel); border: 1px solid var(--rule); border-radius: 8px; padding: 14px; margin-top: 14px; color: var(--text); }
1220
+
1221
+ /* Health check groups: a quiet header per meaning. */
1222
+ .check-group { margin: 18px 0 6px; font: 600 12px var(--mono); letter-spacing: .04em; text-transform: uppercase; color: var(--text-2); }
1223
+ .check-group:first-child { margin-top: 0; }
1224
+
1225
+ /* Live: an active share row. */
1226
+ .share-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--rule); flex-wrap: wrap; }
1227
+ .share-row code { border: 1px solid var(--rule); border-radius: 6px; padding: 2px 8px; background: color-mix(in srgb, var(--signal) 8%, var(--card)); }
1228
+ .share-row button { border: 1px solid var(--rule); background: none; border-radius: 6px; padding: 4px 10px; cursor: pointer; color: inherit; }
1229
+
1230
+
1231
+ /* v2: section headings inside panels are mono kickers — the design's
1232
+ SETUP / RECOVERY PHRASE voice — while page headlines stay bold sans. */
1233
+ .panel h3, #view-settings form h3 { font: 600 11px var(--mono); text-transform: uppercase; letter-spacing: 0.09em; color: var(--text-2); }
1234
+
1235
+ /* v2 radii: cards and fields soften to the design's 12px. */
1236
+ .panel, .metric { border-radius: 12px; }
1237
+ input[type="text"], input[type="number"], input[type="password"], input[type="search"], textarea, select { border-radius: 10px; }
1238
+
1239
+ /* v2 terminal chrome for the live mirror: traffic dots and a sealed ground. */
1240
+ .live-mirror { background: var(--seal); color: var(--seal-ink); border-radius: 12px; border-color: color-mix(in srgb, var(--seal-ink) 14%, var(--seal)); padding-top: 40px; position: relative; }
1241
+ .live-mirror::before { content: "● ● ●"; position: absolute; top: 12px; left: 14px; font-size: 9px; letter-spacing: 2px; color: color-mix(in srgb, var(--seal-ink) 26%, var(--seal)); }
1242
+
1243
+ /* Shared view: the team as a table — a round ground with seats on the rim.
1244
+ Seats are positioned by script (percent offsets), so the circle scales. */
1245
+ .table-viz{position:relative;height:260px;margin:1.2rem auto .6rem;max-width:420px}
1246
+ .table-viz .table-top{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
1247
+ width:150px;height:150px;border-radius:50%;background:var(--seal);
1248
+ border:1px solid color-mix(in srgb, var(--seal-ink) 18%, var(--seal));
1249
+ display:flex;align-items:center;justify-content:center;text-align:center;
1250
+ font-family:var(--mono);font-size:.68rem;letter-spacing:.08em;color:var(--seal-ink);padding:1rem}
1251
+ .table-viz .seat{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:.25rem;width:92px;text-align:center}
1252
+ .table-viz .seat .avatar{width:40px;height:40px;border-radius:50%;background:var(--card);
1253
+ border:1px solid var(--rule);display:flex;align-items:center;justify-content:center;
1254
+ font-weight:650;font-size:.9rem;color:var(--ink)}
1255
+ .table-viz .seat.you .avatar{background:var(--live);color:var(--paper);border-color:transparent}
1256
+ .table-viz .seat .who{font-size:.72rem;color:var(--soft);line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:92px}
1257
+ .table-viz .seat button{background:none;border:0;color:var(--warn);font-size:.66rem;cursor:pointer;padding:0}
1258
+ .table-viz .seat button:hover{text-decoration:underline}
1259
+ .copychip{display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--rule);border-radius:10px;
1260
+ padding:.4rem .4rem .4rem .7rem;background:var(--seal)}
1261
+ .copychip code{background:none;color:var(--seal-ink);font-size:.78rem;padding:0}
1262
+ .copychip button{background:none;border:0;color:var(--live);font-family:var(--mono);font-size:.7rem;cursor:pointer;padding:.15rem .5rem;border-radius:8px}
1263
+ .copychip button:hover{background:color-mix(in srgb, var(--live) 14%, transparent)}
1264
+
1265
+ /* Shared projects begin with work already found on this machine. A suggestion
1266
+ is a local folder identity, not a cloud object; the selected outline is the
1267
+ only strong colour until the user deliberately continues to the account. */
1268
+ .project-suggestions-panel{border-color:color-mix(in srgb,var(--live) 32%,var(--rule))}
1269
+ .project-suggestions-head{justify-content:space-between;align-items:flex-start;gap:1rem}
1270
+ .project-suggestions-head h3{margin:0 0 .35rem}.project-suggestions-head .note{margin:0;max-width:66ch}
1271
+ .project-local-badge{flex:none;border:1px solid var(--rule);border-radius:999px;padding:.28rem .6rem;color:var(--soft);font:600 10px var(--mono);letter-spacing:.06em;text-transform:uppercase}
1272
+ .project-suggestion-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:.65rem;margin-top:1rem}
1273
+ .project-suggestion{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr);gap:.75rem;padding:.9rem;border:1px solid var(--rule);border-radius:10px;background:color-mix(in srgb,var(--seal) 56%,var(--card));cursor:pointer;transition:border-color 120ms ease,background 120ms ease}
1274
+ .project-suggestion:hover{border-color:color-mix(in srgb,var(--live) 55%,var(--rule))}
1275
+ .project-suggestion:has(input:checked){border-color:var(--live);background:color-mix(in srgb,var(--live) 7%,var(--card));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--live) 28%,transparent)}
1276
+ .project-suggestion input{width:15px;height:15px;margin:.15rem 0 0;accent-color:var(--live)}
1277
+ .project-suggestion strong{display:block;font:650 13px var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1278
+ .project-suggestion .project-path{display:block;margin-top:.3rem;color:var(--soft);font:11px/1.45 var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1279
+ .project-suggestion .project-facts{display:flex;gap:.45rem;flex-wrap:wrap;margin-top:.6rem;color:var(--soft);font-size:11px}
1280
+ .project-suggestion .project-facts span{border:1px solid var(--rule);border-radius:999px;padding:.15rem .45rem}
1281
+ .project-suggestion[data-state="connected"]{opacity:.58;cursor:default}.project-suggestion[data-state="connected"] input{visibility:hidden}
1282
+ .project-builder{display:grid;grid-template-columns:minmax(190px,1fr) minmax(210px,1fr) auto;align-items:end;gap:.8rem;margin-top:1rem;padding:1rem;border:1px solid var(--live);border-radius:10px;background:color-mix(in srgb,var(--live) 6%,var(--card))}
1283
+ .project-builder-copy strong,.project-builder-copy span{display:block}.project-builder-copy strong{font:650 13px var(--mono)}.project-builder-copy span{color:var(--soft);font-size:12px;margin-top:.25rem;line-height:1.45}
1284
+ .project-name-field{margin:0}.project-name-field input{margin-top:.35rem;width:100%}
1285
+ .project-builder>.action{white-space:nowrap}.project-builder>#team-project-result{grid-column:1/-1}
1286
+ .project-pending-list{display:grid;gap:.45rem;margin-top:.8rem}.project-pending-list:empty{display:none}
1287
+ .project-pending{display:flex;align-items:center;gap:.7rem;padding:.65rem .75rem;border-top:1px solid var(--rule);font-size:12px}.project-pending strong{font:600 12px var(--mono)}.project-pending span{color:var(--soft);flex:1}.project-pending button{background:none;border:0;color:var(--soft);font-size:11px;text-decoration:underline;cursor:pointer}
1288
+ .project-repair-controls{display:grid;grid-template-columns:minmax(220px,1fr) auto auto;gap:.65rem;align-items:center;margin:1rem 0 .75rem}
1289
+ .project-repair-controls[hidden]{display:none}
1290
+ .project-repair-controls input{width:100%;margin:0;font:500 12px var(--mono)}
1291
+ .project-repair-controls .note{margin:0;white-space:nowrap}
1292
+ .project-repair-group{border:1px solid var(--rule);border-radius:10px;overflow:hidden;background:color-mix(in srgb,var(--seal) 44%,var(--card));margin-top:.65rem}
1293
+ .project-repair-group-head{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;margin:0;padding:.75rem .85rem;background:color-mix(in srgb,var(--seal) 72%,var(--card));border-bottom:1px solid var(--rule)}
1294
+ .project-repair-group-head strong{min-width:0;overflow-wrap:anywhere;font:650 13px/1.4 var(--mono)}
1295
+ .project-repair-group-head .note{flex:none;margin:0;text-align:right}
1296
+ .project-repair-row{padding:.8rem .85rem;border-top:1px solid var(--rule)}
1297
+ .project-repair-group-head+.project-repair-row{border-top:0}
1298
+ .project-repair-row>.note{margin:.1rem 0 .55rem}
1299
+ .project-repair-identity{display:block;margin-bottom:.25rem;color:var(--soft);font:600 10px var(--mono);letter-spacing:.06em;text-transform:uppercase}
1300
+ .project-repair-chooser-host:empty{display:none}
1301
+ .project-repair-chooser{display:grid;grid-template-columns:minmax(190px,1fr) minmax(240px,1.35fr) auto;gap:.55rem;align-items:center;margin-top:.6rem;padding:.7rem;border:1px solid var(--rule);border-radius:10px;background:var(--card)}
1302
+ .project-repair-chooser input,.project-repair-chooser select{width:100%;min-width:0;margin:0;font:500 12px var(--mono)}
1303
+ .project-repair-chooser .note{grid-column:1/3;margin:0}
1304
+ .project-repair-chooser .note+.action{justify-self:start}
1305
+ .project-repair-review{grid-column:3;grid-row:1;align-self:stretch}
1306
+ .project-repair-confirmation{grid-column:1/-1;display:flex;justify-content:flex-end;gap:.55rem;flex-wrap:wrap}
1307
+ .project-repair-confirmation:empty{display:none}
1308
+ @media(max-width:820px){.project-builder{grid-template-columns:1fr}.project-builder>.action{width:100%}.project-local-badge{display:none}.project-repair-controls{grid-template-columns:1fr}.project-repair-controls .note{white-space:normal}.project-repair-group-head{align-items:flex-start;flex-direction:column;gap:.25rem}.project-repair-group-head .note{text-align:left}.project-repair-chooser{grid-template-columns:1fr}.project-repair-chooser .note,.project-repair-review,.project-repair-confirmation{grid-column:1;grid-row:auto}.project-repair-chooser .action{width:100%}}
1309
+ /* Task-focused local library: human-readable chrome, technical detail on demand. */
1310
+ .home-decisions { display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;margin-bottom:24px; }
1311
+ .cleanup-summary { margin:20px 0; padding:24px; border:1px solid var(--live); border-radius:10px; background:var(--card); }
1312
+ .cleanup-summary[hidden] { display:none; }
1313
+ .cleanup-summary h2 { font:600 20px/1.4 var(--sans); margin:0; }
1314
+ .cleanup-summary p { max-width:85ch; color:var(--soft); line-height:1.6; }
1315
+ .cleanup-summary ul { padding:0; list-style:none; }
1316
+ .cleanup-summary li { display:grid; grid-template-columns:minmax(180px,1fr) 2fr auto; gap:18px; padding:14px 0; border-top:1px solid var(--rule); }
1317
+ .cleanup-summary li span { color:var(--soft); }
1318
+ .cleanup-summary details { margin-top:20px; }
1319
+ .cleanup-summary pre { white-space:pre-wrap; overflow-wrap:anywhere; max-height:220px; overflow:auto; font:12px/1.6 var(--mono); }
1320
+ @media(max-width:700px) { .cleanup-summary li { grid-template-columns:1fr; gap:8px; } }
1321
+ .home-decision { display:grid; grid-template-columns:24px minmax(0,1fr); align-items:start; gap:12px; padding:20px; background:var(--card);border:1px solid var(--rule);border-radius:12px; }
1322
+ .home-value { display:block;font:600 28px/1.2 var(--sans);letter-spacing:-.03em;color:var(--ink);margin:10px 0;overflow-wrap:anywhere; }
1323
+ .home-decision .action { grid-column:2;justify-self:start;align-self:end; }
1324
+ .home-storage { grid-column:1/-1;padding:20px 24px;border:1px solid var(--rule);border-radius:12px; }
1325
+ .home-storage h2 { margin:0 0 12px;font:600 18px/1.4 var(--sans); }
1326
+ .home-storage h2::before { display:none; }
1327
+ .home-storage p { margin:8px 0;font:14px/1.5 var(--sans);color:var(--soft); }
1328
+ @media(max-width:1100px){.home-decisions{grid-template-columns:repeat(2,minmax(0,1fr));}}
1329
+ @media(max-width:650px){.home-decisions{grid-template-columns:1fr;}}
1330
+ .home-decision > .ui-icon { color:var(--live); }
1331
+ .home-decision h2, .page-journey h2 { font:600 18px/1.4 var(--sans); margin:0; color:var(--ink); }
1332
+ .home-decision h2::before, .page-journey h2::before { display:none; }
1333
+ .home-decision p, .page-journey p { max-width:76ch; margin:6px 0 0; font:14px/1.6 var(--sans); color:var(--soft); }
1334
+ .home-decision .action { min-width:170px; text-align:center; font:500 14px/1.5 var(--sans); }
1335
+ .home-decision .action { background:transparent; color:var(--ink); border:1px solid var(--rule); }
1336
+ .home-decision:first-child .action { background:var(--live); color:var(--paper); }
1337
+ .home-decision .action:hover { background:var(--rail-active); color:var(--ink); border-color:var(--live); filter:none; }
1338
+ .home-decision:first-child .action:hover { background:var(--live); color:var(--paper); filter:brightness(1.08); }
1339
+ .home-decision .action:focus-visible, .journey-actions a:focus-visible { outline:2px solid var(--live); outline-offset:3px; }
1340
+ .view h3, .view legend { font-family:var(--sans); font-size:16px; letter-spacing:0; text-transform:none; }
1341
+ .view h3::before { display:none; }
1342
+ .view input:not([type=checkbox]):not([type=radio]), .view select { font-family:var(--sans); font-size:14px; }
1343
+ #checks { padding:20px; }
1344
+ #settings-load-state { padding:12px 16px; background:var(--card); border-left:3px solid var(--live); }
1345
+ .page-details { margin:24px 0; border:1px solid var(--rule); border-radius:8px; padding:18px; }
1346
+ .page-details > summary { font:500 15px var(--sans); cursor:pointer; }
1347
+ .page-details[open] > summary { margin-bottom:20px; }
1348
+ .page-journey { margin:0 0 26px; padding:0 0 22px; border-bottom:1px solid var(--rule); }
1349
+ .journey-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:14px; }
1350
+ .journey-actions a { padding:7px 12px; border:1px solid var(--rule); border-radius:6px; text-decoration:none; font:500 14px/1.5 var(--sans); color:var(--ink); }
1351
+ .journey-actions a:hover { border-color:var(--live); }
1352
+ .service-attention { display:block; width:fit-content; margin-top:12px; padding:10px 14px; background:var(--card); border:1px solid var(--live); border-radius:6px; color:var(--live); font:500 14px var(--sans); }
1353
+ .service-attention[hidden] { display:none; }
1354
+ .session-more-filters { flex-basis:100%; margin:10px 0; }
1355
+ .session-more-filters > summary { cursor:pointer; font:500 14px var(--sans); padding:8px 0; }
1356
+ .session-filter-options { display:flex; flex-wrap:wrap; gap:8px; padding:12px 0; }
1357
+ #settings-form h3 { scroll-margin-top:30px; font:600 18px/1.5 var(--sans); color:var(--ink); }
1358
+ #settings-form .note { max-width:80ch; }
1359
+ #settings-form > .panel > .row:last-child { position:sticky; bottom:0; background:var(--card); padding:16px 0; border-top:1px solid var(--rule); z-index:2; }
1360
+ @media(max-width:650px) { .home-decision { grid-template-columns:26px minmax(0,1fr); padding:20px; gap:12px; } .home-decision .action { grid-column:2; justify-self:start; min-width:0; } }
1361
+ body { background:var(--paper); font-size:15px; }
1362
+ h1 { font-family:var(--sans); font-weight:650; letter-spacing:-.025em; }
1363
+ nav button, nav a.navlink { font-family:var(--sans); font-size:15px; min-height:44px; }
1364
+ nav button .glyph svg { width:20px; height:20px; display:block; }
1365
+ .brand { font-family:var(--sans); }
1366
+ #archives-panel { background:transparent; border:0; overflow:visible; }
1367
+ #archives-panel table { border:1px solid var(--rule); border-radius:10px; }
1368
+ #archives-panel th { font:500 12px var(--sans); letter-spacing:0; text-transform:none; }
1369
+ .ui-icon { width:24px; height:24px; flex-shrink:0; fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
1370
+ .vault-overview { display:grid; grid-template-columns:1fr 1fr 1fr; margin:0 0 28px; border:1px solid var(--rule); border-radius:12px; background:var(--card); }
1371
+ .vault-overview-item { display:flex; align-items:center; gap:20px; padding:28px; }
1372
+ .vault-overview-item + .vault-overview-item { border-left:1px solid var(--rule); }
1373
+ .vault-overview-item > .ui-icon { width:42px; height:42px; color:var(--soft); }
1374
+ .vault-overview-item:last-child > .ui-icon { color:var(--live); }
1375
+ .vault-overview h2 { margin:0; font:600 20px/1.3 var(--sans); color:var(--ink); }
1376
+ .vault-overview h2::before { display:none; }
1377
+ #archives-panel .vault-project-toggle { background:transparent; color:var(--ink); border:1px solid var(--rule); font:500 14px var(--sans); }
1378
+ #archives-panel .vault-location.selected { background:var(--live); color:var(--paper); }
1379
+ .vault-overview p { margin:7px 0 12px; font:14px/1.5 var(--sans); color:var(--soft); }
1380
+ #archives-panel .vault-tools { display:block; padding:0 0 18px; border:0; }
1381
+ #archives-panel .vault-find { display:block; margin-bottom:18px; }
1382
+ #archives-panel .vault-find input { width:100%; max-width:none; min-height:48px; font:15px var(--sans); padding:12px 16px; }
1383
+ #archives-panel .vault-locations { display:flex; flex-wrap:wrap; align-items:flex-start; gap:10px; }
1384
+ #archives-panel .vault-location { font:500 14px var(--sans); border-radius:7px; padding:11px 15px; }
1385
+ .vault-advanced { position:relative; }
1386
+ .vault-advanced > summary { cursor:pointer; padding:10px 16px; border:1px solid var(--rule); border-radius:7px; font:500 14px var(--sans); }
1387
+ .vault-advanced-body { display:flex; flex-wrap:wrap; gap:12px; padding:18px; margin-top:10px; border:1px solid var(--rule); border-radius:8px; }
1388
+ .vault-advanced[open] { flex-basis:100%; }
1389
+ .vault-project { display:grid; grid-template-columns:minmax(150px,1.2fr) minmax(180px,1fr) minmax(180px,1fr) auto; gap:24px; align-items:center; }
1390
+ .vault-project-name { display:flex; align-items:center; gap:16px; border:0; background:none; color:var(--ink); padding:0; text-align:left; cursor:pointer; min-width:0; }
1391
+ .vault-project-name .ui-icon { color:var(--live); width:28px; height:28px; }
1392
+ #archives-panel .group-row b { font:600 17px/1.4 var(--sans); }
1393
+ .vault-project small { display:block; color:var(--soft); font:13px/1.5 var(--sans); margin-top:4px; }
1394
+ .vault-project-local strong { font:500 14px/1.5 var(--sans); }
1395
+ .vault-project-backup-cell { display:flex; align-items:center; gap:10px; }
1396
+ .vault-project-details { margin:10px 0 0 44px; font:13px/1.6 var(--sans); color:var(--soft); }
1397
+ .vault-project-details summary { cursor:pointer; width:fit-content; }
1398
+ .vault-project-details > span { display:block; max-width:85ch; padding:10px 0; }
1399
+ .vault-transfer-disclosure { margin:12px 0 20px; border:1px solid var(--rule); border-radius:8px; padding:16px; }
1400
+ .vault-transfer-disclosure > summary { cursor:pointer; font:600 15px var(--sans); }
1401
+ .vault-transfer-disclosure[open] > summary { margin-bottom:18px; }
1402
+ #archives-panel .group-row td { padding-top:22px; padding-bottom:22px; }
1403
+ #archives-panel .row > .actions[hidden], #archives-panel [hidden] { display:none !important; }
1404
+ @media (max-width:1100px) {
1405
+ .vault-overview-item { padding:20px; gap:12px; }
1406
+ .vault-overview-item > .ui-icon { width:30px; height:30px; }
1407
+ .vault-project { grid-template-columns:1fr 1fr; gap:16px; }
1408
+ }
1409
+ @media (max-width:650px) {
1410
+ #archives-panel table { display:block; overflow-x:auto; max-width:100%; }
1411
+ .vault-overview { grid-template-columns:1fr; }
1412
+ .vault-overview-item + .vault-overview-item { border-left:0; border-top:1px solid var(--rule); }
1413
+ .vault-project { grid-template-columns:1fr; gap:10px; }
1414
+ .vault-project-details { margin-left:0; }
1415
+ .vault-project-toggle { justify-self:start; }
1416
+ }