Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: strip E2EE branding, reframe as local-only office suite

E2EE claims are misleading when there's no sync or sharing — only one
"end" exists. Replace all user-facing E2EE references with honest
local-storage messaging across landing page, all 6 editor templates,
meta descriptions, and status chips. Update tests to match.

Chainlink: #13

+24 -53
+2 -6
src/calendar/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="E2EE calendar. End-to-end encrypted, real-time collaboration."> 7 + <meta name="description" content="Atmosphere Docs — calendar. All data stored locally in your browser."> 8 8 <meta property="og:title" content="Atmosphere Docs — Calendar"> 9 - <meta property="og:description" content="E2EE calendar. End-to-end encrypted, real-time collaboration."> 9 + <meta property="og:description" content="Atmosphere Docs — calendar. All data stored locally in your browser."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs — Calendar</title> ··· 31 31 <div class="status-indicator" id="status"> 32 32 <span class="status-dot" id="status-dot"></span> 33 33 <span id="status-text">Connecting&hellip;</span> 34 - </div> 35 - <div class="status-indicator"> 36 - <span class="status-dot encrypted"></span> 37 - <span>E2EE</span> 38 34 </div> 39 35 <button class="btn-icon" id="btn-cal-settings" title="Calendar settings" aria-label="Calendar settings"> 40 36 <svg class="tb-icon icon-gear" viewBox="0 0 16 16" style="width:16px;height:16px" fill="none" stroke="currentColor" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.57 6.24 L14.57 9.76 L12.44 9.19 L11.98 10.30 L13.89 11.40 L11.40 13.89 L10.30 11.98 L9.19 12.44 L9.76 14.57 L6.24 14.57 L6.81 12.44 L5.70 11.98 L4.60 13.89 L2.11 11.40 L4.02 10.30 L3.56 9.19 L1.43 9.76 L1.43 6.24 L3.56 6.81 L4.02 5.70 L2.11 4.60 L4.60 2.11 L5.70 4.02 L6.81 3.56 L6.24 1.43 L9.76 1.43 L9.19 3.56 L10.30 4.02 L11.40 2.11 L13.89 4.60 L11.98 5.70 L12.44 6.81 Z"/><circle cx="8" cy="8" r="2.2"/></svg>
+1 -1
src/css/app.css
··· 1 1 /* ======================================================== 2 - Docs — E2EE Collaborative Office Suite 2 + Docs — Local-first Office Suite 3 3 Aesthetic: Refined Editorial + Industrial Utility 4 4 No external font dependencies — system fonts only. 5 5 ======================================================== */
+2 -6
src/diagrams/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="E2EE diagrams and whiteboard. End-to-end encrypted, real-time collaboration."> 7 + <meta name="description" content="Atmosphere Docs — diagrams and whiteboard. All data stored locally in your browser."> 8 8 <meta property="og:title" content="Atmosphere Docs — Diagrams"> 9 - <meta property="og:description" content="E2EE diagrams and whiteboard. End-to-end encrypted, real-time collaboration."> 9 + <meta property="og:description" content="Atmosphere Docs — diagrams and whiteboard. All data stored locally in your browser."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs — Diagrams</title> ··· 42 42 <div class="status-indicator" id="status"> 43 43 <span class="status-dot" id="status-dot"></span> 44 44 <span id="status-text">Connecting&hellip;</span> 45 - </div> 46 - <div class="status-indicator"> 47 - <span class="status-dot encrypted"></span> 48 - <span>E2EE</span> 49 45 </div> 50 46 </div> 51 47
+2 -6
src/docs/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="E2EE collaborative document editor. End-to-end encrypted, real-time collaboration."> 7 + <meta name="description" content="Atmosphere Docs — document editor. All data stored locally in your browser."> 8 8 <meta property="og:title" content="Atmosphere Docs"> 9 - <meta property="og:description" content="E2EE collaborative document editor. End-to-end encrypted, real-time collaboration."> 9 + <meta property="og:description" content="Atmosphere Docs — document editor. All data stored locally in your browser."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs</title> ··· 70 70 <div class="status-indicator" id="status"> 71 71 <span class="status-dot" id="status-dot"></span> 72 72 <span id="status-text">Connecting…</span> 73 - </div> 74 - <div class="status-indicator"> 75 - <span class="status-dot encrypted"></span> 76 - <span>E2EE</span> 77 73 </div> 78 74 <button class="btn-icon" id="btn-shortcuts" title="Keyboard shortcuts">?</button> 79 75 <button class="theme-toggle" id="theme-toggle" title="Toggle dark mode"></button>
+2 -6
src/forms/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="E2EE form builder. End-to-end encrypted, real-time collaboration."> 7 + <meta name="description" content="Atmosphere Docs — form builder. All data stored locally in your browser."> 8 8 <meta property="og:title" content="Atmosphere Docs — Forms"> 9 - <meta property="og:description" content="E2EE form builder. End-to-end encrypted, real-time collaboration."> 9 + <meta property="og:description" content="Atmosphere Docs — form builder. All data stored locally in your browser."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs — Forms</title> ··· 32 32 <div class="status-indicator" id="status"> 33 33 <span class="status-dot" id="status-dot"></span> 34 34 <span id="status-text">Connecting&hellip;</span> 35 - </div> 36 - <div class="status-indicator"> 37 - <span class="status-dot encrypted"></span> 38 - <span>E2EE</span> 39 35 </div> 40 36 <button class="btn-icon" id="btn-ai-chat" title="AI Chat (Cmd+Shift+L)"> 41 37 <svg class="tb-icon" viewBox="0 0 16 16" style="width:16px;height:16px" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h12a1 1 0 0 1 1 1v7a1 1 0 0 1-1 1H5l-3 3V4a1 1 0 0 1 1-1z"/><circle cx="5.5" cy="7.5" r="0.5" fill="currentColor" stroke="none"/><circle cx="8" cy="7.5" r="0.5" fill="currentColor" stroke="none"/><circle cx="10.5" cy="7.5" r="0.5" fill="currentColor" stroke="none"/></svg>
+6 -7
src/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="End-to-end encrypted docs, sheets, slides, and more for the AT Protocol. Your data stays in your browser."> 7 + <meta name="description" content="Documents, spreadsheets, slides, and more — stored locally in your browser. Sign in with your Bluesky account."> 8 8 <meta property="og:title" content="Atmosphere Docs"> 9 - <meta property="og:description" content="End-to-end encrypted docs, sheets, slides, and more for the AT Protocol. Your data stays in your browser."> 9 + <meta property="og:description" content="Documents, spreadsheets, slides, and more — stored locally in your browser. Sign in with your Bluesky account."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs</title> ··· 23 23 <header class="landing-header"> 24 24 <div class="brand"> 25 25 <span class="brand-name">Atmosphere</span> 26 - <span class="brand-badge">E2EE</span> 27 26 <span style="flex:1"></span> 28 27 <span class="user-badge" id="user-badge" title="Account" role="button" tabindex="0" aria-label="Account menu" style="display:none"></span> 29 28 <button class="theme-toggle" id="theme-toggle" title="Toggle dark mode" aria-label="Toggle dark mode"></button> ··· 134 133 <footer style="margin-top: var(--space-2xl); padding-top: var(--space-lg); border-top: 1px solid var(--color-border);"> 135 134 <div class="encryption-bar"> 136 135 <span class="encryption-dot"></span> 137 - <span>All documents are end-to-end encrypted. Keys never leave your browser.</span> 136 + <span>All documents are stored locally in your browser.</span> 138 137 </div> 139 138 <div class="desktop-download" id="desktop-download" style="display:none;"> 140 139 <a class="desktop-download-btn" id="desktop-download-btn" href="#" target="_blank" rel="noopener"> ··· 149 148 <div class="modal-backdrop" id="username-modal" style="display:none;"> 150 149 <div class="modal username-modal" role="dialog" aria-modal="true" aria-labelledby="username-modal-title"> 151 150 <h2 id="username-modal-title">Atmosphere Docs</h2> 152 - <p class="welcome-tagline">End-to-end encrypted office suite for the AT Protocol ecosystem.</p> 151 + <p class="welcome-tagline">A local-only office suite for the AT Protocol ecosystem.</p> 153 152 <ul class="welcome-features"> 154 153 <li>Documents, spreadsheets, slides, diagrams, forms, and calendar</li> 155 - <li>Encrypted with AES-256-GCM &mdash; keys never leave your browser</li> 156 - <li>All data stored locally &mdash; nothing is sent to a server</li> 154 + <li>All data stored locally in your browser &mdash; nothing is sent to a server</li> 155 + <li>Sign in with your Bluesky account</li> 157 156 </ul> 158 157 <p class="welcome-signin-label">Sign in with your Bluesky account</p> 159 158 <input type="text" class="username-input" id="username-input" placeholder="you.bsky.social" maxlength="100" autofocus />
+1 -1
src/landing-render.ts
··· 502 502 deps.docListEl.innerHTML = ` 503 503 <div class="empty-state"> 504 504 <strong>No documents yet</strong> 505 - Create your first encrypted document or spreadsheet above. 505 + Create your first document or spreadsheet above. 506 506 </div>`; 507 507 deps.noResultsEl.style.display = 'none'; 508 508 } else if (sorted.length === 0) {
+2 -6
src/sheets/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="E2EE collaborative spreadsheet. End-to-end encrypted, real-time collaboration."> 7 + <meta name="description" content="Atmosphere Docs — spreadsheet editor. All data stored locally in your browser."> 8 8 <meta property="og:title" content="Atmosphere Docs — Sheets"> 9 - <meta property="og:description" content="E2EE collaborative spreadsheet. End-to-end encrypted, real-time collaboration."> 9 + <meta property="og:description" content="Atmosphere Docs — spreadsheet editor. All data stored locally in your browser."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs — Sheets</title> ··· 45 45 <div class="status-indicator" id="status"> 46 46 <span class="status-dot" id="status-dot"></span> 47 47 <span id="status-text">Connecting…</span> 48 - </div> 49 - <div class="status-indicator"> 50 - <span class="status-dot encrypted"></span> 51 - <span>E2EE</span> 52 48 </div> 53 49 <button class="btn-icon" id="btn-shortcuts" title="Keyboard shortcuts">?</button> 54 50 <button class="theme-toggle" id="theme-toggle" title="Toggle dark mode"></button>
+2 -6
src/slides/index.html
··· 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"> 6 6 <link rel="manifest" href="/manifest.json"> 7 - <meta name="description" content="E2EE slide presentations. End-to-end encrypted, real-time collaboration."> 7 + <meta name="description" content="Atmosphere Docs — slide presentations. All data stored locally in your browser."> 8 8 <meta property="og:title" content="Atmosphere Docs — Slides"> 9 - <meta property="og:description" content="E2EE slide presentations. End-to-end encrypted, real-time collaboration."> 9 + <meta property="og:description" content="Atmosphere Docs — slide presentations. All data stored locally in your browser."> 10 10 <meta property="og:type" content="website"> 11 11 <meta property="og:image" content="/favicon.svg"> 12 12 <title>Atmosphere Docs — Slides</title> ··· 33 33 <div class="status-indicator" id="status"> 34 34 <span class="status-dot" id="status-dot"></span> 35 35 <span id="status-text">Connecting&hellip;</span> 36 - </div> 37 - <div class="status-indicator"> 38 - <span class="status-dot encrypted"></span> 39 - <span>E2EE</span> 40 36 </div> 41 37 <button class="btn-secondary" id="btn-present" title="Present (F5)">&#9655; Present</button> 42 38 <button class="btn-secondary" id="btn-export" title="Export">Export</button>
+4 -8
tests/status-chips.test.ts
··· 1 1 /** 2 2 * @vitest-environment jsdom 3 3 * 4 - * Regression test for #695: the Synced + E2EE chip pair was previously only 5 - * rendered in docs and sheets. Slides, forms, diagrams, and calendar only 6 - * showed the Saved indicator. `wireStatusChips` unifies the Synced chip 7 - * wiring; the E2EE chip is static markup on each template. 4 + * Regression test for #695: `wireStatusChips` unifies the Synced chip 5 + * wiring across all editor templates. 8 6 * 9 7 * These tests pin the contract so future refactors can't silently regress: 10 8 * - `status-dot` flips `.connected` on provider `status` events ··· 80 78 }); 81 79 }); 82 80 83 - describe('#695 — every editor HTML template ships the Synced + E2EE chip pair', () => { 81 + describe('#695 — every editor HTML template ships the Synced status indicator', () => { 84 82 const EDITOR_TEMPLATES = [ 85 83 'src/docs/index.html', 86 84 'src/sheets/index.html', ··· 91 89 ]; 92 90 93 91 for (const template of EDITOR_TEMPLATES) { 94 - it(`${template} contains both the Synced status-indicator and the E2EE chip`, async () => { 92 + it(`${template} contains the Synced status-indicator`, async () => { 95 93 const fs = await import('node:fs'); 96 94 const path = await import('node:path'); 97 95 const html = fs.readFileSync(path.resolve(process.cwd(), template), 'utf-8'); 98 96 expect(html).toMatch(/id=["']status-dot["']/); 99 97 expect(html).toMatch(/id=["']status-text["']/); 100 - expect(html).toMatch(/status-dot encrypted/); 101 - expect(html).toMatch(/>\s*E2EE\s*</); 102 98 }); 103 99 } 104 100 });