/* ==========================================================================
   LogBeetle blog design system.

   Plain CSS on purpose. The blog is generated static HTML and is not part of the SPA bundle,
   so this file never passes through Tailwind. Every visual decision for a post lives here, and
   a post file carries none: authors write semantic HTML plus the closed class vocabulary in
   vite-plugins/blog/vocabulary.ts. Restyling the blog means editing this file and nothing else.

   The token block below is a hand-maintained transcription of the @theme static block in
   src/index.css, the same arrangement mobile/src/global.css already uses.
   src/design-system/token-parity.test.ts fails when the three drift apart.
   ========================================================================== */

:root {
  --font-sans: InterVariable, ui-sans-serif, system-ui, sans-serif;
  --font-display: 'Archivo', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'Space Mono', ui-monospace, 'SFMono-Regular', monospace;

  --color-paper: #f2f0eb;
  --color-panel: #ffffff;
  --color-sunk: #eceae3;
  --color-ink: #0a0a0a;
  --color-hair: rgba(10, 10, 10, 0.13);
  --color-line-3: rgba(10, 10, 10, 0.22);

  --color-brand: #d6ff00;
  --color-brand-ink: #0a0a0a;
  --color-danger: #ff3b30;

  --color-cat-1-fill: #eef9c9;
  --color-cat-1-solid: #d6ff00;
  --color-cat-2-fill: #d4f6ea;
  --color-cat-2-solid: #6ee7c8;
  --color-cat-3-fill: #ece0ff;
  --color-cat-3-solid: #c9a9ff;
  --color-cat-4-fill: #fff0c2;
  --color-cat-4-solid: #ffd84d;
  --color-cat-5-fill: #d9eefe;
  --color-cat-5-solid: #7cc4ff;
  --color-cat-6-fill: #ffe0d4;
  --color-cat-6-solid: #ff9f7a;
  /* Blog only. The app cycles six accents, the blog carries seven categories. */
  --color-cat-7-fill: #ffd6ee;
  --color-cat-7-solid: #f472b6;

  --border-width-nb: 3px;
  --border-width-nb-2: 2px;
  --border-width-hair: 1.5px;
  --radius-nb: 12px;
  --radius-nb-lg: 16px;
  --radius-nb-pill: 999px;

  --shadow-hard-sm: 2px 2px 0 0 var(--color-ink);
  --shadow-hard: 4px 4px 0 0 var(--color-ink);
  --shadow-hard-lg: 6px 6px 0 0 var(--color-ink);

  --motion-duration-fast: 150ms;
  --motion-duration-base: 250ms;
  --ease-nb: cubic-bezier(0, 0, 0.2, 1);

  /* Reading measure. 38rem is about 68-71 characters at the body size, the range that holds up
     over a long article. Change it here and every track follows. */
  --post-measure: 38rem;
  --post-wide: 60rem;
  --post-gutter: 1.5rem;

  color-scheme: light;
}

/* The theme boot script from index.html puts .dark on <html>, the same as the app. */
.dark {
  --color-paper: #0a0a0a;
  --color-panel: #131313;
  --color-sunk: #1c1c1c;
  --color-ink: #f2f0eb;
  --color-hair: rgba(242, 240, 235, 0.12);
  --color-line-3: rgba(242, 240, 235, 0.3);

  --shadow-hard-sm: 2px 2px 0 0 #f2f0eb;
  --shadow-hard: 4px 4px 0 0 #f2f0eb;
  --shadow-hard-lg: 6px 6px 0 0 #f2f0eb;

  --color-cat-1-fill: #12414d;
  --color-cat-2-fill: #0b5f50;
  --color-cat-3-fill: #43307a;
  --color-cat-4-fill: #6b5210;
  --color-cat-4-solid: #ffd84d;
  --color-cat-5-fill: #154d78;
  --color-cat-6-fill: #7a3c20;
  --color-cat-7-fill: #7a2352;

  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   Base. No Tailwind preflight here, so the few resets the pages rely on are explicit.
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-paper);
}

