/* Quiet terminal-inspired personal site. Static implementation. */

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

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/assets/fonts/jetbrains-mono-latin.woff2") format("woff2");
}

:root {
  --bg: #f6f4ef;
  --bg-elev: #efece4;
  --ink: #191714;
  --ink-soft: #3a342d;
  --mute: #766d62;
  --mute-soft: #b8ad9d;
  --rule: #e3ddd0;
  --accent: #9f5a25;
  --accent-soft: rgb(159 90 37 / 0.12);
  --sel: rgb(159 90 37 / 0.25);
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --sans: "Geist", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --serif: Georgia, "Times New Roman", serif;
}

:root[data-theme="dark"] {
  --bg: #11100e;
  --bg-elev: #1a1815;
  --ink: #ecebe7;
  --ink-soft: #c4bfb6;
  --mute: #7a7268;
  --mute-soft: #4a443c;
  --rule: #2a2722;
  --accent: oklch(0.74 0.13 60);
  --accent-soft: oklch(0.74 0.13 60 / 0.15);
  --sel: oklch(0.74 0.13 60 / 0.3);
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--sel);
}

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

a.link {
  text-decoration: underline;
  text-decoration-color: var(--mute-soft);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}

a.link:hover {
  color: var(--ink);
  text-decoration-color: var(--accent);
}

button,
input {
  font: inherit;
}

button {
  border: 0;
  padding: 0;
  color: inherit;
  background: none;
  cursor: pointer;
}

.shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.container {
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 0 32px;
}

.topnav {
  position: sticky;
  top: 14px;
  z-index: 30;
  margin-top: 14px;
  /* The bar itself stays invisible; the pill inside it is the surface. */
  background: transparent;
}

/* The glass is always on; scrolling only deepens it. */
.topnav-inner {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 14px 10px 18px;
  border-radius: 999px;
  border: 1px solid color-mix(in oklab, var(--rule) 75%, transparent);
  background: color-mix(in oklab, var(--bg) 55%, transparent);
  backdrop-filter: blur(14px) saturate(1.6);
  box-shadow:
    /* Inner top highlight: the sheen that reads as a glass edge. */
    inset 0 1px 0 rgb(255 255 255 / 0.55),
    0 1px 2px rgb(0 0 0 / 0.04),
    0 10px 28px -14px rgb(0 0 0 / 0.22);
  transition:
    padding 0.3s cubic-bezier(0.2, 0.7, 0.2, 1),
    background 0.3s ease,
    border-color 0.3s ease,
    box-shadow 0.3s ease,
    backdrop-filter 0.3s ease;
  animation: nav-in 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@keyframes nav-in {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
}

/* Scrolling deepens the blur but keeps the pane see-through -- raising the
   background opacity here is what killed the glass and made it a solid bar. */
.topnav.is-scrolled .topnav-inner {
  padding: 7px 14px 7px 18px;
  border-color: color-mix(in oklab, var(--rule) 100%, transparent);
  background: color-mix(in oklab, var(--bg) 62%, transparent);
  backdrop-filter: blur(22px) saturate(1.9);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.7),
    0 1px 2px rgb(0 0 0 / 0.06),
    0 14px 34px -12px rgb(0 0 0 / 0.3);
}

:root[data-theme="dark"] .topnav-inner {
  background: color-mix(in oklab, var(--bg) 48%, transparent);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.09),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 12px 30px -14px rgb(0 0 0 / 0.6);
}

:root[data-theme="dark"] .topnav.is-scrolled .topnav-inner {
  background: color-mix(in oklab, var(--bg) 56%, transparent);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.13),
    0 1px 2px rgb(0 0 0 / 0.4),
    0 16px 36px -12px rgb(0 0 0 / 0.7);
}

/* On articles the reading strip takes over the top edge; yield the pill to it. */
.shell:has(.reading-strip.is-on) .topnav {
  opacity: 0;
  pointer-events: none;
}

.topnav {
  transition: opacity 0.18s ease;
}

@media (prefers-reduced-motion: reduce) {
  .topnav,
  .topnav-inner,
  .nav-link,
  .icon-btn {
    transition: none;
    animation: none;
  }
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  overflow: hidden;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.brand .prompt,
.slug::before,
.accent {
  color: var(--accent);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  flex-shrink: 0;
}

.nav-link {
  position: relative;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12.5px;
  /* The active marker must not push the label onto a second line. */
  white-space: nowrap;
  border-radius: 999px;
  background: transparent;
  transition: color 0.15s ease, background 0.2s ease;
}

.nav-link:hover,
.nav-link.is-active {
  color: var(--ink);
}

.nav-link:hover {
  background: color-mix(in oklab, var(--rule) 40%, transparent);
}

.nav-link.is-active::before {
  content: ">";
  margin-right: 4px;
  color: var(--accent);
}

.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 0 4px 0 8px;
  padding-left: 10px;
  border-left: 1px solid var(--rule);
}

