gabriel / musehub public
_layout.scss
1,386 lines 34.6 KB
Raw
sha256:3ff952bf9840772755d63295c58e272a14a808035a2d93b7896ba8e0cf602171 fix(layout): two-column sticky sidebar scroll across all pa… Human minor ⚠ breaking 8 days ago
1 // ── Icon base ─────────────────────────────────────────────────────────────────
2 // Applied by the icon() Jinja2 global to every <svg><use> icon.
3 .icon {
4 display: inline-block;
5 vertical-align: middle;
6 flex-shrink: 0;
7 }
8
9 // Meta row icons (author, timestamp, branch) are intentionally muted.
10 .commit-meta-item .icon { opacity: .6; }
11
12 // Decorative empty-state icons use a lighter stroke weight.
13 .icon--light-stroke { stroke-width: 1.2; }
14
15 /*
16 * MuseHub Layout System
17 *
18 * Global structural layout: page container, header/nav chrome, responsive
19 * breakpoints, and utility spacing helpers.
20 *
21 * Breakpoints (mobile-first):
22 * xs < 480px — compact phones
23 * sm 480-767px — large phones / small tablets (portrait)
24 * md 768-1023px— tablets and small laptops
25 * lg 1024-1279px— laptops
26 * xl >= 1280px — desktops / wide monitors
27 *
28 * Minimum supported width: 375px (iPhone SE / most modern phones).
29 * Maximum design width: 1280px (content column; wider screens add side whitespace).
30 */
31
32 /* -------------------------------------------------------------------------
33 * Base scaling
34 *
35 * FOUC prevention is handled by setting background:#0d1117 directly on the
36 * <html> element as an inline style in base.html — no opacity tricks needed.
37 * -------------------------------------------------------------------------*/
38
39 body {
40 zoom: 1.25;
41 }
42
43 @media (max-width: 768px) {
44 body { zoom: 1; }
45 }
46
47 /* -------------------------------------------------------------------------
48 * Global navigation bar (.musehub-navbar)
49 *
50 * Replaces the plain <header> element with a structured nav bar that includes
51 * logo, search form, site links, and a mobile hamburger toggle.
52 * ------------------------------------------------------------------------- */
53
54 /* Hidden checkbox drives the CSS-only mobile collapse — no JS required. */
55 .navbar-toggle-input {
56 display: none;
57 }
58
59 .musehub-navbar {
60 background: var(--bg-surface);
61 border-bottom: 1px solid var(--border-default);
62 position: sticky;
63 top: 0;
64 z-index: var(--z-raised);
65 height: 42px;
66 }
67
68 .navbar-inner {
69 display: flex;
70 align-items: center;
71 gap: var(--space-3);
72 padding: 0 var(--space-4);
73 height: 100%;
74 width: 100%;
75 }
76
77 .navbar-logo {
78 display: inline-flex;
79 align-items: center;
80 gap: var(--space-2);
81 font-size: var(--text-base);
82 font-weight: var(--weight-semibold);
83 color: var(--text-primary);
84 white-space: nowrap;
85 text-decoration: none;
86 flex-shrink: 0;
87 letter-spacing: -0.01em;
88 }
89
90 .navbar-logo:hover {
91 text-decoration: none;
92 color: var(--text-primary);
93 opacity: 0.85;
94
95 .gradient-text {
96 opacity: 1; /* gradient handles its own visual feedback via parent opacity */
97 }
98 }
99
100 .navbar-logo-icon {
101 color: var(--color-accent);
102 flex-shrink: 0;
103 }
104
105 .navbar-logo-text {
106 font-family: var(--font-mono);
107 font-weight: var(--weight-bold);
108 font-size: 16px;
109 }
110
111 /* Search form */
112 .navbar-search-form {
113 display: flex;
114 align-items: center;
115 gap: var(--space-2);
116 flex: 1;
117 max-width: 400px;
118 background: var(--bg-base);
119 border: 1px solid var(--border-default);
120 border-radius: var(--radius-base);
121 padding: 0 var(--space-3);
122 transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
123
124 /* Override the global input[type="search"] rule which has higher specificity
125 (0-1-1) than .navbar-search-input (0-1-0) and would otherwise show its
126 own border, padding, and width as an inner stroke. */
127 input[type="search"],
128 .navbar-search-input {
129 flex: 1;
130 background: transparent;
131 border: none;
132 border-radius: 0;
133 outline: none;
134 box-shadow: none;
135 padding: 6px 0;
136 font-size: var(--text-sm);
137 font-family: var(--font-sans);
138 color: var(--text-primary);
139 min-width: 0;
140 width: auto;
141 }
142
143 input[type="search"]::placeholder,
144 .navbar-search-input::placeholder {
145 color: var(--text-muted);
146 }
147 }
148
149 .navbar-search-form:focus-within {
150 border-color: var(--color-accent);
151 box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 12%, transparent);
152 }
153
154 .navbar-search-icon {
155 color: var(--text-muted);
156 flex-shrink: 0;
157 }
158
159 /* Action links */
160 .navbar-actions {
161 display: flex;
162 align-items: center;
163 gap: var(--space-2);
164 flex-shrink: 0;
165 margin-left: auto;
166 }
167
168 .navbar-link {
169 font-size: var(--text-sm);
170 color: var(--text-secondary);
171 text-decoration: none;
172 white-space: nowrap;
173 padding: var(--space-1) var(--space-2);
174 border-radius: var(--radius-sm);
175 transition: background var(--transition-fast), color var(--transition-fast);
176 }
177
178 .navbar-link:hover {
179 background: var(--bg-hover);
180 color: var(--text-primary);
181 text-decoration: none;
182 }
183
184 /* Icon-only nav button (bell, etc.) */
185 .navbar-icon-btn {
186 position: relative;
187 display: inline-flex;
188 align-items: center;
189 justify-content: center;
190 width: 32px;
191 height: 32px;
192 padding: 0;
193 border-radius: var(--radius-base);
194 color: var(--text-muted);
195 text-decoration: none;
196 transition: background var(--transition-fast), color var(--transition-fast);
197 }
198
199 .navbar-icon-btn:hover {
200 background: var(--bg-hover);
201 color: var(--text-primary);
202 text-decoration: none;
203 }
204
205 .nav-notif-badge {
206 position: absolute;
207 top: 2px;
208 right: 2px;
209 background: var(--color-danger);
210 color: #fff;
211 border-radius: var(--radius-full);
212 font-size: 9px;
213 font-weight: var(--weight-bold);
214 min-width: 14px;
215 height: 14px;
216 display: none;
217 align-items: center;
218 justify-content: center;
219 padding: 0 3px;
220 line-height: 1;
221 pointer-events: none;
222 }
223
224 .navbar-signout {
225 flex-shrink: 0;
226 }
227
228 /* Theme toggle — swap sun/moon icon based on [data-theme] on <html> */
229 .navbar-theme-btn {
230 border: none;
231 background: none;
232 cursor: pointer;
233 }
234
235 .navbar-theme-icon { display: none; }
236
237 /* Dark mode (default): show sun so user can switch to light */
238 .navbar-theme-icon--sun { display: block; }
239
240 /* Light mode: show moon so user can switch back to dark */
241 [data-theme="light"] .navbar-theme-icon--sun { display: none; }
242 [data-theme="light"] .navbar-theme-icon--moon { display: block; }
243
244 /* Hamburger button (hidden on desktop) */
245 .navbar-hamburger {
246 display: none;
247 flex-direction: column;
248 gap: 5px;
249 background: none;
250 border: none;
251 cursor: pointer;
252 padding: var(--space-2);
253 border-radius: var(--radius-sm);
254 flex-shrink: 0;
255 }
256
257 .navbar-hamburger span {
258 display: block;
259 width: 20px;
260 height: 2px;
261 background: var(--text-secondary);
262 border-radius: 1px;
263 transition: background var(--transition-fast);
264 }
265
266 .navbar-hamburger:hover span {
267 background: var(--text-primary);
268 }
269
270 /* Breadcrumb bar below navbar */
271 .breadcrumb-bar {
272 background: var(--bg-surface);
273 border-bottom: 1px solid var(--border-subtle);
274 padding: 4px var(--space-4);
275 display: flex;
276 align-items: center;
277 gap: var(--space-2);
278 min-height: 0;
279 }
280
281 .breadcrumb-bar:empty,
282 .breadcrumb-bar .breadcrumb:empty + * {
283 display: none;
284 }
285
286 .breadcrumb-bar .breadcrumb {
287 color: var(--text-muted);
288 font-size: var(--text-sm);
289 overflow: hidden;
290 text-overflow: ellipsis;
291 white-space: nowrap;
292 }
293
294 .breadcrumb-bar .breadcrumb a,
295 .breadcrumb-link {
296 color: var(--color-accent);
297 text-decoration: none;
298 }
299
300 .breadcrumb-bar .breadcrumb a:hover,
301 .breadcrumb-link:hover {
302 text-decoration: none;
303 }
304
305 .breadcrumb-sep {
306 color: var(--text-muted);
307 padding: 0 var(--space-1);
308 }
309
310 .breadcrumb-current {
311 color: var(--text-muted);
312 font-size: var(--text-sm);
313 }
314
315 /* breadcrumb_data nav rendered by breadcrumbs.html */
316 .breadcrumb-data-nav {
317 display: inline-flex;
318 align-items: center;
319 flex-wrap: wrap;
320 gap: 0;
321 font-size: var(--text-sm);
322 color: var(--text-muted);
323 }
324
325 /* -------------------------------------------------------------------------
326 * Page header / navigation bar (legacy — kept for embed and non-base pages)
327 * ------------------------------------------------------------------------- */
328 header {
329 background: var(--bg-surface);
330 border-bottom: 1px solid var(--border-default);
331 padding: var(--space-3) var(--space-6);
332 display: flex;
333 align-items: center;
334 gap: var(--space-4);
335 position: sticky;
336 top: 0;
337 z-index: var(--z-raised);
338 }
339
340 header .logo {
341 font-size: var(--text-lg);
342 font-weight: var(--weight-bold);
343 color: var(--text-primary);
344 white-space: nowrap;
345 }
346
347 header .breadcrumb {
348 color: var(--text-muted);
349 font-size: var(--text-base);
350 overflow: hidden;
351 text-overflow: ellipsis;
352 white-space: nowrap;
353 }
354
355 header .breadcrumb a {
356 color: var(--color-accent);
357 }
358
359 header .spacer {
360 flex: 1;
361 }
362
363 header .header-actions {
364 display: flex;
365 align-items: center;
366 gap: var(--space-2);
367 flex-shrink: 0;
368 }
369
370 /* -------------------------------------------------------------------------
371 * Repo header card (shown on all repo-scoped pages)
372 * ------------------------------------------------------------------------- */
373 .repo-header {
374 background: var(--bg-surface);
375 border-bottom: 1px solid var(--border-default);
376 padding: 10px 0;
377 }
378
379 .repo-header-inner {
380 padding: 0 var(--space-4);
381 display: flex;
382 align-items: center;
383 gap: var(--space-3);
384 flex-wrap: wrap;
385 width: 100%;
386 }
387
388 .repo-header-identity {
389 display: flex;
390 align-items: center;
391 gap: var(--space-2);
392 font-size: var(--text-lg);
393 font-weight: var(--weight-semibold);
394 flex-shrink: 0;
395 }
396
397 .repo-header-owner {
398 color: var(--color-accent);
399 }
400
401 .repo-header-sep {
402 color: var(--text-muted);
403 font-weight: var(--weight-normal);
404 }
405
406 .repo-header-name {
407 color: var(--text-primary);
408 }
409
410 .repo-visibility-badge {
411 font-size: var(--text-xs);
412 border: 1px solid var(--border-default);
413 background: transparent;
414 color: var(--text-muted);
415 border-radius: var(--radius-full);
416 padding: 1px var(--space-2);
417 }
418
419 .repo-header-meta {
420 display: flex;
421 align-items: center;
422 gap: var(--space-2);
423 flex-wrap: wrap;
424 flex: 1;
425 }
426
427 .nav-meta-pill {
428 display: inline-flex;
429 align-items: center;
430 gap: var(--space-1);
431 background: var(--bg-overlay);
432 color: var(--text-muted);
433 font-family: var(--font-mono);
434 font-size: var(--text-xs);
435 padding: 2px var(--space-2);
436 border-radius: var(--radius-full);
437 border: 1px solid var(--border-subtle);
438 white-space: nowrap;
439
440 svg { flex-shrink: 0; }
441 }
442
443 .nav-meta-tags {
444 display: flex;
445 gap: var(--space-1);
446 flex-wrap: wrap;
447 }
448
449 .nav-meta-tag,
450 .nav-tag-chip {
451 background: var(--bg-overlay);
452 color: var(--color-accent);
453 font-size: var(--text-xs);
454 padding: 2px var(--space-2);
455 border-radius: var(--radius-full);
456 border: 1px solid var(--border-subtle);
457 }
458
459 .repo-visibility-public { color: var(--color-success, #3fb950); border-color: var(--color-success, #3fb950); }
460 .repo-visibility-private { color: var(--text-muted); }
461 .repo-visibility-unlisted { color: var(--color-warning); border-color: var(--color-warning); }
462
463 .repo-header-actions {
464 display: flex;
465 align-items: center;
466 gap: var(--space-2);
467 flex-shrink: 0;
468 }
469
470 /* -------------------------------------------------------------------------
471 * Repo tab strip (sticky below global header)
472 * ------------------------------------------------------------------------- */
473 :root {
474 --header-height: 42px; /* global header height — matches .musehub-navbar height */
475 --repo-tabs-height: 38px; /* repo tab strip height — sticky below global header */
476 }
477
478 /* Repo tab strip present — account for header + tabs in sticky sidebar offset. */
479 body:has(.repo-tabs) {
480 --sticky-offset: calc(var(--header-height) + var(--repo-tabs-height));
481 }
482
483 .repo-tabs {
484 background: var(--bg-surface);
485 border-bottom: 1px solid var(--border-default);
486 padding: 0;
487 overflow-x: auto;
488 scrollbar-width: none;
489 position: sticky;
490 top: var(--header-height);
491 z-index: calc(var(--z-raised) - 1);
492 /* Right-only fade for overflow scroll indicator; left is flush with content */
493 -webkit-mask-image: linear-gradient(to right, black calc(100% - 32px), transparent 100%);
494 mask-image: linear-gradient(to right, black calc(100% - 32px), transparent 100%);
495 }
496
497 /* Inner wrapper aligns tabs with the page container */
498 .repo-tabs-inner {
499 display: flex;
500 align-items: stretch;
501 padding: 0 var(--space-4);
502 width: 100%;
503 }
504
505 .repo-tabs::-webkit-scrollbar { display: none; }
506
507 .repo-tab {
508 display: inline-flex;
509 align-items: center;
510 gap: var(--space-2);
511 padding: var(--space-2) var(--space-3);
512 font-size: var(--text-sm);
513 color: var(--text-muted);
514 border-bottom: 2px solid transparent;
515 white-space: nowrap;
516 text-decoration: none;
517 transition: color var(--transition-fast), border-color var(--transition-fast);
518 flex-shrink: 0;
519
520 svg {
521 opacity: 0.6;
522 transition: opacity var(--transition-fast);
523 }
524 }
525
526 .repo-tab:hover {
527 color: var(--text-primary);
528 text-decoration: none;
529 background: var(--bg-hover);
530
531 svg { opacity: 1; }
532 }
533
534 .repo-tab.active {
535 color: var(--text-primary);
536 border-bottom-color: var(--color-accent);
537
538 svg { opacity: 1; }
539 }
540
541 .tab-count {
542 background: var(--bg-overlay);
543 color: var(--text-muted);
544 border-radius: var(--radius-full);
545 padding: 0 var(--space-2);
546 font-size: var(--text-xs);
547 font-weight: var(--weight-medium);
548 min-width: 18px;
549 text-align: center;
550 }
551
552 .repo-tab.active .tab-count {
553 background: var(--color-accent);
554 color: white;
555 }
556
557 /* -------------------------------------------------------------------------
558 * Page container
559 * ------------------------------------------------------------------------- */
560 .container {
561 max-width: 960px;
562 margin: var(--space-6) auto;
563 padding: 0 var(--space-6);
564 }
565
566 .container-wide {
567 margin: var(--space-3) 0;
568 padding: 0 var(--space-4);
569 }
570
571 .container-narrow {
572 max-width: 720px;
573 margin: var(--space-6) auto;
574 padding: 0 var(--space-6);
575 }
576
577 /* -------------------------------------------------------------------------
578 * Shared full-bleed page layout (.ph-* = page hero/layout primitives)
579 *
580 * Used by MCP docs, Domain detail, and any future full-page layout.
581 * Pages using this system add:
582 * {% block container_extra_class %} page-container{% endblock %}
583 * to strip the default container padding, then manage their own padding
584 * internally so hero backgrounds can be truly full-bleed.
585 * ------------------------------------------------------------------------- */
586
587 /* Strips container padding so child sections can be full-bleed.
588 .container-wide.page-container wins over .container-wide by specificity. */
589 .container-wide.page-container,
590 .page-container {
591 padding: 0;
592 margin-top: 0;
593 }
594
595 /* ── Hero ─────────────────────────────────────────────────────────────────── */
596 .ph-hero {
597 position: relative;
598 border-bottom: 1px solid var(--border-subtle);
599 overflow: hidden;
600 padding: 0 var(--space-4);
601 }
602
603 .ph-hero-inner {
604 display: flex;
605 align-items: flex-start;
606 justify-content: space-between;
607 gap: var(--space-6);
608 padding: var(--space-6) 0 var(--space-4);
609
610 @media (max-width: 768px) { flex-direction: column; }
611 }
612
613 .ph-hero-eyebrow {
614 display: flex;
615 align-items: center;
616 gap: var(--space-2);
617 margin-bottom: var(--space-3);
618 flex-wrap: wrap;
619 }
620
621 .ph-hero-title {
622 font-size: clamp(24px, 3.5vw, 40px);
623 font-weight: 700;
624 line-height: 1.1;
625 letter-spacing: -0.02em;
626 margin: 0 0 var(--space-2);
627 color: var(--text-primary);
628 }
629
630 .ph-hero-sub {
631 font-size: 14px;
632 line-height: 1.6;
633 color: var(--text-secondary);
634 max-width: 520px;
635 margin-bottom: var(--space-3);
636 }
637
638 .ph-hero-actions {
639 display: flex;
640 gap: var(--space-2);
641 flex-wrap: wrap;
642 align-items: center;
643 }
644
645 /* ── Stats strip — flat separator bar ────────────────────────────────────── */
646 .ph-stats-strip {
647 display: flex;
648 background: transparent;
649 border-top: 1px solid var(--border-subtle);
650 border-bottom: 1px solid var(--border-subtle);
651 overflow-x: auto;
652 scrollbar-width: none;
653 &::-webkit-scrollbar { display: none; }
654 }
655
656 .ph-stat {
657 flex: 1;
658 min-width: 70px;
659 display: flex;
660 flex-direction: column;
661 align-items: center;
662 justify-content: center;
663 padding: 10px 12px;
664 gap: 2px;
665 text-align: center;
666 border-right: 1px solid var(--border-subtle);
667 &:last-child { border-right: none; }
668 }
669
670 .ph-stat-value {
671 font-size: 15px;
672 font-weight: 700;
673 color: var(--text-primary);
674 line-height: 1;
675 font-family: var(--font-mono);
676 }
677
678 .ph-stat-label {
679 font-size: 9px;
680 color: var(--text-muted);
681 text-transform: uppercase;
682 letter-spacing: 0.06em;
683 white-space: nowrap;
684 }
685
686 // Color modifiers for ph-stat-value — used by insights page
687 .ins-val--add { color: var(--color-success); }
688 .ins-val--del { color: var(--color-danger); }
689 .ins-val--agent { color: var(--color-purple); }
690
691 /* ── Page body: sidebar + main content ───────────────────────────────────── */
692 .ph-body {
693 display: grid;
694 grid-template-columns: 240px 1fr; // narrow content left | wide sidebar right
695 align-items: start;
696 gap: 0;
697 min-height: 0;
698
699 @media (max-width: 900px) { grid-template-columns: 1fr; }
700 }
701
702 /* ── Sidebar (right column) ───────────────────────────────────────────────── */
703 .ph-sidebar {
704 padding: var(--space-4) var(--space-4) var(--space-4) var(--space-3);
705 border-left: 1px solid var(--border-subtle);
706 min-width: 0;
707 position: sticky;
708 top: var(--sticky-offset, var(--header-height));
709 max-height: calc(100dvh - var(--sticky-offset, var(--header-height)) - var(--space-4));
710 overflow-y: auto;
711 scrollbar-width: thin;
712 scrollbar-color: var(--border-default) transparent;
713
714 @media (max-width: 900px) {
715 position: static;
716 max-height: none;
717 overflow-y: visible;
718 display: none;
719 }
720 }
721
722 .ph-sidebar-section {
723 padding: var(--space-4) 0;
724 border-bottom: 1px solid var(--border-subtle);
725 &:last-child { border-bottom: none; }
726 }
727
728 .ph-sidebar-heading {
729 display: flex; align-items: center; gap: 6px;
730 font-size: 10px;
731 font-weight: 700;
732 letter-spacing: 0.08em;
733 text-transform: uppercase;
734 color: var(--text-muted);
735 margin: 0 0 var(--space-2);
736 }
737
738 .ph-sidebar-link {
739 display: flex;
740 align-items: center;
741 gap: 6px;
742 padding: 3px var(--space-2);
743 border-radius: 3px;
744 font-size: 12px;
745 color: var(--text-secondary);
746 text-decoration: none;
747 transition: color 0.1s, background 0.1s;
748
749 &:hover { color: var(--text-primary); background: var(--bg-hover); text-decoration: none; }
750 &.is-active { color: var(--color-accent); }
751 }
752
753 /* ── Main content area ────────────────────────────────────────────────────── */
754 .ph-content {
755 padding: 0 var(--space-4);
756 min-width: 0;
757 }
758
759 /* ── Section: divider-based, no card box ─────────────────────────────────── */
760 .ph-section {
761 padding: var(--space-4) 0;
762 border-bottom: 1px solid var(--border-subtle);
763
764 &:last-child { border-bottom: none; }
765 }
766
767 .ph-section-title {
768 font-size: 13px;
769 font-weight: 700;
770 color: var(--text-primary);
771 margin: 0 0 var(--space-2);
772 display: flex;
773 align-items: center;
774 gap: var(--space-2);
775 }
776
777 .ph-section-desc {
778 font-size: 13px;
779 color: var(--text-muted);
780 margin: 0 0 var(--space-3);
781 line-height: 1.55;
782 }
783
784 /* ── Count badge (section title inline pill) ─────────────────────────────── */
785 .ph-count {
786 font-size: 11px;
787 font-weight: 600;
788 font-family: var(--font-mono);
789 padding: 1px 6px;
790 border-radius: var(--radius-full);
791 background: var(--bg-overlay);
792 color: var(--text-muted);
793 border: 1px solid var(--border-subtle);
794 }
795
796 /* -------------------------------------------------------------------------
797 * Two-column layout utilities (canonical — musehub#84)
798 * .layout-two-col — grid wrapper; min-height: 0 lets children scroll
799 * .layout-sidebar — sticky scrolling sidebar column
800 * Modifiers preserve legacy left/right column widths.
801 * ------------------------------------------------------------------------- */
802 .layout-two-col {
803 display: grid;
804 align-items: start;
805 min-height: 0;
806 gap: var(--space-6);
807
808 @media (max-width: 900px) { grid-template-columns: 1fr !important; }
809 }
810
811 .layout-two-col--left { grid-template-columns: 240px 1fr; }
812 .layout-two-col--right { grid-template-columns: 1fr 240px; }
813
814 .layout-sidebar {
815 position: sticky;
816 top: var(--sticky-offset, var(--header-height));
817 max-height: calc(100dvh - var(--sticky-offset, var(--header-height)) - var(--space-4));
818 overflow-y: auto;
819 scrollbar-width: thin;
820 scrollbar-color: var(--border-default) transparent;
821 min-width: 0;
822
823 @media (max-width: 900px) {
824 position: static;
825 max-height: none;
826 overflow-y: visible;
827 }
828 }
829
830 /* Legacy aliases — grid presets (prefer .layout-two-col modifiers in new markup). */
831 .layout-sidebar-left {
832 display: grid;
833 grid-template-columns: 240px 1fr;
834 align-items: start;
835 min-height: 0;
836 gap: var(--space-6);
837 }
838
839 .layout-sidebar-right {
840 display: grid;
841 grid-template-columns: 1fr 240px;
842 align-items: start;
843 min-height: 0;
844 gap: var(--space-6);
845 }
846
847 /* -------------------------------------------------------------------------
848 * Section divider
849 * ------------------------------------------------------------------------- */
850 .section-title {
851 font-family: var(--font-mono);
852 font-size: var(--text-xs);
853 font-weight: var(--weight-semibold);
854 color: var(--color-accent);
855 text-transform: uppercase;
856 letter-spacing: 1.5px;
857 margin-bottom: var(--space-3);
858 padding-bottom: var(--space-2);
859 border-bottom: 1px solid var(--border-subtle);
860 }
861
862 /* -------------------------------------------------------------------------
863 * Flex utilities
864 * ------------------------------------------------------------------------- */
865 .flex { display: flex; }
866 .flex-col { display: flex; flex-direction: column; }
867 .items-center { align-items: center; }
868 .items-start { align-items: flex-start; }
869 .justify-between { justify-content: space-between; }
870 .gap-1 { gap: var(--space-1); }
871 .gap-2 { gap: var(--space-2); }
872 .gap-3 { gap: var(--space-3); }
873 .gap-4 { gap: var(--space-4); }
874 .flex-1 { flex: 1; }
875 .flex-wrap { flex-wrap: wrap; }
876 .flex-shrink-0 { flex-shrink: 0; }
877
878 /* -------------------------------------------------------------------------
879 * Spacing utilities
880 * ------------------------------------------------------------------------- */
881 .mb-2 { margin-bottom: var(--space-2); }
882 .mb-3 { margin-bottom: var(--space-3); }
883 .mb-4 { margin-bottom: var(--space-4); }
884 .mb-6 { margin-bottom: var(--space-6); }
885 .mt-2 { margin-top: var(--space-2); }
886 .mt-3 { margin-top: var(--space-3); }
887 .mt-4 { margin-top: var(--space-4); }
888
889 /* -------------------------------------------------------------------------
890 * Text utilities
891 * ------------------------------------------------------------------------- */
892 .text-muted { color: var(--text-muted); }
893 .text-primary { color: var(--text-primary); }
894 .text-accent { color: var(--color-accent); }
895 .text-danger { color: var(--color-danger); }
896 .text-success { color: var(--color-success); }
897 .text-sm { font-size: var(--text-sm); }
898 .text-xs { font-size: var(--text-xs); }
899 .text-mono { font-family: var(--font-mono); }
900 .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
901
902 /* -------------------------------------------------------------------------
903 * Repo landing page — two-column layout (GitHub-style)
904 * Main content (~68%) + sidebar (~30%), collapses to single column on mobile.
905 * ------------------------------------------------------------------------- */
906 .repo-layout {
907 display: grid;
908 grid-template-columns: minmax(0, 1fr) 296px;
909 gap: var(--space-6);
910 align-items: start;
911 margin-top: var(--space-6);
912 }
913
914 .repo-main { min-width: 0; }
915 .repo-sidebar { min-width: 0; }
916
917 @media (max-width: 1023px) {
918 .repo-layout {
919 grid-template-columns: 1fr;
920 }
921 /* On mobile, sidebar collapses above main (like GitHub mobile) */
922 .repo-sidebar { order: -1; }
923 }
924
925 /* Latest commit banner — sits flush above the commit card */
926 .latest-commit-banner {
927 background: var(--bg-overlay);
928 border: 1px solid var(--border-default);
929 border-radius: var(--radius-base) var(--radius-base) 0 0;
930 border-bottom: none;
931 padding: var(--space-3) var(--space-4);
932 display: flex;
933 align-items: center;
934 gap: var(--space-2);
935 font-size: var(--text-sm);
936 color: var(--text-secondary);
937 }
938
939 /* Small inline avatar (author initials) in commit rows and banner */
940 .commit-avatar {
941 width: 20px;
942 height: 20px;
943 border-radius: var(--radius-full);
944 display: inline-flex;
945 align-items: center;
946 justify-content: center;
947 font-size: 9px;
948 font-weight: var(--weight-bold);
949 color: #fff;
950 flex-shrink: 0;
951 vertical-align: middle;
952 }
953
954 /* ── Sidebar ── */
955
956 /* Star / Watch / Fork action strip */
957 .repo-action-strip {
958 display: flex;
959 gap: var(--space-2);
960 margin-bottom: var(--space-5);
961 }
962
963 .repo-action-btn {
964 display: flex;
965 align-items: center;
966 justify-content: center;
967 gap: 4px;
968 padding: 5px var(--space-3);
969 font-size: var(--text-sm);
970 border: 1px solid var(--border-default);
971 border-radius: var(--radius-base);
972 background: var(--bg-overlay);
973 color: var(--text-secondary);
974 cursor: pointer;
975 text-decoration: none;
976 flex: 1;
977 line-height: 1.4;
978 transition: background var(--transition-fast), color var(--transition-fast);
979 }
980
981 .repo-action-btn:hover {
982 background: var(--bg-hover);
983 color: var(--text-primary);
984 text-decoration: none;
985 }
986
987 .repo-action-btn.active {
988 background: var(--color-accent-muted);
989 border-color: var(--color-accent);
990 color: var(--text-primary);
991 }
992
993 .repo-action-count {
994 font-weight: var(--weight-semibold);
995 color: var(--text-primary);
996 font-size: var(--text-xs);
997 }
998
999 /* Sidebar sections — each separated by a subtle rule */
1000 .sidebar-section {
1001 padding-bottom: var(--space-5);
1002 margin-bottom: var(--space-5);
1003 border-bottom: 1px solid var(--border-subtle);
1004 }
1005
1006 .sidebar-section:last-child {
1007 border-bottom: none;
1008 margin-bottom: 0;
1009 padding-bottom: 0;
1010 }
1011
1012 .sidebar-section h3 {
1013 font-size: var(--text-sm);
1014 font-weight: var(--weight-semibold);
1015 color: var(--text-primary);
1016 margin-bottom: var(--space-3);
1017 display: flex;
1018 align-items: center;
1019 gap: var(--space-2);
1020 }
1021
1022 /* About section prose */
1023 .about-description {
1024 font-size: var(--text-sm);
1025 color: var(--text-secondary);
1026 line-height: 1.6;
1027 margin-bottom: var(--space-3);
1028 }
1029
1030 .about-stat-row {
1031 display: flex;
1032 align-items: center;
1033 gap: var(--space-2);
1034 font-size: var(--text-sm);
1035 color: var(--text-secondary);
1036 padding: 3px 0;
1037 }
1038
1039 .about-stat-row strong {
1040 color: var(--text-primary);
1041 font-weight: var(--weight-semibold);
1042 }
1043
1044 /* Contributor avatar grid */
1045 .contributor-grid {
1046 display: flex;
1047 flex-wrap: wrap;
1048 gap: var(--space-1);
1049 margin-bottom: var(--space-2);
1050 }
1051
1052 .contributor-avatar {
1053 width: 32px;
1054 height: 32px;
1055 border-radius: var(--radius-full);
1056 background: var(--bg-overlay);
1057 border: 2px solid var(--border-default);
1058 display: inline-flex;
1059 align-items: center;
1060 justify-content: center;
1061 font-size: 11px;
1062 font-weight: var(--weight-bold);
1063 color: #fff;
1064 text-decoration: none;
1065 cursor: pointer;
1066 transition: border-color var(--transition-fast), transform var(--transition-fast);
1067 position: relative;
1068 flex-shrink: 0;
1069 }
1070
1071 .contributor-avatar:hover {
1072 border-color: var(--color-accent);
1073 transform: scale(1.15);
1074 text-decoration: none;
1075 z-index: 1;
1076 }
1077
1078 /* Instrument / track breakdown bar (like GitHub's language bar) */
1079 .instrument-bar {
1080 height: 8px;
1081 border-radius: var(--radius-full);
1082 overflow: hidden;
1083 display: flex;
1084 gap: 2px;
1085 margin-bottom: var(--space-3);
1086 }
1087
1088 .instrument-segment {
1089 height: 100%;
1090 transition: opacity var(--transition-fast);
1091 }
1092
1093 .instrument-segment:hover { opacity: 0.7; }
1094
1095 .instrument-legend {
1096 display: flex;
1097 flex-wrap: wrap;
1098 gap: var(--space-1) var(--space-4);
1099 }
1100
1101 .instrument-legend-item {
1102 display: flex;
1103 align-items: center;
1104 gap: var(--space-1);
1105 font-size: var(--text-xs);
1106 color: var(--text-secondary);
1107 }
1108
1109 .instrument-dot {
1110 width: 10px;
1111 height: 10px;
1112 border-radius: 50%;
1113 flex-shrink: 0;
1114 }
1115
1116 /* -------------------------------------------------------------------------
1117 * Responsive breakpoints — mobile-first overrides
1118 * ------------------------------------------------------------------------- */
1119
1120 /* xs — phones < 480px */
1121 @media (max-width: 479px) {
1122 header {
1123 padding: var(--space-2) var(--space-3);
1124 gap: var(--space-2);
1125 }
1126
1127 header .breadcrumb {
1128 display: none;
1129 }
1130
1131 /* Mobile navbar: hamburger visible, search and actions collapse */
1132 .navbar-hamburger {
1133 display: flex;
1134 }
1135
1136 .navbar-search-form {
1137 display: none;
1138 max-width: 100%;
1139 }
1140
1141 .navbar-actions {
1142 display: none;
1143 position: absolute;
1144 top: 100%;
1145 left: 0;
1146 right: 0;
1147 background: var(--bg-surface);
1148 border-bottom: 1px solid var(--border-default);
1149 flex-direction: column;
1150 align-items: flex-start;
1151 padding: var(--space-3) var(--space-4);
1152 gap: var(--space-2);
1153 z-index: calc(var(--z-raised) + 1);
1154 }
1155
1156 /* Show when hamburger checkbox is checked */
1157 .navbar-toggle-input:checked ~ * .navbar-search-form,
1158 .navbar-toggle-input:checked + .navbar-inner .navbar-search-form {
1159 display: flex;
1160 }
1161
1162 .navbar-toggle-input:checked ~ .navbar-inner .navbar-actions {
1163 display: flex;
1164 }
1165
1166 .musehub-navbar {
1167 position: relative;
1168 }
1169
1170 .container,
1171 .container-wide,
1172 .container-narrow {
1173 padding: 0 var(--space-3);
1174 margin-top: var(--space-4);
1175 }
1176
1177 .layout-two-col,
1178 .layout-two-col--left,
1179 .layout-two-col--right,
1180 .layout-sidebar-left,
1181 .layout-sidebar-right {
1182 grid-template-columns: 1fr;
1183 }
1184
1185 .grid-2,
1186 .grid-3 {
1187 grid-template-columns: 1fr;
1188 }
1189
1190 h1 { font-size: var(--text-md); }
1191 h2 { font-size: var(--text-base); }
1192 }
1193
1194 /* sm — large phones 480-767px */
1195 @media (min-width: 480px) and (max-width: 767px) {
1196 header {
1197 padding: var(--space-2) var(--space-4);
1198 }
1199
1200 .container,
1201 .container-wide,
1202 .container-narrow {
1203 padding: 0 var(--space-4);
1204 }
1205
1206 .layout-two-col,
1207 .layout-two-col--left,
1208 .layout-two-col--right,
1209 .layout-sidebar-left,
1210 .layout-sidebar-right {
1211 grid-template-columns: 1fr;
1212 }
1213
1214 .grid-3 {
1215 grid-template-columns: 1fr 1fr;
1216 }
1217 }
1218
1219 /* md — tablets 768-1023px */
1220 @media (min-width: 768px) and (max-width: 1023px) {
1221 .container {
1222 max-width: 100%;
1223 padding: 0 var(--space-6);
1224 }
1225
1226 .layout-two-col--left,
1227 .layout-sidebar-left {
1228 grid-template-columns: 200px 1fr;
1229 }
1230
1231 .layout-two-col--right,
1232 .layout-sidebar-right {
1233 grid-template-columns: 1fr 200px;
1234 }
1235 }
1236
1237 /* lg — laptops 1024px+ */
1238 @media (min-width: 1024px) {
1239 /* Full layout — no overrides needed; base styles apply */
1240 }
1241
1242 /* xl — desktops 1280px+ */
1243 @media (min-width: 1280px) {
1244 /* No overrides needed — content is full-width at all viewport sizes */
1245 }
1246
1247 /* -------------------------------------------------------------------------
1248 * Print styles (minimal — MuseHub is primarily a screen UI)
1249 * ------------------------------------------------------------------------- */
1250 @media print {
1251 header { display: none; }
1252 .btn { display: none; }
1253 .token-form { display: none; }
1254 pre { white-space: pre-wrap; border: 1px solid var(--border-default); }
1255 }
1256
1257 /* =========================================================================
1258 * Muse protocol design language utilities
1259 * ========================================================================= */
1260
1261 /* -------------------------------------------------------------------------
1262 * Section eyebrow
1263 * Monospace uppercase label placed above section headings, identical in
1264 * style to the section labels used on cgcardona.github.io/muse/.
1265 * Usage: <p class="eyebrow">Protocol</p><h2>…</h2>
1266 * ------------------------------------------------------------------------- */
1267 .eyebrow {
1268 font-family: var(--font-mono);
1269 font-size: 11px;
1270 color: var(--color-accent);
1271 letter-spacing: 2px;
1272 text-transform: uppercase;
1273 margin-bottom: var(--space-2);
1274 font-weight: var(--weight-medium);
1275 }
1276
1277 /* -------------------------------------------------------------------------
1278 * Page sections — full-bleed horizontal bands with border separator,
1279 * mirroring the section rhythm on the Muse protocol site.
1280 * .page-section — default (--bg-base background)
1281 * .page-section-alt — elevated surface (--bg-surface background)
1282 * .page-section-hero — gradient glow overlay for landing/hero areas
1283 * ------------------------------------------------------------------------- */
1284 .page-section {
1285 padding: var(--space-12) var(--space-6);
1286 border-top: 1px solid var(--border-subtle);
1287 }
1288
1289 .page-section-alt {
1290 background: var(--bg-surface);
1291 }
1292
1293 .page-section-hero {
1294 background:
1295 var(--gradient-hero),
1296 linear-gradient(160deg, var(--bg-base) 0%, var(--bg-surface) 50%, var(--bg-base) 100%);
1297 border-bottom: 1px solid var(--border-default);
1298 }
1299
1300 /* Section lead text — descriptive subtitle beneath a section heading */
1301 .section-lead {
1302 font-size: var(--text-md);
1303 color: var(--text-muted);
1304 max-width: 620px;
1305 margin-bottom: var(--space-10);
1306 line-height: 1.7;
1307
1308 strong { color: var(--text-primary); }
1309 }
1310
1311 /* -------------------------------------------------------------------------
1312 * Accent text — solid brand blue for headings and wordmarks.
1313 * ------------------------------------------------------------------------- */
1314 .gradient-text {
1315 color: var(--color-accent);
1316 }
1317
1318 /* -------------------------------------------------------------------------
1319 * Radial glow overlay — decorative background for hero / banner cards.
1320 * Apply to a position:relative container; the pseudo-element renders the
1321 * radial gradients as a non-interactive overlay.
1322 * ------------------------------------------------------------------------- */
1323 .glow-overlay {
1324 position: relative;
1325 overflow: hidden;
1326
1327 &::before {
1328 content: '';
1329 position: absolute;
1330 inset: 0;
1331 background: var(--gradient-hero);
1332 pointer-events: none;
1333 z-index: 0;
1334 }
1335
1336 > * { position: relative; z-index: 1; }
1337 }
1338
1339 /* -------------------------------------------------------------------------
1340 * Site footer
1341 * ------------------------------------------------------------------------- */
1342
1343 .site-footer {
1344 margin-top: var(--space-12);
1345 border-top: 1px solid var(--border-subtle);
1346 background: var(--bg-base);
1347
1348 &__inner {
1349 display: flex;
1350 align-items: center;
1351 gap: var(--space-6);
1352 max-width: 1280px;
1353 margin: 0 auto;
1354 padding: var(--space-4) var(--space-6);
1355 flex-wrap: wrap;
1356 }
1357
1358 &__brand {
1359 font-size: var(--text-sm);
1360 font-weight: 700;
1361 color: var(--text-primary);
1362 letter-spacing: 0.02em;
1363 }
1364
1365 &__copy {
1366 font-size: var(--text-xs);
1367 color: var(--text-muted);
1368 flex: 1;
1369 }
1370
1371 &__legal {
1372 display: flex;
1373 gap: var(--space-4);
1374
1375 a {
1376 font-size: var(--text-xs);
1377 color: var(--text-muted);
1378 text-decoration: none;
1379 transition: color 0.15s ease;
1380
1381 &:hover {
1382 color: var(--color-accent-link);
1383 }
1384 }
1385 }
1386 }
File History 1 commit
sha256:3ff952bf9840772755d63295c58e272a14a808035a2d93b7896ba8e0cf602171 fix(layout): two-column sticky sidebar scroll across all pa… Human minor 8 days ago