/* ════════════════════════════════════════════════════════════════════
   PROJECT 40 — OPERATOR CONSOLE
   ────────────────────────────────────────────────────────────────────
   A dark, terminal-influenced news intelligence dashboard.
   Hanken Grotesk for prose, JetBrains Mono for data.
   Single accent (electric lime). Six calibrated tier hues. No serifs,
   no paper, no ornament. Trust earned through precision.
   ════════════════════════════════════════════════════════════════════ */

/* ── Self-hosted fonts ─────────────────────────────────────────────
   Both families are variable woff2 — single file per family covers
   the full weight range. Saves the DNS+TLS round-trip to
   fonts.googleapis.com on every cold visit, which the audit flagged
   as the single biggest CWV win available pre-launch. font-display:
   swap means text renders immediately with the system fallback and
   re-paints when the woff2 lands; no FOIT.
   ──────────────────────────────────────────────────────────────── */
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/static/fonts/hanken-grotesk.woff2") format("woff2-variations"),
       url("/static/fonts/hanken-grotesk.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/static/fonts/jetbrains-mono.woff2") format("woff2-variations"),
       url("/static/fonts/jetbrains-mono.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

:root {
  --sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Canvas — warm-graphite, never pure black */
  --bg:        #0A0A0B;
  --bg-1:      #111114;        /* surfaces */
  --bg-2:      #18181D;        /* hover / raised */
  --bg-3:      #1F1F26;        /* input / divider chunks */
  --line:      #25252D;        /* default 1px line */
  --line-2:    #2F2F39;        /* emphasis line */

  /* Text ladder */
  --fg:        #ECECEE;
  --fg-2:      #BCBCC2;
  --fg-3:      #8B8B92;
  --fg-4:      #5A5A62;
  --fg-5:      #3F3F46;

  /* Single accent — electric lime, the "signal" colour */
  --accent:    #B8FF3C;
  --accent-2:  #94D424;
  --accent-bg: rgba(184, 255, 60, 0.10);

  /* Tier ladder — calibrated for dark canvas, each its own muted hue */
  --t-frontier:    #B8FF3C;   /* lime — top tier */
  --t-significant: #6CB6FF;   /* sky blue */
  --t-research:    #B98AFF;   /* lavender */
  --t-tool:        #FFA94D;   /* amber */
  --t-commentary:  #FF7A8E;   /* warm rose */
  --t-meme:        #6E6E76;   /* graphite — deprioritized */

  /* Tier ghost backgrounds — used very sparingly */
  --t-frontier-bg:    rgba(184, 255, 60, 0.07);
  --t-significant-bg: rgba(108, 182, 255, 0.07);
  --t-research-bg:    rgba(185, 138, 255, 0.07);
  --t-tool-bg:        rgba(255, 169, 77, 0.07);
  --t-commentary-bg:  rgba(255, 122, 142, 0.07);
  --t-meme-bg:        rgba(110, 110, 118, 0.07);

  --r-sm: 3px;
  --r-md: 5px;
  --r-lg: 8px;

  font-size: 15px;
  line-height: 1.5;
  font-family: var(--sans);
  font-feature-settings: "ss01", "ss02", "kern", "calt";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--fg);
  background: var(--bg);
  text-rendering: optimizeLegibility;
}

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Sticky footer: body is a flex column tall enough to fill the
   viewport, main.shell flexes to fill any remaining space, and the
   footer naturally lands at the bottom. Tall pages push the footer
   below the fold as before. */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.shell { flex: 1 0 auto; }
.endbar { flex-shrink: 0; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--fg); }

::selection { background: var(--accent); color: var(--bg); }

/* ── Background dot grid (subtle, fixed) ─────────────────────────── */

.bg-grid {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image:
    radial-gradient(circle at 1px 1px, rgba(255,255,255,0.025) 1px, transparent 1px);
  background-size: 28px 28px;
  background-position: 0 0;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 30%, transparent 80%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 30%, transparent 80%);
  pointer-events: none;
}

/* ── Top bar ─────────────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(10, 10, 11, 0.85);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border-bottom: 1px solid var(--line);
}
.topbar-inner {
  max-width: 1080px;
  margin: 0 auto;
  min-height: 56px;
  padding: 0 24px;
  /* 3-column grid: brand | tabs | right-rail.
     Right rail is a flex row holding the LIVE+time stack and the
     avatar side-by-side, so neither overlaps the other on scroll.
     The two side columns are 1fr to keep the tabs pinned center
     regardless of right-rail width changes (signed-in disc vs
     guest pill). */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
}
.topbar-inner > .brand     { grid-column: 1; justify-self: start; }
.topbar-inner > .tabs      { grid-column: 2; justify-self: center; }
.topbar-inner > .topbar-right { grid-column: 3; justify-self: end; }

.topbar-right {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--fg);
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
}
.brand:hover { color: var(--fg); }
.brand-mark {
  display: inline-flex;
  width: 22px;
  height: 22px;
  color: var(--accent);
  flex: 0 0 22px;
}
.brand-mark svg { width: 100%; height: 100%; display: block; }
.brand-name {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  color: var(--fg);
}
.brand-name-accent { color: var(--accent); }
.brand-sep { color: var(--fg-4); }
.brand-section {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.86rem;
  color: var(--fg-2);
  /* Fixed slot so tab-strip doesn't shift horizontally as the section
     label width changes ("Brief" vs "Whispers"). Width fits the
     longest label + a couple px slack. */
  min-width: 72px;
  display: inline-block;
}

.status {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--fg-3);
  /* Stacked: LIVE indicator on top, wall-clock below. The right-rail
     flex aligns the stack's baseline against the avatar pill; column
     direction keeps both lines flush right. */
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  letter-spacing: 0.02em;
  line-height: 1;
}
.status-live {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.status-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 70%, 100% { box-shadow: 0 0 0 0 rgba(184, 255, 60, 0); }
  35% { box-shadow: 0 0 0 6px rgba(184, 255, 60, 0.18); }
}
.status-label {
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.08em;
}
.status-sep { color: var(--fg-5); }
.status-stat { color: var(--fg-3); }
.status-num { color: var(--fg-2); font-weight: 500; }
.status-time {
  color: var(--fg-3);
  font-size: 0.62rem;
}

/* ── Tabs (Brief / Pulse) ────────────────────────────────────────── */

.tabs {
  display: inline-flex;
  align-items: center;
  gap: 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
}

/* Mobile-width sticky-bottom variant (rendered as a sibling of
   .topbar in base.html). Hidden by default; the @media block at
   the bottom of this file flips it to display:flex on narrow
   viewports. Position is anchored on .tab-bottom .tab below. */
.tabs-bottom { display: none; }
.tabs-bottom .tab { position: relative; }
.tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 56px;          /* match topbar-inner */
  padding: 0 0.95rem;
  /* Per-tab min-width so the tab strip doesn't reflow when label
     widths differ ("Brief" vs "Whispers"). Matches mobile parity. */
  min-width: 88px;
  color: var(--fg-3);
  text-transform: uppercase;
  text-decoration: none;
  transition: color 80ms ease;
}
.tab:hover { color: var(--fg-2); }
.tab.is-active {
  color: var(--fg);
}
.tab.is-active::after {
  content: "";
  position: absolute;
  left: 0.95rem;
  right: 0.95rem;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
}

/* ── Shell ───────────────────────────────────────────────────────── */

.shell {
  max-width: 1080px;
  margin: 0 auto;
  padding: 2rem 24px 4rem;
}

/* ── Hero / page intro ───────────────────────────────────────────── */

.hero { padding: 1rem 0 2rem; }

.hero-row {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  flex-wrap: wrap;
  margin-bottom: 0.65rem;
}
.hero-title {
  font-family: var(--sans);
  font-size: clamp(2rem, 5vw, 2.6rem);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1;
  margin: 0;
  color: var(--fg);
}
.hero-sep {
  height: 22px;
  width: 1px;
  background: var(--line-2);
  margin: 0 0.25rem 0 0.15rem;
  align-self: center;
}
.hero-window {
  font-family: var(--mono);
  font-size: 0.85rem;
  color: var(--fg-3);
  letter-spacing: 0.02em;
}
.hero-stats {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.hero-count {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.hero-sources {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-3);
  letter-spacing: 0.02em;
}

.hero-deck {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--fg-3);
  max-width: 60ch;
  margin: 0;
}

/* ── Filter strip ────────────────────────────────────────────────── */

.filters {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 0.85rem 0 0.95rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin-bottom: 1.25rem;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.012), transparent);
}

.filter-row {
  display: grid;
  grid-template-columns: 56px 1fr;
  align-items: baseline;
  gap: 0.85rem;
}
.filter-key {
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--fg-4);
  letter-spacing: 0.14em;
  padding-top: 0.25rem;
}
.filter-set {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.42rem;
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--fg-2);
  background: transparent;
  border: 1px solid var(--line);
  padding: 0.3rem 0.7rem;
  border-radius: var(--r-md);
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.pill:hover {
  color: var(--fg);
  border-color: var(--line-2);
  background: var(--bg-1);
}
.pill.is-on {
  color: var(--bg);
  background: var(--fg);
  border-color: var(--fg);
}

.pill-tier .pill-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--fg-4);
}
.pill-tier.tier-frontier_release .pill-dot { background: var(--t-frontier); }
.pill-tier.tier-significant      .pill-dot { background: var(--t-significant); }
.pill-tier.tier-research         .pill-dot { background: var(--t-research); }
.pill-tier.tier-tool             .pill-dot { background: var(--t-tool); }
.pill-tier.tier-commentary       .pill-dot { background: var(--t-commentary); }
.pill-tier.tier-meme             .pill-dot { background: var(--t-meme); }

.pill-tier.is-on.tier-frontier_release { background: var(--t-frontier); border-color: var(--t-frontier); color: var(--bg); }
.pill-tier.is-on.tier-significant      { background: var(--t-significant); border-color: var(--t-significant); color: var(--bg); }
.pill-tier.is-on.tier-research         { background: var(--t-research); border-color: var(--t-research); color: var(--bg); }
.pill-tier.is-on.tier-tool             { background: var(--t-tool); border-color: var(--t-tool); color: var(--bg); }
.pill-tier.is-on.tier-commentary       { background: var(--t-commentary); border-color: var(--t-commentary); color: var(--bg); }
.pill-tier.is-on.tier-meme             { background: var(--t-meme); border-color: var(--t-meme); color: var(--fg); }
.pill-tier.is-on .pill-dot { background: rgba(0,0,0,0.45); }

/* ── Empty state ─────────────────────────────────────────────────── */

.empty {
  margin: 4rem auto;
  text-align: center;
  max-width: 36rem;
}
.empty-key {
  font-family: var(--mono);
  font-size: 0.74rem;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.18em;
  margin-bottom: 0.5rem;
}
.empty-body {
  font-size: 0.95rem;
  color: var(--fg-3);
  margin: 0;
}

/* ── Feed ────────────────────────────────────────────────────────── */

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

@keyframes row-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.row {
  display: grid;
  grid-template-columns: 4px 76px minmax(0, 1fr);
  gap: 0;
  /* Card-shape padding + lighter bg + soft border so each card reads
     as its own unit at scan distance. Matches mobile parity. */
  padding: 0;
  margin-bottom: 0.7rem;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 12px;
  position: relative;
  cursor: pointer;            /* whole-card tap → /cluster/<id> */
  opacity: 0;
  animation: row-in 0.28s ease both;
  animation-delay: var(--stagger, 0ms);
  transition: background 0.12s ease, border-color 0.12s ease;
}

.row:hover {
  background:
    linear-gradient(90deg, var(--tier-bg, rgba(255,255,255,0.012)) 0%, var(--bg-1) 60%);
  border-color: rgba(140, 140, 145, 0.28);
}
.row.tier-frontier_release    { --tier-bg: var(--t-frontier-bg); }
.row.tier-significant         { --tier-bg: var(--t-significant-bg); }
.row.tier-research            { --tier-bg: var(--t-research-bg); }
.row.tier-tool                { --tier-bg: var(--t-tool-bg); }
.row.tier-commentary          { --tier-bg: var(--t-commentary-bg); }
.row.tier-meme                { --tier-bg: var(--t-meme-bg); }

/* Tier rail — left edge, 4px wide, visible on hover */
.row-rail {
  background: var(--rail-color, var(--line));
  opacity: 0;
  transition: opacity .12s ease;
  border-radius: 0 2px 2px 0;
}
.row.tier-frontier_release .row-rail { background: var(--t-frontier); }
.row.tier-significant      .row-rail { background: var(--t-significant); }
.row.tier-research         .row-rail { background: var(--t-research); }
.row.tier-tool             .row-rail { background: var(--t-tool); }
.row.tier-commentary       .row-rail { background: var(--t-commentary); }
.row.tier-meme             .row-rail { background: var(--t-meme); }
.row:hover .row-rail { opacity: 1; }

/* ── Score meter ─────────────────────────────────────────────────── */

.row-score {
  padding: 14px 8px 12px 12px;
  align-self: start;
  position: sticky;
  top: 70px;
  display: flex;
  flex-direction: column;
  align-items: center;
  border-right: 1px solid rgba(140, 140, 145, 0.10);
}