.lang-opt {
  padding: 4px 6px;
  border-radius: 5px;
  color: var(--mute-soft);
  font-family: var(--mono);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: color 0.15s ease;
}

.lang-opt:hover {
  color: var(--ink);
}

.lang-opt.is-on {
  color: var(--accent);
}

.icon-btn {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  color: var(--mute);
  transition: color 0.15s ease, background 0.2s ease;
}

.icon-btn:hover {
  color: var(--ink);
  background: color-mix(in oklab, var(--rule) 40%, transparent);
}

.icon-btn svg {
  width: 15px;
  height: 15px;
  stroke-width: 1.7;
}

.kbd {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.02em;
}

.slug {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.02em;
}

.slug::before {
  content: "/";
  font-weight: 500;
}

.term-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding-top: 6px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
}

.term-banner .ok {
  color: oklch(0.7 0.16 145);
}

.term-banner .sep {
  color: var(--mute-soft);
}

.hero {
  padding-block: 96px 56px;
}

/* One grid for the whole hero, so the portrait can change place without the
   markup moving: beside the sentence on wide screens, beside the name on
   narrow ones -- where a lone image above the text just floated. */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "id    portrait"
    "title portrait"
    "rule  rule"
    "lede  lede";
  align-items: start;
  column-gap: clamp(28px, 5vw, 56px);
}

.hero-id {
  grid-area: id;
}

.hero h1 {
  grid-area: title;
}

.hero-rule {
  grid-area: rule;
  border-top: 1px solid var(--rule);
}

/* Full measure, not the column left over beside the portrait: at 46ch this
   sentence set 39 characters a line, well under the readable 45-75 band. */
.hero .lede {
  grid-area: lede;
  margin: 32px 0 0;
  max-width: 62ch;
}

.hero .portrait {
  grid-area: portrait;
  /* It now spans the name and the claim, so it aligns to their top edge. */
  margin-top: 0;
}

/* The person behind the claim. Without this the hero has a claim and no author. */
.hero-id {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 22px;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.5;
}

.hero-id .who {
  color: var(--ink);
  letter-spacing: 0.01em;
}

.hero-id .what {
  color: var(--mute);
  font-size: 11.5px;
}

.portrait {
  position: relative;
  margin: 0;
  width: clamp(150px, 17vw, 208px);
}

/* Offset rule behind the portrait: anchors it instead of letting it float. */
.portrait::before {
  content: "";
  position: absolute;
  inset: 10px -10px auto 10px;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--accent);
  border-radius: 10px;
}

.portrait img {
  position: relative;
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: 50% 32%;
  border-radius: 10px;
  background: var(--bg-elev);
  filter: saturate(0.9);
}

/* ---- Hero entrance -------------------------------------------------------
   Staged, one-shot on load. Everything below is gated behind .is-revealing,
   which site.js only adds once it has split the headline into lines and the
   fonts have settled. Without JS -- or with reduced motion -- the hero simply
   renders as-is, so no content can end up stranded invisible. */

.hero h1 .hl {
  display: block;
  overflow: hidden;
}

.hero.is-revealing .hl-in {
  display: block;
  animation: hero-line 0.72s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: calc(var(--i) * 90ms + 0.15s);
}

@keyframes hero-line {
  from {
    transform: translateY(105%);
  }
}

/* The image develops rather than fades: a downward wipe. */
.hero.is-revealing .portrait picture {
  display: block;
  animation: hero-wipe 0.85s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: 0.3s;
}

