// Shell: the sticky top bar, the signed-in sidebar, the page column and the footer. From 900px // the sidebar is always there, and a repo's tabs take it over. Below 900px the sidebar moves // into a menu in the top bar, and the repo tabs become a horizontal strip. // Icons: strokes use currentColor, so they follow the text colour in both themes. .ico { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; } // Top bar .topbar { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 12px; box-sizing: border-box; height: var(--topbar-h); min-width: 0; padding: 0 16px; background: var(--bg); border-bottom: 1px solid var(--border); } .wordmark { display: inline-flex; align-items: center; gap: 8px; flex: none; font-size: 17px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); text-decoration: none; &:hover { text-decoration: none; } } .wordmark-mark { width: 20px; height: 20px; color: var(--accent); } .topbar .crumbs { display: flex; align-items: center; flex: 0 1 auto; min-width: 0; overflow: hidden; font-size: 14px; color: var(--muted); white-space: nowrap; &::before { content: "/"; margin-right: 10px; color: var(--border-strong); } ol { flex-wrap: nowrap; } } .top-search { position: relative; flex: 0 1 340px; min-width: 0; margin: 0 0 0 auto; input { box-sizing: border-box; width: 100%; height: 36px; min-width: 0; margin: 0; padding: 0 12px 0 36px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); font: inherit; font-size: 14px; &::placeholder { color: var(--muted); } &:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); } } } .top-search-icon { position: absolute; top: 10px; left: 11px; width: 16px; height: 16px; color: var(--muted); pointer-events: none; } .topbar .icon-btn { position: relative; display: grid; place-items: center; flex: none; box-sizing: border-box; width: 36px; height: 36px; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text-2); font: inherit; list-style: none; cursor: pointer; &:hover { background: var(--surface-2); text-decoration: none; } &::-webkit-details-marker { display: none; } } .theme-form { display: flex; flex: none; margin: 0; } .topbar .bell { color: var(--text-2); } .topbar .bell-count { position: absolute; top: -6px; right: -6px; min-width: 1.2rem; padding: 0 0.3rem; box-shadow: 0 0 0 2px var(--bg); font-size: 0.6875rem; line-height: 1.2rem; } // The shared button keeps its natural width in columns; in the top bar it sits on the centre line. .topbar .button { align-self: center; flex: none; } .topbar-link { flex: none; color: var(--text-2); font-size: 14.5px; font-weight: 500; text-decoration: none; &:hover { color: var(--text); text-decoration: none; } } // The avatar menu: the avatar is the summary; the menu list keeps its links from main.scss. .topbar .menu { flex: none; summary { display: grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%; } summary img { display: block; width: 28px; height: 28px; } &[open] summary { box-shadow: 0 0 0 2px var(--accent-soft); } } .topbar .menu-list { top: calc(100% + 8px); } // Phone menu: the sidebar in a panel under the top bar. Hidden from 900px. .nav-toggle { flex: none; } .nav-panel { position: absolute; top: 100%; left: 12px; z-index: 30; box-sizing: border-box; width: 280px; max-width: calc(100vw - 24px); max-height: calc(100vh - var(--topbar-h)); padding: 12px; overflow-y: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); } // Sidebar .shell { display: grid; grid-template-columns: minmax(0, 1fr); min-height: calc(100vh - var(--topbar-h)); } .shell-sidebar { display: none; } .side-links { display: flex; flex-direction: column; gap: 2px; } .side-link { display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 12px; border-radius: var(--radius); color: var(--text-2); font-size: 14.5px; font-weight: 500; white-space: nowrap; text-decoration: none; &:hover { background: var(--surface-2); text-decoration: none; } .ico { color: var(--muted); } .count { margin-left: auto; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; } &.on { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; .ico, .count { color: var(--accent-ink); } } } .side-group { margin-top: 24px; } .side-h { margin: 0 12px 8px; font-size: 12.5px; font-weight: 600; line-height: 1.4; color: var(--muted); } .side-empty { margin: 0 12px; font-size: 13px; color: var(--muted); } .side-repos { display: flex; flex-direction: column; gap: 2px; a { display: flex; align-items: center; min-height: 32px; padding: 0 12px; overflow: hidden; border-radius: var(--radius); font-family: var(--mono); font-size: 13.5px; color: var(--text-2); white-space: nowrap; text-decoration: none; &:hover { background: var(--surface-2); text-decoration: none; } } } // Page column and footer .shell > main { box-sizing: border-box; width: 100%; min-width: 0; max-width: 1280px; margin: 0 auto; padding: 24px 16px 48px; } .site-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; box-sizing: border-box; padding: 14px 16px 20px; font-size: 12.5px; color: var(--muted); border-top: 1px solid var(--border); } // Wide screens: the sidebar sits beside the page, and a repo's tabs replace its links. @media (max-width: 699px) { .topbar .crumbs { display: none; } .top-search { flex: 1 1 0; } } // Narrow phones: the search field no longer fits beside the other top bar items, so it becomes an // icon that opens the public repository search on the Explore page (the same search, no JS). .topbar .top-search-link { display: none; } @media (max-width: 639px) { .top-search { display: none; } .topbar .top-search-link { display: grid; margin-left: auto; } } @media (min-width: 700px) { .shell > main { padding: 28px 28px 48px; } .site-footer { padding: 14px 28px 20px; } } @media (min-width: 900px) { .nav-toggle { display: none; } .shell:has(> .shell-sidebar) { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); } .shell-sidebar { position: sticky; top: var(--topbar-h); align-self: start; display: block; box-sizing: border-box; height: calc(100vh - var(--topbar-h)); min-width: 0; padding: 16px 12px 24px; overflow-y: auto; background: var(--surface); border-right: 1px solid var(--border); } // A repo page: its tabs become the sidebar, fixed under the top bar, and the global links go. .shell:has(.repo-tabs) .shell-sidebar .side-links, .shell:has(.repo-tabs) .shell-sidebar .side-group { display: none; } .shell:has(> .shell-sidebar) .repo-tabs { position: fixed; top: var(--topbar-h); bottom: 0; left: 0; z-index: 5; box-sizing: border-box; width: var(--sidebar-w); flex-direction: column; align-items: stretch; gap: 2px; margin: 0; padding: 16px 12px 24px; overflow-x: hidden; overflow-y: auto; background: var(--surface); border-right: 1px solid var(--border); border-bottom: 0; } .shell:has(> .shell-sidebar) .repo-tabs .tab { display: flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 12px; border-radius: var(--radius); box-shadow: none; color: var(--text-2); font-size: 14.5px; font-weight: 500; &:hover { background: var(--surface-2); color: var(--text); } &.active { background: var(--accent-soft); color: var(--accent-ink); font-weight: 600; box-shadow: none; } } .shell:has(> .shell-sidebar) .repo-tabs .tab-count { margin-left: auto; padding: 0; background: none; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; } } // Soft navigation: a thin progress line along the top while a page is being fetched in place // (nav.js sets aria-busy on ). Decorative; the page stays usable underneath. html[aria-busy="true"] body::before { content: ""; position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 1000; background: var(--accent); transform-origin: left center; pointer-events: none; animation: soft-nav-progress 1.1s ease-in-out infinite; } @keyframes soft-nav-progress { 0% { transform: scaleX(0); } 50% { transform: scaleX(0.7); } 100% { transform: scaleX(1); opacity: 0; } } @media (prefers-reduced-motion: reduce) { html[aria-busy="true"] body::before { animation: none; transform: scaleX(1); opacity: 0.45; } }