/* ============================================================
   Fonts
   ============================================================ */

@font-face {
  font-family: "Euclid Circular";
  src: url("../fonts/EuclidCircularB-Regular-WebXL.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Euclid Circular";
  src: url("../fonts/EuclidCircularB-Medium-WebXL.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Euclid Circular";
  src: url("../fonts/EuclidCircularB-Semibold-WebXL.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Euclid Flex";
  src: url("../fonts/EuclidFlex-Semibold-WebXL.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Euclid Flex Medium";
  src: url("../fonts/EuclidFlex-Medium-WebXL.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Euclid Mono Vanguard";
  src: url("../fonts/EuclidMono-Vanguard-WebXL.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* ============================================================
   Tokens
   ============================================================ */

:root {
  --font-sans: "Euclid Circular", sans-serif;
  --font-heading: "Euclid Flex", "Euclid Circular", sans-serif;
  --font-heading-medium: "Euclid Flex Medium", "Euclid Circular", sans-serif;
  --font-mono: ui-monospace, Menlo, monospace;
  --font-euclid-mono: "Euclid Mono Vanguard", ui-monospace, Menlo, monospace;

  --color-accent: #2e5d50;
  --color-ink: #111111;
  --color-body: #3a3a35;
  --color-muted: #66665f;
  --color-faint: #71716b;
  --color-bg-soft: #f7f6f3;
  --color-line: #e4e2dc;
  --color-line-soft: #edece7;
  --color-surface-dark: #111111;

  --width-container: 880px;
  --width-prose: 620px;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Belt-and-suspenders with body's own overflow-x: hidden below — iOS
     Safari's rubber-band overscroll can still reveal a descendant that
     overflows if only body is constrained, since the visual viewport pans
     against html, not body. */
  overflow-x: hidden;
}

body {
  margin: 0;
  overflow-x: hidden;
  background: #ffffff;
  color: var(--color-body);
  font-family: var(--font-sans);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading), sans-serif; margin: 0; }

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

a { color: inherit; text-decoration: none; }

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

.site-main { flex: 1 0 auto; }

/* ============================================================
   Header
   ============================================================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid var(--color-line);
  background: rgba(255, 255, 255, 0.98);
  backdrop-filter: blur(10px);
}

.site-header-inner {
  margin: 0 auto;
  max-width: 1280px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 22px 24px;
}

@media (min-width: 1024px) {
  .site-header-inner { padding-left: 48px; padding-right: 48px; }
}

.site-header-logo { display: flex; align-items: center; }

.logo-full { display: none; height: 51px; width: auto; }
.logo-emblem { display: block; height: 48px; width: 48px; }

@media (min-width: 360px) {
  .logo-full { display: block; }
  .logo-emblem { display: none; }
}

.site-header-home-link {
  display: flex;
  align-items: center;
  height: 51px;
  border: 1px solid var(--color-ink);
  padding: 0 28px;
  font-size: 15px;
  font-weight: 500;
  color: var(--color-ink);
  transition: color 150ms, border-color 150ms;
}
.site-header-home-link:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

/* ============================================================
   Footer
   ============================================================ */

.site-footer {
  margin-top: auto;
  background: var(--color-surface-dark);
  color: #ffffff;
  padding: 56px 0 40px;
}

.site-footer-inner { margin: 0 auto; max-width: 1280px; padding: 0 24px; }

@media (min-width: 1024px) {
  .site-footer-inner { padding-left: 48px; padding-right: 48px; }
}

.site-footer-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}

.site-footer-logo {
  height: 32px;
  width: auto;
  filter: brightness(0) invert(1);
}

.site-footer-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 32px; }
.site-footer-nav a {
  font-size: 15px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.7);
  transition: color 150ms;
}
.site-footer-nav a:hover { color: #ffffff; }

.site-footer-bottom {
  margin-top: 44px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  padding-top: 24px;
}

.site-footer-copyright,
.site-footer-links {
  font-family: var(--font-euclid-mono);
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.55);
}
.site-footer-links a { transition: color 150ms; }
.site-footer-links a:hover { color: #ffffff; }

/* ============================================================
   Blog index
   ============================================================ */

.blog-index { margin: 0 auto; max-width: var(--width-container); padding: 64px 24px 96px; }

.blog-index-header { margin-top: 8px; border-top: 2px solid var(--color-ink); padding-top: 18px; }

.blog-index-title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
}

.blog-index-title-row h1 {
  font-size: 30px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--color-ink);
}
@media (min-width: 640px) {
  .blog-index-title-row h1 { font-size: 40px; }
}

.locale-switch {
  font-family: var(--font-euclid-mono);
  font-size: 13px;
  color: var(--color-accent);
  text-underline-offset: 2px;
}
.locale-switch:hover { text-decoration: underline; }

.blog-index-intro { margin-top: 18px; max-width: var(--width-prose); font-size: 16px; line-height: 1.7; color: var(--color-body); }
.blog-index-empty { margin-top: 44px; font-size: 16px; line-height: 1.7; color: var(--color-body); }
.blog-index-empty a { color: var(--color-accent); text-underline-offset: 2px; }
.blog-index-empty a:hover { text-decoration: underline; }

.post-list {
  margin-top: 44px;
  display: grid;
  grid-template-columns: 1fr;
  border-left: 1px solid var(--color-line);
  border-top: 1px solid var(--color-line);
}

.post-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-bottom: 1px solid var(--color-line);
  border-right: 1px solid var(--color-line);
  background: #ffffff;
  padding: 28px;
  transition: background-color 150ms;
}
.post-card:hover { background: var(--color-bg-soft); }

.post-card-featured { border-left: 3px solid var(--color-accent); padding-left: 25px; }

.post-card-featured-label {
  margin: 0;
  font-family: var(--font-euclid-mono);
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-accent);
}

