@layer tokens, base, components, chrome, overrides;

/* theme.css — layered CSS entry point.
 * @layer tokens: Base16/24 palette system (formerly themes.css).
 *
 * ARCHITECTURE:
 *   1. :root defines convenience mappings (--bg-main etc.) that derive from
 *      the raw --base00..--base0F variables via var().
 *   2. Each theme/scheme only needs to set the 16 raw base vars.
 *   3. var() is resolved at use-time, so changing base vars cascades
 *      automatically to all convenience names.
 *
 * To add a new scheme: set --base00..--base0F in a [data-scheme="X"] rule.
 */

@layer tokens {
  :root {
    /* Backgrounds — base00/01/02 are the scheme's bg ladder (main → dim → active).
     * color-mix creates midpoints: hover between dim and active; hl-line subtler than dim. */
    --bg-main: var(--base00);
    --bg-dim: var(--base01);
    --bg-active: var(--base02);
    --bg-hover: var(--base02);
    --bg-hover: color-mix(
      in oklch,
      var(--base01) 50%,
      var(--base02)
    ); /* midpoint dim→active */
    --bg-hl-line: var(--base01);
    --bg-hl-line: color-mix(
      in oklch,
      var(--base00) 75%,
      var(--base01)
    ); /* subtler than dim */

    /* Foregrounds — base05/04/03 cover main/alt/dim; unfocused pushed further toward bg. */
    --fg-main: var(--base05);
    /* dim = a muted version of the real fg, not base03 (base16's comment slot, too
       faint: e.g. Nord base03 is 1.7:1 on its bg). 70% toward fg keeps it readable
       yet visibly dimmer on every scheme; base04 is the pre-color-mix fallback. */
    --fg-dim: var(--base04);
    --fg-dim: color-mix(in oklch, var(--base05) 70%, var(--base00));
    --fg-alt: var(--base04);

    /* Borders */
    --border: var(--base02);
    --border-highlight: var(--base0D);
    --border-dim: var(--base01);
    --border-dim: color-mix(
      in oklch,
      var(--base00) 55%,
      var(--base01)
    ); /* barely visible */

    /* Cursor */
    --cursor: var(--base05);

    /* Accent color families — three-tier system:
     *  1. var(--baseXX)       — old-browser fallback; tracks active scheme via JS
     *  2. color-mix(in oklch) — works without @supports; faint mixes toward bg,
     *                           warmer/cooler mix toward adjacent palette slots
     *  3. @supports block     — precise ±20° hue shifts in oklch perceptual space
     *
     * base08..base0E MUST stay as var() — JS sets these as hex for all 305 schemes. */

    --red: var(--base08);

    --green: var(--base0B);
    --green-faint: var(--base0B);
    --green-faint: color-mix(in oklch, var(--base0B) 85%, var(--base00));

    --yellow: var(--base0A);
    --yellow-faint: var(--base0A);
    --yellow-faint: color-mix(in oklch, var(--base0A) 85%, var(--base00));
    --yellow-cooler: var(--base0A);
    --yellow-cooler: color-mix(
      in oklch,
      var(--base0A) 80%,
      var(--base0B)
    ); /* → green */

    --blue: var(--base0D);
    --blue-faint: var(--base0D);
    --blue-faint: color-mix(in oklch, var(--base0D) 85%, var(--base00));

    --magenta: var(--base0E);

    --cyan: var(--base0C);
    --cyan-faint: var(--base0C);
    --cyan-faint: color-mix(in oklch, var(--base0C) 85%, var(--base00));
    --cyan-cooler: var(--base0C);
    --cyan-cooler: color-mix(
      in oklch,
      var(--base0C) 80%,
      var(--base0D)
    ); /* → blue */

    /* Modeline — no split-window; only one active buffer renders at a time. */
    --modeline-fg: var(--base05);
    --modeline-border: var(--base0D);

    /* Menu bar */
    --menu-bg: var(--base01);
    --menu-fg: var(--base05);
    --menu-border: var(--base02);
    --menu-hover-bg: var(--base02);
    --menu-hover-bg: color-mix(
      in oklch,
      var(--base01) 50%,
      var(--base02)
    ); /* distinct from border */
    --menu-active-bg: var(--base02);

    /* Fringe */
    --fringe-fg: var(--base03);

    /* Links */
    --link: var(--base0D);
    --link-visited: var(--base0E);
    --link-hover: var(--base0C);

    /* Syntax highlighting */
    --syntax-keyword: var(--base0E);
    --syntax-builtin: var(--base09);
    --syntax-string: var(--base0B);
    --syntax-comment: var(--base03); /* fallback */
    --syntax-comment: color-mix(in oklch, var(--base05) 70%, var(--base00));
    --syntax-function: var(--base0D);
    --syntax-variable: var(--base08);
    --syntax-constant: var(--base0E);
    --syntax-type: var(--base0C);
    --syntax-number: var(--base09);
    --syntax-operator: var(--base05);
    --syntax-preprocessor: var(--base08);

    /* Code blocks */
    --code-bg: var(--base01);
    --code-border: var(--base02);

    /* Selection */
    --selection-bg: var(--base02);
    --selection-fg: inherit;

    /* Scrollbar */
    --scrollbar-bg: var(--base01);
    --scrollbar-thumb: var(--base02);
    --scrollbar-thumb-hover: var(--base03);

    /* Article list */
    --list-selected-bg: var(--base02);
    --list-selected-fg: var(--base05);
    --list-hover-bg: var(--base01);
    --list-hover-bg: color-mix(
      in oklch,
      var(--base01) 60%,
      var(--base02)
    ); /* between dim and selected */

    /* Heading colors (h1–h4) */
    --h1-color: var(--base0E); /* violet   */
    --h2-color: var(--base09); /* orange   */
    --h3-color: var(--base0B); /* green    */
    --h4-color: var(--base08); /* red/pink */

    /* Content width — cycled by the width-toggle button */
    --content-max-width: 840px;

    /* Body font — cycled by font-mode button */
    --body-font-family: var(--code-font);
  }

  /* Scale tokens: spacing / radius / transition / type */
  :root {
    --space: 0.5em;
    --radius: 4px;
    --transition: 0.15s;
    --tracking-caps: 0.05em;
    --backdrop-dim: 30%;
    --backdrop-blur: 5px;
    --chrome-bg-opacity: 70%;
    --dialog-transition: 0.45s;

    --fs-base: 1rem;
    --fs-sm: calc(var(--fs-base) * 0.9);
    --fs-xs: calc(var(--fs-base) * 0.85);
    --fs-2xs: calc(var(--fs-base) * 0.8);
    --fs-3xs: calc(var(--fs-base) * 0.78);
    --fs-inline: 0.9em;
  }

  /* ── Precise oklch hue shifts (Chrome 119+ / Safari 16.4+ / Firefox 128+) ──────────────────
   * Overrides color-mix fallbacks above with ±20° rotation in perceptual oklch space.
   * Same L and C as the base — only hue changes, so lightness/chroma stay scheme-appropriate.
   * Directions chosen to match the color-mix targets: warmer → adjacent warm slot hue,
   * cooler → adjacent cool slot hue. green and cyan run opposite sign to red/blue/magenta
   * because green (142°) and cyan (200°) sit on the cool side of the hue circle. */
  @supports (color: oklch(from red l c h)) {
    :root {
      --yellow-cooler: oklch(
        from var(--base0A) l c calc(h + 20)
      ); /* → green  ~125° */
      --cyan-cooler: oklch(
        from var(--base0C) l c calc(h + 20)
      ); /* → blue   ~220° */
    }
  }

  /* ── Font mode cycling ──────────────────────────────────────────────── */
  [data-font="mono"] {
    --body-font-family: var(--code-font);
  }
  [data-font="sans"] {
    --body-font-family: var(--sans-font);
  }
  [data-font="serif"] {
    --body-font-family: var(--serif-font);
  }
  /* "Mixed" defaults prose to serif; structure/meta/UI overridden to sans
     below (@layer components, "Mixed font mode"). Code/pre/verbatim stay
     mono always, independent of font mode entirely (custom.css). */
  [data-font="mixed"] {
    --body-font-family: var(--serif-font);
  }

  /* ============================================================
     MODUS VIVENDI — dark default
     protesilaos.com/emacs/modus-themes
     ============================================================ */
  :root,
  [data-theme="dark"] {
    --base00: #000000; /* Default Background       */
    --base01: #1e1e1e; /* Lighter Background        */
    --base02: #323232; /* Selection Background      */
    --base03: #989898; /* Comments / Invisible      */
    --base04: #c6c6c6; /* Dark Foreground           */
    --base05: #ffffff; /* Default Foreground        */
    --base06: #ffffff; /* Light Foreground          */
    --base07: #ffffff; /* Light Background          */
    --base08: #ff5f59; /* Red                       */
    --base09: #feacd0; /* Orange (modus: pink)      */
    --base0A: #d0bc00; /* Yellow                    */
    --base0B: #44bc44; /* Green                     */
    --base0C: #00d3d0; /* Cyan                      */
    --base0D: #2fafff; /* Blue                      */
    --base0E: #b6a0ff; /* Violet / Purple           */
    --base0F: #ff9580; /* Deprecated / Brown        */

    /* Modus-specific semantic overrides (richer than pure base16 mapping) */
    --modeline-fg: oklch(
      0.94 0 0
    ); /* near-white, fixed contrast for dark modeline */
    --modeline-border: oklch(0.43 0 0); /* #626262 */
    --menu-bg: oklch(0.14 0 0); /* #1e1e1e */
    --code-bg: oklch(0.08 0.04 264); /* #0d0e1c — dark blue-tinted */
  }

  /* ============================================================
     MODUS OPERANDI — light
     ============================================================ */
  [data-theme="light"] {
    --base00: #ffffff; /* Default Background   */
    --base01: #f2f2f2; /* Lighter Background    */
    --base02: #d7d7d7; /* Selection Background  */
    --base03: #595959; /* Comments              */
    --base04: #193668; /* Dark Foreground       */
    --base05: #000000; /* Default Foreground    */
    --base06: #000000; /* Light Foreground      */
    --base07: #ffffff; /* Light Background      */
    --base08: #a60000; /* Red                   */
    --base09: #884900; /* Orange                */
    --base0A: #6f5500; /* Yellow                */
    --base0B: #006800; /* Green                 */
    --base0C: #005e8b; /* Cyan                  */
    --base0D: #0031a9; /* Blue                  */
    --base0E: #531ab6; /* Violet                */
    --base0F: #a0132f; /* Deprecated / Brown    */

    /* Modus operandi semantic overrides */
    --modeline-fg: oklch(
      0.18 0 0
    ); /* near-black, fixed contrast for light modeline */
    --modeline-border: oklch(0.67 0 0); /* #a3a3a3 */
    --menu-bg: var(--base01); /* #f2f2f2, fallback */
    --menu-bg: oklch(
      from var(--base01) l c h
    ); /* base-derived, no-op re-expression */
    --code-bg: var(--base01); /* fallback */
    --code-bg: oklch(
      from var(--base01) l calc(c + 0.02) 264
    ); /* base01 + slight blue tint, mirrors dark's tint direction */
  }
}

