/* ─────────────────────────────────────────────────────────────────
   chrome.css — the header and the footer, written once.

   The home page is a React bundle and the blog is static HTML built by
   scripts/build-blog.cjs. They render the same header from the same
   site-chrome.json, and for months they styled it from two stylesheets. The
   history of that is in git: the two headers had different buttons and
   different logos; the wordmark was 17px on one side and 20px on the other; the
   z-index was 50 and 10; one of them blurred on iOS and the other did not; the
   mobile breakpoint was 820 here and 720 there. Each was found separately, by
   measuring, after it had shipped.

   The footer is here for the same reason and a sharper one: it was styled twice
   under two sets of class names, footer-* and foot-*, so nothing about it could
   be compared. The most damaging bug in the whole audit was in it - .foot-inner
   wrote `padding` as a shorthand over .wrap's, at equal specificity, and eighteen
   links sat flush against both window edges on every static page while the ABN
   line two rows below kept its 32px. One name, one rule set, both paths.

   src/styles.css @imports this file and vite inlines it; build-blog.cjs
   concatenates it in front of content/blog.css. So there is one place to change
   a number, and no way to change it on one side only.

   What is NOT here is the drawer's *mechanism*. The home page renders it
   conditionally from React state; a blog page ships no JavaScript and cannot, so
   it uses a checkbox and a label. Those genuinely differ, they live in their own
   files, and each sets nothing but `display` on .nav-mobile. Everything the
   reader can see is here.
   ───────────────────────────────────────────────────────────────── */

.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(250, 250, 247, .82);
  /* Safari 17 and below only know the prefixed property. Without this line the
     header did not blur on iOS while the home page's did. */
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  backdrop-filter: saturate(150%) blur(12px);
  border-bottom: 1px solid var(--line);
}

.nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 68px; gap: 24px; flex-wrap: nowrap;
}

/* min-height, not height: a fixed bar cannot grow, so a label that wrapped grew
   inside it instead and overflowed a 68px box. */

.nav-brand { display: inline-flex; align-items: center; color: var(--ink); text-decoration: none; }

/* The wordmark. This was an inline style object inside bits.jsx, which meant the
   one piece of type that appears on every page of the site could not be reached
   from a stylesheet: content/blog.css restated the size, the weight and the
   tracking for the static pages, and got them wrong - 17px at -0.01em - so the
   wordmark was visibly smaller everywhere except the home page. */
.logo {
  display: inline-flex; align-items: baseline;
  font-family: var(--font-display); font-weight: 600;
  font-size: 20px; letter-spacing: -0.03em; line-height: 1;
  color: var(--ink); text-decoration: none;
}
.logo-y { color: var(--accent-ink); }

.nav-links { display: flex; align-items: center; gap: 28px; flex: 1; justify-content: center; flex-wrap: nowrap; }
.nav-links a {
  color: var(--ink-2); text-decoration: none; font-size: 14px; font-weight: 450;
  transition: color .15s;
}
.nav-links a:hover { color: var(--ink); }
/* Colour alone was 1.46:1 against a normal link and :hover used the same value,
   so hovering made two items look current at once (SC 1.4.1). The underline, not
   weight: at font-weight 600 the current label grew enough to push the six of
   them onto a second row 60px earlier than they had been. */
.nav-links a[aria-current="page"] {
  color: var(--ink);
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* Buttons. The nav button here was the solid lime primary while the home page
   used the outlined ghost with an arrow, so the same header had two different
   buttons in it. Property checks missed it: they compared size and padding and
   never looked at background or border. .btn carries no fill of its own - a
   variant does, on both sides. */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 18px;
  border-radius: 10px; border: 1px solid transparent;
  font-family: var(--font-sans); font-weight: 500; font-size: 14.5px;
  letter-spacing: -0.005em; cursor: pointer; text-decoration: none;
  transition: transform .15s ease, background .15s ease, border-color .15s ease, color .15s ease;
  white-space: nowrap;
}
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-icon { display: inline-flex; transition: transform .2s ease; }
.btn:hover .btn-icon { transform: translateX(3px); }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: color-mix(in oklab, var(--accent) 88%, white); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn-ghost:hover { background: var(--surface); border-color: var(--ink-3); }
.btn-sm { padding: 8px 12px; font-size: 13px; }

