#blazor-error-ui { color-scheme: light only; background: lightyellow; bottom: 0; box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); box-sizing: border-box; display: none; left: 0; padding: 0.6rem 1.25rem 0.7rem 1.25rem; position: fixed; width: 100%; z-index: 1000; } #blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.5rem; } /* Header: pinned to the top while the page scrolls, so the brand and (on mobile) the hamburger button are always reachable. It is a plain block child of (NOT a flex item) -- a stretched flex child fills its cell and never sticks. z-index keeps it above the content; the opaque background stops content showing through as it scrolls underneath. */ .site-header { border-bottom: 1px solid #e0e0e0; background: #fff; position: sticky; top: 0; z-index: 20; } .header-inner { max-width: 60rem; margin: 0 auto; padding: 1rem 1.25rem; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1.5rem; } .brand { font-size: 1.35rem; font-weight: 700; color: #1f3a5f; text-decoration: none; white-space: nowrap; } .main-nav { display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; } /* The hamburger button, its state checkbox, and the mobile-only home link are hidden on wide screens; the media query below turns them on for narrow ones. (On wide screens the brand is the home link, so a "Start" entry is redundant.) */ .nav-toggle, .nav-toggle-label, .nav-home-mobile { display: none; } .main-nav a { color: #333; text-decoration: none; padding: 0.2rem 0; border-bottom: 2px solid transparent; } .main-nav a:hover { color: #1f3a5f; } /* NavLink adds .active to the link of the current route. */ .main-nav a.active { color: #1f3a5f; border-bottom-color: #1f3a5f; } /* Content: at least tall enough that the footer sits at the bottom of the viewport on short pages. 100dvh - 4rem leaves room for the header (which sits above in normal flow); dvh follows the mobile browser's shrinking toolbar. On long pages the content simply grows past this and pushes the footer down naturally. */ .content { min-height: calc(100dvh - 4rem); box-sizing: border-box; width: 100%; max-width: 60rem; margin: 0 auto; padding: 1.5rem 1.25rem 3rem; } /* Footer */ .site-footer { border-top: 1px solid #e0e0e0; background: #fafafa; color: #555; font-size: 0.9rem; } .footer-inner { max-width: 60rem; margin: 0 auto; padding: 1rem 1.25rem; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem 1.5rem; } .footer-nav { display: flex; gap: 1.25rem; } .footer-nav a { color: #555; text-decoration: none; } .footer-nav a:hover { color: #1f3a5f; text-decoration: underline; } /* Mobile: on narrow screens the nav collapses behind a hamburger button. This is pure CSS -- the #nav-toggle checkbox holds the open/closed state and its :checked state reveals the nav. No JavaScript, so it works under static SSR. */ @media (max-width: 40rem) { /* The brand stays on the left, the hamburger goes to the right, and the nav occupies its own full-width row below both. */ .header-inner { flex-wrap: wrap; align-items: center; justify-content: space-between; } /* Show the hamburger button. */ .nav-toggle-label { display: block; cursor: pointer; padding: 0.5rem; margin: -0.5rem; /* keep the tap target large without shifting layout */ } /* The three-bar icon, drawn with one element plus its ::before/::after. */ .nav-toggle-bar, .nav-toggle-bar::before, .nav-toggle-bar::after { display: block; width: 1.5rem; height: 2px; background: #1f3a5f; content: ""; } .nav-toggle-bar::before { transform: translateY(-6px); } .nav-toggle-bar::after { transform: translateY(4px); /* 6px minus the bar's own 2px height */ } /* The nav takes its own row and is hidden until the checkbox is checked. */ .main-nav { flex-basis: 100%; flex-direction: column; gap: 0; max-height: 0; overflow: hidden; transition: max-height 0.2s ease; } /* Checked state: reveal the stacked links. The max-height caps the open menu to the space below the sticky header; a longer list scrolls inside it instead of running off the screen. */ .nav-toggle:checked ~ .main-nav { max-height: 70vh; overflow-y: auto; margin-top: 0.5rem; } /* The mobile-only home link reappears as the first entry in the menu. */ .nav-home-mobile { display: block; } .main-nav a { padding: 0.6rem 0; border-bottom: 1px solid #eee; } /* The active link keeps its colour but not the desktop underline, which would clash with the row separators. */ .main-nav a.active { border-bottom-color: #eee; } }