h1,
h2,
h3,
h4,
p,
pre,
figure,
figcaption,
blockquote,
dl,
dd,
ul,
ol {
  margin: 0;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 2px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* --------------------------------------------------------------------------
   Page chrome. The template emits every class below. A post never contains one.
   -------------------------------------------------------------------------- */

.blog-skip-link {
  position: absolute;
  left: -9999px;
}

.blog-skip-link:focus-visible {
  left: 1rem;
  top: 1rem;
  z-index: 10;
  padding: 0.5rem 0.875rem;
  background: var(--color-brand);
  color: var(--color-brand-ink);
  border: var(--border-width-nb) solid var(--color-brand-ink);
  border-radius: var(--radius-nb);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: none;
}

.blog-footer {
  padding: 1.25rem var(--post-gutter);
}

.blog-header {
  /* 1.125rem is the app navbar's 0.625rem row padding plus its 0.5rem item padding. With the
     1.75em tile that puts the blog header on the same 65.25px as the app chrome, so moving
     between the two does not shift the page down or up. */
  padding: 1.125rem var(--post-gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  border-bottom: var(--border-width-nb) solid var(--color-ink);
}

/* The same proportions as <BrandLockup>: a 1.75em tile and a 0.5em gap off a 15px root. */
.blog-lockup {
  display: flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.blog-lockup a {
  text-decoration: none;
}

.blog-mark {
  display: flex;
}

.blog-mark svg {
  width: 1.75em;
  height: 1.75em;
}

.blog-header nav,
.blog-footer nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

.blog-header nav a,
.blog-footer nav a,
.blog-footer p {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

/* Underlined like every link in the app chrome, and the line drops on hover (docs/design-system.md,
   "A borderless control is underlined"). Prose links in .post-body keep their own treatment. */
.blog-header nav a,
.blog-footer nav a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.blog-header nav a:hover,
.blog-footer nav a:hover {
  text-decoration: none;
}

.blog-footer {
  margin-top: 4rem;
  border-top: var(--border-width-nb) solid var(--color-ink);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
}

.blog-page {
  flex: 1;
  width: 100%;
  margin: 0 auto;
  padding: 3rem 0;
}

/* Listing and post pages that are not the article body keep a plain centred column. */
.blog-page > :not(.post-body) {
  max-width: var(--post-wide);
  margin-inline: auto;
  padding-inline: var(--post-gutter);
}

.blog-page-header {
  margin-bottom: 2.5rem;
}

.blog-page-header > p:first-child {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.blog-page-header h1 {
  margin-top: 0.75rem;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3rem);
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
}

.blog-page-header h1 + p {
  margin-top: 1rem;
  max-width: var(--post-measure);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: color-mix(in oklab, var(--color-ink) 70%, transparent);
}

.blog-post-header {
  max-width: var(--post-measure) !important;
  margin-bottom: 2.5rem;
  padding-bottom: 1.75rem;
  border-bottom: var(--border-width-nb) solid var(--color-ink);
}

.blog-post-header h1 {
  margin-top: 1rem;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(2rem, 1.3rem + 3vw, 3.25rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
  hyphens: auto;
  overflow-wrap: break-word;
}

.blog-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 0.75rem;
  margin-top: 1rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.blog-meta > * + *::before {
  content: '/ ';
}

.blog-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.blog-pill {
  /* A badge is a fill with no border (docs/design-system.md, "Surface tiers"). */
  padding: 0.1875rem 0.5rem;
  border-radius: var(--radius-nb-pill);
  background: var(--color-cat-1-fill);
  color: var(--color-ink);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
}

.blog-pill[data-cat='2'] {
  background: var(--color-cat-2-fill);
}
.blog-pill[data-cat='3'] {
  background: var(--color-cat-3-fill);
}
.blog-pill[data-cat='4'] {
  background: var(--color-cat-4-fill);
}
.blog-pill[data-cat='5'] {
  background: var(--color-cat-5-fill);
}
.blog-pill[data-cat='6'] {
  background: var(--color-cat-6-fill);
}
.blog-pill[data-cat='7'] {
  background: var(--color-cat-7-fill);
}

/* The dark tint of the lime goes muddy, so cat-1 uses the solid there, as the app does. */
.dark .blog-pill[data-cat='1'] {
  background: var(--color-cat-1-solid);
  color: var(--color-brand-ink);
}

.blog-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}

@media (min-width: 44rem) {
  .blog-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.blog-card {
  position: relative;
  padding: 1.5rem;
  /* Tier 2: a 2px border and no shadow. Hover is a tint, never a shadow. */
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb-lg);
  background: var(--color-panel);
  transition: background-color var(--motion-duration-fast) var(--ease-nb);
}

.blog-card:has(a:hover),
.blog-card:has(a:focus-visible) {
  background: var(--color-sunk);
}

.blog-card h2 {
  margin-top: 1rem;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.375rem;
  line-height: 1.1;
  text-transform: uppercase;
  text-wrap: balance;
}

/* One real link for assistive tech, the whole card clickable for everyone else. */
.blog-card h2 a {
  text-decoration: none;
}

.blog-card h2 a::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.blog-card h2 + p {
  margin-top: 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: color-mix(in oklab, var(--color-ink) 70%, transparent);
}

/* The pills sit above the stretched link, so they stay individually clickable. */
.blog-card .blog-pill-row {
  position: relative;
  z-index: 1;
}

.blog-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
}

.blog-pagination a,
.blog-pagination span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

.blog-pagination a,
.blog-pagination [aria-disabled='true'] {
  /* The flat secondary button: a 2px border and no shadow. */
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb);
  background: var(--color-panel);
}

.blog-pagination [aria-disabled='true'] {
  color: color-mix(in oklab, var(--color-ink) 40%, transparent);
}

.blog-pagination a:hover {
  background: var(--color-sunk);
}

.blog-pagination a:active {
  transform: translate(1px, 1px);
}

.blog-draft-ribbon {
  max-width: var(--post-wide);
  margin: 0 auto 1.5rem;
  padding: 0.625rem 1rem;
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb);
  background: var(--color-cat-4-fill);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Article body.

   One grid with named lines, so .post-wide is a single declaration and the measure lives in
   one custom property. No vw units, so a scrollbar can never cause overflow. On a narrow
   screen the two tracks converge and .post-wide degrades with no media query.
   -------------------------------------------------------------------------- */

.post-body {
  --track: calc((var(--post-wide) - var(--post-measure)) / 2);
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--post-gutter), 1fr)
    [wide-start] minmax(0, var(--track))
    [measure-start] min(var(--post-measure), 100% - var(--post-gutter) * 2) [measure-end]
    minmax(0, var(--track)) [wide-end]
    minmax(var(--post-gutter), 1fr) [full-end];
}