@layer base {
  :root {
    --menu-h: calc(2.3rem + env(safe-area-inset-top, 0px));
  }

  /* ── Reset ── */
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }
  * {
    margin: 0;
    padding: 0;
  }

  /* ── Skip to content (WCAG 2.4.1 Bypass Blocks) ── */
  .skip-link {
    position: absolute;
    inset-inline-start: 8px;
    inset-block-start: -100%;
    z-index: 1000;
    padding: var(--space);
    background: var(--bg-main);
    color: var(--fg-main);
    border: 1px solid var(--border-highlight);
    border-radius: 4px;
    text-decoration: none;
    &:focus {
      inset-block-start: 8px;
      outline: 2px solid var(--border-highlight);
      outline-offset: 2px;
    }
  }

  html {
    font-size: 100%;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Anchor jumps / focus / PageDown clear the fixed menu-bar (top) + modeline (bottom). */
    scroll-padding-top: var(--menu-h);
    scroll-padding-bottom: 3rem;
    @media (prefers-reduced-motion: no-preference) {
      scroll-behavior: smooth;
    }
  }

  body {
    font-family: var(--body-font-family, monospace);
    font-size: var(--fs-base);
    line-height: 1.6;
    background: var(--bg-main);
    color: var(--fg-main);
    /* dvh so mobile browser chrome doesn't leave a dead scroll region. */
    min-height: 100dvh;
    /* Reserve room for the fixed menu-bar (top) + fixed modeline (bottom). */
    padding-top: var(--menu-h);
    padding-bottom: 3rem;
  }

  /* Global button reset — components add only what differs. */
  button {
    cursor: pointer;
    font-family: inherit;
    font-size: inherit;
    background: none;
    border: none;
    padding: 0;
    color: inherit;
  }

  /* ── Frame: native document scroll; menu-bar + modeline pin the chrome. ── */
  .emacs-frame {
    display: block;
  }
  .buffer-container {
    display: block;
  }

  /* ── Scrollbar ── */
  ::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }
  ::-webkit-scrollbar-track {
    background: var(--scrollbar-bg);
  }
  ::-webkit-scrollbar-thumb {
    background: var(--scrollbar-thumb);
    &:hover {
      background: var(--scrollbar-thumb-hover);
    }
  }
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-bg);
  }

  /* ── Selection / links ── */
  ::selection {
    background: var(--selection-bg);
    color: var(--selection-fg);
  }
  ::target-text {
    background: var(--yellow-faint);
    color: var(--fg-main);
  }
  a {
    color: var(--link);
    text-decoration: none;
    &:visited {
      color: var(--link-visited);
    }
    &:hover {
      color: var(--link-hover);
      text-decoration: underline;
    }
  }
  /* WCAG 1.4.1 — prose links underlined regardless of scheme; chrome links stay plain
     (layout distinguishes them). */
  :is(.post-body, .references-list, .callout) a {
    text-decoration: underline;
    text-underline-offset: 0.15em;
    text-decoration-thickness: 1px;
    text-decoration-color: color-mix(in oklch, currentColor 45%, transparent);
    &:hover {
      text-decoration-color: currentColor;
    }
  }

  /* ── Typography ── */
  :is(h1, h2, h3, h4, h5, h6) {
    font-weight: bold;
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    line-height: 1.3;
    text-wrap: balance;
  }
  h1 {
    font-size: 1.5rem;
    @media (width <= 480px) {
      font-size: 1.25rem;
    }
  }
  h2 {
    font-size: 1.3rem;
    @media (width <= 480px) {
      font-size: 1.15rem;
    }
  }
  h3 {
    font-size: 1.15rem;
  }
  h4 {
    font-size: 1.05rem;
  }
  h5,
  h6 {
    font-size: var(--fs-base);
  }
  p {
    margin-bottom: 1em;
    text-wrap: pretty;
  }
  blockquote {
    border-left: 3px solid var(--border);
    padding-left: 1em;
    margin: var(--space);
    color: var(--fg-dim);
    font-style: italic;
  }
  :is(ul, ol) {
    margin: var(--space);
    padding-left: 2em;
  }
  li {
    margin-bottom: 0.25em;
  }
  code {
    font-family: var(--code-font, monospace);
    background: var(--code-bg);
    padding: var(--space);
    font-size: var(--fs-inline);
  }
  pre {
    background: var(--code-bg);
    border: 1px solid var(--code-border);
    padding: 1em;
    overflow-x: auto;
    margin: var(--space);
    line-height: 1.4;
    @media (width <= 480px) {
      font-size: 0.82rem;
    }
    & code {
      background: none;
      padding: 0;
    }
  }
  :is(img, video) {
    max-width: 100%;
    height: auto;
  }
  hr {
    width: 80%;
    margin: 2em auto;
    border: none;
    border-top: 1px dashed var(--border-dim);
  }
  figcaption {
    margin-bottom: 1rem;
    align-items: center;
    text-align: center;
  }
  .grid-block {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(120px, 1fr);
    gap: var(--space);
    margin: var(--space) 0;
    overflow-x: auto;
    & figure {
      margin: 0;
    }
    & img {
      width: 100%;
      aspect-ratio: 4 / 3;
      object-fit: contain;
    }
  }
  table {
    border-collapse: collapse;
    width: 100%;
    margin: var(--space);
    @media (width <= 480px) {
      font-size: var(--fs-xs);
    }
  }
  :is(th, td) {
    border: 1px solid var(--border);
    padding: var(--space);
    text-align: left;
  }
  th {
    background: var(--bg-dim);
  }

  /* ── Utilities ── */
  .hidden {
    display: none !important;
  }
  .visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
  }
  :is(button, a, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
  }
  /* Nerd Font glyph — font-family only; sizing/color set per context. */
  .nf {
    font-family:
      "Symbols Nerd Font Mono", "FiraCode Nerd Font", var(--code-font),
      monospace;
  }
}

@layer components {
  .post-body {
    text-align: left;
    -webkit-hyphens: none;
    hyphens: none;
    text-wrap: pretty;
    & p {
      margin-bottom: 1em;
    }
  }
  html[data-align="justify"] .post-body {
    text-align: justify;
    -webkit-hyphens: auto;
    hyphens: auto;
  }
  html[data-align="columns"] .post-body {
    column-width: 20rem;
    column-gap: 2.5rem;
    & :is(pre, table, figure, img, blockquote, .callout) {
      break-inside: avoid;
    }
  }

  /* ── Org-mode checkboxes & TODO ── */
  :is(li.checked, li.unchecked) {
    list-style: none;
    margin-left: -1.2em;
  }
  li.checked::before {
    content: " ";
    color: var(--green);
  }
  li.unchecked::before {
    content: "󱋭 ";
    color: var(--yellow);
  }
  /* org's own TODO-keyword output: <span class="todo TODO">/<span class="done DONE">. */
  :is(.todo, .done) {
    font-size: var(--fs-sm);
    font-weight: bold;
    padding: 0.1em 0.45em;
    margin-right: 0.5em;
    vertical-align: middle;
    letter-spacing: var(--tracking-caps);
  }
  .todo {
    background: var(--yellow);
    color: var(--bg-main);
  }
  .done {
    background: var(--green);
    color: var(--bg-main);
  }

  /* ── Sidenotes ── */
  .sidenote {
    float: right;
    clear: right;
    width: 11em;
    margin-right: -13em;
    margin-top: 0.1em;
    font-size: var(--fs-3xs);
    line-height: 1.5;
    color: var(--fg-dim);
    border-left: 2px solid var(--border-dim);
    padding-left: 0.6em;
    & p {
      margin: 0;
    }
    @media (width <= 900px) {
      float: none;
      width: auto;
      margin: 0.75em 0;
      border-left: none;
      border-top: 1px solid var(--border-dim);
      padding: 0.4em 0 0;
    }
  }

  /* ── Callouts ── */
  .callout {
    border-left: 3px solid var(--border);
    padding: var(--space);
    margin: var(--space);
    background: var(--bg-dim);
    font-size: var(--fs-sm);
    &::before {
      display: block;
      font-size: 0.75rem;
      font-weight: bold;
      letter-spacing: 0.06em;
      text-transform: uppercase;
      margin-bottom: 0.3em;
    }
    & p:last-child {
      margin-bottom: 0;
    }
  }
  .callout-note {
    border-left-color: var(--blue);
    &::before {
      content: "Note";
      color: var(--blue);
    }
  }
  .callout-tip {
    border-left-color: var(--green);
    &::before {
      content: "Tip";
      color: var(--green);
    }
  }
  .callout-warn {
    border-left-color: var(--yellow);
    &::before {
      content: "Warning";
      color: var(--yellow);
    }
  }

  /* ── Comments ── */
  .post-comment {
    margin-top: 3em;
    padding-top: 1.5em;
    border-top: 2px solid var(--border-dim);
  }
  /* display:block :: it is a <label>, which is inline by default; the margin below
     only applies as it did when this was a <p>. */
  .comment-label {
    display: block;
    font-size: var(--fs-xs);
    color: var(--fg-dim);
    margin-bottom: 0.75em;
    text-transform: uppercase;
    letter-spacing: var(--tracking-caps);
  }
  .comment-textarea {
    width: 100%;
    min-height: 7em;
    resize: vertical;
    background: var(--bg-dim);
    color: var(--fg-main);
    border: 1px solid var(--border-dim);
    padding: 0.6em 0.75em;
    font-family: inherit;
    font-size: var(--fs-sm);
    &:focus {
      outline: none;
      border-color: var(--border-highlight);
    }
  }
  .comment-actions {
    display: flex;
    align-items: center;
    gap: 1em;
    margin-top: 0.5em;
    @media (width <= 480px) {
      flex-direction: column;
      align-items: flex-start;
    }
  }
  .comment-submit {
    background: var(--bg-active);
    border: 1px solid var(--border-highlight);
    padding: 0.4em 1em;
    font-size: var(--fs-xs);
    &:hover {
      background: var(--border-highlight);
      color: var(--bg-main);
    }
    @media (width <= 480px) {
      width: 100%;
    }
  }
  .comment-hint {
    font-size: 0.75rem;
    color: var(--fg-dim);
    opacity: 0.6;
  }
}

