WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto
at main 1182 lines 30 kB view raw
1/* theme.css — neobrutal component styles for atBB */ 2/* All values use var(--token) — no hardcoded colors, sizes, or fonts */ 3 4/* ─── Base / Typography ─────────────────────────────────────────────────── */ 5 6body { 7 font-family: var(--font-body); 8 font-size: var(--font-size-base); 9 font-weight: var(--font-weight-normal); 10 line-height: var(--line-height-body); 11 color: var(--color-text); 12 background-color: var(--color-bg); 13} 14 15h1, 16h2, 17h3, 18h4, 19h5, 20h6 { 21 font-family: var(--font-heading); 22 font-weight: var(--font-weight-bold); 23 line-height: var(--line-height-heading); 24} 25 26a { 27 color: var(--color-primary); 28 text-decoration: underline; 29 transition: color 0.15s ease; 30} 31 32a:hover { 33 color: var(--color-primary-hover); 34} 35 36code { 37 font-family: var(--font-mono); 38 font-size: var(--font-size-sm); 39 background-color: var(--color-code-bg); 40 color: var(--color-code-text); 41 padding: var(--space-xs) var(--space-sm); 42 border-radius: var(--radius); 43} 44 45pre { 46 font-family: var(--font-mono); 47 font-size: var(--font-size-sm); 48 background-color: var(--color-code-bg); 49 color: var(--color-code-text); 50 padding: var(--space-md); 51 border-radius: var(--radius); 52 overflow-x: auto; 53} 54 55pre code { 56 padding: 0; 57 background: none; 58} 59 60/* ─── Skip Link ────────────────────────────────────────────────────────── */ 61 62.skip-link { 63 position: absolute; 64 left: -9999px; 65 top: auto; 66 width: 1px; 67 height: 1px; 68 overflow: hidden; 69 z-index: 1000; 70} 71 72.skip-link:focus { 73 position: fixed; 74 top: var(--space-sm); 75 left: var(--space-sm); 76 width: auto; 77 height: auto; 78 padding: var(--space-sm) var(--space-md); 79 background-color: var(--color-primary); 80 color: var(--color-surface); 81 font-weight: var(--font-weight-bold); 82 border: var(--border-width) solid var(--color-border); 83 box-shadow: var(--button-shadow); 84 text-decoration: none; 85 z-index: 1000; 86} 87 88/* ─── Screen Reader Only ───────────────────────────────────────────────── */ 89 90.sr-only { 91 position: absolute; 92 width: 1px; 93 height: 1px; 94 padding: 0; 95 margin: -1px; 96 overflow: hidden; 97 clip: rect(0, 0, 0, 0); 98 white-space: nowrap; 99 border: 0; 100} 101 102/* ─── Focus Styles ─────────────────────────────────────────────────────── */ 103 104:focus-visible { 105 outline: 3px solid var(--color-primary); 106 outline-offset: 2px; 107} 108 109:focus:not(:focus-visible) { 110 outline: none; 111} 112 113/* ─── Layout ────────────────────────────────────────────────────────────── */ 114 115.site-header { 116 height: var(--nav-height); 117 background-color: var(--color-surface); 118 border-bottom: var(--border-width) solid var(--color-border); 119 display: flex; 120 align-items: center; 121} 122 123.site-header__inner { 124 max-width: var(--content-width); 125 width: 100%; 126 margin: 0 auto; 127 padding: 0 var(--space-md); 128 display: flex; 129 align-items: center; 130 justify-content: space-between; 131} 132 133.site-header__title { 134 font-family: var(--font-heading); 135 font-weight: var(--font-weight-bold); 136 font-size: var(--font-size-lg); 137 color: var(--color-text); 138 text-decoration: none; 139 transition: color 0.15s ease; 140} 141 142.site-header__title:hover { 143 color: var(--color-primary); 144} 145 146.site-header__nav { 147 display: flex; 148 align-items: center; 149 gap: var(--space-md); 150} 151 152.site-header__handle { 153 font-weight: var(--font-weight-bold); 154 font-size: var(--font-size-sm); 155} 156 157.site-header__logout-form { 158 display: inline; 159} 160 161.site-header__logout-btn { 162 cursor: pointer; 163 background: none; 164 border: none; 165 color: var(--color-text-muted); 166 font-family: var(--font-body); 167 font-size: var(--font-size-sm); 168 padding: var(--space-xs) var(--space-sm); 169 text-decoration: underline; 170 transition: color 0.15s ease; 171} 172 173.site-header__logout-btn:hover { 174 color: var(--color-danger); 175} 176 177.site-header__login-link { 178 font-weight: var(--font-weight-bold); 179} 180 181.color-scheme-toggle { 182 cursor: pointer; 183 display: inline-flex; 184 align-items: center; 185 justify-content: center; 186 font-family: var(--font-body); 187 font-size: var(--font-size-base); 188 line-height: 1; 189 border: var(--border-width) solid var(--color-border); 190 border-radius: var(--button-radius); 191 padding: var(--space-xs) var(--space-sm); 192 box-shadow: var(--button-shadow); 193 background-color: var(--color-surface); 194 color: var(--color-text); 195 min-width: 36px; 196 min-height: 36px; 197 transition: transform 0.1s ease, box-shadow 0.1s ease; 198} 199 200.color-scheme-toggle:hover { 201 transform: translate(var(--btn-press-hover), var(--btn-press-hover)); 202 box-shadow: var(--btn-press-hover) var(--btn-press-hover) 0 var(--color-shadow); 203} 204 205.color-scheme-toggle:active { 206 transform: translate(var(--btn-press-active), var(--btn-press-active)); 207 box-shadow: none; 208} 209 210.content-container { 211 max-width: var(--content-width); 212 margin: 0 auto; 213 padding: var(--space-xl) var(--space-md); 214} 215 216.site-footer { 217 padding: var(--space-lg) var(--space-md); 218 text-align: center; 219 color: var(--color-text-muted); 220 font-size: var(--font-size-sm); 221 border-top: var(--border-width) solid var(--color-border); 222} 223 224/* ─── Mobile Navigation ────────────────────────────────────────────────── */ 225 226.mobile-nav { 227 display: block; 228 position: relative; 229} 230 231.mobile-nav__toggle { 232 cursor: pointer; 233 font-size: var(--font-size-lg); 234 list-style: none; 235 padding: var(--space-xs) var(--space-sm); 236 min-width: 44px; 237 min-height: 44px; 238 display: flex; 239 align-items: center; 240 justify-content: center; 241 background: none; 242 border: none; 243} 244 245.mobile-nav__toggle::-webkit-details-marker { 246 display: none; 247} 248 249.mobile-nav__menu { 250 position: absolute; 251 right: 0; 252 top: 100%; 253 background-color: var(--color-surface); 254 border: var(--border-width) solid var(--color-border); 255 box-shadow: var(--card-shadow); 256 padding: var(--space-md); 257 min-width: 200px; 258 z-index: 100; 259 display: flex; 260 flex-direction: column; 261 gap: var(--space-sm); 262} 263 264.desktop-nav { 265 display: none; 266 align-items: center; 267 gap: var(--space-md); 268} 269 270/* ─── Card ──────────────────────────────────────────────────────────────── */ 271 272.card { 273 background-color: var(--color-surface); 274 border: var(--border-width) solid var(--color-border); 275 border-radius: var(--card-radius); 276 box-shadow: var(--card-shadow); 277 padding: var(--space-md); 278 transition: transform 0.15s ease, box-shadow 0.15s ease; 279} 280 281/* ─── Button ────────────────────────────────────────────────────────────── */ 282 283.btn { 284 cursor: pointer; 285 display: inline-flex; 286 align-items: center; 287 gap: var(--space-sm); 288 font-family: var(--font-body); 289 font-weight: var(--font-weight-bold); 290 font-size: var(--font-size-base); 291 line-height: 1; 292 border: var(--border-width) solid var(--color-border); 293 border-radius: var(--button-radius); 294 padding: var(--space-sm) var(--space-md); 295 box-shadow: var(--button-shadow); 296 background-color: var(--color-surface); 297 color: var(--color-text); 298 text-decoration: none; 299 transition: transform 0.1s ease, box-shadow 0.1s ease; 300 user-select: none; 301} 302 303.btn-primary { 304 background-color: var(--color-primary); 305 color: var(--color-surface); 306} 307 308.btn-secondary { 309 background-color: var(--color-secondary); 310 color: var(--color-surface); 311} 312 313.btn-danger { 314 background-color: var(--color-danger); 315 color: var(--color-surface); 316} 317 318.btn:hover { 319 transform: translate(var(--btn-press-hover), var(--btn-press-hover)); 320 box-shadow: var(--btn-press-hover) var(--btn-press-hover) 0 var(--color-shadow); 321} 322 323.btn:active { 324 transform: translate(var(--btn-press-active), var(--btn-press-active)); 325 box-shadow: none; 326} 327 328/* ─── Page Header ───────────────────────────────────────────────────────── */ 329 330.page-header { 331 display: flex; 332 align-items: center; 333 justify-content: space-between; 334 margin-bottom: var(--space-lg); 335 gap: var(--space-md); 336 padding-bottom: var(--space-md); 337 border-bottom: var(--border-width) solid var(--color-border); 338} 339 340.page-header__text h1 { 341 margin: 0; 342 font-size: var(--font-size-xl); 343} 344 345.page-header__text p { 346 margin: var(--space-xs) 0 0; 347 color: var(--color-text-muted); 348 font-size: var(--font-size-sm); 349} 350 351/* ─── Error Display ─────────────────────────────────────────────────────── */ 352 353.error-display { 354 background-color: var(--color-surface); 355 border: var(--border-width) solid var(--color-danger); 356 border-left-width: calc(var(--border-width) * 3); 357 border-radius: var(--radius); 358 padding: var(--space-lg); 359 color: var(--color-danger); 360} 361 362.error-display__message { 363 font-weight: var(--font-weight-bold); 364 font-size: var(--font-size-lg); 365 margin-bottom: var(--space-xs); 366} 367 368.error-display__detail { 369 color: var(--color-text-muted); 370 font-size: var(--font-size-sm); 371} 372 373/* ─── Empty State ───────────────────────────────────────────────────────── */ 374 375.empty-state { 376 text-align: center; 377 padding: var(--space-xl) var(--space-md); 378 color: var(--color-text-muted); 379 border: var(--border-width) dashed var(--color-border); 380 margin: var(--space-md) 0; 381} 382 383.empty-state p { 384 font-size: var(--font-size-lg); 385 margin-bottom: var(--space-sm); 386} 387 388.empty-state__action { 389 margin-top: var(--space-md); 390} 391 392/* ─── Loading State (HTMX indicator) ───────────────────────────────────── */ 393 394.loading-state { 395 opacity: 0; 396 transition: opacity 0.2s ease; 397 text-align: center; 398 padding: var(--space-md); 399 color: var(--color-text-muted); 400} 401 402.loading-state.htmx-request { 403 opacity: 1; 404} 405 406.htmx-indicator { 407 opacity: 0; 408 transition: opacity 0.2s ease; 409} 410 411.htmx-request .htmx-indicator, 412.htmx-request.htmx-indicator { 413 opacity: 1; 414} 415 416/* ─── Error Page ────────────────────────────────────────────────────────── */ 417 418.error-page { 419 text-align: center; 420 padding: var(--space-xl) var(--space-md); 421} 422 423.error-page__code { 424 font-family: var(--font-heading); 425 font-size: 6rem; 426 font-weight: var(--font-weight-bold); 427 line-height: 1; 428 color: var(--color-primary); 429 margin-bottom: var(--space-sm); 430} 431 432.error-page__title { 433 font-size: var(--font-size-xl); 434 margin-bottom: var(--space-sm); 435} 436 437.error-page__message { 438 color: var(--color-text-muted); 439 font-size: var(--font-size-base); 440 margin-bottom: var(--space-lg); 441} 442 443/* ─── Homepage ──────────────────────────────────────────────────────────── */ 444 445.category-section { 446 margin-bottom: var(--space-xl); 447} 448 449.category-header { 450 margin: 0 0 var(--space-md) 0; 451 font-size: var(--font-size-lg); 452 padding-bottom: var(--space-sm); 453 border-bottom: var(--border-width) solid var(--color-border); 454} 455 456.board-grid { 457 display: flex; 458 flex-direction: column; 459 gap: var(--space-md); 460} 461 462.board-card { 463 display: block; 464 text-decoration: none; 465 color: inherit; 466} 467 468.board-card:hover .card { 469 transform: translate(-2px, -2px); 470 box-shadow: calc(var(--shadow-offset) + 2px) calc(var(--shadow-offset) + 2px) 0 var(--color-shadow); 471} 472 473.board-card__name { 474 font-weight: var(--font-weight-bold); 475 font-size: var(--font-size-base); 476 margin: 0 0 var(--space-xs) 0; 477} 478 479.board-card__description { 480 margin: 0; 481 color: var(--color-text-muted); 482 font-size: var(--font-size-sm); 483} 484 485/* ─── Forms ─────────────────────────────────────────────────────────────── */ 486 487.form-group { 488 display: flex; 489 flex-direction: column; 490 gap: var(--space-xs); 491 margin-bottom: var(--space-md); 492} 493 494.form-group label { 495 font-weight: var(--font-weight-bold); 496 font-size: var(--font-size-sm); 497} 498 499.form-group input, 500.form-group textarea, 501.form-group select { 502 border: var(--input-border); 503 border-radius: var(--input-radius); 504 padding: var(--space-sm) var(--space-md); 505 font-family: var(--font-body); 506 font-size: var(--font-size-base); 507 background-color: var(--color-surface); 508 color: var(--color-text); 509 min-height: 44px; 510} 511 512.form-group textarea { 513 min-height: 120px; 514 resize: vertical; 515} 516 517.form-actions { 518 display: flex; 519 flex-direction: row; 520 gap: var(--space-sm); 521 margin-top: var(--space-md); 522} 523 524.form-error { 525 color: var(--color-danger); 526 font-size: var(--font-size-sm); 527 font-weight: var(--font-weight-bold); 528 margin: var(--space-xs) 0; 529} 530 531.char-count { 532 font-size: var(--font-size-sm); 533 color: var(--color-text-muted); 534} 535 536.char-count[data-over="true"] { 537 color: var(--color-danger); 538 font-weight: var(--font-weight-bold); 539} 540 541.success-banner { 542 background-color: var(--color-success); 543 color: var(--color-surface); 544 padding: var(--space-sm) var(--space-md); 545 margin-bottom: var(--space-md); 546 font-weight: var(--font-weight-bold); 547 border: var(--border-width) solid var(--color-border); 548} 549 550/* ─── Login Form ────────────────────────────────────────────────────────── */ 551 552.login-form { 553 max-width: 480px; 554} 555 556.login-form__form { 557 display: flex; 558 flex-direction: column; 559 gap: var(--space-md); 560} 561 562.login-form__label { 563 font-weight: var(--font-weight-bold); 564} 565 566.login-form__input { 567 border: var(--input-border); 568 border-radius: var(--input-radius); 569 padding: var(--space-sm) var(--space-md); 570 font-family: var(--font-body); 571 font-size: var(--font-size-base); 572 background-color: var(--color-surface); 573 color: var(--color-text); 574 min-height: 44px; 575 width: 100%; 576 box-sizing: border-box; 577} 578 579.login-form__hint { 580 color: var(--color-text-muted); 581 font-size: var(--font-size-sm); 582} 583 584.login-form__error { 585 border: var(--border-width) solid var(--color-danger); 586 padding: var(--space-sm) var(--space-md); 587 color: var(--color-danger); 588 font-weight: var(--font-weight-bold); 589} 590 591.login-form__submit { 592 cursor: pointer; 593 display: inline-flex; 594 align-items: center; 595 justify-content: center; 596 gap: var(--space-sm); 597 font-family: var(--font-body); 598 font-weight: var(--font-weight-bold); 599 font-size: var(--font-size-base); 600 line-height: 1; 601 border: var(--border-width) solid var(--color-border); 602 border-radius: var(--button-radius); 603 padding: var(--space-sm) var(--space-md); 604 box-shadow: var(--button-shadow); 605 background-color: var(--color-primary); 606 color: var(--color-surface); 607 text-decoration: none; 608 transition: transform 0.1s ease, box-shadow 0.1s ease; 609 user-select: none; 610} 611 612.login-form__submit:hover { 613 transform: translate(var(--btn-press-hover), var(--btn-press-hover)); 614 box-shadow: var(--btn-press-hover) var(--btn-press-hover) 0 var(--color-shadow); 615} 616 617.login-form__submit:active { 618 transform: translate(var(--btn-press-active), var(--btn-press-active)); 619 box-shadow: none; 620} 621 622/* ─── Post Cards ────────────────────────────────────────────────────────── */ 623 624.post-card { 625 background-color: var(--color-surface); 626 border: var(--border-width) solid var(--color-border); 627 border-left-width: calc(var(--border-width) * 2); 628 border-left-color: var(--color-primary); 629 padding: var(--space-md); 630 margin-bottom: var(--space-md); 631 transition: transform 0.15s ease, box-shadow 0.15s ease; 632} 633 634.post-card--op { 635 border-left-width: calc(var(--border-width) * 3); 636 box-shadow: var(--card-shadow); 637} 638 639.post-card--reply { 640 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--color-shadow); 641} 642 643.post-card__header { 644 display: flex; 645 flex-direction: row; 646 align-items: center; 647 gap: var(--space-sm); 648 margin-bottom: var(--space-sm); 649 flex-wrap: wrap; 650} 651 652.post-card__number { 653 font-weight: var(--font-weight-bold); 654 background-color: var(--color-primary); 655 color: var(--color-surface); 656 padding: var(--space-xs) var(--space-sm); 657 min-width: 2em; 658 text-align: center; 659} 660 661.post-card__author { 662 font-weight: var(--font-weight-bold); 663 font-size: var(--font-size-sm); 664} 665 666.post-card__date { 667 color: var(--color-text-muted); 668 font-size: var(--font-size-sm); 669 margin-left: auto; 670} 671 672.post-card__body { 673 white-space: pre-wrap; 674 word-break: break-word; 675 line-height: var(--line-height-body); 676} 677 678/* ─── Breadcrumb ────────────────────────────────────────────────────────── */ 679 680.breadcrumb { 681 font-size: var(--font-size-sm); 682 color: var(--color-text-muted); 683 margin-bottom: var(--space-md); 684} 685 686.breadcrumb a { 687 color: var(--color-text-muted); 688 text-decoration: none; 689} 690 691.breadcrumb a:hover { 692 color: var(--color-primary); 693} 694 695.breadcrumb ol { 696 display: flex; 697 flex-wrap: wrap; 698 gap: 0; 699 list-style: none; 700 padding: 0; 701 margin: 0; 702} 703 704.breadcrumb li { 705 display: flex; 706 align-items: center; 707} 708 709.breadcrumb li + li::before { 710 content: "/"; 711 margin: 0 var(--space-sm); 712 color: var(--color-text-muted); 713} 714 715/* ─── Topic Rows ────────────────────────────────────────────────────────── */ 716 717.topic-row { 718 display: flex; 719 flex-direction: row; 720 justify-content: space-between; 721 align-items: baseline; 722 gap: var(--space-md); 723 padding: var(--space-md); 724 border: var(--border-width) solid var(--color-border); 725 background-color: var(--color-surface); 726 margin-bottom: var(--space-sm); 727 transition: transform 0.15s ease, box-shadow 0.15s ease; 728} 729 730.topic-row:hover { 731 transform: translate(-1px, -1px); 732 box-shadow: 3px 3px 0 var(--color-shadow); 733} 734 735.topic-row__title { 736 font-weight: var(--font-weight-bold); 737 color: var(--color-text); 738 text-decoration: none; 739 flex: 1; 740 overflow: hidden; 741 text-overflow: ellipsis; 742 white-space: nowrap; 743} 744 745.topic-row__title:hover { 746 color: var(--color-primary); 747} 748 749.topic-row__meta { 750 display: flex; 751 gap: var(--space-sm); 752 color: var(--color-text-muted); 753 font-size: var(--font-size-sm); 754 white-space: nowrap; 755} 756 757/* ─── Topic Locked Banner ───────────────────────────────────────────────── */ 758 759.topic-locked-banner { 760 background-color: var(--color-warning); 761 color: var(--color-text); 762 padding: var(--space-sm) var(--space-md); 763 margin-bottom: var(--space-md); 764 font-weight: var(--font-weight-bold); 765 border: var(--border-width) solid var(--color-border); 766 display: flex; 767 align-items: center; 768 gap: var(--space-sm); 769} 770 771.topic-locked-banner__badge { 772 background-color: var(--color-text); 773 color: var(--color-warning); 774 padding: var(--space-xs) var(--space-sm); 775 font-size: var(--font-size-sm); 776 text-transform: uppercase; 777 letter-spacing: 0.05em; 778} 779 780/* ─── Moderation UI ──────────────────────────────────────────────────────── */ 781 782.post-card__mod-actions { 783 display: flex; 784 gap: var(--space-sm); 785 margin-top: var(--space-sm); 786 padding-top: var(--space-sm); 787 border-top: var(--border-width) solid var(--color-border); 788} 789 790.mod-btn { 791 font-size: var(--font-size-xs); 792 padding: var(--space-xs) var(--space-sm); 793 border: var(--border-width) solid currentColor; 794 border-radius: var(--radius); 795 cursor: pointer; 796 background: transparent; 797 font-family: inherit; 798 font-weight: var(--font-weight-bold); 799 text-transform: uppercase; 800 letter-spacing: 0.05em; 801} 802 803.mod-btn--hide, 804.mod-btn--lock { 805 color: var(--color-danger); 806} 807 808.mod-btn--hide:hover, 809.mod-btn--lock:hover { 810 background: var(--color-danger); 811 color: var(--color-surface); 812} 813 814.mod-btn--unhide, 815.mod-btn--unlock, 816.mod-btn--ban { 817 color: var(--color-text-muted); 818} 819 820.mod-btn--unhide:hover, 821.mod-btn--unlock:hover, 822.mod-btn--ban:hover { 823 background: var(--color-text-muted); 824 color: var(--color-surface); 825} 826 827.topic-mod-controls { 828 margin-bottom: var(--space-md); 829} 830 831.mod-dialog { 832 border: var(--border-width) solid var(--color-border); 833 border-radius: var(--radius); 834 padding: var(--space-lg); 835 max-width: 480px; 836 width: 90vw; 837 box-shadow: var(--card-shadow); 838 background: var(--color-bg); 839} 840 841.mod-dialog::backdrop { 842 background: rgba(0, 0, 0, 0.5); 843} 844 845.mod-dialog__title { 846 margin-top: 0; 847 margin-bottom: var(--space-md); 848 font-size: var(--font-size-lg); 849} 850 851/* ═══════════════════════════════════════════════════════════════════════════ 852 RESPONSIVE BREAKPOINTS (mobile-first) 853 Base = mobile (0-767px), tablet = 768px+, desktop = 1024px+ 854 ═══════════════════════════════════════════════════════════════════════════ */ 855 856/* ─── Tablet (768px+) ──────────────────────────────────────────────────── */ 857 858@media (min-width: 768px) { 859 :root { 860 --content-width: 720px; 861 } 862 863 .topic-row { 864 flex-direction: row; 865 align-items: baseline; 866 } 867 868 .topic-row__title { 869 white-space: nowrap; 870 overflow: hidden; 871 text-overflow: ellipsis; 872 } 873 874 .mobile-nav { 875 display: none; 876 } 877 878 .desktop-nav { 879 display: flex; 880 } 881} 882 883/* ─── Desktop (1024px+) ───────────────────────────────────────────────── */ 884 885@media (min-width: 1024px) { 886 :root { 887 --content-width: 960px; 888 --border-width: 3px; 889 --shadow-offset: 4px; 890 --button-shadow: 4px 4px 0 var(--color-shadow); 891 --card-shadow: 6px 6px 0 var(--color-shadow); 892 --btn-press-hover: 2px; 893 --btn-press-active: 4px; 894 --input-border: 3px solid var(--color-border); 895 } 896 897} 898 899/* ─── Mobile-specific overrides ────────────────────────────────────────── */ 900 901@media (max-width: 767px) { 902 .page-header { 903 flex-direction: column; 904 align-items: flex-start; 905 } 906 907 .topic-row { 908 flex-direction: column; 909 gap: var(--space-xs); 910 } 911 912 .topic-row__title { 913 white-space: normal; 914 } 915 916 .topic-row__meta { 917 flex-wrap: wrap; 918 } 919 920 .post-card__header { 921 flex-direction: column; 922 align-items: flex-start; 923 gap: var(--space-xs); 924 } 925 926 .post-card__date { 927 margin-left: 0; 928 } 929 930 .login-form { 931 max-width: 100%; 932 } 933 934 .desktop-nav { 935 display: none; 936 } 937 938 .mobile-nav { 939 display: block; 940 } 941} 942 943/* ─── Admin Panel ───────────────────────────────────────────────────────── */ 944 945.admin-nav-grid { 946 display: grid; 947 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 948 gap: var(--space-md); 949 margin-top: var(--space-lg); 950} 951 952.admin-nav-card { 953 text-decoration: none; 954 color: inherit; 955 display: block; 956} 957 958.admin-nav-card:hover .card { 959 border-color: var(--color-primary); 960} 961 962.admin-nav-card__icon { 963 font-size: var(--font-size-xl); 964 margin-bottom: var(--space-sm); 965} 966 967.admin-nav-card__title { 968 font-family: var(--font-heading); 969 font-weight: var(--font-weight-bold); 970 font-size: var(--font-size-lg); 971 margin-bottom: var(--space-xs); 972} 973 974.admin-nav-card__description { 975 color: var(--color-text-muted); 976 font-size: var(--font-size-sm); 977} 978 979/* ─── Admin Member Table ─────────────────────────────────────────────────── */ 980 981.admin-member-table { 982 width: 100%; 983 border-collapse: collapse; 984 margin-top: var(--space-md); 985} 986 987.admin-member-table th { 988 text-align: left; 989 padding: var(--space-sm) var(--space-md); 990 border-bottom: calc(var(--border-width) * 2) solid var(--color-border); 991 font-weight: var(--font-weight-bold); 992 font-size: var(--font-size-sm); 993 color: var(--color-text-muted); 994 text-transform: uppercase; 995 letter-spacing: 0.05em; 996} 997 998.admin-member-table td { 999 padding: var(--space-sm) var(--space-md); 1000 border-bottom: var(--border-width) solid var(--color-border); 1001 vertical-align: middle; 1002} 1003 1004.admin-member-table tbody tr:last-child td { 1005 border-bottom: none; 1006} 1007 1008.role-badge { 1009 display: inline-block; 1010 padding: var(--space-xs) var(--space-sm); 1011 border: var(--border-width) solid var(--color-border); 1012 font-size: var(--font-size-sm); 1013 font-weight: var(--font-weight-bold); 1014 background-color: var(--color-surface); 1015} 1016 1017.member-row__assign-form { 1018 display: flex; 1019 align-items: center; 1020 gap: var(--space-sm); 1021 flex-wrap: wrap; 1022} 1023 1024.member-row__error { 1025 display: block; 1026 color: var(--color-danger); 1027 font-size: var(--font-size-sm); 1028 font-weight: var(--font-weight-bold); 1029 margin-top: var(--space-xs); 1030} 1031 1032/* ── Structure Management Page ──────────────────────────────────────────── */ 1033 1034.structure-page { 1035 display: flex; 1036 flex-direction: column; 1037 gap: var(--space-lg); 1038} 1039 1040.structure-category { 1041 background: var(--color-surface); 1042 border: var(--border-width) solid var(--color-border); 1043 border-radius: var(--radius); 1044 overflow: hidden; 1045} 1046 1047.structure-category__header { 1048 display: flex; 1049 align-items: center; 1050 gap: var(--space-sm); 1051 padding: var(--space-sm) var(--space-md); 1052 background: var(--color-bg); 1053 border-bottom: var(--border-width) solid var(--color-border); 1054} 1055 1056.structure-category__name { 1057 font-weight: var(--font-weight-bold); 1058 font-size: var(--font-size-base); 1059 flex: 1; 1060} 1061 1062.structure-category__meta { 1063 font-size: var(--font-size-sm); 1064 color: var(--color-text-muted); 1065} 1066 1067.structure-category__actions { 1068 display: flex; 1069 gap: var(--space-sm); 1070 flex-shrink: 0; 1071} 1072 1073.structure-boards { 1074 padding: var(--space-sm); 1075 display: flex; 1076 flex-direction: column; 1077 gap: var(--space-sm); 1078} 1079 1080.structure-board { 1081 background: var(--color-bg); 1082 border: var(--border-width) solid var(--color-border); 1083 border-radius: var(--radius); 1084} 1085 1086.structure-board__header { 1087 display: flex; 1088 align-items: center; 1089 gap: var(--space-sm); 1090 padding: var(--space-xs) var(--space-sm); 1091} 1092 1093.structure-board__name { 1094 font-weight: var(--font-weight-bold); 1095 flex: 1; 1096} 1097 1098.structure-board__meta { 1099 font-size: var(--font-size-sm); 1100 color: var(--color-text-muted); 1101} 1102 1103.structure-board__actions { 1104 display: flex; 1105 gap: var(--space-sm); 1106 flex-shrink: 0; 1107} 1108 1109.structure-edit-form { 1110 border-top: var(--border-width) solid var(--color-border); 1111} 1112 1113.structure-edit-form[open] { 1114 display: block; 1115} 1116 1117.structure-edit-form__body { 1118 padding: var(--space-md); 1119 display: flex; 1120 flex-direction: column; 1121 gap: var(--space-sm); 1122} 1123 1124.structure-add-board { 1125 border: var(--border-width) dashed var(--color-border); 1126 border-radius: var(--radius); 1127 background: transparent; 1128} 1129 1130.structure-add-board__trigger { 1131 display: block; 1132 padding: var(--space-xs) var(--space-sm); 1133 cursor: pointer; 1134 color: var(--color-primary); 1135 font-size: var(--font-size-sm); 1136 user-select: none; 1137} 1138 1139.structure-add-board__trigger:hover { 1140 background: var(--color-surface); 1141 border-radius: var(--radius); 1142} 1143 1144.structure-add-category { 1145 margin-top: var(--space-md); 1146} 1147 1148.structure-confirm-dialog { 1149 border-radius: var(--radius); 1150 border: var(--border-width) solid var(--color-border); 1151 padding: var(--space-lg); 1152 max-width: 24rem; 1153} 1154 1155.structure-confirm-dialog::backdrop { 1156 background: rgba(0, 0, 0, 0.4); 1157} 1158 1159.structure-confirm-dialog p { 1160 margin-bottom: var(--space-md); 1161} 1162 1163.dialog-actions { 1164 display: flex; 1165 gap: var(--space-sm); 1166 justify-content: flex-end; 1167} 1168 1169.structure-error-banner { 1170 background: var(--color-surface); 1171 color: var(--color-danger); 1172 border: var(--border-width) solid var(--color-danger); 1173 border-left-width: calc(var(--border-width) * 3); 1174 border-radius: var(--radius); 1175 padding: var(--space-sm) var(--space-md); 1176 margin-bottom: var(--space-md); 1177} 1178 1179.btn-sm { 1180 font-size: var(--font-size-sm); 1181 padding: var(--space-xs) var(--space-sm); 1182}