/* Public blog (/blog, /blog/:slug) — marketing layout (dark), post type scale
   from the readability spec (custom properties below). The view supplies .aip-section > .aip-wrap, so the left edge
   and side gutter match the marketing pages; .blog is the reading column
   inside it. All hex/rgba via tokens, no OKLCH (brand rule). */

/* The marketing layout only resets box-sizing; blog content relied on the
   old global reset's zero margin/padding. :where() keeps this at zero
   specificity so every rule below still wins. */
:where(.blog, .blog *) { margin: 0; padding: 0; }

/* Post type scale (readability spec). Editable here; colours stay tokens. */
.blog {
  --blog-column-max: 680px;
  --blog-body-size: 18px;
  --blog-body-leading: 1.7;
  --blog-lede-size: 21px;
  --blog-h2-size: 23px;
  --blog-quote-size: 20px;
  --blog-caption-size: 15px;
  --blog-label-size: 14px;
  --blog-meta-size: 15px;
  --blog-para-gap: 20px;
  --blog-h2-gap: 56px;
  --blog-figure-gap: 48px;
  --blog-gallery-gap: 8px;
  max-width: var(--aip-wrap-narrow-max);
  color: var(--fg-1);
}

article.blog { max-width: var(--blog-column-max); }

.blog-head {
  margin-bottom: 40px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--border);
}

/* The article head is roomier than the index head; only the H1 type rule
   below is shared. */
article.blog .blog-head {
  margin-bottom: 48px;
  padding-bottom: 48px;
}

.blog h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(34px, 6vw, 48px);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--fg);
  text-wrap: balance;
}

/* Margins live on the head's h1 only: a Trix heading in the body is an h1 too
   and sets its own margin-top below. */
.blog-head h1 { margin: 0 0 16px; }
article.blog .blog-head h1 { margin: 16px 0 0; }

.blog-meta {
  margin-top: 20px;
  font-family: var(--font-body);
  font-size: var(--blog-meta-size);
  font-weight: 400;
  color: var(--fg-2);
}

.blog-meta a { color: var(--fg-1); text-decoration: underline; text-underline-offset: 3px; }
.blog-meta a:hover { color: var(--accent-hover); }

.blog-empty {
  font-size: 1.02rem;
  color: var(--fg-2);
}

/* Index */

.blog-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.blog-item + .blog-item { border-top: 1px solid var(--border-subtle); }

.blog-item a {
  display: block;
  padding: 28px 0;
  text-decoration: none;
}

.blog-item time {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--fg-3);
}

.blog-item h2 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.4rem;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--fg);
  margin: 6px 0 8px;
}

.blog-item a:hover h2 { color: var(--accent); }

.blog-item p {
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--fg-1);
  margin: 0;
  max-width: var(--measure);
}

/* Lead image thumbnail (Post#lead_image, thumb crop, 16:9). Phone: full
   width above the date. From 720px: a fixed-width column left of the text,
   top-aligned. Posts without an image stay text-only. */
.blog-list { --blog-thumb-width: 280px; }

.blog-thumb {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--bg-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  margin-bottom: 16px;
}

@media (min-width: 720px) {
  .blog-item a.blog-item-media {
    display: grid;
    grid-template-columns: var(--blog-thumb-width) 1fr;
    column-gap: 28px;
    align-items: start;
  }

  .blog-item-media .blog-thumb { margin-bottom: 0; }
}

/* Article body (ActionText) */

/* The body type scale sits on the container, so Trix's <div> paragraphs
   inherit it as well as <p>s (staff bodies are div blocks). */
.blog-body .trix-content {
  font-family: var(--font-body);
  font-size: var(--blog-body-size);
  font-weight: 400;
  line-height: var(--blog-body-leading);
  color: var(--fg-1);
}

/* Flow default: every sibling pair gets the paragraph gap unless a rule below
   says otherwise. :where() on the left keeps this at (0,1,0): enough to beat
   actiontext.css's `.trix-content *` margin reset (0,1,0) on order, yet below
   every `.blog-body <tag>` rule (0,1,1+) that sets its own margin-top. So pre
   and table carry no margin of their own. */
:where(.blog-body) .trix-content > * + * { margin-top: var(--blog-para-gap); }

.blog-body p,
.blog-body li { text-wrap: pretty; }

/* Cancels .trix-content li { margin-left: 1em } (actiontext.css) so the list
   indent is the ul/ol padding alone. */
.blog-body li { margin-left: 0; }

.blog-body p + p,
.blog-body p + ul,
.blog-body p + ol,
.blog-body ul + p,
.blog-body ol + p { margin-top: var(--blog-para-gap); }

/* Lede: the body's first paragraph (a <p>, or a Trix <div> block; never a
   gallery, which is a bare <div> too). */
.blog-body .trix-content > :is(p, div):not(.attachment-gallery):first-child {
  font-size: var(--blog-lede-size);
  line-height: 1.6;
  color: var(--fg);
}

.blog-body p strong { color: var(--fg); font-weight: 600; }

/* Trix's heading button emits h1; style it like the interview question h2. */
.blog-body h1,
.blog-body h2 {
  font-family: var(--font-display);
  font-size: var(--blog-h2-size);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
  color: var(--fg);
  margin-top: var(--blog-h2-gap);
  text-wrap: balance;
}

.blog-body h1:first-child,
.blog-body h2:first-child { margin-top: 0; }

