/* ===========================================================================
   BLOG

   Layered on site.css rather than replacing it: the nav, the footer, the type
   scale, the accent and the particle field are all shared, so a post cannot
   drift away from the rest of the site.

   The reference's shape — one featured post given real size, then everything
   else as a list — is worth copying because it answers the two questions a
   blog index gets asked: "what should I read" and "what else is there". A flat
   grid of equal cards answers neither.
   ========================================================================= */

/* ---------------------------------------------------------------- featured */
.bl-feature{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(24px,4vw,56px);align-items:center;
  padding:clamp(22px,2.6vw,32px);border-radius:var(--r-lg);
  border:1px solid color-mix(in srgb,var(--border) 60%,transparent);
  background:var(--card);
  transition:border-color .35s var(--ease-ui),transform .45s var(--ease-out)}
.bl-feature:hover{border-color:color-mix(in srgb,var(--primary) 40%,transparent);
  transform:translateY(-3px)}
.bl-feature-media{aspect-ratio:16/10;border-radius:var(--r-md);overflow:hidden;
  display:grid;place-items:center;padding:26px;text-align:center;
  border:1px solid color-mix(in srgb,var(--border) 55%,transparent);
  background:radial-gradient(65% 65% at 50% 45%, hsl(var(--glow-a) / .42), transparent 70%),#05070d}
/* ---------------------------------------------------------------- the mark
   One icon per post, from a closed set in build's icons.py. Two tones and no
   more: --primary is what the post is about, --muted is the situation it sits
   in. Both come from `color` on the group, so the palette stays the only
   place a colour is written down — see docs/image-brief.md for why there is
   no third hue and no blue anywhere near this.

   ONLY ON THE LIST CARD, and that is the whole rule. The feature card is
   16:10 and large, and its phrase already reads at 22-34px — an icon above it
   would be a second, smaller statement of the same thing, which is the
   definition of decoration and is what image-brief.md rules out. The icon is
   for the 132px card, where the phrase was set at 12.5px beside a title at
   18-22px and lost.

   --muted AT FULL STRENGTH, not faded. The first version had the dim half at
   78% over a near-black card and the frames, the folder and the window behind
   simply were not there — design-system.md §11 says in as many words never to
   reduce contrast for de-emphasis, and this was that mistake drawn in SVG.
   The hierarchy is carried by which shape is rust, not by how faint the other
   one is.
   ------------------------------------------------------------------------ */
.bl-icon{width:34px;height:34px;flex:none;color:var(--primary)}
.bl-icon .i-dim{color:var(--muted)}

.bl-feature-media b{font-family:"Cabinet Grotesk",sans-serif;font-weight:500;
  font-size:clamp(22px,2.6vw,34px);line-height:1.12;letter-spacing:-.014em;color:var(--lit-ink)}
.bl-feature-title{font-size:var(--t-h3);line-height:var(--lh-h3);letter-spacing:var(--ls-h3);
  margin:0;transition:color .3s var(--ease-ui)}
.bl-feature:hover .bl-feature-title{color:var(--primary)}
.bl-feature-sum{margin:var(--s-3) 0 0;color:var(--ink-soft);max-width:52ch}
.bl-feature .note-go{margin-top:var(--s-4)}

/* ------------------------------------------------------------------- list */
.bl-all{margin:var(--s-7) 0 var(--s-4)}
.bl-list{display:grid;gap:0;
  border-top:1px solid color-mix(in srgb,var(--border) 45%,transparent)}
/* A list with rules rather than a grid of cards. These are all the same kind
   of thing at the same level of importance, and boxing each one would say they
   are separate objects competing for attention. */
.bl-item{display:grid;grid-template-columns:132px minmax(0,1fr);gap:clamp(18px,2.4vw,30px);
  align-items:center;padding:var(--s-4) 0;
  border-bottom:1px solid color-mix(in srgb,var(--border) 45%,transparent);
  transition:background .28s var(--ease-ui)}
.bl-item:hover{background:color-mix(in srgb,var(--secondary) 45%,transparent)}
.bl-item-media{aspect-ratio:16/10;border-radius:var(--r-sm);overflow:hidden;
  display:grid;place-items:center;padding:12px;text-align:center;
  border:1px solid color-mix(in srgb,var(--border) 50%,transparent);
  background:radial-gradient(65% 65% at 50% 45%, hsl(var(--glow-a) / .34), transparent 70%),#05070d}
.bl-item-media b{font-family:"Cabinet Grotesk",sans-serif;font-weight:500;
  font-size:12.5px;line-height:1.18;letter-spacing:-.006em;color:var(--lit-ink)}
.bl-item-title{font-family:"Cabinet Grotesk",sans-serif;font-weight:500;
  font-size:clamp(18px,1.8vw,22px);line-height:1.2;letter-spacing:-.01em;
  color:var(--fg);margin:0;transition:color .3s var(--ease-ui)}
.bl-item:hover .bl-item-title{color:var(--primary)}
.bl-item-sum{margin:var(--s-1) 0 0;color:var(--ink-soft);font-size:15px;max-width:62ch}
.bl-item-meta{display:flex;flex-wrap:wrap;gap:var(--s-2);margin:var(--s-2) 0 0}

/* ------------------------------------------------------------------- post */
.bl-post{padding-top:calc(84px + var(--s-6))}
/* One column, measured. Prose is read, not scanned, and a line longer than
   about 70 characters loses the reader on the carriage return. */
.bl-article{max-width:none}
.bl-crumb{font-family:"JetBrains Mono",monospace;font-size:12px;color:var(--muted);
  margin:0 0 var(--s-5);max-width:68ch;margin-inline:auto}
.bl-crumb a:hover{color:var(--primary)}
.bl-title{font-size:var(--t-h2);line-height:var(--lh-h2);letter-spacing:var(--ls-h2);
  margin:0 auto;max-width:20ch}
.bl-meta{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:var(--s-4) auto 0;max-width:68ch;
  font-family:"JetBrains Mono",monospace;font-size:12px;color:var(--muted)}
.bl-dot{opacity:.5}

.bl-body{max-width:68ch;margin:var(--s-6) auto 0;
  font-size:17.5px;line-height:1.62;color:var(--ink-soft)}
.bl-body h2{font-family:"Cabinet Grotesk",sans-serif;font-weight:500;color:var(--fg);
  font-size:clamp(24px,2.6vw,30px);line-height:1.14;letter-spacing:-.014em;
  /* More space above than below: a heading belongs to what follows it. */
  margin:var(--s-6) 0 var(--s-3)}
.bl-body h3{font-family:"Cabinet Grotesk",sans-serif;font-weight:500;color:var(--fg);
  font-size:20px;margin:var(--s-5) 0 var(--s-2)}
.bl-body p{margin:0 0 var(--s-3)}
.bl-body strong{color:var(--fg);font-weight:500}
.bl-body a{color:var(--primary);text-decoration:underline;text-underline-offset:2px;
  text-decoration-color:color-mix(in srgb,var(--primary) 45%,transparent)}
.bl-body a:hover{text-decoration-color:var(--primary)}
.bl-body ul,.bl-body ol{margin:0 0 var(--s-3);padding-left:1.15em}
.bl-body li{margin:0 0 6px}
.bl-body code{font-family:"JetBrains Mono",monospace;font-size:.88em;
  background:var(--secondary);border-radius:5px;padding:2px 6px;color:var(--fg)}
.bl-body hr{border:0;border-top:1px solid color-mix(in srgb,var(--border) 45%,transparent);
  margin:var(--s-6) 0}
.bl-body .code-block{position:relative;margin:0 0 var(--s-4)}
.bl-body pre{margin:0;padding:16px 18px;border-radius:var(--r-md);overflow-x:auto;
  background:var(--secondary);border:1px solid color-mix(in srgb,var(--border) 50%,transparent)}
.bl-body pre code{background:none;padding:0;font-size:13.5px;line-height:1.55}
.bl-body .code-copy{display:none}
/* A callout earns its left rule: it marks a genuine aside, which is the one
   case where a coloured edge is state rather than decoration. */
.bl-body .callout{margin:0 0 var(--s-4);padding:14px 18px;border-radius:var(--r-md);
  background:var(--secondary);border-left:2px solid var(--primary)}
.bl-body .callout-t{font-family:"JetBrains Mono",monospace;font-size:11.5px;
  letter-spacing:.05em;text-transform:uppercase;color:var(--primary);margin:0 0 6px}
.bl-body .callout p{margin:0}
.bl-body .table-wrap{overflow-x:auto;margin:0 0 var(--s-4)}
.bl-body table{width:100%;border-collapse:collapse;font-size:15px}
.bl-body th,.bl-body td{text-align:left;padding:10px 12px;
  border-bottom:1px solid color-mix(in srgb,var(--border) 45%,transparent)}
.bl-body th{font-family:"JetBrains Mono",monospace;font-size:11.5px;
  letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:400}
.bl-body .h-anchor{display:none}

.bl-foot{max-width:68ch;margin:var(--s-7) auto 0;padding-top:var(--s-5);
  border-top:1px solid color-mix(in srgb,var(--border) 45%,transparent);
  display:flex;align-items:center;justify-content:space-between;gap:var(--s-4);flex-wrap:wrap}
.bl-next{display:grid;gap:4px;max-width:34ch}
.bl-next .k{font-family:"JetBrains Mono",monospace;font-size:11px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted)}
.bl-next .t{font-family:"Cabinet Grotesk",sans-serif;font-weight:500;font-size:17px;
  color:var(--fg);transition:color .3s var(--ease-ui)}
.bl-next:hover .t{color:var(--primary)}
.bl-back{font-family:"JetBrains Mono",monospace;font-size:12px;color:var(--muted)}
.bl-back:hover{color:var(--primary)}

@media (max-width:900px){
  .bl-feature{grid-template-columns:1fr}
  .bl-item{grid-template-columns:96px minmax(0,1fr);gap:16px}
  .bl-item-media b{font-size:11px}
}
@media (max-width:560px){
  .bl-item{grid-template-columns:1fr}
  .bl-item-media{aspect-ratio:16/7}
}