.post-body > * {
  grid-column: measure;
}

.post-body > .post-wide {
  grid-column: wide;
}

/* Vertical rhythm lives here, so an author never types a margin. */
.post-body > * + * {
  margin-top: 1.5rem;
}

.post-body > :is(h2, h3, h4) {
  margin-top: 3rem;
}

.post-body > h3 {
  margin-top: 2.25rem;
}

.post-body > h4 {
  margin-top: 1.75rem;
}

.post-body > :is(h2, h3, h4) + * {
  margin-top: 0.75rem;
}

.post-body
  > :is(
    figure,
    pre,
    blockquote,
    .post-quote,
    .post-callout,
    .post-cta,
    .post-stats,
    .post-table,
    .post-code
  ) {
  margin-top: 2.25rem;
}

.post-body > hr {
  margin-block: 3rem;
}

.post-body > .post-footnotes {
  margin-top: 3.5rem;
}

.post-body > :first-child {
  margin-top: 0;
}

/* :where() keeps bare elements at class-level specificity, so a component class always wins
   without !important and without depending on rule order. */
.post-body :where(p) {
  font-size: clamp(1.0625rem, 0.98rem + 0.35vw, 1.125rem);
  line-height: 1.7;
  text-wrap: pretty;
}

.post-body :where(h2, h3, h4) {
  font-family: var(--font-display);
  text-transform: uppercase;
  text-wrap: balance;
  hyphens: auto;
  overflow-wrap: break-word;
  scroll-margin-top: 2rem;
}

.post-body :where(h2) {
  font-weight: 900;
  font-size: clamp(1.625rem, 1.35rem + 1.2vw, 2.125rem);
  line-height: 1.02;
  letter-spacing: -0.01em;
}

.post-body :where(h3) {
  font-weight: 700;
  font-size: clamp(1.1875rem, 1.1rem + 0.35vw, 1.375rem);
  line-height: 1.15;
}