/* When the score chip is a button (clickable for "why this score?"),
   neutralize the browser's default button chrome. */
.row-score-btn {
  background: transparent;
  border: 0;
  border-right: 1px solid rgba(140, 140, 145, 0.10);
  cursor: pointer;
  font: inherit;
  color: inherit;
  border-radius: 0;
  transition: background 0.12s ease;
}
.row-score-btn:hover { background: rgba(255, 255, 255, 0.025); }
.row-score-btn:focus-visible {
  outline: 1px dashed var(--accent);
  outline-offset: 2px;
}

/* Vertically stacked digits — mirrors mobile's ScoreChip "XX/_/"
   shape. Each digit on its own line, tier-colored, in JetBrains Mono.
   The horizontal rule below is the "/" delimiter visualized. */
.score-digits {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
}
.score-digit {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 1.35rem;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--fg-3);
  font-variant-numeric: tabular-nums;
}
.score-digit + .score-digit { margin-top: 1px; }
.row.tier-frontier_release .score-digit { color: var(--t-frontier); }
.row.tier-significant      .score-digit { color: var(--t-significant); }
.row.tier-research         .score-digit { color: var(--t-research); }
.row.tier-tool             .score-digit { color: var(--t-tool); }
.row.tier-commentary       .score-digit { color: var(--t-commentary); }
.row.tier-meme             .score-digit { color: var(--fg-3); }
.score-pending { color: var(--fg-4); }
.score-rule {
  width: 16px;
  height: 2px;
  margin-top: 8px;
  border-radius: 1px;
  background: var(--fg-3);
  opacity: 0.55;
}
.row.tier-frontier_release .score-rule { background: var(--t-frontier); }
.row.tier-significant      .score-rule { background: var(--t-significant); }
.row.tier-research         .score-rule { background: var(--t-research); }
.row.tier-tool             .score-rule { background: var(--t-tool); }
.row.tier-commentary       .score-rule { background: var(--t-commentary); }
.row.tier-meme             .score-rule { background: var(--fg-3); }
.score-trend {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent);
  text-shadow: 0 0 8px rgba(184, 255, 60, 0.45);
  animation: trend-pulse 1.6s ease-in-out infinite;
}
.score-raw {
  margin-top: 6px;
  font-family: var(--mono);
  font-size: 0.55rem;
  color: var(--fg-5);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.meter-num {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 2rem;
  line-height: 0.95;
  color: var(--fg);
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}
.meter-pending { color: var(--fg-4); }

.trend-mark {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--accent);
  margin-left: 0.15em;
  line-height: 1;
  vertical-align: super;
  letter-spacing: 0;
  text-shadow: 0 0 8px rgba(184, 255, 60, 0.45);
  animation: trend-pulse 1.6s ease-in-out infinite;
}
@keyframes trend-pulse {
  0%, 100% { opacity: 0.78; transform: translateY(0); }
  50%      { opacity: 1.0;  transform: translateY(-1px); }
}

.meter-track {
  height: 3px;
  background: var(--bg-3);
  border-radius: 2px;
  margin: 0.6rem 0 0.5rem;
  overflow: hidden;
  position: relative;
}
@keyframes meter-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
.meter-fill {
  height: 100%;
  width: var(--w, 0%);
  background: var(--fg-3);
  border-radius: 2px;
  transform-origin: left;
  animation: meter-fill 0.6s cubic-bezier(0.2, 0.7, 0.25, 1) both;
  animation-delay: calc(var(--stagger, 0ms) + 80ms);
}
.row.tier-frontier_release .meter-fill { background: var(--t-frontier); box-shadow: 0 0 12px rgba(184, 255, 60, 0.35); }
.row.tier-significant      .meter-fill { background: var(--t-significant); }
.row.tier-research         .meter-fill { background: var(--t-research); }
.row.tier-tool             .meter-fill { background: var(--t-tool); }
.row.tier-commentary       .meter-fill { background: var(--t-commentary); }
.row.tier-meme             .meter-fill { background: var(--t-meme); }

.meter-tier {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row.tier-frontier_release .meter-tier { color: var(--t-frontier); }
.row.tier-significant      .meter-tier { color: var(--t-significant); }
.row.tier-research         .meter-tier { color: var(--t-research); }
.row.tier-tool             .meter-tier { color: var(--t-tool); }
.row.tier-commentary       .meter-tier { color: var(--t-commentary); }
.row.tier-meme             .meter-tier { color: var(--fg-3); }

/* Pre-clamp gravity score — shown only on Brief, only as a small
   secondary number under the tier label. Surfaces the differentiation
   among saturated 100s so a reader can tell which of the tied items
   is the actual lead story. */
.meter-raw {
  font-family: var(--mono);
  font-size: 0.6rem;
  color: var(--fg-5);
  letter-spacing: 0.04em;
  margin-top: 0.25rem;
}

/* ── Row body ────────────────────────────────────────────────────── */

.row-body {
  min-width: 0;
  padding: 14px 16px 16px 14px;
  display: flex;
  flex-direction: column;
}

.row-meta {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--fg-3);
  margin-bottom: 0.5rem;
  letter-spacing: 0.01em;
}
.meta-source {
  color: var(--fg-2);
  font-weight: 500;
}
/* Bucket label — bare text in tier color. Matches mobile parity:
   no border, no background, just typography. */
.meta-bucket {
  font-family: var(--mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--fg-3);
  white-space: nowrap;
}
.row.tier-frontier_release .meta-bucket { color: var(--t-frontier); }
.row.tier-significant      .meta-bucket { color: var(--t-significant); }
.row.tier-research         .meta-bucket { color: var(--t-research); }
.row.tier-tool             .meta-bucket { color: var(--t-tool); }
.row.tier-commentary       .meta-bucket { color: var(--t-commentary); }
.row.tier-meme             .meta-bucket { color: var(--fg-3); }

/* Source-authority indicator — three dots inline with the source
   name. Filled count = level (3=high, 2=mid, 1=low). Mirrors the
   mobile AuthorityDots glyph. */
.meta-source-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.authority-dots {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.auth-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(140, 140, 145, 0.25);
}
.authority-1 .auth-dot:nth-child(-n+1) { background: var(--fg-2); }
.authority-2 .auth-dot:nth-child(-n+2) { background: var(--fg-2); }
.authority-3 .auth-dot:nth-child(-n+3) { background: var(--fg-2); }
.meta-time { color: var(--fg-3); font-variant-numeric: tabular-nums; }
.meta-coverage {
  color: var(--accent);
  font-weight: 500;
}
.meta-coverage:hover { color: var(--fg); }
.meta-sep { color: var(--fg-5); user-select: none; }

/* Per-row bookmark star — sits at the right edge of the meta line.
 * Always visible (the lighter outline glyph reads as "save for later"
 * even when off); switches to filled lime when the cluster is in the
 * user's bookmarks. Click is delegated to account-actions.js, which
 * handles the toggle for paid users and the 402 → /pricing redirect
 * for free / anonymous users. */
.row-bookmark {
  margin-left: auto;
  width: 26px; height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--fg-4);
  cursor: pointer;
  padding: 0;
  transition: color 0.12s ease, background-color 0.12s ease, border-color 0.12s ease;
}
.row-bookmark svg { width: 16px; height: 16px; display: block; }
.row-bookmark:hover { color: var(--fg-2); background: rgba(255, 255, 255, 0.04); }
.row-bookmark.is-on {
  color: var(--accent);
  border-color: rgba(184, 255, 60, 0.30);
  background: rgba(184, 255, 60, 0.08);
}
.row-bookmark.is-on:hover { background: rgba(184, 255, 60, 0.14); }

/* Pin / boost / kill curate buttons (.act, .act-on, .act-kill,
   .row-actions container) used to live here. They moved to the
   `cluadm` CLI (scripts/cluster_admin.py); the visual rail +
   gradient on .row.pin-pin / .row.pin-boost below stay since
   they signal operator-set state to the operator on the feed. */

.row-title {
  font-family: var(--sans);
  font-size: 1.18rem;
  font-weight: 600;
  line-height: 1.28;
  letter-spacing: -0.012em;
  margin: 0 0 0.6rem;
  color: var(--fg);
}
.row-title a { color: inherit; }
.row-title a:hover {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(184, 255, 60, 0.3);
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

.row-content {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  margin-bottom: 0.6rem;
}
.row.has-thumb .row-content,
.row .row-content:has(.row-thumb) {
  grid-template-columns: minmax(0, 1fr) 276px;
}

.row-summary, .row-excerpt {
  margin: 0;
  font-size: 0.93rem;
  line-height: 1.55;
  color: var(--fg-2);
  max-width: 64ch;
}
.row-excerpt { color: var(--fg-3); font-style: italic; }

.ai-mark {
  display: inline-block;
  margin-left: 0.35rem;
  vertical-align: 0.15em;
  font-family: var(--mono);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--fg-4);
  background: var(--bg-1);
  padding: 0.14rem 0.42rem;
  border-radius: 2px;
  border: 1px solid var(--line);
  cursor: help;
  transition: color .12s ease, border-color .12s ease;
}
.ai-mark:hover {
  color: var(--accent);
  border-color: var(--line-2);
}

/* ── AI-industry impact blurb ──────────────────────────────────────────
   Sits below the summary on Brief / Pulse / Whispers cards. Same column
   width as the summary so the eye reads them as a pair, but visually
   demoted: smaller, accent-tinted left border + key, monospace key.
   The IMPACT key marker mirrors the operator-console aesthetic
   (RANK_REASON, COVERAGE, etc. — terse all-caps mono labels). */
.row-impact {
  /* Match mobile IMPACT block: 12px padding, accent left rule, breathing
     room above so it reads as its own beat, not a continuation of the
     summary. */
  margin: 0.7rem 0 0.2rem;
  padding: 0.5rem 0 0.5rem 0.75rem;
  border-left: 2px solid var(--accent);
  background: rgba(184, 255, 60, 0.04);
  border-radius: 0 4px 4px 0;
  font-size: 0.83rem;
  line-height: 1.55;
  color: var(--fg-2);
  max-width: 64ch;
}
.row-impact-key {
  display: inline-block;
  margin-right: 0.55rem;
  font-family: var(--mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
  vertical-align: 1px;
}
/* Slightly more contrast on hover/focus so the user perceives it as
   meaningful but doesn't shout when scrolling past a long page. */
.row:hover .row-impact { color: var(--fg); border-left-color: var(--accent); }

/* Read-state dim — same treatment as .row-summary so a "read" card
   visually settles back. */
.row.is-read .row-impact { color: var(--fg-4); border-left-color: var(--fg-5); }
.row.is-read .row-impact-key { color: var(--fg-4); }
.row.is-read:hover .row-impact { color: var(--fg-2); border-left-color: rgba(184, 255, 60, 0.32); }
.row.is-read:hover .row-impact-key { color: var(--accent); }

/* Detail page variant — slightly larger to match the bigger detail
   summary, sits inside the article body. */
.detail-impact {
  margin: 0.65rem 0 0;
  font-size: 0.95rem;
  max-width: 72ch;
}

.row-thumb {
  display: block;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--bg-1);
  aspect-ratio: 16 / 10;
  border: 1px solid var(--line);
  position: relative;
  align-self: start;
}
.row-thumb::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(0,0,0,0.35));
  pointer-events: none;
}
.row-thumb img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform 0.5s ease, filter 0.3s ease;
  filter: saturate(0.9) contrast(1.05);
}
.row-thumb:hover img {
  transform: scale(1.03);
  filter: saturate(1.1) contrast(1.05);
}

/* ── Topic tags ──────────────────────────────────────────────────── */

.row-topics {
  list-style: none;
  margin: 0.2rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.topic {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--fg-3);
  padding: 0.18rem 0.45rem;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: var(--bg-1);
  transition: all .1s ease;
  letter-spacing: 0.01em;
}
.topic-mark { color: var(--fg-5); margin-right: 0.15rem; }
.topic:hover {
  color: var(--fg);
  border-color: var(--line-2);
  background: var(--bg-2);
}
.topic:hover .topic-mark { color: var(--accent); }

/* TEMP — Lever D entity chips. Visible on Brief only. Differentiated
   from .topic by being non-interactive + tinted with the lavender
   tier-research accent so they read as "metadata signal" not "filter
   link". Remove this block + the markup in clusters.html when the
   debug view is no longer needed. */
.row-entities {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}
.entity-chip {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 500;
  color: var(--t-research);
  padding: 0.15rem 0.45rem;
  border: 1px solid rgba(185, 138, 255, 0.35);
  border-radius: var(--r-sm);
  background: rgba(185, 138, 255, 0.12);
  letter-spacing: 0.01em;
  white-space: nowrap;
  text-decoration: none;
  transition: background 80ms, border-color 80ms;
}
a.entity-chip:hover {
  background: rgba(185, 138, 255, 0.22);
  border-color: rgba(185, 138, 255, 0.55);
}

/* ── Pin / Boost / Kill states ───────────────────────────────────── */

.row.pin-pin {
  background:
    linear-gradient(90deg, rgba(184, 255, 60, 0.04) 0%, transparent 60%);
}
.row.pin-pin .row-rail { opacity: 1; background: var(--accent); }
.row.pin-boost { background: linear-gradient(90deg, rgba(184, 255, 60, 0.02) 0%, transparent 60%); }
.row.pin-kill { display: none; }

