/* ============================================================
   GENZ TECH — "Terminal" brand identity
   Dark monochrome developer-console look, one electric-orange
   signal (#FF4D00), IBM Plex Mono + IBM Plex Sans.
   Tokens & components per the brand handoff README.
   ============================================================ */

:root {
  --void: #0a0b0c;
  --panel: #0e0f11;
  --panel-2: #101216;
  --hairline: #1d1f22;
  --border: #26282b;
  --border-dashed: #3a3d41;
  --signal: #ff4d00;
  --signal-faint: rgba(255, 77, 0, 0.33);
  --bone: #f2f2f0;
  --text-hi: #e7e7e5;
  --body: #c7c8ca;
  --text-mid: #a9abae;
  --mist: #8a8d91;
  --text-low: #7d8084;
  --text-faint: #787b7f;

  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", Consolas, monospace;
  --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  --maxw: 1200px;
  --gutter: 28px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
::selection { background: var(--signal); color: var(--void); }

body {
  font-family: var(--sans);
  background: var(--void);
  color: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }

/* 2px Signal bar pinned to the very top of every page */
.signal-bar { position: fixed; top: 0; left: 0; right: 0; height: 2px; background: var(--signal); z-index: 100; }

/* mono helpers */
.mono { font-family: var(--mono); }
.kicker { font-family: var(--mono); font-weight: 600; font-size: 12px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); }
.label { font-family: var(--mono); font-weight: 600; font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-low); }
.meta { font-family: var(--mono); font-weight: 500; font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-low); }
.sig { color: var(--signal); }

/* @keyframes */
@keyframes blink { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }

/* ---------- Logo / wordmark <genz/>tech ---------- */
.logo { font-family: var(--mono); font-weight: 600; font-size: 20px; letter-spacing: -0.02em; color: var(--bone); white-space: nowrap; display: inline-flex; align-items: baseline; }
.logo .slash { color: var(--signal); }
.logo .tech { color: var(--mist); }
.logo .cursor { width: 0.42em; height: 0.95em; background: var(--signal); display: inline-block; margin-left: 4px; transform: translateY(2px); animation: blink 1.1s steps(1) infinite; }

/* ---------- Top nav ---------- */
header.site { position: sticky; top: 0; z-index: 60; background: rgba(10, 11, 12, 0.9); backdrop-filter: blur(10px); border-bottom: 1px solid var(--hairline); }
.nav { display: flex; align-items: center; gap: 18px; height: 64px; }
/* Category strip: flexible + horizontally scrollable so a long list (12+ topics)
   never pushes the search box / menu button off the right edge. Scrollbar hidden;
   the search + menu stay pinned and always fully visible. */
/* overflow:visible so the "More ▾" dropdown can extend below the nav row.
   (overflow-x:auto would compute overflow-y:auto too and clip the dropdown.)
   The priority+ JS keeps the row from overflowing, so no scroll is needed. */
.nav .cats { display: flex; align-items: center; gap: 10px; margin-left: 2px; min-width: 0; flex: 1 1 auto; overflow: visible; }
.nav .cats a { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-mid); cursor: pointer; transition: color 0.15s; white-space: nowrap; flex-shrink: 0; }
.nav .cats a:hover, .nav .cats a.active { color: var(--bone); }

/* Author profile links (verified external identity — E-E-A-T signal). */
.au-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.au-links a { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-mid); border: 1px solid var(--border); border-radius: 4px; padding: 6px 11px; transition: color 0.15s, border-color 0.15s; }
.au-links a:hover { color: var(--signal); border-color: var(--signal); }

/* Terminal "$ " prefix on section-label headings, kept COSMETIC via CSS ::before
   so the DOM heading text stays semantic/keyword-clean for crawlers (the prompt
   is not part of the heading text Google reads). Matches the orange $ prompt used
   in the nav/search. */
.faq h2::before, .related h2::before, .nl h2::before { content: "$ "; color: var(--signal); }

/* Priority+ overflow: categories that don't fit collapse into this "More ▾"
   dropdown (populated by JS in seo.mjs inlineJs + app.js). Scales to any number
   of topics without shrinking the bar. Hidden until JS finds an overflow. */
.nav .cat-more { position: relative; flex-shrink: 0; display: flex; align-items: center; }
.nav .cat-more[hidden] { display: none; }
.nav .cat-more-btn { display: inline-flex; align-items: center; gap: 4px; padding: 0; background: none; border: 0; cursor: pointer; font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-mid); white-space: nowrap; transition: color 0.15s; }
.nav .cat-more-btn:hover, .nav .cat-more.open .cat-more-btn { color: var(--bone); }
.nav .cat-more-btn .caret { font-size: 9px; }
.nav .cat-more-pop { position: absolute; top: calc(100% + 12px); right: 0; display: none; flex-direction: column; min-width: 168px; background: var(--void); border: 1px solid var(--border); border-radius: 4px; padding: 6px; z-index: 70; box-shadow: 0 12px 34px rgba(0, 0, 0, 0.45); }
.nav .cat-more.open .cat-more-pop { display: flex; }
.nav .cat-more-pop a { font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-mid); padding: 9px 11px; border-radius: 3px; white-space: nowrap; transition: color 0.12s, background 0.12s; }
.nav .cat-more-pop a:hover { color: var(--bone); background: var(--panel-2); }
/* Drawer-only elements: present in #cats for the mobile drawer, hidden on the desktop inline bar. */
.nav .cats .cat-search, .nav .cats .drawer-pages { display: none; }
.nav .spacer { display: none; }
.nav .search { display: flex; align-items: center; gap: 8px; border: 1px solid var(--border); border-radius: 3px; padding: 7px 10px; min-width: 128px; flex-shrink: 0; }
.nav .search .p { font-family: var(--mono); color: var(--signal); font-size: 13px; }
.nav .search input { background: none; border: 0; outline: none; color: var(--bone); font-family: var(--mono); font-size: 13px; width: 100%; }
.nav .search input::placeholder { color: var(--text-faint); }
.nav .menu-wrap { position: relative; flex-shrink: 0; }
.nav .menu-btn { display: flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-mid); background: none; border: 1px solid var(--border); border-radius: 3px; padding: 7px 12px; cursor: pointer; transition: color 0.15s, border-color 0.15s; }
.nav .menu-btn:hover, .nav .menu-btn[aria-expanded="true"] { color: var(--bone); border-color: var(--text-low); }
.nav .menu-btn .caret { color: var(--signal); transition: transform 0.15s; }
.nav .menu-btn[aria-expanded="true"] .caret { transform: rotate(180deg); }
.menu-pop { position: absolute; top: calc(100% + 8px); right: 0; min-width: 180px; background: var(--void); border: 1px solid var(--border); border-radius: 6px; padding: 6px; display: none; flex-direction: column; z-index: 70; box-shadow: 0 14px 34px rgba(0, 0, 0, 0.55); }
.menu-pop.open { display: flex; }
.menu-pop a { font-family: var(--mono); font-size: 13px; color: var(--text-mid); padding: 9px 12px; border-radius: 4px; text-decoration: none; transition: background 0.12s, color 0.12s; }
.menu-pop a:before { content: "/ "; color: var(--signal); }
.menu-pop a:hover { background: var(--panel-2); color: var(--bone); }
.nav-toggle { display: none; background: none; border: 1px solid var(--border); border-radius: 4px; color: var(--bone); font-size: 1.15rem; line-height: 1; cursor: pointer; font-family: var(--mono); padding: 6px 10px; flex-shrink: 0; }
.nav-toggle:hover { border-color: var(--text-low); }

/* ---------- Section heads ---------- */
.sec { padding: 48px 0; border-bottom: 1px solid var(--hairline); }
.sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 28px; flex-wrap: wrap; }
.sec-head .cmd { font-family: var(--mono); font-weight: 600; font-size: 15px; letter-spacing: -0.01em; color: var(--text-hi); margin: 0; }
.sec-head .cmd b { color: var(--signal); font-weight: 600; }
.viewall { font-family: var(--mono); font-size: 12px; color: var(--signal); cursor: pointer; }
.viewall:hover { opacity: 0.85; }
.related-more { display: inline-block; margin-top: 18px; font-family: var(--mono); font-size: 13px; letter-spacing: 0.04em; color: var(--signal); border: 1px solid var(--border); border-radius: 4px; padding: 8px 14px; text-decoration: none; transition: border-color 0.15s, color 0.15s; }
.related-more:hover { border-color: var(--text-low); color: var(--bone); }