.post-card-meta {
  font-family: var(--font-euclid-mono);
  font-size: 13px;
  color: var(--color-faint);
}

.post-card-title { margin: 0; font-size: 22px; font-weight: 600; line-height: 1.25; color: var(--color-ink); }

.post-card-excerpt { margin: 0; max-width: var(--width-prose); font-size: 16px; line-height: 1.7; color: var(--color-body); }

/* ============================================================
   Article
   ============================================================ */

.article { margin: 0 auto; max-width: var(--width-container); padding: 64px 24px 96px; }

.article-top-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.article-back-link {
  font-family: var(--font-euclid-mono);
  font-size: 13px;
  color: var(--color-faint);
  transition: color 150ms;
}
.article-back-link:hover { color: var(--color-accent); }

.article-byline {
  margin-top: 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.article-byline-left { display: flex; align-items: center; gap: 10px; }

.article-avatar {
  height: 28px;
  width: 28px;
  border-radius: 9999px;
  border: 1px solid var(--color-line);
  object-fit: cover;
  filter: grayscale(1) contrast(1.04);
}

.article-byline-text { font-family: var(--font-euclid-mono); font-size: 13px; color: var(--color-faint); }

.article-kicker {
  margin: 20px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}
.article-kicker-tag {
  font-family: var(--font-euclid-mono);
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-accent);
}
.article-kicker-tag:not(:last-child)::after {
  content: "·";
  display: inline-block;
  margin: 0 8px;
  color: var(--color-faint);
  font-weight: 400;
}

.article-title {
  margin-top: 10px;
  font-size: 32px;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--color-ink);
  text-wrap: balance;
}
.article-kicker + .article-title { margin-top: 10px; }
h1.article-title:first-of-type { margin-top: 16px; }
@media (min-width: 640px) {
  .article-title { font-size: 44px; }
}

.article-lede {
  margin-top: 24px;
  max-width: var(--width-prose);
  font-size: 18px;
  line-height: 1.6;
  color: var(--color-body);
  text-wrap: pretty;
}
@media (min-width: 1024px) {
  .article-lede { font-size: 19px; }
}

.article-cover {
  margin-top: 40px;
  aspect-ratio: 16 / 9;
  width: 100%;
  border: 1px solid var(--color-line);
  object-fit: cover;
  filter: grayscale(1) contrast(1.04);
}

