/* Light palette by default. The theme picker pins data-theme on <html>;
   with no attribute, prefers-color-scheme decides. */
:root { --accent: #f37626; --ink: #1c1c1c;
        /* text grays clear WCAG AAA (7:1) on both --bg and --card */
        --soft: #444444; --muted: #525252; --bg: #f4f4f4; --card: #ffffff;
        --line: #e2e2e2; --code-bg: #f6f6f6; --mark: #fbd6bc;
        --error-bg: #fef2f2; --error-line: #fecaca; --error-ink: #dc2626;
        --error-soft: #b91c1c;
        /* Link choice (see link-picker.html): each choice sets a light
           (-l) and dark (-d) value; the palette in force picks one.
           The accent (2.83:1 on --card) is never link text. */
        --link-l: currentColor; --link-rule-l: currentColor;
        --link-d: currentColor; --link-rule-d: currentColor;
        --link: var(--link-l); --link-rule: var(--link-rule-l);
        /* syntax colours: Primer's prettylights light set */
        --syn-keyword: #cf222e; --syn-string: #0a3069; --syn-comment: #6e7781;
        --syn-number: #0550ae; --syn-name: #6639ba; --syn-builtin: #953800;
        /* which masthead logo shows (see .site-logo) */
        --logo-light: block; --logo-dark: none;
        color-scheme: light; }
:root[data-theme="dark"] {
  /* text grays clear WCAG AAA (7:1) on both --bg and --card */
  --ink: #e8e6e3; --soft: #c9c6c2; --muted: #aeaaa4;
  --bg: #131313; --card: #1e1e1e; --line: #333333; --code-bg: #2a2a2a;
  --mark: #7a4114; --error-bg: #2a1a1a; --error-line: #5c2828;
  --error-ink: #f87171; --error-soft: #ef4444;
  /* the dark value of each link choice */
  --link: var(--link-d); --link-rule: var(--link-rule-d);
  --syn-keyword: #ff7b72; --syn-string: #a5d6ff; --syn-comment: #8b949e;
  --syn-number: #79c0ff; --syn-name: #d2a8ff; --syn-builtin: #ffa657;
  /* show the dark-palette logo (see .site-logo) */
  --logo-light: none; --logo-dark: block;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  /* text grays clear WCAG AAA (7:1) on both --bg and --card */
  --ink: #e8e6e3; --soft: #c9c6c2; --muted: #aeaaa4;
  --bg: #131313; --card: #1e1e1e; --line: #333333; --code-bg: #2a2a2a;
  --mark: #7a4114; --error-bg: #2a1a1a; --error-line: #5c2828;
  --error-ink: #f87171; --error-soft: #ef4444;
  /* the dark value of each link choice */
  --link: var(--link-d); --link-rule: var(--link-rule-d);
  --syn-keyword: #ff7b72; --syn-string: #a5d6ff; --syn-comment: #8b949e;
  --syn-number: #79c0ff; --syn-name: #d2a8ff; --syn-builtin: #ffa657;
  /* show the dark-palette logo (see .site-logo) */
  --logo-light: none; --logo-dark: block;
  color-scheme: dark;
  }
}
* { box-sizing: border-box; }
/* Font choices (see font-picker.html), pinned as data-font on <html>;
   no attribute is the Source Serif default. Each choice sets --body-font
   (page, headings, chrome) and --mono (code). Serif choices keep a sans
   --body-font and set only .post in the serif, further down. */