@keyframes hero-wipe {
  from {
    clip-path: inset(0 0 100% 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

/* The offset accent rule draws itself in, left to right. */
.hero.is-revealing .portrait::before {
  animation: hero-rule 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: 0.62s;
}

@keyframes hero-rule {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

.hero.is-revealing .lede {
  animation: hero-rise 0.6s ease-out both;
  animation-delay: 0.8s;
}

@keyframes hero-rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* The caret rides the last line up, then resumes its idle blink. */
.hero.is-revealing .caret::after {
  animation-delay: 1.1s;
}

@media (prefers-reduced-motion: reduce) {
  .hero.is-revealing .hl-in,
  .hero.is-revealing .portrait picture,
  .hero.is-revealing .portrait::before,
  .hero.is-revealing .lede {
    animation: none;
  }
}

.portrait figcaption {
  margin-top: 10px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.5;
}

@media (max-width: 720px) {
  /* The portrait pairs up with the name instead of sitting alone above the
     copy: an image on its own line reads as decoration, next to the name it
     reads as the person making the claim. */
  .hero {
    grid-template-areas:
      "id    portrait"
      "title title"
      "rule  rule"
      "lede  lede";
    align-items: center;
    column-gap: 16px;
  }

  .hero .portrait {
    margin-top: 0;
    width: 76px;
  }

  .hero .lede {
    max-width: none;
  }

  /* Too narrow for the offset frame to read. */
  .portrait::before {
    display: none;
  }

  .portrait figcaption {
    display: none;
  }
}

.hero-row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin: 22px 0;
}

h1,
h2,
.post-title,
.card .h,
.sub .h {
  font-family: var(--serif);
}

/* Two sentences, two lines. The display size is what decides where the line
   breaks -- at 56px sentence one no longer fits the 720px column and snapped
   mid-sentence, which killed the caesura the claim depends on. */
.hero h1 {
  max-width: 25ch;
  margin: 18px 0 36px;
  color: var(--ink);
  font-size: clamp(30px, 4.4vw, 44px);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.05;
  overflow-wrap: break-word;
  /* Evens out the two lines, which lands the break on the sentence boundary --
     a fixed ch measure could not do that for both languages at once. */
  text-wrap: balance;
}

.hero h1 em {
  color: var(--accent);
  font-style: italic;
}

.caret::after {
  content: "|";
  margin-left: 6px;
  color: var(--accent);
  font-weight: 400;
  animation: caret 1.05s steps(1) infinite;
}

@keyframes caret {
  50% {
    opacity: 0;
  }
}

.lede {
  max-width: 62ch;
  margin: 0 0 36px;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 20px;
  line-height: 1.5;
}

.hero-meta,
.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
}

.dot {
  margin-right: 2px;
  color: var(--accent);
}

.sec-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin: 96px 0 24px;
}

.sec-head h2 {
  margin: 0;
  color: var(--ink);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: 0;
}

.grow {
  flex: 1;
}

.meta {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
}

.post-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.post-row {
  display: grid;
  grid-template-columns: 18px 96px 1fr auto;
  gap: 20px;
  align-items: baseline;
  padding: 14px 0;
}

.post-row:hover .post-title {
  color: var(--accent);
}

.post-date {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
  white-space: nowrap;
}

.read-mark {
  color: transparent;
  font-family: var(--mono);
  font-size: 12px;
  text-align: center;
}

.post-row.is-read .read-mark {
  color: var(--mute-soft);
}

.post-row.is-current .read-mark {
  color: var(--accent);
}

.post-row.is-read .post-title {
  color: var(--ink-soft);
}

.post-row.is-current .post-title {
  color: var(--ink);
}

.post-title {
  color: var(--ink);
  font-size: 20px;
  line-height: 1.35;
  transition: color 0.15s ease;
}

.post-excerpt {
  display: block;
  max-width: 60ch;
  margin-top: 6px;
  color: var(--mute);
  font-size: 13.5px;
}

.post-tags {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
  white-space: nowrap;
}

.post-tags span + span::before {
  content: "  /  ";
  color: var(--mute-soft);
}

.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 12px 0 36px;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  min-width: 0;
}

.chip {
  margin-right: 14px;
  padding: 4px 0;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
  transition: color 0.15s ease;
}

.chip:hover,
.chip.is-on {
  color: var(--accent);
}

.search {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: 8px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12.5px;
}

.search .slash {
  color: var(--accent);
}

.search input {
  width: 130px;
  border: 0;
  outline: 0;
  background: none;
  color: var(--ink);
}

.cards {
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin: 18px 0 0;
}

.card {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 28px;
  align-items: baseline;
}

.card .lbl {
  padding-top: 4px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: lowercase;
}

.card .h {
  margin: 0 0 6px;
  color: var(--ink);
  font-size: 18px;
  line-height: 1.4;
}

.card .b {
  color: var(--ink-soft);
  font-size: 13.5px;
  line-height: 1.55;
}

.card-projects {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
}

.card-projects dt {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--mono);
  font-size: 12.5px;
}

.card-projects dt:not(:first-child) {
  margin-top: 12px;
}

/* The icon marks a repo, so it only rides along on GitHub links. */
.repo-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.repo-icon {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  color: var(--mute);
}

.repo-link:hover .repo-icon {
  color: var(--accent);
}

.card-projects dd {
  margin: 3px 0 0;
  color: var(--mute);
  font-size: 13px;
  line-height: 1.5;
}

/* Not public yet, so the name must not look like a dead link. */
.project-name {
  color: var(--mute);
}