/* h4 steps down by family rather than size, the same ladder PageHeader uses. */
.post-body :where(h4) {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.post-body :where(ul, ol) {
  padding-inline-start: 1.35em;
}

.post-body :where(ul) {
  list-style: square;
}

.post-body :where(li) {
  font-size: clamp(1.0625rem, 0.98rem + 0.35vw, 1.125rem);
  line-height: 1.7;
}

.post-body :where(li + li),
.post-body :where(li > ul),
.post-body :where(li > ol) {
  margin-top: 0.5rem;
}

.post-body :where(ul li)::marker {
  color: var(--color-ink);
}

.post-body :where(ol li)::marker {
  font-family: var(--font-mono);
  font-weight: 700;
}

.post-body :where(blockquote) {
  padding-inline-start: 1.25rem;
  border-inline-start: var(--border-width-nb) solid var(--color-ink);
  color: color-mix(in oklab, var(--color-ink) 80%, transparent);
}

.post-body :where(pre) {
  padding: 1rem 1.125rem;
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb);
  background: var(--color-sunk);
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  line-height: 1.6;
  tab-size: 2;
}

.post-body :where(code) {
  padding: 0.1em 0.35em;
  border-radius: 6px;
  background: var(--color-sunk);
  font-family: var(--font-mono);
  font-size: 0.875em;
}

/* A border on inline code would make the lines ragged, so only the block form gets one. */
.post-body :where(pre code) {
  padding: 0;
  background: none;
  font-size: inherit;
}

.post-body :where(a) {
  text-decoration: underline;
  text-decoration-color: var(--color-brand);
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: auto;
}

.post-body :where(a):hover {
  background: var(--color-brand);
  color: var(--color-brand-ink);
}

.post-body :where(strong) {
  font-weight: 800;
}

.post-body :where(hr) {
  height: 0;
  border: 0;
  border-top: var(--border-width-nb) solid var(--color-ink);
  /* The UA sheet gives hr `margin-inline: auto`, which collapses it to zero width inside a
     grid track. Both declarations are needed to make it span the measure. */
  width: 100%;
  margin-inline: 0;
}

.post-body :where(img) {
  /* An image drawn narrower than its track sits centred rather than against the left edge. */
  margin-inline: auto;
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb);
  /* Transparent diagrams stay legible on near-black paper. */
  background: var(--color-panel);
}

/* Two images in one figure share the row on wide screens and stack on narrow ones. */
.post-body :where(figure:has(> img + img)) {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: 1rem;
}

.post-body :where(figure:has(> img + img) > img) {
  flex: 1 1 12rem;
  min-width: 0;
  width: auto;
  max-width: 100%;
  margin-inline: 0;
}

.post-body :where(figure:has(> img + img) > figcaption) {
  flex-basis: 100%;
}