:root { --sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
        --system-ui: system-ui, -apple-system, "Segoe UI", Roboto,
                     Helvetica, Arial, sans-serif;
        --system-mono: ui-monospace, SFMono-Regular, Menlo, Consolas,
                       monospace;
        --inter: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
        /* each current face keeps its older name as a local fallback */
        --source-sans: "Source Sans 3", "Source Sans Pro",
                       "Helvetica Neue", Helvetica, Arial, sans-serif;
        --source-serif: "Source Serif 4", "Source Serif Pro", Georgia,
                        Cambria, "Times New Roman", Times, serif;
        --source-code: "Source Code Pro", ui-monospace, SFMono-Regular,
                       Menlo, Consolas, monospace;
        --atkinson: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible",
                    "Helvetica Neue", Helvetica, Arial, sans-serif;
        --atkinson-mono: "Atkinson Hyperlegible Mono", ui-monospace,
                         SFMono-Regular, Menlo, Consolas, monospace;
        --ibm-plex-sans: "IBM Plex Sans", "Helvetica Neue", Helvetica,
                         Arial, sans-serif;
        --ibm-plex-serif: "IBM Plex Serif", Georgia, Cambria,
                          "Times New Roman", Times, serif;
        --ibm-plex-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular,
                         Menlo, Consolas, monospace;
        --literata: "Literata", Georgia, Cambria,
                    "Times New Roman", Times, serif;
        --merriweather: "Merriweather", Georgia, Cambria,
                        "Times New Roman", Times, serif;
        --merriweather-sans: "Merriweather Sans", "Helvetica Neue",
                             Helvetica, Arial, sans-serif;
        /* the default (Source Serif) */
        --body-font: var(--source-sans);
        --mono: var(--source-code); }
:root[data-font="sans"] { --body-font: var(--sans); --mono: var(--system-mono); }
:root[data-font="system-ui"] { --body-font: var(--system-ui);
                               --mono: var(--system-mono); }
:root[data-font="inter"] { --body-font: var(--inter); --mono: var(--system-mono); }
:root[data-font="source-sans"] { --body-font: var(--source-sans);
                                 --mono: var(--source-code); }
:root[data-font="atkinson"] { --body-font: var(--atkinson);
                              --mono: var(--atkinson-mono); }
:root[data-font="ibm-plex-sans"] { --body-font: var(--ibm-plex-sans);
                                   --mono: var(--ibm-plex-mono); }
:root[data-font="ibm-plex-serif"] { --body-font: var(--ibm-plex-sans);
                                    --mono: var(--ibm-plex-mono); }
:root[data-font="literata"] { --body-font: var(--source-sans);
                              --mono: var(--source-code); }
:root[data-font="merriweather"] { --body-font: var(--merriweather-sans);
                                  --mono: var(--system-mono); }
/* font-size-adjust sets every choice at one x-height so the faces read
   at the same size: .486 is Source Sans 3's and Source Code Pro's own,
   so the default is unchanged (.post uses Source Serif 4's .475).
   It must come after the `font` shorthand, which resets it to none. */
body { margin: 0; background: var(--bg); color: var(--ink);
       font: 1rem/1.65 var(--body-font); font-size-adjust: .486; }
.wrap { max-width: 72rem; margin: 0 auto; padding: 0 1.25rem; }
a { color: var(--link); text-decoration-line: underline;
    text-decoration-color: var(--link-rule);
 }
/* Component links: no underline at rest, inherited ink under every
   link choice. */
.site-title, .site-header nav a, .card-cover, .card-title a,
.tag, .share-link, .chip, ul.pagination .page-link,
.archives a { text-decoration-line: none; color: currentColor; }
a:hover { text-decoration-line: underline; }
/* The default link choice ("ink-accent") is the state with no data-link:
   the ink link with an accent underline on hover. The accent is fine
   for a hover rule, a non-text indicator, though not for link text.
   --rule-w approximates the browser's rest underline (Chromium: 1px per
   10px of text, rounded down) so the hover rule is at least 2px and
   never thinner than the rest rule. */
:root { --rule-w: .1em; }
:root:not([data-link]) a:hover { text-decoration-color: var(--accent);
                                 text-decoration-thickness: max(2px, var(--rule-w)); }
/* Coloured link choices: "petrol-aaa" is 7:1 on --card, "link-blue"
   5.5:1 (3.1:1 against --ink, so it reads as a link); both dark values
   ~7:1. Each pins a 1px rule at every size. */
:root[data-link="petrol-aaa"] { --link-l: #05607e; --link-d: #09b6ea;
                                --rule-w: 1px; }