/* The language switcher. Rendered twice - once in the bar, once in the drawer -
   and exactly one of the two is displayed at any width, so only one Language
   landmark is ever in the accessibility tree. */
.nav-lang { display: flex; align-items: center; gap: 10px; flex: none; }
.nav-lang a {
  color: var(--ink-3); text-decoration: none;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .06em;
  padding: 4px 2px; transition: color .15s;
}
.nav-lang a:hover { color: var(--ink); }
.nav-lang a[aria-current="true"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--accent); }
.nav-mobile .nav-lang { display: none; }

.nav-burger { display: none; }

/* Between a full-width bar and the drawer there is a band where six labels, the
   wordmark, the button and the language links all have to fit on one row.
   Spanish needs about 27% more room than English for the same six words, so the
   band is set by Spanish, not by the language the site was written in.
   Tightening the two gaps buys back about 90px. */
@media (max-width: 1240px) {
  .nav-inner { gap: 16px; }
  .nav-links { gap: 16px; }
  .nav-lang  { gap: 8px; }
}

/* 1024, measured per language after the switcher went in: the six labels stop
   fitting on one row at 1000px in English, 975px in Spanish and 961px in
   Japanese. Spanish is the constraint, and 1024 clears its 975 by 49px and lands
   on a width tablets actually are. A breakpoint set to the measured limit itself
   is a breakpoint that fails the first time a font loads late. */
@media (max-width: 1024px) {
  .nav-links { display: none; }
  .nav-inner .btn-sm { display: none; }
  .nav-burger {
    display: flex; flex-direction: column; gap: 5px; flex: none;
    width: 40px; height: 40px; align-items: center; justify-content: center;
    background: transparent; border: 1px solid var(--line-2); border-radius: 8px;
    cursor: pointer;
  }
  .nav-burger span { width: 16px; height: 1.5px; background: var(--ink); display: block; }

  /* Everything about the drawer except whether it is open. top:100% rather than
     68px so it still meets the bar if the bar grows. */
  .nav-mobile {
    position: absolute; top: 100%; left: 0; right: 0;
    padding: 16px 32px 24px;
    background: var(--bg);
    flex-direction: column; gap: 14px;
  }
  .nav-mobile a {
    color: var(--ink); font-size: 18px; font-weight: 500; text-decoration: none;
    padding: 4px 0;
  }
  /* Written as a descendant of .nav-mobile rather than with !important: plain
     .nav-mobile-cta loses to .nav-mobile a on specificity, which is why the call
     to action in the static drawer was ink-coloured and the one on the home page,
     which did use !important, was not. */
  .nav-mobile a.nav-mobile-cta { color: var(--accent-ink); }

  .nav-inner .nav-lang { display: none; }
  .nav-mobile .nav-lang {
    display: flex; gap: 20px;
    margin-top: 6px; padding-top: 14px;
    border-top: 1px solid var(--line);
  }
  /* 14px with 8px of padding clears the 24px of SC 2.5.8; the 11.5px bar version
     is a pointer-sized target and is not offered here. */
  .nav-mobile .nav-lang a { font-size: 14px; padding: 8px 0; }
}

/* ─── the footer ─────────────────────────────────────────────────── */
/* Only `margin-top` is left to the two files: an article ends and needs air
   before the footer, and a home-page section already carries its own. */
.foot {
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding: 64px 0 32px;
}
.foot-inner { display: grid; grid-template-columns: 1fr 2.4fr; gap: 48px; }
/* 1fr 2.4fr, not 1fr 2fr: at 2fr the four columns did not fit and Follow wrapped
   onto a second row, so the home page footer was three columns and a stray while
   every other page was four across. And no `padding` shorthand here - this div is
   <div class="wrap foot-inner"> / <div class="container foot-inner">, and a
   shorthand resets the wrapper's left and right padding at equal specificity. */