.soon {
  padding: 1px 6px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  color: var(--mute-soft);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.sub {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 80px 0 0;
}

.sub .h {
  margin: 6px 0 0;
  color: var(--ink);
  font-size: 24px;
  font-weight: 400;
}

.sub .b {
  max-width: 56ch;
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.55;
}

.sub form {
  position: relative;
  display: flex;
  align-items: center;
  max-width: 480px;
  margin-top: 10px;
  border-bottom: 1px solid var(--mute-soft);
  transition: border-color 0.15s ease;
}

.sub form:focus-within {
  border-color: var(--accent);
}

.sub input {
  flex: 1;
  border: 0;
  outline: 0;
  padding: 12px 0;
  background: none;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 14px;
}

.sub button.primary {
  padding: 12px 0 12px 16px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
}

.sub button.primary:hover {
  color: var(--accent);
}

.primary-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
  transition: color 0.15s ease;
}

.primary-link:hover {
  color: var(--accent);
}

.brand-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--accent);
}

.social-links {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
}

.social-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 14px;
  transition: color 0.15s ease;
}

.social-link span {
  text-decoration: underline;
  text-decoration-color: var(--mute-soft);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 0.15s ease;
}

.social-link:hover {
  color: var(--accent);
}

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

.sub .small,
.form-note {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
}

.page-head {
  padding-top: 56px;
  padding-bottom: 24px;
}

.page-head h1,
.article header h1,
.about-hero h1 {
  margin: 12px 0 14px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(34px, 4.4vw, 46px);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.1;
}

/* The scatter objection, answered before it is raised. */
.roles {
  margin: 88px 0 0;
  padding: 34px 0 0;
  border-top: 1px solid var(--rule);
}

.roles h2 {
  max-width: 22ch;
  margin: 14px 0 16px;
  color: var(--ink);
  font-size: clamp(24px, 3.2vw, 32px);
  font-weight: 400;
  line-height: 1.15;
}

.roles-lede {
  max-width: 58ch;
  margin: 0 0 32px;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.55;
}

.roles-grid {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 20px 32px;
  margin: 0;
}

.roles-grid dt {
  padding-top: 3px;
  color: var(--accent);
  font-family: var(--mono);
  font-size: 12px;
}

.roles-grid dd {
  margin: 0;
  color: var(--ink-soft);
  font-size: 14.5px;
  line-height: 1.6;
}

/* The turn. Everything above is evidence; this is the claim it buys. */
.roles-close {
  max-width: 46ch;
  margin: 34px 0 0;
  padding-left: 18px;
  border-left: 2px solid var(--accent);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.5;
}

@media (max-width: 640px) {
  .roles-grid {
    grid-template-columns: 1fr;
    gap: 6px 0;
  }

  .roles-grid dd {
    margin-bottom: 14px;
  }
}

/* The conclusion carries the weight; mark it. */
.about-grid {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 36px 32px;
  margin: 56px 0 0;
  font-size: 14.5px;
}

.about-grid dt {
  padding-top: 6px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: lowercase;
}

.about-grid dd {
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.6;
}

.legal-doc {
  max-width: 760px;
  padding-bottom: 72px;
}

.legal-doc h1 {
  max-width: 16ch;
  margin: 18px 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(34px, 4vw, 46px);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.08;
}

.legal-doc h2 {
  margin: 34px 0 10px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.15;
}

.legal-doc p,
.legal-doc li {
  color: var(--ink-soft);
}

.legal-doc ul {
  margin: 0 0 20px;
  padding-left: 19px;
}

.legal-meta {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 8px 20px;
  margin: 28px 0;
  padding: 20px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.legal-meta dt {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
}

.legal-meta dd {
  margin: 0;
  color: var(--ink-soft);
}

.article {
  padding-block: 80px 40px;
}

.reading-strip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 55;
  width: 100%;
  background: color-mix(in oklab, var(--bg) 90%, transparent);
  backdrop-filter: blur(12px);
  transform: translateY(-100%);
  transition: transform 0.18s ease;
}

.reading-strip.is-on {
  transform: translateY(0);
}

.reading-strip-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 42px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
}