/* ============================================================
   Article body typography (Koenig / imported HTML output)
   ============================================================ */

.post-content { margin-top: 40px; }

.post-content > * + * { margin-top: 20px; }

.post-content h2 {
  margin: 48px auto 16px;
  max-width: var(--width-prose);
  scroll-margin-top: 112px;
  font-family: var(--font-heading-medium), sans-serif;
  font-size: 24px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--color-ink);
}
.post-content h2:first-child { margin-top: 0; }

.post-content h3 {
  margin: 36px auto 12px;
  max-width: var(--width-prose);
  scroll-margin-top: 112px;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-ink);
}

/* Revealed on hover of the heading it belongs to — a plain hash-link
   rather than a copy-to-clipboard button: clicking it navigates to the
   anchor and puts the shareable URL straight in the address bar. */
.heading-anchor {
  margin-left: 8px;
  vertical-align: middle;
  font-size: 0.75em;
  font-weight: 400;
  color: var(--color-faint);
  text-decoration: none;
  opacity: 0;
  transition: opacity 150ms, color 150ms;
}
.heading-anchor:hover { color: var(--color-accent); }
.post-content h2:hover .heading-anchor,
.post-content h3:hover .heading-anchor { opacity: 1; }
@media print { .heading-anchor { display: none; } }

.post-content p {
  max-width: var(--width-prose);
  margin-left: auto;
  margin-right: auto;
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-body);
}

.post-content a { color: var(--color-accent); text-underline-offset: 2px; transition: color 150ms; }
.post-content a:hover { text-decoration: underline; }

.post-content ul,
.post-content ol {
  max-width: var(--width-prose);
  margin-left: auto;
  margin-right: auto;
  padding-left: 20px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--color-body);
}
.post-content ul { list-style: disc; }
.post-content ol { list-style: decimal; }
.post-content li { margin-top: 8px; }
.post-content li::marker { color: var(--color-accent); }

.post-content blockquote {
  max-width: var(--width-prose);
  margin-left: auto;
  margin-right: auto;
  border-left: 2px solid var(--color-accent);
  padding: 4px 0 4px 20px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--color-ink);
}

.lede code {
  background: var(--color-bg-soft);
  padding: 2px 6px;
  font-family: var(--font-mono);
  font-size: 0.9em;
  color: var(--color-ink);
}

.post-content :not(pre) > code {
  background: var(--color-bg-soft);
  padding: 2px 6px;
  font-family: var(--font-mono);
  font-size: 0.9em;
  color: var(--color-ink);
  border-radius: 0;
}

.post-content pre {
  position: relative;
  overflow-x: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--color-surface-dark);
  padding: 20px;
}
.post-content pre code {
  background: transparent;
  padding: 0;
  font-family: var(--font-mono);
  font-size: 13.5px;
  line-height: 1.65;
  color: #ffffff;
}

.post-content hr { max-width: var(--width-prose); margin: 40px auto; border: none; border-top: 1px solid var(--color-line); }

.post-content figure,
.post-content .kg-card {
  /* Browsers default <figure> to margin: 1em 40px — additional to width:
     100%, not part of it, so those 40px push the figure past its
     container's right edge instead of just eating into its own padding.
     Barely visible on desktop (plenty of surrounding whitespace to absorb
     it), but on mobile .post-content already spans the full available
     width, so the extra margin overflows the viewport — exactly what made
     images and code blocks scrollable off-screen on a phone. */
  margin: 0;
  width: 100%;
}

.post-content figcaption {
  margin-top: 12px;
  text-align: center;
  font-size: 13px;
  line-height: 1.65;
  color: var(--color-faint);
}

