/* User landing page, all three layouts (S069's list; S070's grid/magazine) —
 * component-level styling for `web/templates/blog/{list,grid,magazine}.html`, per
 * `web/static/css/app.css`'s own module doc ("component-level styling for individual
 * pages ... belongs to the steps that add those templates"). Reuses the shared
 * `.wrap-main` shell (D-33) and every token in `tokens.css`; introduces no new colour.
 * Touches correction recorded in D-73 (S069) and D-78 (S070) — neither card named this
 * stylesheet, the same class of omission D-65/D-68/D-70 already amended for earlier steps.
 *
 * `design/design_handoff_agentblog/mockups/Blog.dc.html`: list is a max-`68ch` column
 * (`.article`'s own reading measure, reused rather than re-declared — this page's cards
 * hold the same prose as the article page, at the same measure) with one bordered
 * "Featured" card then a plain divided `<ol>` of rows; grid reuses that same "Featured"
 * card spanning every column of an `auto-fill, minmax(260px,1fr)` tile wall; magazine is a
 * full-bleed featured block above a two-column "Recent" list + Topics/About sidebar split.
 *
 * Every `<p>` rule below is scoped through its container class (`.post-card .foo`, never
 * bare `.foo`) for the same reason `post.css` scopes `.article-header .eyebrow`/`.dek`:
 * `app.css`'s `.wrap-main p` is `(0,1,1)` and silently wins over a single bare class
 * `(0,1,0)` — a bare `.post-card-eyebrow` loses its `color: var(--accent)` to
 * `.wrap-main p`'s `color: var(--text-2)` entirely, and every other bare rule below would
 * lose its `margin` the same way (post.css's own module doc, S067 review round 3). */

.blog-header {
  margin-bottom: var(--space-10);
  /* `Blog.dc.html:57` narrows the title/description block to `60ch`, distinct from the
     `68ch` `--measure-reading` the list column below keeps (S069 review, nit). */
  max-width: 60ch;
}

/* `Blog.dc.html:58-59,122-123`: the owner name/bio block's own type scale — 32px/400/1.15
   title, 16px/1.6 description with no bottom margin — distinct from the global `h1`/
   `.wrap-main p` defaults (28px/1.2 heading, 15px/1.55 body with a `--space-5` bottom
   margin) every other system page uses (S077e/D-90). The mockup's empty-state block
   (`Blog.dc.html#empty`) reuses this exact title scale for its own `<h1>`, so `.blog-empty
   h1` shares the rule rather than duplicating it; the subtitle keeps its own margin
   (`.blog-empty-subtitle` below) and only borrows the 16px/1.6 type scale.
   `.blog-header p` alone is `(0,1,1)`, the same specificity as `app.css`'s `.wrap-main p`
   — a tie the cascade resolves by stylesheet order, not specificity, which is the exact
   defect class `app.css:156-159`'s `.wrap-bar.blog-footer` finding already named (S077a
   review round 4). Scoped through `.wrap-main .blog-header p` ((0,2,1)) so it wins
   regardless of link order (S077e review round 1, minor). */
.blog-header h1,
.blog-empty h1 {
  margin: 0 0 var(--space-2);
  font-size: 32px;
  line-height: 1.15;
}

.wrap-main .blog-header p {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
}

.blog-list {
  max-width: var(--measure-reading);
}

.post-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface);
  padding: var(--space-6);
  margin-bottom: var(--space-2);
}

.post-card .post-card-eyebrow {
  margin: 0 0 var(--space-2);
  font-family: var(--mono);
  font-size: var(--size-mono);
  /* `Blog.dc.html:66,84,99` tracks every "Featured" eyebrow — list card, grid tile and
     magazine block alike — at `.06em`, the same value `tokens.css` reserves under
     `--tracking-eyebrow-article` for the article's own eyebrow; that token's name predates
     this finding (S077d named it "the one eyebrow the handoff tracks at .06em", which
     `Blog.dc.html` contradicts) but renaming it means editing `tokens.css`/`post.css`,
     both outside this card's `Touches` — reused as-is rather than duplicating the literal
     (S077e/D-90). */
  letter-spacing: var(--tracking-eyebrow-article);
  text-transform: uppercase;
  color: var(--accent);
}

.post-card h2,
.post-row h2 {
  font-family: var(--display);
  font-weight: 500;
}

.post-card h2 {
  margin: 0 0 var(--space-2);
  font-size: var(--size-h1);
}