.foot-tag { margin: 10px 0 0; color: var(--ink-2); font-size: 14px; max-width: 30ch; }
.foot-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; }
.foot-col { display: flex; flex-direction: column; gap: 10px; }
/* The heading is an <h2>, so its UA margins and size have to be reset. */
.foot-col-h {
  margin: 0 0 6px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4);
}
.foot-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.foot-col a { color: var(--ink-2); text-decoration: none; font-size: 14px; transition: color .15s; }
.foot-col a:hover { color: var(--accent-ink); }
/* A sibling of .foot-inner rather than a child, so it is not a grid item and
   `grid-column: 1 / -1` - which the home page carried for months - did nothing. */
.foot-base {
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 24px;
  margin-top: 32px; padding-top: 24px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-4);
}

/* 860 on both. It was 720 here and 860 there, so between them the home page
   showed four columns and every other page showed two. */
@media (max-width: 860px) {
  .foot-inner { grid-template-columns: 1fr; gap: 32px; }
  .foot-cols { grid-template-columns: repeat(2, 1fr); }
}

/* ─────────────────────────────────────────────────────────────────
   blog.css — the stylesheet for /blog/.
   Copied verbatim to public/blog/blog.css by scripts/build-blog.cjs.

   The homepage ships as one inlined HTML file, so its styles.css cannot be
   linked from anywhere else. These are the same tokens, cut down to what an
   article page needs. Keep the values in step with src/styles.css by hand;
   there are only a dozen of them and a build step to share them would cost
   more than it saves.

   A blog page carries no JavaScript at all. Nothing here may depend on any.
   ───────────────────────────────────────────────────────────────── */

:root {
  /* Matched to the home page on 2026-08-30. The blog was navy and blue while the
     site had become white and lime, so following a link looked like changing
     company. --accent is the logo lime and is a FILL only: #B8FC56 measures
     1.17:1 on this ground. --accent-ink is the readable text green. */
  --accent:    #B8FC56;
  /* Named --accent-2 here and --accent-ink in src/styles.css until 2026-09-04,
     for the same #48730E. Two names for one colour is what makes sharing a token
     block between the two stylesheets impossible without silently unresolving
     every var() on one side. */
  --accent-ink: #48730E;   /* 5.38:1 on --bg; links and any accent text */
  --focus:     #0B4FC4;   /* src/styles.css:92. The ring was --accent-ink here, so it
                             changed from blue to green when you followed a link. */
  --on-accent: #0a0c11;   /* text sitting on a lime fill: 15.9:1 */
  --bg:        #fafaf7;
  --bg-2:      #f1f1ec;
  --surface:   #ffffff;
  --surface-2: #f6f6f1;
  --line:      rgba(0,0,0,0.08);
  --line-2:    rgba(0,0,0,0.16);
  --ink:       #0a0c11;
  --ink-2:     #2b2f37;
  --ink-3:     #5e6470;   /* src/styles.css:64. Was #5f6773 here: the "keep it in step
                             by hand" contract had already drifted. */
  --ink-4:     #626a78;   /* same as the home page: 4.81:1 on --bg-2 */
  --code:      #1f2937;

  --font-display: 'Inter Tight', 'Inter', ui-sans-serif, system-ui, sans-serif;
  /* No -apple-system: system-ui already resolves to it on Apple platforms, and
     src/styles.css does not have it - which is why the header button was set in
     a different face here than on the home page whenever Inter was slow. */
  --font-sans:    'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-serif:   'Newsreader', Georgia, serif;

  --container: 1240px;
  --measure:   40rem;      /* about 68 characters at this size */
  --radius:    14px;
  --radius-sm: 10px;

  color-scheme: light;
}

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

/* The homepage opens on a faint blueprint grid. Repeating it behind the top of
   an article is the one decorative thing on these pages, and it is what stops
   /blog/ reading as a different website. Pure CSS: a blog page runs no script. */