/* ---------- Image frame (real photo, dark frame + corner tick) ---------- */
.frame { position: relative; background: var(--panel-2); border: 1px solid var(--border); border-radius: 5px; overflow: hidden; background-size: cover; background-position: center; }
.frame::before { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(135deg, rgba(255,255,255,0.04) 0 14px, transparent 14px 30px); pointer-events: none; opacity: 0.5; z-index: 1; }
.frame::after { content: ""; position: absolute; left: 12px; bottom: 12px; width: 44px; height: 44px; border-left: 2px solid var(--signal); border-bottom: 2px solid var(--signal); opacity: 0.85; pointer-events: none; z-index: 1; }
/* Responsive <img> inside a frame (hero/cards): fill it; the scanline + corner-tick overlays stay on top. */
.frame > .fimg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
/* "GitHub Tool of the Day" cards are 1200x630 banners carrying readable text —
   a tool name and its install command. Cropping them to a card/thumb frame cuts
   ~29% off each side and makes the command unreadable, so they letterbox instead.
   The bars are invisible: the card's own background is the same near-black.
   Attribute selector so this covers the JS-rendered feed too, which builds its
   <img> from post.image and never sees a server-side class. */
.frame > .fimg[src*="/card/"],
.row .r-thumb .fimg[src*="/card/"] { object-fit: contain; background: var(--void); }

/* ---------- Hero ---------- */
.hero { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 44px; align-items: center; padding: 52px 0; border-bottom: 1px solid var(--hairline); }
.hero .h-text .kicker { display: block; margin-bottom: 18px; }
.hero h1 { font-family: var(--mono); font-weight: 600; font-size: clamp(38px, 5vw, 60px); line-height: 1.04; letter-spacing: -0.03em; color: var(--bone); margin-bottom: 20px; }
.hero .dek { font-size: 18px; line-height: 1.6; color: var(--text-mid); max-width: 46ch; margin-bottom: 26px; }
.hero .h-img { aspect-ratio: 4 / 3; }

/* ---------- Buttons ---------- */
.btn { display: inline-flex; align-items: center; gap: 9px; font-family: var(--mono); font-weight: 600; font-size: 13px; letter-spacing: 0.04em; background: var(--signal); color: var(--void); border: 0; padding: 12px 18px; border-radius: 3px; cursor: pointer; transition: filter 0.15s, box-shadow 0.15s; }
.btn:hover { filter: brightness(0.92); box-shadow: 0 0 0 1px var(--signal-faint); }
.btn.ghost { background: transparent; color: var(--text-mid); border: 1px solid var(--border); }
.btn.ghost:hover { color: var(--bone); border-color: var(--border-dashed); filter: none; }
.read { font-family: var(--mono); font-weight: 600; font-size: 13px; letter-spacing: 0.04em; color: var(--signal); display: inline-flex; align-items: center; gap: 8px; cursor: pointer; transition: gap 0.15s; }
.read:hover { gap: 13px; }
.byline { margin-top: 18px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-low); display: flex; gap: 8px; flex-wrap: wrap; }
.byline .author { color: var(--text-mid); }

/* ---------- Top stories cards ---------- */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.card { cursor: pointer; }
.card .c-img { aspect-ratio: 16 / 10; margin-bottom: 16px; transition: transform 0.2s ease; }
.card:hover .c-img { transform: translateY(-3px); }
.card .c-kicker { font-family: var(--mono); font-weight: 600; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-bottom: 9px; display: block; }
.card h3 { font-family: var(--sans); font-weight: 500; font-size: 19px; line-height: 1.28; letter-spacing: -0.01em; color: var(--text-hi); margin-bottom: 9px; }
.card:hover h3 { color: var(--bone); }
.card .dek { font-size: 14.5px; line-height: 1.55; color: var(--text-mid); }
.card .c-meta { margin-top: 12px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-low); }

/* ---------- Latest numbered terminal rows ---------- */
.rows { display: flex; flex-direction: column; }
.row { display: grid; grid-template-columns: 34px 88px 1fr auto; gap: 16px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--hairline); cursor: pointer; }
.row:hover { background: var(--panel); }
.row .idx { font-family: var(--mono); font-weight: 600; font-size: 13px; color: var(--signal); }
.row .r-thumb { width: 88px; aspect-ratio: 16 / 10; border-radius: 4px; overflow: hidden; background: var(--panel-2); border: 1px solid var(--border); }
.row .r-thumb .fimg { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.row:hover .r-thumb .fimg { transform: scale(1.05); }
.row .r-main .r-cat { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-low); margin-bottom: 6px; }
.row .r-main h3 { font-family: var(--sans); font-weight: 500; font-size: 18px; line-height: 1.3; color: var(--text-hi); }
.row:hover .r-main h3 { color: var(--bone); }
.row .r-time { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-low); white-space: nowrap; }
.empty { font-family: var(--mono); font-size: 13px; color: var(--text-faint); padding: 28px 0; }

/* "Load more" reveals the next slice of the already-loaded post array — no
   fetch, just DOM growth — so it can render instantly on click. */
.load-more { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; margin-top: 10px; padding: 15px; font-family: var(--mono); font-weight: 600; font-size: 13px; letter-spacing: 0.04em; color: var(--text-mid); background: none; border: 1px solid var(--border); border-radius: 4px; cursor: pointer; transition: color 0.15s, border-color 0.15s; }
.load-more:hover { color: var(--bone); border-color: var(--text-low); }
.load-more[hidden] { display: none; }
.load-more .lm-count { color: var(--signal); }
.load-more .lm-arrow { color: var(--signal); display: inline-block; transition: transform 0.15s; }
.load-more:hover .lm-arrow { transform: translateY(2px); }

/* ---------- Topics rail ---------- */
.topics { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.topics .t-label { font-family: var(--mono); font-weight: 600; font-size: 13px; color: var(--text-mid); }
.chip { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; color: var(--text-mid); border: 1px solid var(--border); border-radius: 3px; padding: 7px 13px; cursor: pointer; background: none; transition: all 0.15s; }
.chip:hover { color: var(--bone); border-color: var(--border-dashed); }
.chip.active { background: var(--signal); color: var(--void); border-color: var(--signal); font-weight: 600; }

/* ---------- Ad slot ---------- */
/* The wrapper ships with [hidden] and is only revealed once a real ad unit is
   pushed — an empty "Advertisement" box reads as an unfinished site (and is a
   bad look during AdSense review). This rule is belt-and-braces: `hidden` is
   only a default UA style, so any later `display:` here would silently defeat
   it. Keep the [hidden] guard if you touch .ad-wrap. */
.ad-wrap[hidden] { display: none !important; }
.ad-wrap { padding: 40px 0; border-bottom: 1px solid var(--hairline); }
.ad-label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-faint); text-align: center; margin-bottom: 8px; }
.ad-slot { min-height: 100px; display: flex; align-items: center; justify-content: center; background: var(--panel); border: 1px solid var(--border); border-radius: 4px; overflow: hidden; }

/* ---------- Footer ---------- */
footer.site { background: var(--panel); border-top: 1px solid var(--hairline); margin-top: 0; }
.nl { padding: 56px 0; border-bottom: 1px solid var(--hairline); }
.nl h2 { font-family: var(--mono); font-weight: 600; font-size: 30px; letter-spacing: -0.02em; color: var(--bone); margin: 10px 0 12px; }
.nl p { color: var(--text-mid); max-width: 52ch; margin-bottom: 22px; }
.nl form { display: flex; align-items: center; gap: 10px; border: 1px solid var(--border); border-radius: 3px; padding: 6px 6px 6px 14px; max-width: 460px; }
.nl form .p { font-family: var(--mono); color: var(--signal); }
.nl form input { flex: 1; background: none; border: 0; outline: none; color: var(--bone); font-family: var(--mono); font-size: 14px; }
.nl form input::placeholder { color: var(--text-faint); }
.nl .fine { margin-top: 12px; font-family: var(--mono); font-size: 11px; color: var(--text-faint); }
.pref-src { display: inline-flex; align-items: center; gap: 8px; margin-top: 18px; padding: 9px 14px; border: 1px solid var(--hairline); border-radius: 8px; font-family: var(--mono); font-size: 12px; color: var(--text-mid); text-decoration: none; transition: border-color .2s, color .2s, background-color .2s; }
.pref-src:hover { border-color: var(--signal); color: var(--bone); background: rgba(255, 77, 0, 0.08); }
.pref-src strong { color: var(--bone); font-weight: 600; }
.pref-src .ps-star { color: var(--signal); font-size: 13px; line-height: 1; }
.a-cta { margin: 44px 0 8px; padding: 26px 24px; border: 1px solid var(--hairline); border-radius: 14px; background: var(--panel); }
.a-cta .a-cta-k { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--signal); }
.a-cta h3 { font-family: var(--sans); font-weight: 600; font-size: 22px; line-height: 1.2; color: var(--bone); margin: 10px 0 6px; }
.a-cta p { color: var(--text-mid); font-size: 15px; line-height: 1.55; margin: 0 0 16px; max-width: 52ch; }
.a-cta .nl-form { display: flex; align-items: center; gap: 10px; max-width: 460px; padding: 6px 6px 6px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--void); }
.a-cta .nl-form .p { font-family: var(--mono); color: var(--signal); }
.a-cta .nl-form input { flex: 1; min-width: 0; background: none; border: 0; outline: none; color: var(--bone); font-family: var(--mono); font-size: 14px; }
.a-cta .nl-form input::placeholder { color: var(--text-faint); }
.a-cta .nl-form .btn { white-space: nowrap; }
.a-cta .fine { margin-top: 10px; font-family: var(--mono); font-size: 11px; color: var(--text-faint); }
@media (max-width: 480px) { .a-cta .nl-form { flex-wrap: wrap; } .a-cta .nl-form input { width: 100%; flex-basis: 100%; } }