.post-content table {
  /* Ghost's table card wraps this in its own markup, not a `.table-wrap`
     div this theme never actually emits — targeting the table itself is
     what actually applies regardless of what wraps it. `display: block`
     on <table> keeps the normal table layout algorithm for its
     thead/tbody/td descendants (still a real table internally) while
     letting the outer box scroll horizontally instead of squeezing every
     column into unreadable slivers on a narrow screen, which is what was
     happening before this rule existed. */
  display: block;
  width: 100%;
  overflow-x: auto;
  margin-top: 24px;
  border: 1px solid var(--color-line);
  border-collapse: collapse;
  text-align: left;
  font-size: 15px;
}
/* !important, and repeated on every descendant: tables typed straight
   into Ghost's editor (there's no native table card — Koenig just keeps
   whatever HTML got pasted in as-is) routinely arrive from Google Docs
   carrying a `style="font-family: -apple-system, ..."` on the <table>
   itself and often on every individual <td> too. An inline style beats
   any selector here regardless of specificity, so the only way to
   actually guarantee "no font outside the brand book" is to out-rank it
   with !important — confirmed via a real post's inspected DOM that this
   is genuinely an inline attribute, not something to fix by tweaking a
   selector. */
.post-content table,
.post-content table * {
  font-family: var(--font-sans) !important;
}
.post-content th {
  border-bottom: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: 12px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-faint);
}
.post-content td {
  border-bottom: 1px solid var(--color-line-soft);
  padding: 12px 16px;
  vertical-align: top;
  line-height: 1.65;
  color: var(--color-body);
}

@media (max-width: 640px) {
  /* Horizontal scroll works fine for tables of short values, but this
     project's tables tend to have a prose-heavy last column (see the
     Hetzner posts) — scrolling sideways mid-sentence to keep reading is
     worse than just stacking each row as label/value pairs instead.
     main.js's setupResponsiveTables() supplies the data-label attribute
     the ::before below reads (the raw imported HTML has no per-cell
     labels of its own). */
  .post-content table,
  .post-content thead,
  .post-content tbody,
  .post-content tr,
  .post-content th,
  .post-content td {
    display: block;
    width: 100%;
  }
  .post-content table { overflow-x: visible; }
  .post-content thead { display: none; }
  .post-content tr {
    border-bottom: 1px solid var(--color-line);
  }
  .post-content tr:last-child { border-bottom: none; }
  .post-content td {
    border-bottom: none;
    padding: 10px 16px;
  }
  .post-content td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 4px;
    /* Inherits Euclid Circular, same as the rest of the table. */
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--color-faint);
  }
}

.post-content .pullquote,
.pullquote {
  max-width: 100%;
  margin-top: 32px;
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: 24px 28px;
}
.pullquote-label {
  font-family: var(--font-euclid-mono);
  font-size: 13px;
  font-weight: 500;
  color: var(--color-faint);
}
.pullquote-body { margin-top: 8px; font-size: 16px; font-weight: 500; line-height: 1.65; color: var(--color-ink); }

/* ============================================================
   Baseline styling for native Koenig cards we don't otherwise use
   (the migration only produces headings/paragraphs/lists/blockquotes/
   code/tables/images and the custom Pullquote HTML block, but the
   editor could add a callout or an alt-style quote later).
   ============================================================ */