body::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 620px;
  z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(0,0,0,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,0,0,.045) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(88% 70% at 50% 0%, #000 0%, transparent 74%);
  -webkit-mask-image: radial-gradient(88% 70% at 50% 0%, #000 0%, transparent 74%);
}
body::after {
  /* A fixed 900px box at left:50% with a -450px margin sticks out of any window
     narrower than 900px. src/styles.css:177 hides that with overflow-x on the
     home page; this file had no overflow rule at all, so every page here scrolled
     sideways below 900px: scrollWidth 834 at a 768 window, 645 at 390. */
  content: '';
  position: absolute; top: -220px; left: 50%; width: min(900px, 100%); height: 560px;
  transform: translateX(-50%); z-index: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(184, 252, 86, .16), transparent 62%);
}
/* Not .nav: header.css is concatenated in front of this file, so a .nav rule
   here would come later and beat its `position: sticky; z-index: 50` - the
   header would scroll away. .nav is already above the decorations without help. */
main, .foot { position: relative; z-index: 1; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  /* clip, not hidden: hidden would force overflow-y to auto and make the body a
     scroll container, which the sticky header positions against. */
  overflow-x: clip;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  /* 16/1.55, the same as the home page. The 17/1.65 that used to be here is the
     reading size for an article, and it was set on <body>, so it also set the
     navigation, the footer and every card - which is why the header needed a
     line-height patch further down to stop being a pixel taller than the home
     page's, and why the footer's links stayed 1.4px taller than the same links
     one click away. The reading size is on the reading column now. */
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The only anchor on these pages the 84px on .prose h2/h3 does not cover is the
   one the skip link uses, so #main landed 69px under the sticky header. */
#main { scroll-margin-top: 88px; }

.wrap { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 32px; }
.wrap-narrow { max-width: calc(var(--measure) + 48px); }
.blog-head .wrap-narrow, .blog-list .wrap-narrow { max-width: 928px; }

a { color: var(--accent-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: #365314; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 2px; }
@supports not selector(:focus-visible) {
  :focus { outline: 2px solid var(--focus); outline-offset: 3px; }
}

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 20;
  padding: 10px 16px; border-radius: var(--radius-sm);
  background: var(--ink); color: var(--bg);
  font-weight: 600; text-decoration: none;
  transition: top .15s ease;
}
.skip:focus { top: 12px; color: var(--bg); }

/* ─── nav ────────────────────────────────────────────────────────── */
/* The header's appearance is in src/header.css, concatenated in front of this
   file by scripts/build-blog.cjs. Only the drawer's mechanism is here: this page
   ships no JavaScript and cannot, so a checkbox and a <label> open it where the
   home page uses React state. Neither file sets anything on .nav-mobile but
   `display`. */
.nav-toggle { display: none; }
.nav-mobile { display: none; }

@media (max-width: 1024px) {
  /* Off-screen but still focusable and still the thing the label toggles.
     display:none above the breakpoint so it is not a phantom tab stop there. */
  .nav-toggle {
    display: block; position: absolute; top: 0; left: 0;
    width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none;
  }
  .nav-toggle:focus-visible ~ .nav-inner .nav-burger {
    outline: 2px solid var(--focus); outline-offset: 3px;
  }
  .nav-toggle:checked ~ .nav-mobile { display: flex; }
}

/* ─── article head ───────────────────────────────────────────────── */
.crumb {
  margin: 0 0 20px;
  font-family: var(--font-mono); font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase;
}
.crumb a { color: var(--ink-3); text-decoration: none; }
.crumb a:hover { color: var(--ink-2); text-decoration: underline; }

.post, .blog-head { padding: 56px 0 0; }
.blog-list { padding-bottom: 96px; }

h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 2.9rem);
  line-height: 1.06;
  letter-spacing: -.032em;
  font-weight: 600;
  text-wrap: balance;
}
.dek {
  margin: 18px 0 0;
  font-family: var(--font-serif);
  font-size: 1.24rem; line-height: 1.5; font-style: italic;
  color: var(--ink-2);
}
.post-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 26px 0 0; padding-bottom: 26px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
.tag {
  padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--line-2);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-2);
}