/* Newsletter honeypot. Formspree silently drops any submission whose _gotcha
   field is non-empty; naive form-scrapers fill every input they find. Pulled
   off-screen rather than display:none (some bots skip hidden fields), never
   focusable (tabindex="-1"), and excluded from the WebMCP tool schema because
   it carries no toolparamdescription. !important because .nl form input and
   .a-cta .nl-form input both out-specify a bare input.nl-hp. */
.nl-hp { position: absolute !important; left: -9999px !important; width: 1px !important; height: 1px !important; padding: 0 !important; border: 0 !important; opacity: 0 !important; flex: 0 0 0 !important; pointer-events: none; }
.foot-cols { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 28px; padding: 44px 0; border-bottom: 1px solid var(--hairline); }
.foot-cols .col h3 { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-low); margin: 0 0 16px; }
.foot-cols .col a { display: block; font-size: 14px; color: var(--text-mid); margin-bottom: 10px; }
.foot-cols .col a:hover { color: var(--bone); }
.foot-cols .brand .logo { font-size: 22px; margin-bottom: 14px; }
.foot-cols .brand p { font-size: 13px; color: var(--text-faint); max-width: 32ch; margin-bottom: 14px; }
.foot-bottom { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding: 22px 0; font-family: var(--mono); font-size: 11px; color: var(--text-faint); }

/* ---------- Article ---------- */
.progress { position: fixed; top: 2px; left: 0; height: 2px; width: 0; background: var(--signal); z-index: 99; }
.article { max-width: 720px; margin: 0 auto; padding: 44px 0 56px; }
.article .back { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; color: var(--text-mid); display: inline-block; margin-bottom: 28px; }
.article .back:hover { color: var(--signal); }
.article .a-kicker { display: block; margin-bottom: 14px; }
.article h1 { font-family: var(--mono); font-weight: 600; font-size: clamp(34px, 4.6vw, 52px); line-height: 1.08; letter-spacing: -0.03em; color: var(--bone); margin-bottom: 18px; }
.article .a-dek { font-size: 19px; line-height: 1.6; color: var(--text-mid); margin-bottom: 26px; }
/* Answer-first "gist" box — the direct summary AI answer engines + snippets lift. */
.article .a-gist { position: relative; margin: 4px 0 30px; padding: 18px 22px 18px 24px; background: var(--panel-2); border: 1px solid var(--border); border-left: 3px solid var(--signal); border-radius: 4px; }
.article .a-gist .gist-k { display: block; font-family: var(--mono); font-weight: 600; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-bottom: 8px; }
.article .a-gist p { font-size: 19px; line-height: 1.6; color: var(--text-hi); margin: 0; }
.article .a-byline { display: flex; align-items: center; gap: 14px; padding-bottom: 26px; border-bottom: 1px solid var(--hairline); margin-bottom: 32px; }
.article .a-byline .avatar { width: 44px; height: 44px; border-radius: 4px; background: var(--panel-2); border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; font-family: var(--mono); font-weight: 600; font-size: 15px; color: var(--signal); overflow: hidden; }
.avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
.share { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 44px 0 8px; }
.share .share-label { font-family: var(--mono); font-weight: 600; font-size: 13px; letter-spacing: 0.04em; color: var(--bone); margin-right: 4px; }
.share .sbtn { font-family: var(--mono); font-weight: 500; font-size: 13px; color: var(--text-mid); background: none; border: 1px solid var(--border); border-radius: 4px; padding: 9px 14px; cursor: pointer; text-decoration: none; transition: color 0.12s, border-color 0.12s; }
.share .sbtn:hover { color: var(--bone); border-color: var(--text-low); }
.share .sbtn-copy { color: var(--signal); border-color: rgba(255, 77, 0, 0.45); }
.share .sbtn-copy:hover { color: var(--signal); border-color: var(--signal); }
.share .share-msg { font-family: var(--sans); font-size: 13px; color: var(--signal); margin-left: 4px; }
.article .a-byline .who { font-family: var(--mono); font-size: 12px; }
.article .a-byline .who .name { color: var(--text-hi); }
.article .a-byline .who .role { color: var(--text-low); letter-spacing: 0.05em; text-transform: uppercase; font-size: 11px; margin-top: 3px; }
.article .a-hero { aspect-ratio: 16 / 9; margin-bottom: 10px; }
.article .a-cap { font-family: var(--mono); font-size: 11px; color: var(--text-faint); margin-bottom: 34px; }
.article-body { font-size: 18px; line-height: 1.78; color: var(--body); }
.article-body p { margin-bottom: 24px; }
.article-body h2 { font-family: var(--mono); font-weight: 600; font-size: 15px; letter-spacing: 0.04em; text-transform: lowercase; color: var(--signal); margin: 40px 0 16px; }
.article-body h2::before { content: "// "; color: var(--text-low); }
.article-body ul { list-style: none; margin: 0 0 24px; padding: 0; }
.article-body li { position: relative; padding-left: 22px; margin-bottom: 12px; }
.article-body li::before { content: ""; position: absolute; left: 0; top: 11px; width: 7px; height: 7px; background: var(--signal); }
.article-body blockquote { font-family: var(--mono); font-weight: 500; font-size: 25px; line-height: 1.4; letter-spacing: -0.02em; color: var(--bone); border-left: 3px solid var(--signal); padding-left: 22px; margin: 32px 0; }
.article-body strong { color: var(--text-hi); font-weight: 600; }
.article-body a { color: var(--signal); }
/* Contextual in-body "Related" link (internal linking for SEO + readers). */
.article-body .inline-rel { display: flex; align-items: baseline; gap: 10px; margin: 6px 0 24px; padding: 12px 16px; background: var(--panel-2); border-left: 2px solid var(--border-dashed); border-radius: 3px; font-size: 16px; }
.article-body .inline-rel .ir-k { font-family: var(--mono); font-weight: 600; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-low); flex: none; }
.article-body .inline-rel a { color: var(--text-hi); }
.article-body .inline-rel a:hover { color: var(--signal); }
.article-body a:hover { text-decoration: underline; }
.article-body .src { font-family: var(--mono); font-size: 13px; color: var(--text-faint); margin-top: 32px; }

/* Recency block at the top of /funding-tracker/ ("announced this week").
   Each raise is its own record with the company name as a real heading — a
   left rule and a mono meta line keep it reading as tracker data rather than
   prose, without repeating the full table's card treatment below it. */
.fund-recent { margin: 0 0 40px; display: grid; gap: 2px; }
.fr-item { position: relative; padding: 18px 20px; background: var(--panel-2); border-left: 2px solid var(--border-dashed); transition: border-color 140ms ease, background 140ms ease; }
.fr-item:hover { border-left-color: var(--signal); background: var(--panel); }
.fr-item:first-child { border-left-color: var(--signal); }
.article-body .fr-co { font-family: var(--mono); font-weight: 600; font-size: 17px; letter-spacing: -0.01em; text-transform: none; color: var(--bone); margin: 0 0 6px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.article-body .fr-co::before { content: none; }
.article-body .fr-co a { color: inherit; }
.article-body .fr-co a:hover { color: var(--signal); text-decoration: none; }
.fr-amt { font-size: 13px; font-weight: 500; color: var(--signal); letter-spacing: 0.02em; }
.article-body .fr-meta { font-family: var(--mono); font-size: 11.5px; line-height: 1.6; letter-spacing: 0.03em; color: var(--text-low); margin: 0 0 10px; overflow-wrap: anywhere; }
.article-body .fr-what { font-size: 15.5px; line-height: 1.62; color: var(--body); margin: 0; }
.article-body .fr-more { font-family: var(--mono); font-size: 12px; white-space: nowrap; }
@media (max-width: 600px) {
  .fr-item { padding: 15px 16px; }
  .article-body .fr-co { font-size: 15.5px; }
  .article-body .fr-what { font-size: 15px; }
}

.tags { display: flex; gap: 10px; flex-wrap: wrap; margin: 36px 0; }
.tagline-foot { margin-top: 44px; padding-top: 24px; border-top: 1px solid var(--hairline); font-family: var(--mono); font-size: 12px; color: var(--text-faint); }

/* ---------- Category page ---------- */
.cat-masthead { padding: 48px 0; border-bottom: 1px solid var(--hairline); }
.cat-masthead .crumb { font: 600 12px/1 var(--mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-low); margin-bottom: 16px; }
.cat-title { font: 600 clamp(46px, 7vw, 84px)/0.96 var(--mono); letter-spacing: -0.04em; color: var(--bone); }
.cat-title .dot-sig { color: var(--signal); }
.cat-desc { font: 400 17px/1.6 var(--sans); color: var(--text-mid); max-width: 54ch; margin-top: 16px; }
.cat-count { font: 500 12px/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-low); margin-top: 16px; }
.cat-count .live { color: var(--text-mid); }
.cat-count .live .dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 8px rgba(255,77,0,.9); margin-right: 4px; }
.cat-grid { display: grid; grid-template-columns: 1fr 300px; gap: 48px; padding: 44px 0; }
.cat-main .cards { grid-template-columns: 1fr 1fr; }
.cat-side { position: sticky; top: 88px; align-self: start; }
.cat-side h4 { font: 600 13px/1 var(--mono); color: var(--text-hi); margin-bottom: 8px; }
.cat-side h4 b { color: var(--signal); font-weight: 600; }
.side-row { display: grid; grid-template-columns: 28px 1fr; gap: 8px; padding: 14px 0; border-bottom: 1px solid var(--hairline); }
.side-row .idx { font: 600 13px/1.4 var(--mono); color: var(--signal); }
.side-row a { font: 500 14px/1.35 var(--sans); color: var(--text-hi); }
.side-row a:hover { color: var(--bone); }
.side-cta { margin-top: 24px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 5px; padding: 20px; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 28px; }
  .cards { grid-template-columns: 1fr 1fr; }
  .foot-cols { grid-template-columns: 1fr 1fr; }
  .cat-grid { grid-template-columns: 1fr; gap: 32px; }
  .cat-side { position: static; }
}
/* The 9-item inline category bar + search need ~1201px, so collapse them into
   the hamburger menu below ~1240px (not just on phones) to stop the overflow. */