/* `Blog.dc.html:72-75`: a list row's own title/dek scale is smaller than the featured
   card's — 22px/1.3 title with a 6px bottom margin, 15px/1.55 dek with the same 6px
   margin — distinct from `.post-card`'s 28px/1.2/`--space-3` scale above (S077e/D-90). No
   token lands on 6px, so it's raw like this file's other one-off margins. */
.post-row h2 {
  margin: 0 0 6px;
  font-size: var(--size-h2);
  line-height: 1.3;
}

.post-card h2 a,
.post-row h2 a {
  color: var(--text);
}

.post-card .post-card-dek,
.post-row .post-row-dek {
  max-width: none;
  line-height: 1.6;
  color: var(--text-2);
}

.post-card .post-card-dek {
  margin: 0 0 var(--space-3);
  font-size: 16px;
}

.post-row .post-row-dek {
  margin: 0 0 6px;
  font-size: var(--size-ui);
  line-height: 1.55;
}

/* Shared by every landing surface's meta line (S077c) — the featured card, list rows,
 * grid tiles, the magazine featured block, and the magazine Recent list — one class
 * `partials/post_meta.html` now owns, replacing the four near-identical per-surface
 * rules it used to be (`post-card-meta`/`post-row-meta`/`grid-tile-meta`/magazine's own
 * reuse of `post-card-meta`), per AGENTS.md's "second callsite" rule. The magazine
 * Recent list's own narrow date column needs its own grid-item positioning on top of
 * this, added near `.magazine-recent` below. */
.post-card .post-meta,
.post-row .post-meta,
.grid-tile .post-meta,
.magazine-featured .post-meta,
.magazine-recent .post-meta {
  margin: 0;
  max-width: none;
  font-family: var(--mono);
  font-size: var(--size-mono);
  color: var(--text-2);
}

/* Each `· N min`/`· N sources`/`· N claim` segment `partials/post_meta.html` emits is
 * wrapped in its own `.post-meta-seg`, including the leading " · " — this is the only
 * break opportunity the line has, so a narrow tile (the grid tile's own
 * `minmax(260px,1fr)` column) wraps between segments and never inside one (S077c review
 * round 2, minor: at that width the populated line used to break mid-segment, e.g.
 * "2 sources · 1" / "claim"). */
.post-meta-seg {
  white-space: nowrap;
}

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

.post-row {
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--line);
}

/* Base rule shared by every paginated page lives in `app.css`; this page only ever
 * renders one link ("Older →"), so it right-aligns it. */
.pagination {
  justify-content: flex-end;
}

.blog-empty {
  /* `Blog.dc.html#empty` narrows the empty-state block to `60ch`, the same nit `.blog-header`
     corrects above. */
  max-width: 60ch;
}

.blog-empty .blog-empty-subtitle {
  margin: 0 0 var(--space-8);
  max-width: none;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-2);
}

.empty-card {
  border: 1px dashed var(--line);
  border-radius: var(--radius-m);
  /* `Blog.dc.html#empty:124`: `28px 24px`, not `--space-8 --space-6` (32px 24px) — no
     token lands on 28px (S077e/D-90). */
  padding: 28px var(--space-6);
}

.empty-card .empty-card-title {
  /* `Blog.dc.html#empty:125`: `margin:0 0 6px`, not `--space-2` (8px) — no token lands on
     6px (S077e/D-90). */
  margin: 0 0 6px;
  max-width: none;
  font-family: var(--display);
  font-size: var(--size-h2);
  color: var(--text);
}

.empty-card.empty-card-visitor {
  /* `Auth States.dc.html#empty-blog`: the visitor-facing counterpart is a solid surface
     card, not the owner's dashed nudge — README §4/§5 calls the two states out as distinct
     (S069 review, minor). Exact mockup padding/min-height: no `--space-*` token lands on
     40/28, and a fixed min-height keeps the card's footprint stable regardless of copy
     length. */
  border-style: solid;
  background: var(--surface);
  padding: 40px 28px;
  min-height: 280px;
}

.empty-card .empty-card-note {
  margin: 0 0 var(--space-5);
  max-width: none;
  font-size: var(--size-ui);
  line-height: 1.6;
  color: var(--text-2);
}

.empty-card-steps {
  margin: 0 0 var(--space-5);
  padding-left: var(--space-5);
  font-size: var(--size-ui);
  line-height: 1.8;
  color: var(--text-2);
}

/* `Blog.dc.html#empty:132`: 14px, not `--size-helper` (13px) — a wrong-token pick, not a
   spacing rounding (S077e/D-90). */