@layer components {
  /* ── Code blocks (Emacs-style header + Chroma) ── */
  pre {
    position: relative;
    background-color: var(--code-bg);
    border: 1px solid var(--code-border);
    border-radius: 0;
    padding: 0;
    margin: var(--space);
    overflow: hidden;
    &::before {
      content: attr(data-lang);
      display: block;
      padding: 0.25em 1em;
      background-color: var(--bg-dim);
      border-bottom: 1px solid var(--code-border);
      color: var(--fg-dim);
      font-size: var(--fs-2xs);
      text-transform: lowercase;
    }
    &:not([data-lang])::before {
      display: none;
    }
    & code {
      display: block;
      padding: 1em;
      overflow-x: auto;
      background: none;
      font-size: var(--fs-sm);
      line-height: 1.5;
    }
  }

  .code-copy-btn {
    position: absolute;
    top: 0.3em;
    right: 0.5em;
    z-index: 2;
    padding: 0.15em 0.6em;
    border: 1px solid var(--border-dim);
    border-radius: var(--radius);
    background: var(--bg-dim);
    color: var(--fg-dim);
    font-size: 0.72rem;
    font-family: var(--code-font);
    opacity: 0;
    transition:
      opacity var(--transition),
      color var(--transition),
      border-color var(--transition);
    &:hover {
      color: var(--fg-main);
      border-color: var(--border-highlight);
    }
    &.copied {
      color: var(--green);
      border-color: var(--green);
      opacity: 1;
    }
  }
  pre:is(:hover, :focus-within) .code-copy-btn,
  .code-copy-btn:focus-visible {
    opacity: 1;
  }

  /* ── Chroma syntax highlighting (Hugo default classes) ── */
  .highlight {
    background-color: var(--code-bg);
    margin: var(--space);
    & pre {
      margin: 0;
      border: 1px solid var(--code-border);
    }
    & :is(.ln, .lnt) {
      color: var(--fringe-fg);
      padding-right: 1em;
      user-select: none;
    }
    & .lnt {
      margin-right: 0.5em;
    }
    & .hl {
      display: block;
      background-color: var(--bg-hl-line);
    }
    & .err {
      color: var(--red);
      background-color: transparent;
    }
    & .lnlinks {
      text-decoration: none;
      color: inherit;
    }
    /* keywords */
    & :is(.k, .kc, .kd, .kn, .kp, .kr, .kt) {
      color: var(--syntax-keyword);
      font-weight: bold;
    }
    /* names / identifiers */
    & .n {
      color: var(--fg-main);
    }
    & .na {
      color: var(--syntax-variable);
    }
    & .nb {
      color: var(--syntax-builtin);
    }
    & .nc {
      color: var(--syntax-type);
      font-weight: bold;
    }
    & .no {
      color: var(--syntax-constant);
    }
    & .nd {
      color: var(--syntax-preprocessor);
    }
    & .ni {
      color: var(--yellow);
    }
    & .ne {
      color: var(--red);
      font-weight: bold;
    }
    & .nf {
      color: var(--syntax-function);
    }
    & .nl {
      color: var(--cyan);
    }
    & .nn {
      color: var(--syntax-type);
    }
    & .nt {
      color: var(--syntax-keyword);
    }
    & :is(.nv, .nx) {
      color: var(--syntax-variable);
    }
    /* literals */
    & .l {
      color: var(--blue);
    }
    & .ld {
      color: var(--green);
    }
    /* strings */
    & :is(.s, .sa, .sb, .sc, .dl, .sd, .s2, .se, .sh, .si, .sx, .sr, .s1, .ss) {
      color: var(--syntax-string);
    }
    /* numbers */
    & :is(.m, .mb, .mf, .mh, .mi, .il, .mo) {
      color: var(--syntax-number);
    }
    /* operators */
    & :is(.o, .ow) {
      color: var(--syntax-operator);
    }
    /* punctuation */
    & .p {
      color: var(--fg-main);
    }
    /* comments */
    & :is(.c, .ch, .cm, .c1, .cs) {
      color: var(--syntax-comment);
      font-style: italic;
    }
    & .cp {
      color: var(--syntax-preprocessor);
      font-style: normal;
    }
    & .cpf {
      color: var(--syntax-string);
    }
    /* generic */
    & .gd {
      color: var(--red);
      background-color: color-mix(in oklch, var(--red) 12%, transparent);
    }
    & .ge {
      font-style: italic;
    }
    & .gr {
      color: var(--red);
    }
    & .gh {
      color: var(--magenta);
      font-weight: bold;
    }
    & .gi {
      color: var(--green);
      background-color: color-mix(in oklch, var(--green) 12%, transparent);
    }
    & .go {
      color: var(--fg-dim);
    }
    & .gp {
      color: var(--cyan);
      font-weight: bold;
    }
    & .gs {
      font-weight: bold;
    }
    & .gu {
      color: var(--blue);
      font-weight: bold;
    }
    & .gt {
      color: var(--red);
    }
  }

  /* ── Org-mode source blocks ── */
  .org-src-container {
    margin: var(--space);
    & pre {
      margin: 0;
    }
  }
  .org-block-begin-line,
  .org-block-end-line {
    color: var(--fg-dim);
    font-size: var(--fs-xs);
    padding: var(--space);
    background-color: var(--bg-dim);
    border: 1px solid var(--code-border);
  }
  .org-block-begin-line {
    border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0;
  }
  .org-block-end-line {
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
  }

  /* ── Inline code ── */
  code:not(pre code) {
    background-color: var(--code-bg);
    padding: var(--space);
    border-radius: var(--radius);
    font-size: var(--fs-inline);
    color: var(--cyan);
  }
  .org-verbatim {
    background-color: var(--code-bg);
    padding: var(--space);
    color: var(--green);
  }
  .org-code {
    background-color: var(--code-bg);
    padding: var(--space);
    color: var(--cyan);
  }
}