@media (max-width: 1240px) {
  /* Collapse the whole nav into one ☰ button that opens a drawer with search + topics + pages. */
  .nav .cats, .nav .search, .nav .util, .nav .menu-wrap { display: none; }
  .nav-toggle { display: block; }
  .nav .cats.open { display: flex; flex-direction: column; align-items: stretch; position: absolute; top: 64px; left: 0; right: 0; background: var(--void); border-bottom: 1px solid var(--hairline); padding: 16px var(--gutter) 22px; gap: 2px; z-index: 60; max-height: calc(100vh - 64px); overflow: hidden auto; }
  .nav .cats.open a { font-size: 15px; padding: 11px 2px; letter-spacing: 0.08em; }
  /* The desktop "More" overflow is meaningless in the drawer (every topic already lists). */
  .nav .cat-more { display: none; }
  /* search field at top of the drawer */
  .nav .cats.open .cat-search { display: flex; align-items: center; gap: 8px; border: 1px solid var(--border); border-radius: 4px; padding: 11px 12px; margin-bottom: 10px; }
  .nav .cats.open .cat-search .p { color: var(--signal); font-family: var(--mono); font-size: 14px; }
  .nav .cats.open .cat-search input { background: none; border: 0; outline: none; color: var(--bone); font-family: var(--mono); font-size: 15px; width: 100%; }
  .nav .cats.open .cat-search input::placeholder { color: var(--text-faint); }
  /* page links section below the topics */
  .nav .cats.open .drawer-pages { display: flex; flex-direction: column; gap: 0; margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--hairline); }
  .nav .cats.open .drawer-pages .drawer-lbl { font-family: var(--mono); font-size: 11px; color: var(--text-faint); letter-spacing: 0.12em; padding: 6px 2px 6px; }
  .nav .cats.open .drawer-pages a { color: var(--text-mid); font-size: 14px; padding: 10px 2px; text-transform: none; letter-spacing: 0; }
}
@media (max-width: 720px) {
  .cards { grid-template-columns: 1fr; }
  .row { grid-template-columns: 28px 1fr; }
  .row .r-thumb { display: none; }
  .row .r-time { display: none; }
  .foot-cols { grid-template-columns: 1fr; }
}

/* CLS: reserve space for JS-rendered regions so the homepage/SPA doesn't shift
   while app.js fills them (measured at Lighthouse desktop 1350px + mobile 390px). */
#nav-root { min-height: 64px; }
#hero { min-height: 650px; }
/* #topstories now holds 8 cards. Reservations follow the .cards GRID breakpoints
   (3-col >900, 2-col ≤900, 1-col ≤720) and are sized to each band's TALLEST case
   so a JS-fill never pushes visible content down (CLS=0). On mobile (≤720) the
   section sits below the fold, so it fills off-screen — reserving there would only
   add permanent whitespace, so it's dropped. Re-measure if the card layout changes. */