/* ─── table of contents ──────────────────────────────────────────── */
.toc {
  margin: 32px 0 0; padding: 20px 24px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.toc h2 {
  margin: 0 0 10px;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.toc ol { margin: 0; padding-left: 20px; }
.toc li { margin: 5px 0; }
.toc a { color: var(--ink-2); text-decoration: none; }
.toc a:hover { color: var(--accent-ink); text-decoration: underline; }

/* ─── prose ──────────────────────────────────────────────────────── */
/* The article's reading size. .faq and .cta are siblings of .prose rather than
   children, but they are the same kind of thing - sentences somebody reads - so
   they take it too. The table of contents does not: it is a control, and it now
   sits at the site's own size like the rest of the furniture.
   --measure is in rem, so the column width does not move with this. */
.prose,
.faq dd,
.cta p { font-size: 17px; line-height: 1.65; }

.prose { margin-top: 38px; }
.prose > *:first-child { margin-top: 0; }
.prose p, .prose li { color: var(--ink-2); }
.prose p { margin: 0 0 1.25em; }

.prose h2 {
  margin: 2.4em 0 .6em;
  font-family: var(--font-display);
  font-size: 1.55rem; line-height: 1.2; letter-spacing: -.02em; font-weight: 600;
  color: var(--ink);
  scroll-margin-top: 84px;
}
.prose h3 {
  margin: 2em 0 .5em;
  font-size: 1.16rem; font-weight: 600; letter-spacing: -.01em;
  color: var(--ink);
  scroll-margin-top: 84px;
}

.prose ul, .prose ol { margin: 0 0 1.25em; padding-left: 1.35em; }
.prose li { margin: .45em 0; }
.prose li::marker { color: var(--ink-3); }

.prose strong { color: var(--ink); font-weight: 600; }

.prose code {
  padding: 2px 6px; border-radius: 6px;
  background: var(--surface-2); border: 1px solid var(--line);
  font-family: var(--font-mono); font-size: .87em;
  color: var(--code);
  word-break: break-word;
}

.prose blockquote {
  margin: 1.8em 0; padding: 4px 0 4px 22px;
  border-left: 3px solid var(--accent);
}
.prose blockquote p { margin: 0; color: var(--ink); font-size: 1.06rem; }

.prose hr { margin: 2.6em 0; border: 0; border-top: 1px solid var(--line); }

.prose a { color: var(--accent-ink); }

/* ─── figures ────────────────────────────────────────────────────── */
/* Every image carries width and height from the file, so the browser reserves
   the space before the picture arrives and the text underneath does not jump. */
.fig { margin: 2.4em 0; }
.fig img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line-2); border-radius: var(--radius);
  background: var(--surface);
}
.fig figcaption {
  margin-top: 12px; padding-left: 14px;
  border-left: 2px solid var(--line-2);
  font-size: 14.5px; line-height: 1.5; color: var(--ink-3);
}

/* ─── FAQ ────────────────────────────────────────────────────────── */
.faq { margin: 56px 0 0; padding-top: 32px; border-top: 1px solid var(--line); }
.faq h2 {
  margin: 0 0 20px;
  font-family: var(--font-display); font-size: 1.35rem; font-weight: 600;
  letter-spacing: -.02em;
}
.faq dl { margin: 0; }
.faq dt { margin: 20px 0 6px; font-weight: 600; color: var(--ink); }
.faq dd { margin: 0; color: var(--ink-2); }

/* ─── call to action ─────────────────────────────────────────────── */
.cta {
  margin: 56px 0 0; padding: 30px;
  background: linear-gradient(180deg, var(--surface) 0%, var(--bg-2) 100%);
  border: 1px solid var(--line-2); border-radius: var(--radius);
}
.cta h2 {
  margin: 0 0 10px;
  font-family: var(--font-display); font-size: 1.3rem; font-weight: 600;
  letter-spacing: -.02em;
}
.cta p { margin: 0 0 16px; color: var(--ink-2); }
.cta p:last-child { margin: 0; }