.empty-card .empty-card-fallback {
  margin: 0;
  max-width: none;
  font-size: var(--size-ui-dense);
  color: var(--text-2);
}

/* Grid view (S070). Compound selectors throughout for the same `(0,1,1)` reason as the
 * list rules above — `.grid-tile h2`/`.grid-tile-dek` are never bare; the meta line's own
 * `.post-meta` is the shared S077c rule above. */
.blog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-4);
}

.grid-tile-featured {
  /* Reuses `.post-card`'s border/background/padding (same markup class, module docs);
     this rule only adds the grid-specific placement and inner layout `.post-card` alone
     does not need. `margin-bottom: 0` neutralizes `.post-card`'s own row-spacing margin —
     `.blog-grid`'s `gap` already spaces the featured tile from the row below it, so
     keeping both would double that gap. */
  grid-column: 1 / -1;
  margin-bottom: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-6);
  align-items: end;
}

/* `Blog.dc.html:84`: the featured tile's own title is 32px/1.15 with no bottom margin —
   the two-column `grid-tile-featured` layout already spaces the eyebrow/title block from
   the dek/meta column beside it via its own `gap` — distinct from `.post-card h2`'s
   28px/`--size-h1` the list view's featured card keeps (S077e/D-90). `.post-card
   .grid-tile-featured h2` (0,2,1) beats `.post-card h2` (0,1,1) on specificity rather than
   relying on source order. */
.post-card.grid-tile-featured h2 {
  margin: 0;
  font-size: 32px;
  line-height: 1.15;
}

.grid-tile {
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  background: var(--surface);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* `Blog.dc.html:87-92`: every non-featured grid tile title is 21px/1.3, not `--size-h2`
   (22px/inherited 1.2) — no token lands on 21px (S077e/D-90). */
.grid-tile h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 500;
  font-size: 21px;
  line-height: 1.3;
}

.grid-tile h2 a {
  color: var(--text);
}

.grid-tile .grid-tile-dek {
  margin: 0;
  max-width: none;
  font-size: var(--size-ui-dense);
  line-height: 1.55;
  color: var(--text-2);
}

.grid-tile .grid-tile-tags {
  margin-top: auto;
  padding-top: var(--space-2);
}

/* `Blog.dc.html:87`: the grid tile's own tag chip is smaller than the shared `.chip`
   below (magazine Topics cloud, `:114`, `1px 7px`/`11px` vs `3px 10px`/`13px`) — the same
   "two distinct chip paddings need separate rules" finding `post.css`'s article-footer/
   concept-card split already made (S077d, D-90). No token lands on 7px/11px, so this is a
   raw value like that split's own. */
.grid-tile-tags .chip {
  padding: 1px 7px;
  font-size: 11px;
}

/* Magazine view (S070). */
.magazine-featured {
  margin-bottom: var(--space-10);
  padding-bottom: var(--space-10);
  border-bottom: 1px solid var(--line);
}

.magazine-featured .eyebrow {
  margin: 0 0 var(--space-3);
  font-family: var(--mono);
  font-size: var(--size-mono);
  /* `Blog.dc.html:99` — the same `.06em` finding `.post-card-eyebrow` above cites. */
  letter-spacing: var(--tracking-eyebrow-article);
  text-transform: uppercase;
  color: var(--accent);
}

.magazine-featured h2 {
  margin: 0 0 var(--space-4);
  max-width: 24ch;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(32px, 4.5vw, 48px);
  line-height: 1.1;
  letter-spacing: var(--tracking-display);
}

.magazine-featured h2 a {
  color: var(--text);
}

/* `Blog.dc.html:101`: the italic display dek is 20px, a step below `--size-h2` (22px) —
   deliberately smaller than the card-title scale here (S077e/D-90). No token lands on
   20px. */
.magazine-featured .dek {
  margin: 0 0 var(--space-3);
  max-width: 56ch;
  font-family: var(--display);
  font-style: italic;
  font-size: 20px;
  line-height: 1.5;
  color: var(--text-2);
}

.magazine-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-12);
  align-items: start;
}

.magazine-grid h3,
.layout-section h3 {
  margin: 0 0 var(--space-4);
  font-family: var(--mono);
  font-size: var(--size-mono);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--text-2);
  font-weight: 400;
}

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

