Social Annotations in the Atmosphere
15
fork

Configure Feed

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

Merge branch 'main' of git.sealight.xyz:aynish/seams.so

+448 -97
+20
.beads/.gitignore
··· 1 + # SQLite databases 2 + *.db 3 + *.db-journal 4 + *.db-wal 5 + *.db-shm 6 + 7 + # Daemon runtime files 8 + daemon.lock 9 + daemon.log 10 + daemon.pid 11 + bd.sock 12 + 13 + # Legacy database files 14 + db.sqlite 15 + bd.db 16 + 17 + # Keep JSONL exports and config (source of truth for git) 18 + !*.jsonl 19 + !metadata.json 20 + !config.json
+56
.beads/config.yaml
··· 1 + # Beads Configuration File 2 + # This file configures default behavior for all bd commands in this repository 3 + # All settings can also be set via environment variables (BD_* prefix) 4 + # or overridden with command-line flags 5 + 6 + # Issue prefix for this repository (used by bd init) 7 + # If not set, bd init will auto-detect from directory name 8 + # Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc. 9 + # issue-prefix: "" 10 + 11 + # Use no-db mode: load from JSONL, no SQLite, write back after each command 12 + # When true, bd will use .beads/issues.jsonl as the source of truth 13 + # instead of SQLite database 14 + # no-db: false 15 + 16 + # Disable daemon for RPC communication (forces direct database access) 17 + # no-daemon: false 18 + 19 + # Disable auto-flush of database to JSONL after mutations 20 + # no-auto-flush: false 21 + 22 + # Disable auto-import from JSONL when it's newer than database 23 + # no-auto-import: false 24 + 25 + # Enable JSON output by default 26 + # json: false 27 + 28 + # Default actor for audit trails (overridden by BD_ACTOR or --actor) 29 + # actor: "" 30 + 31 + # Path to database (overridden by BEADS_DB or --db) 32 + # db: "" 33 + 34 + # Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON) 35 + # auto-start-daemon: true 36 + 37 + # Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE) 38 + # flush-debounce: "5s" 39 + 40 + # Multi-repo configuration (experimental - bd-307) 41 + # Allows hydrating from multiple repositories and routing writes to the correct JSONL 42 + # repos: 43 + # primary: "." # Primary repo (where this database lives) 44 + # additional: # Additional repos to hydrate from (read-only) 45 + # - ~/beads-planning # Personal planning repo 46 + # - ~/work-planning # Work planning repo 47 + 48 + # Integration settings (access with 'bd config get/set') 49 + # These are stored in the database, not in this file: 50 + # - jira.url 51 + # - jira.project 52 + # - linear.url 53 + # - linear.api-key 54 + # - github.org 55 + # - github.repo 56 + # - sync.branch - Git branch for beads commits (use BEADS_SYNC_BRANCH env var or bd config set)
+5
.beads/metadata.json
··· 1 + { 2 + "database": "beads.db", 3 + "version": "0.23.0", 4 + "jsonl_export": "beads.jsonl" 5 + }
+3
.gitattributes
··· 1 + 2 + # Use bd merge for beads JSONL files 3 + .beads/beads.jsonl merge=beads
+11 -1
entrypoints/sidepanel/main.ts
··· 93 93 }); 94 94 95 95 // Login handler 96 - loginBtn?.addEventListener('click', async () => { 96 + const handleLogin = async () => { 97 97 let handle = handleInput?.value.trim(); 98 98 if (!handle) { 99 99 alert('Please enter your handle'); ··· 129 129 } catch (error) { 130 130 if (authStatus) authStatus.textContent = 'Login failed'; 131 131 console.error('Login error:', error); 132 + } 133 + }; 134 + 135 + loginBtn?.addEventListener('click', handleLogin); 136 + 137 + // Handle Enter key on handle input 138 + handleInput?.addEventListener('keydown', (e) => { 139 + if (e.key === 'Enter') { 140 + e.preventDefault(); 141 + handleLogin(); 132 142 } 133 143 }); 134 144
+75 -5
flake.lock
··· 1 1 { 2 2 "nodes": { 3 + "beads": { 4 + "inputs": { 5 + "flake-utils": "flake-utils", 6 + "nixpkgs": "nixpkgs" 7 + }, 8 + "locked": { 9 + "lastModified": 1762602968, 10 + "narHash": "sha256-3F7sv4mAKBQ4YBSABgp9bendgHopObNivO5NQhJYUek=", 11 + "owner": "steveyegge", 12 + "repo": "beads", 13 + "rev": "367bf077e10695976480bba097e2ae47593a4d82", 14 + "type": "github" 15 + }, 16 + "original": { 17 + "owner": "steveyegge", 18 + "ref": "v0.23.0", 19 + "repo": "beads", 20 + "type": "github" 21 + } 22 + }, 3 23 "flake-utils": { 4 24 "inputs": { 5 25 "systems": "systems" ··· 18 38 "type": "github" 19 39 } 20 40 }, 41 + "flake-utils_2": { 42 + "inputs": { 43 + "systems": "systems_2" 44 + }, 45 + "locked": { 46 + "lastModified": 1731533236, 47 + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 48 + "owner": "numtide", 49 + "repo": "flake-utils", 50 + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 51 + "type": "github" 52 + }, 53 + "original": { 54 + "owner": "numtide", 55 + "repo": "flake-utils", 56 + "type": "github" 57 + } 58 + }, 21 59 "nixpkgs": { 22 60 "locked": { 23 - "lastModified": 1760878510, 24 - "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", 61 + "lastModified": 1760284886, 62 + "narHash": "sha256-TK9Kr0BYBQ/1P5kAsnNQhmWWKgmZXwUQr4ZMjCzWf2c=", 25 63 "owner": "NixOS", 26 64 "repo": "nixpkgs", 27 - "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", 65 + "rev": "cf3f5c4def3c7b5f1fc012b3d839575dbe552d43", 66 + "type": "github" 67 + }, 68 + "original": { 69 + "owner": "NixOS", 70 + "ref": "nixos-unstable", 71 + "repo": "nixpkgs", 72 + "type": "github" 73 + } 74 + }, 75 + "nixpkgs_2": { 76 + "locked": { 77 + "lastModified": 1762363567, 78 + "narHash": "sha256-YRqMDEtSMbitIMj+JLpheSz0pwEr0Rmy5mC7myl17xs=", 79 + "owner": "NixOS", 80 + "repo": "nixpkgs", 81 + "rev": "ae814fd3904b621d8ab97418f1d0f2eb0d3716f4", 28 82 "type": "github" 29 83 }, 30 84 "original": { ··· 36 90 }, 37 91 "root": { 38 92 "inputs": { 39 - "flake-utils": "flake-utils", 40 - "nixpkgs": "nixpkgs" 93 + "beads": "beads", 94 + "flake-utils": "flake-utils_2", 95 + "nixpkgs": "nixpkgs_2" 41 96 } 42 97 }, 43 98 "systems": { 99 + "locked": { 100 + "lastModified": 1681028828, 101 + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 102 + "owner": "nix-systems", 103 + "repo": "default", 104 + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 105 + "type": "github" 106 + }, 107 + "original": { 108 + "owner": "nix-systems", 109 + "repo": "default", 110 + "type": "github" 111 + } 112 + }, 113 + "systems_2": { 44 114 "locked": { 45 115 "lastModified": 1681028828, 46 116 "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+3 -1
flake.nix
··· 4 4 inputs = { 5 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 6 flake-utils.url = "github:numtide/flake-utils"; 7 + beads.url = "github:steveyegge/beads/v0.23.0"; 7 8 }; 8 9 9 - outputs = { self, nixpkgs, flake-utils }: 10 + outputs = { self, nixpkgs, flake-utils, beads }: 10 11 flake-utils.lib.eachDefaultSystem (system: 11 12 let 12 13 pkgs = nixpkgs.legacyPackages.${system}; ··· 14 15 { 15 16 devShells.default = pkgs.mkShell { 16 17 buildInputs = with pkgs; [ 18 + beads.packages.${system}.default 17 19 bun 18 20 nodejs_22 19 21 pnpm
+45 -21
public/index.html
··· 3 3 <head> 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 - <title>seams.so - Web Annotations on AT Protocol</title> 6 + <title>seams.so - Wisdom is made Together</title> 7 7 <link rel="stylesheet" href="landing.css"> 8 8 </head> 9 9 <body> 10 - <div class="container"> 11 - <header class="hero"> 12 - <h1>seams.so</h1> 13 - <p class="tagline">Web annotations on AT Protocol</p> 14 - <p class="description"> 15 - Highlight, annotate, and discuss any webpage. Built on the open AT Protocol, 16 - your annotations live in your personal data server. 17 - </p> 18 - </header> 10 + <div class="layout"> 11 + <aside class="sidebar"> 12 + <div class="sidebar-content"> 13 + <header class="hero"> 14 + <div class="logo">Seams</div> 15 + <h1>Wisdom is made Together</h1> 16 + <p class="tagline">Annotations in the Atmosphere</p> 17 + <div class="cta-buttons"> 18 + <a href="#install" class="cta-primary">Install Extension</a> 19 + </div> 20 + </header> 19 21 20 - <main class="feed-section"> 21 - <h2>Recent Annotations</h2> 22 - <div id="annotations-feed" class="annotations-feed"> 23 - <div class="loading">Loading annotations...</div> 22 + <footer class="footer desktop-footer"> 23 + <div class="footer-icons"> 24 + <a href="https://tangled.org/@hyl.st/seams.so" target="_blank" aria-label="Tangled"> 25 + <img src="https://semble.so/_next/static/media/tangled-icon.b95d4d65.svg" alt="Tangled" /> 26 + </a> 27 + <a href="https://bsky.app" target="_blank" aria-label="Bluesky"> 28 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 320"> 29 + <path fill="currentColor" d="M180 142c-16.3-31.7-60.7-90.8-102-120C38.5-5.9 23.4-1 13.5 3.4 2.1 8.6 0 26.2 0 36.5c0 10.4 5.7 84.8 9.4 97.2 12.2 41 55.7 55 95.7 50.5-58.7 8.6-110.8 30-42.4 106.1 75.1 77.9 103-16.7 117.3-64.6 14.3 48 30.8 139 116 64.6 64-64.6 17.6-97.5-41.1-106.1 40 4.4 83.5-9.5 95.7-50.5 3.7-12.4 9.4-86.8 9.4-97.2 0-10.3-2-27.9-13.5-33C336.5-1 321.5-6 282 22c-41.3 29.2-85.7 88.3-102 120Z"/> 30 + </svg> 31 + </a> 32 + </div> 33 + </footer> 24 34 </div> 25 - <div id="load-more" class="load-more" style="display: none;"> 26 - <button id="load-more-btn">Load More</button> 35 + </aside> 36 + 37 + <main class="main-content"> 38 + <div class="feed-section" id="feed"> 39 + <div id="annotations-feed" class="annotations-feed"> 40 + <div class="loading">Tending the garden...</div> 41 + </div> 42 + <div id="load-more" class="load-more" style="display: none;"> 43 + <button id="load-more-btn">Nurture More</button> 44 + </div> 27 45 </div> 28 46 </main> 29 47 30 - <footer class="footer"> 31 - <p> 32 - <a href="https://github.com/Chickensoupwithrice/synthes.is" target="_blank">GitHub</a> 33 - · Built with AT Protocol 34 - </p> 48 + <footer class="footer mobile-footer"> 49 + <div class="footer-icons"> 50 + <a href="https://tangled.org/@hyl.st/seams.so" target="_blank" aria-label="Tangled"> 51 + <img src="https://semble.so/_next/static/media/tangled-icon.b95d4d65.svg" alt="Tangled" /> 52 + </a> 53 + <a href="https://bsky.app" target="_blank" aria-label="Bluesky"> 54 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 320"> 55 + <path fill="currentColor" d="M180 142c-16.3-31.7-60.7-90.8-102-120C38.5-5.9 23.4-1 13.5 3.4 2.1 8.6 0 26.2 0 36.5c0 10.4 5.7 84.8 9.4 97.2 12.2 41 55.7 55 95.7 50.5-58.7 8.6-110.8 30-42.4 106.1 75.1 77.9 103-16.7 117.3-64.6 14.3 48 30.8 139 116 64.6 64-64.6 17.6-97.5-41.1-106.1 40 4.4 83.5-9.5 95.7-50.5 3.7-12.4 9.4-86.8 9.4-97.2 0-10.3-2-27.9-13.5-33C336.5-1 321.5-6 282 22c-41.3 29.2-85.7 88.3-102 120Z"/> 56 + </svg> 57 + </a> 58 + </div> 35 59 </footer> 36 60 </div> 37 61
+219 -64
public/landing.css
··· 4 4 padding: 0; 5 5 } 6 6 7 + :root { 8 + --forest-green: #2d5016; 9 + --forest-green-light: #3d6b1f; 10 + --forest-green-dark: #1f3810; 11 + } 12 + 7 13 body { 8 14 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 9 15 background: #fafafa; 10 16 color: #1a1a1a; 11 17 position: relative; 12 18 line-height: 1.6; 19 + margin: 0; 20 + padding: 0; 13 21 } 14 22 15 23 /* Blueprint grid background */ ··· 19 27 inset: 0; 20 28 pointer-events: none; 21 29 background-image: 22 - radial-gradient(circle, rgba(0, 0, 0, 0.08) 1px, transparent 1px); 30 + radial-gradient(circle, rgba(45, 80, 22, 0.06) 1px, transparent 1px); 23 31 background-size: 20px 20px; 24 32 z-index: 0; 25 33 } 26 34 27 - .container { 28 - max-width: 800px; 29 - margin: 0 auto; 30 - padding: 40px 20px; 35 + /* Layout - Sidebar + Main Content */ 36 + .layout { 37 + display: flex; 38 + min-height: 100vh; 31 39 position: relative; 32 40 z-index: 1; 33 41 } 34 42 35 - /* Hero Section */ 43 + /* Sidebar */ 44 + .sidebar { 45 + width: 420px; 46 + background: #fff; 47 + border-right: 2px dashed #d0d0d0; 48 + position: sticky; 49 + top: 0; 50 + height: 100vh; 51 + overflow-y: auto; 52 + flex-shrink: 0; 53 + } 54 + 55 + .sidebar-content { 56 + display: flex; 57 + flex-direction: column; 58 + justify-content: space-between; 59 + min-height: 100vh; 60 + padding: 60px 0; 61 + } 62 + 63 + /* Hero Section in Sidebar */ 36 64 .hero { 65 + flex: 1; 66 + display: flex; 67 + flex-direction: column; 68 + justify-content: center; 69 + align-items: center; 37 70 text-align: center; 38 - padding: 60px 20px; 39 - margin-bottom: 60px; 40 - border: 1px dashed #d0d0d0; 41 - border-radius: 2px; 42 - background: #fff; 71 + padding: 0 48px; 72 + } 73 + 74 + .logo { 75 + font-size: 14px; 76 + font-weight: 600; 77 + letter-spacing: 0.15em; 78 + text-transform: uppercase; 79 + color: #999; 80 + margin-bottom: 24px; 43 81 } 44 82 45 83 .hero h1 { 46 - font-size: 48px; 84 + font-size: clamp(32px, 3.5vw, 48px); 47 85 font-weight: 700; 48 - margin-bottom: 16px; 49 - color: #0085ff; 86 + margin-bottom: 24px; 87 + color: #1a1a1a; 88 + line-height: 1.1; 89 + letter-spacing: -0.02em; 50 90 } 51 91 52 92 .tagline { 53 - font-size: 20px; 93 + font-size: 14px; 54 94 color: #666; 55 - margin-bottom: 24px; 95 + margin-bottom: 32px; 96 + font-weight: 400; 97 + line-height: 1.6; 98 + } 99 + 100 + /* CTA Buttons */ 101 + .cta-buttons { 102 + display: flex; 103 + gap: 12px; 104 + flex-direction: column; 105 + align-items: center; 106 + } 107 + 108 + .cta-primary, 109 + .cta-secondary { 110 + padding: 12px 28px; 111 + border-radius: 2px; 112 + font-size: 14px; 56 113 font-weight: 500; 114 + text-decoration: none; 115 + transition: all 0.2s; 116 + border: 1px dashed; 117 + display: inline-block; 57 118 } 58 119 59 - .description { 60 - font-size: 16px; 61 - color: #555; 62 - max-width: 600px; 63 - margin: 0 auto; 64 - line-height: 1.7; 120 + .cta-primary { 121 + background: var(--forest-green); 122 + color: #fff; 123 + border-color: var(--forest-green-dark); 124 + } 125 + 126 + .cta-primary:hover { 127 + background: var(--forest-green-dark); 128 + transform: translateY(-1px); 129 + } 130 + 131 + .cta-secondary { 132 + background: transparent; 133 + color: var(--forest-green); 134 + border-color: var(--forest-green); 135 + } 136 + 137 + .cta-secondary:hover { 138 + border-color: var(--forest-green-dark); 139 + background: rgba(45, 80, 22, 0.05); 140 + } 141 + 142 + /* Main Content Area */ 143 + .main-content { 144 + flex: 1; 145 + background: #fafafa; 146 + overflow-y: auto; 65 147 } 66 148 67 149 /* Feed Section */ 68 150 .feed-section { 69 - margin-bottom: 60px; 70 - } 71 - 72 - .feed-section h2 { 73 - font-size: 24px; 74 - margin-bottom: 24px; 75 - font-weight: 600; 76 - color: #333; 151 + padding: 60px 48px; 152 + max-width: 900px; 77 153 } 78 154 79 155 .annotations-feed { 80 156 display: flex; 81 157 flex-direction: column; 82 - gap: 20px; 158 + gap: 24px; 83 159 } 84 160 85 161 /* Annotation Card */ 86 162 .annotation-card { 87 - padding: 20px; 163 + padding: 24px; 88 164 border: 1px dashed #d0d0d0; 89 165 border-radius: 2px; 90 166 background: #fff; 91 - transition: border-color 0.2s; 167 + transition: all 0.2s; 168 + position: relative; 92 169 } 93 170 94 171 .annotation-card:hover { 95 - border-color: #0085ff; 172 + border-color: var(--forest-green); 173 + box-shadow: 0 2px 8px rgba(45, 80, 22, 0.08); 96 174 } 97 175 98 176 .annotation-quote { 99 177 margin-bottom: 16px; 100 178 padding: 12px 16px; 101 179 background: #fafafa; 102 - border-left: 3px solid #0085ff; 180 + border-left: 3px solid var(--forest-green); 103 181 font-style: italic; 104 182 color: #555; 105 183 font-size: 15px; 184 + line-height: 1.6; 106 185 } 107 186 108 187 .annotation-body { ··· 124 203 } 125 204 126 205 .annotation-source { 127 - color: #0085ff; 206 + color: #1a1a1a; 128 207 text-decoration: none; 129 208 font-weight: 500; 130 209 display: inline-flex; 131 210 align-items: center; 132 211 gap: 4px; 212 + border-bottom: 1px dashed transparent; 213 + transition: border-color 0.2s; 133 214 } 134 215 135 216 .annotation-source:hover { 136 - text-decoration: underline; 217 + border-bottom-color: #1a1a1a; 137 218 } 138 219 139 220 .annotation-author { ··· 148 229 height: 24px; 149 230 border-radius: 50%; 150 231 object-fit: cover; 232 + border: 1px dashed #d0d0d0; 151 233 } 152 234 153 235 .annotation-author a { 154 - color: #0085ff; 236 + color: #1a1a1a; 155 237 text-decoration: none; 156 238 font-weight: 500; 239 + border-bottom: 1px dashed transparent; 240 + transition: border-color 0.2s; 157 241 } 158 242 159 243 .annotation-author a:hover { 160 - text-decoration: underline; 244 + border-bottom-color: #1a1a1a; 161 245 } 162 246 163 247 .annotation-time { ··· 169 253 .empty, 170 254 .error { 171 255 text-align: center; 172 - padding: 40px 20px; 256 + padding: 60px 20px; 173 257 color: #999; 174 258 font-style: italic; 175 259 } ··· 182 266 /* Load More */ 183 267 .load-more { 184 268 text-align: center; 185 - margin-top: 32px; 269 + margin-top: 40px; 186 270 } 187 271 188 272 #load-more-btn { 189 - background: #0085ff; 273 + background: var(--forest-green); 190 274 color: white; 191 - border: 1px dashed #0070dd; 275 + border: 1px dashed var(--forest-green-dark); 192 276 padding: 12px 32px; 193 277 border-radius: 2px; 194 278 cursor: pointer; 195 279 font-size: 14px; 196 280 font-weight: 500; 197 - transition: background 0.2s; 281 + transition: all 0.2s; 198 282 } 199 283 200 284 #load-more-btn:hover { 201 - background: #0070dd; 285 + background: var(--forest-green-dark); 286 + transform: translateY(-1px); 202 287 } 203 288 204 289 #load-more-btn:disabled { 205 290 background: #ccc; 206 291 border-color: #aaa; 207 292 cursor: not-allowed; 293 + transform: none; 208 294 } 209 295 210 - /* Footer */ 296 + /* Footer in Sidebar */ 211 297 .footer { 298 + padding-top: 40px; 299 + color: #999; 300 + font-size: 13px; 212 301 text-align: center; 213 - padding: 40px 20px; 214 - color: #666; 215 - font-size: 14px; 302 + margin: 0; 303 + border-top: 2px dashed #d0d0d0; 304 + } 305 + 306 + .mobile-footer { 307 + display: none; 308 + } 309 + 310 + .desktop-footer { 311 + display: block; 312 + } 313 + 314 + .footer-icons { 315 + display: flex; 316 + gap: 20px; 317 + justify-content: center; 318 + align-items: center; 216 319 } 217 320 218 - .footer a { 219 - color: #0085ff; 321 + .footer-icons a { 322 + color: #1a1a1a; 220 323 text-decoration: none; 221 - font-weight: 500; 324 + transition: all 0.2s; 325 + display: flex; 326 + align-items: center; 327 + justify-content: center; 328 + } 329 + 330 + .footer-icons a img, 331 + .footer-icons a svg { 332 + width: 32px; 333 + height: 32px; 334 + opacity: 0.6; 335 + transition: opacity 0.2s; 222 336 } 223 337 224 - .footer a:hover { 225 - text-decoration: underline; 338 + .footer-icons a:hover img, 339 + .footer-icons a:hover svg { 340 + opacity: 1; 226 341 } 227 342 228 343 /* Responsive */ 344 + @media (max-width: 1024px) { 345 + .layout { 346 + flex-direction: column; 347 + } 348 + 349 + .sidebar { 350 + width: 100%; 351 + height: auto; 352 + position: relative; 353 + border-right: none; 354 + border-bottom: 2px dashed #d0d0d0; 355 + } 356 + 357 + .sidebar-content { 358 + min-height: auto; 359 + padding: 40px 0; 360 + } 361 + 362 + .hero { 363 + justify-content: flex-start; 364 + padding: 0 32px; 365 + } 366 + 367 + .desktop-footer { 368 + display: none; 369 + } 370 + 371 + .mobile-footer { 372 + display: block; 373 + padding: 40px 32px; 374 + margin: 0; 375 + border-top: 2px dashed #d0d0d0; 376 + background: #fafafa; 377 + } 378 + 379 + .feed-section { 380 + padding: 48px 32px; 381 + } 382 + } 383 + 229 384 @media (max-width: 640px) { 230 - .container { 231 - padding: 20px 16px; 385 + .sidebar-content { 386 + padding: 32px 0; 232 387 } 233 388 234 389 .hero { 235 - padding: 40px 16px; 236 - margin-bottom: 40px; 390 + padding: 0 24px; 237 391 } 238 392 239 393 .hero h1 { 240 - font-size: 36px; 394 + font-size: 32px; 241 395 } 242 396 243 - .tagline { 244 - font-size: 18px; 397 + .mobile-footer { 398 + padding: 32px 24px; 399 + font-size: 12px; 245 400 } 246 401 247 - .description { 248 - font-size: 15px; 402 + .feed-section { 403 + padding: 32px 24px; 249 404 } 250 405 251 406 .annotation-card { 252 - padding: 16px; 407 + padding: 20px; 253 408 } 254 409 }
+2 -1
public/oauth/client-metadata.json
··· 4 4 "redirect_uris": [ 5 5 "https://synthes-is.netlify.app", 6 6 "https://synthes-is.netlify.app/oauth/callback", 7 - "https://synthes-is.netlify.app/oauth/ff/callback" 7 + "https://synthes-is.netlify.app/oauth/ff/callback", 8 + "https://e7a0b7703dc3d21c8ef60539da3ed68d27b48e8c.extensions.allizom.org/" 8 9 ], 9 10 "application_type": "web", 10 11 "client_name": "Synthesis",
+2 -4
public/oauth/ff/callback.html
··· 8 8 <p>Redirecting...</p> 9 9 <script> 10 10 // Relay to Firefox extension callback 11 - // Firefox extensions use browser.identity.getRedirectURL() which returns a moz-extension:// URL 12 - // The actual URL will be captured by launchWebAuthFlow 13 - // For Firefox, we redirect to a web_accessible_resource 14 - const extRedirect = browser.identity.getRedirectURL('extension-callback.html'); 11 + // The extension ID is synthesis@seams.so, which Firefox hashes to this subdomain 12 + const extRedirect = 'https://e7a0b7703dc3d21c8ef60539da3ed68d27b48e8c.extensions.allizom.org/'; 15 13 window.location.href = extRedirect + window.location.search + window.location.hash; 16 14 </script> 17 15 </body>
+7
wxt.config.ts
··· 8 8 ...(env.browser === 'chrome' && { 9 9 key: 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyv6hsV+VmGtQB8kZFQE0x0VYvhH0Lq2GzDhKZHh9BvPZLmFJQjXqzD9K0UzXxMXBj8FqV3WEJ9xFzDqJc+hKRBqJFQp0vXYrG8hVLVsqxW2wYpF1K8ZqMH3J0V2VB9C3KxvqBJk9kQxqHj8BvXJFqVQ3E5VqJzYqK0Hh9vK0E2J1YxLqJ8kV9qBxV0E1J2V3kQxqFz8B1XJFqVQ3E5VqJzYqK0Hh9vK0E2J1YxLqJ8kV9qBxV0E1J2V3kQxqFz8B1XJFqVQ3E5VqJzYqK0Hh9vK0E2J1YxLqJ8kV9qBxV0E1J2V3kQxqFz8B1XJFqVQ3E5VqJzYqK0Hh9vK0E2J1YxLqJ8kV9qBxV0E1J2V3kQxqFQIDAQAB', 10 10 }), 11 + ...(env.browser === 'firefox' && { 12 + browser_specific_settings: { 13 + gecko: { 14 + id: 'synthesis@seams.so', 15 + }, 16 + }, 17 + }), 11 18 permissions: [ 12 19 'storage', 13 20 'tabs',