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
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.content-container {
182 max-width: var(--content-width);
183 margin: 0 auto;
184 padding: var(--space-xl) var(--space-md);
185}
186
187.site-footer {
188 padding: var(--space-lg) var(--space-md);
189 text-align: center;
190 color: var(--color-text-muted);
191 font-size: var(--font-size-sm);
192 border-top: var(--border-width) solid var(--color-border);
193}
194
195/* ─── Mobile Navigation ────────────────────────────────────────────────── */
196
197.mobile-nav {
198 display: block;
199 position: relative;
200}
201
202.mobile-nav__toggle {
203 cursor: pointer;
204 font-size: var(--font-size-lg);
205 list-style: none;
206 padding: var(--space-xs) var(--space-sm);
207 min-width: 44px;
208 min-height: 44px;
209 display: flex;
210 align-items: center;
211 justify-content: center;
212 background: none;
213 border: none;
214}
215
216.mobile-nav__toggle::-webkit-details-marker {
217 display: none;
218}
219
220.mobile-nav__menu {
221 position: absolute;
222 right: 0;
223 top: 100%;
224 background-color: var(--color-surface);
225 border: var(--border-width) solid var(--color-border);
226 box-shadow: var(--card-shadow);
227 padding: var(--space-md);
228 min-width: 200px;
229 z-index: 100;
230 display: flex;
231 flex-direction: column;
232 gap: var(--space-sm);
233}
234
235.desktop-nav {
236 display: none;
237 align-items: center;
238 gap: var(--space-md);
239}
240
241/* ─── Card ──────────────────────────────────────────────────────────────── */
242
243.card {
244 background-color: var(--color-surface);
245 border: var(--border-width) solid var(--color-border);
246 border-radius: var(--card-radius);
247 box-shadow: var(--card-shadow);
248 padding: var(--space-md);
249 transition: transform 0.15s ease, box-shadow 0.15s ease;
250}
251
252/* ─── Button ────────────────────────────────────────────────────────────── */
253
254.btn {
255 cursor: pointer;
256 display: inline-flex;
257 align-items: center;
258 gap: var(--space-sm);
259 font-family: var(--font-body);
260 font-weight: var(--font-weight-bold);
261 font-size: var(--font-size-base);
262 line-height: 1;
263 border: var(--border-width) solid var(--color-border);
264 border-radius: var(--button-radius);
265 padding: var(--space-sm) var(--space-md);
266 box-shadow: var(--button-shadow);
267 background-color: var(--color-surface);
268 color: var(--color-text);
269 text-decoration: none;
270 transition: transform 0.1s ease, box-shadow 0.1s ease;
271 user-select: none;
272}
273
274.btn-primary {
275 background-color: var(--color-primary);
276 color: var(--color-surface);
277}
278
279.btn-secondary {
280 background-color: var(--color-secondary);
281 color: var(--color-surface);
282}
283
284.btn-danger {
285 background-color: var(--color-danger);
286 color: var(--color-surface);
287}
288
289.btn:hover {
290 transform: translate(var(--btn-press-hover), var(--btn-press-hover));
291 box-shadow: var(--btn-press-hover) var(--btn-press-hover) 0 var(--color-shadow);
292}
293
294.btn:active {
295 transform: translate(var(--btn-press-active), var(--btn-press-active));
296 box-shadow: none;
297}
298
299/* ─── Page Header ───────────────────────────────────────────────────────── */
300
301.page-header {
302 display: flex;
303 align-items: center;
304 justify-content: space-between;
305 margin-bottom: var(--space-lg);
306 gap: var(--space-md);
307 padding-bottom: var(--space-md);
308 border-bottom: var(--border-width) solid var(--color-border);
309}
310
311.page-header__text h1 {
312 margin: 0;
313 font-size: var(--font-size-xl);
314}
315
316.page-header__text p {
317 margin: var(--space-xs) 0 0;
318 color: var(--color-text-muted);
319 font-size: var(--font-size-sm);
320}
321
322/* ─── Error Display ─────────────────────────────────────────────────────── */
323
324.error-display {
325 background-color: var(--color-surface);
326 border: var(--border-width) solid var(--color-danger);
327 border-left-width: calc(var(--border-width) * 3);
328 border-radius: var(--radius);
329 padding: var(--space-lg);
330 color: var(--color-danger);
331}
332
333.error-display__message {
334 font-weight: var(--font-weight-bold);
335 font-size: var(--font-size-lg);
336 margin-bottom: var(--space-xs);
337}
338
339.error-display__detail {
340 color: var(--color-text-muted);
341 font-size: var(--font-size-sm);
342}
343
344/* ─── Empty State ───────────────────────────────────────────────────────── */
345
346.empty-state {
347 text-align: center;
348 padding: var(--space-xl) var(--space-md);
349 color: var(--color-text-muted);
350 border: var(--border-width) dashed var(--color-border);
351 margin: var(--space-md) 0;
352}
353
354.empty-state p {
355 font-size: var(--font-size-lg);
356 margin-bottom: var(--space-sm);
357}
358
359.empty-state__action {
360 margin-top: var(--space-md);
361}
362
363/* ─── Loading State (HTMX indicator) ───────────────────────────────────── */
364
365.loading-state {
366 opacity: 0;
367 transition: opacity 0.2s ease;
368 text-align: center;
369 padding: var(--space-md);
370 color: var(--color-text-muted);
371}
372
373.loading-state.htmx-request {
374 opacity: 1;
375}
376
377.htmx-indicator {
378 opacity: 0;
379 transition: opacity 0.2s ease;
380}
381
382.htmx-request .htmx-indicator,
383.htmx-request.htmx-indicator {
384 opacity: 1;
385}
386
387/* ─── Error Page ────────────────────────────────────────────────────────── */
388
389.error-page {
390 text-align: center;
391 padding: var(--space-xl) var(--space-md);
392}
393
394.error-page__code {
395 font-family: var(--font-heading);
396 font-size: 6rem;
397 font-weight: var(--font-weight-bold);
398 line-height: 1;
399 color: var(--color-primary);
400 margin-bottom: var(--space-sm);
401}
402
403.error-page__title {
404 font-size: var(--font-size-xl);
405 margin-bottom: var(--space-sm);
406}
407
408.error-page__message {
409 color: var(--color-text-muted);
410 font-size: var(--font-size-base);
411 margin-bottom: var(--space-lg);
412}
413
414/* ─── Homepage ──────────────────────────────────────────────────────────── */
415
416.category-section {
417 margin-bottom: var(--space-xl);
418}
419
420.category-header {
421 margin: 0 0 var(--space-md) 0;
422 font-size: var(--font-size-lg);
423 padding-bottom: var(--space-sm);
424 border-bottom: var(--border-width) solid var(--color-border);
425}
426
427.board-grid {
428 display: flex;
429 flex-direction: column;
430 gap: var(--space-md);
431}
432
433.board-card {
434 display: block;
435 text-decoration: none;
436 color: inherit;
437}
438
439.board-card:hover .card {
440 transform: translate(-2px, -2px);
441 box-shadow: calc(var(--shadow-offset) + 2px) calc(var(--shadow-offset) + 2px) 0 var(--color-shadow);
442}
443
444.board-card__name {
445 font-weight: var(--font-weight-bold);
446 font-size: var(--font-size-base);
447 margin: 0 0 var(--space-xs) 0;
448}
449
450.board-card__description {
451 margin: 0;
452 color: var(--color-text-muted);
453 font-size: var(--font-size-sm);
454}
455
456/* ─── Forms ─────────────────────────────────────────────────────────────── */
457
458.form-group {
459 display: flex;
460 flex-direction: column;
461 gap: var(--space-xs);
462 margin-bottom: var(--space-md);
463}
464
465.form-group label {
466 font-weight: var(--font-weight-bold);
467 font-size: var(--font-size-sm);
468}
469
470.form-group input,
471.form-group textarea,
472.form-group select {
473 border: var(--input-border);
474 border-radius: var(--input-radius);
475 padding: var(--space-sm) var(--space-md);
476 font-family: var(--font-body);
477 font-size: var(--font-size-base);
478 background-color: var(--color-surface);
479 color: var(--color-text);
480 min-height: 44px;
481}
482
483.form-group textarea {
484 min-height: 120px;
485 resize: vertical;
486}
487
488.form-actions {
489 display: flex;
490 flex-direction: row;
491 gap: var(--space-sm);
492 margin-top: var(--space-md);
493}
494
495.form-error {
496 color: var(--color-danger);
497 font-size: var(--font-size-sm);
498 font-weight: var(--font-weight-bold);
499 margin: var(--space-xs) 0;
500}
501
502.char-count {
503 font-size: var(--font-size-sm);
504 color: var(--color-text-muted);
505}
506
507.char-count[data-over="true"] {
508 color: var(--color-danger);
509 font-weight: var(--font-weight-bold);
510}
511
512.success-banner {
513 background-color: var(--color-success);
514 color: var(--color-surface);
515 padding: var(--space-sm) var(--space-md);
516 margin-bottom: var(--space-md);
517 font-weight: var(--font-weight-bold);
518 border: var(--border-width) solid var(--color-border);
519}
520
521/* ─── Login Form ────────────────────────────────────────────────────────── */
522
523.login-form {
524 max-width: 480px;
525}
526
527.login-form__form {
528 display: flex;
529 flex-direction: column;
530 gap: var(--space-md);
531}
532
533.login-form__label {
534 font-weight: var(--font-weight-bold);
535}
536
537.login-form__input {
538 border: var(--input-border);
539 border-radius: var(--input-radius);
540 padding: var(--space-sm) var(--space-md);
541 font-family: var(--font-body);
542 font-size: var(--font-size-base);
543 background-color: var(--color-surface);
544 color: var(--color-text);
545 min-height: 44px;
546 width: 100%;
547 box-sizing: border-box;
548}
549
550.login-form__hint {
551 color: var(--color-text-muted);
552 font-size: var(--font-size-sm);
553}
554
555.login-form__error {
556 border: var(--border-width) solid var(--color-danger);
557 padding: var(--space-sm) var(--space-md);
558 color: var(--color-danger);
559 font-weight: var(--font-weight-bold);
560}
561
562.login-form__submit {
563 cursor: pointer;
564 display: inline-flex;
565 align-items: center;
566 justify-content: center;
567 gap: var(--space-sm);
568 font-family: var(--font-body);
569 font-weight: var(--font-weight-bold);
570 font-size: var(--font-size-base);
571 line-height: 1;
572 border: var(--border-width) solid var(--color-border);
573 border-radius: var(--button-radius);
574 padding: var(--space-sm) var(--space-md);
575 box-shadow: var(--button-shadow);
576 background-color: var(--color-primary);
577 color: var(--color-surface);
578 text-decoration: none;
579 transition: transform 0.1s ease, box-shadow 0.1s ease;
580 user-select: none;
581}
582
583.login-form__submit:hover {
584 transform: translate(var(--btn-press-hover), var(--btn-press-hover));
585 box-shadow: var(--btn-press-hover) var(--btn-press-hover) 0 var(--color-shadow);
586}
587
588.login-form__submit:active {
589 transform: translate(var(--btn-press-active), var(--btn-press-active));
590 box-shadow: none;
591}
592
593/* ─── Post Cards ────────────────────────────────────────────────────────── */
594
595.post-card {
596 background-color: var(--color-surface);
597 border: var(--border-width) solid var(--color-border);
598 border-left-width: calc(var(--border-width) * 2);
599 border-left-color: var(--color-primary);
600 padding: var(--space-md);
601 margin-bottom: var(--space-md);
602 transition: transform 0.15s ease, box-shadow 0.15s ease;
603}
604
605.post-card--op {
606 border-left-width: calc(var(--border-width) * 3);
607 box-shadow: var(--card-shadow);
608}
609
610.post-card--reply {
611 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--color-shadow);
612}
613
614.post-card__header {
615 display: flex;
616 flex-direction: row;
617 align-items: center;
618 gap: var(--space-sm);
619 margin-bottom: var(--space-sm);
620 flex-wrap: wrap;
621}
622
623.post-card__number {
624 font-weight: var(--font-weight-bold);
625 background-color: var(--color-primary);
626 color: var(--color-surface);
627 padding: var(--space-xs) var(--space-sm);
628 min-width: 2em;
629 text-align: center;
630}
631
632.post-card__author {
633 font-weight: var(--font-weight-bold);
634 font-size: var(--font-size-sm);
635}
636
637.post-card__date {
638 color: var(--color-text-muted);
639 font-size: var(--font-size-sm);
640 margin-left: auto;
641}
642
643.post-card__body {
644 white-space: pre-wrap;
645 word-break: break-word;
646 line-height: var(--line-height-body);
647}
648
649/* ─── Breadcrumb ────────────────────────────────────────────────────────── */
650
651.breadcrumb {
652 font-size: var(--font-size-sm);
653 color: var(--color-text-muted);
654 margin-bottom: var(--space-md);
655}
656
657.breadcrumb a {
658 color: var(--color-text-muted);
659 text-decoration: none;
660}
661
662.breadcrumb a:hover {
663 color: var(--color-primary);
664}
665
666.breadcrumb ol {
667 display: flex;
668 flex-wrap: wrap;
669 gap: 0;
670 list-style: none;
671 padding: 0;
672 margin: 0;
673}
674
675.breadcrumb li {
676 display: flex;
677 align-items: center;
678}
679
680.breadcrumb li + li::before {
681 content: "/";
682 margin: 0 var(--space-sm);
683 color: var(--color-text-muted);
684}
685
686/* ─── Topic Rows ────────────────────────────────────────────────────────── */
687
688.topic-row {
689 display: flex;
690 flex-direction: row;
691 justify-content: space-between;
692 align-items: baseline;
693 gap: var(--space-md);
694 padding: var(--space-md);
695 border: var(--border-width) solid var(--color-border);
696 background-color: var(--color-surface);
697 margin-bottom: var(--space-sm);
698 transition: transform 0.15s ease, box-shadow 0.15s ease;
699}
700
701.topic-row:hover {
702 transform: translate(-1px, -1px);
703 box-shadow: 3px 3px 0 var(--color-shadow);
704}
705
706.topic-row__title {
707 font-weight: var(--font-weight-bold);
708 color: var(--color-text);
709 text-decoration: none;
710 flex: 1;
711 overflow: hidden;
712 text-overflow: ellipsis;
713 white-space: nowrap;
714}
715
716.topic-row__title:hover {
717 color: var(--color-primary);
718}
719
720.topic-row__meta {
721 display: flex;
722 gap: var(--space-sm);
723 color: var(--color-text-muted);
724 font-size: var(--font-size-sm);
725 white-space: nowrap;
726}
727
728/* ─── Topic Locked Banner ───────────────────────────────────────────────── */
729
730.topic-locked-banner {
731 background-color: var(--color-warning);
732 color: var(--color-text);
733 padding: var(--space-sm) var(--space-md);
734 margin-bottom: var(--space-md);
735 font-weight: var(--font-weight-bold);
736 border: var(--border-width) solid var(--color-border);
737 display: flex;
738 align-items: center;
739 gap: var(--space-sm);
740}
741
742.topic-locked-banner__badge {
743 background-color: var(--color-text);
744 color: var(--color-warning);
745 padding: var(--space-xs) var(--space-sm);
746 font-size: var(--font-size-sm);
747 text-transform: uppercase;
748 letter-spacing: 0.05em;
749}
750
751/* ─── Moderation UI ──────────────────────────────────────────────────────── */
752
753.post-card__mod-actions {
754 display: flex;
755 gap: var(--space-2);
756 margin-top: var(--space-2);
757 padding-top: var(--space-2);
758 border-top: 1px solid var(--color-border);
759}
760
761.mod-btn {
762 font-size: 0.75rem;
763 padding: 0.25rem 0.6rem;
764 border: 2px solid currentColor;
765 border-radius: 0;
766 cursor: pointer;
767 background: transparent;
768 font-family: inherit;
769 font-weight: 700;
770 text-transform: uppercase;
771 letter-spacing: 0.05em;
772}
773
774.mod-btn--hide,
775.mod-btn--lock {
776 color: var(--color-danger, #d00);
777}
778
779.mod-btn--hide:hover,
780.mod-btn--lock:hover {
781 background: var(--color-danger, #d00);
782 color: #fff;
783}
784
785.mod-btn--unhide,
786.mod-btn--unlock,
787.mod-btn--ban {
788 color: var(--color-text-muted, #666);
789}
790
791.mod-btn--unhide:hover,
792.mod-btn--unlock:hover,
793.mod-btn--ban:hover {
794 background: var(--color-text-muted, #666);
795 color: #fff;
796}
797
798.topic-mod-controls {
799 margin-bottom: var(--space-4);
800}
801
802.mod-dialog {
803 border: 3px solid var(--color-border);
804 border-radius: 0;
805 padding: var(--space-6);
806 max-width: 480px;
807 width: 90vw;
808 box-shadow: 6px 6px 0 var(--color-shadow);
809 background: var(--color-bg);
810}
811
812.mod-dialog::backdrop {
813 background: rgba(0, 0, 0, 0.5);
814}
815
816.mod-dialog__title {
817 margin-top: 0;
818 margin-bottom: var(--space-4);
819 font-size: 1.25rem;
820}
821
822/* ═══════════════════════════════════════════════════════════════════════════
823 RESPONSIVE BREAKPOINTS (mobile-first)
824 Base = mobile (0-767px), tablet = 768px+, desktop = 1024px+
825 ═══════════════════════════════════════════════════════════════════════════ */
826
827/* ─── Tablet (768px+) ──────────────────────────────────────────────────── */
828
829@media (min-width: 768px) {
830 :root {
831 --content-width: 720px;
832 }
833
834 .topic-row {
835 flex-direction: row;
836 align-items: baseline;
837 }
838
839 .topic-row__title {
840 white-space: nowrap;
841 overflow: hidden;
842 text-overflow: ellipsis;
843 }
844
845 .mobile-nav {
846 display: none;
847 }
848
849 .desktop-nav {
850 display: flex;
851 }
852}
853
854/* ─── Desktop (1024px+) ───────────────────────────────────────────────── */
855
856@media (min-width: 1024px) {
857 :root {
858 --content-width: 960px;
859 --border-width: 3px;
860 --shadow-offset: 4px;
861 --button-shadow: 4px 4px 0 var(--color-shadow);
862 --card-shadow: 6px 6px 0 var(--color-shadow);
863 --btn-press-hover: 2px;
864 --btn-press-active: 4px;
865 --input-border: 3px solid var(--color-border);
866 }
867
868}
869
870/* ─── Mobile-specific overrides ────────────────────────────────────────── */
871
872@media (max-width: 767px) {
873 .page-header {
874 flex-direction: column;
875 align-items: flex-start;
876 }
877
878 .topic-row {
879 flex-direction: column;
880 gap: var(--space-xs);
881 }
882
883 .topic-row__title {
884 white-space: normal;
885 }
886
887 .topic-row__meta {
888 flex-wrap: wrap;
889 }
890
891 .post-card__header {
892 flex-direction: column;
893 align-items: flex-start;
894 gap: var(--space-xs);
895 }
896
897 .post-card__date {
898 margin-left: 0;
899 }
900
901 .login-form {
902 max-width: 100%;
903 }
904
905 .desktop-nav {
906 display: none;
907 }
908
909 .mobile-nav {
910 display: block;
911 }
912}
913
914/* ─── Admin Panel ───────────────────────────────────────────────────────── */
915
916.admin-nav-grid {
917 display: grid;
918 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
919 gap: var(--space-md);
920 margin-top: var(--space-lg);
921}
922
923.admin-nav-card {
924 text-decoration: none;
925 color: inherit;
926 display: block;
927}
928
929.admin-nav-card:hover .card {
930 border-color: var(--color-primary);
931}
932
933.admin-nav-card__icon {
934 font-size: var(--font-size-xl, 2rem);
935 margin-bottom: var(--space-sm);
936}
937
938.admin-nav-card__title {
939 font-family: var(--font-heading);
940 font-weight: var(--font-weight-bold);
941 font-size: var(--font-size-lg);
942 margin-bottom: var(--space-xs);
943}
944
945.admin-nav-card__description {
946 color: var(--color-text-muted);
947 font-size: var(--font-size-sm);
948}
949
950/* ─── Admin Member Table ─────────────────────────────────────────────────── */
951
952.admin-member-table {
953 width: 100%;
954 border-collapse: collapse;
955 margin-top: var(--space-md);
956}
957
958.admin-member-table th {
959 text-align: left;
960 padding: var(--space-sm) var(--space-md);
961 border-bottom: calc(var(--border-width) * 2) solid var(--color-border);
962 font-weight: var(--font-weight-bold);
963 font-size: var(--font-size-sm);
964 color: var(--color-text-muted);
965 text-transform: uppercase;
966 letter-spacing: 0.05em;
967}
968
969.admin-member-table td {
970 padding: var(--space-sm) var(--space-md);
971 border-bottom: var(--border-width) solid var(--color-border);
972 vertical-align: middle;
973}
974
975.admin-member-table tbody tr:last-child td {
976 border-bottom: none;
977}
978
979.role-badge {
980 display: inline-block;
981 padding: var(--space-xs) var(--space-sm);
982 border: var(--border-width) solid var(--color-border);
983 font-size: var(--font-size-sm);
984 font-weight: var(--font-weight-bold);
985 background-color: var(--color-surface);
986}
987
988.member-row__assign-form {
989 display: flex;
990 align-items: center;
991 gap: var(--space-sm);
992 flex-wrap: wrap;
993}
994
995.member-row__error {
996 display: block;
997 color: var(--color-danger);
998 font-size: var(--font-size-sm);
999 font-weight: var(--font-weight-bold);
1000 margin-top: var(--space-xs);
1001}