#topstories { min-height: 1590px; } /* 3-col × 3 rows (content caps at 1200px) */
.ad-slot { min-height: 90px; }
@media (max-width: 980px) { #hero { min-height: 700px; } }
@media (max-width: 900px) { #topstories { min-height: 2690px; } } /* 2-col × 5 rows */
@media (max-width: 760px) { #hero { min-height: 820px; } }
@media (max-width: 720px) { #topstories { min-height: 0; } }      /* 1-col, below fold: fill off-screen, no reserve */
@media (max-width: 560px) { #hero { min-height: 920px; } }

/* Self-hosted IBM Plex (latin, woff2) — no third-party render-blocking. */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/fonts/plex-mono-400.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/fonts/plex-mono-500.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url('/fonts/plex-mono-600.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;src:url('/fonts/plex-sans-400.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;src:url('/fonts/plex-sans-500.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;src:url('/fonts/plex-sans-600.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:700;font-display:swap;src:url('/fonts/plex-sans-700.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}


/* ─── Deep-dive components ─────────────────────────────────────────────────
   Reusable analysis building blocks: inline-SVG figures, comparison matrix,
   timeline, prediction callout, primary-sources block. Terminal brand — mono
   labels, Signal-orange accent, panel fills, hairline rules. Safe inside an
   article's `content` HTML (renders identically in the SPA and prerendered /p/). */
.article-body .tp-k { font-family: var(--mono); font-weight: 600; font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); }

/* Figure wrapper for inline SVG diagrams / charts */
.article-body .tp-figure { margin: 34px 0; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); overflow: hidden; }
.article-body .tp-figure__frame { padding: 22px 22px 6px; }
.article-body .tp-figure svg { display: block; width: 100%; height: auto; }
.article-body .tp-figure figcaption { font-family: var(--sans); font-size: 13.5px; line-height: 1.55; color: var(--text-mid); margin: 6px 0 0; padding: 13px 22px 16px; border-top: 1px solid var(--hairline); }
.article-body .tp-figure figcaption b { color: var(--text-hi); font-weight: 600; }
.article-body figcaption .tp-k { margin-right: 9px; }
/* In-article reel (2:1, matches the hero image ratio). Sits between the hero and the body. */
/* In-article video. Replaced the self-hosted .tp-reel player on 2026-09-10 when
   the reels moved to YouTube (see videoEmbed() in scripts/seo.mjs). 16/9 because
   that is the YouTube player's frame regardless of what the source was, and the
   ratio is set on the button too so the box is reserved before the poster loads
   and the swap to the iframe causes no layout shift. */
.article .tp-yt { margin: 34px 0; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); overflow: hidden; }
.article .tp-yt__btn { display: block; position: relative; width: 100%; aspect-ratio: 16 / 9; padding: 0; border: 0; border-radius: 6px 6px 0 0; background-color: #0a0b0c; background-size: cover; background-position: center; cursor: pointer; }
.article .tp-yt__btn::after { content: ""; position: absolute; inset: 0; background: rgba(10, 11, 12, 0.32); transition: background 0.15s ease; }
.article .tp-yt__btn:hover::after,
.article .tp-yt__btn:focus-visible::after { background: rgba(10, 11, 12, 0.14); }
.article .tp-yt__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1; width: 72px; height: 50px; border-radius: 10px; background: var(--signal); transition: transform 0.15s ease; }
.article .tp-yt__play::before { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-42%, -50%); border-style: solid; border-width: 11px 0 11px 18px; border-color: transparent transparent transparent #0a0b0c; }
.article .tp-yt__btn:hover .tp-yt__play { transform: translate(-50%, -50%) scale(1.06); }
.article .tp-yt__dur { position: absolute; right: 12px; bottom: 12px; z-index: 1; font-family: var(--mono); font-size: 11.5px; color: var(--bone); background: rgba(10, 11, 12, 0.78); padding: 3px 7px; border-radius: 3px; }
.article .tp-yt__f { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: 6px 6px 0 0; background: #0a0b0c; }
.article .tp-yt figcaption { font-family: var(--sans); font-size: 13.5px; line-height: 1.55; color: var(--text-mid); padding: 13px 22px 16px; border-top: 1px solid var(--hairline); }
.article .tp-yt figcaption a { color: var(--signal); text-decoration: none; }
.article .tp-yt figcaption a:hover { text-decoration: underline; }
.article .tp-yt .tp-k { font-family: var(--mono); font-weight: 600; font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-right: 9px; }

/* Terminal code blocks (tutorials: install/setup commands). <pre><code> = block,
   bare <code> in prose = inline chip. .p = non-selectable $ prompt, .c = comment. */
.article-body pre { margin: 26px 0; padding: 16px 18px; background: var(--void); border: 1px solid var(--border); border-radius: 6px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.article-body pre code { display: block; font-family: var(--mono); font-size: 13px; line-height: 1.75; color: var(--text-hi); white-space: pre; }
.article-body pre .p { color: var(--signal); user-select: none; }
.article-body pre .c { color: var(--text-faint); }
/* One-click copy button on every code block (added by inlineJs / app.js). The
   button lives on a relative wrapper, NOT the pre itself, so it stays pinned
   top-right while the code scrolls horizontally inside the pre. */
.article-body .code-block { position: relative; margin: 26px 0; }
.article-body .code-block > pre { margin: 0; }
.code-copy { position: absolute; top: 8px; right: 8px; z-index: 2; font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; color: var(--text-low); background: var(--panel-2); border: 1px solid var(--border); border-radius: 5px; padding: 4px 9px; cursor: pointer; opacity: 0.6; transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease; }
.code-block:hover .code-copy, .code-copy:focus-visible { opacity: 1; }
.code-copy:hover { color: var(--signal); border-color: var(--signal); }
.code-copy.copied { color: var(--signal); border-color: var(--signal); opacity: 1; }
@media (hover: none) { .code-copy { opacity: 0.85; } }
.article-body p code, .article-body li code, .article-body h2 code, .article-body h3 code { font-family: var(--mono); font-size: 0.88em; color: var(--text-hi); background: var(--panel-2); border: 1px solid var(--hairline); border-radius: 4px; padding: 1.5px 6px; overflow-wrap: anywhere; }

/* Comparison matrix (horizontally scrollable on small screens) */
.article-body .tp-scroll { margin: 30px 0; overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--border); border-radius: 6px; }
.article-body .tp-compare { width: 100%; min-width: 660px; border-collapse: collapse; font-family: var(--sans); font-size: 14.5px; }
.article-body .tp-compare th, .article-body .tp-compare td { text-align: left; vertical-align: top; padding: 12px 16px; border-bottom: 1px solid var(--hairline); }
.article-body .tp-compare thead th { font-family: var(--mono); font-weight: 600; font-size: 10.5px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-low); background: var(--panel-2); border-bottom: 1px solid var(--border); }
.article-body .tp-compare thead th.col-lb { color: var(--signal); }
.article-body .tp-compare tbody th { font-family: var(--mono); font-weight: 600; font-size: 12px; letter-spacing: 0.02em; color: var(--text-hi); white-space: nowrap; }
.article-body .tp-compare td { color: var(--text-mid); }
.article-body .tp-compare .col-lb { background: rgba(255, 77, 0, 0.06); color: var(--text-hi); }
.article-body .tp-compare tbody tr:last-child th, .article-body .tp-compare tbody tr:last-child td { border-bottom: 0; }

/* Timeline (semantic ordered list; dashed rail for future milestones) */
.article-body .tp-timeline { list-style: none; margin: 30px 0; padding: 4px 0 0; }
.article-body .tp-timeline li { position: relative; margin: 0; padding: 0 0 22px 30px; border-left: 1px solid var(--border); }
.article-body .tp-timeline li::before { content: ""; position: absolute; left: -5px; top: 4px; width: 9px; height: 9px; border-radius: 50%; background: var(--void); border: 2px solid var(--text-low); }
.article-body .tp-timeline li.is-future { border-left-style: dashed; }
.article-body .tp-timeline li.is-future::before { border-color: var(--signal); }
.article-body .tp-timeline li:last-child { padding-bottom: 2px; }
.article-body .tp-timeline .tl-date { display: block; font-family: var(--mono); font-weight: 600; font-size: 11px; letter-spacing: 0.06em; color: var(--signal); margin-bottom: 3px; }
.article-body .tp-timeline .tl-event { color: var(--text-hi); font-weight: 600; }
.article-body .tp-timeline .tl-note { color: var(--text-mid); }

/* Prediction / what-to-watch callout */
.article-body .tp-verdict { margin: 32px 0; padding: 20px 22px; background: var(--panel-2); border: 1px solid var(--border); border-left: 3px solid var(--signal); border-radius: 4px; }
.article-body .tp-verdict > .tp-k { display: block; margin-bottom: 13px; }
.article-body .tp-verdict ul { margin: 0; }
.article-body .tp-verdict li { margin-bottom: 11px; color: var(--text-mid); }
.article-body .tp-verdict li:last-child { margin-bottom: 0; }
.article-body .tp-verdict li b { color: var(--text-hi); font-weight: 600; }

/* Inline download / call-to-action */
.article-body .tp-cta { margin: 26px 0; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.article-body .tp-cta .tp-btn { display: inline-flex; align-items: center; gap: 9px; font: 600 14px/1 var(--mono); letter-spacing: 0.03em; background: var(--signal); color: var(--void); padding: 14px 22px; border-radius: 4px; text-decoration: none; transition: filter 0.15s, box-shadow 0.15s; }
.article-body .tp-cta .tp-btn:hover { filter: brightness(0.92); box-shadow: 0 0 0 1px var(--signal-faint); text-decoration: none; }
.article-body .tp-cta .tp-cta-note { font: 400 13.5px/1.4 var(--sans); color: var(--text-mid); }

/* Primary-sources block */
.article-body .tp-sources { margin: 34px 0 8px; padding: 20px 22px; background: var(--panel); border: 1px solid var(--border); border-radius: 6px; }
.article-body .tp-sources > .tp-k { display: block; margin-bottom: 14px; }
.article-body .tp-sources ul { margin: 0; }
.article-body .tp-sources li { display: flex; gap: 12px; align-items: baseline; margin: 0; padding: 11px 0; border-top: 1px solid var(--hairline); }
.article-body .tp-sources li::before { display: none; }
.article-body .tp-sources li:first-child { padding-top: 0; border-top: 0; }
.article-body .tp-sources .src-t { flex: none; width: 76px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-low); padding-top: 3px; }
.article-body .tp-sources a { color: var(--text-hi); font-weight: 600; }
.article-body .tp-sources a:hover { color: var(--signal); }
.article-body .tp-sources .src-d { color: var(--text-faint); font-weight: 400; }

/* ---- AI Coding Leaderboard ------------------------------------------------- */
.lb-masthead .cat-desc b { color: var(--text-hi); font-weight: 600; }
/* the leaderboard article runs FULL wrap width (1144px) so the standings table
   fits without horizontal scroll on desktop; text blocks stay readable via ch caps */
.article.lb-article { max-width: none; border: 0; }
.lb-article .a-gist p { max-width: 78ch; }
.lb-article .a-gist .gist-k { color: var(--signal); }
.lb-article .faq, .lb-article .share { max-width: 900px; }
/* standings table — extends .tp-compare, scoped to win the cascade */
.article-body .lb-table { min-width: 840px; width: 100%; }
.article-body .lb-table thead th { white-space: nowrap; }
.article-body .lb-table .lb-rankcell { width: 46px; text-align: center; vertical-align: middle; }
.article-body .lb-table .lb-rank { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; font-family: var(--mono); font-weight: 600; font-size: 13px; color: var(--void); background: var(--signal); border-radius: 5px; }
.article-body .lb-table .lb-tr:not(.is-leader) .lb-rank { color: var(--text-hi); background: var(--border); }
.article-body .lb-table .lb-verifying { display: inline-block; font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-low); border: 1px solid var(--border-dashed); border-radius: 999px; padding: 3px 6px; white-space: nowrap; }
.article-body .lb-table .lb-model { min-width: 180px; max-width: 260px; padding-top: 14px; }
/* the trackers run up to 9 columns; 16px side padding alone cost ~50px of table
   width, which is the difference between fitting the 1144px article and clipping */
.article-body .lb-table th, .article-body .lb-table td { padding: 12px 13px; }
.article-body .lb-table .lb-name { color: var(--bone); font-family: var(--sans); font-weight: 600; font-size: 15.5px; }
/* was white-space:nowrap — the funding tracker feeds a full sentence in here, and
   nowrap turned the Company column into 5897px (table 7272px vs a 1142px holder).
   Wrapping + a max-width means no data source can blow the layout out again. */
.article-body .lb-table .lb-maker { display: block; margin-top: 3px; font-family: var(--mono); font-weight: 500; font-size: 11px; line-height: 1.45; letter-spacing: 0.02em; color: var(--text-low); white-space: normal; overflow-wrap: anywhere; }
.article-body .lb-table .lb-open { display: inline-block; margin-left: 6px; font-family: var(--mono); font-size: 9px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--signal); border: 1px solid var(--signal-faint); border-radius: 3px; padding: 1px 5px; vertical-align: middle; }
.article-body .lb-table .lb-src { margin-left: 5px; color: var(--text-low); text-decoration: none; font-size: 12px; }
.article-body .lb-table .lb-src:hover { color: var(--signal); }
.article-body .lb-table .lb-score { font-family: var(--mono); font-weight: 600; font-size: 15px; color: var(--text-hi); white-space: nowrap; }
.article-body .lb-table td.lb-score.col-lb { color: var(--signal); }
.article-body .lb-table .lb-dash { color: var(--text-faint); font-weight: 400; }
.article-body .lb-table .lb-price { font-family: var(--mono); font-weight: 600; font-size: 14px; color: var(--text-hi); white-space: nowrap; }
.article-body .lb-table .lb-u { color: var(--text-low); font-weight: 400; font-size: 11px; }
.article-body .lb-table .lb-for { min-width: 200px; max-width: 300px; color: var(--text-mid); font-size: 14px; line-height: 1.5; }
/* Column behaviour for the tracker tables. Only atomic values (scores, money,
   dates) stay nowrap; anything that can hold a phrase wraps and is width-capped,
   so a single long value can never widen the table past its holder again. */
.article-body .lb-table .lb-wrap { color: var(--text-mid); font-size: 14px; line-height: 1.5; min-width: 96px; max-width: 170px; }
.article-body .lb-table .lb-tag { font-family: var(--mono); font-size: 12px; line-height: 1.45; color: var(--text-mid); min-width: 88px; max-width: 140px; }
.article-body .lb-table .lb-date { font-family: var(--mono); font-size: 12.5px; color: var(--text-mid); white-space: nowrap; }
.article-body .lb-table .lb-val { font-family: var(--mono); font-size: 13.5px; color: var(--text-hi); min-width: 84px; max-width: 116px; }
.article-body .lb-table .lb-srct { display: none; }
/* visible scroll affordance for the 720-1144px band, where a wide table still
   scrolls: the default overlay scrollbar gave no hint the row continued. */
.article-body .tp-scroll { scrollbar-width: thin; scrollbar-color: var(--text-low) var(--panel-2); }
.article-body .tp-scroll::-webkit-scrollbar { height: 10px; }
.article-body .tp-scroll::-webkit-scrollbar-track { background: var(--panel-2); border-radius: 0 0 6px 6px; }
.article-body .tp-scroll::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.article-body .tp-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-low); }
.article-body .lb-table .lb-rownote { display: block; margin-top: 7px; font-family: var(--mono); font-size: 11px; line-height: 1.5; color: var(--text-faint); }
.article-body .lb-table .lb-notemore { color: var(--text-low); text-decoration: none; white-space: nowrap; border-bottom: 1px dotted var(--border); }
.article-body .lb-table .lb-notemore:hover { color: var(--signal); border-bottom-color: var(--signal); }
.article-body .lb-table .lb-tr.is-leader th, .article-body .lb-table .lb-tr.is-leader td { background: rgba(255, 77, 0, 0.06); }
.article-body .lb-table .lb-tr.is-pending .lb-name { color: var(--text-mid); }
.article-body .lb-note { font-family: var(--mono); font-size: 12.5px; line-height: 1.6; color: var(--text-faint); margin: 16px 2px 6px; padding: 0; max-width: 92ch; }
.article-body .lb-note::before { content: "// "; color: var(--text-low); }
/* picks grid */
.article-body .lb-picks { display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr)); gap: 14px; margin: 6px 0; }
.article-body .lb-pick { padding: 18px 18px 16px; background: var(--panel); border: 1px solid var(--border); border-top: 2px solid var(--signal); border-radius: 6px; }
.article-body .lb-pick .tp-k { display: block; margin-bottom: 10px; }
.article-body .lb-pick .lb-pick-m { display: block; font-family: var(--sans); font-weight: 600; font-size: 17px; color: var(--bone); margin-bottom: 6px; }
.article-body .lb-pick p { margin: 0; padding: 0; font-size: 13.5px; line-height: 1.55; color: var(--text-mid); }
.article-body .lb-pick p::before { content: none; }