/* ── Read state (localStorage-tracked) ───────────────────────────── */

.row.is-read .meter-num,
.row.is-read .row-title,
.row.is-read .row-summary,
.row.is-read .row-excerpt,
.row.is-read .meta-source {
  opacity: 0.45;
  transition: opacity .15s ease;
}
.row.is-read:hover .meter-num,
.row.is-read:hover .row-title,
.row.is-read:hover .row-summary,
.row.is-read:hover .row-excerpt,
.row.is-read:hover .meta-source {
  opacity: 0.85;
}
.row.is-read .row-thumb img {
  filter: saturate(0.4) contrast(0.95) brightness(0.85);
}
.row.is-read .row-meta::after {
  content: 'READ';
  font-family: var(--mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--accent);
  background: var(--accent-bg);
  padding: 0.08rem 0.4rem;
  border-radius: 2px;
  margin-left: 0.3rem;
  order: 99;
}

/* ── Cluster detail ──────────────────────────────────────────────── */

.crumb {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  margin: 0 0 1.5rem;
}
.crumb-link {
  color: var(--fg-3);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  letter-spacing: 0.02em;
  transition: color .12s ease;
}
.crumb-link:hover { color: var(--fg); }
.crumb-arrow { color: var(--fg-4); transition: transform .12s ease; }
.crumb-link:hover .crumb-arrow { transform: translateX(-2px); color: var(--accent); }
.crumb-sep { color: var(--fg-5); }
.crumb-id {
  color: var(--accent);
  letter-spacing: 0.04em;
  font-weight: 500;
}

.detail { margin-bottom: 4rem; }

.detail-head { margin-bottom: 1.5rem; }

.detail-meta {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--fg-3);
  margin-bottom: 1.4rem;
  letter-spacing: 0.01em;
}
.detail-tier {
  font-weight: 700;
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
.detail.tier-frontier_release .detail-tier { color: var(--t-frontier); }
.detail.tier-significant      .detail-tier { color: var(--t-significant); }
.detail.tier-research         .detail-tier { color: var(--t-research); }
.detail.tier-tool             .detail-tier { color: var(--t-tool); }
.detail.tier-commentary       .detail-tier { color: var(--t-commentary); }
.detail.tier-meme             .detail-tier { color: var(--fg-2); }

.detail-grid {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
}

.detail-score {
  padding-top: 0.4rem;
}
.detail-score .meter-num {
  font-size: 2.6rem;
  letter-spacing: -0.05em;
}
.detail-score .meter-track {
  height: 4px;
}
.detail.tier-frontier_release .meter-fill { background: var(--t-frontier); box-shadow: 0 0 16px rgba(184, 255, 60, 0.4); }
.detail.tier-significant      .meter-fill { background: var(--t-significant); }
.detail.tier-research         .meter-fill { background: var(--t-research); }
.detail.tier-tool             .meter-fill { background: var(--t-tool); }
.detail.tier-commentary       .meter-fill { background: var(--t-commentary); }
.detail.tier-meme             .meter-fill { background: var(--t-meme); }

.detail.tier-frontier_release .meter-tier { color: var(--t-frontier); }
.detail.tier-significant      .meter-tier { color: var(--t-significant); }
.detail.tier-research         .meter-tier { color: var(--t-research); }
.detail.tier-tool             .meter-tier { color: var(--t-tool); }
.detail.tier-commentary       .meter-tier { color: var(--t-commentary); }

.detail-title {
  font-family: var(--sans);
  font-size: clamp(1.7rem, 4vw, 2.3rem);
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: 1.12;
  margin: 0;
  color: var(--fg);
}

/* Detail body: two-column grid matching .row-content on feed cards.
   Single-column when no thumb is present. */
.detail-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  margin: 1.5rem 0 0.6rem;
  align-items: start;
}
.detail-body.has-thumb {
  grid-template-columns: minmax(0, 1fr) 276px;
}
.detail-body-text > .detail-summary { margin-top: 0; }

.detail-summary {
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--fg);
  max-width: 64ch;
  margin: 1.5rem 0 1.25rem;
}

.detail-reason {
  font-size: 0.9rem;
  color: var(--fg-3);
  font-style: italic;
  background: var(--bg-1);
  border-left: 2px solid var(--line-2);
  padding: 0.85rem 1rem;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  margin: 1.25rem 0 2rem;
  max-width: 60ch;
}
.detail-reason-key {
  display: block;
  font-style: normal;
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--fg-4);
  margin-bottom: 0.3rem;
}

.detail-section {
  margin-top: 2rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}
.detail-section-title {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 700;
  margin: 0 0 1rem;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.detail-section-key { color: var(--fg-2); }
.detail-section-count { color: var(--accent); }

/* ── Members list ────────────────────────────────────────────────── */

.members {
  list-style: none;
  margin: 0;
  padding: 0;
}
.member {
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--line);
}
.member:last-child { border-bottom: none; }
.member-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-3);
  margin-bottom: 0.45rem;
  letter-spacing: 0.01em;
}
.member-author { font-style: italic; color: var(--fg-3); }
.member-title {
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.32;
  margin: 0 0 0.45rem;
  letter-spacing: -0.01em;
}
/* Member title links — visible as links at rest (subtle underline)
   so the row reads as tappable on web the way it does on mobile,
   where the whole Pressable row signals interactivity via touch
   feedback. White → lime on hover. */
.member-title a {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: rgba(184, 255, 60, 0.30);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 120ms, text-decoration-color 120ms;
}
.member-title a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1.5px;
}
/* External-link glyph after the title so users see "this opens
   somewhere else" without hovering. Pure CSS — no extra DOM. */
.member-title a::after {
  content: " ↗";
  color: var(--fg-4);
  font-weight: 400;
  text-decoration: none;
  display: inline-block;
  transition: color 120ms;
}
.member-title a:hover::after { color: var(--accent); }

/* External-link chip group below each source — mirrors the mobile
   ClusterMemberRow's ExternalLinks block (lime-tinted pills,
   JetBrains Mono micro-text, host + slug snippet). For social-
   sourced clusters where the post quotes an article, this is
   often the only meaningful link on the page. */
.member-external-links {
  margin-top: 0.55rem;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.member-external-links-label {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--fg-2);
}
.member-external-links-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.external-link-chip {
  display: inline-block;
  padding: 4px 9px;
  border-radius: 6px;
  background: rgba(184, 255, 60, 0.10);
  border: 1px solid rgba(184, 255, 60, 0.30);
  color: var(--accent);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.4px;
  text-decoration: none;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background-color 120ms, border-color 120ms;
}
.external-link-chip:hover {
  background: rgba(184, 255, 60, 0.20);
  border-color: rgba(184, 255, 60, 0.55);
}
.member-excerpt {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--fg-3);
  margin: 0;
  max-width: 62ch;
}

/* ── End bar (footer) ────────────────────────────────────────────── */

.endbar {
  border-top: 1px solid var(--line);
  background: rgba(10, 10, 11, 0.6);
}
.endbar-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 1.6rem 24px 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--fg-4);
  letter-spacing: 0.04em;
}
.endbar-toprow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem 1.5rem;
}
.endbar-bottomrow {
  display: flex;
  align-items: baseline;
}
.endbar-key {
  color: var(--fg-3);
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: 0.78rem;
}
.endbar-tag {
  color: var(--fg-4);
  min-width: 0;
}
.endbar-tag .ai-tag {
  display: inline-block;
  margin-left: 0.25rem;
  font-family: var(--mono);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--fg-3);
  border: 1px solid var(--line);
  padding: 0.08rem 0.35rem;
  border-radius: 2px;
  vertical-align: 0.1em;
}
.endbar-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  justify-content: flex-end;
}
.endbar-link {
  color: var(--fg-3);
  text-decoration: none;
  border-bottom: 1px dotted transparent;
  transition: color 0.12s ease, border-bottom-color 0.12s ease;
}
.endbar-link:hover {
  color: var(--fg);
  border-bottom-color: var(--fg-3);
}

/* ── Legal pages (privacy, terms) ────────────────────────────────── */

.legal {
  max-width: 64ch;
  margin: 0 auto;
  padding: 1.5rem 0 3rem;
  color: var(--fg-2);
  line-height: 1.6;
}
.legal h1 {
  font-family: var(--mono);
  font-size: 1.6rem;
  letter-spacing: 0.02em;
  color: var(--fg);
  margin: 0 0 0.5rem;
}
.legal h2 {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin: 2rem 0 0.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.legal h2:first-of-type { border-top: 0; padding-top: 0; }
.legal p, .legal li { color: var(--fg-2); }
.legal em { color: var(--fg-4); font-style: normal; font-family: var(--mono); font-size: 0.78rem; }
.legal ul { padding-left: 1.2rem; }
.legal li { margin: 0.4rem 0; }
.legal strong { color: var(--fg); font-weight: 600; }
.legal a { color: var(--accent); text-decoration: none; border-bottom: 1px solid rgba(184, 255, 60, 0.4); }
.legal a:hover { border-bottom-color: var(--accent); }

/* ── Responsive ──────────────────────────────────────────────────── */

@media (max-width: 760px) {
  .topbar-inner { padding: 0 16px; }
  /* Extra bottom padding leaves room for the fixed bottom-tab bar
     (52px) + the device's home-indicator inset, so the last row of
     content isn't hidden under the bar. */
  .shell {
    padding: 1.5rem 16px calc(3rem + 52px + env(safe-area-inset-bottom, 0px));
  }
  .endbar-inner { padding: 1rem 16px; }

  /* Topbar collapses to brand + status/avatar — the desktop tab
     row inside the topbar is hidden, and the sibling `.tabs-bottom`
     element (rendered outside .topbar in base.html) takes over as
     a sticky-bottom bar. The grid loses its center cell so brand +
     topbar-right take the whole width without the tabs fighting
     for room. Note: position:fixed descendants of .topbar resolve
     against the topbar (because of its backdrop-filter), which is
     why the bottom bar is a sibling, not a child. */
  .topbar-inner {
    grid-template-columns: 1fr auto;
  }
  .topbar-inner > .brand        { grid-column: 1; }
  .topbar-inner > .tabs         { display: none; }
  .topbar-inner > .topbar-right { grid-column: 2; }

  .tabs-bottom {
    display: flex;
    justify-content: space-around;
    gap: 0;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    padding: 6px 4px calc(8px + env(safe-area-inset-bottom, 0px));
    background: rgba(10, 10, 11, 0.92);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border-top: 1px solid var(--line);
    font-family: var(--mono);
  }
  .tabs-bottom .tab {
    flex: 1;
    text-align: center;
    padding: 10px 4px;
    height: auto;        /* override the desktop 56px row-height */
    min-width: 0;        /* override desktop's 88px min */
    font-size: 0.7rem;
    letter-spacing: 0.16em;
    color: var(--fg-3);
    text-transform: uppercase;
    text-decoration: none;
  }
  .tabs-bottom .tab.is-active { color: var(--fg); }
  .tabs-bottom .tab.is-active::after {
    /* Underline indicator at the TOP of the cell (above the label)
       so the bottom bar reads as "you tapped here" without bleeding
       into the home-indicator area. */
    content: "";
    position: absolute;
    top: 0;
    left: 0.95rem;
    right: 0.95rem;
    height: 2px;
    background: var(--accent);
  }
  .tabs-bottom .tab.tab-whispers { color: var(--t-research); }
  .tabs-bottom .tab.tab-whispers.is-active { color: var(--t-research); }

  .brand-section, .brand-sep { display: none; }
  .status-stat:not(.status-time) { display: none; }

  .row {
    grid-template-columns: 3px 64px minmax(0, 1fr);
    padding: 1.1rem 0 1.2rem;
  }
  .row-score {
    padding: 0 10px 0 12px;
    position: static;
  }
  .meter-num { font-size: 1.5rem; }
  .meter-tier { font-size: 0.55rem; letter-spacing: 0.1em; }

  .row-content { grid-template-columns: minmax(0, 1fr) !important; }
  .row-thumb { aspect-ratio: 16 / 9; }

  .row-title { font-size: 1.05rem; }

  .filter-row { grid-template-columns: 1fr; gap: 0.35rem; }
  .filter-key { padding-top: 0; }

  .detail-grid { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
  .detail-body.has-thumb { grid-template-columns: minmax(0, 1fr); }
  .detail-score { display: flex; align-items: baseline; gap: 1rem; }
  .detail-score .meter-num { font-size: 2.2rem; }
  .detail-score .meter-track { flex: 1; max-width: 200px; }
  .detail-score .meter-tier { white-space: nowrap; }
}

/* ── Reduced motion ──────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .row, .meter-fill { animation: none; opacity: 1; transform: none; }
  .status-dot { animation: none; }
  .row-thumb img { transition: none; }
}

/* ── Pulse-specific bits ─────────────────────────────────────────── */

.platform-strip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  color: var(--fg-3);
}
.platform-chip {
  display: inline-block;
  padding: 0.06rem 0.42rem;
  border: 1px solid var(--fg-5);
  border-radius: var(--r-sm);
  text-transform: uppercase;
  color: var(--fg-2);
  background: rgba(255, 255, 255, 0.02);
}

/* Source-language indicator on cluster cards. Shape matches .platform-chip
   for visual consistency, but mixes native script (left) + uppercase ISO
   code (right) and overrides the inherited uppercase to keep CJK readable.
   Sits inline with .row-meta and .member-meta near the source name. */
.lang-chip {
  display: inline-block;
  margin-left: 0.4rem;        /* visual adjacency to the source name */
  padding: 0.10rem 0.5rem;
  border: 1px solid rgba(184, 255, 60, 0.28);   /* faint accent ring */
  border-radius: var(--r-sm);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  font-weight: 500;
  text-transform: none;       /* preserve native-script glyphs */
  color: var(--fg);
  background: rgba(184, 255, 60, 0.06);
  white-space: nowrap;
  vertical-align: 1px;        /* nudge baseline so it sits with the source */
  cursor: help;               /* signals the hover tooltip */
  transition: background 100ms ease, border-color 100ms ease, color 100ms ease;
}
.lang-chip:hover {
  border-color: rgba(184, 255, 60, 0.55);
  background: rgba(184, 255, 60, 0.14);
  color: var(--accent);
}

/* Roundup-source chip. Visual disambiguation from the language chip
   uses a desaturated amber tint — same shape, different signal. The
   click destination on synthetic-child cards is a digest page, not the
   atomic story; this chip warns the reader. Hover deepens the amber. */
.lang-chip.roundup-chip {
  border-color: rgba(255, 169, 77, 0.32);
  background: rgba(255, 169, 77, 0.08);
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.lang-chip.roundup-chip:hover {
  border-color: rgba(255, 169, 77, 0.65);
  background: rgba(255, 169, 77, 0.18);
  color: var(--t-tool);   /* amber tier hue, defined at the top of the file */
}

/* Original-language headline shown under the translated title on the
   detail page. The chip sits to the left of the original-language string;
   keep both muted so the English title still leads the page. */
/* When the lead title was machine-translated, the language chip +
   original-language title now ride on the meta row right next to
   the post time (see cluster.html). The chip stays flush with the
   chip; the text drops below as a wrapped flex item if the line
   is full. .lead-title is no longer rendered in the grid, but
   the .lang-chip-inline rule still gets reused on the chip. */
.meta-lang {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  /* flex-grow is 0 so the meta-lang span doesn't eat the leftover
     row space — that space belongs to .cluster-row-actions's
     `margin-left: auto`, which has to pin the action pills to the
     absolute right edge. flex-shrink stays 1 so a long CJK string
     can shrink + wrap on a narrow viewport. */
  flex: 0 1 auto;
  min-width: 0;
}
.meta-lang-text {
  /* CJK titles aren't great in JetBrains Mono; switch to the
     site's sans (Hanken Grotesk + system CJK fallbacks) for
     legibility, and let it wrap naturally on word/syllable
     boundaries. */
  font-family: var(--sans);
  color: var(--fg-3);
  white-space: normal;
  overflow-wrap: anywhere;
}
.lang-chip-inline {
  flex: 0 0 auto;
}

.gem-mark {
  display: inline-block;
  padding: 0.06rem 0.42rem;
  border-radius: var(--r-sm);
  font-family: var(--mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bg);
  background: var(--accent);
}

/* Slight accent on hidden-gem rows in Pulse — extra-subtle so it doesn't
   shout at every other card. */
.row.is-gem .row-rail {
  background: var(--accent);
  opacity: 0.4;
}
.row.is-gem:hover .row-rail {
  opacity: 0.85;
}

.pill-platform {
  text-transform: lowercase;
}

/* ── Pager ───────────────────────────────────────────────────────── */

.pager {
  margin-top: 2rem;
  padding: 1.1rem 1.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-top: 1px solid var(--fg-6);
  border-bottom: 1px solid var(--fg-6);
  background: rgba(255, 255, 255, 0.012);
}
.pager-status {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--fg-3);
}
.pager-key {
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--fg-4);
  font-size: 0.65rem;
}
.pager-num {
  color: var(--fg);
  font-weight: 500;
  font-size: 0.86rem;
}
.pager-sep { color: var(--fg-5); }
.pager-meta { color: var(--fg-3); }

