Client side atproto account migrator in your web browser, along with services for backups and adversarial migrations. pdsmoover.com
pds atproto migrations moo cow
at main 474 lines 9.3 kB view raw
1:root { 2 font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; 3 line-height: 1.5; 4 font-weight: 400; 5 6 color-scheme: light dark; 7 color: rgba(255, 255, 255, 0.87); 8 background-color: #242424; 9 10 font-synthesis: none; 11 text-rendering: optimizeLegibility; 12 -webkit-font-smoothing: antialiased; 13 -moz-osx-font-smoothing: grayscale; 14} 15 16a { 17 font-weight: 500; 18 color: #a2a7ff; 19 text-decoration: inherit; 20 text-decoration: underline; 21} 22 23a:hover { 24 color: #535bf2; 25} 26 27body { 28 margin: 0; 29 min-width: 320px; 30 padding: 24px 0; /*This will help with centering the whole page */ 31} 32 33button { 34 border-radius: 8px; 35 border: 1px solid transparent; 36 padding: 0.6em 1.2em; 37 font-size: 1em; 38 font-weight: 500; 39 font-family: inherit; 40 background-color: #1a1a1a; 41 cursor: pointer; 42 transition: border-color 0.25s; 43} 44 45button:hover { 46 border-color: #646cff; 47} 48 49button:focus, 50button:focus-visible { 51 outline: 4px auto -webkit-focus-ring-color; 52} 53 54@media (prefers-color-scheme: light) { 55 :root { 56 color: #213547; 57 background-color: #ffffff; 58 } 59 60 a:hover { 61 color: #747bff; 62 } 63 64 button { 65 background-color: #f9f9f9; 66 } 67} 68 69.container { 70 max-width: 500px; 71 margin: 0 auto; 72 padding: 20px; 73 text-align: center; 74} 75 76.form-group { 77 margin-bottom: 15px; 78 text-align: left; 79} 80 81.form-group label { 82 /*display: block;*/ 83 margin-bottom: 5px; 84} 85 86.form-group input { 87 width: 100%; 88 padding: 8px; 89 box-sizing: border-box; 90} 91 92/* Input group for handle with domain dropdown */ 93.input-group { 94 display: flex; 95 width: 100%; 96} 97 98.input-group input { 99 flex: 1; 100 border-top-right-radius: 0; 101 border-bottom-right-radius: 0; 102 border-right: none; 103} 104 105.input-group .domain-select { 106 padding: 8px; 107 border: 1px solid rgba(128, 128, 128, 0.5); 108 border-top-left-radius: 0; 109 border-bottom-left-radius: 0; 110 border-top-right-radius: 4px; 111 border-bottom-right-radius: 4px; 112 background-color: #1a1a1a; 113 color: rgba(255, 255, 255, 0.87); 114 cursor: pointer; 115 min-width: 120px; 116} 117 118@media (prefers-color-scheme: light) { 119 .input-group .domain-select { 120 background-color: #f9f9f9; 121 color: #213547; 122 } 123} 124 125.cow-image { 126 height: 150px; 127 margin: 20px 0 8px 0; 128 display: flex; 129 align-items: center; 130 justify-content: center; 131} 132 133.missing-cow-image { 134 height: 300px; 135 margin: 20px 0 8px 0; 136 display: flex; 137 align-items: center; 138 justify-content: center; 139} 140 141.section { 142 margin-top: 30px; 143} 144 145/* Left align the advance options section */ 146.show-advance { 147 text-align: left; 148} 149 150.made-by-blur { 151 font-size: 0.9em; 152 color: rgba(127, 127, 127, 0.9); 153 margin-bottom: 12px; 154} 155 156h1 { 157 font-size: 3.2em; 158 line-height: 1.1; 159 margin-bottom: 20px; 160} 161 162.error-message { 163 color: red; 164 font-size: 1.2em; 165 margin-top: 10px; 166} 167 168.status-message { 169 display: block; 170 margin: 15px auto; 171 padding: 10px; 172 background-color: #4a5568; 173 color: white; 174 border-radius: 5px; 175 /*font-weight: bold;*/ 176 text-align: center; 177 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); 178} 179 180.form-checkbox { 181 font-size: 2rem; 182 font-weight: bold; 183 line-height: 1.1; 184 display: grid; 185 grid-template-columns: 1em auto; 186 gap: 0.5em; 187} 188 189/* Navbar styles */ 190body { 191 padding-top: 64px; /* space for fixed navbar */ 192} 193 194.navbar { 195 position: fixed; 196 top: 0; 197 left: 0; 198 right: 0; 199 z-index: 1000; 200 backdrop-filter: saturate(180%) blur(10px); 201 background: rgba(36, 36, 36, 0.7); 202 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 203} 204 205.bar { 206 color: #ffffff; 207} 208 209@media (prefers-color-scheme: light) { 210 .navbar { 211 background: rgba(255, 255, 255, 0.7); 212 border-bottom-color: rgba(0, 0, 0, 0.08); 213 } 214} 215 216.navbar-inner { 217 max-width: 1000px; 218 margin: 0 auto; 219 padding: 10px 16px; 220 display: flex; 221 align-items: center; 222 justify-content: space-between; 223 gap: 12px; 224} 225 226.brand { 227 font-weight: 800; 228 letter-spacing: 0.3px; 229 color: inherit; 230 text-decoration: none; 231} 232 233.nav-links { 234 display: flex; 235 align-items: center; 236 gap: 6px; 237 flex-wrap: wrap; 238} 239 240.nav-links a { 241 color: inherit; 242 text-decoration: none; 243 padding: 6px 10px; 244 border-radius: 8px; 245 transition: 246 background-color 0.2s ease, 247 color 0.2s ease; 248} 249 250.nav-links a:hover, 251.nav-links a:focus-visible { 252 background-color: rgba(100, 108, 255, 0.16); 253} 254 255.page-content { 256 width: 100%; 257} 258 259/* Mobile-friendly navbar additions */ 260.navbar-toggle { 261 display: none; 262 align-items: center; 263 justify-content: center; 264 height: 40px; 265 background: transparent; 266 border: 1px solid rgba(255, 255, 255, 0.15); 267 border-radius: 8px; 268 color: #ffffff; /* default white icon */ 269 cursor: pointer; 270} 271 272/* Force the toggle icon to be white in all color schemes */ 273.navbar .navbar-toggle { 274 color: #ffffff; 275} 276 277.navbar .navbar-toggle svg { 278 width: 22px; 279 height: 22px; 280 display: block; 281} 282 283.navbar .navbar-toggle svg * { 284 fill: currentColor; /* ensure paths use the button color (white) */ 285} 286 287@media (prefers-color-scheme: light) { 288 .navbar-toggle { 289 border-color: rgba(0, 0, 0, 0.12); 290 /* keep icon white per request */ 291 color: #ffffff; 292 } 293} 294 295.navbar-toggle .bar { 296 display: block; 297 width: 18px; 298 height: 2px; 299 background: currentColor; 300 margin: 2px 0; 301 border-radius: 2px; 302} 303 304/* Active link example styling */ 305.nav-links a.active { 306 background-color: rgba(100, 108, 255, 0.28); 307 font-weight: 600; 308} 309 310/* Responsive behavior */ 311@media (max-width: 700px) { 312 .navbar-inner { 313 position: relative; 314 } 315 316 .navbar-toggle { 317 display: inline-flex; 318 } 319 320 .nav-links { 321 position: absolute; 322 top: 100%; 323 left: 0; 324 right: 0; 325 display: none; 326 flex-direction: column; 327 gap: 4px; 328 padding: 10px 16px 12px 16px; 329 background: rgba( 330 36, 331 36, 332 36, 333 0.95 334 ); /* solid enough to not bleed into title */ 335 backdrop-filter: saturate(180%) blur(10px); 336 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 337 z-index: 1001; /* above page content */ 338 box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25); 339 } 340 341 @media (prefers-color-scheme: light) { 342 .nav-links { 343 border-bottom-color: rgba(0, 0, 0, 0.08); 344 background: rgba(255, 255, 255, 0.98); 345 box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); 346 } 347 } 348 .nav-links.open { 349 display: flex; 350 } 351} 352 353/* Support buttons row */ 354.support-buttons { 355 display: inline-flex; 356 /*align-items: flex-end; !* bottom-align Ko-fi and GitHub buttons *!*/ 357 gap: 8px; 358 justify-content: center; 359 flex-wrap: wrap; 360 margin-top: 8px; 361} 362 363/* Try to coerce Ko-fi generated button to sit inline */ 364.support-buttons a.kofi-button, /* common class name used by Ko-fi */ 365.support-buttons .kofiwidget, /* fallback */ 366.support-buttons .btn-kofi, /* another fallback */ 367.support-buttons span.kofi-slot > * { 368 display: inline-block !important; 369 vertical-align: middle; 370} 371 372.support-buttons iframe { 373 vertical-align: middle; 374} 375 376.moove-checkbox-label { 377 display: inline-flex; 378 align-items: center; 379 gap: 0.5rem; 380 white-space: nowrap; 381} 382 383.bold { 384 font-weight: bold; 385} 386 387/* Align action buttons in a row with spacing */ 388.actions { 389 display: inline-flex; 390 align-items: center; 391 gap: 8px; /* little bit of spacing between buttons */ 392 flex-wrap: wrap; /* stay responsive on very small screens */ 393} 394 395/* Refresh button near header */ 396.section-header { 397 display: flex; 398 align-items: center; 399 justify-content: space-between; 400 gap: 0.75rem; 401 margin-bottom: 0.5rem; 402 /*flex-wrap: nowrap; !* keep header and button on the same line when possible *!*/ 403} 404 405.section-header .icon-button { 406 display: inline-flex; 407 align-items: center; 408 justify-content: center; 409 width: 36px; 410 height: 36px; 411 padding: 0; 412 border-radius: 50%; 413 border: 1px solid transparent; 414 background-color: #1a1a1a; 415 color: #ffffff; /* make SVG icon white via currentColor */ 416} 417 418.section-header .icon-button .icon { 419 width: 20px; 420 height: 20px; 421 fill: currentColor; 422} 423 424.section-header .icon-button:hover { 425 border-color: #646cff; 426} 427 428@media (prefers-color-scheme: light) { 429 .section-header .icon-button { 430 background-color: #1a1a1a; /* keep contrast for white icon */ 431 } 432} 433 434/* Stats grid and cards for the index page */ 435.stats-grid { 436 display: grid; 437 grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); 438 gap: 12px; 439} 440 441.stat-card { 442 border: 1px solid rgba(128, 128, 128, 0.35); 443 border-radius: 10px; 444 padding: 14px; 445 background: rgba(0, 0, 0, 0.05); 446} 447 448.stat-label { 449 font-size: 0.9rem; 450 opacity: 0.8; 451} 452 453.stat-value { 454 font-size: 1.4rem; 455 font-weight: 700; 456 margin-top: 4px; 457} 458 459.stat-value--small { 460 font-size: 1rem; 461 font-weight: 600; 462 word-break: break-word; 463} 464 465.stat-sub { 466 font-size: 0.85rem; 467 opacity: 0.7; 468 margin-top: 6px; 469} 470 471.warning { 472 /*text-decoration: underline;*/ 473 font-weight: bold; 474}