/* ─── cards (index + read next) ──────────────────────────────────── */
/* A bordered grid rather than a list of paragraphs: the homepage is built of
   bordered cards with mono labels, and /blog/ should look like the same firm.
   Each card is a single link — a separate thumbnail link would put the same
   destination in the tab order twice for no gain. */
.card-list {
  list-style: none;
  margin: 26px 0 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}
.card {
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  transition: border-color .18s ease, background .18s ease;
}
.card:hover { border-color: rgba(124,176,255,.42); background: var(--surface-2); }
.card:focus-within { border-color: var(--accent-ink); }

.card-link {
  display: flex; flex-direction: column; height: 100%;
  color: inherit; text-decoration: none;
}
.card-head { position: relative; padding: 24px 52px 22px 26px; }
.card-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.3rem; line-height: 1.2; letter-spacing: -.022em; font-weight: 600;
  color: var(--ink);
  text-wrap: balance;
}
.card:hover .card-title { color: var(--accent-ink); }
.card-dek { margin: 10px 0 0; font-size: 15px; line-height: 1.55; color: var(--ink-2); }
.card-arrow {
  position: absolute; top: 22px; right: 22px;
  font-size: 18px; line-height: 1; color: var(--ink-3);
  transition: color .18s ease, transform .18s ease;
}
.card:hover .card-arrow { color: var(--accent-ink); transform: translate(2px, -2px); }

/* The card image is the post's social card, and that card carries the title —
   which is already the headline two centimetres above it. So the card shows a
   band cropped from the right of it: the grid, the glow and the mark, and none
   of the words. One file still serves both jobs, and the headline is not
   printed twice on the same card. */
/* The band is drawn at the shape it is shown at, so nothing is cropped and
   nothing is scaled up. A post with no band falls back to its social card,
   which is cropped instead — that is why the object-fit is here at all. */
.card-media {
  margin-top: auto;
  border-top: 1px solid var(--line);
  background: var(--bg-2);
  aspect-ratio: 40 / 21;
  overflow: hidden;
}
.card-media img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center 40%;
}

/* The meta row is a strip of cells with hairline dividers, the way the terminal
   card on the homepage is built. Mono, small, and it never wraps to two rows. */
.card-foot { display: flex; border-top: 1px solid var(--line); }
.card-cell {
  padding: 11px 14px;
  border-right: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3); white-space: nowrap;
}
.card-who {
  color: var(--accent-ink); font-weight: 500; letter-spacing: .08em;
  background: rgba(184, 252, 86, .08);
}
.card-cell-draft { color: #7a5c00; background: rgba(250,204,21,.16); }
.card-cell-tags {
  flex: 1; min-width: 0;
  border-right: 0; text-align: right;
  letter-spacing: .1em; text-transform: uppercase;
  overflow: hidden; text-overflow: ellipsis;
}

/* The newest post takes the full width. It is the one a first-time reader
   lands on, and on a blog this small a two-column grid with nothing leading it
   reads as an archive rather than as something being written. */
.card-lead { grid-column: 1 / -1; }
.card-lead .card-head { padding: 32px 64px 28px 32px; }
.card-lead .card-title { font-size: clamp(1.6rem, 3.4vw, 2.15rem); line-height: 1.12; }
.card-lead .card-dek { font-size: 17px; max-width: 62ch; }
/* A 16/3 strip is an editorial band across a card that spans both columns. It
   only reads as one while there are two columns: below 760 the grid collapses,
   the lead card is the same width as every other, and the strip became 60px of a
   photograph that is 3:2 - about a quarter of its height, with the two people in
   it unrecognisable. Below the collapse it takes the same ratio as its
   neighbours. */
.card-lead .card-media { aspect-ratio: 16 / 3; }
@media (max-width: 760px) { .card-lead .card-media { aspect-ratio: 40 / 21; } }
.card-lead .card-arrow { top: 30px; right: 30px; font-size: 22px; }

/* The tag cell hides at 860, not with the rest of this at 760. In the hundred
   pixels between, the cell was narrow enough to clip its own text to an ellipsis:
   measured at 780px, "small business" wanted 141px and had 112, so an iPad in
   portrait read "SMALL BUSINES…". A tag that cannot be finished is worse than no
   tag, and it is the least important thing in the row. */
@media (max-width: 860px) {
  .card-cell-tags { display: none; }
}

/* The same cell clips again in "Read next", and there the window is not what is
   too narrow: those two cards sit inside .wrap-narrow, so they are about 330px
   wide at any window size and the tag ellipsises even at 1440. Related posts do
   not need a tag - the reader is already in the subject. */
.more .card-cell-tags { display: none; }

@media (max-width: 760px) {
  .card-list { grid-template-columns: 1fr; }
  .card-lead .card-head { padding: 24px 52px 22px 26px; }
}

.more { margin-top: 72px; padding: 48px 0 0; border-top: 1px solid var(--line); }
.more h2 {
  margin: 0;
  font-family: var(--font-mono); font-size: 11.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.more .card-list { margin-top: 18px; gap: 16px; }
.more .card-title { font-size: 1.1rem; }
.more .card-dek { font-size: 14.5px; }

/* ─── the section label the homepage uses ────────────────────────── */
.eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  margin: 8px 0 0;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3);
}
.eyebrow-num { color: var(--accent-ink); }
.eyebrow-line { width: 36px; height: 1px; background: var(--line-2); }

