web+home: "backup" copy becomes sign-in language (#1259)
The audit's copy sweep: the product's model is "you sign in" (the anchor model), but several surfaces still said "backup" — the retired framing. - adddevice.js + the menu: "Add a device or back up" → "Add a device"; the enrol button "Back up" → "Sign in with Eleven"; the note frames the one-time link as "a way back in", not "your backup". - shell.js sign-out-of-only-device dialog: "Save a backup link first" → "Save a way back in first" (button to match). - home: anchors.go's last-anchor refusal drops the dangling "or delete the backup instead" (no such surfaced action); merge.go's precondition refusal says "still has spaces saved to it"; home.js's combine fallbacks say "spaces list" (matching the busy line beside them). Internal identifiers (backup.js module, deferBackupReminders verb, native enum cases) deliberately keep their names — code, not copy.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
7 files changed,
+21
−16
changelog/2026-07-22-sign-in-not-backup.md+5 −0home/anchors.go+1 −1home/merge.go+2 −2home/web/static/home.js+2 −2web/pages/index.html+1 −1web/static/adddevice.js+6 −6web/static/shell.js+4 −4
diff --git a/changelog/2026-07-22-sign-in-not-backup.md b/changelog/2026-07-22-sign-in-not-backup.md| new file mode 100644 |
| index 0000000..e45bba1 |
| --- /dev/null |
| +++ b/changelog/2026-07-22-sign-in-not-backup.md |
| @@ -0,0 +1,5 @@ |
| +🤖 Clearer words for keeping your access safe. The old "back up" language is |
| +gone: the menu now says "Add a device", the add-a-device card offers "Sign in |
| +with Eleven" alongside saving the one-time link, and signing out of your only |
| +device asks you to save a way back in first. Same protections, said the way |
| +they work — you sign in; nothing to file away. |
diff --git a/home/anchors.go b/home/anchors.go| index 68852ec..6e07407 100644 |
| --- a/home/anchors.go |
| +++ b/home/anchors.go |
| @@ -110,7 +110,7 @@ func (s *Server) deleteAnchorHandler(w http.ResponseWriter, r *http.Request) { |
| return |
| } |
| if last { |
| - http.Error(w, "that's the last way into this account — add another way to sign in before removing it, or delete the backup instead", http.StatusConflict) |
| + http.Error(w, "that's the last way into this account — add another way to sign in before removing it", http.StatusConflict) |
| return |
| } |
| if !deleted { |
diff --git a/home/merge.go b/home/merge.go| index c5b4b65..5c46031 100644 |
| --- a/home/merge.go |
| +++ b/home/merge.go |
| @@ -75,14 +75,14 @@ func (s *Server) mergeAccountHandler(w http.ResponseWriter, r *http.Request) { |
| http.Error(w, "db error", http.StatusInternalServerError) |
| return |
| } else if found { |
| - http.Error(w, "That account still holds a backup — move the spaces over first", http.StatusConflict) |
| + http.Error(w, "That account still has spaces saved to it — move them over first", http.StatusConflict) |
| return |
| } |
| moved, err := s.store.mergeAccounts(survivor, absorbed) |
| if errors.Is(err, errAbsorbedHasBlob) { |
| // The store's belt caught a blob written between the check above and |
| // the merge. |
| - http.Error(w, "That account still holds a backup — move the spaces over first", http.StatusConflict) |
| + http.Error(w, "That account still has spaces saved to it — move them over first", http.StatusConflict) |
| return |
| } |
| if err != nil { |
diff --git a/home/web/static/home.js b/home/web/static/home.js| index bbfe0e8..42ff5f4 100644 |
| --- a/home/web/static/home.js |
| +++ b/home/web/static/home.js |
| @@ -2366,7 +2366,7 @@ async function combineSkipYes() { |
| await deleteAbsorbedBlob(); |
| combineFinish(0); |
| } catch (e) { |
| - combineStatus((e && e.message) || "Couldn’t clear the other account’s backup.", "error"); |
| + combineStatus((e && e.message) || "Couldn’t clear the other account’s spaces list.", "error"); |
| } finally { |
| btn.disabled = false; |
| } |
| @@ -2382,7 +2382,7 @@ async function deleteAbsorbedBlob() { |
| } |
| const res = await fetch("/api/blob", { method: "DELETE", headers: { "X-Ceremony-Proof": combine.absorbedProof } }); |
| if (!res.ok && res.status !== 404) { |
| - throw new Error(((await res.text().catch(() => "")) || "").trim() || "Couldn’t clear the other account’s backup."); |
| + throw new Error(((await res.text().catch(() => "")) || "").trim() || "Couldn’t clear the other account’s spaces list."); |
| } |
| } |
diff --git a/web/pages/index.html b/web/pages/index.html| index 983e565..8e10d19 100644 |
| --- a/web/pages/index.html |
| +++ b/web/pages/index.html |
| @@ -152,7 +152,7 @@ |
| <button class="menu-item" id="menu-apps" role="menuitem">Apps</button> |
| <button class="menu-item" id="menu-notif" role="menuitem">Notifications</button> |
| <button class="menu-item" id="menu-theme" role="menuitem">Theme</button> |
| - <button class="menu-item" id="menu-add-device" role="menuitem">Add a device / back up</button> |
| + <button class="menu-item" id="menu-add-device" role="menuitem">Add a device</button> |
| <!-- Mac desktop browsers only (shell.js unhides): the one |
| platform with a scheme receiver today; iOS follows. --> |
| <button class="menu-item" id="menu-open-app" role="menuitem" hidden>Open in the Eleven app</button> |
diff --git a/web/static/adddevice.js b/web/static/adddevice.js| index 6965fb1..34cc514 100644 |
| --- a/web/static/adddevice.js |
| +++ b/web/static/adddevice.js |
| @@ -41,10 +41,10 @@ export async function addDevice() { |
| const backdrop = verbs.modal(); |
| const card = backdrop.querySelector(".sheet"); |
| const h = document.createElement("h2"); |
| - h.textContent = "Add a device or back up"; |
| + h.textContent = "Add a device"; |
| const note = document.createElement("p"); |
| note.className = "sub"; |
| - note.textContent = "Open this on another device to sign in there — or save it somewhere safe (like a password manager) as your backup: it's the only way back in if you lose this device. It works once, and anyone who uses it signs in as you."; |
| + note.textContent = "Open this on another device to sign in there — or save it somewhere safe (like a password manager): it's a way back in if you lose this device. It works once, and anyone who uses it signs in as you."; |
| const qr = document.createElement("div"); |
| qr.className = "qr-wrap"; |
| try { |
| @@ -80,13 +80,13 @@ export async function addDevice() { |
| const row = document.createElement("div"); |
| row.className = "row"; |
| row.appendChild(copy); |
| - // A passkey backup is the one-tap alternative to saving the link: enrol (or |
| - // update) this instance with the home server. Only shown when a home server |
| - // is configured — launchEnrol is a no-op otherwise. |
| + // Signing in with Eleven is the one-tap alternative to saving the link: |
| + // enrol (or update) this instance with the home server. Only shown when a |
| + // home server is configured — launchEnrol is a no-op otherwise. |
| if (window.__homeOrigin) { |
| const backup = document.createElement("button"); |
| backup.className = "secondary"; |
| - backup.textContent = "Back up"; |
| + backup.textContent = "Sign in with Eleven"; |
| backup.onclick = () => { |
| backdrop.remove(); // web navigates same-tab; native/PWA opens a new context |
| launchEnrol(session); |
diff --git a/web/static/shell.js b/web/static/shell.js| index 73b86f2..cea5a1e 100644 |
| --- a/web/static/shell.js |
| +++ b/web/static/shell.js |
| @@ -8093,7 +8093,7 @@ async function leave() { |
| return; |
| } |
| - // Only device: warn hard and offer to save a backup link first. |
| + // Only device: warn hard and offer a way back in first. |
| const backdrop = modal(); |
| const card = backdrop.querySelector(".sheet"); |
| const h = document.createElement("h2"); |
| @@ -8101,7 +8101,7 @@ async function leave() { |
| const p = document.createElement("p"); |
| p.className = "sub"; |
| p.textContent = |
| - "Your chats are encrypted to a key that lives only on this device. Sign out and you'll lose access to them for good — there's no way to recover it. Save a backup link first so you can get back in."; |
| + "Your chats are encrypted to a key that lives only on this device. Sign out and you'll lose access to them for good — there's no way to recover it. Save a way back in first."; |
| const foot = document.createElement("div"); |
| foot.className = "sheet-foot"; |
| const out = document.createElement("button"); |
| @@ -8112,10 +8112,10 @@ async function leave() { |
| doSignout(); |
| }; |
| const backup = document.createElement("button"); |
| - backup.textContent = "Save a backup first"; |
| + backup.textContent = "Save a way back in"; |
| backup.onclick = () => { |
| backdrop.remove(); |
| - addDevice(); // save that link, then sign out later if you still want to |
| + addDevice(); // sign in with Eleven or save the link, then sign out later if you still want to |
| }; |
| foot.appendChild(out); |
| foot.appendChild(backup); |