Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com

Tweaked brand graphics

+677 -85
+1
AGENTS.md
··· 216 216 ``` 217 217 218 218 Static files are served from `static/` at `/static/`. 219 +
bin/server

This is a binary file and will not be displayed.

docs/assets/16.png

This is a binary file and will not be displayed.

docs/assets/32.png

This is a binary file and will not be displayed.

docs/assets/48.png

This is a binary file and will not be displayed.

docs/assets/64.png

This is a binary file and will not be displayed.

docs/assets/dd-logo.png

This is a binary file and will not be displayed.

+80
docs/assets/dd-logo.svg
··· 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <svg 3 + width="365" 4 + height="466.50885" 5 + viewBox="0 0 365 466.50885" 6 + version="1.1" 7 + xml:space="preserve" 8 + style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2" 9 + id="svg8" 10 + xmlns="http://www.w3.org/2000/svg" 11 + xmlns:svg="http://www.w3.org/2000/svg"><defs 12 + id="defs8" /> 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + <g 21 + id="g9" 22 + transform="matrix(10.138889,0,0,10.602474,-20.277778,-21.204948)"><path 23 + d="M 2,4 C 2,2.895 2.895,2 4,2 h 22 l 12,12 v 30 c 0,1.105 -0.895,2 -2,2 H 4 C 2.895,46 2,45.105 2,44 Z" 24 + style="fill:#2563eb" 25 + id="path1" /><path 26 + d="M 7.9224904,13.449877 H 6.1110306 v -1.04191 h 1.7326966 c 0.7963736,0 1.457103,-0.146446 1.9821849,-0.439355 0.5250799,-0.292911 0.9167029,-0.711339 1.1748679,-1.255305 0.258169,-0.548157 0.387252,-1.2009176 0.387252,-1.9582872 0,-0.7490003 -0.12909,-1.393392 -0.387252,-1.9331744 C 10.746997,6.2820628 10.366305,5.8678111 9.8587302,5.57909 9.355527,5.2861849 8.7232396,5.139732 7.9618709,5.139732 H 6.1110306 V 4.097847 l 1.9361656,-2.1e-5 c 0.9538997,-1.05e-5 1.7677766,0.1862038 2.4416338,0.5586122 0.67823,0.3724081 1.196749,0.9080066 1.555554,1.606795 0.363179,0.6946035 0.544769,1.5251982 0.544769,2.4917866 0,0.9749583 -0.18159,1.8139222 -0.544769,2.5168922 -0.363177,0.698793 -0.892637,1.236485 -1.588377,1.613074 -0.6957302,0.376591 -1.5402366,0.564891 -2.5335166,0.564891 z M 6.1109554,4.097826 v 9.352051 H 4.8770122 V 4.097826 Z" 27 + id="text1" 28 + style="font-size:67.4282px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#ececec;stroke-width:0.258756" 29 + aria-label="D" /><text 30 + style="font-style:normal;font-size:13.1447px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#b3b3b3;stroke-width:0.258756" 31 + x="10.490101" 32 + y="13.585623" 33 + id="text2" 34 + transform="scale(1.0226062,0.97789354)">d</text><g 35 + transform="matrix(0,-1.475264,1,0,-17.976555,48.258067)" 36 + id="g2"> 37 + <path 38 + d="m 11,28 c 0,0.552 -0.304,1 -0.678,1 H 7.678 C 7.304,29 7,28.552 7,28 7,27.448 7.304,27 7.678,27 h 2.644 C 10.696,27 11,27.448 11,28 Z" 39 + style="fill:#03d02c" 40 + id="path2" /> 41 + </g><g 42 + transform="matrix(1.495816,0,0,1,-3.470715,7)" 43 + id="g3"> 44 + <path 45 + d="m 11,28 c 0,0.552 -0.3,1 -0.669,1 H 7.669 C 7.3,29 7,28.552 7,28 7,27.448 7.3,27 7.669,27 h 2.662 C 10.7,27 11,27.448 11,28 Z" 46 + style="fill:#03d02c" 47 + id="path3" /> 48 + </g><path 49 + d="M 26,2 38,14 H 28 c -1.105,0 -2,-0.895 -2,-2 z" 50 + style="fill:#1a56db;fill-rule:nonzero" 51 + id="path4" /><g 52 + transform="matrix(1.226958,0,0,1,-1.581784,0)" 53 + id="g5"> 54 + <path 55 + d="m 29,21 c 0,0.552 -0.365,1 -0.815,1 H 7.815 C 7.365,22 7,21.552 7,21 7,20.448 7.365,20 7.815,20 h 20.37 C 28.635,20 29,20.448 29,21 Z" 56 + style="fill:#ffffff;fill-opacity:0.4" 57 + id="path5" /> 58 + </g><g 59 + transform="matrix(1.51098,0,0,1,-3.576862,0)" 60 + id="g6"> 61 + <path 62 + d="m 11,28 c 0,0.552 -0.297,1 -0.662,1 H 7.662 C 7.297,29 7,28.552 7,28 7,27.448 7.297,27 7.662,27 h 2.676 C 10.703,27 11,27.448 11,28 Z" 63 + style="fill:#fca5a5" 64 + id="path6" /> 65 + </g><g 66 + transform="translate(2)" 67 + id="g7"> 68 + <path 69 + d="m 27,28 c 0,0.552 -0.448,1 -1,1 H 14 c -0.552,0 -1,-0.448 -1,-1 0,-0.552 0.448,-1 1,-1 h 12 c 0.552,0 1,0.448 1,1 z" 70 + style="fill:#ffffff;fill-opacity:0.3" 71 + id="path7" /> 72 + </g><g 73 + transform="matrix(1.055556,0,0,1,1.277778,0)" 74 + id="g8"> 75 + <path 76 + d="m 31,35 c 0,0.552 -0.425,1 -0.947,1 H 13.947 C 13.425,36 13,35.552 13,35 c 0,-0.552 0.425,-1 0.947,-1 H 30.053 C 30.575,34 31,34.448 31,35 Z" 77 + style="fill:#ffffff;fill-opacity:0.8" 78 + id="path8" /> 79 + </g></g> 80 + </svg>
docs/assets/dd-logograph.png

This is a binary file and will not be displayed.

+52
docs/assets/diffdown-logo-inkscape.svg
··· 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <svg 3 + width="420" 4 + height="420" 5 + viewBox="43 84 327.6 327.6" 6 + version="1.1" 7 + id="svg2" 8 + sodipodi:docname="diffdown-logo-inkscape.svg" 9 + inkscape:version="1.3.2 (091e20e, 2023-11-25)" 10 + inkscape:export-filename="favicon.png" 11 + inkscape:export-xdpi="96" 12 + inkscape:export-ydpi="96" 13 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 14 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 15 + xmlns="http://www.w3.org/2000/svg" 16 + xmlns:svg="http://www.w3.org/2000/svg"> 17 + <defs 18 + id="defs2" /> 19 + <sodipodi:namedview 20 + id="namedview2" 21 + pagecolor="#ffffff" 22 + bordercolor="#000000" 23 + borderopacity="0.25" 24 + inkscape:showpageshadow="2" 25 + inkscape:pageopacity="0.0" 26 + inkscape:pagecheckerboard="0" 27 + inkscape:deskcolor="#d1d1d1" 28 + inkscape:zoom="3.42" 29 + inkscape:cx="43.128655" 30 + inkscape:cy="49.853801" 31 + inkscape:window-width="1392" 32 + inkscape:window-height="1184" 33 + inkscape:window-x="3277" 34 + inkscape:window-y="31" 35 + inkscape:window-maximized="0" 36 + inkscape:current-layer="svg2" 37 + inkscape:export-bgcolor="#ffffffff" /> 38 + <g 39 + id="g2" 40 + transform="matrix(5.7367355,0,0,5.7367355,-259.39616,-458.25129)"> 41 + <text 42 + style="font-style:normal;font-size:50.8px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#2563eb;fill-opacity:1" 43 + x="52.5" 44 + y="141.88016" 45 + id="text1">D</text> 46 + <text 47 + style="font-style:normal;font-size:50.8px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#0000ff" 48 + x="78.900238" 49 + y="141.22972" 50 + id="text2">d</text> 51 + </g> 52 + </svg>
docs/assets/diffdown.ico

This is a binary file and will not be displayed.

docs/assets/favicon.png

This is a binary file and will not be displayed.

+512
docs/superpowers/plans/2026-03-17-tailwindcss-migration.md
··· 1 + # TailwindCSS Migration Implementation Plan 2 + 3 + > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. 4 + 5 + **Goal:** Replace the ~1000 lines of custom CSS with TailwindCSS utility classes, while preserving the existing design and dark mode support. 6 + 7 + **Architecture:** 8 + 1. Install TailwindCSS as a dev dependency with PostCSS 9 + 2. Create a minimal `tailwind.config.js` that extends the default theme with the existing color palette 10 + 3. Keep a small `base.css` for critical custom styles that can't be replaced (e.g., CodeMirror overrides, Milkdown-specific styles) 11 + 4. Replace HTML class names with Tailwind utility classes in templates 12 + 5. Use `@apply` for complex patterns that appear multiple times 13 + 14 + **Tech Stack:** TailwindCSS 4.x, PostCSS, existing esbuild for CSS bundling 15 + 16 + --- 17 + 18 + ## Current CSS Inventory 19 + 20 + | File | Lines | Purpose | 21 + |------|-------|---------| 22 + | `static/css/style.css` | 427 | Base styles, navbar, cards, buttons, forms, alerts | 23 + | `static/css/editor.css` | 419 | Editor layout, toolbar, modals, split pane | 24 + | `static/css/markdown.css` | 84 | Markdown preview rendering | 25 + | `static/css/diff.css` | 60 | Diff view styling | 26 + | **Total** | **990** | | 27 + 28 + --- 29 + 30 + ## Chunk 1: Setup TailwindCSS 31 + 32 + **Files:** 33 + - Modify: `/Users/johnluther/projects/diffdown/package.json` 34 + - Create: `/Users/johnluther/projects/diffdown/tailwind.config.js` 35 + - Create: `/Users/johnluther/projects/diffdown/postcss.config.js` 36 + - Create: `/Users/johnluther/projects/diffdown/src/styles/input.css` 37 + 38 + - [ ] **Step 1: Install TailwindCSS and dependencies** 39 + 40 + Run: `npm install -D tailwindcss postcss autoprefixer` 41 + 42 + - [ ] **Step 2: Initialize Tailwind config** 43 + 44 + ```javascript 45 + /** @type {import('tailwindcss').Config} */ 46 + module.exports = { 47 + content: [ 48 + "./templates/**/*.html", 49 + "./static/**/*.js", 50 + ], 51 + darkMode: 'class', // Use data-theme attribute for dark mode 52 + theme: { 53 + extend: { 54 + colors: { 55 + bg: 'var(--bg)', 56 + 'bg-card': 'var(--bg-card)', 57 + text: 'var(--text)', 58 + 'text-muted': 'var(--text-muted)', 59 + border: 'var(--border)', 60 + primary: 'var(--primary)', 61 + 'primary-hover': 'var(--primary-hover)', 62 + danger: 'var(--danger)', 63 + success: 'var(--success)', 64 + 'code-bg': 'var(--code-bg)', 65 + 'alert-error-bg': 'var(--alert-error-bg)', 66 + 'alert-error-border': 'var(--alert-error-border)', 67 + }, 68 + fontFamily: { 69 + sans: ['"Barlow"', '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', 'sans-serif'], 70 + heading: ['"Lexend"', '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', 'sans-serif'], 71 + mono: ['"JetBrains Mono"', '"Fira Code"', '"Cascadia Code"', 'monospace'], 72 + }, 73 + borderRadius: { 74 + DEFAULT: '6px', 75 + }, 76 + }, 77 + }, 78 + plugins: [], 79 + } 80 + ``` 81 + 82 + - [ ] **Step 3: Create PostCSS config** 83 + 84 + ```javascript 85 + module.exports = { 86 + plugins: { 87 + tailwindcss: {}, 88 + autoprefixer: {}, 89 + }, 90 + } 91 + ``` 92 + 93 + - [ ] **Step 4: Create input.css for Tailwind directives** 94 + 95 + ```css 96 + @tailwind base; 97 + @tailwind components; 98 + @tailwind utilities; 99 + 100 + /* Keep custom font import */ 101 + @import url(https://fonts.bunny.net/css?family=barlow:100,200,300,400,500,600|lexend:100,200,300,400,500,600,700,800,900); 102 + 103 + /* CSS variables - kept for backward compatibility */ 104 + :root { 105 + --bg: #fafafa; 106 + --bg-card: #fff; 107 + --text: #1a1a2e; 108 + --text-muted: #6b7280; 109 + --border: #e5e7eb; 110 + --primary: #2563eb; 111 + --primary-hover: #1d4ed8; 112 + --danger: #dc2626; 113 + --success: #16a34a; 114 + --code-bg: #f3f4f6; 115 + --alert-error-bg: #fef2f2; 116 + --alert-error-border: #fecaca; 117 + } 118 + 119 + [data-theme="dark"] { 120 + --bg: #0d1117; 121 + --bg-card: #161b22; 122 + --text: #e6edf3; 123 + --text-muted: #ededed; 124 + --text-secondary: #d4d4d4; 125 + --border: #30363d; 126 + --code-bg: #1f2428; 127 + --primary: #388bfd; 128 + --primary-hover: #58a6ff; 129 + --danger: #f85149; 130 + --success: #3fb950; 131 + --alert-error-bg: #1c0608; 132 + --alert-error-border: #6e1c20; 133 + } 134 + 135 + @media (prefers-color-scheme: dark) { 136 + :root:not([data-theme="light"]) { 137 + --bg: #0d1117; 138 + --bg-card: #161b22; 139 + --text: #e6edf3; 140 + --text-muted: #ededed; 141 + --text-secondary: #d4d4d4; 142 + --border: #30363d; 143 + --code-bg: #1f2428; 144 + --primary: #388bfd; 145 + --primary-hover: #58a6ff; 146 + --danger: #f85149; 147 + --success: #3fb950; 148 + --alert-error-bg: #1c0608; 149 + --alert-error-border: #6e1c20; 150 + } 151 + } 152 + ``` 153 + 154 + - [ ] **Step 5: Add build script to package.json** 155 + 156 + ```json 157 + "scripts": { 158 + "build:css": "npx tailwindcss -i ./src/styles/input.css -o ./static/css/tailwind.css", 159 + "build:collab": "npx esbuild node_modules/prosemirror-collab/dist/index.js --bundle --format=esm --outfile=static/vendor/collab.js", 160 + "build": "npm run build:css && npm run build:collab" 161 + } 162 + ``` 163 + 164 + - [ ] **Step 6: Build TailwindCSS** 165 + 166 + Run: `npm run build:css` 167 + 168 + Expected: Creates `static/css/tailwind.css` with Tailwind utilities 169 + 170 + - [ ] **Step 7: Commit** 171 + 172 + ```bash 173 + git add package.json tailwind.config.js postcss.config.js src/styles/input.css static/css/tailwind.css 174 + git commit -m "feat: add TailwindCSS setup" 175 + ``` 176 + 177 + --- 178 + 179 + ## Chunk 2: Replace CSS in base.html 180 + 181 + **Files:** 182 + - Modify: `/Users/johnluther/projects/diffdown/templates/base.html` 183 + 184 + - [ ] **Step 1: Replace navbar styles with Tailwind classes** 185 + 186 + Old: 187 + ```html 188 + <nav class="navbar"> 189 + <a href="/" class="logo"> 190 + <img src="/static/img/dd-logo.svg" alt="" width="22" height="28" style="vertical-align:middle;margin-right:0.4rem">Diffdown 191 + </a> 192 + <div class="nav-right"> 193 + {{if .User}} 194 + <a href="/">Documents</a> 195 + <a href="/about">About</a> 196 + <span class="nav-user">{{.User.Name}}</span> 197 + <form method="post" action="/auth/logout" style="display:inline"> 198 + <button type="submit" class="btn-link">Log out</button> 199 + </form> 200 + {{else}} 201 + <a href="/auth/login">Log in</a> 202 + <a href="/auth/register" class="btn btn-sm">Sign up</a> 203 + <a href="/about">About</a> 204 + {{end}} 205 + <button id="theme-toggle" class="btn-link" aria-label="Toggle dark mode" onclick="toggleTheme()" style="font-size:1.1rem;padding:0.25rem">☀</button> 206 + </div> 207 + </nav> 208 + ``` 209 + 210 + New: 211 + ```html 212 + <nav class="flex items-center justify-between px-6 py-3 border-b border-[var(--border)]"> 213 + <a href="/" class="flex items-center"> 214 + <img src="/static/img/dd-logo.svg" alt="" width="22" height="28" class="align-middle mr-1">Diffdown 215 + </a> 216 + <div class="flex items-center gap-4"> 217 + {{if .User}} 218 + <a href="/" class="text-[var(--primary)] hover:underline">Documents</a> 219 + <a href="/about" class="text-[var(--primary)] hover:underline">About</a> 220 + <span class="text-[var(--text-muted)]">{{.User.Name}}</span> 221 + <form method="post" action="/auth/logout"> 222 + <button type="submit" class="text-[var(--primary)] bg-transparent border-none cursor-pointer hover:underline">Log out</button> 223 + </form> 224 + {{else}} 225 + <a href="/auth/login" class="text-[var(--primary)] hover:underline">Log in</a> 226 + <a href="/auth/register" class="px-3 py-1.5 text-sm bg-[var(--primary)] text-white rounded hover:bg-[var(--primary-hover)]">Sign up</a> 227 + <a href="/about" class="text-[var(--primary)] hover:underline">About</a> 228 + {{end}} 229 + <button id="theme-toggle" class="text-[var(--primary)] bg-transparent border-none cursor-pointer text-lg" aria-label="Toggle dark mode" onclick="toggleTheme()">☀</button> 230 + </div> 231 + </nav> 232 + ``` 233 + 234 + - [ ] **Step 2: Replace main and alert styles** 235 + 236 + Old: 237 + ```html 238 + <main> 239 + {{if .Error}} 240 + <div class="alert alert-error">{{.Error}}</div> 241 + {{end}} 242 + {{block "content" .}}{{end}} 243 + </main> 244 + ``` 245 + 246 + New: 247 + ```html 248 + <main class="p-6"> 249 + {{if .Error}} 250 + <div class="p-4 mb-4 bg-[var(--alert-error-bg)] border border-[var(--alert-error-border)] rounded text-[var(--danger)]">{{.Error}}</div> 251 + {{end}} 252 + {{block "content" .}}{{end}} 253 + </main> 254 + ``` 255 + 256 + - [ ] **Step 3: Update base.html to link tailwind.css instead of style.css** 257 + 258 + Old: 259 + ```html 260 + <link rel="stylesheet" href="/static/css/style.css"> 261 + ``` 262 + 263 + New (keep style.css for now, we'll remove later): 264 + ```html 265 + <link rel="stylesheet" href="/static/css/tailwind.css"> 266 + <link rel="stylesheet" href="/static/css/style.css"> 267 + ``` 268 + 269 + - [ ] **Step 4: Test locally** 270 + 271 + Run: `make run` 272 + Open: `http://127.0.0.1:8080` 273 + Verify: Navbar, main content, and dark mode still work 274 + 275 + - [ ] **Step 5: Commit** 276 + 277 + ```bash 278 + git add templates/base.html 279 + git commit -m "refactor: convert base.html to TailwindCSS classes" 280 + ``` 281 + 282 + --- 283 + 284 + ## Chunk 3: Replace style.css (base styles) 285 + 286 + **Files:** 287 + - Modify: `/Users/johnluther/projects/diffdown/templates/landing.html` 288 + - Modify: `/Users/johnluther/projects/diffdown/templates/documents.html` 289 + - Modify: `/Users/johnluther/projects/diffdown/templates/register.html` 290 + - Modify: `/Users/johnluther/projects/diffdown/templates/login.html` 291 + 292 + - [ ] **Step 1: Review style.css for reusable patterns** 293 + 294 + Run: `cat static/css/style.css` 295 + 296 + Identify patterns to convert: 297 + - `.btn`, `.btn-sm`, `.btn-outline` → Tailwind utility classes 298 + - `.alert`, `.alert-error` → Already handled in base.html 299 + - `.card` → Tailwind card styles 300 + - `.form-group`, `.form-label`, `.form-input` → Tailwind form styles 301 + 302 + - [ ] **Step 2: Convert landing.html** 303 + 304 + Read and convert elements to use Tailwind classes inline instead of custom CSS classes. 305 + 306 + - [ ] **Step 3: Convert documents.html** 307 + 308 + Same approach for the documents dashboard page. 309 + 310 + - [ ] **Step 4: Convert auth pages (register, login)** 311 + 312 + Convert form elements to use Tailwind classes. 313 + 314 + - [ ] **Step 5: Test all pages** 315 + 316 + Run: `make run` 317 + Verify: Landing, documents, login, register pages render correctly with dark mode 318 + 319 + - [ ] **Step 6: Commit** 320 + 321 + ```bash 322 + git add templates/ 323 + git commit -m "refactor: convert auth and dashboard pages to TailwindCSS" 324 + ``` 325 + 326 + --- 327 + 328 + ## Chunk 4: Replace editor.css (complex layout) 329 + 330 + **Files:** 331 + - Modify: `/Users/johnluther/projects/diffdown/templates/document_edit.html` 332 + - Modify: `/Users/johnluther/projects/diffdown/templates/document_view.html` 333 + 334 + - [ ] **Step 1: Review editor.css** 335 + 336 + Key patterns: 337 + - `.editor-page` → Full height flex container 338 + - `.editor-toolbar` → Sticky top toolbar with flex layout 339 + - `.editor-rich` → Rich text editor container 340 + - `.editor-split` → Split pane layout (editor + preview) 341 + - `.invite-modal` → Modal overlay and box 342 + 343 + - [ ] **Step 2: Convert document_edit.html toolbar** 344 + 345 + ```html 346 + <!-- Old --> 347 + <div class="editor-toolbar"> 348 + <div class="breadcrumb"> 349 + ... 350 + </div> 351 + <div class="toolbar-actions"> 352 + ... 353 + </div> 354 + </div> 355 + 356 + <!-- New --> 357 + <div class="sticky top-0 z-50 flex items-center justify-between px-4 py-2 border-b border-[var(--border)] bg-[var(--bg)]"> 358 + <div class="flex items-center gap-2"> 359 + ... 360 + </div> 361 + <div class="flex items-center gap-2"> 362 + ... 363 + </div> 364 + </div> 365 + ``` 366 + 367 + - [ ] **Step 3: Convert editor containers** 368 + 369 + - [ ] **Step 4: Convert modal components** 370 + 371 + - [ ] **Step 5: Test editor functionality** 372 + 373 + Run: `make run` 374 + Create/edit a document 375 + Verify: Rich mode, source mode, preview, toolbar all work 376 + 377 + - [ ] **Step 6: Commit** 378 + 379 + ```bash 380 + git add templates/document_edit.html templates/document_view.html 381 + git commit -m "refactor: convert editor pages to TailwindCSS classes" 382 + ``` 383 + 384 + --- 385 + 386 + ## Chunk 5: Replace markdown.css and diff.css 387 + 388 + **Files:** 389 + - Modify: `/Users/johnluther/projects/diffdown/templates/document_view.html` 390 + - Modify: `/Users/johnluther/projects/diffdown/templates/landing.html` 391 + - Create: Keep minimal overrides in a new file if needed 392 + 393 + - [ ] **Step 1: Review markdown.css** 394 + 395 + Mostly Markdown rendering styles - can keep as-is for now with minimal overrides. 396 + 397 + - [ ] **Step 2: Review diff.css** 398 + 399 + Diff view styles - can keep as-is. 400 + 401 + - [ ] **Step 3: Link tailwind.css in view templates** 402 + 403 + Add `<link rel="stylesheet" href="/static/css/tailwind.css">` to templates that don't have it. 404 + 405 + - [ ] **Step 4: Test view pages** 406 + 407 + Run: `make run` 408 + View a document 409 + Verify: Markdown renders correctly with dark mode 410 + 411 + - [ ] **Step 5: Commit** 412 + 413 + ```bash 414 + git add templates/ 415 + git commit -m "refactor: add TailwindCSS to view pages" 416 + ``` 417 + 418 + --- 419 + 420 + ## Chunk 6: Cleanup and final integration 421 + 422 + **Files:** 423 + - Delete: `/Users/johnluther/projects/diffdown/static/css/style.css` (after verifying no missing styles) 424 + - Delete: `/Users/johnluther/projects/diffdown/static/css/editor.css` (after verifying no missing styles) 425 + - Modify: `/Users/johnluther/projects/diffdown/templates/base.html` 426 + - Modify: `/Users/johnluther/projects/diffdown/package.json` 427 + 428 + - [ ] **Step 1: Check for any remaining custom CSS references** 429 + 430 + Run: `grep -r 'class="' templates/ | grep -E '\.(btn|alert|card|form)' | head -20` 431 + 432 + - [ ] **Step 2: Remove unused CSS files one by one** 433 + 434 + Start with style.css - comment out the link in base.html, test thoroughly, then delete. 435 + 436 + - [ ] **Step 3: Keep minimal base.css for CodeMirror/Milkdown overrides** 437 + 438 + Create `static/css/base.css` for: 439 + - CodeMirror theme overrides 440 + - Milkdown-specific styles 441 + - Any other third-party library styles 442 + 443 + - [ ] **Step 4: Update base.html to remove old CSS links** 444 + 445 + ```html 446 + <link rel="stylesheet" href="/static/css/tailwind.css"> 447 + <link rel="stylesheet" href="/static/css/base.css"> 448 + ``` 449 + 450 + - [ ] **Step 5: Add CSS build to existing build command** 451 + 452 + ```json 453 + "scripts": { 454 + "build": "npm run build:css && npm run build:collab", 455 + "build:css": "npx tailwindcss -i ./src/styles/input.css -o ./static/css/tailwind.css --minify", 456 + "build:collab": "npx esbuild node_modules/prosemirror-collab/dist/index.js --bundle --format=esm --outfile=static/vendor/collab.js" 457 + } 458 + ``` 459 + 460 + - [ ] **Step 6: Final testing** 461 + 462 + Run: `make build && make run` 463 + Test all pages: 464 + - Landing page 465 + - Login/register 466 + - Documents list 467 + - Document edit (rich + source mode) 468 + - Document view 469 + - About page 470 + - Dark mode toggle 471 + 472 + - [ ] **Step 7: Commit final cleanup** 473 + 474 + ```bash 475 + git add -A 476 + git commit -m "refactor: complete TailwindCSS migration, remove legacy CSS" 477 + ``` 478 + 479 + --- 480 + 481 + ## Testing Checklist 482 + 483 + - [ ] Landing page displays correctly (logged out) 484 + - [ ] Login page renders with proper styling 485 + - [ ] Register page renders with proper styling 486 + - [ ] Dashboard shows document list with cards 487 + - [ ] Dark mode toggle works on all pages 488 + - [ ] Document editor loads in rich mode 489 + - [ ] Document editor toggles to source mode 490 + - [ ] Preview pane renders Markdown 491 + - [ ] Invite modal opens/closes properly 492 + - [ ] Document view renders Markdown 493 + - [ ] About page displays correctly 494 + - [ ] Navbar shows correct links for logged in/out users 495 + 496 + --- 497 + 498 + ## Rollback Plan 499 + 500 + If issues arise: 501 + 1. Keep old CSS files in a `static/css/legacy/` folder 502 + 2. Restore old link in base.html: `<link rel="stylesheet" href="/static/css/style.css">` 503 + 3. Test before committing deletions 504 + 505 + --- 506 + 507 + ## Notes 508 + 509 + - TailwindCSS 4.x uses a different configuration approach - verify which version is installed 510 + - The `data-theme` attribute approach is already implemented, Tailwind's `darkMode: 'class'` should work with it 511 + - CodeMirror and Milkdown may need specific overrides in a separate CSS file 512 + - Consider using `@layer components` in input.css for complex custom patterns
+1 -1
static/css/style.css
··· 166 166 border-radius: var(--radius); 167 167 margin-bottom: 1rem; 168 168 } 169 - 169 + Th 170 170 .alert-error { 171 171 background: var(--alert-error-bg); 172 172 color: var(--danger);
static/favicon.ico

This is a binary file and will not be displayed.

static/favicon.png

This is a binary file and will not be displayed.

+6 -28
static/favicon.svg
··· 1 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 2 <svg 3 - width="80" 4 - height="80" 5 - viewBox="43 84 62.4 62.4" 3 + width="420" 4 + height="420" 5 + viewBox="43 84 327.6 327.6" 6 6 version="1.1" 7 7 id="svg2" 8 - sodipodi:docname="favicon.svg" 9 - inkscape:version="1.3.2 (091e20e, 2023-11-25)" 10 - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 11 - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 12 8 xmlns="http://www.w3.org/2000/svg" 13 9 xmlns:svg="http://www.w3.org/2000/svg"> 14 10 <defs 15 11 id="defs2" /> 16 - <sodipodi:namedview 17 - id="namedview2" 18 - pagecolor="#ffffff" 19 - bordercolor="#000000" 20 - borderopacity="0.25" 21 - inkscape:showpageshadow="2" 22 - inkscape:pageopacity="0.0" 23 - inkscape:pagecheckerboard="0" 24 - inkscape:deskcolor="#d1d1d1" 25 - inkscape:zoom="3.42" 26 - inkscape:cx="42.982456" 27 - inkscape:cy="49.853801" 28 - inkscape:window-width="1392" 29 - inkscape:window-height="1212" 30 - inkscape:window-x="3158" 31 - inkscape:window-y="31" 32 - inkscape:window-maximized="0" 33 - inkscape:current-layer="svg2" /> 34 12 <g 35 13 id="g2" 36 - transform="translate(-7.0650602,-7.8754474)"> 14 + transform="matrix(5.7367355,0,0,5.7367355,-259.39616,-458.25129)"> 37 15 <text 38 - style="font-size:50.8px;line-height:1;font-family:'Inter 18pt';font-style:normal;letter-spacing:0px;fill:#2563eb;fill-opacity:1" 16 + style="font-style:normal;font-size:50.8px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#2563eb;fill-opacity:1" 39 17 x="52.5" 40 18 y="141.88016" 41 19 id="text1">D</text> 42 20 <text 43 - style="font-size:50.8px;line-height:1;font-family:'Inter 18pt';font-style:normal;letter-spacing:0px;fill:#0000ff" 21 + style="font-style:normal;font-size:50.8px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#0000ff" 44 22 x="78.900238" 45 23 y="141.22972" 46 24 id="text2">d</text>
static/favicon/favicon.ico

This is a binary file and will not be displayed.

+25 -11
static/img/favicon.svg
··· 1 - <?xml version="1.0" encoding="UTF-8"?> 2 - <svg width="100" height="100" viewBox="43 84 78 78" version="1.1" 3 - xmlns="http://www.w3.org/2000/svg"> 4 - <text 5 - style="font-size:50.8px;line-height:1;font-family:'Inter 18pt';font-style:normal;letter-spacing:0px;fill:#2563eb;fill-opacity:1" 6 - x="52.5" 7 - y="141.88016">D</text> 8 - <text 9 - style="font-size:50.8px;line-height:1;font-family:'Inter 18pt';font-style:normal;letter-spacing:0px;fill:#0000ff" 10 - x="78.900238" 11 - y="141.22972">d</text> 1 + <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 + <svg 3 + width="420" 4 + height="420" 5 + viewBox="43 84 327.6 327.6" 6 + version="1.1" 7 + id="svg2" 8 + xmlns="http://www.w3.org/2000/svg" 9 + xmlns:svg="http://www.w3.org/2000/svg"> 10 + <defs 11 + id="defs2" /> 12 + <g 13 + id="g2" 14 + transform="matrix(5.7367355,0,0,5.7367355,-259.39616,-458.25129)"> 15 + <text 16 + style="font-style:normal;font-size:50.8px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#2563eb;fill-opacity:1" 17 + x="52.5" 18 + y="141.88016" 19 + id="text1">D</text> 20 + <text 21 + style="font-style:normal;font-size:50.8px;line-height:1;font-family:'Inter 18pt';letter-spacing:0px;fill:#0000ff" 22 + x="78.900238" 23 + y="141.22972" 24 + id="text2">d</text> 25 + </g> 12 26 </svg>
-40
static/img/logo-monogram.svg
··· 1 - <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 - <!-- Created with Inkscape (http://www.inkscape.org/) --> 3 - 4 - <svg 5 - width="210mm" 6 - height="297mm" 7 - viewBox="0 0 210 297" 8 - version="1.1" 9 - id="svg1" 10 - xmlns="http://www.w3.org/2000/svg" 11 - xmlns:svg="http://www.w3.org/2000/svg"> 12 - <defs 13 - id="defs1" /> 14 - <g 15 - id="layer1"> 16 - <g 17 - id="g2"> 18 - <text 19 - xml:space="preserve" 20 - style="font-size:50.8px;line-height:1;font-family:'Inter 18pt';-inkscape-font-specification:'Inter 18pt';letter-spacing:0px;fill:#2563eb;fill-opacity:1;stroke-width:6.61432" 21 - x="52.5" 22 - y="141.88016" 23 - id="text1"><tspan 24 - id="tspan1" 25 - style="font-size:50.8px;fill:#2563eb;fill-opacity:1;stroke-width:6.61432" 26 - x="52.5" 27 - y="141.88016">D</tspan></text> 28 - <text 29 - xml:space="preserve" 30 - style="font-size:50.8px;line-height:1;font-family:'Inter 18pt';-inkscape-font-specification:'Inter 18pt';letter-spacing:0px;fill:#0000ff;stroke-width:6.61432" 31 - x="78.900238" 32 - y="141.22972" 33 - id="text2"><tspan 34 - id="tspan2" 35 - style="stroke-width:6.61432" 36 - x="78.900238" 37 - y="141.22972">d</tspan></text> 38 - </g> 39 - </g> 40 - </svg>
-5
templates/about.html
··· 8 8 <div class="about-col"> 9 9 <h2>What is This?</h2> 10 10 <p>Diffdown is a real-time collaborative Markdown editor/previewer built on the <a href="https://atproto.com/">AT Protocol</a> (the tech that powers <a href="https://bsky.app">Bluesky</a>). 11 - 12 11 <p>Diffdown is decentralized; it stores documents as AT Protocol records on the document creator's PDS, not on the Diffdown server or some cloud provider.</p> 13 - 14 12 <p>I built Diffdown to learn <a href="https://atproto.com/">AT Protocol</a>, <a href="https://atproto.com/guides/lexicon">lexicons</a>, and <a href="https://www.ibm.com/think/topics/agentic-engineering">agentic engineering</a>. Consider it a "pre-alpha" prototype. Because AT Proto does not support private records (<a href="https://atproto.wiki/en/working-groups/private-data">yet</a>), <strong>any documents you create will be visible to anyone with the URL</strong> (<a href="https://atproto.at/viewer?uri=did:plc:za4vlvbizdstoym7lpymc5q5/com.diffdown.document/3mgzsp6m5hs24">example</a>).</p> 15 - 16 13 <h2>About Me</h2> 17 14 <p>I've worked in tech for a long time as a product manager and executive. These days, I'm a co-founder of <a href="https://limeleaf.coop">Limeleaf Worker Collective</a>, and an advisor to a few startups. Read about my journey building Diffdown <a href="https://www.jluther.net/tags/nonfiction/">on my Leaflet</a>.</p> 18 - 19 15 </div> 20 16 <div class="about-col"> 21 17 <h2>Technology</h2> ··· 31 27 <p><strong class="warning">Important:</strong> Because AT Proto does not support private data (<a href="https://atproto.wiki/en/working-groups/private-data">yet</a>), any documents you create will be visible to anyone with the URL.</p> 32 28 <p>Expect bugs, breaking changes, and limited features.</p> 33 29 <p>However, any documents you create will be stored in your AT Proto account, so even if Diffdown goes away, you will still have your documents.</p> 34 - 35 30 <h2>Contact</h2> 36 31 <p>Feedback, bug reports, and feature requests are welcome. Reach out via Bluesky or check the <a href="https://github.com/limeleaf/diffdown">GitHub repository</a>.</p> 37 32 </div>