.pager-controls {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.pager-btn {
  display: inline-flex;
  align-items: center;
  padding: 0.42rem 0.8rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg-2);
  background: transparent;
  border: 1px solid var(--fg-5);
  border-radius: var(--r-sm);
  transition: color 80ms ease, border-color 80ms ease, background 80ms ease;
}
.pager-btn:hover {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}
.pager-btn.is-disabled {
  color: var(--fg-5);
  border-color: var(--fg-6);
  background: transparent;
  cursor: not-allowed;
}
.pager-btn.is-disabled:hover {
  color: var(--fg-5);
  background: transparent;
  border-color: var(--fg-6);
}

/* ── Cited (citation graph) ──────────────────────────────────────── */

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

.cite-row {
  display: grid;
  grid-template-columns: 4px 100px minmax(0, 1fr);
  gap: 0;
  padding: 1.4rem 0 1.5rem;
  border-bottom: 1px solid var(--line);
  position: relative;
  opacity: 0;
  animation: row-in 0.28s ease both;
  animation-delay: var(--stagger, 0ms);
  transition: background 0.12s ease;
}
.cite-row:hover {
  background: linear-gradient(90deg, rgba(184,255,60,0.04) 0%, transparent 60%);
}

.cite-rail {
  background: var(--accent);
  opacity: 0;
  transition: opacity .12s ease;
  border-radius: 0 2px 2px 0;
}
.cite-row:hover .cite-rail { opacity: 0.6; }

.cite-count {
  padding: 2px 16px 0 18px;
  align-self: start;
}
.cite-num {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 2rem;
  line-height: 0.95;
  color: var(--accent);
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}
.cite-num-label {
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  color: var(--fg-4);
  text-transform: uppercase;
  margin-top: 0.4rem;
}
.cite-extra {
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--fg-5);
  margin-top: 0.25rem;
}

.cite-body {
  padding: 0 1rem 0 1.25rem;
  min-width: 0;
}

.cite-meta {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  text-transform: uppercase;
  margin-bottom: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.cite-meta .meta-source { color: var(--fg-2); font-weight: 500; }
.cite-meta .meta-sep { color: var(--fg-5); }
.cite-meta .meta-time { color: var(--fg-4); font-feature-settings: "tnum"; }

.cite-title {
  margin: 0 0 0.6rem;
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.4;
  word-break: break-all;
}
.cite-title a {
  color: var(--fg);
  text-decoration: none;
  border-bottom: 1px dashed var(--fg-5);
  transition: color 80ms ease, border-color 80ms ease;
}
.cite-title a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.cite-linkers {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.45rem;
}
.cite-linker {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--fg-2);
  padding: 2px 0.5rem;
  border: 1px solid var(--fg-6);
  border-radius: var(--r-sm);
  background: rgba(255,255,255,0.02);
}
.cite-linker-more {
  color: var(--fg-4);
  border-style: dashed;
  background: transparent;
}

/* ── Whispers (long-tail) ────────────────────────────────────────── */

/* Whispers reuses the operator-console row layout but swaps the
   accent to the lavender tier-research hue. The framing is "the
   signal that escapes Brief", so the meter num glows lavender
   instead of lime; the score-meter fill keeps the cluster's tier
   color so research/tool/commentary still read at a glance. */
body[data-mode="whispers"] .meter-num { color: var(--t-research); }
body[data-mode="whispers"] .row:hover .row-rail { background: var(--t-research); }
body[data-mode="whispers"] .row-summary { color: var(--fg-2); }
body[data-mode="whispers"] .pill.is-on { border-color: var(--t-research); color: var(--t-research); }
body[data-mode="whispers"] .filter-row .pill:hover { color: var(--t-research); }
body[data-mode="whispers"] .hero-title { color: var(--t-research); }
body[data-mode="whispers"] .meter-fill { background: var(--t-research); }
body[data-mode="whispers"] .row { border-color: rgba(185, 138, 255, 0.18); }

/* The whispers tab pill in the nav — give it a permanent lavender
   tint so the "this is the secret one" vibe is visible from any tab. */
.tab.tab-whispers { color: var(--t-research); }
.tab.tab-whispers.is-active {
  border-bottom-color: var(--t-research);
  color: var(--t-research);
}

/* ── Image lightbox ──────────────────────────────────────────────── */

.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(10, 10, 11, 0.94);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  display: none;
  align-items: center;
  justify-content: center;
  cursor: zoom-out;
  animation: lightbox-in 0.18s ease both;
}
.lightbox-overlay.is-open { display: flex; }
@keyframes lightbox-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.lightbox-img {
  max-width: 92vw;
  max-height: 82vh;
  width: auto;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
}
.lightbox-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 24px;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--fg-3);
  padding: 0 16px;
  pointer-events: none;
}
.lightbox-close {
  position: absolute;
  top: 18px;
  right: 22px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(20, 20, 24, 0.7);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: 50%;
  font-size: 18px;
  cursor: pointer;
}
.lightbox-close:hover { color: var(--accent); border-color: var(--accent); }

/* Headline + thumbnail link to the cluster permalink. Underline only
   on hover so the card body still reads cleanly when scrolling. */
.row-title a, .row-thumb {
  cursor: pointer;
}
.row-title a:hover { text-decoration-color: var(--accent); }

/* "Read on <Source>" CTA on cluster detail. Single primary action so
   users still reach the original article in one click after clicking
   into a cluster from the list. */
.detail-cta {
  margin: 1.2rem 0 0;
}
.detail-cta-btn {
  display: inline-block;
  padding: 0.55rem 1rem;
  background: var(--accent);
  color: var(--bg);
  border-radius: 6px;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.92rem;
  text-decoration: none;
  letter-spacing: -0.005em;
}
.detail-cta-btn:hover { color: var(--bg); filter: brightness(1.08); }

/* ── "Why this score?" modal ─────────────────────────────────────── */

.score-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(10, 10, 11, 0.78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: lightbox-in 0.18s ease both;
}
.score-modal-overlay.is-open { display: flex; }

.score-modal {
  position: relative;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: 14px;
  width: 100%;
  max-width: 520px;
  max-height: 85vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.score-modal-close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--fg-3);
  border: 0;
  border-radius: 50%;
  font-size: 18px;
  cursor: pointer;
}
.score-modal-close:hover { color: var(--accent); background: rgba(184, 255, 60, 0.08); }
.score-modal-body { overflow: auto; padding: 22px 24px; }
.score-modal-loading {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-4);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  padding: 32px 0;
}

.score-modal-content { display: flex; flex-direction: column; }

/* Header — matches mobile: TIER · score · /100 · raw (right) */
.score-modal-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 14px;
}
.score-modal-tier {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--fg-3);
  text-transform: uppercase;
}
.score-modal-tier.tier-frontier_release { color: var(--t-frontier); }
.score-modal-tier.tier-significant      { color: var(--t-significant); }
.score-modal-tier.tier-research         { color: var(--t-research); }
.score-modal-tier.tier-tool             { color: var(--t-tool); }
.score-modal-tier.tier-commentary       { color: var(--t-commentary); }
.score-modal-tier.tier-meme             { color: var(--fg-3); }
.score-modal-sep { color: var(--fg-3); }
.score-modal-num {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 1.8rem;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.score-modal-num.tier-frontier_release { color: var(--t-frontier); }
.score-modal-num.tier-significant      { color: var(--t-significant); }
.score-modal-num.tier-research         { color: var(--t-research); }
.score-modal-num.tier-tool             { color: var(--t-tool); }
.score-modal-num.tier-commentary       { color: var(--t-commentary); }
.score-modal-num.tier-meme             { color: var(--fg-3); }
.score-modal-num-suffix {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-3);
}
.score-modal-raw {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 0.6rem;
  color: var(--fg-3);
  letter-spacing: 0.04em;
}

/* "Why this tier" callout — matches mobile bg-2 panel + accent rule */
.score-modal-reason {
  background: var(--bg-2);
  border-left: 2px solid var(--fg-3);
  border-radius: 0 8px 8px 0;
  padding: 10px 12px;
  margin: 4px 0 12px;
}
.score-modal-reason.tier-frontier_release { border-left-color: var(--t-frontier); }
.score-modal-reason.tier-significant      { border-left-color: var(--t-significant); }
.score-modal-reason.tier-research         { border-left-color: var(--t-research); }
.score-modal-reason.tier-tool             { border-left-color: var(--t-tool); }
.score-modal-reason.tier-commentary       { border-left-color: var(--t-commentary); }
.score-modal-reason-key {
  font-family: var(--mono);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  margin-bottom: 6px;
  color: var(--fg-3);
}
.score-modal-reason.tier-frontier_release .score-modal-reason-key { color: var(--t-frontier); }
.score-modal-reason.tier-significant      .score-modal-reason-key { color: var(--t-significant); }
.score-modal-reason.tier-research         .score-modal-reason-key { color: var(--t-research); }
.score-modal-reason.tier-tool             .score-modal-reason-key { color: var(--t-tool); }
.score-modal-reason.tier-commentary       .score-modal-reason-key { color: var(--t-commentary); }
.score-modal-reason-body {
  margin: 0;
  font-size: 0.81rem;
  line-height: 1.45;
  color: var(--fg-2);
}

