this repo has no description
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Tranquil</title> 7 <link rel="preconnect" href="https://fonts.googleapis.com"> 8 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 9 <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700;800&display=swap" rel="stylesheet"> 10 <style> 11 * { margin: 0; padding: 0; box-sizing: border-box; } 12 13 body { 14 font-family: 'JetBrains Mono', monospace; 15 line-height: 1.7; 16 background: #2c00ff; 17 color: #ffffff; 18 min-height: 100vh; 19 position: relative; 20 } 21 22 .pattern-container { 23 position: fixed; 24 top: -32px; 25 left: -32px; 26 right: -32px; 27 bottom: -32px; 28 pointer-events: none; 29 z-index: 1; 30 overflow: hidden; 31 } 32 33 .pattern { 34 position: absolute; 35 top: 0; 36 left: 0; 37 width: calc(100% + 500px); 38 height: 100%; 39 animation: drift 80s linear infinite; 40 } 41 42 .dot { 43 position: absolute; 44 width: 10px; 45 height: 10px; 46 background: rgba(255,255,255,0.15); 47 border-radius: 50%; 48 transition: transform 0.04s linear; 49 } 50 51 .pattern-fade { 52 position: fixed; 53 top: 0; 54 left: 0; 55 right: 0; 56 bottom: 0; 57 background: linear-gradient(135deg, transparent 50%, #2c00ff 75%); 58 pointer-events: none; 59 z-index: 2; 60 } 61 62 @keyframes drift { 63 0% { transform: translateX(-500px); } 64 100% { transform: translateX(0); } 65 } 66 67 nav { z-index: 100; } 68 main { position: relative; z-index: 10; } 69 .site-footer { position: relative; z-index: 10; } 70 71 a { color: #ff2400; text-decoration: none; } 72 a:hover { color: #ff5533; } 73 74 nav { 75 position: fixed; 76 top: 12px; 77 left: 32px; 78 right: 32px; 79 background: #1a00a3; 80 padding: 10px 18px; 81 z-index: 100; 82 border-radius: 8px; 83 border: 1px solid rgba(255, 255, 255, 0.1); 84 display: flex; 85 justify-content: space-between; 86 align-items: center; 87 } 88 89 nav .brand { 90 font-weight: 600; 91 font-size: 1rem; 92 letter-spacing: 0.08em; 93 color: #ffffff; 94 text-transform: uppercase; 95 } 96 97 nav .nav-meta { 98 font-size: 0.85rem; 99 color: rgba(255, 255, 255, 0.7); 100 letter-spacing: 0.05em; 101 } 102 103 main { 104 max-width: 1000px; 105 margin: 0 auto; 106 padding: 80px 32px 80px; 107 } 108 109 .meta { 110 display: flex; 111 align-items: center; 112 gap: 16px; 113 margin-bottom: 32px; 114 font-size: 0.8rem; 115 font-weight: 500; 116 text-transform: uppercase; 117 letter-spacing: 0.1em; 118 } 119 120 .category { 121 color: #ff2400; 122 background: rgba(255, 255, 255, 0.95); 123 padding: 4px 10px; 124 border-radius: 4px; 125 } 126 127 .read-time { 128 color: rgba(255, 255, 255, 0.8); 129 } 130 131 h1 { 132 font-size: 2.75rem; 133 font-weight: 600; 134 line-height: 1.15; 135 color: #ffffff; 136 margin-bottom: 32px; 137 letter-spacing: -0.02em; 138 } 139 140 .byline { 141 display: flex; 142 align-items: center; 143 gap: 16px; 144 padding: 24px 0; 145 border-top: 1px solid rgba(255, 255, 255, 0.12); 146 border-bottom: 1px solid rgba(255, 255, 255, 0.12); 147 margin-bottom: 48px; 148 } 149 150 .avatar { 151 width: 44px; 152 height: 44px; 153 border-radius: 50%; 154 background: linear-gradient(135deg, #ff2400 0%, #ff6b4a 100%); 155 } 156 157 .author-info { 158 flex: 1; 159 } 160 161 .author { 162 display: block; 163 font-weight: 500; 164 color: #ffffff; 165 font-size: 1rem; 166 } 167 168 .author-handle { 169 display: block; 170 font-size: 0.85rem; 171 color: rgba(255, 255, 255, 0.8); 172 margin-top: 2px; 173 } 174 175 .verification { 176 font-size: 0.75rem; 177 font-weight: 500; 178 color: rgba(255, 255, 255, 0.85); 179 text-transform: uppercase; 180 letter-spacing: 0.08em; 181 } 182 183 .placeholder-image { 184 aspect-ratio: 16 / 9; 185 background: rgba(255, 255, 255, 0.08); 186 border-radius: 8px; 187 display: flex; 188 align-items: center; 189 justify-content: center; 190 font-size: 0.9rem; 191 color: rgba(255, 255, 255, 0.6); 192 text-transform: uppercase; 193 letter-spacing: 0.1em; 194 border: 1px solid rgba(255, 255, 255, 0.15); 195 } 196 197 figcaption { 198 margin-top: 12px; 199 font-size: 0.85rem; 200 color: rgba(255, 255, 255, 0.75); 201 text-align: center; 202 } 203 204 .carousel { 205 margin: 64px 0 0; 206 } 207 208 .carousel-header { 209 display: flex; 210 justify-content: space-between; 211 align-items: center; 212 margin-bottom: 20px; 213 } 214 215 .carousel-title { 216 font-size: 0.85rem; 217 font-weight: 600; 218 text-transform: uppercase; 219 letter-spacing: 0.1em; 220 color: #ffffff; 221 } 222 223 .carousel-nav { 224 display: flex; 225 gap: 8px; 226 } 227 228 .carousel-nav button { 229 font-family: 'JetBrains Mono', monospace; 230 width: 36px; 231 height: 36px; 232 background: rgba(255, 255, 255, 0.08); 233 border: 1px solid rgba(255, 255, 255, 0.15); 234 border-radius: 6px; 235 color: #ffffff; 236 cursor: pointer; 237 transition: all 0.15s ease; 238 font-size: 1rem; 239 } 240 241 .carousel-nav button:hover { 242 background: rgba(255, 36, 0, 0.15); 243 border-color: #ff2400; 244 } 245 246 .carousel-track { 247 display: flex; 248 gap: 16px; 249 overflow-x: auto; 250 scroll-snap-type: x mandatory; 251 scrollbar-width: none; 252 -ms-overflow-style: none; 253 padding-bottom: 8px; 254 -webkit-overflow-scrolling: touch; 255 user-select: none; 256 } 257 258 .carousel-track::-webkit-scrollbar { 259 display: none; 260 } 261 262 .carousel-slide { 263 flex: 0 0 70%; 264 scroll-snap-align: start; 265 } 266 267 .carousel-slide .placeholder-image { 268 aspect-ratio: 16 / 10; 269 } 270 271 .carousel-label { 272 margin-top: 12px; 273 font-size: 0.8rem; 274 font-weight: 500; 275 color: rgba(255, 255, 255, 0.85); 276 text-transform: uppercase; 277 letter-spacing: 0.08em; 278 } 279 280 .content { 281 font-size: 1.05rem; 282 font-weight: 400; 283 } 284 285 .content p { 286 margin-bottom: 28px; 287 } 288 289 .lede { 290 font-size: 1.3rem; 291 font-weight: 500; 292 color: #ffffff; 293 line-height: 1.5; 294 } 295 296 .content h2 { 297 font-size: 0.9rem; 298 font-weight: 600; 299 text-transform: uppercase; 300 letter-spacing: 0.1em; 301 color: #ffffff; 302 margin: 56px 0 24px; 303 } 304 305 blockquote { 306 margin: 40px 0; 307 padding: 32px; 308 background: rgba(255, 255, 255, 0.05); 309 border-left: 2px solid #ff2400; 310 border-radius: 0 8px 8px 0; 311 } 312 313 blockquote p { 314 font-size: 1.15rem; 315 color: #ffffff; 316 font-style: italic; 317 margin-bottom: 16px !important; 318 } 319 320 blockquote cite { 321 font-size: 0.8rem; 322 color: rgba(255, 255, 255, 0.8); 323 font-style: normal; 324 text-transform: uppercase; 325 letter-spacing: 0.05em; 326 } 327 328 .context-panel { 329 margin: 40px 0; 330 padding: 24px; 331 background: rgba(255, 255, 255, 0.05); 332 border-radius: 8px; 333 border: 1px solid rgba(255, 255, 255, 0.1); 334 } 335 336 .context-panel h3 { 337 font-size: 0.8rem; 338 font-weight: 600; 339 text-transform: uppercase; 340 letter-spacing: 0.1em; 341 color: #ffffff; 342 margin-bottom: 16px; 343 } 344 345 .context-panel ul { 346 list-style: none; 347 } 348 349 .context-panel li { 350 padding: 10px 0; 351 border-bottom: 1px solid rgba(255, 255, 255, 0.1); 352 } 353 354 .context-panel li:last-child { 355 border-bottom: none; 356 } 357 358 .context-panel a { 359 font-size: 0.95rem; 360 font-weight: 500; 361 color: #ff2400; 362 text-decoration: none; 363 transition: color 0.15s ease; 364 } 365 366 .context-panel a:hover { 367 color: #ff5533; 368 } 369 370 .article-footer { 371 margin-top: 64px; 372 padding-top: 32px; 373 border-top: 1px solid rgba(255, 255, 255, 0.12); 374 } 375 376 .actions { 377 display: flex; 378 gap: 12px; 379 margin-bottom: 24px; 380 } 381 382 .actions button { 383 font-family: 'JetBrains Mono', monospace; 384 font-size: 0.85rem; 385 font-weight: 500; 386 text-transform: uppercase; 387 letter-spacing: 0.06em; 388 padding: 14px 24px; 389 background: rgba(255, 255, 255, 0.06); 390 border: 1px solid rgba(255, 255, 255, 0.12); 391 border-radius: 6px; 392 color: #ffffff; 393 cursor: pointer; 394 transition: all 0.15s ease; 395 } 396 397 .actions button:hover { 398 background: rgba(255, 36, 0, 0.15); 399 border-color: #ff2400; 400 color: #ffffff; 401 } 402 403 .attestation-info { 404 display: flex; 405 flex-wrap: wrap; 406 gap: 24px; 407 font-size: 0.8rem; 408 color: rgba(255, 255, 255, 0.7); 409 text-transform: uppercase; 410 letter-spacing: 0.05em; 411 } 412 413 .site-footer { 414 max-width: 1000px; 415 margin: 0 auto; 416 padding: 48px 32px; 417 display: flex; 418 justify-content: space-between; 419 font-size: 0.8rem; 420 color: rgba(255, 255, 255, 0.65); 421 text-transform: uppercase; 422 letter-spacing: 0.05em; 423 border-top: 1px solid rgba(255, 255, 255, 0.12); 424 } 425 426 ::selection { 427 background: rgba(255, 36, 0, 0.4); 428 } 429 </style> 430</head> 431<body> 432 433<div class="pattern-container"> 434 <div class="pattern"></div> 435</div> 436<div class="pattern-fade"></div> 437 438<nav> 439 <span class="brand">Tranquil</span> 440 <span class="nav-meta">0.1.0</span> 441</nav> 442 443<main> 444 <article> 445 <div class="meta"> 446 <span class="category">Landing page</span> 447 <span class="read-time">1 min read</span> 448 </div> 449 450 <h1>Lorem Ipsum Dolor Sit Amet Consectetur</h1> 451 452 <div class="byline"> 453 <div class="avatar"></div> 454 <div class="author-info"> 455 <span class="author">Mysterious benefactor</span> 456 <span class="author-handle">@lewis.moe</span> 457 </div> 458 <div class="verification">47 attestations</div> 459 </div> 460 461 <div class="content"> 462 <blockquote> 463 <p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."</p> 464 <cite>Cicero, De Finibus Bonorum et Malorum</cite> 465 </blockquote> 466 467 <p class="lede">Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.</p> 468 469 <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p> 470 471 <p>Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</p> 472 473 <h2>Neque Porro Quisquam</h2> 474 475 <p>Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.</p> 476 477 <p>Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur.</p> 478 479 <h2>Quis Autem Vel Eum</h2> 480 481 <p>Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur.</p> 482 483 <p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident.</p> 484 485 <p>Similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio.</p> 486 487 <p>Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.</p> 488 489 <p>Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae.</p> 490 491 <div class="carousel"> 492 <div class="carousel-header"> 493 <span class="carousel-title">Interface</span> 494 <div class="carousel-nav"> 495 <button class="carousel-prev"></button> 496 <button class="carousel-next"></button> 497 </div> 498 </div> 499 <div class="carousel-track"> 500 <div class="carousel-slide"> 501 <div class="placeholder-image">Dashboard goes here</div> 502 <div class="carousel-label">Dashboard</div> 503 </div> 504 <div class="carousel-slide"> 505 <div class="placeholder-image">Profile Settings go here</div> 506 <div class="carousel-label">Profile Settings</div> 507 </div> 508 <div class="carousel-slide"> 509 <div class="placeholder-image">Account Security goes here</div> 510 <div class="carousel-label">Account Security</div> 511 </div> 512 <div class="carousel-slide"> 513 <div class="placeholder-image">Repository Browser goes here</div> 514 <div class="carousel-label">Repository Browser</div> 515 </div> 516 <div class="carousel-slide"> 517 <div class="placeholder-image">OAuth Applications go here</div> 518 <div class="carousel-label">OAuth Applications</div> 519 </div> 520 <div class="carousel-slide"> 521 <div class="placeholder-image">Invite Codes go here</div> 522 <div class="carousel-label">Invite Codes</div> 523 </div> 524 </div> 525 </div> 526 </div> 527 528 <footer class="article-footer"> 529 <div class="actions"> 530 <button>Propagate</button> 531 <button>Annotate</button> 532 <button>Verify Source</button> 533 </div> 534 535 <div class="attestation-info"> 536 <span>hash: 7f3a9c...</span> 537 <span>signed: 2847.12.03</span> 538 <span>nodes: 12,847</span> 539 </div> 540 </footer> 541 </article> 542</main> 543 544<footer class="site-footer"> 545 <div>Mesh Commons License</div> 546 <div>node: local-7f3a</div> 547</footer> 548 549<script> 550const pattern = document.querySelector('.pattern'); 551const spacing = 32; 552const cols = Math.ceil((window.innerWidth + 600) / spacing); 553const rows = Math.ceil((window.innerHeight + 100) / spacing); 554const dots = []; 555 556for (let y = 0; y < rows; y++) { 557 for (let x = 0; x < cols; x++) { 558 const dot = document.createElement('div'); 559 dot.className = 'dot'; 560 dot.style.left = (x * spacing) + 'px'; 561 dot.style.top = (y * spacing) + 'px'; 562 pattern.appendChild(dot); 563 dots.push({ el: dot, x: x * spacing, y: y * spacing }); 564 } 565} 566 567let mouseX = -1000, mouseY = -1000; 568document.addEventListener('mousemove', e => { 569 mouseX = e.clientX; 570 mouseY = e.clientY; 571}); 572 573function updateDots() { 574 const patternRect = pattern.getBoundingClientRect(); 575 dots.forEach(dot => { 576 const dotX = patternRect.left + dot.x + 5; 577 const dotY = patternRect.top + dot.y + 5; 578 const dist = Math.hypot(mouseX - dotX, mouseY - dotY); 579 const maxDist = 120; 580 const scale = Math.min(1, Math.max(0.1, dist / maxDist)); 581 dot.el.style.transform = `scale(${scale})`; 582 }); 583 requestAnimationFrame(updateDots); 584} 585updateDots(); 586 587const track = document.querySelector('.carousel-track'); 588const prevBtn = document.querySelector('.carousel-prev'); 589const nextBtn = document.querySelector('.carousel-next'); 590const slideWidth = track?.querySelector('.carousel-slide')?.offsetWidth + 16; 591 592prevBtn?.addEventListener('click', () => { 593 track.scrollBy({ left: -slideWidth, behavior: 'smooth' }); 594}); 595nextBtn?.addEventListener('click', () => { 596 track.scrollBy({ left: slideWidth, behavior: 'smooth' }); 597}); 598 599let isDragging = false; 600let startX, scrollLeft; 601 602track?.addEventListener('mousedown', e => { 603 isDragging = true; 604 track.style.cursor = 'grabbing'; 605 track.style.scrollSnapType = 'none'; 606 startX = e.pageX - track.offsetLeft; 607 scrollLeft = track.scrollLeft; 608}); 609 610track?.addEventListener('mouseleave', () => { 611 isDragging = false; 612 track.style.cursor = 'grab'; 613 track.style.scrollSnapType = 'x mandatory'; 614}); 615 616function snapTo(target, duration = 120) { 617 const start = track.scrollLeft; 618 const distance = target - start; 619 const startTime = performance.now(); 620 function step(currentTime) { 621 const elapsed = currentTime - startTime; 622 const progress = Math.min(elapsed / duration, 1); 623 const ease = 1 - Math.pow(1 - progress, 3); 624 track.scrollLeft = start + distance * ease; 625 if (progress < 1) requestAnimationFrame(step); 626 else track.style.scrollSnapType = 'x mandatory'; 627 } 628 requestAnimationFrame(step); 629} 630 631track?.addEventListener('mouseup', () => { 632 isDragging = false; 633 track.style.cursor = 'grab'; 634 const slideW = track.querySelector('.carousel-slide').offsetWidth + 16; 635 const targetIndex = Math.round(track.scrollLeft / slideW); 636 snapTo(targetIndex * slideW); 637}); 638 639track?.addEventListener('mousemove', e => { 640 if (!isDragging) return; 641 e.preventDefault(); 642 const x = e.pageX - track.offsetLeft; 643 const walk = (x - startX) * 1.5; 644 track.scrollLeft = scrollLeft - walk; 645}); 646 647if (track) track.style.cursor = 'grab'; 648</script> 649</body> 650</html>