/* ══════════════════════════════════════════════════════════════════════
   listing.css — PAGE LAYOUT for the forum HOME page (functions/index.js)
   and the CATEGORY listing (functions/c/[slug].js). Nothing else links it.

   WHAT THIS FILE IS NOT. It does not define the list, tab, pill, avatar,
   pager or badge PRIMITIVES — .bf-list, .bf-list-row, .bf-list-row__main /
   __title / __meta / __stat / __latest, .bf-list-head, .bf-tabs / .bf-tab,
   .bf-pill*, .bf-badge, .bf-pin, .bf-avatar*, .bf-pager*, .bf-crumbs,
   .bf-empty and .bf-num all live in /forum.css, which every page already
   loads through shell(). Defining any of them a second time here is how two
   design systems quietly diverge; this sheet only positions them.

   WHAT IT IS. Two things a shared primitive cannot know:
     1. the COLUMN TEMPLATE of a row on THIS page (a category row has four
        columns, a thread row has three — same primitive, different grid), and
     2. the bands around the lists (page head, block heads, the rules panel).
   Both are scoped under .bfl-cats / .bfl-threads / .bfl-* so they can never
   reach a .bf-list-row on the thread page or in the chrome.

   COLOUR. Every value below is a token from /forum.css's :root — there is no
   raw hex in this file. The one hsl() is the deterministic avatar/marker hue,
   whose --av-h channel is set per element by the server (see index.js's
   avatarHue()) exactly as the shared contract specifies.

   LIGHT THEME ONLY, deliberately: the forum matches the store, which has one
   theme. No prefers-color-scheme block belongs here.
═══════════════════════════════════════════════════════════════════════ */

/* ── PAGE HEAD ─────────────────────────────────────────────────────────
   Compact by design. What stood here before was a marketing hero plus a
   gradient promo card, which pushed every thread title below the fold —
   the one thing a forum front page exists to show. One h1, one line, one
   quiet stat row, then straight into the rooms. */
.bfl-head{
  display:flex;
  flex-direction:column;
  gap:6px;
}
.bfl-title{
  font-family:var(--f-display);
  font-weight:500;
  font-size:var(--t-h2);
  letter-spacing:-.015em;
  line-height:1.1;
  color:var(--ink);
  margin:0;
}
.bfl-lede{
  font-family:var(--f-text);
  font-size:16px;
  line-height:1.6;
  color:var(--body);
  max-width:66ch;
  margin:0;
}
/* The old stat CLUSTER was two big numbers in their own dl, competing with
   the headline. A forum's totals are orientation, not a headline — mono,
   small, one line, the same idiom as every other label in the system. */
/* The orientation line. Still mono, still small — but it was 11px at
   2.36:1 on the canvas, which is a decorative smudge where the forum states
   how big it is. Lifted to the meta tier and given its figures real ink:
   "1,566 threads" is the single most reassuring thing on the page for a
   stranger deciding whether anyone is here. */
.bfl-stats{
  font-family:var(--f-mono);
  font-size:11.5px;
  letter-spacing:.07em;
  text-transform:uppercase;
  color:var(--body);
  margin:4px 0 0;
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  gap:6px;
}
.bfl-stats .bf-num{ color:var(--ink); font-weight:600; }
.bfl-sep{ color:var(--text-mute); }

/* Category page head — the same band with the New-thread action pinned right. */
.bfl-cat-head{
  flex-direction:row;
  flex-wrap:wrap;
  align-items:flex-end;
  justify-content:space-between;
  gap:16px;
}
.bfl-cat-head-text{
  display:flex;
  flex-direction:column;
  gap:6px;
  flex:1;
  min-width:min(100%, 300px);
}

/* ── BLOCKS (a heading + its list) ─────────────────────────────────────
   .bf-main is already a flex column with a --s3 gap, so a block only owns
   the space between its own head and its list. */
.bfl-block{
  display:flex;
  flex-direction:column;
  gap:10px;
}
.bfl-block-head{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  padding-bottom:2px;
}
.bfl-block-title{
  font-family:var(--f-display);
  font-weight:500;
  font-size:var(--t-h3);
  letter-spacing:-.01em;
  line-height:1.2;
  color:var(--ink);
  margin:0;
}
.bfl-block-blurb{
  font-family:var(--f-text);
  font-size:14px;
  line-height:1.5;
  color:var(--body);
  margin:-4px 0 0;
}

/* ── COLUMN TEMPLATES ──────────────────────────────────────────────────
   The only thing this sheet asserts about .bf-list-row: how many columns it
   has HERE and how wide they are. Everything else about the row — the
   hairline, the hover wash, the whole-row click target — is the primitive's.

   CATEGORY ROW: marker | name + description | threads | posts | latest.
   The two numeric columns are fixed and narrow so the eye can compare down
   the column; "latest" gets a hard ceiling so a long thread title cannot
   push the numbers around. */