/* Section header above each dim group */
.score-modal-section-key {
  font-family: var(--mono);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--fg-3);
  text-transform: uppercase;
  margin: 14px 0 6px;
}

/* Per-dimension row — matches mobile DimRow exactly */
.score-modal-dim {
  padding: 8px 0;
}
.score-modal-dim-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 5px;
}
.score-modal-dim-label {
  color: var(--fg);
  font-size: 0.81rem;
}
.score-modal-dim-value {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--fg-2);
  font-variant-numeric: tabular-nums;
}
.score-modal-dim-bar {
  height: 4px;
  background: var(--bg-2);
  border-radius: 2px;
  overflow: hidden;
}
.score-modal-dim-bar-fill {
  height: 100%;
  width: var(--w, 0%);
  background: var(--fg-3);
  border-radius: 2px;
}
.score-modal-dim-bar-fill.tier-frontier_release { background: var(--t-frontier); }
.score-modal-dim-bar-fill.tier-significant      { background: var(--t-significant); }
.score-modal-dim-bar-fill.tier-research         { background: var(--t-research); }
.score-modal-dim-bar-fill.tier-tool             { background: var(--t-tool); }
.score-modal-dim-bar-fill.tier-commentary       { background: var(--t-commentary); }
.score-modal-dim-hint {
  margin-top: 4px;
  font-size: 0.7rem;
  color: var(--fg-3);
  line-height: 1.35;
}
.score-modal-empty {
  font-size: 0.78rem;
  color: var(--fg-3);
}

.score-modal-footer {
  margin-top: 18px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--fg-4);
  letter-spacing: 0.04em;
}


/* ── Embed mode ─────────────────────────────────────────────────────
 * Activated by ?embed=1 in the URL — the inline script in
 * base.html sets <html data-embed="1"> pre-paint. Used when a
 * page is rendered inside a host webview (the mobile app's
 * Privacy / Terms taps from Settings) where the surrounding
 * chrome is already provided by the host.
 *
 * Hides the topbar (brand + tabs + status + avatar), the bottom
 * tab bar variant added by the @media block above, and the
 * footer endbar. The shell padding-bottom set by the responsive
 * block is also no longer needed since there's no bottom bar to
 * sit above.
 */
html[data-embed="1"] .topbar,
html[data-embed="1"] .endbar,
html[data-embed="1"] .topbar-inner > .tabs,
html[data-embed="1"] .tabs-bottom {
  display: none !important;
}
html[data-embed="1"] .shell {
  padding-top: 1rem;
  padding-bottom: 2rem;
}


/* ── Lab Watch (web /lab/<slug>) ────────────────────────────────────
 * Per-entity dashboard reachable from any entity chip on Brief or
 * a cluster permalink page. Reuses the operator-console palette: no
 * new colour tokens, just compositions of existing ones.
 */
.lab-head {
  margin: 1rem 0 1.5rem;
  max-width: 720px;
}
.lab-title {
  font-family: var(--mono);
  font-size: 1.7rem;
  letter-spacing: 0.01em;
  color: var(--fg);
  margin: 0 0 0.4rem;
}
.lab-sub {
  color: var(--fg-3);
  font-size: 0.9rem;
  line-height: 1.5;
  margin: 0;
}

/* Follow toggle on Lab Watch. Sits between the lede sub and the
   stats grid. Lime accent — same family as the entity-chip
   research-tier color so it reads as a metadata action, not a CTA. */
.lab-follow {
  margin: 1rem 0 0;
}
.lab-follow-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.95rem;
  border-radius: 999px;
  border: 1px solid rgba(184, 255, 60, 0.35);
  background: rgba(184, 255, 60, 0.06);
  color: var(--accent);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, opacity 120ms ease;
}
.lab-follow-btn:hover {
  background: rgba(184, 255, 60, 0.10);
  border-color: rgba(184, 255, 60, 0.55);
}
.lab-follow-btn.is-following {
  background: rgba(184, 255, 60, 0.18);
  border-color: rgba(184, 255, 60, 0.55);
}
.lab-follow-btn:disabled {
  opacity: 0.55;
  cursor: progress;
}
.lab-follow-icon {
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1;
}

.lab-section-key {
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--fg-3);
  letter-spacing: 0.16em;
  margin-bottom: 0.5rem;
}

.lab-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin: 1.5rem 0 2rem;
}
.lab-stat {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 0.85rem 1rem;
}
.lab-stat-key {
  font-family: var(--mono);
  font-size: 0.6rem;
  color: var(--fg-3);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.lab-stat-val {
  font-family: var(--mono);
  font-size: 1.9rem;
  color: var(--fg);
  margin-top: 0.15rem;
  line-height: 1;
}
.lab-stat-val-frontier { color: var(--accent); }
.lab-stat-val-research { color: var(--t-research); }
.lab-stat-sub {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-3);
  margin-top: 0.4rem;
}

.lab-tier-mix { margin: 0 0 2rem; }
.lab-tier-bar {
  display: flex;
  height: 14px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-1);
  border: 1px solid var(--line);
}
.lab-tier-seg {
  display: block;
  height: 100%;
  width: var(--w, 0%);
}
.lab-tier-frontier_release { background: var(--accent); }
.lab-tier-significant      { background: var(--t-significant); }
.lab-tier-research         { background: var(--t-research); }
.lab-tier-tool             { background: var(--t-tool); }
.lab-tier-commentary       { background: var(--t-commentary); }
.lab-tier-meme             { background: var(--t-meme); }

.lab-tier-legend {
  list-style: none;
  padding: 0;
  margin: 0.6rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem 1.2rem;
}
.lab-tier-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.7rem;
}
.lab-tier-dot {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  display: inline-block;
}
.lab-tier-label {
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.lab-tier-count { color: var(--fg-3); }

.lab-feed { margin: 0 0 3rem; }
.lab-feed-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.lab-feed-row {
  border-top: 1px solid var(--line);
}
.lab-feed-row:last-child {
  border-bottom: 1px solid var(--line);
}
.lab-feed-link {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 14px;
  padding: 0.95rem 0;
  text-decoration: none;
  color: inherit;
}
.lab-feed-link:hover {
  background: linear-gradient(90deg,
    rgba(184, 255, 60, 0.025) 0%, transparent 60%);
}
.lab-feed-meter {
  /* Stack digits + score-rule in a centered column so the rule
     paints directly under the digits, not offset to one side.
     Mirrors `.row-score`'s flex-column treatment. */
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-right: 6px;
  border-right: 1px solid var(--line);
}
.lab-feed-score {
  font-family: var(--mono);
  font-size: 1.4rem;
  color: var(--fg);
  display: block;
  line-height: 1;
}
.tier-frontier_release .lab-feed-score { color: var(--accent); }
.tier-significant      .lab-feed-score { color: var(--t-significant); }
.tier-research         .lab-feed-score { color: var(--t-research); }
.tier-tool             .lab-feed-score { color: var(--t-tool); }
.tier-commentary       .lab-feed-score { color: var(--t-commentary); }
.tier-meme             .lab-feed-score { color: var(--t-meme); }
.lab-feed-score-pending { color: var(--fg-4); }
/* `.lab-feed-tier` deprecated 2026-05-05 — the lab feed now renders
   the bucket label via `.meta-bucket` in the meta row instead of
   below the score, so this class is unused. Left empty as a no-op
   marker in case any historical cached HTML still emits it. */
.lab-feed-tier { display: none; }

/* Tier-color overrides for the lab-feed score column + meta bucket.
   The canonical rules live under `.row.tier-X .score-digit` etc., but
   `.lab-feed-row` doesn't carry the `.row` class — these parallel
   selectors port the same colors. Meme falls through to fg-3, matching
   `.row.tier-meme .score-digit` semantics. */
.lab-feed-row.tier-frontier_release .score-digit,
.lab-feed-row.tier-frontier_release .meta-bucket { color: var(--t-frontier); }
.lab-feed-row.tier-frontier_release .score-rule  { background: var(--t-frontier); }
.lab-feed-row.tier-significant .score-digit,
.lab-feed-row.tier-significant .meta-bucket      { color: var(--t-significant); }
.lab-feed-row.tier-significant .score-rule       { background: var(--t-significant); }
.lab-feed-row.tier-research .score-digit,
.lab-feed-row.tier-research .meta-bucket         { color: var(--t-research); }
.lab-feed-row.tier-research .score-rule          { background: var(--t-research); }
.lab-feed-row.tier-tool .score-digit,
.lab-feed-row.tier-tool .meta-bucket             { color: var(--t-tool); }
.lab-feed-row.tier-tool .score-rule              { background: var(--t-tool); }
.lab-feed-row.tier-commentary .score-digit,
.lab-feed-row.tier-commentary .meta-bucket       { color: var(--t-commentary); }
.lab-feed-row.tier-commentary .score-rule        { background: var(--t-commentary); }
.lab-feed-row.tier-meme .score-digit,
.lab-feed-row.tier-meme .meta-bucket             { color: var(--fg-3); }
.lab-feed-row.tier-meme .score-rule              { background: var(--fg-3); }
.lab-feed-meta {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-3);
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}
.lab-feed-source { color: var(--fg-2); }
.lab-feed-title {
  font-family: var(--sans);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--fg);
  margin: 0.25rem 0 0.35rem;
  line-height: 1.3;
}
.lab-feed-summary {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--fg-2);
  line-height: 1.45;
  margin: 0;
}

.lab-empty {
  color: var(--fg-3);
  font-size: 0.9rem;
  margin: 0.4rem 0 0;
}

/* Permalink-page entity chips — slightly more breathing room than
 * the feed-row variant since they sit inside a wider article column. */
.detail-entities {
  margin-top: 1rem;
}

@media (max-width: 760px) {
  .lab-stats { grid-template-columns: 1fr; }
  .lab-feed-link { grid-template-columns: 56px minmax(0, 1fr); gap: 10px; }
  .lab-feed-score { font-size: 1.2rem; }
  .lab-feed-title { font-size: 1rem; }
}

/* ── Settings page (interactive forms) ─────────────────────────── */
.settings-page { max-width: 720px; margin: 0 auto; padding: 24px 16px 80px; }
.settings-page h1 { font-size: 1.6rem; margin: 0 0 16px; }
.settings-page h2 { font-size: 1.15rem; margin: 32px 0 8px; }
.settings-empty {
  padding: 14px 16px;
  border: 1px solid #1F1F25;
  border-radius: 10px;
  background: #111114;
  color: var(--fg-3);
  font-size: 0.95rem;
  margin: 0 0 24px;
}
.settings-empty a { color: var(--accent); text-decoration: none; }
.settings-empty a:hover { text-decoration: underline; }
.settings-card {
  border: 1px solid #1F1F25;
  border-radius: 12px;
  background: #0F0F12;
  padding: 4px 0;
  margin: 0 0 24px;
}
.settings-section {
  border: 0;
  border-top: 1px solid #1F1F25;
  margin: 0;
  padding: 18px 20px;
}
.settings-section:first-of-type { border-top: 0; }
.settings-section legend {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-3);
  padding: 0 6px 0 0;
  margin: 0 0 6px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
/* Per-section PRO chip — surfaces the entitlement gate inline so
   free / anon users see what's paid before they reach the toggle.
   Lime-bordered pill, mono micro-text, mirrors mobile's PRO chip
   on locked rows. */
.settings-pro-chip {
  display: inline-block;
  padding: 2px 7px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--accent);
  background: rgba(184, 255, 60, 0.10);
  border: 1px solid rgba(184, 255, 60, 0.42);
  border-radius: 999px;
  line-height: 1;
}

/* Free / anon banner above the form — replaces the prior
   single-line "Upgrade to enable them" sentence with a proper
   call-to-action card. */
.settings-paywall-banner {
  background: linear-gradient(
    180deg,
    rgba(184, 255, 60, 0.06),
    rgba(184, 255, 60, 0.00)
  ), #111114;
  border: 1px solid rgba(184, 255, 60, 0.45);
  border-radius: 10px;
  padding: 14px 16px;
  margin: 0 0 18px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.settings-paywall-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2.4px;
  color: var(--accent);
}
.settings-paywall-msg {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 14px;
  line-height: 1.45;
  color: var(--fg);
  margin: 0;
}
.settings-paywall-cta {
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border: 1px solid rgba(184, 255, 60, 0.45);
  background: rgba(184, 255, 60, 0.10);
  color: var(--accent);
  border-radius: 999px;
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.2px;
  text-decoration: none;
  transition: background 120ms, border-color 120ms;
}
.settings-paywall-cta:hover {
  background: rgba(184, 255, 60, 0.20);
  border-color: rgba(184, 255, 60, 0.65);
}
.settings-hint {
  color: var(--fg-3);
  font-size: 0.88rem;
  margin: 0 0 14px;
}
.settings-row {
  /* Mirror mobile Settings rows: label + sub stack on the left,
     iOS-style toggle on the right. Click anywhere on the row
     (label) toggles the checkbox. */
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 14px;
  padding: 12px 0;
  border-bottom: 1px dashed rgba(255,255,255,0.04);
  cursor: pointer;
}
.settings-row:last-child { border-bottom: 0; }
/* iOS-style switch — matches mobile <Switch trackColor={{ false: "#3A3A40",
   true: colors.accent }} thumbColor="#ECECEE" />. The input is the entire
   visual control: appearance:none strips the native checkbox, the track
   is the input's own background, and ::before draws the thumb. */