.strip-title {
  min-width: 0;
  overflow: hidden;
  color: var(--ink-soft);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.strip-pct {
  margin-left: auto;
  color: var(--accent);
}

.strip-progress {
  height: 1px;
}

.strip-progress i {
  display: block;
  width: 0;
  height: 1px;
  background: var(--accent);
}

/* A table of contents, not a row of dots: the section titles stay readable so
   the reader can see what is still ahead. */
.article-rail {
  position: fixed;
  left: max(24px, calc((100vw - 720px) / 2 - 232px));
  top: 50%;
  z-index: 10;
  display: none;
  width: 200px;
  transform: translateY(-50%);
  flex-direction: column;
  gap: 2px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
}

.article-rail a {
  display: block;
  padding: 5px 0 5px 12px;
  border-left: 2px solid var(--rule);
  color: var(--mute);
  line-height: 1.4;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.article-rail a:hover {
  color: var(--ink);
  border-left-color: var(--mute-soft);
}

.article-rail a.is-on {
  color: var(--ink);
  border-left-color: var(--accent);
}

.reading-meter {
  position: fixed;
  right: max(24px, calc((100vw - 720px) / 2 - 210px));
  top: 28vh;
  z-index: 10;
  display: none;
  width: 168px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
}

.reading-meter .lbl {
  color: var(--mute);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.reading-meter .num {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
}

.reading-meter .unit {
  margin-left: 4px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
}

.reading-meter .bar {
  position: relative;
  width: 100%;
  height: 1px;
  margin: 8px 0 10px;
  background: var(--mute-soft);
}

.reading-meter .bar i {
  position: absolute;
  top: -1px;
  left: 0;
  width: 0;
  height: 3px;
  background: var(--accent);
}

.reading-meter .small {
  color: var(--ink-soft);
}

.article header .deck {
  max-width: 58ch;
  margin: 8px 0 36px;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 20px;
  line-height: 1.5;
}

.back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
  transition: color 0.15s ease;
}

.back:hover {
  color: var(--accent);
}

.prose {
  max-width: 62ch;
  margin: 56px 0;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.7;
}

.prose p {
  margin: 0 0 1.2em;
}

/* Body links had inherited the global reset and were invisible as links. */
.prose a:not(.anchor) {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.15s ease;
}

.prose a:not(.anchor):hover {
  color: var(--accent);
}

.prose p:first-of-type::first-letter {
  float: left;
  padding: 6px 12px 0 0;
  color: var(--accent);
  font-family: var(--serif);
  font-size: 3.2em;
  font-weight: 500;
  line-height: 0.9;
}

.prose h2 {
  position: relative;
  margin: 2.4em 0 0.6em;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 500;
}

/* The section mark is the deep link: click it to copy a URL to this heading. */
.prose h2 .anchor {
  position: absolute;
  top: 0.05em;
  left: -1.4em;
  color: var(--accent);
  font-family: var(--mono);
  font-size: 0.7em;
  opacity: 0.45;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.prose h2:hover .anchor,
.prose h2 .anchor:focus-visible {
  opacity: 1;
}

.prose h2 .anchor.is-copied::after {
  content: attr(data-copied);
  position: absolute;
  top: -0.2em;
  left: calc(100% + 8px);
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.prose h2.is-pulse {
  animation: section-pulse 2s ease;
}

@keyframes section-pulse {
  0% {
    background: var(--accent-soft);
    box-shadow: 0 0 0 10px var(--accent-soft);
  }
  100% {
    background: transparent;
    box-shadow: none;
  }
}

.prose ul {
  margin: 0.6em 0 1.4em;
  padding-left: 1.2em;
}

.prose ol {
  margin: 0.6em 0 1.4em;
  padding-left: 1.4em;
}

.prose li {
  margin: 0.5em 0;
}

/* The sources block is apparatus, not argument: quieter and set apart. */
.prose h2#quellen,
.prose h2#sources {
  margin-top: 2.4em;
  padding-top: 1.6em;
  border-top: 1px solid var(--rule);
  font-size: 20px;
}

.prose h2#quellen ~ ol,
.prose h2#sources ~ ol,
.prose h2#quellen ~ p,
.prose h2#sources ~ p {
  color: var(--mute);
  font-size: 14px;
  line-height: 1.6;
}

.prose pre {
  position: relative;
  overflow: auto;
  margin: 1.6em 0;
  border-radius: 6px;
  padding: 18px 22px;
  background: var(--bg-elev);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.7;
}

.prose pre::before {
  content: attr(data-lang);
  position: absolute;
  top: 10px;
  right: 14px;
  color: var(--mute);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.copy-code {
  position: absolute;
  top: 10px;
  right: 58px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 10px;
  opacity: 0;
  transition: color 0.15s ease, opacity 0.15s ease;
}

.prose pre:hover .copy-code,
.copy-code.is-done {
  opacity: 1;
}

.copy-code:hover,
.copy-code.is-done {
  color: var(--accent);
}

/* Comparison figure: three paths a prompt can take. The last row is the argument,
   so it carries the accent; the others stay quiet. */
.trust-figure {
  margin: 2em 0 2.4em;
  padding: 20px 22px 18px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--bg-elev);
}

.trust-head {
  margin-bottom: 14px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}

.trust-rows {
  display: grid;
  gap: 2px;
}

.trust-row {
  display: grid;
  grid-template-columns: minmax(0, 15em) minmax(0, 1fr);
  gap: 16px;
  padding: 12px 0 12px 14px;
  border-left: 2px solid var(--rule);
}

.trust-row.is-on {
  border-left-color: var(--accent);
}

.trust-key {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.4;
}

.trust-sub {
  color: var(--mute-soft);
  font-size: 10.5px;
  line-height: 1.4;
}

.trust-val {
  color: var(--mute);
  font-size: 13.5px;
  line-height: 1.5;
}

.trust-row.is-on .trust-val {
  color: var(--ink-soft);
}

.trust-row.is-on .trust-val b {
  color: var(--accent);
  font-weight: 400;
  font-family: var(--mono);
  font-size: 12.5px;
}

.trust-figure figcaption {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  color: var(--mute);
  font-size: 13px;
  line-height: 1.5;
}

@media (max-width: 640px) {
  .trust-row {
    grid-template-columns: 1fr;
    gap: 6px;
  }
}

/* An entry that does not exist yet: announced, not linked, so it cannot rot. */
.prose .soon-note {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  margin-left: 4px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
}

/* Inline chart figure. One series, so no legend: the values are labelled directly
   and the track runs the full 0-100 scale, which is the point being made. */
.chart {
  margin: 2em 0 2.4em;
  padding: 20px 22px 18px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--bg-elev);
}

.chart-head {
  margin-bottom: 16px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}

.chart .bars {
  display: grid;
  gap: 10px;
}

.chart .bar {
  display: grid;
  grid-template-columns: minmax(0, 13em) minmax(0, 1fr) 3.2em;
  align-items: center;
  gap: 12px;
}

.chart .bar-key {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.35;
}

.chart .bar-track {
  height: 10px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--rule) 70%, transparent);
}

