/* ── Self-hosted fonts (IBM Plex) ──────────────────────────── */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/ibm-plex-mono-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-400-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-500-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-600-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Design tokens ─────────────────────────────────────────── */
@layer base {
  :root {
    --bg: #f5f5f0;
    --surface: #ffffff;
    --border: #d8d8d0;
    --text: #1a1a18;
    --muted: #6b6b65;
    --accent: #2563eb;
    --radius: 6px;       /* general interactive elements, inputs, inline code */
    --radius-lg: 10px;   /* larger containers: cards, code blocks, callouts  */
    --sidebar-w: 180px;
  }

  [data-theme="dark"] {
    --bg: #0f0f0d;
    --surface: #1a1a18;
    --border: #2e2e2a;
    --text: #e8e8e2;
    --muted: #8a8a82;
    --accent: #3b82f6;
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --bg: #0f0f0d;
      --surface: #1a1a18;
      --border: #2e2e2a;
      --text: #e8e8e2;
      --muted: #8a8a82;
      --accent: #3b82f6;
    }
  }

  * {
    box-sizing: border-box;
  }

  html {
    font-family: 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
    background-color: var(--bg);
    color: var(--text);
    line-height: 1.65;
    font-size: 16px;
  }

  /* Start invisible so the 150ms fade-in conceals any residual layout shift
     on first paint. The anti-FOUC script in head.html restores the stored theme
     *before* this CSS even applies, so there is never a light-flash followed by
     a dark fade — the correct palette is already in place when opacity reaches 1. */
  body {
    opacity: 0;
    animation: fadein 0.15s ease forwards;
    margin: 0;
  }

  @keyframes fadein {
    to { opacity: 1; }
  }

  h1, h2, h3, h4, h5, h6 {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    color: var(--text);
    font-weight: 600;
    line-height: 1.3;
  }

  a {
    color: var(--accent);
    text-decoration: none;
  }

  a:hover {
    text-decoration: underline;
  }

  /* Inline code */
  code {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.875em;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.15em 0.35em;
  }

  /* Fallback for un-highlighted <pre> (no .highlight wrapper).
   * Scoped to .page-body and excludes Chroma's own pre.chroma elements. */
  .page-body pre:not(.chroma) {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1rem 1.25rem;
    overflow-x: auto;
    font-size: 0.875rem;
    margin: 1.5rem 0;
  }

  /* Reset inline-code styles when inside any <pre> */
  pre code {
    background: none;
    border: none;
    padding: 0;
    font-size: inherit;
  }

  /* ── Syntax-highlighted code blocks (Hugo/Chroma) ────────────────
   * Hugo wraps highlighted blocks: .highlight > .chroma > [table] > pre
   * We own the outer border/radius; Chroma owns the background colour.
   * ──────────────────────────────────────────────────────────────── */

  .highlight {
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    /* Shrink to content width so short snippets don't stretch across the page.
     * max-width: 100% ensures long lines stay within the column and scroll. */
    width: fit-content;
    max-width: 100%;
    overflow-x: auto;    /* scroll long lines horizontally */
    margin: 1.5rem 0;
    font-size: 0.875rem;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    /* Set the code background here so there's never a colour gap between
     * .highlight and its .chroma child, regardless of table height. */
    background: #f6f8fa;
  }

  [data-theme="dark"] .highlight { background: #161b22; }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .highlight { background: #161b22; }
  }

  /* Chroma fills the wrapper; overflow is handled by .highlight */
  .chroma {
    margin: 0;
  }

  /* pre elements inside Chroma get padding; background comes from the
   * Chroma token CSS below, not from our surface token */
  .chroma pre {
    margin: 0;
    padding: 0.875rem 1.125rem;
    background: transparent !important;
    border: none !important;
    border-radius: 0 !important;
  }

  /* Line-number table layout.
   * .lntable is a real <table> inside .page-body, so .page-body table styles
   * would normally match it and add border/radius/margin — reset all of those
   * here. Specificity of .chroma .lntable (0,2,1) beats .page-body table (0,1,1). */
  .chroma .lntable {
    border-spacing: 0;
    border-collapse: separate; /* keep separate so lntd padding works */
    width: 100%;
    /* reset .page-body table overrides */
    border: none;
    border-radius: 0;
    overflow: visible;
    margin: 0;
    font-size: inherit;
  }

  .chroma .lntd {
    vertical-align: top;
    padding: 0;
    /* reset .page-body td overrides */
    border-bottom: none;
  }

  /* Prevent row background from .page-body tbody tr bleeding into code blocks */
  .chroma tbody tr {
    background: transparent;
  }

  /* Line-number column: sticky so it stays visible during horizontal scroll.
     Background must match Chroma's so the code column doesn't bleed through. */
  .chroma .lntd:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background-color: #f6f8fa;  /* light Chroma bg (github style) */
    border-right: 1px solid var(--border);
    /* No opacity here — it would make the background translucent too.
       The muted colour on the numbers themselves comes from .chroma .lnt/.ln. */
    user-select: none;
    -webkit-user-select: none;
  }

  [data-theme="dark"] .chroma .lntd:first-child { background-color: #161b22; }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .chroma .lntd:first-child { background-color: #161b22; }
  }

  .chroma .lntd:first-child pre {
    padding-right: 0.75rem;
  }

  /* Code column: left padding so it clears the line-number border */
  .chroma .lntd:last-child pre {
    padding-left: 1rem;
  }

  /* ── Chroma token colours — light (GitHub) ───────────────────────
   * Generated with: hugo gen chromastyles --style=github
   * ──────────────────────────────────────────────────────────────── */
  .chroma                      { color:#24292e; background-color:#f6f8fa; }
  .chroma .lnt                 { color:#6e7781; }
  .chroma .ln                  { color:#6e7781; }
  .chroma .hl                  { background-color:#fffbdd; display:block; width:100%; }
  .chroma .k                   { color:#cf222e; }
  .chroma .kc                  { color:#cf222e; }
  .chroma .kd                  { color:#cf222e; }
  .chroma .kn                  { color:#cf222e; }
  .chroma .kp                  { color:#cf222e; }
  .chroma .kr                  { color:#cf222e; }
  .chroma .kt                  { color:#cf222e; }
  .chroma .nc                  { color:#8250df; }
  .chroma .nf                  { color:#8250df; }
  .chroma .fm                  { color:#8250df; }
  .chroma .no                  { color:#0550ae; }
  .chroma .nd                  { color:#0550ae; }
  .chroma .ni                  { color:#8250df; }
  .chroma .nt                  { color:#116329; }
  .chroma .nv, .chroma .vc,
  .chroma .vg, .chroma .vi,
  .chroma .vm                  { color:#953800; }
  .chroma .nb, .chroma .bp     { color:#8250df; }
  .chroma .s,  .chroma .sa,
  .chroma .sb, .chroma .sc,
  .chroma .dl, .chroma .sd,
  .chroma .s2, .chroma .se,
  .chroma .sh, .chroma .si,
  .chroma .sx, .chroma .sr,
  .chroma .s1, .chroma .ss     { color:#0a3069; }
  .chroma .m,  .chroma .mb,
  .chroma .mf, .chroma .mh,
  .chroma .mi, .chroma .il,
  .chroma .mo                  { color:#0550ae; }
  .chroma .o, .chroma .ow      { color:#0550ae; }
  .chroma .c,  .chroma .ch,
  .chroma .cm, .chroma .c1,
  .chroma .cs, .chroma .cp,
  .chroma .cpf                 { color:#6e7781; font-style:italic; }
  .chroma .gd                  { color:#82071e; background-color:#ffebe9; }
  .chroma .gi                  { color:#116329; background-color:#dafbe1; }
  .chroma .ge                  { font-style:italic; }
  .chroma .gs                  { font-weight:bold; }
  .chroma .p                   { color:#24292e; }

  /* ── Chroma token colours — dark (GitHub Dark) ───────────────────
   * Generated with: hugo gen chromastyles --style=github-dark
   * Applied when data-theme="dark" or when the OS prefers dark and
   * the user has not explicitly chosen light mode.
   * ──────────────────────────────────────────────────────────────── */
  [data-theme="dark"] .chroma                     { color:#e6edf3; background-color:#161b22; }
  [data-theme="dark"] .chroma .lnt                { color:#6e7681; }
  [data-theme="dark"] .chroma .ln                 { color:#6e7681; }
  [data-theme="dark"] .chroma .hl                 { background-color:#2d333b; display:block; width:100%; }
  [data-theme="dark"] .chroma .k                  { color:#ff7b72; }
  [data-theme="dark"] .chroma .kc                 { color:#79c0ff; }
  [data-theme="dark"] .chroma .kd                 { color:#ff7b72; }
  [data-theme="dark"] .chroma .kn                 { color:#ff7b72; }
  [data-theme="dark"] .chroma .kp                 { color:#79c0ff; }
  [data-theme="dark"] .chroma .kr                 { color:#ff7b72; }
  [data-theme="dark"] .chroma .kt                 { color:#ff7b72; }
  [data-theme="dark"] .chroma .nc                 { color:#f0883e; font-weight:bold; }
  [data-theme="dark"] .chroma .nf                 { color:#d2a8ff; font-weight:bold; }
  [data-theme="dark"] .chroma .fm                 { color:#d2a8ff; }
  [data-theme="dark"] .chroma .no                 { color:#79c0ff; font-weight:bold; }
  [data-theme="dark"] .chroma .nd                 { color:#d2a8ff; font-weight:bold; }
  [data-theme="dark"] .chroma .ni                 { color:#ffa657; }
  [data-theme="dark"] .chroma .nt                 { color:#7ee787; }
  [data-theme="dark"] .chroma .nv, [data-theme="dark"] .chroma .vc,
  [data-theme="dark"] .chroma .vg, [data-theme="dark"] .chroma .vi,
  [data-theme="dark"] .chroma .vm                 { color:#79c0ff; }
  [data-theme="dark"] .chroma .nb, [data-theme="dark"] .chroma .bp { color:#79c0ff; }
  [data-theme="dark"] .chroma .s,  [data-theme="dark"] .chroma .sa,
  [data-theme="dark"] .chroma .sb, [data-theme="dark"] .chroma .sc,
  [data-theme="dark"] .chroma .dl, [data-theme="dark"] .chroma .sd,
  [data-theme="dark"] .chroma .s2, [data-theme="dark"] .chroma .se,
  [data-theme="dark"] .chroma .sh, [data-theme="dark"] .chroma .si,
  [data-theme="dark"] .chroma .sx, [data-theme="dark"] .chroma .sr,
  [data-theme="dark"] .chroma .s1, [data-theme="dark"] .chroma .ss { color:#a5d6ff; }
  [data-theme="dark"] .chroma .m,  [data-theme="dark"] .chroma .mb,
  [data-theme="dark"] .chroma .mf, [data-theme="dark"] .chroma .mh,
  [data-theme="dark"] .chroma .mi, [data-theme="dark"] .chroma .il,
  [data-theme="dark"] .chroma .mo                 { color:#a5d6ff; }
  [data-theme="dark"] .chroma .o, [data-theme="dark"] .chroma .ow  { color:#ff7b72; font-weight:bold; }
  [data-theme="dark"] .chroma .c,  [data-theme="dark"] .chroma .ch,
  [data-theme="dark"] .chroma .cm, [data-theme="dark"] .chroma .c1,
  [data-theme="dark"] .chroma .cs, [data-theme="dark"] .chroma .cp,
  [data-theme="dark"] .chroma .cpf                { color:#8b949e; font-style:italic; }
  [data-theme="dark"] .chroma .gd                 { color:#ffa198; background-color:#490202; }
  [data-theme="dark"] .chroma .gi                 { color:#56d364; background-color:#0f5323; }
  [data-theme="dark"] .chroma .ge                 { font-style:italic; }
  [data-theme="dark"] .chroma .gs                 { font-weight:bold; }
  [data-theme="dark"] .chroma .p                  { color:#e6edf3; }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .chroma                     { color:#e6edf3; background-color:#161b22; }
    :root:not([data-theme="light"]) .chroma .lnt                { color:#6e7681; }
    :root:not([data-theme="light"]) .chroma .ln                 { color:#6e7681; }
    :root:not([data-theme="light"]) .chroma .hl                 { background-color:#2d333b; display:block; width:100%; }
    :root:not([data-theme="light"]) .chroma .k                  { color:#ff7b72; }
    :root:not([data-theme="light"]) .chroma .kc                 { color:#79c0ff; }
    :root:not([data-theme="light"]) .chroma .kd                 { color:#ff7b72; }
    :root:not([data-theme="light"]) .chroma .kn                 { color:#ff7b72; }
    :root:not([data-theme="light"]) .chroma .kp                 { color:#79c0ff; }
    :root:not([data-theme="light"]) .chroma .kr                 { color:#ff7b72; }
    :root:not([data-theme="light"]) .chroma .kt                 { color:#ff7b72; }
    :root:not([data-theme="light"]) .chroma .nc                 { color:#f0883e; font-weight:bold; }
    :root:not([data-theme="light"]) .chroma .nf                 { color:#d2a8ff; font-weight:bold; }
    :root:not([data-theme="light"]) .chroma .fm                 { color:#d2a8ff; }
    :root:not([data-theme="light"]) .chroma .no                 { color:#79c0ff; font-weight:bold; }
    :root:not([data-theme="light"]) .chroma .nd                 { color:#d2a8ff; font-weight:bold; }
    :root:not([data-theme="light"]) .chroma .ni                 { color:#ffa657; }
    :root:not([data-theme="light"]) .chroma .nt                 { color:#7ee787; }
    :root:not([data-theme="light"]) .chroma .nv,
    :root:not([data-theme="light"]) .chroma .vc,
    :root:not([data-theme="light"]) .chroma .vg,
    :root:not([data-theme="light"]) .chroma .vi,
    :root:not([data-theme="light"]) .chroma .vm                 { color:#79c0ff; }
    :root:not([data-theme="light"]) .chroma .nb,
    :root:not([data-theme="light"]) .chroma .bp                 { color:#79c0ff; }
    :root:not([data-theme="light"]) .chroma .s,
    :root:not([data-theme="light"]) .chroma .sa,
    :root:not([data-theme="light"]) .chroma .sb,
    :root:not([data-theme="light"]) .chroma .sc,
    :root:not([data-theme="light"]) .chroma .dl,
    :root:not([data-theme="light"]) .chroma .sd,
    :root:not([data-theme="light"]) .chroma .s2,
    :root:not([data-theme="light"]) .chroma .se,
    :root:not([data-theme="light"]) .chroma .sh,
    :root:not([data-theme="light"]) .chroma .si,
    :root:not([data-theme="light"]) .chroma .sx,
    :root:not([data-theme="light"]) .chroma .sr,
    :root:not([data-theme="light"]) .chroma .s1,
    :root:not([data-theme="light"]) .chroma .ss                 { color:#a5d6ff; }
    :root:not([data-theme="light"]) .chroma .m,
    :root:not([data-theme="light"]) .chroma .mb,
    :root:not([data-theme="light"]) .chroma .mf,
    :root:not([data-theme="light"]) .chroma .mh,
    :root:not([data-theme="light"]) .chroma .mi,
    :root:not([data-theme="light"]) .chroma .il,
    :root:not([data-theme="light"]) .chroma .mo                 { color:#a5d6ff; }
    :root:not([data-theme="light"]) .chroma .o,
    :root:not([data-theme="light"]) .chroma .ow                 { color:#ff7b72; font-weight:bold; }
    :root:not([data-theme="light"]) .chroma .c,
    :root:not([data-theme="light"]) .chroma .ch,
    :root:not([data-theme="light"]) .chroma .cm,
    :root:not([data-theme="light"]) .chroma .c1,
    :root:not([data-theme="light"]) .chroma .cs,
    :root:not([data-theme="light"]) .chroma .cp,
    :root:not([data-theme="light"]) .chroma .cpf               { color:#8b949e; font-style:italic; }
    :root:not([data-theme="light"]) .chroma .gd                { color:#ffa198; background-color:#490202; }
    :root:not([data-theme="light"]) .chroma .gi                { color:#56d364; background-color:#0f5323; }
    :root:not([data-theme="light"]) .chroma .ge                { font-style:italic; }
    :root:not([data-theme="light"]) .chroma .gs                { font-weight:bold; }
    :root:not([data-theme="light"]) .chroma .p                 { color:#e6edf3; }
  }

  hr {
    border: none;
    border-top: 1px solid var(--border);
    margin: 2rem 0;
  }

  blockquote {
    border-left: 3px solid var(--border);
    margin: 1.5rem 0;
    padding: 0.5rem 0 0.5rem 1.25rem;
    color: var(--muted);
    font-style: italic;
  }

  img {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius);
  }

  /* ── Content tables ──────────────────────────────────────────────
   * Scoped to .page-body to avoid touching Chroma's internal .lntable
   * (the line-number layout table inside code blocks).
   *
   * border-collapse: separate is required for border-radius + overflow:hidden
   * to clip corner cells correctly in all modern browsers.
   * ──────────────────────────────────────────────────────────────── */
  .page-body table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.875rem;
    margin: 1.5rem 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
  }

  .page-body th,
  .page-body td {
    padding: 0.5rem 0.875rem;
    text-align: left;
    border-bottom: 1px solid var(--border);
  }

  /* Vertical dividers between columns */
  .page-body th:not(:last-child),
  .page-body td:not(:last-child) {
    border-right: 1px solid var(--border);
  }

  /* Last row has no bottom border — the table border provides the edge */
  .page-body tr:last-child td {
    border-bottom: none;
  }

  /* Header row — surface colour so it reads as a distinct band */
  .page-body th {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    background: var(--surface);
  }

  /* Body rows — same background as code blocks */
  .page-body tbody tr { background: #f6f8fa; }

  [data-theme="dark"] .page-body tbody tr { background: #161b22; }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .page-body tbody tr { background: #161b22; }
  }
}

/* ── Layout ────────────────────────────────────────────────── */
@layer components {
  .site-wrapper {
    display: flex;
    min-height: 100vh;
  }

  /* Sidebar (desktop) */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: var(--sidebar-w);
    height: 100vh;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    padding: 1.75rem 1.25rem;
    z-index: 50;
    overflow-y: auto;
  }

  .sidebar-brand {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
    text-decoration: none;
    letter-spacing: -0.02em;
    margin-bottom: 2rem;
    display: block;
  }

  .sidebar-brand:hover {
    text-decoration: none;
    color: var(--accent);
  }

  .sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1;
  }

  .sidebar-nav a {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.85rem;
    color: var(--muted);
    padding: 0.35rem 0.5rem;
    border-radius: var(--radius);
    transition: color 0.1s, background 0.1s;
    text-decoration: none;
  }

  .sidebar-nav a:hover,
  .sidebar-nav a.active {
    color: var(--text);
    background: var(--bg);
    text-decoration: none;
  }

  /* Project list — inlined under the Projects nav entry */
  .sidebar-sub-nav {
    display: flex;
    flex-direction: column;
    margin-left: 0.6rem;
    padding-left: 0.65rem;
    border-left: 1px solid var(--border);
    margin-bottom: 0.1rem;
  }

  .sidebar-sub-nav a {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.78rem;
    color: var(--muted);
    padding: 0.25rem 0.4rem;
    border-radius: var(--radius);
    text-decoration: none;
    line-height: 1.35;
    transition: color 0.1s, background 0.1s;
  }

  .sidebar-sub-nav a:hover {
    color: var(--text);
    background: var(--bg);
    text-decoration: none;
  }

  .sidebar-sub-nav a.active {
    color: var(--accent);
  }

  /* TOC — inlined under the project list when on a single project page */
  .sidebar-toc {
    margin-left: 0.6rem;
    padding-left: 0.65rem;
    border-left: 1px solid var(--border);
    margin-bottom: 0.1rem;
  }

.sidebar-toc nav#TableOfContents ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }

  .sidebar-toc nav#TableOfContents > ul {
    display: flex;
    flex-direction: column;
  }

  .sidebar-toc nav#TableOfContents a {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.73rem;
    color: var(--muted);
    padding: 0.2rem 0.4rem;
    border-radius: var(--radius);
    text-decoration: none;
    display: block;
    line-height: 1.35;
    transition: color 0.1s, background 0.1s;
  }

  .sidebar-toc nav#TableOfContents a:hover {
    color: var(--text);
    background: var(--bg);
    text-decoration: none;
  }

  /* Indent h3 and h4 levels */
  .sidebar-toc nav#TableOfContents ul ul a {
    padding-left: 0.9rem;
    font-size: 0.69rem;
  }

  .sidebar-toc nav#TableOfContents ul ul ul a {
    padding-left: 1.6rem;
    font-size: 0.66rem;
  }

  /* Mobile nav: project sub-group */
  .mobile-nav-group {
    border-top: 1px solid var(--border);
    padding-top: 0.25rem;
  }

  .mobile-nav-sub {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.85rem;
    color: var(--muted);
    padding: 0.4rem 0;
    padding-left: 0.75rem;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
    display: block;
  }

  .mobile-nav-sub:last-child {
    border-bottom: none;
  }

  .mobile-nav-sub:hover,
  .mobile-nav-sub.active {
    color: var(--text);
  }

  .mobile-nav-sub.active {
    color: var(--accent);
  }

  .sidebar-footer {
    margin-top: 0;
    padding-top: 0.75rem;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
  }

  .theme-toggle {
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
    padding: 0;
    margin-left: auto;
    transition: color 0.1s;
  }

  .theme-toggle:hover {
    color: var(--text);
  }

  /* Main content area */
  .page-wrapper {
    margin-left: var(--sidebar-w);
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
  }

  .main-content {
    flex: 1;
    padding: 2.5rem 3rem;
    max-width: calc(70ch + 6rem);
  }

  /* Top bar (mobile only) */
  /* Sticky wrapper keeps the topbar AND the open nav drawer pinned together */
  .mobile-header {
    display: none;
    position: sticky;
    top: 0;
    z-index: 50;
  }

  .topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 0.75rem 1rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .topbar-brand {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text);
    text-decoration: none;
  }

  .topbar-right {
    display: flex;
    align-items: center;
    gap: 0.75rem;
  }

  .hamburger {
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--muted);
    cursor: pointer;
    padding: 0.35rem 0.5rem;
    font-size: 1rem;
    line-height: 1;
  }

  .mobile-nav {
    display: none;
    flex-direction: column;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 0.5rem 1rem 1rem;
  }

  .mobile-nav.open {
    display: flex;
    /* Cap height so the nav never fills the whole screen on pages with a
     * long TOC; the user can scroll within the dropdown */
    max-height: calc(100svh - 4rem);
    overflow-y: auto;
  }

  .mobile-nav a {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.9rem;
    color: var(--muted);
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
  }

  .mobile-nav a:last-child {
    border-bottom: none;
  }

  .mobile-nav a:hover,
  .mobile-nav a.active {
    color: var(--text);
  }

  @media (max-width: 768px) {
    .site-wrapper {
      flex-direction: column;
    }

    .sidebar {
      display: none;
    }

    .mobile-header {
      display: block;
    }

    .page-wrapper {
      margin-left: 0;
    }

    .main-content {
      padding: 1.5rem 1.25rem;
    }

    /* Show the inline TOC block that is hidden on desktop */
    details.mobile-toc {
      display: block;
    }

    /* Offset anchor scroll targets by the sticky topbar height so headings
       don't disappear behind the bar (~0.75rem padding × 2 + ~2rem button). */
    .page-body h1,
    .page-body h2,
    .page-body h3,
    .page-body h4 {
      scroll-margin-top: 3.5rem;
    }
  }

  /* ── Page headings ───────────────────────────────────────── */
  .page-title {
    font-size: 1.5rem;
    margin: 0 0 0.25rem;
  }

  .page-meta {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8rem;
    color: var(--muted);
    margin-bottom: 2rem;
  }

  .page-body {
    max-width: 70ch;
  }

  .page-body p {
    margin: 0 0 1.1rem;
  }

  .page-body h2 {
    font-size: 1.15rem;
    margin: 2rem 0 0.75rem;
  }

  .page-body h3 {
    font-size: 1rem;
    margin: 1.5rem 0 0.5rem;
  }

  .page-body ul,
  .page-body ol {
    padding-left: 1.5rem;
    margin: 0 0 1.1rem;
  }

  .page-body li {
    margin-bottom: 0.3rem;
  }

  /* ── Post list ───────────────────────────────────────────── */

  /* Year group block */
  .post-year-block {
    margin-bottom: 0.5rem;
  }

  .post-year-marker {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--muted);
    padding: 1.25rem 0 0.35rem;
    border-bottom: 1px solid var(--border);
  }

  .post-year-block:first-child .post-year-marker {
    padding-top: 0;
  }

  .post-list {
    list-style: none;
    padding: 0;
    margin: 0;
  }

  .post-list-item {
    display: grid;
    grid-template-columns: 5rem 1fr;
    gap: 1rem;
    align-items: start;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--border);
  }

  .post-date {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.78rem;
    color: var(--muted);
    white-space: nowrap;
    padding-top: 0.1rem; /* optical alignment with title */
  }

  .post-list-right {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
  }

  .post-list-title {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    line-height: 1.35;
  }

  .post-list-title:hover {
    color: var(--accent);
    text-decoration: none;
  }

  .post-list-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
  }

  .post-list-tag {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.68rem;
    color: var(--muted);
    opacity: 0.8;
  }

  .post-list-tag + .post-list-tag::before {
    content: '·';
    margin-right: 0.4rem;
  }

  /* Post prev/next navigation */
  .post-nav {
    display: flex;
    justify-content: space-between;
    margin-top: 3rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border);
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8rem;
  }

  .post-nav a {
    color: var(--muted);
    text-decoration: none;
  }

  .post-nav a:hover {
    color: var(--text);
  }

  .post-nav-next {
    margin-left: auto;
  }

  /* Post article header */
  .post-header {
    margin-bottom: 2rem;
  }

  /* ── Post cover image (front matter: image: "cover.jpg") ─────── */
  .post-cover {
    margin-bottom: 1.75rem;
    border-radius: var(--radius-lg);
    overflow: hidden;   /* clips the img to our radius */
  }

  .post-cover img {
    display: block;
    width: 100%;
    /* 2:1 crop keeps landscape shots from dominating the page */
    aspect-ratio: 2 / 1;
    object-fit: cover;
  }

  /* ── Mobile inline TOC (details/summary) ────────────────── */
  /* Hidden on desktop — the sidebar already shows the TOC there.
     Shown at the top of articles on mobile via the 768px media query. */
  details.mobile-toc {
    display: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    margin-bottom: 2rem;
    overflow: hidden;
  }

  details.mobile-toc summary {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8rem;
    font-weight: 600;
    padding: 0.6rem 0.9rem;
    cursor: pointer;
    user-select: none;
    color: var(--muted);
    /* hide the browser's default disclosure triangle */
    list-style: none;
  }

  details.mobile-toc summary::-webkit-details-marker { display: none; }

  details.mobile-toc summary::before       { content: '▸  '; font-size: 0.65rem; }
  details.mobile-toc[open] summary::before { content: '▾  '; }

  details.mobile-toc[open] summary {
    border-bottom: 1px solid var(--border);
    color: var(--text);
  }

  .mobile-toc-body {
    padding: 0.5rem 0.75rem 0.75rem;
  }

  .mobile-toc-body nav#TableOfContents ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }

  .mobile-toc-body nav#TableOfContents a {
    display: block;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.78rem;
    color: var(--muted);
    padding: 0.2rem 0.4rem;
    border-radius: var(--radius);
    text-decoration: none;
    border-bottom: none;
    line-height: 1.35;
    transition: color 0.1s, background 0.1s;
  }

  .mobile-toc-body nav#TableOfContents a:hover {
    color: var(--text);
    background: var(--bg);
  }

  /* h3/h4 indentation */
  .mobile-toc-body nav#TableOfContents ul ul a {
    padding-left: 0.9rem;
    font-size: 0.72rem;
  }

  .mobile-toc-body nav#TableOfContents ul ul ul a {
    padding-left: 1.6rem;
    font-size: 0.68rem;
  }

  @media (max-width: 500px) {
    .post-list-item {
      grid-template-columns: 1fr;
      gap: 0.1rem;
    }
  }

  /* ── Tags ────────────────────────────────────────────────── */
  .tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.75rem;
  }

  .tag {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.1rem 0.45rem;
    text-decoration: none;
    transition: color 0.1s, border-color 0.1s;
  }

  .tag:hover {
    color: var(--accent);
    border-color: var(--accent);
    text-decoration: none;
  }

  /* ── Tags index page (/tags/) ────────────────────────────── */
  .tag-groups {
    margin-top: 2rem;
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  .tag-group {
    display: grid;
    grid-template-columns: 2rem 1fr;
    gap: 0 1.25rem;
    padding: 0.75rem 0;
    border-top: 1px solid var(--border);
    align-items: start;
  }

  .tag-group-letter {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--muted);
    padding-top: 0.3rem;   /* optical alignment with first chip */
  }

  .tag-group-items {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .tag-index-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    text-decoration: none;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.15rem 0.5rem;
    transition: border-color 0.1s, color 0.1s;
  }

  .tag-index-name {
    font-size: 0.75rem;
    color: var(--text);
  }

  .tag-index-count {
    font-size: 0.62rem;
    color: var(--muted);
  }

  .tag-index-item:hover {
    border-color: var(--accent);
  }

  .tag-index-item:hover .tag-index-name {
    color: var(--accent);
  }

  /* Label on individual tag pages: "tagged: hugo" */
  .tag-term-label {
    color: var(--muted);
    font-weight: 400;
  }

  /* ── Project grid ────────────────────────────────────────── */
  .project-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
    margin-top: 1rem;
  }

  @media (max-width: 580px) {
    .project-grid {
      grid-template-columns: 1fr;
    }
  }

  .project-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1.1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.1s;
  }

  .project-card:hover {
    border-color: var(--accent);
    text-decoration: none;
  }

  .project-card-title {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
  }

  .project-card-summary {
    font-size: 0.875rem;
    color: var(--muted);
    line-height: 1.5;
    flex: 1;
  }

  .project-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.25rem;
  }

  .tech-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
  }

  .tech-tag {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.68rem;
    color: var(--muted);
  }

  .tech-tag + .tech-tag::before {
    content: "·";
    margin-right: 0.3rem;
  }

  /* ── Project single ──────────────────────────────────────── */
  .project-header {
    margin-bottom: 2rem;
  }

  .project-links {
    display: flex;
    gap: 0.75rem;
    margin-top: 0.75rem;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8rem;
  }

  .project-links a {
    color: var(--accent);
    text-decoration: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.2rem 0.6rem;
  }

  .project-links a:hover {
    border-color: var(--accent);
    text-decoration: none;
  }

  /* ── Homepage ────────────────────────────────────────────── */
  .home-splash {
    margin-bottom: 3rem;
    padding-bottom: 2.5rem;
    border-bottom: 1px solid var(--border);
  }

  .splash-name {
    font-size: 2rem;
    font-weight: 700;
    margin: 0 0 0.4rem;
    letter-spacing: -0.04em;
  }

  .splash-bio {
    color: var(--muted);
    font-size: 0.9rem;
    margin: 0;
    line-height: 1.6;
  }

  /* ── Random post picker ─────────────────────────────────────── */
  /* Shown on the homepage below the about content; filled by JS on each page load. */
  .home-random {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8rem;
  }

  .random-post-label {
    color: var(--muted);
    margin-right: 0.6rem;
  }


  /* ── Taxonomy (tags) page ────────────────────────────────── */
  .taxonomy-list {
    list-style: none;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
  }

  .taxonomy-item a {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.85rem;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.2rem 0.6rem;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
  }

  .taxonomy-item a:hover {
    color: var(--accent);
    border-color: var(--accent);
    text-decoration: none;
  }

  .taxonomy-count {
    font-size: 0.7rem;
    opacity: 0.7;
  }

  /* ── Pagination ──────────────────────────────────────────── */
  .pagination {
    display: flex;
    gap: 0.5rem;
    margin-top: 2rem;
    padding: 0;          /* reset <ul> default padding */
    list-style: none;    /* reset <ul> bullets */
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8rem;
  }

  .pagination .page-item {
    list-style: none;
  }

  /* Hugo's internal pagination template emits:
     ul.pagination > li.page-item > a.page-link > [optional span for arrow glyphs]
     Target only .page-link — not the inner span — to avoid double borders. */
  .pagination .page-link {
    display: inline-block;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.3rem 0.65rem;
    color: var(--muted);
    text-decoration: none;
  }

  .pagination .page-link:hover {
    color: var(--text);
    border-color: var(--text);
    text-decoration: none;
  }

  .pagination .page-item.active .page-link {
    color: var(--accent);
    border-color: var(--accent);
  }

  .pagination .page-item.disabled .page-link {
    opacity: 0.4;
    cursor: default;
    pointer-events: none;
  }

  /* ── Callouts / alerts ───────────────────────────────────────── */
  /*
   * Rendered by render-blockquote.html (GitHub [!NOTE] syntax)
   * or the {{< callout >}} shortcode.
   * Uses a single --callout-color custom property per type so dark
   * mode works without extra overrides — the surface/border tokens
   * handle the rest.
   */
  .callout {
    --callout-color: var(--accent);
    border: 1px solid var(--border);
    border-left: 3px solid var(--callout-color);
    border-radius: var(--radius-lg);
    background: var(--surface);
    padding: 0.875rem 1rem;
    margin: 1.75rem 0;
  }

  .callout-label {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--callout-color);
    margin-bottom: 0.4rem;
  }

  .callout-body {
    font-size: 0.9rem;
    line-height: 1.6;
  }

  .callout-body > :last-child {
    margin-bottom: 0;
  }

  .callout-note      { --callout-color: #3b82f6; }
  .callout-tip       { --callout-color: #22c55e; }
  .callout-important { --callout-color: #a855f7; }
  .callout-warning   { --callout-color: #f59e0b; }
  .callout-caution   { --callout-color: #ef4444; }

  /* ── Copy button on code blocks ──────────────────────────────── */
  /* .highlight already has position:relative (set in the Chroma section) */

  .copy-btn {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    /* Sit above the chroma background */
    z-index: 1;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--muted);
    cursor: pointer;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.65rem;
    padding: 0.2rem 0.5rem;
    opacity: 0;
    transition: opacity 0.1s, color 0.1s;
  }

  .code-wrap:hover .copy-btn,
  .code-with-filename:hover .copy-btn,
  .copy-btn:focus {
    opacity: 1;
  }

  .copy-btn.is-copied {
    color: #22c55e;
    opacity: 1;
  }

  /* ── Lightbox ────────────────────────────────────────────────── */
  .page-body img.is-zoomable {
    cursor: zoom-in;
  }

  .lightbox {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 200;
    opacity: 0;
    transition: opacity 0.2s ease;
    padding: 2rem;
  }

  .lightbox.is-open {
    opacity: 1;
  }

  .lightbox img {
    max-width: 90vw;
    max-height: 90vh;
    object-fit: contain;
    border: none;
    border-radius: var(--radius);
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.6);
  }

  .lightbox-close {
    position: fixed;
    top: 1.25rem;
    right: 1.25rem;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 50%;  /* circle — suits a single-glyph dismiss button */
    color: #fff;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.1s;
  }

  .lightbox-close:hover {
    background: rgba(255, 255, 255, 0.22);
  }

  /* ── Figure with caption ─────────────────────────────────────── */
  .figure {
    margin: 1.75rem 0;
  }

  .figure img {
    display: block;
    width: 100%;
  }

  .figure-caption {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.75rem;
    color: var(--muted);
    margin-top: 0.5rem;
    line-height: 1.5;
  }

  /* ── Mermaid diagrams ────────────────────────────────────────── */
  .mermaid-wrap {
    margin: 1.75rem 0;
    overflow-x: auto;
  }

  .mermaid-wrap pre.mermaid {
    background: none;
    border: none;
    padding: 0;
    text-align: center;
  }

  /* ── Keyboard keys <kbd> ─────────────────────────────────────── */
  kbd {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.8em;
    background: var(--surface);
    border: 1px solid var(--border);
    border-bottom-width: 2px;
    border-radius: var(--radius);
    padding: 0.1em 0.4em;
    white-space: nowrap;
  }

  /* ── Reading progress bar ─────────────────────────────────────── */
  /* Thin accent line pinned to the top of the viewport. Width is driven
     by JS (0–100%). Sits above everything else so it's always visible. */
  #reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    background: var(--accent);
    z-index: 100;
    transition: width 0.1s linear;
    pointer-events: none;
  }

  /* On mobile the sticky topbar is at the top, so push the bar below it */
  @media (max-width: 768px) {
    #reading-progress {
      top: 3.5rem;
    }
  }

  /* ── Back-to-top button ───────────────────────────────────────── */
  /* Hidden (opacity 0) until JS adds .is-visible after 400px of scroll */
  .back-to-top {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: 40;
    width: 2.25rem;
    height: 2.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--muted);
    font-size: 1rem;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s, color 0.1s;
  }

  .back-to-top.is-visible {
    opacity: 1;
    pointer-events: auto;
  }

  .back-to-top:hover {
    color: var(--text);
  }

  /* ── Heading anchor links ─────────────────────────────────────── */
  /* The # link is invisible by default; it fades in when the heading is hovered.
     aria-hidden keeps it out of screen-reader content. */
  .page-body .heading-anchor {
    opacity: 0;
    margin-left: 0.4rem;
    font-size: 0.7em;
    color: var(--muted);
    text-decoration: none;
    border-bottom: none;
    transition: opacity 0.1s;
    user-select: none;
  }

  .page-body :is(h1, h2, h3, h4):hover .heading-anchor {
    opacity: 1;
  }

  /* ── Footnotes ────────────────────────────────────────────────── */
  /* Goldmark renders: <sup id="fnref:1"><a role="doc-noteref">1</a></sup>
     and at the bottom: <section class="footnotes"> <hr> <ol> ... */

  /* Inline superscript reference numbers */
  .page-body sup a[role="doc-noteref"] {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.65em;
    color: var(--accent);
    text-decoration: none;
    border-bottom: none;
    padding: 0 0.1em;
  }

  .page-body sup a[role="doc-noteref"]:hover {
    text-decoration: underline;
  }

  /* Footnote section */
  .page-body .footnotes {
    margin-top: 3rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    font-size: 0.85rem;
    color: var(--muted);
  }

  /* Hugo emits an <hr> before the list; our border-top replaces it visually */
  .page-body .footnotes hr {
    display: none;
  }

  .page-body .footnotes ol {
    padding-left: 1.25rem;
    margin: 0;
  }

  .page-body .footnotes li {
    margin-bottom: 0.5rem;
    line-height: 1.6;
  }

  /* ↩ back-reference link */
  .page-body .footnotes a[role="doc-backlink"] {
    color: var(--muted);
    text-decoration: none;
    border-bottom: none;
    font-size: 0.9em;
  }

  .page-body .footnotes a[role="doc-backlink"]:hover {
    color: var(--accent);
  }

  /* ── Code filename label ({{< code file="..." >}} shortcode) ──── */
  /* The filename tab sits flush above the code block, sharing its border.
     The code block loses its top-left radius so the tab looks attached. */
  /* .code-wrap — generated by JS to wrap plain .highlight blocks so the copy
     button can be anchored outside the horizontally-scrolling container */
  .code-wrap {
    position: relative;
    margin: 1.5rem 0;
    width: fit-content;
    max-width: 100%;
  }

  /* Remove the margin that .highlight normally owns; .code-wrap provides it */
  .code-wrap .highlight {
    margin: 0;
  }

  .code-with-filename {
    position: relative;  /* anchor for the copy button */
    margin: 1.5rem 0;
    /* Match the shrink-wrap behaviour of .highlight so the filename tab
       never extends past the width of the code block below it */
    width: fit-content;
    max-width: 100%;
  }

  .code-with-filename .code-filename {
    display: inline-flex;
    align-items: center;
    background: var(--border);
    color: var(--muted);
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.75rem;
    padding: 0.25rem 0.75rem;
    border: 1px solid var(--border);
    border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0;
  }

  /* Override the default highlight margin and top-left radius so the tab
     and the code block form a single connected element */
  .code-with-filename .highlight {
    margin: 0;
    border-radius: 0 var(--radius-lg) var(--radius-lg) var(--radius-lg);
  }

  /* ── Project single: three-column layout (nav | content | TOC) ── */

  /* Lift the max-width cap on the content area so the article and the
     right-side TOC panel can sit side by side without being clipped. */
  body.layout-project .main-content { max-width: none; }

  /* Two-column flex inside main-content: article grows up to 70ch,
     TOC panel is pinned on the right */
  .project-wrap {
    display: flex;
    align-items: flex-start;
    gap: 3rem;
  }

  .project-wrap > article {
    flex: 1;
    min-width: 0;       /* prevent flex item from overflowing */
    max-width: 70ch;
  }

  /* Right-side sticky TOC panel — same width as the nav sidebar it replaces */
  .project-toc-panel {
    width: var(--sidebar-w);
    flex-shrink: 0;
    position: sticky;
    top: 2rem;
  }

  /* On mobile the nav sidebar is already gone; collapse the project wrap to
     a single column and hide the TOC panel (mobile-toc details handles it) */
  @media (max-width: 768px) {
    .project-wrap             { display: block; }
    .project-toc-panel        { display: none; }
  }

  /* ── TOC scroll spy active link ───────────────────────────── */
  /* JS adds .active to the sidebar TOC link matching the heading
     currently in the top reading band of the viewport. */
  .sidebar-toc nav#TableOfContents a.active {
    color: var(--accent);
    background: var(--bg);
  }

  /* ── Smooth theme transition ──────────────────────────────── */
  /* Only active while JS adds .theme-transitioning during a user toggle.
     Never fires at page load, so the anti-FOUC script has no visible effect. */
  html.theme-transitioning *,
  html.theme-transitioning *::before,
  html.theme-transitioning *::after {
    transition:
      background-color 200ms ease,
      color 200ms ease,
      border-color 200ms ease !important;
  }

  /* ── Social links ─────────────────────────────────────────── */
  .social-links {
    display: flex;
    gap: 0.5rem;
    align-items: center;
  }

  .social-link {
    color: var(--muted);
    display: inline-flex;
    align-items: center;
    transition: color 0.1s;
    text-decoration: none;
  }

  .social-link:hover {
    color: var(--text);
    text-decoration: none;
  }

  .social-link svg {
    width: 1.1rem;
    height: 1.1rem;
  }

  /* ── Print styles ─────────────────────────────────────────── */
  @media print {
    /* Strip navigation chrome */
    .sidebar,
    .mobile-header,
    #reading-progress,
    .back-to-top,
    details.mobile-toc {
      display: none !important;
    }

    /* Full-width content — no sidebar to account for */
    .site-wrapper  { display: block; }
    .page-wrapper  { margin-left: 0; }
    .main-content  { padding: 0; max-width: 100%; }

    /* Sensible print typography */
    body {
      font-size: 11pt;
      line-height: 1.5;
      color: #000;
      background: #fff;
    }

    /* Don't break headings from their content */
    h1, h2, h3, h4 { break-after: avoid; }

    /* Keep code blocks and blockquotes together */
    pre, blockquote, figure { break-inside: avoid; }

    /* Show full URL after links (skip anchor-only and heading links) */
    .page-body a[href]:not([href^="#"])::after {
      content: " (" attr(href) ")";
      font-size: 0.8em;
      color: #555;
    }

    /* Suppress the # anchor link that appears in the rendered HTML */
    .heading-anchor { display: none; }

    /* Code: slightly smaller so it fits within page margins */
    pre, code { font-size: 9pt; }

    img { max-width: 100% !important; }

    /* Show post/project nav links in print */
    .post-nav {
      border-top: 1pt solid #ccc;
      padding-top: 0.5cm;
      margin-top: 0.5cm;
    }
  }
}