@layer components {
  /* ── Buffer frame: native document scroll, buffers are plain blocks ── */
  .buffer {
    display: none;
    min-width: 0;
  }
  .buffer.active {
    display: block;
  }
  .buffer-body {
    overflow-x: hidden;
  }

  /* ── Article list (Dired-style) ── */
  .article-list {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  .article-list.similar-posts {
    margin-top: 2em;
    border-top: 1px solid var(--border-dim);
    padding-top: 0.5em;
  }

  .article-item {
    display: flex;
    align-items: baseline;
    cursor: pointer;
    font-size: var(--fs-sm);
    background: var(--bg-dim);
    border: 1px solid var(--border-dim);
    border-left: 2px solid transparent;
    border-radius: var(--radius);
    box-shadow: 0 1px 3px color-mix(in oklch, black 12%, transparent);
    margin-bottom: var(--space);
    padding: 0.15em 0.3em;
    transition:
      border-color var(--transition),
      background-color var(--transition);
    &:last-child {
      margin-bottom: 0;
    }
    &:is(:hover, :focus-within) {
      border-left-color: var(--cursor);
      background: var(--list-hover-bg);
    }
    &.no-articles {
      color: var(--fg-dim);
      padding: 1em;
    }
  }

  .article-meta {
    display: flex;
    gap: 1em;
    font-size: var(--fs-xs);
    flex-shrink: 0;
    margin-right: 1em;
  }
  .article-reading-time {
    color: var(--cyan-faint);
  }
  .article-date {
    width: 7em;
    color: var(--yellow-faint);
  }
  .article-title {
    flex: 1;
    white-space: normal;
    word-wrap: break-word;
    color: var(--fg-main);
  }
  .article-item:is(:hover, :focus-within) .article-title {
    text-decoration: underline;
  }

  .article-link {
    display: flex;
    align-items: baseline;
    flex: 1;
    min-width: 0;
    text-decoration: none;
    color: inherit;
    padding: 0.35em 0.75em;
    &:is(:hover, :focus-visible, :visited) {
      text-decoration: none;
      color: inherit;
    }
  }

  .article-type-icon {
    width: 1.4em;
    text-align: center;
    flex-shrink: 0;
    color: var(--fg-dim);
    font-size: 0.85em;
    margin-right: 0.5em;
  }

  .nf-sm {
    font-size: 0.85em;
    opacity: 0.7;
    margin-right: 0.2em;
  }

  /* ── Post content ── */
  .post-content {
    width: 100%;
    max-width: var(--content-max-width, 840px);
    padding: 1em 2em;
    margin: 0 auto;
    box-sizing: border-box;
  }

  .breadcrumbs {
    font-size: var(--fs-2xs);
    color: var(--fg-dim);
    margin-bottom: 1.5em;
    opacity: 0.75;
    & a {
      color: var(--fg-dim);
      text-decoration: none;
    }
    & a:is(:hover, :focus-visible) {
      color: var(--link);
    }
  }
  .breadcrumb-sep {
    margin: 0 0.3em;
    opacity: 0.5;
  }
  .breadcrumb-current {
    color: var(--fg-main);
    opacity: 0.6;
  }

  @keyframes read-progress-fill {
    from {
      transform: scaleX(0);
    }
    to {
      transform: scaleX(1);
    }
  }
  .read-progress {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1;
    height: 2px;
    background: var(--blue);
    transform-origin: 0 50%;
    transform: scaleX(0);
    will-change: transform;
  }
  @supports (animation-timeline: scroll(root)) {
    .read-progress {
      animation: read-progress-fill linear;
      animation-duration: 1ms;
      animation-timeline: scroll(root);
    }
  }

  .post-header {
    margin-bottom: 2em;
    padding-bottom: 1em;
    border-bottom: 1px solid var(--border-dim);
  }
  .post-title {
    font-size: 1.5rem;
    color: var(--magenta);
    margin: 0 0 0.5em;
  }
  .post-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1em;
    font-size: var(--fs-sm);
    color: var(--fg-dim);
  }
  .post-date {
    color: var(--yellow);
  }
  .post-date-updated {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    color: var(--yellow-faint);
    cursor: help;
  }
  .post-reading-time {
    color: var(--cyan);
  }
  .post-tags {
    display: flex;
    gap: 0.5em;
    flex-wrap: wrap;
  }
  .post-tag {
    color: var(--blue);
    &::before {
      content: "#";
      color: var(--fg-dim);
    }
  }

  .table-of-contents {
    background: var(--bg-dim);
    border: 1px solid var(--border-dim);
    padding: 1em;
    margin: var(--space);
    & h2 {
      font-size: var(--fs-base);
      margin: 0 0 0.5em;
      color: var(--fg-main);
    }
    & nav ul {
      margin: 0;
      padding-left: 1.5em;
    }
    & nav li {
      margin-bottom: 0.25em;
    }
  }

  .post-body {
    line-height: 1.7;
    & h2 {
      margin-top: 2em;
    }
    & h3 {
      margin-top: 1.5em;
    }
    & :is(ul, ol, pre, blockquote) {
      margin-bottom: 1em;
    }
    & img {
      display: block;
      margin: 1em auto;
      max-width: 100%;
      cursor: zoom-in;
    }
    /* #+begin_center/left/right and captioned images (org defaults). */
    & :is(.org-center, .figure) {
      text-align: center;
    }
    & .org-left {
      text-align: left;
    }
    & .org-right {
      text-align: right;
    }
    /* org's own _underlined_ text; distinct from the menu bar's .underline. */
    & .underline {
      text-decoration: underline;
    }
  }

  /* Shared by .post-body headings, Pose cards, and the Pose dialog title. */
  :is(:is(.post-body, .pose-card) :is(h2, h3, h4, h5, h6), #pose-dialog-title) .heading-anchor {
    /* Stays above the Pose card's full-card click overlay (.pose-card-trigger). */
    position: relative;
    z-index: 1;
    margin-left: 0.4em;
    font-size: 0.75em;
    color: var(--fg-dim);
    text-decoration: none;
    opacity: 0;
    transition:
      opacity var(--transition),
      color var(--transition);
  }
  :is(:is(.post-body, .pose-card) :is(h2, h3, h4, h5, h6), #pose-dialog-title):hover .heading-anchor,
  :is(.post-body, .pose-card, #pose-dialog-title) .heading-anchor:focus-visible {
    opacity: 1;
  }
  :is(.post-body, .pose-card, #pose-dialog-title) .heading-anchor:hover {
    color: var(--link);
  }

  /* ── List page layout ── */
  .list-content {
    max-width: var(--content-max-width, 840px);
    margin: 0 auto;
    width: 100%;
    display: flex;
    flex-direction: column;
    min-height: 100%;
  }
  .list-content .list-footer {
    margin-top: auto;
  }

  .year-divider {
    display: flex;
    align-items: center;
    padding: 0.5em 0.75em 0.25em;
    pointer-events: none;
    user-select: none;
    border-bottom: 1px solid var(--border-dim);
    margin-top: 1.25em;
    &:first-child {
      margin-top: 0;
    }
  }
  .year-label {
    font-weight: bold;
    color: var(--magenta);
    letter-spacing: var(--tracking-caps);
    opacity: 0.9;
  }
  .year-count {
    margin-left: 0.5em;
    font-size: 0.75em;
    font-weight: normal;
    color: var(--fg-dim);
    opacity: 0.7;
  }

  /* ── References / citations ── */
  .post-navigation {
    margin-top: 3em;
    padding-top: 1em;
    border-top: 1px solid var(--border-dim);
    & > div {
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
      gap: 1em;
      /* The lone spacer <span> between prev/next; grows to push a single
         link to its own side rather than both sitting flush left. */
      & > span {
        flex: 1;
      }
    }
    & a {
      color: var(--link);
      text-decoration: none;
    }
    & a:is(:hover, :focus-visible) {
      color: var(--link-hover);
    }
  }

  .references {
    margin-top: 3em;
    padding-top: 1em;
    border-top: 1px solid var(--border-dim);
  }
  .references-title {
    font-size: 1.1rem;
    color: var(--fg-dim);
    margin-bottom: 0.5em;
  }
  .references-list {
    margin: 0;
    padding-left: 1.6em;
    display: flex;
    flex-direction: column;
    gap: 0.3em;
    & li {
      color: var(--fg-dim);
      font-size: var(--fs-sm);
    }
    & a {
      color: var(--blue);
      overflow-wrap: anywhere;
    }
  }
  .references-url {
    color: var(--fg-dim);
    opacity: 0.65;
    margin-left: 0.5em;
    font-size: 0.85em;
  }

  .term-header {
    display: flex;
    align-items: baseline;
    gap: 0.5em;
    padding: var(--space);
    border-bottom: 1px solid var(--border-dim);
    background: var(--bg-dim);
  }
  .term-tag-name {
    font-size: 1.1rem;
    font-weight: bold;
    color: var(--cyan-cooler);
  }
  .term-back {
    margin-left: auto;
    font-size: var(--fs-2xs);
    color: var(--yellow-cooler);
    text-decoration: none;
    opacity: 0.8;
    &:is(:hover, :focus-visible) {
      opacity: 1;
      text-decoration: underline;
    }
  }

  .tag-cloud {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35em;
    padding: var(--space);
    border-bottom: 1px solid var(--border-dim);
    background: var(--bg-dim);
  }
  .tag-cloud-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.25em;
    padding: 0.15em 0.5em;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--fg-dim);
    font-size: var(--fs-3xs);
    transition:
      color var(--transition),
      border-color var(--transition),
      background var(--transition);
    &:is(:hover, :focus-visible) {
      color: var(--cyan-cooler);
      border-color: var(--cyan-cooler);
      background: var(--bg-active);
    }
    &.active {
      border-color: var(--cursor);
      background: var(--bg-hl-line);
      color: var(--cursor);
    }
  }
  /* view-toggle is a real checkbox styled as a .tag-cloud-btn (see markup);
     the label picks up the active look straight off :checked, no JS class. */
  .view-toggle-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
    &:checked + .tag-cloud-btn {
      border-color: var(--cursor);
      background: var(--bg-hl-line);
      color: var(--cursor);
    }
    &:focus-visible + .tag-cloud-btn {
      outline: 2px solid var(--blue);
      outline-offset: 2px;
    }
  }
  .tag-cloud-count {
    font-size: 0.7em;
    color: var(--fg-dim);
    opacity: 0.85;
  }

  .list-search {
    display: flex;
    align-items: center;
    gap: 0.6em;
    padding: 0.7em 1em;
    border: 1px solid var(--border-highlight);
    border-radius: 0.3em;
    margin: 1.5em 0;
    background: var(--bg-main);
    font-size: var(--fs-sm);
  }
  .list-search-prompt {
    color: var(--cyan-cooler);
    flex-shrink: 0;
    font-weight: bold;
  }
  .list-search-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--fg-main);
    font-family: inherit;
    font-size: inherit;
    caret-color: var(--cursor);
    &::placeholder {
      color: var(--fg-dim);
      opacity: 0.6;
    }
  }
  .list-search-count {
    color: var(--yellow-cooler);
    font-size: var(--fs-2xs);
    flex-shrink: 0;
  }

  .list-footer {
    border-top: 1px solid var(--border-dim);
    padding: 0.75em 1em;
    color: var(--fg-dim);
    text-align: center;
    & a {
      color: var(--cyan-cooler);
      text-decoration: none;
    }
    & a:is(:hover, :focus-visible) {
      text-decoration: underline;
    }
    & .craftering {
      margin: 0.25em 0;
    }
  }

  .social-links {
    display: flex;
    flex-direction: column;
    gap: 0.6em;
    margin: var(--space);
  }
  .social-links.is-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    align-items: start;
  }
  .social-link {
    display: inline-flex;
    align-items: center;
    gap: 0.6em;
    color: var(--fg-main);
    text-decoration: none;
    padding: var(--space);
    border-left: 2px solid transparent;
    transition:
      border-color var(--transition),
      background var(--transition);
    &:is(:hover, :focus-visible) {
      border-left-color: var(--cursor);
      background: var(--bg-active);
      text-decoration: none;
      color: var(--fg-main);
    }
  }
  .social-label {
    font-size: var(--fs-inline);
    color: var(--fg-dim);
  }

  /* ── Wander listing ── */
  .wander-launch {
    display: flex;
    align-items: center;
    gap: 1em;
    padding: 0.75em 0.75em;
    border-bottom: 1px solid var(--border-dim);
    margin-bottom: 0.5em;
  }
  .wander-hint {
    flex: 1;
    font-size: var(--fs-xs);
    color: var(--fg-dim);
  }
  .wander-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    padding: 0.3em 0.9em;
    border: 1px solid var(--border);
    color: var(--cyan-cooler);
    background: var(--bg-dim);
    text-decoration: none;
    font-size: var(--fs-xs);
    transition: border-color var(--transition);
    &:is(:hover, :focus-visible) {
      border-color: var(--cyan-cooler);
    }
  }
  .wander-list .article-title {
    flex: 1;
  }
  .wander-list .article-date {
    flex: 1;
    width: auto;
    color: var(--blue);
  }
  .wander-desc {
    font-size: var(--fs-xs);
    color: var(--fg-alt);
    min-width: 0;
  }

  /* ── Topic listing (wander, projects, media, …) ── */
  /* The whole card is one click target. HTML forbids nesting <a> inside <a>, so
     the title anchor is *stretched* over the card with a transparent ::after
     instead of wrapping it :: one link, one tab stop, and the tag/ref links stay
     real separate links above the overlay. Card needs position: relative to be
     the overlay's containing block.
     Known tradeoff: the overlay sits over the description, so drag-selecting that
     text no longer works. Pure CSS has no fix for that; JS would be needed. */
  .topic-item {
    align-items: flex-start;
    position: relative;
  }
  /* Plain-text term, no <dt> link (parse-dl.html only sets data-url when one
     exists) — the card isn't a click target, so it shouldn't look like one. */
  .topic-item:not([data-url]) {
    cursor: default;
    &:is(:hover, :focus-within) {
      border-left-color: transparent;
      background: none;
    }
  }
  .topic-item .article-link {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15em;
  }
  .topic-item .project-name::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
  }
  /* Anything clickable inside the card must sit above the overlay, or the overlay
     swallows its clicks. .wander-desc is author HTML and may contain links. */
  .topic-item :is(.project-ref-link, .project-tag, .wander-desc a) {
    position: relative;
    z-index: 1;
  }
  /* Card hover/focus also recolours the title. The underline itself comes from
     the shared .article-item rule above, which every listing gets. */
  .topic-item:is(:hover, :focus-within) .project-name {
    color: var(--cyan-cooler);
  }

  /* Topic pages: grid / card view. Native checkbox + :has(), no JS to show it —
     #view-toggle's checked state is read straight off the DOM; a tiny JS shim
     (topic-list-js.html) only persists the choice across page loads. */
  #article-content:has(#view-toggle:checked) .article-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.6em;
    padding: var(--space);
  }
  #article-content:has(#view-toggle:checked) .article-list .year-divider {
    grid-column: 1 / -1;
  }
  #article-content:has(#view-toggle:checked) .article-list .topic-item {
    padding: 0.6em 0.8em;
  }
  #article-content:has(#view-toggle:checked) .article-list .topic-item:hover {
    border-color: var(--border-highlight);
    background: var(--bg-active);
  }

  /* ── /themes gallery — scheme cards (extends .topic-item / grid view) ── */
  .scheme-card {
    display: block;
  }
  #article-content:has(#view-toggle:checked) .article-list .scheme-card {
    content-visibility: auto;
    contain-intrinsic-size: 0 130px;
  }
  .scheme-card-btn {
    display: flex;
    flex-direction: column;
    gap: 0.4em;
    width: 100%;
    padding: 0;
    text-align: left;
  }
  .scheme-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5em;
  }
  .scheme-card-name {
    font-weight: bold;
    color: var(--fg-main);
  }
  .scheme-card-variant {
    font-size: 0.7rem;
    padding: 0.1em 0.5em;
    border-radius: var(--radius);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fg-dim);
    border: 1px solid var(--border-dim);
  }
  .scheme-card-swatches {
    display: flex;
    gap: 0.15em;
  }
  .scheme-card-swatches .swatch {
    width: 1rem;
    height: 1rem;
    border-radius: var(--radius);
    flex-shrink: 0;
  }
  .scheme-card-author {
    font-size: var(--fs-3xs);
    color: var(--fg-dim);
    text-decoration: none;
    &:is(:hover, :focus-visible) {
      color: var(--cyan-cooler);
      text-decoration: underline;
    }
  }

  .project-left {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 2.5em;
    flex-shrink: 0;
    gap: 0.25em;
    padding: 0.3em 0;
  }
  .project-icon {
    text-align: center;
    color: var(--fg-dim);
    font-size: 1em;
  }
  .project-header {
    display: block;
    width: 100%;
    line-height: 1.4;
  }
  .project-header .article-title {
    display: inline;
  }
  .project-name {
    color: inherit;
    text-decoration: none;
    &:is(:hover, :focus-visible) {
      color: var(--cyan-cooler);
    }
  }
  .project-refs {
    display: inline-flex;
    gap: 0.2em;
    vertical-align: middle;
  }
  .project-ref-link {
    font-size: 0.72rem;
    font-family: var(--code-font);
    color: var(--chip-color, var(--fg-dim));
    text-decoration: none;
    opacity: 0.75;
    &:is(:hover, :focus-visible) {
      opacity: 1;
      text-decoration: underline;
    }
  }
  .project-tags {
    display: flex;
    gap: 0.3em;
    flex-wrap: wrap;
    margin-top: 0.1em;
  }
  .project-tag {
    font-size: 0.72rem;
    padding: 0.05em 0.4em;
    background: var(--bg-dim);
    border: 1px solid var(--chip-color, var(--border-dim));
    color: var(--chip-color, var(--cyan));
    font-family: var(--code-font);
    text-decoration: none;
  }
  a.project-tag:is(:hover, :focus-visible) {
    opacity: 0.8;
    text-decoration: underline;
  }
}