.chart .bar-fill {
  display: block;
  height: 100%;
  min-width: 3px;
  border-radius: 999px;
  background: #9f5a25;
}

:root[data-theme="dark"] .chart .bar-fill {
  background: #bf8146;
}

.chart .bar-val {
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.chart-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--rule);
  color: var(--mute-soft);
  font-family: var(--mono);
  font-size: 10.5px;
}

.chart figcaption {
  margin-top: 12px;
  color: var(--mute);
  font-size: 13px;
  line-height: 1.5;
}

@media (max-width: 640px) {
  .chart .bar {
    grid-template-columns: minmax(0, 1fr) 3.2em;
  }

  /* The label needs the full width on a phone; the bar drops beneath it. */
  .chart .bar-key {
    grid-column: 1 / -1;
  }
}

.case-figure {
  margin: 2em 0 2.2em;
}

.case-figure img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
  background: var(--bg-elev);
}

.case-figure figcaption {
  margin-top: 10px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.55;
}

/* Three routes a prompt can take. Only the last one carries the guarantee, so
   only the last one gets the accent -- the figure must not promise more than
   the "catch" section below it delivers. */
.trust-figure {
  margin: 2em 0 2.4em;
  padding: 20px 22px 18px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--bg-elev);
}

.trust-head {
  margin-bottom: 16px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}

.trust-rows {
  display: flex;
  flex-direction: column;
}

.trust-row {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 20px;
  padding: 12px 0 12px 14px;
  border-left: 2px solid var(--rule);
}

.trust-row + .trust-row {
  border-top: 1px solid var(--rule);
}

.trust-row.is-on {
  border-left-color: var(--accent);
}

.trust-key {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--ink-soft);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.35;
}

.trust-row.is-on .trust-key {
  color: var(--accent);
}

.trust-sub {
  color: var(--mute-soft);
  font-size: 10.5px;
  line-height: 1.4;
}

.trust-val {
  color: var(--mute);
  font-size: 13.5px;
  line-height: 1.5;
}

.trust-row.is-on .trust-val {
  color: var(--ink-soft);
}

.trust-val b {
  color: var(--ink);
  font-weight: 500;
}

.trust-figure figcaption {
  margin-top: 14px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.55;
}

@media (max-width: 640px) {
  .trust-row {
    grid-template-columns: 1fr;
    gap: 6px;
  }
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  margin: 1.8em 0 2.1em;
}

.metric-card {
  padding: 16px 0 14px;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule-soft);
}

.metric-label {
  display: block;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.metric-card strong {
  display: block;
  margin: 4px 0 6px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 28px;
  font-weight: 500;
  line-height: 1.1;
}

.metric-card span:last-child {
  display: block;
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 12.5px;
  line-height: 1.45;
}

.workflow-steps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px 24px;
  margin: 1.7em 0 2em;
}

.workflow-steps > div {
  position: relative;
  padding-left: 34px;
}

.workflow-steps > div::before {
  content: "";
  position: absolute;
  left: 12px;
  top: 30px;
  bottom: 2px;
  width: 1px;
  background: var(--rule);
}

.workflow-steps span {
  position: absolute;
  left: 0;
  top: 2px;
  color: var(--accent);
  font-family: var(--mono);
  font-size: 11px;
}