/* ---- homepage leaderboard ticker (stock-ticker strip under the nav) -------- */
.lb-ticker { display: flex; align-items: stretch; height: 40px; background: var(--panel); border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--border); text-decoration: none; overflow: hidden; position: relative; z-index: 1; }
.lb-ticker__tag { flex: none; display: inline-flex; align-items: center; gap: 8px; padding: 0 16px; background: var(--void); border-right: 1px solid var(--border); font: 600 11px/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--signal); white-space: nowrap; }
.lb-ticker__tag .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 8px rgba(255, 77, 0, 0.9); animation: tick-pulse 1.6s ease-in-out infinite; }
.lb-ticker__mask { flex: 1 1 auto; min-width: 0; overflow: hidden; display: flex; align-items: center; }
.lb-ticker__track { display: inline-flex; align-items: center; flex: none; width: max-content; white-space: nowrap; will-change: transform; animation: ticker-scroll 46s linear infinite; }
.lb-ticker:hover .lb-ticker__track { animation-play-state: paused; }
.lb-tick { display: inline-flex; align-items: baseline; gap: 9px; padding: 0 20px; border-right: 1px solid var(--hairline); }
.lb-tick__r { font: 600 11px/1 var(--mono); color: var(--signal); letter-spacing: 0.04em; }
.lb-tick__n { font: 600 13px/1 var(--sans); color: var(--bone); letter-spacing: -0.01em; }
.lb-tick__o { font: 600 8.5px/1 var(--mono); letter-spacing: 0.06em; color: var(--signal); border: 1px solid var(--signal-faint); border-radius: 3px; padding: 2px 4px; align-self: center; }
.lb-tick__v { display: inline-flex; align-items: center; gap: 3px; font: 600 13px/1 var(--mono); color: var(--text-hi); }
.lb-tick__v i { font-style: normal; font-size: 8px; color: var(--signal); }
.lb-tick__d { font: 500 11px/1 var(--mono); color: var(--text-low); }
.lb-ticker__cta { flex: none; display: inline-flex; align-items: center; padding: 0 16px; background: var(--void); border-left: 1px solid var(--border); font: 600 11px/1 var(--mono); letter-spacing: 0.06em; color: var(--text-mid); white-space: nowrap; transition: color var(--dur, 150ms) ease; }
.lb-ticker:hover .lb-ticker__cta { color: var(--signal); }
@keyframes ticker-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes tick-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
@media (max-width: 560px) { .lb-ticker__cta { display: none; } .lb-ticker__tag { padding: 0 12px; } }
@media (prefers-reduced-motion: reduce) { .lb-ticker__track { animation: none; } .lb-ticker__tag .dot { animation: none; } }

/* ---- homepage tools showcase ("$ ls ./tools") ------------------------------
   Baked at build time (seo.homeTools + injectHomeTools), same recipe as the
   ticker above: static HTML, no app.js render pass, crawlable, no CLS. */
.tools-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.tool-card { display: flex; flex-direction: column; padding: 22px 24px 20px; background: var(--panel); border: 1px solid var(--border); border-left: 3px solid var(--signal-faint); border-radius: 6px; text-decoration: none; transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s; }
.tool-card:hover { border-color: var(--text-low); border-left-color: var(--signal); transform: translateY(-3px); box-shadow: 0 14px 30px rgba(0, 0, 0, 0.4), 0 0 0 1px var(--signal-faint); }
.tc-kicker { display: block; font-family: var(--mono); font-weight: 600; font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-bottom: 12px; }
.tc-title { display: block; font-family: var(--sans); font-weight: 600; font-size: 18px; letter-spacing: -0.01em; color: var(--bone); margin-bottom: 8px; }
.tc-stat { display: block; font-family: var(--mono); font-weight: 600; font-size: 15px; color: var(--text-hi); margin-bottom: 10px; }
.tc-desc { flex: 1; font-size: 14px; line-height: 1.55; color: var(--text-mid); margin: 0 0 16px; }
.tc-cta { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; color: var(--text-low); transition: color 0.15s, gap 0.15s; }
.tool-card:hover .tc-cta { color: var(--signal); gap: 10px; }
/* Declared after the base rule (not inside the shared ---- Responsive ---- block
   above) so it actually wins the cascade at equal specificity — an earlier
   conditional rule loses to a later unconditional one with the same selector. */
@media (max-width: 900px) { .tools-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 720px) { .tools-grid { grid-template-columns: 1fr; } }

