/* ═══════════════════════════════════════════════════════════════════
   blog-index.css — /blog and /blog/category/:slug
   Redesigned 2026-08-06. Replaces the legacy card grid.

   NO :root, NO RESET, NO body{} IN THIS FILE.

   Every other page-level stylesheet in this directory is a legacy page's
   inline <style> extracted verbatim, and each one carries its own reset,
   its own custom properties and its own body rule. Loading two of them on
   one page gives you two global resets. This file is written fresh against
   what main.css and home.css already provide — --dark, --amber, --max-w,
   --gutter, .wrap, and the base typography — and adds nothing global.

   The design is TYPOGRAPHIC FIRST. 49 of the 50 posts arrived with no cover
   image, so the hierarchy is carried by type, rules and numbering — a card
   grid would have been a wall of identical placeholder tiles.

   Covers were added afterwards (migration 0018) and sit INSIDE that
   structure rather than replacing it: a thumbnail column in the list, art
   beside the lead. They are generated SVG at ~1.5KB, so the whole 50-row
   index still weighs less than one stock photograph would.
   ═══════════════════════════════════════════════════════════════════ */

/* [hidden] has to beat the display values set below, or a filtered-out row
   stays on screen. This is the whole reason the filter uses el.hidden rather
   than an inline style — one rule here, none in the script. */
#blog-feed [hidden] { display: none !important; }

/* ── Lede ──────────────────────────────────────────────────────── */
#blog-lede {
    background: var(--dark);
    /* 9rem clears the fixed nav pill. The legacy hero used the same figure;
       anything less and the h1 sits under it on load. */
    padding: 9rem var(--gutter) 3.5rem;
    border-bottom: 1px solid var(--border-dark);
}

#blog-lede h1 {
    font-family: 'Sora', sans-serif;
    font-weight: 800;
    font-size: clamp(2.4rem, 6vw, 4.2rem);
    letter-spacing: -0.035em;
    line-height: 1.02;
    max-width: 16ch;
    margin-bottom: 1.25rem;
}

.blog-lede-sub {
    color: rgba(255, 255, 255, 0.5);
    font-size: 1.05rem;
    line-height: 1.7;
    max-width: 58ch;
    margin-bottom: 2.5rem;
}

/* ── Search ────────────────────────────────────────────────────── */
.blog-search {
    position: relative;
    max-width: 460px;
    margin-bottom: 1.75rem;
}
.blog-search svg {
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    width: 17px;
    height: 17px;
    color: rgba(255, 255, 255, 0.35);
    pointer-events: none;
}
.blog-search input {
    width: 100%;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-dark);
    border-radius: 999px;
    color: var(--light);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.95rem;
    padding: 0.85rem 1.1rem 0.85rem 2.75rem;
    transition: border-color 0.2s, background 0.2s;
}
.blog-search input::placeholder { color: rgba(255, 255, 255, 0.32); }
.blog-search input:focus {
    outline: none;
    border-color: rgba(217, 119, 6, 0.55);
    background: rgba(255, 255, 255, 0.06);
}
/* Safari draws its own clear button and it renders as a grey blob on dark. */
.blog-search input::-webkit-search-decoration,
.blog-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ── Category pills ────────────────────────────────────────────── */
.blog-cats {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.blog-cat {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.5rem 0.95rem;
    border: 1px solid var(--border-dark);
    border-radius: 999px;
    background: transparent;
    color: rgba(255, 255, 255, 0.62);
    font-size: 0.83rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.18s, border-color 0.18s, background 0.18s;
}
.blog-cat:hover {
    color: var(--light);
    border-color: rgba(255, 255, 255, 0.2);
}
.blog-cat.is-active {
    color: #1a1206;
    background: var(--amber);
    border-color: var(--amber);
    font-weight: 600;
}
.blog-cat-n {
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
    opacity: 0.6;
}
.blog-cat.is-active .blog-cat-n { opacity: 0.7; }

/* ── Feed ──────────────────────────────────────────────────────── */
#blog-feed {
    background: var(--dark);
    padding: 3.5rem var(--gutter) 6rem;
}

.blog-dot {
    display: inline-block;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.45;
    vertical-align: middle;
    flex: none;
}

/* ── Cover art ─────────────────────────────────────────────────── */
/*
  Every cover is a generated SVG at 1200×630 (see tools/generate-blog-covers).
  aspect-ratio + the width/height attributes on the tag reserve the box before
  the file arrives, so the list does not reflow as 50 images decode — the
  cheapest layout-shift fix there is, and it costs one line.
*/
.blog-lead-img,
.blog-row-img {
    display: block;
    width: 100%;
    aspect-ratio: 1200 / 630;
    height: auto;
    object-fit: cover;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.03);
}