:root[data-link="link-blue"] { --link-l: #046bb9; --link-d: #59adfe;
                               --rule-w: 1px; }
:root[data-link="petrol-aaa"] a, :root[data-link="link-blue"] a {
                               text-decoration-thickness: var(--rule-w); }
/* same accent hover rule as the default */
:root[data-link="petrol-aaa"] a:hover, :root[data-link="link-blue"] a:hover {
                               text-decoration-color: var(--accent);
                               text-decoration-thickness: max(2px, var(--rule-w)); }
/* "browser": the platform link colour. VisitedText is not used: it
   would also hit card titles and nav items, which the reset above
   cannot outrank. */
:root[data-link="browser"] { --link-l: LinkText; --link-d: LinkText; }

/* Matches jupyter.org's .global-banner box (43.8px tall with one line),
   but in --body-font so it follows the font picker. The box is 14px/20px
   and .announcement-content (added by announcement.html) 18px/27px.
   font-size-adjust must follow the `font` shorthand, as on body. */
.announcement { position: relative; background: var(--accent); color: #fff;
                text-shadow: 0 0 4px #000;
                text-align: center;
                font: 400 .875rem/1.42857143 var(--body-font);
                font-size-adjust: .486;
                padding: .6em 2.5em; }
.announcement[hidden] { display: none; }
.announcement-content { font-size: 1.125rem; line-height: 1.5; }
.announcement p { margin: 0; }
.announcement a { color: #fff; text-decoration: underline;
                  text-decoration-thickness: 2px; }
/* buttons default to the UA's UI font */
.announcement-close { position: absolute; right: .5em; top: 50%;
                      transform: translateY(-50%); padding: .2em .4em;
                      border: 0; background: none; color: inherit;
                      text-shadow: inherit;
                      font-family: inherit;
                      font-size: 1.4em; line-height: 1; cursor: pointer; }

/* Same height as jupyter.org's navbar: 15px (.9375rem) padding around a
   40px logo, plus the 1px border. The nav tab bar depends on .9375rem. */
.site-header { background: var(--card); border-bottom: 1px solid var(--line); }
.site-header .bar { display: flex; align-items: center; justify-content: space-between;
                    flex-wrap: wrap; gap: .5rem;
                    padding-top: .9375rem; padding-bottom: .9375rem; }
.site-title { font-size: 1.25rem; font-weight: 700; color: var(--ink);
              display: flex; align-items: center; gap: .55rem; }
.site-title img { height: 2.1rem; width: auto; }
/* Logo in place of the title (site.toml "logo"; "logo_dark" for the
   dark palette, picked by --logo-light/--logo-dark). */
.site-title img.site-logo { height: 2.5rem; }
.site-title img.site-logo-light { display: var(--logo-light); }
.site-title img.site-logo-dark { display: var(--logo-dark); }
/* a:hover outranks .site-title, so this needs its own rule */
.site-title:hover { text-decoration-line: none; }
/* Nav items are tabs: the current page is bold ink with a 3px accent
   bar on the header's bottom border (padding down through the bar's
   bottom padding, pulled back by a matching negative margin). A flex
   row with row-gap, not inline-blocks, so wrapped rows don't overlap
   the negative margin; row-gap must exceed .9375rem. */
.site-header nav { display: flex; flex-wrap: wrap; align-items: center;
                   column-gap: 1.25rem; row-gap: 1.25rem; }
.site-header nav a { display: inline-block;
                     padding-bottom: calc(.9375rem - 3px); margin-bottom: -.9375rem;
                     border-bottom: 3px solid transparent;
                     color: var(--soft); font-weight: 500; }
.site-header nav a:hover { color: var(--ink); }
.site-header nav a[aria-current="page"] { color: var(--ink); font-weight: 700;
                                          border-bottom-color: var(--accent); }

