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 465 lines 9.1 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 142.section { 143 margin-top: 30px; 144} 145 146/* Left align the advance options section */ 147.show-advance { 148 text-align: left; 149} 150 151.made-by-blur { 152 font-size: 0.9em; 153 color: rgba(127, 127, 127, 0.9); 154 margin-bottom: 12px; 155} 156 157h1 { 158 font-size: 3.2em; 159 line-height: 1.1; 160 margin-bottom: 20px; 161} 162 163.error-message { 164 color: red; 165 font-size: 1.2em; 166 margin-top: 10px; 167} 168 169.status-message { 170 display: block; 171 margin: 15px auto; 172 padding: 10px; 173 background-color: #4a5568; 174 color: white; 175 border-radius: 5px; 176 /*font-weight: bold;*/ 177 text-align: center; 178 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); 179} 180 181.form-checkbox { 182 183 font-size: 2rem; 184 font-weight: bold; 185 line-height: 1.1; 186 display: grid; 187 grid-template-columns: 1em auto; 188 gap: 0.5em; 189} 190 191/* Navbar styles */ 192body { 193 padding-top: 64px; /* space for fixed navbar */ 194} 195 196.navbar { 197 position: fixed; 198 top: 0; 199 left: 0; 200 right: 0; 201 z-index: 1000; 202 backdrop-filter: saturate(180%) blur(10px); 203 background: rgba(36, 36, 36, 0.7); 204 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 205} 206 207.bar { 208 color: #ffffff; 209} 210 211@media (prefers-color-scheme: light) { 212 .navbar { 213 background: rgba(255, 255, 255, 0.7); 214 border-bottom-color: rgba(0, 0, 0, 0.08); 215 } 216} 217 218.navbar-inner { 219 max-width: 1000px; 220 margin: 0 auto; 221 padding: 10px 16px; 222 display: flex; 223 align-items: center; 224 justify-content: space-between; 225 gap: 12px; 226} 227 228.brand { 229 font-weight: 800; 230 letter-spacing: 0.3px; 231 color: inherit; 232 text-decoration: none; 233} 234 235.nav-links { 236 display: flex; 237 align-items: center; 238 gap: 6px; 239 flex-wrap: wrap; 240} 241 242.nav-links a { 243 color: inherit; 244 text-decoration: none; 245 padding: 6px 10px; 246 border-radius: 8px; 247 transition: background-color 0.2s ease, 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(36, 36, 36, 0.95); /* solid enough to not bleed into title */ 330 backdrop-filter: saturate(180%) blur(10px); 331 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 332 z-index: 1001; /* above page content */ 333 box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25); 334 } 335 336 @media (prefers-color-scheme: light) { 337 .nav-links { 338 border-bottom-color: rgba(0, 0, 0, 0.08); 339 background: rgba(255, 255, 255, 0.98); 340 box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12); 341 } 342 } 343 .nav-links.open { 344 display: flex; 345 } 346} 347 348/* Support buttons row */ 349.support-buttons { 350 display: inline-flex; 351 /*align-items: flex-end; !* bottom-align Ko-fi and GitHub buttons *!*/ 352 gap: 8px; 353 justify-content: center; 354 flex-wrap: wrap; 355 margin-top: 8px; 356} 357 358/* Try to coerce Ko-fi generated button to sit inline */ 359.support-buttons a.kofi-button, /* common class name used by Ko-fi */ 360.support-buttons .kofiwidget, /* fallback */ 361.support-buttons .btn-kofi, /* another fallback */ 362.support-buttons span.kofi-slot > * { 363 display: inline-block !important; 364 vertical-align: middle; 365} 366 367.support-buttons iframe { 368 vertical-align: middle; 369} 370 371.moove-checkbox-label { 372 display: inline-flex; 373 align-items: center; 374 gap: 0.5rem; 375 white-space: nowrap; 376} 377 378.bold { 379 font-weight: bold; 380} 381 382/* Align action buttons in a row with spacing */ 383.actions { 384 display: inline-flex; 385 align-items: center; 386 gap: 8px; /* little bit of spacing between buttons */ 387 flex-wrap: wrap; /* stay responsive on very small screens */ 388} 389 390/* Refresh button near header */ 391.section-header { 392 display: flex; 393 align-items: center; 394 justify-content: space-between; 395 gap: 0.75rem; 396 margin-bottom: 0.5rem; 397 /*flex-wrap: nowrap; !* keep header and button on the same line when possible *!*/ 398} 399 400.section-header .icon-button { 401 display: inline-flex; 402 align-items: center; 403 justify-content: center; 404 width: 36px; 405 height: 36px; 406 padding: 0; 407 border-radius: 50%; 408 border: 1px solid transparent; 409 background-color: #1a1a1a; 410 color: #ffffff; /* make SVG icon white via currentColor */ 411} 412 413.section-header .icon-button .icon { 414 width: 20px; 415 height: 20px; 416 fill: currentColor; 417} 418 419.section-header .icon-button:hover { 420 border-color: #646cff; 421} 422 423@media (prefers-color-scheme: light) { 424 .section-header .icon-button { 425 background-color: #1a1a1a; /* keep contrast for white icon */ 426 } 427} 428 429 430/* Stats grid and cards for the index page */ 431.stats-grid { 432 display: grid; 433 grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); 434 gap: 12px; 435} 436 437.stat-card { 438 border: 1px solid rgba(128, 128, 128, 0.35); 439 border-radius: 10px; 440 padding: 14px; 441 background: rgba(0, 0, 0, 0.05); 442} 443 444.stat-label { 445 font-size: 0.9rem; 446 opacity: 0.8; 447} 448 449.stat-value { 450 font-size: 1.4rem; 451 font-weight: 700; 452 margin-top: 4px; 453} 454 455.stat-value--small { 456 font-size: 1rem; 457 font-weight: 600; 458 word-break: break-word; 459} 460 461.stat-sub { 462 font-size: 0.85rem; 463 opacity: 0.7; 464 margin-top: 6px; 465}