/* ---- pillar hubs (category pages) ------------------------------------------ */
.pillar-intro { font: 400 18px/1.7 var(--sans); color: var(--body); max-width: 66ch; margin: 16px 0 0; }
.cat-masthead .pillar-intro + .cat-count { margin-top: 16px; }
.pillar-cta { display: block; margin: 22px 0 0; padding: 16px 20px; background: var(--panel); border: 1px solid var(--border); border-left: 3px solid var(--signal); border-radius: 6px; text-decoration: none; max-width: 640px; transition: border-color 0.15s; }
.pillar-cta:hover { border-color: var(--text-low); }
.pillar-cta .tp-k { display: block; font: 600 10px/1 var(--mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-bottom: 8px; }
.pillar-cta__t { display: block; font: 600 17px/1.2 var(--sans); color: var(--bone); margin-bottom: 5px; }
.pillar-cta__d { display: block; font: 400 14px/1.55 var(--sans); color: var(--text-mid); }
.pillar-pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 32px 0 8px; padding-top: 20px; border-top: 1px solid var(--hairline); }
.pillar-pager a, .pillar-pager__disabled { font: 500 13px/1 var(--mono); text-decoration: none; padding: 8px 13px; border: 1px solid var(--border); border-radius: 4px; transition: color 0.15s, border-color 0.15s; }
.pillar-pager a { color: var(--text-mid); }
.pillar-pager a:hover { color: var(--signal); border-color: var(--text-low); }
.pillar-pager__disabled { color: var(--text-low); opacity: 0.4; cursor: default; }
.pillar-pager__pos { font: 600 11px/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-low); }
.pillar-more { margin: 44px 0 8px; padding-top: 24px; border-top: 1px solid var(--hairline); }
.pillar-more .tp-k { display: block; font: 600 10px/1 var(--mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-low); margin-bottom: 14px; }
.pillar-more__links { display: flex; flex-wrap: wrap; gap: 10px; }
.pillar-more__links a { font: 500 13px/1 var(--mono); color: var(--text-mid); text-decoration: none; padding: 8px 13px; border: 1px solid var(--border); border-radius: 4px; transition: color 0.15s, border-color 0.15s; }
.pillar-more__links a:hover { color: var(--signal); border-color: var(--text-low); }

/* Pillar hubs (DePIN / Web3 / Memecoin): head-term explainer + curated series.
   The series sits above the reverse-chron feed and is styled as a deliberate
   reading order, not another card grid, so the two sections read differently. */
.pillar-body { max-width: 66ch; margin: 14px 0 0; }
.pillar-body p { font: 400 16px/1.75 var(--sans); color: var(--text-mid); margin: 0 0 12px; }
.pillar-body p:last-child { margin-bottom: 0; }

.pillar-series { margin: 40px 0 8px; padding: 26px 28px; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; }
.pillar-series h2 { font: 600 13px/1 var(--mono); letter-spacing: 0.14em; text-transform: uppercase; color: var(--signal); margin: 0 0 10px; }
.pillar-series__lede { font: 400 15px/1.6 var(--sans); color: var(--text-mid); margin: 0 0 20px; max-width: 60ch; }
.pillar-series__list { list-style: none; counter-reset: step; margin: 0; padding: 0; display: grid; gap: 2px; }
.pillar-series__list li { counter-increment: step; border-top: 1px solid var(--border); }
.pillar-series__list li:first-child { border-top: 0; }
.pillar-series__list a { display: grid; grid-template-columns: 2.4rem 1fr; align-items: baseline; gap: 4px; padding: 13px 6px 13px 0; text-decoration: none; font: 400 16px/1.45 var(--sans); color: var(--body); border-radius: 4px; transition: color 0.15s, background-color 0.15s; }
.pillar-series__list a::before { content: counter(step, decimal-leading-zero); font: 600 12px/1.45 var(--mono); color: var(--text-low); transition: color 0.15s; }
.pillar-series__list a:hover { color: var(--signal); background: rgba(255, 255, 255, 0.02); }
.pillar-series__list a:hover::before { color: var(--signal); }

.pillar-series__more { margin: 18px 0 0; font: 500 14px/1 var(--mono); }
.pillar-series__more a { color: var(--text-mid); text-decoration: none; transition: color 0.15s; }
.pillar-series__more a:hover { color: var(--signal); }

.pillar-feed-h { font: 600 13px/1 var(--mono); letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-low); margin: 44px 0 18px; }

@media (max-width: 560px) {
  .pillar-series { padding: 20px 18px; }
  .pillar-series__list a { grid-template-columns: 2rem 1fr; font-size: 15px; }
}

/* ---- article -> leaderboard callout + comparison tables -------------------- */
.lb-callout { margin: 26px 0; padding: 16px 20px; background: var(--panel-2); border: 1px solid var(--border); border-left: 3px solid var(--signal); border-radius: 4px; max-width: 720px; }
.lb-callout .tp-k { display: block; font: 600 10px/1 var(--mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); margin-bottom: 9px; }
.lb-callout p { margin: 0; font: 400 15px/1.6 var(--sans); color: var(--text-mid); }
.lb-callout a { color: var(--signal); font-weight: 600; }
.lb-callout a:hover { text-decoration: underline; }
.article-body .cmp-table { min-width: 480px; }

/* ---- cite & embed block (leaderboard) ------------------------------------- */
.article-body .cite-box { margin: 10px 0 4px; display: grid; gap: 10px; }
/* min-width:0 on the GRID ITEM, not just the <code>: a grid item defaults to
   min-width:auto, so the nowrap citation string (~1590px) set the row's floor and
   pushed the whole leaderboard page into horizontal scroll (+424px desktop,
   +1361px mobile). The code element's own min-width:0 could never win that. */
.article-body .cite-row { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; min-width: 0; }
.article-body .cite-row .tp-k { flex: none; align-self: center; width: 52px; }
.article-body .cite-row code { flex: 1 1 320px; min-width: 0; overflow-x: auto; white-space: nowrap; font-family: var(--mono); font-size: 12.5px; color: var(--text-hi); background: var(--void); border: 1px solid var(--border); border-radius: 5px; padding: 11px 13px; }
.article-body .cite-btn { flex: none; font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-mid); background: var(--panel-2); border: 1px solid var(--border); border-radius: 5px; padding: 8px 14px; cursor: pointer; transition: color 0.15s, border-color 0.15s; }
.article-body .cite-btn:hover { color: var(--signal); border-color: var(--text-low); }

/* ---- data API docs (/api/) ------------------------------------------------
   Four small primitives the API table needs. Declared here, ABOVE the trailing
   responsive block, so the `lb-cards` card reflow below still wins on source
   order at narrow widths (see the note at the end of this file). */