.settings-row input[type="checkbox"] {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  appearance: none;
  -webkit-appearance: none;
  width: 51px;
  height: 31px;
  flex-shrink: 0;
  margin: 0;
  border: 0;
  border-radius: 999px;
  background: #3A3A40;
  position: relative;
  cursor: pointer;
  transition: background-color 200ms ease;
}
.settings-row input[type="checkbox"]::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #ECECEE;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.30),
              0 0 0 1px rgba(0, 0, 0, 0.04);
  transition: transform 200ms ease;
}
.settings-row input[type="checkbox"]:checked {
  background: var(--accent);
}
.settings-row input[type="checkbox"]:checked::before {
  transform: translateX(20px);
}
.settings-row input[type="checkbox"]:focus-visible {
  outline: 2px solid rgba(184, 255, 60, 0.45);
  outline-offset: 2px;
}
.settings-row input[type="checkbox"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.settings-label {
  display: block;
  font-weight: 500;
  color: var(--fg);
}
.settings-sub {
  display: block;
  font-size: 0.85rem;
  color: var(--fg-3);
  grid-column: 1;
}
.settings-sub a { color: var(--accent); text-decoration: none; }
.settings-time-pair { display: flex; gap: 14px; flex-wrap: wrap; }
.settings-time {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 4px 0 0;
  flex: 1 1 160px;
}
.settings-time select,
.settings-card select {
  background: #0A0A0B;
  color: var(--fg);
  border: 1px solid #1F1F25;
  border-radius: 8px;
  padding: 8px 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.9rem;
}
/* Anon form: no Identity, every input is locked. Selects dim,
   toggles lose pointer events but keep their lime saturation
   (mirrors mobile <Switch> disabled behavior). */
.settings-card[data-locked="1"] select { opacity: 0.5; }
.settings-card[data-locked="1"] input[type="checkbox"] {
  cursor: not-allowed;
  pointer-events: none;
}
.settings-card[data-locked="1"] input[type="checkbox"]:not(:checked) {
  opacity: 0.6;
}

/* Per-row PRO lock — applied to .settings-row / .settings-stack
   when the user isn't paid. Disables the row's controls without
   dimming their brand color. The PRO pill on the label carries
   the visual signal. */
.settings-row[data-pro-locked="1"] input,
.settings-row[data-pro-locked="1"] select,
.settings-stack[data-pro-locked="1"] input,
.settings-stack[data-pro-locked="1"] select {
  cursor: not-allowed;
  pointer-events: none;
}
.settings-row[data-pro-locked="1"] input[type="checkbox"]:not(:checked) {
  opacity: 0.6;
}
.settings-stack[data-pro-locked="1"] select { opacity: 0.6; }

/* Per-row PRO pill — small inline chip next to the label text.
   Smaller than the section .settings-pro-chip so it fits inline
   with row labels without overshadowing them. */
.settings-pro-pill {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1.4px;
  color: var(--accent);
  background: rgba(184, 255, 60, 0.10);
  border: 1px solid rgba(184, 255, 60, 0.42);
  border-radius: 999px;
  vertical-align: middle;
  line-height: 1;
}

/* Non-toggle PRO row — used for quiet-hours and digest-time blocks
   that have a label + hint + select(s) instead of a single toggle.
   Same padding/border as .settings-row so the visual rhythm
   continues down the form. */
.settings-stack {
  padding: 14px 0;
  border-bottom: 1px dashed rgba(255, 255, 255, 0.04);
}
.settings-stack:last-child { border-bottom: 0; }
.settings-stack > .settings-label { margin-bottom: 4px; }

/* H2 between out-of-form sections (Custom alerts, Manage my data,
   Legal). Mirrors the legend style — uppercase mono micro-text. */
.settings-h2 {
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin: 28px 0 10px;
  padding-top: 4px;
}

/* LinkRow — chevron-styled row for navigation targets (Manage
   saved searches, Privacy, Terms, Download data, Delete account).
   Same card frame as .settings-card sections so the page reads
   as one continuous list, but each row stands alone. */
.settings-link-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid #1F1F25;
  border-radius: 10px;
  background: #0F0F12;
  margin: 0 0 8px;
  text-decoration: none;
  color: inherit;
  transition: border-color 120ms, background-color 120ms;
}
.settings-link-row:hover {
  border-color: rgba(184, 255, 60, 0.30);
  background: #131318;
}
.settings-link-row.is-locked { cursor: pointer; }
.settings-link-info { min-width: 0; }
.settings-link-info .settings-label { display: block; }
.settings-link-info .settings-sub {
  display: block;
  margin-top: 2px;
}
.settings-link-chev {
  font-size: 22px;
  line-height: 1;
  color: var(--fg-3);
  font-family: 'JetBrains Mono', monospace;
}
.settings-status {
  padding: 8px 20px 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  color: var(--fg-3);
  min-height: 1.2em;
}
.settings-status[data-kind="ok"] { color: var(--accent); }
.settings-status[data-kind="error"] { color: #ff7676; }

/* ── Bookmarks + alerts list pages ─────────────────────────────── */
.account-list-page { max-width: 720px; margin: 0 auto; padding: 24px 16px 80px; }
.account-list-page h1 { font-size: 1.6rem; margin: 0 0 4px; }
.account-list-page .page-sub { color: var(--fg-3); font-size: 0.95rem; margin: 0 0 18px; }
.account-list-cta {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid rgba(184,255,60,0.35);
  background: rgba(184,255,60,0.10);
  color: var(--accent);
  text-decoration: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.account-list-cta:hover { background: rgba(184,255,60,0.2); }
.bookmark-row, .alert-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid #1F1F25;
  border-radius: 10px;
  background: #111114;
  margin: 8px 0;
}
.bookmark-row .bk-name, .alert-row .al-name {
  font-weight: 500;
  color: var(--fg);
}
.bookmark-row .bk-url, .alert-row .al-filter {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  color: var(--fg-3);
  margin-top: 4px;
  word-break: break-all;
}
.bookmark-row .bk-url a { color: inherit; text-decoration: none; }
.bookmark-row .bk-url a:hover { color: var(--accent); }
.bookmark-row .bk-actions, .alert-row .al-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.bookmark-row .bk-actions a,
.alert-row .al-actions a,
.alert-row .al-actions button,
.bookmark-row .bk-actions button {
  padding: 6px 10px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid #1F1F25;
  color: var(--fg-3);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  cursor: pointer;
  text-decoration: none;
}
.bookmark-row .bk-actions button:hover,
.alert-row .al-actions button:hover { color: #ff7676; border-color: #ff7676; }
.alert-row .al-actions input[type="checkbox"] { accent-color: var(--accent); }

/* ── Cluster detail row-actions (bookmark + mark-read) ─────────── */
/* Lives inside .detail-meta as the final flex item on the bucket /
   sources / time line. margin-left:auto pushes it to the right edge;
   the meta-lang span (CJK original title) wraps below if the line
   doesn't fit both. */
.cluster-row-actions {
  display: flex;
  gap: 8px;
  margin: 0 0 0 auto;
}
.act-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid #1F1F25;
  background: #111114;
  color: var(--fg-3);
  font-family: 'JetBrains Mono', monospace;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: none;
}
.act-pill:hover { color: var(--fg); border-color: rgba(255,255,255,0.18); }
.act-pill.is-on {
  color: var(--accent);
  border-color: rgba(184,255,60,0.35);
  background: rgba(184,255,60,0.10);
}
.act-pill-glyph {
  width: 14px;
  height: 14px;
  display: block;
  flex-shrink: 0;
}

/* ── Paid pills (clusters.html filter row) ─────────────────────── */
.pill.is-paid {
  position: relative;
  border-style: dashed;
  border-color: rgba(184,255,60,0.35);
  color: var(--accent);
}
.pill.is-paid::after {
  content: " 🔒";
  font-size: 0.9em;
  margin-left: 2px;
}

/* ── /about, /about/founder, /editorial-standards ───────────────
   E-E-A-T pages ship in the same dark-graphite chrome as the rest
   of the site. Generous reading width but capped well below
   .shell so the prose stays comfortable rather than expanding to
   the full grid. Hierarchy reads: eyebrow / title / lede / sections,
   like a long-form post rather than a feed view.
   ──────────────────────────────────────────────────────────────── */
.about, .editorial, .founder {
  max-width: 720px;
  margin: 32px auto 80px;
  padding: 0 20px;
}

.about-hero, .founder-hero {
  margin-bottom: 40px;
}
.about-eyebrow, .founder-eyebrow {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
  margin-bottom: 12px;
  text-transform: uppercase;
}
.about-title, .founder-title {
  font-family: var(--sans);
  font-size: 36px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--fg);
  margin: 0 0 16px;
}
.about-lede, .founder-tagline {
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  color: var(--fg-mute, rgba(255,255,255,0.74));
  margin: 0;
}

.founder-hero {
  display: grid;
  grid-template-columns: 1fr 200px;
  gap: 32px;
  align-items: start;
}
@media (max-width: 600px) {
  .founder-hero {
    grid-template-columns: 1fr;
  }
}
.founder-portrait {
  width: 200px;
  height: 240px;
  border-radius: 6px;
  overflow: hidden;
  background: linear-gradient(135deg, rgba(184,255,60,0.18) 0%, rgba(184,255,60,0.04) 100%);
  border: 1px solid rgba(184,255,60,0.18);
}
.founder-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.founder-portrait-placeholder::before {
  content: "CV";
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: var(--mono);
  font-size: 48px;
  font-weight: 700;
  color: var(--accent);
}

.founder-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 16px 18px;
  margin: 0 0 40px;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 4px;
  background: rgba(255,255,255,0.02);
  font-family: var(--mono);
  font-size: 12px;
}
.founder-toc a {
  color: var(--fg-mute, rgba(255,255,255,0.7));
  text-decoration: none;
  border-bottom: 1px dotted rgba(184,255,60,0.3);
}
.founder-toc a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.about-section, .founder-section {
  margin: 0 0 40px;
}
.about-section h2, .founder-section h2 {
  font-family: var(--sans);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--fg);
  margin: 0 0 14px;
  scroll-margin-top: 80px;
}
.about-section p, .founder-section p {
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg-mute, rgba(255,255,255,0.82));
  margin: 0 0 14px;
}
.about-section a, .founder-section a, .editorial-list a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(184,255,60,0.4);
  text-underline-offset: 2px;
}
.about-section a:hover, .founder-section a:hover {
  text-decoration-color: var(--accent);
}
.about-section code, .founder-section code {
  font-family: var(--mono);
  font-size: 0.92em;
  background: rgba(184,255,60,0.08);
  padding: 1px 6px;
  border-radius: 3px;
  color: var(--accent);
}
.about-section em, .founder-section em {
  font-style: italic;
  color: rgba(255,255,255,0.92);
}
.about-section strong, .founder-section strong {
  font-weight: 700;
  color: var(--fg);
}

.founder-links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.founder-links li {
  font-family: var(--mono);
  font-size: 13px;
}

.editorial-list {
  list-style: none;
  padding: 0;
  margin: 0 0 14px;
}
.editorial-list li {
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg-mute, rgba(255,255,255,0.82));
  padding-left: 20px;
  position: relative;
  margin-bottom: 10px;
}
.editorial-list li::before {
  content: "·";
  color: var(--accent);
  position: absolute;
  left: 6px;
  font-weight: 700;
}

.ai-mark-inline {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 1px 5px;
  border: 1px solid rgba(184,255,60,0.4);
  border-radius: 3px;
  color: var(--accent);
  background: rgba(184,255,60,0.08);
  vertical-align: middle;
  margin: 0 2px;
}

/* ── Cluster-detail E-E-A-T polish ─────────────────────────────────
   Per-summary AI disclosure + cluster byline. Both render small,
   in mono, with the link in lime accent. Reads as honest signal of
   what's machine-written without dominating the cluster card.
   ──────────────────────────────────────────────────────────────── */
.ai-summary-disclosure {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.5;
  color: rgba(255,255,255,0.55);
  margin: -8px 0 18px;
  padding-left: 14px;
  border-left: 2px solid rgba(184,255,60,0.18);
}
.ai-summary-disclosure a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted rgba(184,255,60,0.4);
  margin-left: 4px;
}
.ai-summary-disclosure a:hover {
  border-bottom-style: solid;
}
.detail-byline {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.5;
  color: rgba(255,255,255,0.62);
  margin: 12px 0 0;
  padding: 10px 0 0;
  border-top: 1px solid rgba(255,255,255,0.06);
}
.detail-byline-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.42);
  margin-right: 4px;
}
.detail-byline-author {
  color: rgba(255,255,255,0.85);
  font-weight: 500;
}
.detail-byline-meta {
  color: rgba(255,255,255,0.55);
}

/* ── Source authority tier chip on cluster member rows ────────── */
.source-tier {
  display: inline-block;
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  border-radius: 2px;
  margin-left: 6px;
  vertical-align: middle;
}
.source-tier-tier_1 {
  color: var(--accent);
  background: rgba(184,255,60,0.10);
  border: 1px solid rgba(184,255,60,0.30);
}
.source-tier-tier_2 {
  color: rgba(255,255,255,0.78);
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.15);
}
.source-tier-tier_3 {
  color: rgba(255,255,255,0.50);
  background: transparent;
  border: 1px solid rgba(255,255,255,0.10);
}