.post-body :where(figcaption) {
  margin-top: 0.625rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.5;
  text-align: center;
  /* A centred caption that wraps would otherwise leave one short word on the last line. */
  text-wrap: balance;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.post-body :where(table) {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.post-body :where(th) {
  padding: 0.625rem 0.875rem;
  border-bottom: var(--border-width-nb) solid var(--color-ink);
  background: var(--color-sunk);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: left;
}

.post-body :where(td) {
  padding: 0.625rem 0.875rem;
  border-bottom: 1.5px solid var(--color-hair);
  font-variant-numeric: tabular-nums;
}

.post-body :where(caption) {
  padding: 0.625rem 0.875rem;
  border-bottom: 1.5px solid var(--color-hair);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: left;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.post-body :where(dt) {
  font-family: var(--font-mono);
  font-weight: 700;
  text-transform: uppercase;
}

.post-body :where(dd) {
  margin-inline-start: 1rem;
  color: color-mix(in oklab, var(--color-ink) 80%, transparent);
}

.post-body :where(sup a) {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-decoration: none;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

/* Metadata that ended up outside the leading block can never paint. */
.post-body :where(meta) {
  display: none;
}

/* --------------------------------------------------------------------------
   Post components. The closed vocabulary an author may use.
   -------------------------------------------------------------------------- */

.post-lede {
  font-size: clamp(1.25rem, 1.13rem + 0.5vw, 1.4375rem) !important;
  line-height: 1.55 !important;
}

.post-anchor {
  margin-inline-start: 0.35em;
  font-family: var(--font-mono);
  font-weight: 400;
  text-decoration: none;
  color: color-mix(in oklab, var(--color-ink) 25%, transparent);
}

:is(h2, h3, h4):hover .post-anchor,
.post-anchor:focus-visible {
  color: var(--color-ink);
}

/* Always visible where there is no hover to reveal it. */
@media (hover: none) {
  .post-anchor {
    color: color-mix(in oklab, var(--color-ink) 45%, transparent);
  }
}

.post-callout {
  padding: 1rem 1.125rem;
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb);
  background: var(--color-sunk);
}

.post-callout > * + * {
  margin-top: 0.5rem;
}

.post-callout__title {
  font-family: var(--font-mono);
  font-size: 0.6875rem !important;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.post-callout--warning {
  background: var(--color-cat-4-fill);
}

/* Mixing against --color-panel means the fill follows the theme with no dark rule. */
.post-callout--danger {
  border-color: var(--color-danger);
  background: color-mix(in oklab, var(--color-danger) 10%, var(--color-panel));
}

.post-quote {
  padding-inline-start: 1.25rem;
  border-inline-start: var(--border-width-nb) solid var(--color-brand);
}

.post-quote p {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.3rem + 0.9vw, 1.875rem) !important;
  line-height: 1.2 !important;
  text-wrap: balance;
}

.post-quote cite {
  display: block;
  margin-top: 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-style: normal;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.post-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

/* A column with the number pushed down, so labels of one, two or three lines all sit their
   number on the same baseline across the row. */
.post-stats > div {
  display: flex;
  flex: 1 1 8rem;
  flex-direction: column;
  gap: 0.375rem;
  padding: 1rem;
  /* Tier 3 tiles: the 1.5px line. */
  border: var(--border-width-hair) solid var(--color-line-3);
  border-radius: var(--radius-nb);
  background: var(--color-panel);
}

.post-stats dt {
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  color: color-mix(in oklab, var(--color-ink) 60%, transparent);
}

.post-stats dd {
  margin: auto 0 0;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--color-ink);
}

.post-cta {
  padding: 1.5rem;
  border: var(--border-width-nb) solid var(--color-brand-ink);
  border-radius: var(--radius-nb-lg);
  background: var(--color-brand);
  color: var(--color-brand-ink);
  box-shadow: 4px 4px 0 0 rgba(10, 10, 10, 0.25);
}

.post-cta p {
  color: var(--color-brand-ink);
}

.post-cta > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-top: 1rem;
  padding: 0 1.125rem;
  border: var(--border-width-nb) solid var(--color-brand-ink);
  border-radius: var(--radius-nb);
  background: var(--color-panel);
  color: var(--color-ink);
  box-shadow: 4px 4px 0 0 rgba(10, 10, 10, 0.25);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

.post-cta > a:hover {
  background: var(--color-panel);
}

.post-cta > a:active {
  transform: translate(2px, 2px);
  box-shadow: none;
}

/* Ink goes bone-white in dark mode and would disappear on the lime. */
.post-cta :focus-visible {
  outline-color: var(--color-brand-ink);
}

.post-code figcaption {
  /* The tab opens the figure, so it drops the gap a figure caption normally sits below. */
  margin-top: 0;
  padding: 0.375rem 0.875rem;
  width: fit-content;
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-bottom: 0;
  border-radius: var(--radius-nb) var(--radius-nb) 0 0;
  background: var(--color-sunk);
  color: var(--color-ink);
}

.post-code pre {
  border-start-start-radius: 0;
}

.post-table {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border: var(--border-width-nb-2) solid var(--color-ink);
  border-radius: var(--radius-nb);
}

.post-table :where(td):last-child,
.post-table :where(th):last-child {
  border-inline-end: 0;
}

.post-footnotes {
  padding-top: 1.5rem;
  border-top: var(--border-width-nb) solid var(--color-ink);
  font-size: 0.875rem;
  color: color-mix(in oklab, var(--color-ink) 70%, transparent);
}

.post-footnotes li::marker {
  font-family: var(--font-mono);
}

.post-footnotes li:target {
  background: var(--color-cat-1-fill);
}

.post-footnotes li {
  scroll-margin-top: 2rem;
}

@media (prefers-reduced-motion: reduce) {
  .blog-card,
  .blog-pagination a,
  .post-cta > a {
    transition: none;
  }
}