.bfl-cats .bf-list-row,
.bfl-cats .bf-list-head{
  display:grid;
  grid-template-columns:10px minmax(0,1fr) 68px 68px minmax(0, 300px);
  align-items:center;
  gap:14px;
}
/* THREAD ROW: avatar | title + meta | replies | activity. */
.bfl-threads .bf-list-row,
.bfl-threads .bf-list-head{
  display:grid;
  grid-template-columns:26px minmax(0,1fr) 68px 84px;
  align-items:center;
  gap:14px;
}
/* Column labels sit over the numeric columns, so they align the same way the
   values do. */
.bfl-cats-head > :nth-child(3),
.bfl-cats-head > :nth-child(4),
.bfl-threads-head > :nth-child(3),
.bfl-threads-head > :nth-child(4){ text-align:right; }

/* The row's main cell is a stack; the primitive supplies its type, this only
   makes it a column that can shrink. */
.bfl-cats .bf-list-row__main,
.bfl-threads .bf-list-row__main{
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:0;
}
/* Two lines of description maximum. A category blurb is orientation, not
   copy — a third line starts pushing rows apart and the list stops being a
   list. */
.bfl-cat-desc{
  display:-webkit-box;
  -webkit-line-clamp:2;
  line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
}

/* Title + its markers on one line, markers never wrapping mid-word. */
.bfl-title-line{
  display:flex;
  align-items:center;
  flex-wrap:wrap;
  gap:8px;
  min-width:0;
}
.bfl-title-line .bf-list-row__title{ min-width:0; overflow-wrap:anywhere; }

/* The unit under each number ("threads", "replies"). Mono micro-caps, so the
   figure stays the loud part — a bare number in a listing is exactly the
   insider shorthand a stranger has to decode.

   The INTENT above was always right and the RENDER was the exact opposite:
   forum.css's `.bf-list-row__stat > span:first-child` (0,2,1) out-specified
   this rule (0,1,0) and handed the label the number's 14px/600/.80 ink while
   the figure itself sat at 12.5px/400. forum.css now restates that selector
   the right way round at the bottom of its own file; this rule agrees with
   it instead of losing to it. */
.bfl-stat-label{
  display:block;
  font-family:var(--f-mono);
  font-size:9.5px;
  font-weight:500;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--text-ghost);
  line-height:1.3;
}

/* Last-activity column. Mono + tabular so the times form a readable column
   rather than a ragged edge. "8h ago" is half of what a forum listing is
   FOR — it is the proof that the place is alive — so it reads at the meta
   tier, not below it. */
.bfl-when{
  font-family:var(--f-mono);
  font-size:11.5px;
  letter-spacing:.03em;
  color:var(--body);
  text-align:right;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}

/* ── CATEGORY MARKER ───────────────────────────────────────────────────
   A 10px stripe in the category's own deterministic hue: the cheapest thing
   that makes six rows distinguishable at a glance without six icons, six
   illustrations, or the six loud cards this list replaced. --av-h is set on
   the element by the server. */
/* Taller and a shade more saturated. This stripe is the only colour in the
   category list and it was doing the work of six illustrations at 26px of
   4px-wide, half-desaturated hue — easy to miss entirely. */
.bfl-marker{
  width:4px;
  height:34px;
  border-radius:var(--radius-pill);
  background:hsl(var(--av-h, 190) 48% 40%);
  justify-self:center;
  flex:none;
}

/* ── LATEST-ACTIVITY COLUMN ────────────────────────────────────────────
   Avatar + thread link + who/when, stacked tight on the right of a category
   row. z-index/position keep this link clickable above the primitive's
   whole-row target — the row routes into the category, this one link routes
   into the thread. */
.bfl-cats .bf-list-row__latest{
  display:flex;
  align-items:center;
  gap:9px;
  min-width:0;
}
.bfl-latest-text{
  display:flex;
  flex-direction:column;
  gap:1px;
  min-width:0;
}
.bfl-latest-link{
  position:relative;
  z-index:1;
  font-family:var(--f-text);
  font-size:13.5px;
  font-weight:600;
  line-height:1.35;
  color:var(--ink-soft);
  text-decoration:none;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  transition:color var(--dur-base) var(--ease-out);
}
.bfl-latest-link:hover{ color:var(--teal); text-decoration:underline; text-underline-offset:3px; }