@layer chrome {
  /* ── Menu bar (fixed top; mirrors the fixed modeline) ── */
  .menu-bar {
    view-transition-name: menu-bar;
    display: flex;
    flex-direction: row;
    align-items: center;
    background: color-mix(
      in oklch,
      var(--menu-bg) var(--chrome-bg-opacity),
      transparent
    );
    backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
    -webkit-backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
    border-bottom: 1px solid var(--menu-border);
    padding: 0;
    font-size: var(--fs-sm);
    user-select: none;
    /* Fixed so it never moves/jitters during momentum scroll. body reserves the
       space with padding-top: var(--menu-h), and this height makes the bar match
       that token exactly — border-box, so the 1px border and the notch padding
       below are both inside it. */
    height: var(--menu-h);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    flex-wrap: nowrap;
    /* Own compositor layer: content scrolls under without repainting the bar. */
    will-change: transform;
    /* iOS notch: keep content below the safe-area inset (0 elsewhere). */
    padding-top: env(safe-area-inset-top, 0);
  }
  .menu-items {
    display: flex;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
  }

  /* Menus are <details>: open/closed and one-at-a-time (name="menu") are
     native, no JS. Positioning stays exactly the old absolute-under-a-
     relative-ancestor trick — <details> content is normal flow, unlike a
     popover, so nothing here needed to change for that. */
  .menu-item {
    position: relative;
    display: inline-block;
    & > summary {
      display: flex;
      align-items: center;
      padding: 0.4em 0.8em;
      color: var(--menu-fg);
      cursor: pointer;
      list-style: none;
      transition: background-color var(--transition);
      &::-webkit-details-marker {
        display: none;
      }
      & .underline {
        text-decoration: underline;
      }
    }
    & > summary:is(:hover, :focus-visible) {
      background: var(--menu-hover-bg);
    }
    &[open] > summary {
      background: var(--menu-active-bg);
    }
  }

  .menu-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 200px;
    background: var(--menu-bg);
    border: 1px solid var(--menu-border);
    box-shadow: 2px 2px 8px color-mix(in oklch, black 30%, transparent);
    z-index: 1000;
  }
  .menu-dropdown-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2em;
    padding: 0.4em 1em;
    color: var(--menu-fg);
    transition: background-color var(--transition);
    width: 100%;
    /* Keep label left + shortcut right on one line; dropdown widens to fit. */
    white-space: nowrap;
    text-align: left;
    &:is(:hover, :focus-visible) {
      background: var(--menu-hover-bg);
    }
    &.disabled {
      color: var(--fg-dim);
      pointer-events: none;
    }
  }
  .menu-shortcut {
    color: var(--fg-dim);
    font-size: 0.85em;
    margin-left: 2em;
  }
  .menu-separator {
    height: 1px;
    background: var(--menu-border);
    margin: 0.25em 0;
  }

  .menu-bar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    padding-right: 0.5em;
  }

  /* Scheme option — preview colours from inline CSS vars */
  .scheme-option {
    background: var(--p-bg, var(--menu-bg));
    color: var(--p-fg, var(--menu-fg));
    gap: 0.5em;
    &:is(:hover, :focus-visible) {
      filter: brightness(1.15);
    }
    &.active .scheme-dot {
      background: var(--p-accent, currentColor);
    }
  }
  .scheme-dot {
    width: 0.55em;
    height: 0.55em;
    border-radius: 50%;
    border: 1.5px solid var(--p-accent, currentColor);
    background: transparent;
    flex-shrink: 0;
    transition: background var(--transition);
  }

  .scheme-popup-actions {
    display: flex;
    border-top: 1px solid var(--menu-border);
  }
  .scheme-action-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.3em;
    padding: 0.4em 0.6em;
    color: var(--fg-dim);
    font-size: 0.82rem;
    transition:
      background var(--transition),
      color var(--transition);
    &:is(:hover, :focus-visible) {
      background: var(--menu-hover-bg);
      color: var(--fg-main);
    }
    & + .scheme-action-btn {
      border-left: 1px solid var(--menu-border);
    }
  }

  .scheme-popup-container {
    position: relative;
  }
  .menu-bar-btn,
  .scheme-popup-btn {
    display: flex;
    align-items: center;
    padding: 0.3em 0.55em;
    border: 1px solid var(--border-dim);
    border-radius: var(--radius);
    color: var(--fg-dim);
    font-family: "Symbols Nerd Font Mono", inherit;
    font-size: var(--fs-sm);
    transition:
      background var(--transition),
      color var(--transition),
      border-color var(--transition);
    margin-left: 0.3em;
  }
  /* .scheme-popup-btn is a <summary> — same marker removal as .menu-item's. */
  .scheme-popup-btn {
    cursor: pointer;
    list-style: none;
    &::-webkit-details-marker {
      display: none;
    }
  }
  :is(.menu-bar-btn, .scheme-popup-btn):is(
    :hover,
    :focus-visible,
    [aria-expanded="true"]
  ) {
    background: var(--menu-hover-bg);
    color: var(--fg-main);
    border-color: var(--border);
  }

  .scheme-popup {
    position: absolute;
    top: calc(100% + 2px);
    right: 0;
    min-width: 180px;
    background: var(--menu-bg);
    border: 1px solid var(--menu-border);
    box-shadow: 2px 4px 12px color-mix(in oklch, black 40%, transparent);
    z-index: 1001;
    overflow: hidden;
  }

  /* Backdrop */
  .menu-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: color-mix(in oklch, black var(--backdrop-dim), transparent);
    backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
    -webkit-backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
    z-index: 198;
    &.visible {
      display: block;
    }
  }

  /* Theme toggle icons — CSS-driven */
  :root .theme-icon-light,
  [data-theme="dark"] .theme-icon-light {
    display: none;
  }
  [data-theme="light"] .theme-icon-dark {
    display: none;
  }
  [data-theme="light"] .theme-icon-light {
    display: inline;
  }

  /* Site title */
  .menu-bar-title {
    color: var(--fg-dim);
    font-size: var(--fs-xs);
    padding: 0 1em;
    text-decoration: none;
    &:is(:hover, :focus-visible) {
      color: var(--fg-main);
    }
  }

  /* ── Hamburger ── */
  .menu-hamburger {
    display: none;
    padding: 0.5em;
    color: var(--menu-fg);
    font-size: 1.2rem;
    &:is(:hover, :focus-visible) {
      background: var(--menu-hover-bg);
    }
  }
}

@layer chrome {
  /* ── Modeline (fixed bottom; Emacs mode-line) ── */
  .modeline {
    view-transition-name: modeline;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    padding: 0.8em 1.5em 0.8em 0.4em;
    /* iOS home indicator: keep the bar above the safe-area inset. */
    padding-bottom: max(0.8em, env(safe-area-inset-bottom, 0));
    background-color: color-mix(
      in oklch,
      var(--bg-dim) var(--chrome-bg-opacity),
      transparent
    );
    backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
    -webkit-backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
    color: var(--modeline-fg);
    font-family: var(--code-font), monospace;
    font-size: 0.82rem;
    border-top: 1px solid var(--modeline-border);
    white-space: nowrap;
    overflow: hidden;
    min-height: 1.9em;
    user-select: none;
    /* Static during scroll (no per-frame JS writes): containment + own layer so
       content scrolls under it without repainting the page. */
    contain: layout paint;
    will-change: transform;
    @media (width <= 768px) {
      padding: 0.2em 0.5em;
      font-size: var(--fs-3xs);
      padding-bottom: max(0.2em, env(safe-area-inset-bottom, 0));
    }
  }

  .ml-left {
    display: flex;
    align-items: center;
    overflow: hidden;
    flex-shrink: 1;
    min-width: 0;
    gap: 0.3ch;
  }
  .ml-group {
    display: flex;
    align-items: center;
    gap: 0.3ch;
    white-space: nowrap;
  }
  .ml-fill {
    flex: 1;
    min-width: 0.5em;
  }
  .ml-right {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    gap: 0.5ch;
  }

  /* Buffer/title name — button that opens the palette */
  .ml-buffer {
    font-weight: 600;
    color: var(--modeline-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: none;
    border: none;
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
    padding: 0;
    &:hover {
      text-decoration: underline;
      background: var(--bg-hover);
    }
    @media (width <= 768px) {
      max-width: 20ch;
    }
  }

  .ml-pin-btn {
    color: var(--fg-dim);
    opacity: 0.7;
    transition:
      opacity var(--transition),
      color var(--transition);
    border-radius: var(--radius);
    padding: 0 0.4ch;
    &:hover {
      opacity: 1;
      color: var(--fg-main);
    }
    &.pinned {
      color: var(--yellow);
      opacity: 1;
    }
  }

  .ml-hide-mobile {
    display: inline-flex;
    @media (width <= 768px) {
      display: none !important;
    }
  }

  .ml-sep {
    color: var(--modeline-border);
    padding: 0 1ch;
    flex-shrink: 0;
    @media (width <= 768px) {
      padding: 0 0.3ch;
    }
  }
  .ml-date-icon {
    color: var(--yellow-faint);
    font-size: var(--fs-inline);
  }
  .ml-wc {
    color: var(--blue-faint);
  }
  .ml-readtime {
    color: var(--cyan-faint);
    opacity: 0.75;
    font-size: var(--fs-inline);
  }
  .ml-date {
    color: var(--yellow-faint);
    opacity: 0.8;
  }

  /* Echo message — default "? help", flashes on messages */
  .ml-echo-msg {
    background: var(--bg-active);
    border: none;
    color: var(--blue);
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
    padding: 0 0.5ch;
    opacity: 0.9;
    white-space: nowrap;
    overflow: hidden;
    /* Expand to fit on desktop but never dominate the bar; ellipsis on long messages. */
    max-width: min(52ch, 45vw);
    text-overflow: ellipsis;
    transition:
      opacity var(--transition),
      background var(--transition);
    border-radius: var(--radius);
    &:hover {
      opacity: 1;
    }
    &.flash {
      background: var(--blue);
      color: var(--bg-main);
      opacity: 1;
      padding: 0 0.5ch;
    }
    @media (width <= 768px) {
      max-width: 16ch;
    }
  }
}

@layer chrome {
  /* ── Command palette (native <dialog>) ── */
  #palette-dialog {
    background: var(--bg-main);
    border: 1px solid var(--border);
    box-shadow: 0 8px 32px color-mix(in oklch, black 50%, transparent);
    width: min(640px, 92vw);
    max-height: 70vh;
    padding: 0;
    margin: 8vh auto 0;
    /* Appear from above, not an instant pop. */
    opacity: 0;
    transform: translateY(-24px);
    transition:
      opacity var(--dialog-transition) ease,
      transform var(--dialog-transition) ease,
      overlay var(--dialog-transition) ease allow-discrete,
      display var(--dialog-transition) ease allow-discrete;
    &[open] {
      display: flex;
      flex-direction: column;
      overflow: hidden;
      opacity: 1;
      transform: translateY(0);
    }
    @starting-style {
      &[open] {
        opacity: 0;
        transform: translateY(-24px);
      }
    }
    &::backdrop {
      background: color-mix(in oklch, black var(--backdrop-dim), transparent);
      backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
      -webkit-backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
      opacity: 0;
      transition:
        opacity var(--dialog-transition) ease,
        overlay var(--dialog-transition) ease allow-discrete,
        display var(--dialog-transition) ease allow-discrete;
    }
    &[open]::backdrop {
      opacity: 1;
    }
    @starting-style {
      &[open]::backdrop {
        opacity: 0;
      }
    }
  }

  .palette-input-wrap {
    display: flex;
    align-items: center;
    padding: 0.6em 1em;
    border-bottom: 1px solid var(--border-dim);
    flex-shrink: 0;
  }
  .palette-input {
    flex: 1;
    background: none;
    border: none;
    outline: none;
    color: var(--fg-main);
    font-family: var(--code-font), monospace;
    font-size: var(--fs-base);
    &::placeholder {
      color: var(--fg-dim);
    }
  }

  /* Contain scroll so flicking the results list doesn't scroll the page behind. */
  #palette-results {
    overflow-y: auto;
    flex: 1;
    overscroll-behavior: contain;
  }

  .palette-item {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    padding: 0.45em 1em;
    cursor: pointer;
    border-bottom: 1px solid var(--border-dim);
    gap: 0.6em;
    &:last-child {
      border-bottom: none;
    }
  }
  :is(.palette-item.selected, .palette-item:hover) {
    background: var(--list-selected-bg, var(--bg-active));
    color: var(--list-selected-fg, var(--fg-main));
  }
  .palette-item-icon {
    flex: none;
    width: 1.3em;
    text-align: center;
    color: var(--fg-dim);
    opacity: 0.85;
  }
  .palette-item-text {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
    gap: 0.15em;
  }
  .palette-item-title {
    font-size: 0.92rem;
    color: var(--fg-main);
  }
  /* Search-result body excerpt — clamped to 2 lines regardless of match position. */
  .palette-item-snippet {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    font-size: 0.8rem;
    line-height: 1.3;
    color: var(--fg-dim);
  }

  /* ── Lightbox dialogs (native <dialog>): image preview and Pose share this chrome. ── */
  :is(#image-lightbox, #pose-dialog) {
    padding: 0;
    border: none;
    outline: 2px dashed var(--border-highlight);
    background: transparent;
    max-width: 92vw;
    max-height: 92vh;
    margin: auto;
    /* Scale up from slightly smaller */
    opacity: 0;
    transform: scale(0.85);
    transition:
      opacity var(--dialog-transition) ease,
      transform var(--dialog-transition) ease,
      overlay var(--dialog-transition) ease allow-discrete,
      display var(--dialog-transition) ease allow-discrete;
    &[open] {
      opacity: 1;
      transform: scale(1);
    }
    @starting-style {
      &[open] {
        opacity: 0;
        transform: scale(0.85);
      }
    }
    &::backdrop {
      background: color-mix(in oklch, black var(--backdrop-dim), transparent);
      backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
      -webkit-backdrop-filter: blur(var(--backdrop-blur)) saturate(160%);
      opacity: 0;
      transition:
        opacity var(--dialog-transition) ease,
        overlay var(--dialog-transition) ease allow-discrete,
        display var(--dialog-transition) ease allow-discrete;
    }
    &[open]::backdrop {
      opacity: 1;
    }
    @starting-style {
      &[open]::backdrop {
        opacity: 0;
      }
    }
    & img {
      display: block;
      max-width: 92vw;
      max-height: 92vh;
      width: auto;
      height: auto;
      cursor: zoom-out;
    }
  }
  #pose-dialog {
    padding: 1.5rem 1.75rem;
    outline-color: var(--border-highlight);
    background: var(--bg-main);
    color: var(--fg-main);
    max-width: min(640px, 92vw);
    overflow-y: auto;
  }
}