/* ── Related-cluster rails on cluster detail ───────────────────── */
.detail-related {
  margin-top: 36px;
}
.related-rail {
  list-style: none;
  padding: 0;
  margin: 12px 0 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.related-rail li {
  margin: 0;
}
.related-rail a {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 4px;
  background: rgba(255,255,255,0.02);
  border: 1px solid rgba(255,255,255,0.06);
  text-decoration: none;
  color: var(--fg);
  transition: background 0.12s ease, border-color 0.12s ease;
}
.related-rail a:hover {
  background: rgba(184,255,60,0.06);
  border-color: rgba(184,255,60,0.25);
}
.related-bucket {
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: rgba(184,255,60,0.75);
  flex-shrink: 0;
  min-width: 84px;
}
.related-title {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.4;
  color: rgba(255,255,255,0.85);
}

/* ── Auto-linked entity / topic mentions in cluster summary ────── */
.entity-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted rgba(184,255,60,0.45);
  padding-bottom: 1px;
  transition: border-color 0.12s ease, color 0.12s ease;
}
.entity-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
  border-bottom-style: solid;
}

/* ── Pillar pages (long-form guides) ──────────────────────────── */
.pillar {
  max-width: 760px;
  margin: 32px auto 80px;
  padding: 0 20px;
}
.pillar-hero {
  margin-bottom: 32px;
}
.pillar-eyebrow {
  display: inline-block;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
  margin-bottom: 12px;
  text-transform: uppercase;
}
.pillar-title {
  font-family: var(--sans);
  font-size: 38px;
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--fg);
  margin: 0 0 14px;
}
.pillar-lede {
  font-family: var(--sans);
  font-size: 18px;
  line-height: 1.55;
  color: var(--fg-mute, rgba(255,255,255,0.78));
  margin: 0 0 16px;
}
.pillar-meta {
  font-family: var(--mono);
  font-size: 12px;
  color: rgba(255,255,255,0.55);
  margin: 0;
}
.pillar-meta a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted rgba(184,255,60,0.4);
}
.pillar-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 16px 18px;
  margin: 24px 0 32px;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 4px;
  background: rgba(255,255,255,0.02);
  font-family: var(--mono);
  font-size: 12px;
}
.pillar-toc a {
  color: rgba(255,255,255,0.7);
  text-decoration: none;
  border-bottom: 1px dotted rgba(184,255,60,0.3);
}
.pillar-toc a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.pillar-body section {
  margin-bottom: 32px;
}
.pillar-body section h2 {
  font-family: var(--sans);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--fg);
  margin: 0 0 12px;
  scroll-margin-top: 80px;
}
.pillar-body p {
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  color: var(--fg-mute, rgba(255,255,255,0.82));
  margin: 0 0 14px;
}
.pillar-body a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(184,255,60,0.4);
  text-underline-offset: 2px;
}
.pillar-todo {
  display: inline-block;
  padding: 8px 12px;
  background: rgba(255,200,80,0.08);
  border-left: 3px solid rgba(255,200,80,0.6);
  color: rgba(255,200,80,0.9);
  font-style: italic;
  font-size: 14px;
}
.pillar-table {
  width: 100%;
  border-collapse: collapse;
  margin: 16px 0 20px;
  font-family: var(--sans);
  font-size: 14px;
}
.pillar-table thead th {
  text-align: left;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(184,255,60,0.85);
  padding: 8px 12px;
  border-bottom: 1px solid rgba(184,255,60,0.2);
}
.pillar-table tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  color: var(--fg-mute, rgba(255,255,255,0.82));
  vertical-align: top;
}
.pillar-table tbody tr:hover td {
  background: rgba(184,255,60,0.03);
}
.pillar-table tbody tr:last-child td {
  border-bottom: none;
}
.pillar-body ol.editorial-list {
  counter-reset: item;
  padding-left: 0;
}
.pillar-body ol.editorial-list li {
  list-style: none;
  counter-increment: item;
  padding-left: 28px;
  position: relative;
}
.pillar-body ol.editorial-list li::before {
  content: counter(item) ".";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-family: var(--mono);
  font-weight: 700;
}
.pillar-footer {
  margin-top: 48px;
  padding-top: 24px;
  border-top: 1px solid rgba(255,255,255,0.08);
  font-family: var(--sans);
  font-size: 14px;
  color: rgba(255,255,255,0.62);
}
.pillar-footer a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(184,255,60,0.4);
}

/* ── Topic / entity intro paragraph ────────────────────────────── */
.topic-intro {
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--fg-mute, rgba(255,255,255,0.78));
  max-width: 740px;
  margin: 24px 0 36px;
}
.topic-intro a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: rgba(184,255,60,0.4);
  text-underline-offset: 2px;
}

/* ════════════════════════════════════════════════════════════════════
   COLLECTION PAGES — /topic/<slug> + /entity/<slug>
   ────────────────────────────────────────────────────────────────────
   Operator-console editorial. Bloomberg-terminal density meets FT
   sector-page typographic restraint. Score-as-feature on each card,
   tier-keyed left rail for scanability, hero stat strip up top. The
   shared template renders both topic and entity pages; entity pages
   add a grounding-chip row when the curated table has Wikidata /
   Wikipedia / homepage URLs.
   ════════════════════════════════════════════════════════════════════ */

.collection-shell {
  max-width: 1080px;
  margin: 0 auto;
  padding: 36px 24px 80px;
}

/* ── Crumb (anchor home) ──────────────────────────────────────── */
.collection-crumb {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.45);
  margin-bottom: 28px;
  text-transform: uppercase;
}
.collection-crumb-link {
  color: rgba(255, 255, 255, 0.65);
  text-decoration: none;
  border-bottom: 1px dotted transparent;
  transition: color 0.15s ease, border-bottom-color 0.15s ease;
}
.collection-crumb-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.collection-crumb-arrow { margin-right: 2px; }
.collection-crumb-sep { color: rgba(255, 255, 255, 0.25); }
.collection-crumb-id { color: rgba(184, 255, 60, 0.65); font-weight: 500; }

/* ── Hero ─────────────────────────────────────────────────────── */
.collection-hero {
  position: relative;
  padding-bottom: 32px;
  margin-bottom: 36px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  animation: collection-hero-rise 0.55s ease-out both;
}

.collection-hero-eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 18px;
}
.collection-hero-kind {
  position: relative;
  padding: 4px 10px;
  border: 1px solid rgba(184, 255, 60, 0.4);
  background: rgba(184, 255, 60, 0.06);
  border-radius: 2px;
  letter-spacing: 0.18em;
}
.collection-hero-eyebrow-rule {
  flex: 0 0 32px;
  height: 1px;
  background: linear-gradient(to right,
    rgba(184, 255, 60, 0.6),
    rgba(184, 255, 60, 0));
}
.collection-hero-slug {
  color: rgba(255, 255, 255, 0.55);
  font-weight: 500;
  letter-spacing: 0.1em;
}

.collection-hero-title {
  font-family: var(--sans);
  font-size: clamp(38px, 5vw, 56px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--fg);
  margin: 0 0 18px;
  /* Subtle lime undertone on the lead character — readable as
     "this is the topic" without screaming for attention. */
}

.collection-hero-intro {
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.62;
  color: rgba(255, 255, 255, 0.78);
  max-width: 720px;
  margin: 0 0 24px;
}
.collection-hero-intro a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid rgba(184, 255, 60, 0.35);
  transition: border-bottom-color 0.15s ease;
}
.collection-hero-intro a:hover {
  border-bottom-color: var(--accent);
}

/* Entity-page grounding chips (only render when grounding is present
   and kind == "entity"). The Wikipedia / Wikidata / homepage links
   are the same anchors AI engines crawl from the JSON-LD, surfaced
   visually so human readers see the disambiguation chain too. */
.collection-grounding {
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.collection-grounding-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
  font-family: var(--mono);
  font-size: 11px;
  color: rgba(255, 255, 255, 0.78);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.collection-grounding-chip:hover {
  border-color: rgba(184, 255, 60, 0.5);
  background: rgba(184, 255, 60, 0.05);
  color: var(--fg);
}
.collection-grounding-chip-key {
  display: inline-block;
  min-width: 22px;
  text-align: center;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
}
.collection-grounding-chip-label {
  letter-spacing: 0.04em;
}

/* Stat strip — operator data summary. "How much, what age, what
   shape" in one row. dl semantic so it's interpretable to assistive
   tech as a key-value list rather than just a row of numbers. */
.collection-statstrip {
  display: flex;
  flex-wrap: wrap;
  gap: 32px 48px;
  margin: 0;
  padding: 18px 22px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 4px;
  background:
    linear-gradient(to right, rgba(184, 255, 60, 0.04), rgba(184, 255, 60, 0) 40%),
    rgba(255, 255, 255, 0.012);
  position: relative;
}
.collection-statstrip::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 2px;
  background: linear-gradient(to bottom, var(--accent), rgba(184, 255, 60, 0));
  border-radius: 1px;
}
.collection-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.collection-stat-label {
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
  margin: 0;
}
.collection-stat-value {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--mono);
  margin: 0;
}
.collection-stat-num {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
  line-height: 1;
}
.collection-stat-unit {
  font-size: 13px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.5);
  text-transform: lowercase;
  letter-spacing: 0.04em;
}
.collection-stat-buckets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  align-items: center;
  padding-top: 2px;
}
.collection-stat-bucket {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7);
}
.collection-stat-bucket-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--tier-dot, rgba(184, 255, 60, 0.7));
  display: inline-block;
}
.collection-stat-bucket-n {
  color: rgba(255, 255, 255, 0.92);
  font-weight: 700;
  margin-left: 2px;
}