.magazine-recent li {
  /* Single-column row instead of `Blog.dc.html`'s two-column `72px 1fr` date layout, per
     `docs/decisions.md` D-90's exception register ("`Blog.dc.html`'s magazine Recent row
     draws each entry as a two-column..."): a populated `date · N min · N sources ·
     N claim(s)` line no longer fits a 72px date column on one line (S077c review round 2,
     minor). */
  display: grid;
  gap: var(--space-2);
  /* `Blog.dc.html:107-110`: `14px 0`, not `--space-4` (16px) — no token lands on 14px
     (S077e/D-90). */
  padding: 14px 0;
  border-top: 1px solid var(--line);
}

/* `Blog.dc.html:110` closes the list with a bottom border on the last row, so the column
   doesn't end open-ended (S077e/D-90). */
.magazine-recent li:last-child {
  border-bottom: 1px solid var(--line);
}

/* `Blog.dc.html:107` margins each Recent row's title 4px off its dek, not the 8px
   `--space-2` every other card title below uses (S077e/D-90); `line-height:1.3`, not the
   inherited 1.2 (S077e review round 1, minor). */
.magazine-recent h2 {
  margin: 0 0 var(--space);
  font-family: var(--display);
  font-weight: 500;
  font-size: var(--size-h2);
  line-height: 1.3;
}

.magazine-recent h2 a {
  color: var(--text);
}

.magazine-recent p {
  margin: 0;
  max-width: none;
  font-size: var(--size-ui-dense);
  color: var(--text-2);
}

.magazine-sidebar {
  display: grid;
  gap: var(--space-8);
  align-content: start;
}

/* `auto-fit` (`.magazine-grid`, above) collapses empty tracks, so a magazine blog with no
 * "Recent" section (one published post, `blog/magazine.html`'s own `{% if posts or
 * next_href %}` guard) leaves the sidebar as the grid's sole child, stretching Topics/About
 * to the full 1032px content measure — a render `mockups/Blog.dc.html` has no state for and
 * D-90's exception register does not carry (S080 review round 3, minor). Capped to the same
 * width the sidebar column renders at when the split is populated. */
.magazine-grid > .magazine-sidebar:only-child {
  max-width: 360px;
}

.magazine-sidebar .about-blurb {
  margin: 0;
  max-width: none;
  font-size: var(--size-ui);
  line-height: 1.6;
  color: var(--text-2);
}

/* Tag/topic chip, shared by the grid view's per-tile footer and the magazine sidebar's
 * Topics cloud — the same visual as `post.css`'s `.chip`/`.chip-row` (the article page's
 * tag-chip row, S067), redeclared here rather than cross-imported: each page loads only
 * its own component stylesheet (this module's own doc, "belongs to the steps that add
 * those templates"), and `post.css`'s bare `.chip`/`.chip-row` selectors are its own
 * module's private contract, not one this page depends on. */
.chip-row {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: center;
}

/* `Blog.dc.html:114`: `3px 10px`, not `3px --space-3` (3px 12px) — no token lands on
   10px (S077e review round 1, minor: the grid-tile-tags comment above already claimed
   this value; the shared rule itself still shipped 12px). */
.chip {
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  padding: 3px 10px;
  font-family: var(--mono);
  font-size: var(--size-helper);
  color: var(--text);
}

.chip-count {
  color: var(--text-2);
}

/* README's "all grids use `repeat(auto-fit/auto-fill, minmax(...))` so columns collapse to
 * 1-up on narrow viewports" already holds without help once the container is narrower than
 * one `minmax()` track — this rule is the explicit, greppable contract the `Tests` bullet
 * asks for ("collapse to 1-up asserted via CSS media query presence", D-78), forcing both
 * grids to a single column well above where the fluid collapse would otherwise bite. */
@media (max-width: 640px) {
  .blog-grid,
  .grid-tile-featured,
  .magazine-grid {
    grid-template-columns: 1fr;
  }
}

/* A published layout document's own `sections[]` (S118,
 * `web/templates/partials/layout_sections.html`) — supplementary blocks rendered after
 * the main list/grid/topics: before pagination on list/grid, but after the whole
 * two-column `.magazine-grid` (Recent column, its own nested pagination, and the
 * Topics/About sidebar) on magazine (D-90's exception register, S118 review round 1,
 * minor: this comment previously claimed "before pagination" uniformly). `.post-list`/
 * `.post-row` above already style this block's rows (bare selectors, so they apply here
 * without a second copy) — only the section's own spacing needs declaring here; the
 * heading rule itself is grouped with `.magazine-grid h3` above, one declaration for
 * both rather than duplicated per layout (S118 review round 2, nit: this comment used to
 * claim "generalized" while the rule below was a byte-for-byte copy). */
.layout-section {
  margin-top: var(--space-10);
}