/* ── Responsive + environment overrides ────────────────────────────────────
   Last layer, so it wins over every earlier layer regardless of specificity —
   mirroring the old mobile.css that was concatenated last. */
@layer overrides {
  .center {
    display: flex;
    width: fit-content;
    margin-inline: auto;
    align-items: center;
    justify-content: center;
  }
  /* Tablet */
  @media screen and (width <= 1024px) {
    .article-meta {
      gap: 0.5em;
    }
  }

  /* Mobile */
  @media screen and (width <= 768px) {
    /* Taller bar here: the hamburger (1.2rem glyph + 0.5em padding block = 3.12rem)
       replaces the desktop button row, and .menu-items moves out of flow below. */
    :root {
      --menu-h: calc(3.2rem + env(safe-area-inset-top, 0px));
    }

    /* Menu: hidden by default, revealed via hamburger */
    .menu-bar .menu-items {
      display: none;
      flex-direction: row;
      flex-wrap: wrap;
      align-items: center;
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      background: var(--menu-bg);
      border-bottom: 1px solid var(--menu-border);
      z-index: 200;
    }
    .menu-bar.menu-open .menu-items {
      display: flex;
    }
    .menu-hamburger {
      display: block;
    }
    .menu-bar-title {
      display: none;
    }
    .menu-bar-right {
      margin-left: auto;
    }
    /* Last menu item (Help) anchors its dropdown to the right edge. */
    .menu-item:last-child .menu-dropdown {
      left: auto;
      right: 0;
    }

    /* Article list */
    .article-meta {
      display: none;
    }
    .article-item {
      flex-wrap: wrap;
      padding: var(--space);
    }
    .article-title {
      width: 100%;
    }
    .article-item .article-link {
      flex: 0 0 100%;
      padding: 0.5em 0.75em 0.2em;
    }
    .article-item .post-tags {
      flex: 0 0 100%;
      display: flex;
      flex-wrap: wrap;
      gap: 0.3em;
      padding: 0 0.75em 0.4em 0.75em;
    }

    /* Content */
    .post-content {
      padding: 0.75em;
    }
    .term-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 0.3em;
    }

    /* Topic items (projects/wander): keep [icon] [title] on one line */
    .topic-item {
      flex-wrap: nowrap;
      align-items: flex-start;
    }
    .topic-item .project-left {
      width: 1.8em;
      padding: 0.3em 0 0 0;
      flex-shrink: 0;
    }
    .topic-item .article-link {
      flex: 1;
      width: auto;
      padding: 0.2em 0;
    }
    .project-tags {
      flex-wrap: wrap;
    }
    .project-header {
      flex-wrap: wrap;
    }
    .project-name {
      word-break: break-word;
    }

    /* Wander launch bar */
    .wander-launch {
      flex-direction: column;
      align-items: flex-start;
      gap: 0.4em;
    }

    /* Wander table: stack 3 columns into rows */
    .wander-list .article-link {
      flex-wrap: wrap;
      gap: 0.1em 0;
    }
    .wander-list .article-title {
      flex: 0 0 100%;
    }
    .wander-list .article-date {
      flex: 0 0 auto;
      font-size: var(--fs-2xs);
    }
    .wander-list .wander-desc {
      flex: 0 0 100%;
      padding-left: 0;
      font-size: var(--fs-3xs);
      opacity: 0.8;
    }

    /* Content tables: scroll horizontally instead of cramming. */
    .post-content table {
      display: block;
      width: 100%;
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
    }
    .post-content :is(th, td) {
      white-space: nowrap;
    }
  }

  /* Small mobile */
  @media screen and (width <= 480px) {
    body {
      font-size: var(--fs-sm);
    }
    .article-item {
      padding: 0.5em;
    }
    .tag-cloud {
      gap: 0.25em;
      padding: 0.4em 0.5em;
    }
    .tag-cloud-btn {
      font-size: 0.75rem;
      padding: var(--space);
    }
    .list-search {
      margin: 0.4em 0;
    }
    .breadcrumbs {
      font-size: 0.75rem;
      white-space: normal;
      word-break: break-word;
    }
    .post-title {
      font-size: 1.25rem;
    }
    .post-meta {
      gap: 0.5em;
      font-size: var(--fs-2xs);
    }
    pre code {
      font-size: var(--fs-2xs);
    }
    .social-links {
      font-size: var(--fs-base);
    }
  }

  /* Touch devices */
  @media (hover: none) and (pointer: coarse) {
    .article-item {
      min-height: 44px;
      padding: 0.75em;
    }
    .menu-dropdown-item {
      min-height: 44px;
      padding: 0.75em 1em;
    }
    .article-item:hover {
      background: transparent;
    }
    .article-item:active {
      background: var(--list-hover-bg);
    }
    .menu-shortcut {
      display: none;
    }
  }

  /* Print */
  @media print {
    :is(.menu-bar, .modeline) {
      display: none !important;
    }
    .emacs-frame {
      height: auto;
      overflow: visible;
    }
    .buffer-container {
      display: block;
    }
    .buffer-body {
      overflow: visible;
    }
    body {
      background: white;
      color: black;
      font-size: 12pt;
    }
    a {
      color: black;
      text-decoration: underline;
    }
    :is(pre, code) {
      background: #f5f5f5;
      border: 1px solid #ddd;
    }
  }

  /* Cross-document View Transitions: tuning. */
  ::view-transition-old(menu-bar),
  ::view-transition-new(menu-bar) {
    animation: none;
  }
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(modeline),
  ::view-transition-new(modeline) {
    mix-blend-mode: normal;
    animation-duration: 0.18s;
  }

  /* Reduced motion */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
      animation: none !important;
    }
  }
}

@layer components {
  /* ── Mixed font mode ──────────────────────────────────────────────────
     Prose (paragraphs, list items, blockquotes, table data) reads in serif —
     inherited from --body-font-family set above; no rule needed, it's the
     baseline. Structure/meta/UI elements are overridden to sans here: they're
     scanned, not read, so they get the neutral register (classic serif-body /
     sans-byline editorial split). Table headers are labels, so sans; table
     data stays the inherited serif. Code/pre/verbatim stay mono always,
     independent of font mode entirely (custom.css). */
  [data-font="mixed"]
    :is(
      .post-meta,
      .breadcrumbs,
      .table-of-contents,
      .references,
      .post-comment,
      .callout,
      .sidenote,
      .todo
    ) {
    font-family: var(--sans-font);
  }
  [data-font="mixed"] .post-body th {
    font-family: var(--sans-font);
  }
}
/* ---- custom.css (merged 2026-09-30) ---- */
/* Fonts | custom built */
:root {
  --heading-font: "impress", "nerd-icons", sans-serif;
  --sans-font: "code-ace", "nerd-icons", sans-serif;
  --code-font: "code-op", "nerd-icons", monospace;
  --serif-font: "code-haki", "nerd-icons", serif;
}