/* Per-tier accent for the dot. */
.collection-stat-bucket.tier-frontier_release { --tier-dot: #B8FF3C; color: rgba(220, 255, 180, 0.95); border-color: rgba(184, 255, 60, 0.32); }
.collection-stat-bucket.tier-significant      { --tier-dot: #FFB347; color: rgba(255, 220, 180, 0.92); border-color: rgba(255, 179, 71, 0.28); }
.collection-stat-bucket.tier-research         { --tier-dot: #6EC1FF; color: rgba(180, 220, 255, 0.92); border-color: rgba(110, 193, 255, 0.28); }
.collection-stat-bucket.tier-tool             { --tier-dot: #C893FF; color: rgba(220, 200, 255, 0.92); border-color: rgba(200, 147, 255, 0.28); }
.collection-stat-bucket.tier-commentary       { --tier-dot: #FF7A8E; color: rgba(255, 200, 210, 0.92); border-color: rgba(255, 122, 142, 0.28); }
.collection-stat-bucket.tier-meme             { --tier-dot: #6E6E76; color: rgba(190, 190, 200, 0.7);  border-color: rgba(110, 110, 118, 0.24); }
.collection-stat-bucket.tier-paper            { --tier-dot: #6EC1FF; color: rgba(180, 220, 255, 0.92); border-color: rgba(110, 193, 255, 0.28); }
.collection-stat-bucket.tier-product          { --tier-dot: #C893FF; color: rgba(220, 200, 255, 0.92); border-color: rgba(200, 147, 255, 0.28); }

/* ── Cluster list ─────────────────────────────────────────────── */
.collection-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.collection-card {
  position: relative;
  /* staggered reveal — first 14 cards animate, the rest skip the
     intro for above-the-fold focus. Pure CSS. */
  animation: collection-card-rise 0.5s ease-out both;
  animation-delay: calc(min(var(--card-i, 0), 13) * 38ms);
}
.collection-card-link {
  display: grid;
  /* score | meter | body. Zero column-gap; the body has its own
     left padding to create breathing room after the meter. Score
     column holds only the digit stack; meter is its own track,
     so neither affects the other's positioning. */
  grid-template-columns: 40px 3px 1fr;
  column-gap: 0;
  /* Top/right/bottom keep the original card breathing room; left
     drops to 8px so the score column doesn't float in dead space
     (which made the digit read off-center relative to the meter). */
  padding: 18px 22px 20px 8px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg-1);
  text-decoration: none;
  color: inherit;
  position: relative;
  overflow: hidden;
  /* Mirror .row's hover model: solid tier-color rail (opacity 0 → 1
     on hover), gradient hover bg keyed off the tier's --tier-bg, no
     transform shift. Same hover language as the feed cards on
     /clusters, /social, /whispers, /citations. */
  transition: border-color 0.12s ease, background 0.12s ease;
}
.collection-card-link::before {
  /* Tier-keyed left rail. Solid color (no gradient), hidden until
     hover. Sits flush against the card's left edge, full height. */
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--tier-rail-color, var(--line));
  opacity: 0;
  transition: opacity 0.12s ease;
  border-radius: 0 2px 2px 0;
}
.collection-card-link:hover {
  background: linear-gradient(90deg, var(--tier-bg, rgba(255,255,255,0.012)) 0%, var(--bg-1) 60%);
  border-color: rgba(140, 140, 145, 0.28);
}
.collection-card-link:hover::before { opacity: 1; }
.collection-card-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Tier rail + hover bg per bucket. Solid `--t-*` colors so the card's
   rail matches the feed cards (.row-rail) exactly. `--tier-bg`
   matches .row.tier-*'s hover gradient origin. */
.collection-card.tier-frontier_release { --tier-rail-color: var(--t-frontier);    --tier-bg: var(--t-frontier-bg); }
.collection-card.tier-significant      { --tier-rail-color: var(--t-significant); --tier-bg: var(--t-significant-bg); }
.collection-card.tier-research         { --tier-rail-color: var(--t-research);    --tier-bg: var(--t-research-bg); }
.collection-card.tier-paper            { --tier-rail-color: var(--t-research);    --tier-bg: var(--t-research-bg); }
.collection-card.tier-tool             { --tier-rail-color: var(--t-tool);        --tier-bg: var(--t-tool-bg); }
.collection-card.tier-product          { --tier-rail-color: var(--t-tool);        --tier-bg: var(--t-tool-bg); }
.collection-card.tier-commentary       { --tier-rail-color: var(--t-commentary);  --tier-bg: var(--t-commentary-bg); }
.collection-card.tier-meme             { --tier-rail-color: var(--t-meme);        --tier-bg: var(--t-meme-bg); }

/* Meta-bucket pill — colored per tier via the global --t-* palette,
   mirroring `.row.tier-X .meta-bucket`. The .meta-bucket base style
   (uppercase mono, letter-spacing) is already defined above next to
   the feed-card rules; we only need the tier color override here. */
.collection-card.tier-frontier_release .meta-bucket { color: var(--t-frontier); }
.collection-card.tier-significant      .meta-bucket { color: var(--t-significant); }
.collection-card.tier-research         .meta-bucket { color: var(--t-research); }
.collection-card.tier-paper            .meta-bucket { color: var(--t-research); }
.collection-card.tier-tool             .meta-bucket { color: var(--t-tool); }
.collection-card.tier-product          .meta-bucket { color: var(--t-tool); }
.collection-card.tier-commentary       .meta-bucket { color: var(--t-commentary); }
.collection-card.tier-meme             .meta-bucket { color: var(--fg-3); }

/* Score digits + rule on collection cards — same per-tier color
   inheritance as .row.tier-X (line ~568). Defined locally so the
   .score-digit / .score-rule rules don't fight each other when both
   .row and .collection-card share an ancestor. */
.collection-card.tier-frontier_release .score-digit { color: var(--t-frontier); }
.collection-card.tier-significant      .score-digit { color: var(--t-significant); }
.collection-card.tier-research         .score-digit { color: var(--t-research); }
.collection-card.tier-tool             .score-digit { color: var(--t-tool); }
.collection-card.tier-commentary       .score-digit { color: var(--t-commentary); }
.collection-card.tier-meme             .score-digit { color: var(--fg-3); }
.collection-card.tier-frontier_release .score-rule { background: var(--t-frontier); }
.collection-card.tier-significant      .score-rule { background: var(--t-significant); }
.collection-card.tier-research         .score-rule { background: var(--t-research); }
.collection-card.tier-tool             .score-rule { background: var(--t-tool); }
.collection-card.tier-commentary       .score-rule { background: var(--t-commentary); }
.collection-card.tier-meme             .score-rule { background: var(--fg-3); }

/* Score column. Vertical digits + tier-colored rule + a vertical
   meter pinned to the right edge of the column, replacing the column
   divider. The meter itself is the visual seam between the score and
   the body — bg track at low-alpha, tier-colored fill grows up from
   the bottom proportional to display_score. */
.collection-card-score {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 0 6px 0 0;
}
.collection-card-meter {
  /* Its own grid track. Spans the full row height via the grid's
     default `stretch` align. Acts as the visual divider between
     score and body. */
  position: relative;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}
.collection-card-meter-fill {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--w, 0%);
  background: var(--tier-rail-color, var(--accent));
  opacity: 0.85;
  transition: height 0.4s ease;
}
.collection-card-score-meter {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}
.collection-card-score-fill {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* `--w` is the display_score (0-100); drives vertical fill height. */
  height: var(--w, 0%);
  width: 100%;
  background: var(--tier-rail-color, var(--accent));
  opacity: 0.85;
  transition: height 0.4s ease;
}

/* Body column. */
.collection-card-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding-left: 16px;
}
.collection-card-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.collection-card-id {
  color: rgba(184, 255, 60, 0.55);
  letter-spacing: 0.1em;
}
.collection-card-meta-sep {
  color: rgba(255, 255, 255, 0.2);
}
.collection-card-time {
  color: rgba(255, 255, 255, 0.55);
}
.collection-card-title {
  font-family: var(--sans);
  font-size: 19px;
  font-weight: 500;
  line-height: 1.32;
  letter-spacing: -0.005em;
  color: var(--fg);
  margin: 4px 0 2px;
  /* Multi-line clamp for runaway titles — we already clamp via
     clean_headline server-side, but defense in depth. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color 0.18s ease;
}
.collection-card-link:hover .collection-card-title {
  color: var(--accent);
}
.collection-card-summary {
  font-family: var(--sans);
  font-size: 14.5px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.66);
  margin: 0 0 6px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.collection-card-cta {
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(184, 255, 60, 0.55);
  margin-top: 2px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.18s ease, transform 0.18s ease, color 0.18s ease;
}
.collection-card-link:hover .collection-card-cta {
  opacity: 1;
  transform: translateX(0);
  color: var(--accent);
}
.collection-card-cta-arrow {
  display: inline-block;
  transition: transform 0.18s ease;
}
.collection-card-link:hover .collection-card-cta-arrow {
  transform: translateX(3px);
}

/* ── Empty state ──────────────────────────────────────────────── */
.collection-empty {
  border: 1px dashed rgba(255, 255, 255, 0.1);
  border-radius: 5px;
  padding: 40px 24px;
  text-align: center;
  background: rgba(255, 255, 255, 0.012);
}
.collection-empty-headline {
  font-family: var(--sans);
  font-size: 17px;
  color: rgba(255, 255, 255, 0.78);
  margin: 0 0 8px;
}
.collection-empty-hint {
  font-family: var(--mono);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.45);
  margin: 0;
  letter-spacing: 0.04em;
}

/* ── Reveal animations ────────────────────────────────────────── */
@keyframes collection-hero-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes collection-card-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Reduced-motion preference — honor it. */
@media (prefers-reduced-motion: reduce) {
  .collection-hero,
  .collection-card { animation: none; }
  .collection-card-link,
  .collection-card-link::before,
  .collection-card-title,
  .collection-card-cta,
  .collection-card-cta-arrow,
  .collection-card-score-fill,
  .collection-card-meter-fill,
  .collection-grounding-chip {
    transition: none;
  }
}

/* ── Responsive ───────────────────────────────────────────────── */
@media (max-width: 720px) {
  .collection-shell { padding: 24px 16px 60px; }
  .collection-hero { padding-bottom: 22px; margin-bottom: 26px; }
  .collection-hero-title { font-size: clamp(30px, 8vw, 38px); }
  .collection-hero-intro { font-size: 16px; }
  .collection-statstrip { padding: 14px 16px; gap: 18px 28px; }
  .collection-stat-num { font-size: 22px; }
  .collection-card-link {
    grid-template-columns: 24px 3px 1fr;
    column-gap: 0;
    padding: 14px 16px 16px 6px;
  }
  .collection-card-score { padding: 0; }
  .collection-card-body { padding-left: 12px; }
  .collection-card-score-num { font-size: 28px; }
  .collection-card-title { font-size: 16px; }
  .collection-card-summary { font-size: 13.5px; }
}

@media (max-width: 420px) {
  .collection-card-link {
    grid-template-columns: 22px 3px 1fr;
    column-gap: 0;
  }
  .collection-card-body { padding-left: 10px; }
  .collection-card-score-num { font-size: 24px; }
  .collection-card-score-tier { display: none; }
}

/* ── ENTITY PAGES — net-new bits: stats grid, tier-mix bar, follow
       CTA, pager. Hero / cards / list / empty reuse .collection-* CSS
       defined above. Tier hue cascade uses the lab-tier-* utility
       classes that already exist further up the file. ──────────── */

.entity-shell { /* alias of .collection-shell; nothing extra */ }

.entity-section-key {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: var(--fg-4);
  margin-bottom: 0.85rem;
  text-transform: uppercase;
}

/* Typed-relationship chips. The whole pill is the link — type label +
   target name + confidence read as one unit, and the entire chip
   highlights on hover (border + bg lift) so the affordance is honest. */
.entity-relationship-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em;
  padding: 0;
  margin: 0 0 1.5rem;
  list-style: none;
}
.entity-rel-chip {
  display: inline-flex;
}
.entity-rel-chip-link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45em;
  padding: 0.3em 0.7em;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
  color: inherit;
  text-decoration: none;
  font-size: 0.85em;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.entity-rel-chip-link:hover,
.entity-rel-chip-link:focus-visible {
  border-color: var(--accent);
  background: rgba(184, 255, 60, 0.08);
  color: var(--fg-1);
  outline: none;
}
.entity-rel-chip-link:hover .entity-rel-target,
.entity-rel-chip-link:focus-visible .entity-rel-target {
  color: var(--accent);
}
.entity-rel-type {
  opacity: 0.7;
  font-family: var(--mono);
  font-size: 0.85em;
  text-transform: lowercase;
  letter-spacing: 0.02em;
}
.entity-rel-target {
  font-weight: 600;
  transition: color 0.12s ease;
}
.entity-rel-conf {
  opacity: 0.5;
  font-family: var(--mono);
  font-size: 0.78em;
  font-variant-numeric: tabular-nums;
}

/* Stats grid — three operator-console cells with 30d primary value
   and 90d sub-stat. Same beat as the lab page's .lab-stats but spans
   the collection-shell width and keys colour off the accent. */
.entity-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 6px;
  overflow: hidden;
  margin: 0 0 1.5rem;
}
.entity-stat {
  background: rgba(10, 10, 11, 0.6);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.entity-stat-key {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--fg-4);
  text-transform: uppercase;
}
.entity-stat-val {
  font-family: var(--mono);
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--fg);
  line-height: 1;
}
.entity-stat-val-frontier { color: #B8FF3C; }
.entity-stat-val-research { color: #6EC1FF; }
.entity-stat-sub {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-4);
  letter-spacing: 0.04em;
}

@media (max-width: 600px) {
  .entity-stats { grid-template-columns: 1fr; }
}

/* Tier-mix bar + legend. Bar segments use --w (set inline as a
   percentage) to fill proportional widths. Hue comes from the
   lab-tier-* classes the template applies. */
.entity-tier-mix {
  margin: 0 0 1.5rem;
}
.entity-tier-bar {
  display: flex;
  width: 100%;
  height: 10px;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.05);
  margin-bottom: 0.85rem;
}
.entity-tier-seg {
  width: var(--w);
  display: block;
  height: 100%;
  transition: width 0.2s ease;
}
.entity-tier-legend {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
}
.entity-tier-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--fg-3);
  letter-spacing: 0.04em;
}
.entity-tier-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  display: inline-block;
}
.entity-tier-label { text-transform: uppercase; letter-spacing: 0.12em; }
.entity-tier-count { color: var(--fg-4); font-weight: 700; }

.entity-empty-line {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--fg-4);
  margin: 0;
}

/* Follow CTA — pill button. Compact-but-readable, sits above the
   stats grid as a hero-row affordance. Inactive (default) state
   uses the accent ring; the .is-following modifier flips to a
   filled lime pill. */
.entity-follow {
  margin-top: 14px;
}
.entity-follow-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--accent);
  background: rgba(184, 255, 60, 0.06);
  border: 1px solid rgba(184, 255, 60, 0.4);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  text-transform: uppercase;
}
.entity-follow-btn:hover {
  background: rgba(184, 255, 60, 0.12);
  border-color: var(--accent);
  transform: translateY(-1px);
}
.entity-follow-btn.is-following {
  background: var(--accent);
  color: #0A0A0B;
  border-color: var(--accent);
}
.entity-follow-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 900;
  line-height: 1;
}
.entity-follow-label { line-height: 1; }

/* Recent feed wrapper — section banner above the .collection-list. */
.entity-feed { margin-top: 0.5rem; }

/* Pager. Three columns on desktop (prev / pos / next), stacks at
   narrow widths. Disabled state goes monochrome and non-interactive. */
.entity-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 1.5rem 0 0;
  padding-top: 1.2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
}
.entity-pager-link {
  color: var(--accent);
  text-decoration: none;
  border: 1px solid rgba(184, 255, 60, 0.3);
  border-radius: 4px;
  padding: 8px 14px;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  white-space: nowrap;
}
.entity-pager-link:hover {
  background: rgba(184, 255, 60, 0.08);
  border-color: var(--accent);
}
.entity-pager-link--disabled {
  color: var(--fg-4);
  border-color: rgba(255, 255, 255, 0.08);
  background: transparent;
  pointer-events: none;
  cursor: default;
}
.entity-pager-pos {
  color: var(--fg-3);
  text-align: center;
  flex: 1 1 auto;
}

@media (max-width: 540px) {
  .entity-pager {
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
  }
  .entity-pager-pos { order: -1; flex: 1 1 100%; }
}