.theme-picker { display: inline-flex; vertical-align: middle; }
.theme-picker[hidden] { display: none; }
.theme-picker button {
                       display: inline-flex; align-items: center;
                       justify-content: center; width: 1.9rem; height: 1.9rem;
                       padding: 0; border: 1px solid var(--line);
                       border-radius: 999px; background: none;
                       color: var(--muted); cursor: pointer; }
.theme-picker button:hover { color: var(--accent); }
.theme-picker svg { width: 1rem; height: 1rem; }
/* The font and link pickers (font-picker.html, link-picker.html) float
   fixed at the bottom-right; hidden until their scripts run. */
.font-picker, .link-picker { position: fixed; right: 1.25rem; z-index: 40; }
.font-picker { bottom: 1.25rem; }
/* one select height (2.1rem) plus a gap above the font picker */
.link-picker { bottom: 3.85rem; color: var(--muted); }
.font-picker[hidden], .link-picker[hidden] { display: none; }
/* Fixed width (fits "Atkinson Hyperlegible Next") so the box doesn't
   resize as the script sets its font to the current choice.
   -webkit-appearance is needed for Safari to drop the native arrow. */
.font-picker select, .link-picker select {
                      display: block; width: 13rem; height: 2.1rem;
                      padding: 0 1.9rem 0 .9rem; border: 1px solid var(--line);
                      border-radius: 999px; background: var(--card);
                      color: var(--muted); font-size: .8rem; cursor: pointer;
                      box-shadow: 0 1px 3px rgba(0,0,0,.09),
                                  0 4px 14px rgba(0,0,0,.05);
                      appearance: none; -webkit-appearance: none; }
/* previews the current link colour; currentColor choices resolve to
   the picker's --muted */
.link-picker select { color: var(--link); }
.font-picker select:hover, .font-picker select:focus-visible,
.link-picker select:hover, .link-picker select:focus-visible { color: var(--accent); }
.picker-arrow { position: absolute; right: 1rem; top: 50%;
                transform: translateY(-50%); width: .85rem; height: .85rem;
                fill: none; stroke: currentColor; stroke-width: 2;
                stroke-linecap: round; stroke-linejoin: round;
                color: var(--muted); pointer-events: none; }
.font-picker select:hover ~ .picker-arrow,
.font-picker select:focus-visible ~ .picker-arrow,
.link-picker select:hover ~ .picker-arrow,
.link-picker select:focus-visible ~ .picker-arrow { color: var(--accent); }

/* feed icon in the header nav and beside tag/author page titles */
.feed-link { display: inline-flex; align-items: center; }
.feed-icon { width: 1rem; height: 1rem; }
.site-header nav .feed-link { vertical-align: middle; padding-bottom: 0;
                              margin-bottom: 0; border-bottom: 0; }
.page-title .feed-link { margin-left: .55rem; color: var(--muted);
                         vertical-align: middle; }
.page-title .feed-link:hover { color: var(--accent); }
.page-title .feed-icon { width: 1.4rem; height: 1.4rem; }

.page-title { font-size: 2.4rem; font-weight: 400; margin: 2.2rem 0 1rem; }
.intro { max-width: 46rem; color: var(--muted); margin-bottom: 2rem; }

.card-grid { display: grid; gap: 1.5rem; margin: 1rem 0 2.5rem;
             grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); }
.card { background: var(--card); border-radius: 8px; overflow: hidden;
        box-shadow: 0 1px 3px rgba(0,0,0,.09), 0 4px 14px rgba(0,0,0,.05);
        display: flex; flex-direction: column; }
.card-cover { display: block; aspect-ratio: 16/9; background: var(--bg); }
.card-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-body { padding: 1.1rem 1.25rem 1.25rem; display: flex;
             flex-direction: column; flex: 1; }