.feed-note { margin: 40px 0 0; font-size: 14.5px; color: var(--ink-3); }

/* ─── footer ─────────────────────────────────────────────────────── */
/* Everything else about it is in src/chrome.css. An article ends and needs air
   before the footer starts; the home page's last section brings its own. */
.foot { margin-top: 96px; }

/* ─── reduced motion (SC 2.2.2) ──────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ─── print: an article should survive being printed ─────────────── */
@media print {
  .nav, .cta, .more, .skip, .toc, .card-media, .card-arrow { display: none; }
  .card-list { display: block; }
  body::before, body::after { display: none; }
  .fig { break-inside: avoid; }
  .fig img { border-color: #ccc; }
  body { background: #fff; color: #000; font-size: 12pt; }
  .prose p, .prose li, .dek, .card-dek { color: #000; }
  a { color: #000; }
  .prose a::after { content: " (" attr(href) ")"; font-size: 10pt; color: #444; }
}

/* The cover at the top of a post. The band is 4:1, which sets the page without
   pushing the opening paragraph below the fold. */
.post-cover {
  display: block; width: 100%; height: auto; aspect-ratio: 4 / 1;
  object-fit: cover; margin: 26px 0 4px;
  border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--bg-2);
}

/* Sydney, from Garden Island. CC0 1.0, provenance in public/img/CREDITS.md.
   Wide and short on purpose: it sets the page without pushing the first post
   below the fold on a phone. */
.blog-hero {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 1; object-fit: cover;
  margin: 26px 0 0; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--bg-2);
}
@media (max-width: 560px) { .blog-hero { aspect-ratio: 2 / 1; } }

/* Same wordmark as the home page. */

/* Matches the React Footer on the home page. Four columns, the wordmark, and the
   ABN and street address on the base line. */
/* This div is <div class="wrap foot-inner">. Writing padding as a shorthand here
   reset .wrap's `padding: 0 32px` to zero at equal specificity, so the wordmark,
   the tagline and all eighteen links sat flush against both window edges while
   the ABN line two rows below them - .foot-base, which only sets longhands - kept
   its 32px. Measured at 1440: brand x=100, ABN x=132, header logo x=132. */

/* A figure is a 1200x520 diagram. Cropped into a 420x220 card it became a slice of
   illegible text, so it is contained instead. The figure's own ground is --bg, the
   same as the card, so the letterboxing does not show as a band. A photograph still
   crops, because a photograph reads fine cropped and a diagram does not. */
.card-media-figure img { object-fit: contain; object-position: center; background: var(--bg); }
.card-media-figure { background: var(--bg); }