.post-content .kg-callout-card {
  display: flex;
  gap: 12px;
  max-width: var(--width-prose);
  margin: 24px auto 0;
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: 16px 20px;
}
.post-content .kg-callout-emoji { flex: none; font-size: 1.2em; line-height: 1.65; }
.post-content .kg-callout-text { margin: 0; font-size: 16px; line-height: 1.65; color: var(--color-ink); }
.post-content .kg-callout-card-grey { background: var(--color-bg-soft); }
.post-content .kg-callout-card-white { background: #ffffff; }
.post-content .kg-callout-card-accent { background: rgba(46, 93, 80, 0.1); }

.post-content .kg-width-wide { max-width: 100%; }
.post-content .kg-width-full { max-width: 100vw; }

.post-content .kg-gallery-container { display: flex; flex-direction: column; max-width: 100%; }
.post-content .kg-gallery-row { display: flex; width: 100%; }
.post-content .kg-gallery-image img { width: 100%; height: 100%; object-fit: cover; }

.post-content .kg-bookmark-card { width: 100%; }
.post-content .kg-bookmark-container {
  display: flex;
  min-height: 148px;
  border: 1px solid var(--color-line);
  color: inherit;
}
.post-content .kg-bookmark-content { flex: 1 1 auto; padding: 20px; order: 1; }
.post-content .kg-bookmark-title { font-size: 15px; font-weight: 600; color: var(--color-ink); }
.post-content .kg-bookmark-description {
  margin-top: 6px;
  max-height: 3.4em;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.65;
  color: var(--color-faint);
}
.post-content .kg-bookmark-metadata { display: flex; align-items: center; gap: 8px; margin-top: 14px; font-family: var(--font-euclid-mono); font-size: 12px; color: var(--color-faint); }
.post-content .kg-bookmark-author,
.post-content .kg-bookmark-publisher { color: var(--color-faint); }
.post-content .kg-bookmark-icon { height: 16px; width: 16px; }
.post-content .kg-bookmark-thumbnail { flex: 0 0 auto; width: 220px; order: 2; }
.post-content .kg-bookmark-thumbnail img { height: 100%; width: 100%; object-fit: cover; }

.post-content .kg-blockquote-alt {
  border: none;
  padding-left: 0;
  font-family: var(--font-heading), sans-serif;
  font-style: normal;
}

/* ============================================================
   Table of contents (built by toc.js)
   ============================================================ */

.toc-box {
  container-type: inline-size;
  margin: 40px auto 0;
  max-width: var(--width-prose);
  scroll-margin-top: 152px;
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: 24px 28px;
}
.toc-label { font-family: var(--font-euclid-mono); font-size: 13px; font-weight: 500; color: var(--color-faint); }
.toc-list { margin-top: 12px; column-width: 200px; column-gap: 28px; }
.toc-entry { display: block; break-inside: avoid; padding: 4px 8px; }
.toc-entry.is-h3 { padding-left: 20px; }
.toc-entry a { display: flex; gap: 8px; align-items: baseline; font-size: 15px; line-height: 1.65; color: var(--color-body); }
.toc-num { font-family: var(--font-euclid-mono); font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--color-faint); }
.toc-entry.is-active { background: rgba(46, 93, 80, 0.1); }
.toc-entry.is-active a,
.toc-entry.is-active .toc-num { color: var(--color-accent); font-weight: 500; }
.toc-entry.is-flash { background: rgba(46, 93, 80, 0.3); }

.current-section-bar {
  position: sticky;
  top: 96px;
  z-index: 40;
  display: none;
  border-bottom: 1px solid var(--color-line);
  background: rgba(255, 255, 255, 0.98);
  backdrop-filter: blur(10px);
}
.current-section-bar.is-visible { display: block; }
.current-section-bar a {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 0;
  text-decoration: none;
}
.current-section-arrow {
  flex-shrink: 0;
  color: var(--color-faint);
  transition: color 150ms;
}
.current-section-num {
  flex-shrink: 0;
  font-family: var(--font-euclid-mono);
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--color-faint);
  transition: color 150ms;
}
.current-section-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-ink);
  transition: color 150ms;
}
.current-section-bar a:hover .current-section-arrow,
.current-section-bar a:hover .current-section-num,
.current-section-bar a:hover .current-section-text { color: var(--color-accent); }

/* ============================================================
   Reading progress / back to top
   ============================================================ */

.reading-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  height: 3px;
  width: 0;
  background: var(--color-accent);
  transition: width 100ms linear;
}

.back-to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 40;
  height: 44px;
  width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-ink);
  background: #ffffff;
  color: var(--color-ink);
  font-size: 18px;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms;
}
.back-to-top.is-visible { opacity: 1; pointer-events: auto; }

/* ============================================================
   Code copy button
   ============================================================ */

.code-copy-btn {
  position: absolute;
  right: 12px;
  top: 12px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: var(--color-surface-dark);
  padding: 4px 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  opacity: 0;
  transition: opacity 150ms;
}
.post-content pre:hover .code-copy-btn,
.code-copy-btn:focus-visible { opacity: 1; }

