/* Fonts (spec 3.2) — self-hosted WOFF2 (wwwroot/fonts), no third-party requests. */
@font-face {
    font-family: "Source Serif 4";
    src: url("fonts/SourceSerif4-Regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Source Serif 4";
    src: url("fonts/SourceSerif4-Italic.woff2") format("woff2");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: "Source Serif 4";
    src: url("fonts/SourceSerif4-SemiBold.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Source Serif 4";
    src: url("fonts/SourceSerif4-Bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Source Sans 3";
    src: url("fonts/SourceSans3-Regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Source Sans 3";
    src: url("fonts/SourceSans3-SemiBold.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "JetBrains Mono";
    src: url("fonts/JetBrainsMono-Regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

:root {
    --font-serif: "Source Serif 4", Georgia, "Times New Roman", serif;
    --font-ui: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
}

/* The colour tokens are not here: they are generated into /branding/theme.css from the site's
   branding folder (linked before this file), so this stylesheet holds no colour values of its
   own — bar the two marked regions BrandingThemeCssTests allow-lists: the drawer scrim directly
   below and MudBlazor's scrollbar copy at the end of this file. */

/* The one exception besides the marked scrollbar copy: the contents drawer's scrim (brief 07i
   item 3). Its alphas are fixed design constants — black 32% in light, 48% in dark — not
   site-brandable palette entries (the brandable tokens are exactly the 18 theme.css generates),
   so they live here as theme-keyed custom properties in modern CSS colour syntax: the drawer
   paints with var(--scrim) and no alpha value appears in any component or style attribute. The
   three blocks mirror theme.css's structure: explicit light, explicit dark, system dark. */
/* scrim-colour-values:begin */
:root { --scrim: color(srgb 0 0 0 / 0.32); }
:root[data-theme=dark] { --scrim: color(srgb 0 0 0 / 0.48); }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme=light]) { --scrim: color(srgb 0 0 0 / 0.48); }
}
/* scrim-colour-values:end */

html, body {
    background-color: var(--bg);
    color: var(--text);
    font-family: var(--font-ui);
}

/* Fluid root type (brief 03f item 1): the root font size grows linearly from 16px at 1440px to
   19px at 2560px, capped at both ends, so rem-sized surfaces scale with the type on big screens.
   At 1440px the middle term is 16px, at 2560px it is 19px, and between it rises ~3px over 1120px
   of viewport (17.3px at 1920px). Viewports ≤1440px (including phones) stay at 16px. */
html {
    font-size: clamp(16px, calc(16px + (100vw - 1440px) * 3 / 1120), 19px);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-serif);
}

code, pre, kbd, samp {
    font-family: var(--font-mono);
}

/* Typography (spec §3.2): headings and post body in Source Serif 4, UI text in
   Source Sans 3, code in JetBrains Mono. MudBlazor injects its --mud-typography-*-family
   variables as inline custom properties on <html> at runtime, hence !important. */
:root {
    --mud-typography-default-family: var(--font-ui) !important;
    --mud-typography-h1-family: var(--font-serif) !important;
    --mud-typography-h2-family: var(--font-serif) !important;
    --mud-typography-h3-family: var(--font-serif) !important;
    --mud-typography-h4-family: var(--font-serif) !important;
    --mud-typography-h5-family: var(--font-serif) !important;
    --mud-typography-h6-family: var(--font-serif) !important;
    --mud-typography-subtitle1-family: var(--font-serif) !important;
    --mud-typography-subtitle2-family: var(--font-serif) !important;
    --mud-typography-body1-family: var(--font-ui) !important;
    --mud-typography-body2-family: var(--font-ui) !important;
    --mud-typography-button-family: var(--font-ui) !important;
    --mud-typography-caption-family: var(--font-ui) !important;
    --mud-typography-overline-family: var(--font-ui) !important;
}

/* Article body 1.125rem/1.65 desktop, 1.0625rem on phones; hero title 2.5rem desktop / 1.875rem
   phone; subtitles Source Serif italic in --muted (spec §3.2). The sizes are rem so the reading
   text scales with the fluid root (brief 03f item 5): 18px/17px/40px/30px at a 16px root, larger
   above 1440px. */
.markdown-body {
    font-family: var(--font-serif);
    font-size: 1.125rem;
    line-height: 1.65;
}

.hero-title {
    font-family: var(--font-serif);
    font-size: 2.5rem;
    line-height: 1.15;
}

.subtitle {
    font-family: var(--font-serif);
    font-style: italic;
    color: var(--muted);
}

@media (max-width: 959.98px) {
    .markdown-body {
        font-size: 1.0625rem;
    }

    .hero-title {
        font-size: 1.875rem;
    }
}

/* Anchors speak in the accent colour (spec §3.1: crimson = act/current). */
a {
    color: var(--primary);
}

/* h1 receives FocusOnNavigate's programmatic focus (Routes.razor); no ring for it. */
h1:focus {
    outline: none;
}

/* Layout shell: a CSS grid with a sidebar area and a content area. Global
   because it styles <html> classes. */
.shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }
.shell > .sidebar { position: sticky; top: 0; height: 100vh; overflow-y: auto; }
.shell > main { container-type: inline-size; min-width: 0; }
:root { --sidebar-w: 260px; }
html.sidebar-collapsed { --sidebar-w: 64px; }
@media (min-width: 960px) and (max-width: 1279.98px) { :root { --sidebar-w: 64px; } }
@media (max-width: 959.98px) {
  .shell { grid-template-columns: 1fr; }
  /* The closed overlay also gets visibility: hidden so its
     links leave the tab order. The delayed visibility transition keeps the slide-out visible; the
     open state resets the delay to 0 so the slide-in and the immediate focus move still work.
     The height is the dynamic viewport height (100dvh, with 100vh as the fallback) so the last
     footer item ("Log in"/"Log out") clears Safari's toolbar on iPhone, and the drawer scrolls
     itself (overflow-y: auto) when its content is taller than the screen. No bottom edge: the
     height comes from dvh sizing, not from top + bottom stretching. */
  .shell > .sidebar { position: fixed; inset: 0 auto auto 0; width: 280px; height: 100vh; height: 100dvh;
                      overflow-y: auto; transform: translateX(-100%);
                      transition: transform .2s, visibility 0s .2s; visibility: hidden; z-index: 1300; }
  /* Clear the home indicator: viewport-fit=cover (App.razor) makes env(safe-area-inset-bottom)
     non-zero on notched phones. The id selector outranks the scoped .sidebar padding (12px 10px),
     so the bottom keeps its 12px plus the inset. */
  #sidebar-nav { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
  html.nav-open .shell > .sidebar { transform: none; visibility: visible; transition: transform .2s, visibility 0s; }
  /* Scroll lock: while the drawer is open the page behind it must not scroll. The drawer's own
     scrolling is on .sidebar itself (overflow-y: auto), not on the root, so it is unaffected. */
  html.nav-open { overflow: hidden; }
  .topbar { display: flex; }
}
@media (min-width: 960px) { .topbar { display: none; } }
/* rail: hide labels/counts, keep icons, tooltips via title. Gated to ≥1280px — the collapse rail
   exists only there, and blog-sidebar=collapsed stored at a wide width must not strip labels from
   the overlays below 1280px. */
@media (min-width: 1280px) {
  :root:is(.sidebar-collapsed) .sidebar .label { display: none; }
}
/* 960-1279px rail vs drawer: labels appear only in the drawer. The section headings and the
   brand copy keep their boxes in the rail (text hidden, not display:none) — the headings reserve
   their vertical space and the brand block its height — so opening the drawer adds only the
   labels beside the icons and no icon moves. */
@media (min-width: 960px) and (max-width: 1279.98px) {
  .sidebar .label { display: none; }
  html.nav-open .sidebar .label { display: inline; }
  html .sidebar .section-heading,
  html .sidebar .brand-name,
  html .sidebar .brand-tagline { display: block; visibility: hidden; }
  html.nav-open .sidebar .section-heading,
  html.nav-open .sidebar .brand-name,
  html.nav-open .sidebar .brand-tagline { display: block; visibility: visible; }
}

/* 960-1279px: html.nav-open widens the rail to the full sidebar as an overlay over the
   content (spec §4.1). */
@media (min-width: 960px) and (max-width: 1279.98px) {
  html.nav-open .shell > .sidebar {
    position: fixed; inset: 0 auto 0 0; width: 260px; height: 100vh; overflow-y: auto;
    transform: none; transition: transform .2s; z-index: 1300;
    box-shadow: 0 0 24px var(--fallback-wash);
  }
}

/* The scrim behind the overlay sidebar (phone and the 960-1279 overlay). */
.scrim { display: none; position: fixed; inset: 0; background: var(--fallback-wash); z-index: 1200; }
@media (max-width: 1279.98px) { html.nav-open .scrim { display: block; } }
/* MudBlazor's scrollbar rules, copied verbatim from the <style> block MudThemeProvider
   renders; MainLayout's DefaultScrollbar "true" turns that block off, so this copy is what
   keeps the look it produced. The copy stays byte-identical (line endings aside — this file
   is CRLF) to a fresh render of the block, asserted in MudThemeStyleCspTests. It is one of
   the two marked regions of app.css allowed to carry colour values (BrandingThemeCssTests):
   they are MudBlazor's rules, not this file's own. */
/* mudblazor-scrollbar-copy:begin */
::-webkit-scrollbar {width: 8px;height: 8px;z-index: 1;}
::-webkit-scrollbar-track {background: transparent;}
::-webkit-scrollbar-thumb {background: #c4c4c4;border-radius: 1px;}
::-webkit-scrollbar-thumb:hover {background: #a6a6a6;}
html, body * {scrollbar-color: #c4c4c4 transparent;scrollbar-width: thin;}
/* mudblazor-scrollbar-copy:end */