/* ── Lead article ──────────────────────────────────────────────── */
.blog-lead {
    display: grid;
    gap: 2.25rem;
    align-items: center;
    text-decoration: none;
    color: inherit;
    padding: 0 0 3rem;
    border-bottom: 1px solid var(--border-dark);
}
@media (min-width: 860px) {
    /* Art second in the DOM order would be simpler, but the text has to come
       first for a screen reader and for the no-CSS fallback. Column placement
       does the visual swap without reordering the markup. */
    .blog-lead {
        grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
        gap: 3rem;
    }
    .blog-lead-img { order: 2; }
    .blog-lead-text { order: 1; }
}
.blog-lead-img { border-radius: 14px; }
.blog-lead-meta,
.blog-lead-foot,
.blog-row-meta {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.42);
}
.blog-lead-meta { margin-bottom: 1.1rem; }
.blog-lead-flag {
    color: var(--amber);
    font-weight: 700;
}
.blog-lead-title {
    font-family: 'Sora', sans-serif;
    font-weight: 800;
    font-size: clamp(1.75rem, 3.6vw, 2.9rem);
    line-height: 1.1;
    letter-spacing: -0.03em;
    max-width: 22ch;
    margin-bottom: 1rem;
    transition: color 0.2s;
}
.blog-lead:hover .blog-lead-title { color: var(--amber); }
.blog-lead-excerpt {
    color: rgba(255, 255, 255, 0.55);
    font-size: 1.02rem;
    line-height: 1.7;
    max-width: 62ch;
    margin-bottom: 1.5rem;
}
.blog-lead-go {
    color: var(--amber);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: none;
    margin-left: auto;
}

/* ── The list ──────────────────────────────────────────────────── */
.blog-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.blog-row { display: block; }
.blog-row > a {
    display: grid;
    grid-template-columns: 3.5rem 128px 1fr auto;
    gap: 1.5rem;
    align-items: start;
    padding: 2rem 1rem 2rem 0;
    border-bottom: 1px solid var(--border-dark);
    text-decoration: none;
    color: inherit;
    transition: background 0.18s;
}
.blog-row-img {
    margin-top: 0.2rem;
    transition: transform 0.2s, opacity 0.2s;
    opacity: 0.9;
}
.blog-row > a:hover .blog-row-img {
    opacity: 1;
    transform: scale(1.03);
}
.blog-row > a:hover { background: rgba(255, 255, 255, 0.022); }

.blog-row-n {
    font-family: 'Sora', sans-serif;
    font-size: 0.8rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: rgba(255, 255, 255, 0.22);
    padding-top: 0.35rem;
    padding-left: 1rem;
    transition: color 0.2s;
}
.blog-row > a:hover .blog-row-n { color: var(--amber); }

.blog-row-meta { margin-bottom: 0.6rem; }
.blog-row-cat { color: rgba(255, 255, 255, 0.55); }

.blog-row-title {
    font-family: 'Sora', sans-serif;
    font-weight: 700;
    font-size: clamp(1.1rem, 1.9vw, 1.4rem);
    line-height: 1.28;
    letter-spacing: -0.02em;
    margin-bottom: 0.5rem;
    transition: color 0.2s;
}
.blog-row > a:hover .blog-row-title { color: var(--amber); }

.blog-row-excerpt {
    color: rgba(255, 255, 255, 0.44);
    font-size: 0.92rem;
    line-height: 1.65;
    max-width: 68ch;
}

.blog-row-read {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.3);
    white-space: nowrap;
    padding-top: 0.35rem;
    font-variant-numeric: tabular-nums;
}

/* ── Empty states ──────────────────────────────────────────────── */
.blog-noresults,
.blog-empty {
    text-align: center;
    padding: 4rem 1rem;
    color: rgba(255, 255, 255, 0.45);
}
.blog-empty h2 {
    font-family: 'Sora', sans-serif;
    font-size: 1.6rem;
    color: var(--light);
    margin-bottom: 0.5rem;
}

/* ── Subscribe ─────────────────────────────────────────────────── */
#blog-subscribe {
    background: var(--dark-2);
    border-top: 1px solid var(--border-dark);
    padding: 5rem var(--gutter);
}
.blog-sub-inner {
    display: flex;
    gap: 3rem;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
}
.blog-sub-inner h2 {
    font-family: 'Sora', sans-serif;
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    letter-spacing: -0.025em;
    margin-bottom: 0.5rem;
}
.blog-sub-inner p { color: rgba(255, 255, 255, 0.45); }