/* ── THE EMPTY ROOM ────────────────────────────────────────────────────
   Five rooms all saying "No threads yet" in disabled grey read as a forum
   that failed, not one that is new. Same words, same link, given the warm
   ground and the live invitation they should always have had: the sentence
   is clay-ink (the store's own clay, walked down to 6.29:1 on white so it
   can legally carry text) and the link is a real teal call to action.
   The row behind it picks up --warm-tint in forum.css. */
.bfl-latest-empty{
  position:relative;
  z-index:1;
  font-size:13.5px;
  line-height:1.4;
  color:var(--clay-ink);
  white-space:normal;
}
/* nowrap on the LINK only: the sentence may wrap after the dash, but
   "start the first one" breaking across two lines mid-phrase turns the one
   call to action in an empty room into visual debris. */
.bfl-latest-empty .bfl-latest-link{
  display:inline;
  overflow:visible;
  white-space:nowrap;
  color:var(--teal);
  font-weight:700;
  text-decoration:underline;
  text-underline-offset:3px;
  text-decoration-thickness:1.5px;
}
.bfl-latest-empty .bfl-latest-link:hover{ color:var(--accent-press); }

/* A member's own held/removed thread, marked for that member only. Clay, not
   red: it is a queue state, not an error. */
.bfl-badge-state{ color:var(--clay); border-color:var(--clay); }

/* ── THE RULES PANEL ───────────────────────────────────────────────────
   Kept, demoted. It used to sit half-width beside a cramped thread list,
   taking the same visual weight as the forum's actual content. It is now a
   quiet full-width band at the foot of the page, where posting rules belong:
   findable when you go looking, not competing with the threads. */
/* Warm ground rather than a bare rule: this band is the first thing a
   first-time poster reads before they type, and a set of house rules on the
   naked canvas reads as fine print. On the store's own paper it reads as a
   welcome note. */
.bfl-rules{
  border:1px solid var(--warm-rule);
  border-radius:var(--radius-sm);
  background:var(--warm-band);
  padding:16px 18px;
  display:flex;
  flex-direction:column;
  gap:8px;
  align-items:flex-start;
}
.bfl-rules-title{
  font-family:var(--f-mono);
  font-size:11px;
  font-weight:600;
  letter-spacing:.15em;
  text-transform:uppercase;
  color:var(--teal);
  margin:0;
}
.bfl-rules-list{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(240px, 1fr));
  gap:4px 24px;
  margin:0;
  padding:0;
  list-style:none;
}
.bfl-rules-list li{
  font-family:var(--f-text);
  font-size:14px;
  line-height:1.55;
  color:var(--body);
  padding-left:15px;
  position:relative;
}
.bfl-rules-list li::before{
  content:'';
  position:absolute;
  left:0;
  top:.62em;
  width:4px;
  height:4px;
  border-radius:50%;
  background:var(--teal);
}

/* ── RESPONSIVE ────────────────────────────────────────────────────────
   Below 900px the "latest activity" column is the first to go: on a phone a
   truncated thread title in a 120px gutter is noise, and the row still says
   name, description and both counts. */
@media (max-width:900px){
  .bfl-cats .bf-list-row,
  .bfl-cats .bf-list-head{
    grid-template-columns:10px minmax(0,1fr) 62px 62px;
  }
  .bfl-cats .bf-list-row__latest,
  .bfl-cats-head > :nth-child(5){ display:none; }
}

/* Below 620px both lists drop to three columns. The category row sheds its
   "posts" total (threads is the number that routes a reader, and it keeps its
   label so the survivor is never a bare figure). The thread row keeps its
   last-activity time — that is half of what a forum listing is FOR — by
   wrapping it onto a second grid row under the title instead of hiding it.

   Child indexes, not :last-of-type: every cell in these rows is a <span>, so
   a type selector would match whichever span happens to come last rather than
   the column meant. */
@media (max-width:620px){
  .bfl-cats .bf-list-row,
  .bfl-cats .bf-list-head{
    grid-template-columns:10px minmax(0,1fr) 58px;
    gap:10px;
  }
  .bfl-cats .bf-list-row > :nth-child(4),
  .bfl-cats-head > :nth-child(4){ display:none; }

  .bfl-threads .bf-list-row,
  .bfl-threads .bf-list-head{
    grid-template-columns:26px minmax(0,1fr) 58px;
    gap:2px 10px;
  }
  .bfl-threads .bf-list-row > .bfl-when{
    grid-column:2 / 3;
    text-align:left;
  }
  .bfl-threads-head > :nth-child(4){ display:none; }

  .bfl-cat-head{ flex-direction:column; align-items:flex-start; }
  .bfl-block-head{ align-items:flex-start; flex-direction:column; gap:8px; }
}