.lb-sub { display: block; font: 400 12px/1.45 var(--sans); color: var(--text-low); margin-top: 5px; font-weight: 400; letter-spacing: 0; text-transform: none; }
.lb-dim { color: var(--text-low); }
.article-body .api-id { font: 600 11px/1 var(--mono); letter-spacing: 0.08em; color: var(--signal); border: 1px solid rgba(255, 77, 0, 0.33); border-radius: 4px; padding: 3px 7px; vertical-align: middle; margin-left: 6px; }
.article-body .api-fields { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.article-body .api-fields code { font-size: 11.5px; padding: 3px 7px; }

/* ---- tracker tables on small screens: rows become cards --------------------
   A 6-9 column data table read through a ~317px porthole is not a layout
   problem you can scroll your way out of, so below 720px every tracker row
   (funding, AI funding, CVE, leaderboard, cost calculator) reflows into a card
   with the column header carried in as a label via data-label. The <thead> is
   kept in the DOM but visually hidden so the table stays a real table for
   screen readers and crawlers. */
@media (max-width: 900px) {
  /* no tracker table forces its 840px desktop floor on a phone — the card-shaped
     ones reflow below, the label/value ones (model specs, X-vs-Y) just fit.
     Every desktop nowrap/min-width guard is released here: on a phone those are
     what push a table (and with it the page) past the viewport. */
  .article-body .lb-table { min-width: 0; }
  .article-body .lb-table tbody th, .article-body .lb-table thead th { white-space: normal; }
  .article-body .lb-table .lb-model { min-width: 0; max-width: none; }
  .article-body .lb-table .lb-score, .article-body .lb-table .lb-price, .article-body .lb-table .lb-date { white-space: normal; }
  .article-body .lb-table th, .article-body .lb-table td { padding: 11px 12px; }
  .article-body .tp-cards { overflow: visible; border: 0; border-radius: 0; margin: 22px 0; }
  .article-body .lb-cards { display: block; min-width: 0; width: 100%; }
  .article-body .lb-cards thead { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .article-body .lb-cards tbody { display: grid; gap: 12px; }
  .article-body .lb-cards .lb-tr { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 12px; padding: 15px 16px 4px; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; }
  .article-body .lb-cards .lb-tr.is-leader { border-color: var(--signal-faint); }
  .article-body .lb-cards .lb-tr.is-leader th, .article-body .lb-cards .lb-tr.is-leader td { background: none; }
  .article-body .lb-cards .lb-tr > th, .article-body .lb-cards .lb-tr > td { display: block; padding: 0; border-bottom: 0; max-width: none; }
  .article-body .lb-cards .lb-rankcell { grid-column: 1; grid-row: 1; width: auto; text-align: left; }
  .article-body .lb-cards .lb-model { grid-column: 2; grid-row: 1; min-width: 0; padding-top: 1px; }
  /* the CVE table has no rank cell — its <th> leads the row, so it spans both */
  .article-body .lb-cards .lb-model:first-child { grid-column: 1 / -1; }
  .article-body .lb-cards .lb-maker { white-space: normal; }
  /* every remaining cell = one full-width "LABEL   value" line */
  .article-body .lb-cards .lb-tr > td:not(.lb-rankcell) { grid-column: 1 / -1; display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 9px 0; border-top: 1px solid var(--hairline); }
  .article-body .lb-cards .lb-tr > td:not(.lb-rankcell)::before { content: attr(data-label); font-family: var(--mono); font-weight: 600; font-size: 9.5px; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-low); }
  .article-body .lb-cards .lb-tr > th.lb-model + td { margin-top: 12px; }
  .article-body .lb-cards .lb-wrap, .article-body .lb-cards .lb-tag, .article-body .lb-cards .lb-for { min-width: 0; }
  .article-body .lb-cards .lb-score, .article-body .lb-cards .lb-price, .article-body .lb-cards .lb-date { white-space: normal; }
  .article-body .lb-cards td.lb-score.col-lb { font-size: 16px; }
  /* "Story" collapses to a real labelled link instead of a lone arrow glyph */
  .article-body .lb-cards .lb-srct { display: inline; font-family: var(--mono); font-size: 12.5px; }
  .article-body .lb-cards .lb-src { margin-left: 0; color: var(--signal); }
  .article-body .lb-cards .lb-rownote { margin-top: 5px; }
  /* the value cell is a grid, so an inline-block chip would stretch across it */
  .article-body .lb-cards .cvw-chip { justify-self: start; }
  /* X-vs-Y compare tables are only 3 columns, so they should fit rather than
     scroll. Releasing min-width isn't enough — the widest cell ("Access": a
     comma list of surfaces) still set a ~200px min-content floor per column,
     so the layout is fixed and the columns split the available width instead. */
  .article-body .cmp-table { min-width: 0; table-layout: fixed; width: 100%; }
  .article-body .cmp-table th:first-child, .article-body .cmp-table td:first-child { width: 32%; }
  .article-body .cmp-table th, .article-body .cmp-table td { padding: 11px 12px; overflow-wrap: anywhere; }
}
/* the memecoin table is 6 short numeric columns — it reads better staying a
   table than as cards, so it gets compaction instead: drop the least-load-bearing
   column and tighten cells until it fits a phone without page-level overflow. */
@media (max-width: 720px) {
  .article-body .mc-table { min-width: 0; font-size: 13.5px; }
  .article-body .mc-table th, .article-body .mc-table td { padding: 10px 9px; }
  .article-body .mc-coin img { margin-right: 6px; }
  .article-body .mc-sym { display: block; margin-left: 0; }
}
@media (max-width: 560px) {
  .article-body .mc-table th:nth-child(6), .article-body .mc-table td:nth-child(6) { display: none; }
  .article-body .mc-table th, .article-body .mc-table td { padding: 10px 7px; }
}
@media (max-width: 460px) {
  .article-body .mc-table th:nth-child(5), .article-body .mc-table td:nth-child(5) { display: none; }
  /* long coin names ("币安人生 (BinanceLife)") were the widest cell and kept the
     table ~25px past the phone; let the name wrap instead of setting the floor */
  .article-body .mc-coin { max-width: 118px; }
  .article-body .mc-name { display: block; overflow-wrap: anywhere; }
  .article-body .mc-table { font-size: 12.5px; }
  .article-body .mc-table th, .article-body .mc-table td { padding: 9px 4px; }
  .article-body .mc-coin img { width: 18px; height: 18px; margin-right: 5px; }
}

/* The masthead H1 bottoms out at 46px, but IBM Plex Mono at 46px makes a single
   long word ("Leaderboard") ~292px — wider than the 264px of content a 320px
   phone has, so it pushed the page sideways. Scale the floor with the viewport
   below 380px instead of letting one word set the page width. */
@media (max-width: 380px) {
  .cat-title { font-size: clamp(34px, 11vw, 46px); }
}

/* Primary-sources rows are flex with a fixed 76px type label and no wrapping, so
   on a narrow phone the title + note could not shrink below their min-content and
   pushed the page sideways. Below 560px the label takes its own line and the
   title/note wrap. Applies to deep-dive articles too, not just the tool pages. */
@media (max-width: 560px) {
  .article-body .tp-sources li { flex-wrap: wrap; gap: 4px 10px; }
  .article-body .tp-sources .src-t { width: 100%; padding-top: 0; }
  .article-body .tp-sources a, .article-body .tp-sources .src-d { min-width: 0; overflow-wrap: anywhere; }
}

/* ---- long gist: CSS-only "show more" below 900px --------------------------
   Emitted only when the gist exceeds 700 chars (seo.mjs gistBox) — today that is
   the leaderboard alone (~1650); the CVE gist (676) already fits a screen and is
   left open. The <p> is clipped by max-height, NEVER display:none, so the full
   text stays in the DOM, in the a11y tree, and extractable for Speakable/AI
   citation. Desktop keeps the gist fully open — the control is display:none.
   ⚠️ max-height is a multiple of the p's OWN line box (18.4em = 11.5 x 1.6em), so
   the collapsed height is identical before and after the webfont swap — that is
   what keeps CLS at 0. Never express it in px, and never transition it. */
.a-gist .gist-toggle, .a-gist .gist-more { display: none; }
@media (max-width: 900px) {
  /* 11.5 lines, not 12: the half-line cut under the fade is the affordance —
     an exact multiple reads as "the text ended". */
  .article .a-gist--long p { position: relative; max-height: 18.4em; overflow: hidden; }
  /* gradient terminates in --panel-2 (#101216) = the .a-gist background — NOT
     --void (#0a0b0c), NOT --panel (#0e0f11). rgb() cannot take a hex custom
     property, so the channels are literal: if --panel-2 changes, change these.
     An ::after gradient rather than mask-image — a mask would promote this
     above-the-fold paragraph to its own compositing layer in the LCP region. */
  .article .a-gist--long p::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 5.6em; pointer-events: none;
    background: linear-gradient(to bottom, rgb(16 18 22 / 0) 0%, rgb(16 18 22 / 0.72) 55%, rgb(16 18 22 / 1) 100%); }
  .article .a-gist--long .gist-toggle:checked ~ p { max-height: none; }
  .article .a-gist--long .gist-toggle:checked ~ p::after { content: none; }
  /* sr-only, NOT display:none — the checkbox must stay keyboard-focusable (2.1.1) */
  .article .a-gist--long .gist-toggle { display: block; position: absolute; top: 0; left: 0; width: 1px; height: 1px; margin: 0; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
  .article .a-gist--long .gist-more { display: flex; align-items: center; gap: 9px; min-height: 44px; /* WCAG 2.5.8 target size */
    margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hairline); scroll-margin-top: 88px; /* 64px sticky nav + 2px signal bar */
    font: 600 11px/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-low); cursor: pointer; user-select: none; transition: color 0.15s; }
  .article .a-gist--long .gist-more::before { content: ""; flex: none; width: 6px; height: 6px; margin-left: 1px; border-right: 1.5px solid var(--signal); border-bottom: 1.5px solid var(--signal); transform: translateY(-2px) rotate(-45deg); transition: transform var(--dur, 150ms) ease; }
  .article .a-gist--long .gist-toggle:checked ~ .gist-more::before { transform: translateY(1px) rotate(45deg); }
  .article .a-gist--long .gist-more:hover { color: var(--bone); }
  /* ring lives on the label but is driven by focus on the invisible input;
     :focus first so older Safari still gets a ring, then undo for mouse users */
  .article .a-gist--long .gist-toggle:focus ~ .gist-more { color: var(--bone); outline: 2px solid var(--signal); outline-offset: 3px; border-radius: 2px; }
  .article .a-gist--long .gist-toggle:focus:not(:focus-visible) ~ .gist-more { outline: none; }
  /* exactly one label string is in the a11y tree at a time */
  .article .a-gist--long .gist-more__less { display: none; }
  .article .a-gist--long .gist-toggle:checked ~ .gist-more .gist-more__more { display: none; }
  .article .a-gist--long .gist-toggle:checked ~ .gist-more .gist-more__less { display: inline; }
}
/* forced-colors removes the gradient affordance, so never hide text there */
@media (forced-colors: active) {
  .article .a-gist--long p { max-height: none; }
  .article .a-gist--long p::after { content: none; }
}
/* print gets the whole answer and no control */
@media print {
  .article .a-gist--long p { max-height: none; }
  .article .a-gist--long p::after { content: none; }
  .article .a-gist--long .gist-more { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .article .a-gist--long .gist-more::before { transition: none; }
}