.card-tags { margin: 0 0 .5rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.card-title { margin: 0 0 .5rem; font-size: 1.3rem; line-height: 1.3; }
.card-title a { color: var(--ink); }
.card-excerpt { margin: 0; color: var(--muted); font-size: .95rem; flex: 1; }
.card-meta { margin: 1rem 0 0; color: var(--muted); font-size: .85rem; }

/* Article text at 1.25rem/1.6 under every font choice; .475 is Source
   Serif 4's x-height (see body). */
.post { background: var(--card); border-radius: 8px; margin: 2rem auto 3rem;
        padding: 2.5rem clamp(1.25rem, 5vw, 3.5rem); max-width: 52rem;
        font-size: 1.25rem; line-height: 1.6; font-size-adjust: .475;
        box-shadow: 0 1px 3px rgba(0,0,0,.09), 0 4px 14px rgba(0,0,0,.05); }
.post h1 { font-size: 2.1rem; line-height: 1.25; margin: 0 0 .5rem; }
/* Headings would otherwise inherit .post's 1.6 line-height. More space
   above than below binds a heading to the text it introduces. */
.post :is(h2, h3, h4, h5, h6) { line-height: 1.25; }
.post h2 { margin: 2.75rem 0 .5rem; }
.post :is(h3, h4, h5, h6) { margin: 1.8em 0 .3em; }
/* The section link heading-anchor.html appends to each heading: shown
   on heading hover, on focus, or always without hover. Hidden by
   opacity so revealing it doesn't re-wrap the heading. */
.heading-anchor { margin-left: .3em; color: var(--muted); opacity: 0; }
.heading-anchor, .heading-anchor:hover { text-decoration-line: none; }
.post :hover > .heading-anchor,
.heading-anchor:focus-visible { opacity: 1; }
@media (hover: none) { .heading-anchor { opacity: 1; } }
.heading-anchor svg { width: .8em; height: .8em; vertical-align: baseline; }
.heading-anchor:hover, .heading-anchor:focus-visible { color: var(--accent); }
/* The inner <p> comes from Pelican, which renders the subtitle as
   Markdown (FORMATTED_FIELDS). */
.post-subtitle { color: var(--muted); font-size: 1.45rem; line-height: 1.35;
                 margin: 0 0 1rem; }
.post-subtitle p { margin: 0; font: inherit; color: inherit; }
.post-meta { color: var(--muted); margin: 0 0 .9rem; font-size: 1rem; }
/* Tag pill. Hover colours the border, not the text: orange text fails
   contrast. */
.tag { display: inline-flex; align-items: center;
       background: var(--code-bg); border: 1px solid var(--line);
       border-radius: 999px; padding: .05rem .65rem;
       font-size: .82rem; color: var(--soft); }
.tag:hover { border-color: var(--accent); color: var(--ink);
             text-decoration: none; }
/* white behind transparent images, which were drawn for Medium's white
   page, so dark logos stay legible */
.post img { max-width: 100%; height: auto; border-radius: 4px; background: #fff; }
/* fluid 16:9 embeds (convert writes YouTube embeds as 560x315 iframes) */
.post iframe { width: 100%; max-width: 100%; height: auto; aspect-ratio: 16 / 9;
               border: 0; border-radius: 4px; }
/* clips replacing animated gifs and Giphy embeds (see clip-motion.html) */
.post video { max-width: 100%; height: auto; border-radius: 4px; }
.post p:has(> video:only-child) { text-align: center; }
/* Centre standalone images (alone in a paragraph, optionally linked,
   or in a figure); inline images in running text are not matched. */
.post p:has(> img:only-child), .post p:has(> a:only-child > img:only-child),
.post figure { text-align: center; }
/* Inline code is em so it tracks the prose. Blocks are rem (Medium's
   14px on 1.4), which fits about 80 columns at the column's full width. */
.post pre { overflow-x: auto; padding: 1rem; background: var(--code-bg);
            border-radius: 6px; font-family: var(--mono);
            font-size: .875rem; line-height: 1.4; }
.post code { background: var(--code-bg); font-family: var(--mono);
             font-size: .9em; }
.post pre code { font-size: inherit; background: none; }
/* Token colours on the class names shared by Pygments (Pelican) and
   Chroma (Hugo, noClasses = false). The --syn-* values are Primer's
   (AA, not AAA): all clear 4.5:1 on --code-bg except the light comment
   grey at 4.2:1; a test checks this. */
.post .highlight .k, .post .highlight .kd, .post .highlight .kn,
.post .highlight .kr, .post .highlight .kt, .post .highlight .kc,
.post .highlight .ow { color: var(--syn-keyword); }
.post .highlight .s, .post .highlight .s1, .post .highlight .s2,
.post .highlight .sb, .post .highlight .sd, .post .highlight .sa,
.post .highlight .se, .post .highlight .sh, .post .highlight .si,
.post .highlight .sx, .post .highlight .sr, .post .highlight .ss,
.post .highlight .dl { color: var(--syn-string); }
.post .highlight .c, .post .highlight .c1, .post .highlight .cm,
.post .highlight .cp, .post .highlight .cs,
.post .highlight .ch { color: var(--syn-comment); font-style: italic; }
.post .highlight .m, .post .highlight .mi, .post .highlight .mf,
.post .highlight .mh, .post .highlight .mo, .post .highlight .mb,
.post .highlight .il { color: var(--syn-number); }
.post .highlight .nf, .post .highlight .fm, .post .highlight .nc,
.post .highlight .nd, .post .highlight .ne, .post .highlight .nn,
.post .highlight .nt { color: var(--syn-name); }
.post .highlight .nb, .post .highlight .bp,
.post .highlight .na { color: var(--syn-builtin); }
/* Copy button from code-copy.html. It is positioned on the .code-block
   wrapper, not the pre, so it doesn't scroll away with the code. Shown
   on hover, on focus, or always without hover; hidden by opacity so it
   stays in the tab order. .code-copy-status is a visually hidden live
   region. */
.code-block { position: relative; }
.code-copy { position: absolute; top: .45rem; right: .45rem;
             display: inline-flex; align-items: center; justify-content: center;
             width: 1.9rem; height: 1.9rem; padding: 0;
             border: 1px solid var(--line); border-radius: 6px;
             background: var(--code-bg); color: var(--muted);
             cursor: pointer; opacity: 0; }
.code-block:hover .code-copy, .code-copy:focus-visible { opacity: 1; }
@media (hover: none) { .code-copy { opacity: 1; } }
.code-copy svg { width: 1rem; height: 1rem; }
.code-copy svg[hidden] { display: none; }
.code-copy:hover, .code-copy:focus-visible { color: var(--accent);
                                             border-color: var(--accent); }
.code-copy-status { position: absolute; width: 1px; height: 1px;
                    margin: -1px; padding: 0; overflow: hidden;
                    clip-path: inset(50%); white-space: nowrap; }
.post blockquote { margin-left: 0; padding-left: 1rem;
                   border-left: 3px solid var(--accent); color: var(--soft); }
/* tables come from Markdown gists inlined by convert */
.post table { border-collapse: collapse; width: 100%; margin: 1rem 0;
              font-size: .9em; }
.post th, .post td { padding: .45em .6em; text-align: left;
                     vertical-align: top; border-bottom: 1px solid var(--line); }
.post th { border-bottom: 2px solid var(--line); }
/* Override the UA's 40px figure indent. Goldmark renders an embed
   figure's caption as a paragraph. */
.post figure { margin: 1rem 0; }
.post figure > p { margin: 0; }
/* undo the figure centring for captioned code blocks */
.post figure pre { text-align: left; }
.post figcaption { font-size: .8em; font-style: italic;
                   margin-top: .35rem; text-align: center; }
.post figcaption p { margin: 0; }
.post figcaption, .post em img + em { color: var(--muted); }

/* Serif choices set only the article's running text in the serif;
   headings, subtitle, byline, share bar and captions stay in
   --body-font. Source Serif is the default, so it matches
   :not([data-font]). */
:root:not([data-font]) .post { font-family: var(--source-serif); }
:root:not([data-font]) .post :is(h1, h2, h3, h4, h5, h6),
:root:not([data-font]) .post-subtitle,
:root:not([data-font]) .post-meta,
:root:not([data-font]) .post-share,
:root:not([data-font]) .post figcaption { font-family: var(--body-font); }
:root[data-font="ibm-plex-serif"] .post { font-family: var(--ibm-plex-serif); }
:root[data-font="ibm-plex-serif"] .post :is(h1, h2, h3, h4, h5, h6),
:root[data-font="ibm-plex-serif"] .post-subtitle,
:root[data-font="ibm-plex-serif"] .post-meta,
:root[data-font="ibm-plex-serif"] .post-share,
:root[data-font="ibm-plex-serif"] .post figcaption { font-family: var(--body-font); }
:root[data-font="literata"] .post { font-family: var(--literata); }
:root[data-font="literata"] .post :is(h1, h2, h3, h4, h5, h6),
:root[data-font="literata"] .post-subtitle,
:root[data-font="literata"] .post-meta,
:root[data-font="literata"] .post-share,
:root[data-font="literata"] .post figcaption { font-family: var(--body-font); }
:root[data-font="merriweather"] .post { font-family: var(--merriweather); }
:root[data-font="merriweather"] .post :is(h1, h2, h3, h4, h5, h6),
:root[data-font="merriweather"] .post-subtitle,
:root[data-font="merriweather"] .post-meta,
:root[data-font="merriweather"] .post-share,
:root[data-font="merriweather"] .post figcaption { font-family: var(--body-font); }
/* parts in --body-font or --mono take body's x-height, not .post's */
.post :is(h1, h2, h3, h4, h5, h6, code, pre, kbd, samp),
.post-subtitle, .post-meta, .post-share,
.post figcaption { font-size-adjust: .486; }

/* Share bar (share-icons.html sprite), under the byline and at the foot
   of a post. */
.share-sprite { display: none; }
.post-share { display: flex; align-items: center; flex-wrap: wrap; gap: .55rem;
              margin: 2.5rem 0 0; padding-top: 1.6rem;
              border-top: 1px solid var(--line); }
/* the copy under the byline has no top rule */
.post-meta + .post-share { margin: 0 0 2rem; padding-top: 0; border-top: 0; }
.related { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.related .page-title { font-size: 1.6rem; margin: 1rem 0; }
.share-label { color: var(--muted); font-size: .9rem; margin-right: .2rem; }
.share-link { display: inline-flex; align-items: center; justify-content: center;
              width: 2.1rem; height: 2.1rem; border: 1px solid var(--line);
              border-radius: 999px; color: var(--muted); }
/* network logos are not recoloured with the accent (brand guidelines);
   only the ring is */
.share-link:hover { color: var(--ink); border-color: var(--accent);
                    text-decoration: none; }
.share-icon { width: 1.05rem; height: 1.05rem; fill: currentColor; }

/* Click-to-zoom (image-zoom.html marks only images whose original is
   larger than shown as .zoomable). */
.post img.zoomable { cursor: zoom-in; }
.post img.zoomable:focus-visible { outline: 2px solid var(--accent);
                                   outline-offset: 3px; }
.zoom-dialog { width: 100%; height: 100%; max-width: 100%; max-height: 100%;
               margin: 0; padding: 0; border: 0; background: none;
               color: #f2f2f2; cursor: zoom-out;
               display: none; flex-direction: column; align-items: center;
               justify-content: center; gap: .75rem; overflow: hidden; }
.zoom-dialog[open] { display: flex; }
.zoom-dialog::backdrop { background: rgba(0, 0, 0, .85); }
/* white behind transparency, as for .post img */
.zoom-dialog img { max-width: 94vw; max-height: 88vh; width: auto;
                   height: auto; border-radius: 4px; background: #fff; }
.zoom-caption { max-width: 60ch; margin: 0; padding: 0 1rem;
                text-align: center; font-size: .9rem; }
.zoom-caption[hidden] { display: none; }
@keyframes zoom-open { from { opacity: 0; transform: scale(.97); } }
@keyframes backdrop-open { from { opacity: 0; } }
.zoom-dialog[open] img { animation: zoom-open .18s ease-out; }
.zoom-dialog[open]::backdrop { animation: backdrop-open .18s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .zoom-dialog[open] img, .zoom-dialog[open]::backdrop { animation: none; }
}

.term-list { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.5rem 0 3rem; }
.chip { background: var(--card); border: 1px solid var(--line); border-radius: 999px;
        padding: .35rem .9rem; color: var(--ink); }
.chip span { color: var(--muted); font-size: .85em; }
.chip:hover { border-color: var(--accent); text-decoration: none; }

.term-sort { margin: 1.5rem 0 0; color: var(--muted); font-size: .9rem; }
.term-sort[hidden] { display: none; }
.term-sort button { border: 1px solid var(--line); border-radius: 999px;
                    background: var(--card); color: var(--soft); font: inherit;
                    padding: .15rem .8rem; margin-left: .35rem; cursor: pointer; }
.term-sort button:hover { border-color: var(--accent); }
.term-sort button[aria-pressed="true"] { border-color: var(--accent);
                                         color: var(--ink); }
/* ~, not +: term-sort.html's script tag sits between the two */
.term-sort ~ .term-list { margin-top: .9rem; }

ul.pagination { display: flex; justify-content: center; gap: .25rem;
                list-style: none; padding: 0; margin: 0 0 3rem; }
ul.pagination .page-link { display: inline-block; padding: .35rem .8rem;
                           background: var(--card); border-radius: 6px; color: var(--ink); }
ul.pagination .page-link:hover { text-decoration-line: underline; }
ul.pagination .active .page-link { background: var(--accent); color: #fff; }
ul.pagination .disabled .page-link { color: var(--muted); opacity: .5; }

.archives { list-style: none; padding: 0; margin: 1rem 0 2rem; }
.archives time { color: var(--muted); font-variant-numeric: tabular-nums;
                 margin-right: .6rem; }
.archives a { color: var(--ink); }

/* Pagefind's component CSS has ID-level specificity, so overrides here
   need !important. */
#search { margin: 0 0 3rem;
          /* map Pagefind's --pf-* variables to the site palette, since
             it does not follow prefers-color-scheme itself */
          --pf-text: var(--ink); --pf-text-secondary: var(--soft);
          --pf-text-muted: var(--muted); --pf-background: var(--card);
          --pf-border: var(--line); --pf-skeleton: var(--code-bg);
          --pf-hover: var(--code-bg); --pf-mark: var(--ink);
          --pf-error-bg: var(--error-bg); --pf-error-border: var(--error-line);
          --pf-error-text: var(--error-ink);
          --pf-error-text-secondary: var(--error-soft); }
#search mark { color: inherit; border-radius: 2px; padding: 0 .12em;
               background: var(--mark) !important; }
#search .pf-result-title { margin-bottom: .2rem; }
#search .pf-result-link { font-size: 1.25rem !important;
                          font-weight: 700 !important;
                          color: var(--ink) !important; }
#search .pf-result-excerpt { color: var(--soft) !important; }
#search .pf-heading-link { font-size: .92rem !important;
                           font-weight: 600 !important;
                           color: var(--ink) !important; }
#search .pf-heading-excerpt { color: var(--muted) !important;
                              font-size: .9rem !important; }
/* Newsletter band. The HubSpot form renders in its own iframe, so
   newsletter.html styles it from these tokens and unhides the band. */
.newsletter { background: var(--card); border-top: 1px solid var(--line);
              margin-top: 3rem; padding: 2.5rem 0; }
.newsletter[hidden] { display: none; }
.newsletter h2 { font-size: 1.6rem; font-weight: 400; line-height: 1.25;
                 margin: 0 0 1.5rem; }
/* the footer (site.toml "footer") is Markdown and may arrive wrapped
   in a <p> */
.site-footer { color: var(--muted); font-size: .85rem; padding-top: 1rem;
               padding-bottom: 2.5rem; }
.site-footer p { margin: 0; }