/* ============================================================
   Mastodon share
   ============================================================ */

.mastodon-share {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 9999px;
  background: #6364ff;
  color: #ffffff;
  font-size: 15px;
  padding: 10px 20px;
  transition: opacity 150ms;
}
.mastodon-share:hover { opacity: 0.9; }
.mastodon-share-compact { gap: 6px; padding: 7px 14px; font-size: 13px; }
.mastodon-share-standalone { margin: 32px auto 0; display: flex; width: fit-content; }

/* ============================================================
   Discuss box
   ============================================================ */

.discuss-box { max-width: var(--width-prose); margin: 24px auto 0; border: 1px solid var(--color-line); background: var(--color-bg-soft); padding: 24px 28px; }

/* ============================================================
   Subscribe CTA — accent-colored so it stands out against the
   discuss-box/related-posts around it, not just another muted section.
   ============================================================ */

.subscribe-cta {
  margin-top: 24px;
  background: var(--color-accent);
  color: #ffffff;
  padding: 28px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 28px;
}

.subscribe-cta-label {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.subscribe-form-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.subscribe-form-input {
  min-width: 220px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: transparent;
  color: #ffffff;
  font-family: var(--font-sans);
  font-size: 14px;
  padding: 10px 14px;
}
.subscribe-form-input::placeholder { color: rgba(255, 255, 255, 0.55); }
.subscribe-form-input:focus {
  outline: none;
  border-color: #ffffff;
}

.subscribe-form-button {
  border: none;
  background: #ffffff;
  color: var(--color-ink);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  padding: 10px 20px;
  cursor: pointer;
  transition: background-color 150ms;
}
.subscribe-form-button:hover { background: rgba(255, 255, 255, 0.85); }
.subscribe-form-button:disabled { cursor: default; opacity: 0.6; }

.subscribe-form-message {
  flex-basis: 100%;
  margin: 0;
  font-size: 13.5px;
  color: rgba(255, 255, 255, 0.85);
}
.subscribe-form-message[data-state="error"] { color: #ffd7d7; }

@media (max-width: 640px) {
  .subscribe-cta { padding: 24px; }
  .subscribe-form-fields { width: 100%; }
  .subscribe-form-input { flex: 1 1 auto; min-width: 0; }
}

.related-posts { margin-top: 64px; padding-top: 40px; border-top: 1px solid var(--color-line); }
.related-posts-label {
  margin: 0 0 20px;
  font-family: var(--font-euclid-mono);
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-faint);
}
.related-posts .post-list { margin-top: 0; }
.discuss-box-label { font-family: var(--font-euclid-mono); font-size: 13px; font-weight: 500; color: var(--color-faint); }
.discuss-box-text { margin-top: 8px; font-size: 15px; line-height: 1.65; }
.discuss-box-text a { color: var(--color-accent); text-underline-offset: 2px; }
.discuss-box-text a:hover { text-decoration: underline; }

/* ============================================================
   Zoomable image lightbox (built by zoomable-image.js)
   ============================================================ */

.post-content figure img,
.post-content > img { cursor: zoom-in; border: 1px solid var(--color-line); height: auto; width: 100%; }

.image-lightbox {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(17, 17, 17, 0.95);
  padding: 24px;
}
.image-lightbox.is-open { display: flex; }
.image-lightbox img { max-height: 90vh; max-width: 90vw; object-fit: contain; cursor: zoom-out; }
.image-lightbox-close {
  position: absolute;
  right: 24px;
  top: 24px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: var(--color-surface-dark);
  padding: 8px 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: #ffffff;
  cursor: pointer;
}

/* ============================================================
   Print
   ============================================================ */

@media print {
  .site-header,
  .reading-progress,
  .back-to-top,
  .mastodon-share,
  .current-section-bar,
  .article-top-nav .locale-switch,
  .code-copy-btn { display: none !important; }
  .post-content pre { border: 1px solid var(--color-line); background: #ffffff; }
  .post-content pre code { color: var(--color-ink); }
  .toc-box { break-inside: avoid; }
}
