A simple tool which lets you scrape twitter accounts and crosspost them to bluesky accounts! Comes with a CLI and a webapp for managing profiles! Works with images/videos/link embeds/threads.

style: use standard Bootstrap 5.3 dark mode

jack 182e3ad3 3bb1e161

+15 -26
+15 -26
public/index.html
··· 7 7 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> 8 8 <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> 9 9 <style> 10 - body { background-color: #f8f9fa; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; transition: background-color 0.3s, color 0.3s; } 11 - .card { border: none; border-radius: 12px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); transition: background-color 0.3s, box-shadow 0.3s; } 12 - .navbar { background-color: #fff; box-shadow: 0 2px 4px rgba(0,0,0,0.03); transition: background-color 0.3s; } 10 + body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; transition: background-color 0.3s, color 0.3s; } 11 + .card { border: none; border-radius: 12px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); transition: transform 0.2s; } 12 + .navbar { box-shadow: 0 2px 4px rgba(0,0,0,0.03); } 13 13 .btn-primary { background-color: #0085ff; border: none; border-radius: 8px; } 14 14 .btn-primary:hover { background-color: #0072db; } 15 15 .login-container { max-width: 400px; margin: 100px auto; } 16 - .owner-badge { background-color: #e9ecef; color: #495057; padding: 4px 8px; border-radius: 6px; font-size: 0.8rem; font-weight: 600; transition: background-color 0.3s, color 0.3s; } 16 + .owner-badge { background-color: rgba(0,0,0,0.05); padding: 4px 8px; border-radius: 6px; font-size: 0.8rem; font-weight: 600; } 17 17 18 - /* Dark mode styles - fixed selectors */ 19 - body.dark { background-color: #1a1a2e; color: #e0e0e0; } 20 - body.dark .card { background-color: #16213e; box-shadow: 0 4px 6px rgba(0,0,0,0.3); } 21 - body.dark .navbar { background-color: #16213e; color: #e0e0e0; } 22 - body.dark .form-control { background-color: #0f3460; border-color: #1a4a7a; color: #e0e0e0; } 23 - body.dark .form-control:focus { background-color: #0f3460; border-color: #0085ff; color: #e0e0e0; } 24 - body.dark .form-label { color: #b0b0b0; } 25 - body.dark .text-muted { color: #888 !important; } 26 - body.dark input::placeholder { color: #666; } 27 - body.dark .table { color: #e0e0e0; } 28 - body.dark .table td, body.dark .table th { border-color: #2a3a5a; } 29 - body.dark hr { border-color: #2a3a5a; } 30 - body.dark .owner-badge { background-color: #0f3460; color: #a0a0a0; } 31 - body.dark .btn-outline-secondary { border-color: #4a5a7a; color: #a0a0a0; } 32 - body.dark .btn-outline-secondary:hover { background-color: #0f3460; border-color: #4a5a7a; color: #e0e0e0; } 33 - body.dark .btn-link { color: #6ea8fe; } 18 + /* Dark mode custom refinements */ 19 + [data-bs-theme="dark"] body { background-color: #0f172a; } 20 + [data-bs-theme="dark"] .card { background-color: #1e293b; border: 1px solid #334155; } 21 + [data-bs-theme="dark"] .navbar { background-color: #1e293b; border-bottom: 1px solid #334155; } 22 + [data-bs-theme="dark"] .owner-badge { background-color: rgba(255,255,255,0.1); color: #cbd5e1; } 34 23 35 24 .status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 8px; } 36 - .status-active { background-color: #28a745; } 37 - .status-queued { background-color: #ffc107; } 25 + .status-active { background-color: #22c55e; box-shadow: 0 0 8px rgba(34, 197, 94, 0.4); } 26 + .status-queued { background-color: #eab308; box-shadow: 0 0 8px rgba(234, 179, 8, 0.4); } 38 27 </style> 39 28 </head> 40 29 <body> ··· 102 91 }, [token, fetchStatus, handleLogout]); 103 92 104 93 useEffect(() => { 105 - document.body.classList.toggle('dark', darkMode); 94 + document.documentElement.setAttribute('data-bs-theme', darkMode ? 'dark' : 'light'); 106 95 localStorage.setItem('darkMode', darkMode); 107 96 }, [darkMode]); 108 97 ··· 259 248 260 249 if (view === 'login' || view === 'register' || !token) { 261 250 return ( 262 - <div className={`container login-container ${darkMode ? 'dark' : ''}`}> 251 + <div className="container login-container"> 263 252 <div className="card p-4"> 264 253 <h2 className="text-center mb-4">{view === 'login' ? 'Login' : 'Register'}</h2> 265 254 {error && <div className="alert alert-danger">{error}</div>} ··· 294 283 const isBackfillQueued = (id) => status.pendingBackfills?.includes(id); 295 284 296 285 return ( 297 - <div className={darkMode ? 'dark' : ''}> 286 + <div> 298 287 <nav className="navbar navbar-expand-lg mb-4"> 299 288 <div className="container"> 300 289 <span className="navbar-brand d-flex align-items-center"> ··· 425 414 root.render(<App />); 426 415 </script> 427 416 </body> 428 - </html> 417 + </html>