@font-face {
  font-family: "impress";
  src: url("../fonts/impress.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "code-ace";
  src: url("../fonts/code-ace.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "code-op";
  src: url("../fonts/code-op.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "code-haki";
  src: url("../fonts/code-haki.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "nerd-icons";
  src: url("../fonts/symbols-nerd.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

body,
article.post-content {
  font-family: var(--body-font-family), "nerd-icons";
}
/* Code/verbatim stay monospace always, independent of font mode entirely */
pre,
code,
kbd,
samp,
.highlight,
.org-verbatim,
.org-code {
  font-family: var(--code-font);
}
.nf {
  font-family: "nerd-icons", var(--code-font), monospace;
}

/* headings */
h1 {
  color: var(--h1-color);
}
h2 {
  color: var(--h2-color);
}
h3 {
  color: var(--h3-color);
}
h4, h5, h6 {
  color: var(--h4-color);
}

.webring,
.webring a {
  color: var(--cyan);
}

p a {
  text-decoration: underline;
}

article :is(h1, h2, h3, h4, h5, h6) {
  font-family: var(--heading-font);
}

.post-title {
  color: var(--h1-color) !important;
}

h1::before,
h1::after {
  content: " ⩮ ";
  color: var(--h1-color);
}

article h1 {
  color: var(--h1-color) !important;
  text-align: center;
}

:is(article h2, #pose-dialog-title)::before {
  content: "◉ ";
}
article h2 {
  color: var(--h2-color);
}

article h3::before {
  content: "◈ ";
}
article h3 {
  color: var(--h3-color);
}

article h4::before, article h5::before, article h6::before {
  content: "✥ ";
}
article h4, article h5, article h6 {
  color: var(--h4-color);
}

.article-item .post-tags {
  flex-shrink: 0;
  font-size: 0.78rem;
  padding: 0 0.5em;
}

.article-item .post-tag {
  color: var(--h3-color);
  text-decoration: none;
  opacity: 0.85;
}

.article-item .post-tag:hover {
  color: var(--cursor);
  opacity: 1;
}

.article-item .post-tag:visited {
  color: var(--h3-color);
}

/* badges */
.badge {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  width: 6.5rem;
  padding: 0.6rem 0.4rem;
  margin: 0 0.4rem;
  /* border: 1px solid var(--border); */
  border-radius: var(--radius);
  text-decoration: none;
  text-align: center;
  vertical-align: top;
}

/* Rotating gradient ring, hover/focus, for every card/button/dialog; each sets its own --glow or falls back to --border-highlight. */
@property --glow-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
@keyframes glow-spin {
  to {
    --glow-angle: 360deg;
  }
}
/* Paints onto the element's own border (needs real border-width; bare <button> gets a transparent one below so hover adds no shift). */
button {
  border: 1px solid transparent;
}
:is(.badge, .pose-card, .wander-btn, .tag-cloud-btn, .code-copy-btn, button):is(:hover, :focus-visible),
.pose-card:focus-within,
#palette-dialog[open] {
  border-image: conic-gradient(
      from var(--glow-angle),
      color-mix(in oklch, var(--glow, var(--border-highlight)) 80%, white),
      var(--glow, var(--border-highlight)),
      color-mix(in oklch, var(--glow, var(--border-highlight)) 80%, black),
      var(--glow, var(--border-highlight)),
      color-mix(in oklch, var(--glow, var(--border-highlight)) 80%, white)
    )
    1;
  animation: glow-spin 3s linear infinite;
}

.rain-confetti {
  display: contents;
  pointer-events: none;
}

.rain-confetti span {
  position: fixed;
  top: -5vh;
  left: var(--rain-left);
  font-family: var(--code-font);
  font-size: 0.95rem;
  color: var(--fg-dim);
  opacity: 0;
  z-index: 500;
}

.rain-confetti span:nth-child(1) {
  --rain-left: 4%;
  animation-duration: 2.6s;
  animation-delay: -0.1s;
}
.rain-confetti span:nth-child(2) {
  --rain-left: 8%;
  animation-duration: 3s;
  animation-delay: -0.4s;
}
.rain-confetti span:nth-child(3) {
  --rain-left: 12%;
  animation-duration: 3.5s;
  animation-delay: -0.7s;
}
.rain-confetti span:nth-child(4) {
  --rain-left: 16%;
  animation-duration: 4s;
  animation-delay: -1s;
}
.rain-confetti span:nth-child(5) {
  --rain-left: 20%;
  animation-duration: 2.9s;
  animation-delay: -1.3s;
}
.rain-confetti span:nth-child(6) {
  --rain-left: 24%;
  animation-duration: 3.4s;
  animation-delay: -1.6s;
}
.rain-confetti span:nth-child(7) {
  --rain-left: 28%;
  animation-duration: 2.6s;
  animation-delay: -1.9s;
}
.rain-confetti span:nth-child(8) {
  --rain-left: 32%;
  animation-duration: 3s;
  animation-delay: -2.2s;
}
.rain-confetti span:nth-child(9) {
  --rain-left: 36%;
  animation-duration: 3.5s;
  animation-delay: -0.1s;
}
.rain-confetti span:nth-child(10) {
  --rain-left: 40%;
  animation-duration: 4s;
  animation-delay: -0.4s;
}
.rain-confetti span:nth-child(11) {
  --rain-left: 44%;
  animation-duration: 2.9s;
  animation-delay: -0.7s;
}
.rain-confetti span:nth-child(12) {
  --rain-left: 48%;
  animation-duration: 3.4s;
  animation-delay: -1s;
}
.rain-confetti span:nth-child(13) {
  --rain-left: 52%;
  animation-duration: 2.6s;
  animation-delay: -1.3s;
}
.rain-confetti span:nth-child(14) {
  --rain-left: 56%;
  animation-duration: 3s;
  animation-delay: -1.6s;
}
.rain-confetti span:nth-child(15) {
  --rain-left: 60%;
  animation-duration: 3.5s;
  animation-delay: -1.9s;
}
.rain-confetti span:nth-child(16) {
  --rain-left: 64%;
  animation-duration: 4s;
  animation-delay: -2.2s;
}
.rain-confetti span:nth-child(17) {
  --rain-left: 68%;
  animation-duration: 2.9s;
  animation-delay: -0.1s;
}
.rain-confetti span:nth-child(18) {
  --rain-left: 72%;
  animation-duration: 3.4s;
  animation-delay: -0.4s;
}
.rain-confetti span:nth-child(19) {
  --rain-left: 76%;
  animation-duration: 2.6s;
  animation-delay: -0.7s;
}
.rain-confetti span:nth-child(20) {
  --rain-left: 80%;
  animation-duration: 3s;
  animation-delay: -1s;
}
.rain-confetti span:nth-child(21) {
  --rain-left: 84%;
  animation-duration: 3.5s;
  animation-delay: -1.3s;
}
.rain-confetti span:nth-child(22) {
  --rain-left: 88%;
  animation-duration: 4s;
  animation-delay: -1.6s;
}
.rain-confetti span:nth-child(23) {
  --rain-left: 92%;
  animation-duration: 2.9s;
  animation-delay: -1.9s;
}
.rain-confetti span:nth-child(24) {
  --rain-left: 96%;
  animation-duration: 3.4s;
  animation-delay: -2.2s;
}

@media (prefers-reduced-motion: no-preference) {
  .rain-hover:hover .rain-confetti span {
    animation-name: badge-rain-fall;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
}

@keyframes badge-rain-fall {
  0% {
    opacity: 0;
    transform: translateY(0);
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateY(110vh);
  }
}

.badge-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  /* border-radius: 50%; */
  overflow: hidden;
  /* background: var(--bg-active); */
}

.badge-icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.2rem;
}

.badge-subtitle {
  font-size: 0.62rem;
  color: var(--fg-dim);
}

.badge-name {
  width: 100%;
  font-family: var(--heading-font);
  font-size: 0.72rem;
  font-weight: bold;
  color: #ffffff;
  mix-blend-mode: difference;
  padding: 0.15em 0.5em;
  border-radius: var(--radius);
}

/* 404 page's WANTED-poster gag */
.wanted-poster {
  max-width: 22rem;
  margin: 1.5rem auto;
  padding: 1.25rem 1rem;
  border: 0.2rem dashed var(--border);
  border-radius: var(--radius);
  text-align: center;
  color: var(--fg-dim);
}

.wanted-poster-heading {
  font-family: var(--heading-font);
  font-size: 1.8rem;
  font-weight: bold;
  letter-spacing: 0.2rem;
  color: var(--h1-color);
  margin: 0 0 0.5rem;
}

.wanted-poster-subject {
  font-size: 1.1rem;
  margin: 0 0 0.5rem;
}

.wanted-poster-tag {
  font-weight: bold;
  letter-spacing: 0.1rem;
  color: var(--red);
  margin: 0 0 0.75rem;
}

.wanted-poster-footer {
  font-size: 0.85rem;
  font-style: italic;
  margin: 0.75rem 0 0;
}

/* Pose layout -- one page of short-form entries, each its own full-width
   card (like topic-list's list view, minus the grid option, minus the
   dt/dl link shape -- these are free-form paragraphs, not links). Each
   card reads as a small poneglyph/scroll: a plain bordered tablet, not
   a literal image or texture -- kept subtle on purpose. */
.pose-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  margin: 1.5rem 0;
  padding: 0;
}

.pose-card {
  position: relative;
  padding: 1.25rem 1.5rem;
  border: 2px solid var(--border);
  border-radius: 3px 10px 3px 10px;
  background: var(--code-bg);
}

/* Stretches the title button's click area over the whole card; still one control, keyboard reaches the button directly. */
.pose-card-trigger {
  &::after {
    content: "";
    position: absolute;
    inset: 0;
  }
}

:is(.pose-card h2, #pose-dialog-title) {
  margin-top: 0;
  font-size: 1rem;
  letter-spacing: 0.05rem;
  color: var(--h2-color);
  border-bottom: 1px dashed var(--border-dim);
  padding-bottom: 0.4rem;
}

.pose-card p:last-child {
  margin-bottom: 0;
}

/* ================================================================
   Custom color schemes — hand-written, single source for both this
   file's live CSS AND the /themes gallery + "t " picker (parsed at
   build time by layouts/partials/all-schemes.html).

   Convention: one "@scheme: Name | Author (URL) | dark|light" comment
   directly above each [data-scheme="X"] block. Selector order is
   fixed: [data-scheme="X"] then, for the light variant,
   [data-scheme="X"][data-theme="light"] — scheme attribute first.
   ================================================================ */

/* @scheme: Haki | Dilip-Zororg (https://github.com/idlip/haki) | dark */
[data-scheme="haki"] {
  --base00: #000000; /* pure black bg        */
  --base01: #0a0f0a; /* dark green-tint dim  */
  --base02: #111c17; /* active/hover bg      */
  --base03: #b4aeae; /* dim fg / comments    */
  --base04: #888888; /* dark fg              */
  --base05: #ffffff; /* main fg              */
  --base06: #ffffff;
  --base07: #ffffff;
  --base08: #ffa9bf; /* red/pink  — h4       */
  --base09: #fab387; /* orange    — h2       */
  --base0A: #d0bc00; /* yellow               */
  --base0B: #6ae4b9; /* green/teal — h3      */
  --base0C: #5fd7af; /* cyan/cursor          */
  --base0D: #2fafff; /* blue                 */
  --base0E: #ab82ff; /* violet    — h1       */
  --base0F: #248f6c; /* teal accent/border   */

  /* Haki-specific semantic overrides */
  --modeline-bg: #0a0f0a;
  --modeline-border: #248f6c;
  --menu-bg: #0a0f0a;
  --code-bg: #0a0f0a;
  --echo-bg: #000000;
  --cursor: #5fd7af;
  --selection-bg: #248f6c;
  --bg-region: #248f6c;
  --scrollbar-thumb: #248f6c;
  --scrollbar-thumb-hover: #5fd7af;
  --border: #1b2a24;
  --border-dim: #0a0f0a;
  --code-border: #1b2a24;
  --menu-border: #1b2a24;
  --menu-hover-bg: #111c17;
}

/* @scheme: Haki Light | Dilip-Zororg (https://github.com/idlip/haki) | light */
[data-scheme="haki"][data-theme="light"] {
  --base00: #ffffff;
  --base01: #f2f2f2;
  --base02: #d7d7d7;
  --base03: #595959;
  --base04: #193668;
  --base05: #000000;
  --base06: #000000;
  --base07: #ffffff;
  --base08: #a60000;
  --base09: #884900;
  --base0A: #6f5500;
  --base0B: #006800;
  --base0C: #005e8b;
  --base0D: #0031a9;
  --base0E: #531ab6;
  --base0F: #a0132f;

  --modeline-bg: #c8c8c8;
  --modeline-border: #a3a3a3;
  --menu-bg: #f2f2f2;
  --code-bg: #f5f5f5;
  --echo-bg: #ffffff;
  --cursor: #005f5f;
  --selection-bg: #c4e3ff;
  --bg-region: #c4e3ff;
  --scrollbar-thumb: #a3a3a3;
  --scrollbar-thumb-hover: #595959;
  --border: #d7d7d7;
  --border-dim: #e4e4e4;
  --code-border: #d7d7d7;
  --menu-border: #d7d7d7;
  --menu-hover-bg: #e4e4e4;
}

/* ---- generated: base16 scheme variables (site-scheme-css) ---- */
[data-scheme="dracula"]{--base00:#282a36;--base01:#363447;--base02:#44475a;--base03:#6272a4;--base04:#9ea8c7;--base05:#f8f8f2;--base06:#f0f1f4;--base07:#ffffff;--base08:#ff5555;--base09:#ffb86c;--base0A:#f1fa8c;--base0B:#50fa7b;--base0C:#8be9fd;--base0D:#80bfff;--base0E:#ff79c6;--base0F:#bd93f9;}
[data-scheme="gruvbox"]{--base00:#282828;--base01:#3c3836;--base02:#504945;--base03:#665c54;--base04:#bdae93;--base05:#d5c4a1;--base06:#ebdbb2;--base07:#fbf1c7;--base08:#fb4934;--base09:#fe8019;--base0A:#fabd2f;--base0B:#b8bb26;--base0C:#8ec07c;--base0D:#83a598;--base0E:#d3869b;--base0F:#d65d0e;}
[data-scheme="gruvbox"][data-theme="light"]{--base00:#fbf1c7;--base01:#ebdbb2;--base02:#d5c4a1;--base03:#bdae93;--base04:#665c54;--base05:#504945;--base06:#3c3836;--base07:#282828;--base08:#9d0006;--base09:#af3a03;--base0A:#b57614;--base0B:#79740e;--base0C:#427b58;--base0D:#076678;--base0E:#8f3f71;--base0F:#d65d0e;}
[data-scheme="tokyo-night"]{--base00:#1A1B26;--base01:#16161E;--base02:#2F3549;--base03:#444B6A;--base04:#787C99;--base05:#A9B1D6;--base06:#CBCCD1;--base07:#D5D6DB;--base08:#C0CAF5;--base09:#A9B1D6;--base0A:#0DB9D7;--base0B:#9ECE6A;--base0C:#B4F9F8;--base0D:#2AC3DE;--base0E:#BB9AF7;--base0F:#F7768E;}
[data-scheme="tokyo-night"][data-theme="light"]{--base00:#D5D6DB;--base01:#CBCCD1;--base02:#DFE0E5;--base03:#9699A3;--base04:#4C505E;--base05:#343B59;--base06:#1A1B26;--base07:#1A1B26;--base08:#343B58;--base09:#965027;--base0A:#166775;--base0B:#485E30;--base0C:#3E6968;--base0D:#34548A;--base0E:#5A4A78;--base0F:#8C4351;}
[data-scheme="catppuccin-mocha"]{--base00:#1e1e2e;--base01:#181825;--base02:#313244;--base03:#45475a;--base04:#585b70;--base05:#cdd6f4;--base06:#f5e0dc;--base07:#b4befe;--base08:#f38ba8;--base09:#fab387;--base0A:#f9e2af;--base0B:#a6e3a1;--base0C:#94e2d5;--base0D:#89b4fa;--base0E:#cba6f7;--base0F:#f2cdcd;}
[data-scheme="catppuccin-mocha"][data-theme="light"]{--base00:#eff1f5;--base01:#e6e9ef;--base02:#ccd0da;--base03:#bcc0cc;--base04:#acb0be;--base05:#4c4f69;--base06:#dc8a78;--base07:#7287fd;--base08:#d20f39;--base09:#fe640b;--base0A:#df8e1d;--base0B:#40a02b;--base0C:#179299;--base0D:#1e66f5;--base0E:#8839ef;--base0F:#dd7878;}
[data-scheme="one-dark"]{--base00:#282c34;--base01:#353b45;--base02:#3e4451;--base03:#545862;--base04:#565c64;--base05:#abb2bf;--base06:#b6bdca;--base07:#c8ccd4;--base08:#e06c75;--base09:#d19a66;--base0A:#e5c07b;--base0B:#98c379;--base0C:#56b6c2;--base0D:#61afef;--base0E:#c678dd;--base0F:#be5046;}
[data-scheme="one-dark"][data-theme="light"]{--base00:#fafafa;--base01:#f0f0f1;--base02:#e5e5e6;--base03:#a0a1a7;--base04:#696c77;--base05:#383a42;--base06:#202227;--base07:#090a0b;--base08:#ca1243;--base09:#d75f00;--base0A:#c18401;--base0B:#50a14f;--base0C:#0184bc;--base0D:#4078f2;--base0E:#a626a4;--base0F:#986801;}
[data-scheme="rose-pine"]{--base00:#191724;--base01:#1f1d2e;--base02:#26233a;--base03:#6e6a86;--base04:#908caa;--base05:#e0def4;--base06:#e0def4;--base07:#524f67;--base08:#eb6f92;--base09:#f6c177;--base0A:#ebbcba;--base0B:#31748f;--base0C:#9ccfd8;--base0D:#c4a7e7;--base0E:#f6c177;--base0F:#524f67;}
[data-scheme="rose-pine"][data-theme="light"]{--base00:#faf4ed;--base01:#fffaf3;--base02:#f2e9de;--base03:#9893a5;--base04:#797593;--base05:#575279;--base06:#575279;--base07:#cecacd;--base08:#b4637a;--base09:#ea9d34;--base0A:#d7827e;--base0B:#286983;--base0C:#56949f;--base0D:#907aa9;--base0E:#ea9d34;--base0F:#cecacd;}
[data-scheme="kanagawa"]{--base00:#1F1F28;--base01:#16161D;--base02:#223249;--base03:#54546D;--base04:#727169;--base05:#DCD7BA;--base06:#C8C093;--base07:#717C7C;--base08:#C34043;--base09:#FFA066;--base0A:#C0A36E;--base0B:#76946A;--base0C:#6A9589;--base0D:#7E9CD8;--base0E:#957FB8;--base0F:#D27E99;}
[data-scheme="ayu"]{--base00:#0b0e14;--base01:#131721;--base02:#202229;--base03:#3e4b59;--base04:#bfbdb6;--base05:#e6e1cf;--base06:#ece8db;--base07:#f2f0e7;--base08:#f07178;--base09:#ff8f40;--base0A:#ffb454;--base0B:#aad94c;--base0C:#95e6cb;--base0D:#59c2ff;--base0E:#d2a6ff;--base0F:#e6b450;}
[data-scheme="ayu"][data-theme="light"]{--base00:#f8f9fa;--base01:#edeff1;--base02:#d2d4d8;--base03:#a0a6ac;--base04:#8A9199;--base05:#5c6166;--base06:#4e5257;--base07:#404447;--base08:#f07171;--base09:#fa8d3e;--base0A:#f2ae49;--base0B:#6cbf49;--base0C:#4cbf99;--base0D:#399ee6;--base0E:#a37acc;--base0F:#e6ba7e;}
[data-scheme="everforest"]{--base00:#272e33;--base01:#2e383c;--base02:#414b50;--base03:#859289;--base04:#9da9a0;--base05:#d3c6aa;--base06:#edeada;--base07:#fffbef;--base08:#e67e80;--base09:#e69875;--base0A:#dbbc7f;--base0B:#a7c080;--base0C:#83c092;--base0D:#7fbbb3;--base0E:#d699b6;--base0F:#9da9a0;}
[data-scheme="oxocarbon"]{--base00:#161616;--base01:#262626;--base02:#393939;--base03:#525252;--base04:#dde1e6;--base05:#f2f4f8;--base06:#ffffff;--base07:#08bdba;--base08:#ee5396;--base09:#ff7eb6;--base0A:#ff6f00;--base0B:#42be65;--base0C:#3ddbd9;--base0D:#33b1ff;--base0E:#be95ff;--base0F:#82cfff;}
[data-scheme="oxocarbon"][data-theme="light"]{--base00:#f2f4f8;--base01:#dde1e6;--base02:#bec6cf;--base03:#a1acba;--base04:#68788d;--base05:#525f70;--base06:#3d4652;--base07:#272d35;--base08:#ff7eb6;--base09:#ee5396;--base0A:#ff6f00;--base0B:#42be65;--base0C:#673ab7;--base0D:#0f62fe;--base0E:#be95ff;--base0F:#803800;}
[data-scheme="monokai"]{--base00:#272822;--base01:#383830;--base02:#49483e;--base03:#75715e;--base04:#a59f85;--base05:#f8f8f2;--base06:#f5f4f1;--base07:#f9f8f5;--base08:#f92672;--base09:#fd971f;--base0A:#f4bf75;--base0B:#a6e22e;--base0C:#a1efe4;--base0D:#66d9ef;--base0E:#ae81ff;--base0F:#cc6633;}
[data-scheme="github-dark"]{--base00:#161b22;--base01:#30363d;--base02:#484f58;--base03:#6e7681;--base04:#8b949e;--base05:#c9d1d9;--base06:#f0f6fc;--base07:#ffffff;--base08:#f85149;--base09:#db6d28;--base0A:#bb8009;--base0B:#2ea043;--base0C:#2A9D9A;--base0D:#388bfd;--base0E:#a371f7;--base0F:#3D2F00;}
[data-scheme="github-dark"][data-theme="light"]{--base00:#eaeef2;--base01:#d0d7de;--base02:#afb8c1;--base03:#8c959f;--base04:#6e7781;--base05:#424a53;--base06:#32383f;--base07:#1f2328;--base08:#fa4549;--base09:#e16f24;--base0A:#bf8700;--base0B:#2da44e;--base0C:#339D9B;--base0D:#218bff;--base0E:#a475f9;--base0F:#4d2d00;}

/* ---- generated: code-highlight colors (site-highlight-stylesheet) ---- */
.org-default { color: var(--base05); }
.org-comment { color: var(--base03); }
.org-comment-delimiter { color: var(--base03); }
.org-string { color: var(--base0B); }
.org-doc { color: var(--base0B); }
.org-keyword { color: var(--base0E); }
.org-negation-char { color: var(--base0E); }
.org-preprocessor { color: var(--base0F); }
.org-builtin { color: var(--base0C); }
.org-function-name { color: var(--base0D); }
.org-variable-name { color: var(--base08); }
.org-type { color: var(--base0A); }
.org-constant { color: var(--base09); }
.org-warning { color: var(--base08); }