.workflow-steps strong {
  display: block;
  margin-bottom: 4px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
}

.workflow-steps p {
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.55;
}

.timeline {
  position: relative;
  list-style: none;
  margin: 1.6em 0 2.1em;
  padding: 0 0 0 22px;
}

.timeline::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 7px;
  bottom: 8px;
  width: 1px;
  background: var(--rule);
}

.timeline li {
  position: relative;
  margin: 0 0 1.4em;
}

.timeline li::before {
  content: "";
  position: absolute;
  left: -22px;
  top: 7px;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--accent);
}

.timeline span {
  display: block;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.timeline strong {
  display: block;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
}

.timeline p {
  margin: 0.25em 0 0;
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.55;
}

.callout {
  display: block;
  margin: 1.8em 0;
  border-left: 2px solid var(--accent);
  padding: 4px 0 4px 26px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 19px;
  font-style: italic;
  line-height: 1.55;
}

.acro {
  position: relative;
  border-bottom: 1px dotted var(--accent);
  color: var(--ink);
  cursor: help;
}

.acro:hover {
  color: var(--accent);
}

.acro .tt {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  z-index: 10;
  padding: 5px 9px;
  border-radius: 5px;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--mono);
  font-size: 11px;
  font-style: normal;
  letter-spacing: 0.02em;
  line-height: 1.4;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(2px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  white-space: nowrap;
}

.acro .tt::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  border: 4px solid transparent;
  border-top-color: var(--ink);
  transform: translateX(-50%);
}

.acro:hover .tt {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Two halves of one row, and each keeps its side even when the other is absent:
   a lone "next" that stretched across the full width read as the only thing
   there was. */
.post-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin: 0;
}

.nav-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  border: 1px solid var(--rule);
  border-radius: 12px;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.nav-card:hover {
  border-color: var(--mute-soft);
  background: var(--bg-elev);
}

.nav-card.is-next {
  grid-column: 2;
  text-align: right;
}

.nav-card .lbl {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
}

.nav-card:hover .lbl {
  color: var(--accent);
}

.nav-card .h {
  color: var(--ink);
  font-size: 15.5px;
  line-height: 1.4;
}

/* The one place the author appears on an article: after the last line, not
   before the first one. */
.author-box {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0 0 34px;
  padding: 16px 18px;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--bg-elev);
  transition: border-color 0.2s ease;
}

.author-box:hover {
  border-color: var(--mute-soft);
}

/* avatar-sm is already cropped square around the face -- no object-position
   nudging needed, and it ships 2.4 KB instead of the 32 KB full portrait. */
.author-box img {
  width: 52px;
  height: 52px;
  flex: 0 0 auto;
  border-radius: 999px;
  object-fit: cover;
}

.author-name {
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12.5px;
}

.author-bio {
  margin: 3px 0 0;
  color: var(--mute);
  font-size: 13.5px;
  line-height: 1.5;
}

.progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  width: 0;
  height: 1px;
  background: var(--accent);
}

.footer {
  margin-top: auto;
  padding: 120px 0 56px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 12px;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 32px;
  padding-top: 24px;
  border-top: 1px solid var(--rule);
}

.footer-id {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-right: auto;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.footer-note {
  flex-basis: 100%;
  margin: 0;
  color: var(--mute-soft);
  font-size: 11px;
  line-height: 1.6;
}

@media (max-width: 640px) {
  .footer {
    padding: 80px 0 40px;
  }

  .footer-inner {
    align-items: flex-start;
    gap: 18px;
  }

  /* Two even columns beat a ragged wrap that orphans the last link. */
  .footer-links {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 16px;
    width: 100%;
  }

  .footer-links .link {
    justify-self: start;
  }
}

.cmdk-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 14vh;
  background: color-mix(in oklab, var(--ink) 30%, transparent);
  backdrop-filter: blur(8px);
}

.cmdk-backdrop.is-open {
  display: flex;
}

.cmdk {
  width: min(580px, 92vw);
  max-height: 70vh;
  overflow: hidden;
  border-radius: 14px;
  background: var(--bg);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.22), 0 2px 8px rgba(0, 0, 0, 0.06);
}

.cmdk-input {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 20px 14px;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 14px;
}

.cmdk-input .prompt {
  color: var(--accent);
}

.cmdk-input input {
  flex: 1;
  border: 0;
  outline: 0;
  padding: 2px 0;
  background: none;
  color: inherit;
}

.cmdk-list {
  max-height: 48vh;
  overflow: auto;
  padding: 4px 0 12px;
}

.cmdk-group {
  padding: 16px 20px 6px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.cmdk-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 20px;
  color: var(--ink-soft);
  font-family: var(--mono);
  font-size: 13px;
}