.blog-sub-form {
    display: flex;
    gap: 0.6rem;
    flex: 1 1 340px;
    max-width: 460px;
}
.blog-sub-form input[type='email'] {
    flex: 1;
    min-width: 0;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-dark);
    border-radius: 2px;
    color: var(--light);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.92rem;
    padding: 0.85rem 1rem;
}
.blog-sub-form input[type='email']::placeholder { color: rgba(255, 255, 255, 0.3); }
.blog-sub-form input[type='email']:focus {
    outline: none;
    border-color: rgba(217, 119, 6, 0.55);
}
.blog-sub-form button {
    background: var(--amber);
    color: #fff;
    border: none;
    border-radius: 2px;
    padding: 0.85rem 1.6rem;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.2s;
}
.blog-sub-form button:hover { background: var(--amber-hover); }

/* Honeypot. Positioned off-screen rather than display:none — a headless bot
   that reads computed styles skips display:none fields, and skipping the trap
   defeats the trap. aria-hidden + tabindex -1 keep it away from real users
   and from screen readers. */
.hp-field {
    position: absolute !important;
    left: -9999px !important;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* ── Responsive ────────────────────────────────────────────────── */
@media (max-width: 820px) {
    #blog-lede { padding-top: 7rem; }
    .blog-row > a {
        grid-template-columns: 92px 1fr;
        gap: 1rem;
        padding: 1.5rem 0;
        align-items: center;
    }
    /* The number and the read time are ornament, not information — the meta
       line already carries the date and the category. In a narrow column they
       would each steal a whole row. The thumbnail earns its place: it is what
       makes a long list scannable by thumb. */
    .blog-row-n,
    .blog-row-read { display: none; }
    .blog-row-excerpt { display: none; }
    .blog-row-img { margin-top: 0; border-radius: 8px; }
    .blog-lead-go { margin-left: 0; width: 100%; margin-top: 0.5rem; }
    .blog-lead-foot { flex-wrap: wrap; }
}

/* ─────────────────────────────────────────────────────────────────
   .eyebrow-amber — defined here because NOTHING ELSE LOADED DEFINES IT.

   `.eyebrow` itself comes from home.css, but the amber modifier only ever
   lived inside the legacy per-page extracts. Parking blog-index.legacy.bak
   quietly took it away, and because a class that matches nothing throws no
   error, every eyebrow on this page was rendering in inherited white with
   no sign anything was wrong. Caught by a script that diffs class names in
   the JSX against the loaded stylesheets — worth keeping in the toolbox.
   ───────────────────────────────────────────────────────────────── */
.eyebrow-amber { color: var(--amber); }

/* Grid children default to min-width:auto, which refuses to shrink below the
   widest unbreakable word. A long slug or URL in a title would push the row
   wider than the grid and force a horizontal scrollbar on the whole page. */
.blog-row-main { min-width: 0; }
.blog-lead-wrap { display: block; }

/* ─────────────────────────────────────────────────────────────────
   UNDOING home.css's MOBILE SLEDGEHAMMER

   home.css loads on every page and, inside @media (max-width: 768px),
   sets two blanket rules with !important:

       section { padding-top: 2.75rem !important;
                 padding-bottom: 2.75rem !important; }
       h2      { font-size: clamp(1.9rem, 6.5vw, 2.5rem) !important; }

   They were written for the home page's own sections and they reach every
   <section> and every <h2> on the site. On this page the first one crushes
   the lede's 7rem top padding down to 2.75rem, which slides the h1 under the
   fixed nav pill on a phone — and the second inflates the lead article's
   title to home-page hero size.

   Overriding with !important is not a preference here; !important can only
   be beaten by !important. These selectors are more specific than the ones
   above (an id beats an element), so the pair resolves in this file's favour.
   Deleting the rules in home.css would be the better fix, but they are load-
   bearing for the home page and that is a separate change with its own risk.
   ───────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
    #blog-lede {
        padding-top: 7rem !important;
        padding-bottom: 2.5rem !important;
    }
    #blog-feed {
        padding-top: 2.5rem !important;
        padding-bottom: 4rem !important;
    }
    #blog-subscribe {
        padding-top: 3.5rem !important;
        padding-bottom: 3.5rem !important;
    }
    .blog-lead-title { font-size: clamp(1.6rem, 6.5vw, 2rem) !important; }
    .blog-sub-inner h2 { font-size: 1.5rem !important; }
}