.blog-body h1 + :is(p, div),
.blog-body h2 + :is(p, div),
.blog-body h3 + :is(p, div) { margin-top: 16px; }

.blog-body h3 {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--fg);
  margin-top: 32px;
  letter-spacing: -0.005em;
}

.blog-body a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.blog-body a:hover { color: var(--accent-hover); }

.blog-body ul,
.blog-body ol { padding-left: 1.2rem; }
.blog-body li + li { margin-top: 8px; }

/* The prompt line: italic, no bar, no indent (overrides trix.css). */
.blog-body blockquote {
  margin: 24px 0 0;
  padding: 0;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--blog-quote-size);
  font-style: italic;
  font-weight: 400;
  line-height: 1.55;
  color: var(--fg);
}

/* <blockquote><p>…</p></blockquote>: the inner block keeps the quote's type,
   not the body's, and sits flush at the top. */
.blog-body blockquote :is(p, div) {
  font: inherit;
  color: inherit;
  line-height: inherit;
}
.blog-body blockquote > :is(p, div):first-child { margin-top: 0; }

/* Figures: one image or one gallery per block. */
.blog-body action-text-attachment,
.blog-body .attachment-gallery { display: block; margin-top: var(--blog-figure-gap); }
.blog-body blockquote + action-text-attachment,
.blog-body blockquote + .attachment-gallery { margin-top: 40px; }
.blog-body .attachment-gallery > action-text-attachment { margin-top: 0; }
/* A body that opens with a figure sits flush under the head, like h1/h2. */
.blog-body .trix-content > action-text-attachment:first-child,
.blog-body .trix-content > .attachment-gallery:first-child { margin-top: 0; }

.blog-body .attachment--preview { text-align: left; }

.blog-body img {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}

/* Three classes on purpose: actiontext.css sets the preview caption's colour,
   size and leading at .trix-content .attachment--preview .attachment__caption
   (0,3,0); this one wins on order. */
.blog-body .attachment--preview .attachment__caption {
  margin-top: 12px;
  font-family: var(--font-body);
  font-size: var(--blog-caption-size);
  font-weight: 400;
  line-height: 1.55;
  color: var(--fg-2);
  text-align: left;
}

/* Galleries: two-up at every width, 4:3 tiles, a short label under each. */
.blog-body .attachment-gallery {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--blog-gallery-gap);
}
/* The .trix-content prefix lifts this to (0,3,1) so it beats actiontext.css's
   .attachment-gallery--2 > action-text-attachment (max-width: 50%) on order. */
.blog-body .trix-content .attachment-gallery > action-text-attachment,
.blog-body .trix-content .attachment-gallery > .attachment {
  max-width: none;
  padding: 0;
  flex: none;
}
.blog-body .attachment-gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.blog-body .attachment-gallery .attachment__caption {
  margin-top: 8px;
  font-size: var(--blog-label-size);
  font-weight: 600;
  color: var(--fg-1);
}

/* A plain paragraph after a gallery (before the caption rule, so the
   em-only caption below keeps its 12px). */
.blog-body .attachment-gallery + p { margin-top: var(--blog-figure-gap); }

/* Group caption: a paragraph holding only <em>, straight after a gallery
   (bot contract, readability spec). Without :has() it stays body text. */
.blog-body .attachment-gallery + p:has(> em:only-child) {
  margin-top: 12px;
  font-size: var(--blog-caption-size);
  line-height: 1.55;
  color: var(--fg-2);
}
.blog-body .attachment-gallery + p:has(> em:only-child) em { font-style: normal; }

/* A paragraph after a figure. */
.blog-body action-text-attachment + p { margin-top: var(--blog-figure-gap); }

.blog-body code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--bg-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: 6px;
  padding: 1px 6px;
}

.blog-body pre {
  background: var(--bg-sunken);
  border: 1px solid var(--border-subtle);
  border-radius: 12px;
  padding: 16px 20px;
  overflow-x: auto;
}

.blog-body pre code {
  background: none;
  border: none;
  padding: 0;
  font-size: 0.85rem;
  line-height: 1.6;
}

/* Video embeds (VideoEmbed partial): a full-width 16:9 player. */
.blog-body .attachment--video { display: block; width: 100%; margin-inline: 0; }
.blog-body .attachment--video iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--radius-md);
}

.blog-body hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 40px 0;
}

.blog-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.blog-body th,
.blog-body td {
  text-align: left;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-subtle);
}

.blog-body th { color: var(--fg); font-weight: 600; }

.blog-foot {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

.blog-foot a {
  font-size: 16px;
  color: var(--accent);
  text-decoration: none;
}

.blog-foot a:hover { color: var(--accent-hover); }

/* Author card (avatar, name, title, bio, links): every part is optional. */
.blog-author {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  margin-bottom: 32px;
  padding: 20px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.blog-author-avatar {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
}

.blog-author-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  color: var(--fg);
}

.blog-foot .blog-author-name a { font-size: inherit; color: inherit; }
.blog-foot .blog-author-name a:hover { color: var(--accent-hover); }

.blog-author-title {
  margin-top: 2px;
  font-size: var(--blog-label-size);
  color: var(--fg-2);
}

.blog-author-bio {
  margin-top: 8px;
  font-size: var(--blog-meta-size);
  line-height: 1.6;
  color: var(--fg-1);
}

.blog-author-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-top: 10px;
  list-style: none;
}

.blog-foot .blog-author-links a { font-size: var(--blog-label-size); }