.cmdk-item:hover,
.cmdk-item.is-on {
  background: var(--bg-elev);
  color: var(--ink);
}

.cmdk-item .glyph {
  width: 14px;
  color: var(--mute);
  text-align: center;
}

.cmdk-item .hint {
  margin-left: auto;
  color: var(--mute);
  font-size: 11px;
}

.cmdk-foot {
  display: flex;
  gap: 20px;
  padding: 12px 20px 14px;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 11px;
}

.empty-state {
  display: none;
  padding: 30px 0;
  color: var(--mute);
  font-family: var(--mono);
  font-size: 13px;
}

.consent-locked {
  overflow: hidden;
}

.consent-backdrop {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: none;
  align-items: flex-end;
  justify-content: center;
  padding: 18px;
  background: color-mix(in oklab, var(--ink) 34%, transparent);
  backdrop-filter: blur(8px);
}

.consent-backdrop.is-open {
  display: flex;
}

.consent-panel {
  width: min(560px, 100%);
  padding: 22px 24px 20px;
  border-radius: 8px;
  background: var(--bg);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.24), 0 2px 10px rgba(0, 0, 0, 0.08);
}

.consent-panel h2 {
  margin: 10px 0 8px;
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.15;
}

.consent-panel p {
  margin: 0;
  color: var(--ink-soft);
}

.consent-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 18px;
}

.link-btn {
  color: var(--mute);
  font-family: var(--mono);
  font-size: 13px;
  text-decoration: underline;
  text-decoration-color: var(--mute-soft);
  text-underline-offset: 3px;
}

.link-btn:hover {
  color: var(--ink);
  text-decoration-color: var(--accent);
}

.consent-link {
  display: inline-block;
  margin-top: 14px;
  font-family: var(--mono);
  font-size: 12px;
}

@media (min-width: 1120px) {
  .article-rail,
  .reading-meter {
    display: flex;
    flex-direction: column;
  }

  /* The meter to the right carries the reading time from here on. */
  .meta-row .read-time {
    display: none;
  }

  /* Out of the reading column: the eye drops from the lede straight into the
     entries, and the filters wait beside them. Mirrors .article-rail. */
  .filter-row {
    position: fixed;
    right: max(24px, calc((100vw - 720px) / 2 - 232px));
    top: 50%;
    z-index: 10;
    width: 200px;
    margin: 0;
    transform: translateY(-50%);
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  .filter-row .chips {
    flex-direction: column;
    align-items: flex-start;
  }

  .filter-row .grow {
    display: none;
  }

  .filter-row .search {
    order: -1;
    margin: 0 0 14px;
  }

  .filter-row .chip {
    margin-right: 0;
    padding: 3px 0;
  }

  .page-head .post-list {
    margin-top: 36px;
  }
}

/* No rail here, so the filters stay above the list -- but wrapped they build a
   wall the reader has to climb over. One scrollable line instead. */
@media (max-width: 1119px) {
  .filter-row {
    flex-wrap: nowrap;
    margin: 12px 0 28px;
  }

  .chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    /* Room for the focus ring the overflow would otherwise clip. */
    padding: 2px 0;
  }

  .chips::-webkit-scrollbar {
    display: none;
  }

  .chips.has-more {
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  }

  .chips .chip {
    flex: 0 0 auto;
  }

  .filter-row .grow {
    display: none;
  }

  .filter-row .search {
    flex: 0 0 auto;
    margin-left: 12px;
  }
}

@media (max-width: 640px) {
  .container {
    padding: 0 24px;
  }

  .filter-row .search input {
    width: 72px;
  }

  .post-nav {
    grid-template-columns: 1fr;
  }

  .nav-card.is-next {
    grid-column: 1;
    text-align: left;
  }

  .topnav-inner {
    gap: 8px;
    padding: 8px 10px 8px 14px;
  }

  .brand {
    flex-shrink: 0;
  }

  .nav-links {
    gap: 0;
  }

  .nav-link {
    padding: 6px 7px;
  }

  .lang-switch {
    margin: 0 2px 0 4px;
    padding-left: 6px;
  }

  .hero {
    padding-top: 64px;
  }

  /* A date gutter costs a third of the width here; stack instead. */
  .post-row {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 16px 0;
  }

  .post-row .read-mark {
    display: none;
  }

  .post-tags {
    grid-column: 1;
  }

  .card {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .about-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .legal-meta {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .metric-grid,
  .workflow-steps {
    grid-template-columns: 1fr;
  }

  .acro .tt {
    left: 0;
    width: min(240px, 80vw);
    white-space: normal;
    transform: translateY(2px);
  }

  .acro:hover .tt {
    transform: translateY(0);
  }
}
