online Minecraft written book viewer

refactor: make stylesheet.css less unbearable to look at

kokirigla.de 2976c5a4 7d654551

verified
+114 -193
+114 -193
src/web/assets/stylesheet.css
··· 105 105 106 106 :root { 107 107 color-scheme: light; 108 + 108 109 --ink: #101010; 109 110 --ink-muted: #2f2f2f; 111 + --link: #1d4ed8; 112 + 110 113 --surface: #c6c6c6; 111 114 --surface-strong: #b7b7b7; 112 - --surface-weak: #d7d7d7; 113 - --link: #1d4ed8; 115 + --tile-surface: #c0c0c0; 116 + --input-surface: #e2e2e2; 117 + --chip-surface: #cdcdcd; 118 + 114 119 --accent: #4f9a3a; 115 120 --accent-strong: #336f26; 121 + --category-active-border: #275117; 122 + --category-active-surface: #78b65a; 123 + --category-active-ink: #0f2a09; 124 + 116 125 --border: #3b3b3b; 117 - --shadow: none; 126 + --button-border: #1f1f1f; 127 + --border-thin: 0.0625rem solid var(--border); 128 + --border-thick: 0.125rem solid var(--border); 129 + 130 + --radius-panel: 0; 131 + --radius-control: 0; 132 + --bevel-panel: 133 + inset 0.0625rem 0.0625rem 0 rgba(255, 255, 255, 0.45), 134 + inset -0.0625rem -0.0625rem 0 rgba(0, 0, 0, 0.45); 135 + --bevel-control: 136 + inset 0.0625rem 0.0625rem 0 rgba(255, 255, 255, 0.4), 137 + inset -0.0625rem -0.0625rem 0 rgba(0, 0, 0, 0.4); 138 + --bevel-button: 139 + inset 0.0625rem 0.0625rem 0 #88cf67, 140 + inset -0.0625rem -0.0625rem 0 #274d1e; 141 + 142 + --focus-ring: 0.125rem solid rgba(179, 106, 46, 0.35); 143 + 144 + --page-max-width: 71.875rem; 145 + --page-padding: 2rem 1.5rem 3rem; 146 + 118 147 --book-sprite-width: clamp(12.5rem, 24vw, 14.5rem); 119 148 --book-sprite-height: calc(var(--book-sprite-width) * 180 / 146); 120 149 --book-header-top: calc(var(--book-sprite-width) * 12 / 146); ··· 131 160 box-sizing: border-box; 132 161 } 133 162 134 - congress html { 163 + html { 135 164 font-size: clamp(0.875rem, 0.25vw + 0.8rem, 1rem); 136 165 } 137 166 ··· 154 183 } 155 184 156 185 .page { 157 - max-width: 71.875rem; 186 + max-width: var(--page-max-width); 158 187 margin: 0 auto; 159 - padding: 2rem 1.5rem 3rem; 188 + padding: var(--page-padding); 160 189 min-height: 100vh; 161 190 min-height: 100dvh; 162 191 display: flex; 163 192 flex-direction: column; 164 193 } 165 194 166 - .hero { 195 + :is(.hero, .sidebar .panel, .page-preview, .empty-state, .footer, .book-tile) { 196 + border-radius: var(--radius-panel); 197 + border: var(--border-thick); 198 + box-shadow: var(--bevel-panel); 199 + } 200 + 201 + :is(.hero, .sidebar .panel, .page-preview, .empty-state, .footer) { 167 202 background: var(--surface); 168 - border: 0.0625rem solid var(--border); 169 - border-radius: 1.125rem; 203 + } 204 + 205 + .book-tile { 206 + background: var(--tile-surface); 207 + } 208 + 209 + :is(.book-badge, .book-icon, .category-link, .tag, .chip, .detail-link, button, .button, .link-reset, input[type="search"], select) { 210 + border-radius: var(--radius-control); 211 + } 212 + 213 + .hero { 170 214 padding: 1.5rem; 171 - box-shadow: var(--shadow); 172 215 } 173 216 174 217 .brand { ··· 182 225 height: 3.5rem; 183 226 aspect-ratio: 1 / 1; 184 227 flex: 0 0 auto; 185 - border-radius: 0.875rem; 186 228 background: var(--surface-strong); 187 229 display: inline-flex; 188 230 align-items: center; 189 231 justify-content: center; 190 - border: 0.0625rem solid var(--border); 232 + border: var(--border-thin); 191 233 } 192 234 193 235 .book-badge img { 194 236 width: 2.5rem; 195 237 height: 2.5rem; 196 238 object-fit: contain; 197 - congress 198 239 } 199 240 200 241 .eyebrow { 242 + margin: 0 0 0.375rem; 201 243 text-transform: uppercase; 202 244 font-size: 0.75rem; 203 245 letter-spacing: 0.12em; 204 246 color: var(--ink-muted); 205 - margin: 0 0 0.375rem; 206 247 } 207 248 208 249 .hero h1 { ··· 211 252 } 212 253 213 254 .subtle { 214 - color: var(--ink-muted); 215 255 margin: 0.375rem 0 0; 256 + color: var(--ink-muted); 216 257 } 217 258 218 259 .search { 260 + margin-top: 1.25rem; 219 261 display: grid; 220 262 grid-template-columns: repeat(auto-fit, minmax(11.25rem, 1fr)); 221 263 gap: 0.75rem; 222 - margin-top: 1.25rem; 223 264 align-items: end; 224 265 } 225 266 ··· 233 274 234 275 input[type="search"], 235 276 select { 236 - border-radius: 0.625rem; 237 - border: 0.0625rem solid var(--border); 238 277 padding: 0.625rem 0.75rem; 278 + border: var(--border-thick); 239 279 font-family: inherit; 240 280 font-size: 0.875rem; 241 - background: var(--surface-weak); 281 + background: var(--input-surface); 242 282 color: var(--ink); 243 283 } 244 284 245 285 input[type="search"]:focus, 246 286 select:focus { 247 - outline: 0.125rem solid rgba(179, 106, 46, 0.35); 287 + outline: var(--focus-ring); 248 288 border-color: var(--accent); 249 289 } 250 290 251 291 .actions { 252 292 display: flex; 253 - gap: 0.75rem; 254 293 align-items: center; 294 + gap: 0.75rem; 255 295 grid-column: 1 / -1; 256 296 } 257 297 ··· 261 301 262 302 button, 263 303 .button { 264 - border: none; 265 - border-radius: 0.625rem; 266 304 padding: 0.625rem 1.125rem; 305 + border: 0.125rem solid var(--button-border); 267 306 background: var(--accent); 268 - color: #fff; 307 + color: #ffffff; 269 308 font-family: inherit; 270 309 font-size: 0.875rem; 271 310 cursor: pointer; 311 + box-shadow: var(--bevel-button); 312 + text-shadow: 0.0625rem 0.0625rem 0 rgba(0, 0, 0, 0.45); 272 313 } 273 314 274 315 .button.ghost, 275 316 .link-reset { 276 - background: transparent; 277 - color: var(--link); 278 - border: 0.0625rem solid var(--border); 279 317 padding: 0.5625rem 1rem; 280 - border-radius: 0.625rem; 318 + border: var(--border-thick); 319 + background: var(--surface-strong); 320 + color: var(--link); 321 + box-shadow: var(--bevel-control); 281 322 } 282 323 283 324 .active-filters { 325 + margin-top: 1rem; 284 326 display: flex; 327 + flex-wrap: wrap; 285 328 gap: 0.625rem; 286 - margin-top: 1rem; 287 - flex-wrap: wrap; 288 329 } 289 330 290 331 .chip { 291 - background: rgba(179, 106, 46, 0.12); 292 - color: var(--accent-strong); 293 332 padding: 0.375rem 0.625rem; 294 - border-radius: 999rem; 295 333 font-size: 0.75rem; 334 + color: var(--accent-strong); 335 + border: var(--border-thick); 336 + background: var(--chip-surface); 296 337 } 297 338 298 339 .layout { 340 + margin-top: 1.5rem; 299 341 display: grid; 300 342 grid-template-columns: 16.25rem 1fr; 301 343 gap: 1.5rem; 302 - margin-top: 1.5rem; 303 344 } 304 345 305 346 .sidebar .panel { 306 - background: var(--surface-weak); 307 - border: 0.0625rem solid var(--border); 308 - border-radius: 1rem; 347 + margin-bottom: 1.5rem; 309 348 padding: 1.125rem; 310 - margin-bottom: 1.5rem; 311 349 } 312 350 313 351 .sidebar h2 { ··· 322 360 } 323 361 324 362 .category-list { 363 + margin: 0; 364 + padding: 0; 325 365 list-style: none; 326 - padding: 0; 327 - margin: 0; 328 366 display: grid; 329 367 gap: 0.5rem; 330 368 } ··· 333 371 display: flex; 334 372 justify-content: space-between; 335 373 padding: 0.5rem 0.625rem; 336 - border-radius: 0.625rem; 337 - border: 0.0625rem solid transparent; 374 + border: var(--border-thick); 338 375 color: var(--ink); 339 - background: var(--surface); 376 + background: #c3c3c3; 340 377 } 341 378 342 379 .category-link.active { 343 - border-color: var(--accent); 344 - background: rgba(179, 106, 46, 0.12); 380 + border-color: var(--category-active-border); 381 + background: var(--category-active-surface); 382 + color: var(--category-active-ink); 345 383 } 346 384 347 385 .category-link .count { 386 + font-size: 0.75rem; 348 387 color: var(--ink-muted); 349 - font-size: 0.75rem; 350 388 } 351 389 352 390 .results-header { 391 + margin-bottom: 1rem; 353 392 display: flex; 354 393 align-items: flex-end; 355 394 justify-content: space-between; 356 395 gap: 1.25rem; 357 - margin-bottom: 1rem; 358 396 } 359 397 360 398 .results h2 { ··· 374 412 .book-tile { 375 413 text-align: center; 376 414 padding: 0.75rem 0.625rem; 377 - border-radius: 0.875rem; 378 - border: 0.0625rem solid transparent; 379 415 transition: border 0.15s ease, background 0.15s ease; 380 416 } 381 417 ··· 392 428 .book-icon { 393 429 width: 4.5rem; 394 430 height: 4.5rem; 395 - border-radius: 1rem; 396 - border: 0.0625rem solid var(--border); 431 + border: var(--border-thick); 397 432 background: var(--surface); 398 433 display: inline-flex; 399 434 align-items: center; 400 435 justify-content: center; 401 - box-shadow: 0 0.625rem 1.125rem rgba(20, 14, 9, 0.12); 436 + box-shadow: var(--bevel-control); 402 437 transition: transform 0.15s ease, box-shadow 0.15s ease; 403 438 } 404 439 405 440 .book-icon:hover { 406 - transform: translateY(-0.125rem); 407 - box-shadow: 0 0.875rem 1.625rem rgba(20, 14, 9, 0.16); 441 + transform: translateY(-0.0625rem); 442 + box-shadow: var(--bevel-control); 408 443 } 409 444 410 445 .book-icon img { ··· 419 454 420 455 .meta { 421 456 margin: 0; 422 - color: var(--ink-muted); 423 457 font-size: 0.75rem; 458 + color: var(--ink-muted); 424 459 } 425 460 426 461 .detail-link { 462 + padding: 0.375rem 0.75rem; 427 463 font-size: 0.8125rem; 428 - border: 0.0625rem solid var(--border); 429 - border-radius: 999rem; 430 - padding: 0.375rem 0.75rem; 464 + border: var(--border-thin); 431 465 } 432 466 433 467 .meta-row { 468 + margin-top: 0.625rem; 434 469 display: flex; 435 470 flex-wrap: wrap; 436 - gap: 0.5rem; 437 - margin-top: 0.625rem; 438 471 align-items: center; 472 + gap: 0.5rem; 439 473 } 440 474 441 475 .tag { 476 + height: 1.5rem; 477 + padding: 0 0.625rem; 442 478 display: inline-flex; 443 479 align-items: center; 444 - border-radius: 999rem; 445 - background: var(--surface); 446 - border: 0.0625rem solid var(--border); 447 - padding: 0 0.625rem; 480 + border: var(--border-thick); 481 + background: var(--chip-surface); 448 482 font-size: 0.75rem; 449 - line-height: 1; 450 - height: 1.5rem; 451 483 font-weight: 400; 484 + line-height: 1; 452 485 color: var(--ink); 453 486 text-decoration: none; 454 487 } ··· 470 503 } 471 504 472 505 .page-preview { 473 - background: var(--surface); 474 - border-radius: 0.75rem; 475 506 padding: 0.625rem 0.75rem; 476 - border: 0.0625rem solid var(--border); 477 507 } 478 508 479 509 .page-label { 480 510 margin: 0 0 0.375rem; 481 511 font-size: 0.75rem; 482 - color: var(--ink-muted); 483 512 text-transform: uppercase; 484 513 letter-spacing: 0.08em; 514 + color: var(--ink-muted); 485 515 } 486 516 487 517 .empty-state { 488 - border: 0.0625rem dashed var(--border); 518 + margin-bottom: 1rem; 489 519 padding: 1.25rem; 490 - border-radius: 0.875rem; 491 - background: rgba(255, 255, 255, 0.6); 492 - margin-bottom: 1rem; 493 520 } 494 521 495 522 .pager { 523 + margin-top: 1.125rem; 496 524 display: flex; 497 525 gap: 0.75rem; 498 - margin-top: 1.125rem; 499 526 } 500 527 501 528 .pager-top { ··· 511 538 margin-top: auto; 512 539 padding: 1.5rem; 513 540 text-align: center; 514 - color: var(--ink-muted); 515 - background: var(--surface); 516 - border: 0.0625rem solid var(--border); 517 - border-radius: 1.125rem; 518 541 text-transform: lowercase; 542 + color: var(--ink-muted); 519 543 } 520 544 521 545 .detail { 522 - max-width: 71.875rem; 546 + max-width: var(--page-max-width); 523 547 } 524 548 525 549 .detail-hero { ··· 550 574 .pages { 551 575 display: grid; 552 576 grid-template-columns: repeat(auto-fit, var(--book-sprite-width)); 553 - gap: var(--book-grid-gap); 554 577 justify-content: center; 578 + gap: var(--book-grid-gap); 555 579 } 556 580 557 581 .book-page { ··· 563 587 .book-page-sprite { 564 588 width: var(--book-sprite-width); 565 589 height: var(--book-sprite-height); 590 + position: relative; 566 591 background-image: url("/assets/image/book_background.webp"); 567 592 background-size: 100% 100%; 568 593 background-repeat: no-repeat; 569 594 image-rendering: pixelated; 570 - position: relative; 571 595 filter: none; 572 596 } 573 597 ··· 579 603 width: var(--book-text-width); 580 604 max-width: var(--book-text-width); 581 605 height: var(--book-text-height); 606 + margin-left: 0.125rem; 582 607 overflow: hidden; 583 - font-size: var(--book-page-font-size); 584 - line-height: var(--book-page-line-height); 585 - margin-left: 0.125rem; 586 608 white-space: pre-wrap; 587 609 overflow-wrap: anywhere; 588 610 word-break: break-word; 589 611 color: #000000; 612 + font-size: var(--book-page-font-size); 613 + line-height: var(--book-page-line-height); 590 614 letter-spacing: 0; 591 615 font-kerning: none; 592 616 font-variant-ligatures: none; ··· 600 624 transform: translateX(-50%); 601 625 margin: 0; 602 626 width: var(--book-text-width); 603 - text-align: right; 604 627 padding-right: 0.125rem; 628 + text-align: right; 629 + color: #1b1b1b; 605 630 font-size: var(--book-header-font-size); 606 631 line-height: 1; 607 - color: #1b1b1b; 608 632 white-space: nowrap; 609 633 } 610 634 ··· 612 636 line-height: inherit; 613 637 } 614 638 615 - /* Minecraft UI pass: square panels, pixel-style bevels, no soft shadows */ 616 - .hero, 617 - .sidebar .panel, 618 - .book-tile, 619 - .page-preview, 620 - .empty-state, 621 - .footer { 622 - border-radius: 0; 623 - border: 0.125rem solid var(--border); 624 - box-shadow: 625 - inset 0.0625rem 0.0625rem 0 rgba(255, 255, 255, 0.45), 626 - inset -0.0625rem -0.0625rem 0 rgba(0, 0, 0, 0.45); 627 - } 628 - 629 - .hero, 630 - .sidebar .panel, 631 - .page-preview, 632 - .empty-state, 633 - .footer { 634 - background: var(--surface); 635 - } 636 - 637 - .book-tile { 638 - background: #c0c0c0; 639 - } 640 - 641 - .book-badge, 642 - .book-icon, 643 - .category-link, 644 - .tag, 645 - .chip, 646 - .detail-link, 647 - button, 648 - .button, 649 - .link-reset, 650 - input[type="search"], 651 - select { 652 - border-radius: 0; 653 - } 654 - 655 - input[type="search"], 656 - select { 657 - border: 0.125rem solid var(--border); 658 - background: #e2e2e2; 659 - } 660 - 661 - button, 662 - .button { 663 - border: 0.125rem solid #1f1f1f; 664 - box-shadow: 665 - inset 0.0625rem 0.0625rem 0 #88cf67, 666 - inset -0.0625rem -0.0625rem 0 #274d1e; 667 - text-shadow: 0.0625rem 0.0625rem 0 rgba(0, 0, 0, 0.45); 668 - } 669 - 670 - .button.ghost, 671 - .link-reset { 672 - border: 0.125rem solid var(--border); 673 - background: #b7b7b7; 674 - box-shadow: 675 - inset 0.0625rem 0.0625rem 0 rgba(255, 255, 255, 0.4), 676 - inset -0.0625rem -0.0625rem 0 rgba(0, 0, 0, 0.4); 677 - } 678 - 679 - .link-reset { 680 - color: var(--link); 681 - } 682 - 683 - .category-link { 684 - border: 0.125rem solid var(--border); 685 - background: #c3c3c3; 686 - } 687 - 688 - .category-link.active { 689 - border-color: #275117; 690 - background: #78b65a; 691 - color: #0f2a09; 692 - } 693 - 694 - .book-icon { 695 - border: 0.125rem solid var(--border); 696 - box-shadow: 697 - inset 0.0625rem 0.0625rem 0 rgba(255, 255, 255, 0.4), 698 - inset -0.0625rem -0.0625rem 0 rgba(0, 0, 0, 0.45); 699 - } 700 - 701 - .book-icon:hover { 702 - transform: translateY(-0.0625rem); 703 - box-shadow: 704 - inset 0.0625rem 0.0625rem 0 rgba(255, 255, 255, 0.4), 705 - inset -0.0625rem -0.0625rem 0 rgba(0, 0, 0, 0.45); 706 - } 707 - 708 - .tag, 709 - .chip { 710 - border: 0.125rem solid var(--border); 711 - background: #cdcdcd; 712 - } 713 - 714 639 .item { 715 640 image-rendering: pixelated; 716 641 } ··· 725 650 position: absolute; 726 651 inset: 0; 727 652 pointer-events: none; 653 + opacity: 0.6; 728 654 background-image: url("/assets/image/glint.webp"); 729 655 background-repeat: repeat; 730 656 background-size: 4rem 4rem; 731 657 background-position: 0 0; 732 - opacity: 0.6; 733 658 mix-blend-mode: screen; 734 659 mask-image: var(--mask, var(--book-mask)); 735 660 mask-repeat: no-repeat; 736 661 mask-size: 100% 100%; 737 - animation: glintMove 10.0s linear infinite, glintHue 10s linear infinite; 662 + animation: glintMove 10s linear infinite, glintHue 10s linear infinite; 738 663 } 739 664 740 665 @keyframes glintMove { ··· 776 701 padding: 1.5rem 1rem 2.5rem; 777 702 } 778 703 779 - .brand { 780 - flex-direction: column; 781 - align-items: flex-start; 782 - } 783 - 704 + .brand, 784 705 .detail-hero { 785 706 flex-direction: column; 786 707 align-items: flex-start;