/* website/blog.css
   Blog-specific styles. Loads AFTER styles.css and landing.css and extends
   them: it never redefines an lp-* component, it only adds the blog's own.

   Every value comes from the :root tokens in styles.css. Tokens used here,
   all verified declared 2026-07-20:
     --bg --bg-elev --bg-elev-2 --bg-elev-3 --fg --fg-dim --fg-muted --fg-faint
     --line --line-2 --line-3 --red --red-btn --red-faint --ember
     --font-display --font-body --font-mono --container --gutter --radius --ease
   There is no --radius token above 4px, so nothing here is soft-cornered: the
   site's language is hairline rules and architectural panels, not cards.

   The blog's one signature is the DATELINE. These posts are dated, sourced
   field reports, and a reader checking a 2026 price needs the date before
   anything else, so the index is a ruled ledger with a mono date rail rather
   than a grid of floating boxes. Mono is the face styles.css reserves for data,
   which is exactly what a dateline is. */

/* ─── Hero blocks ────────────────────────────────────────────────────────
   The blog reuses .hero .lp-hero plus the real .hero-bg composition
   (.hero-glow + .stone). These rules only tune the measure and rhythm. */

.blog-index-head .hero-headline,
.blog-author-head .hero-headline {
  max-width: 20ch;
}

/* A post title is editorial, not a sales headline: same condensed face and
   weight as the landing hero, stepped down so a nine-word title still holds a
   single strong block instead of running four lines deep. */
.blog-post-head .hero-headline {
  font-size: clamp(2rem, 3.7vw, 3.25rem);
  max-width: 21ch;
  margin-bottom: 22px;
}

.blog-post-head {
  padding-block: clamp(44px, 5.5vw, 72px) clamp(20px, 2.5vw, 32px);
}

.blog-index-head,
.blog-author-head {
  padding-block: clamp(52px, 6.5vw, 96px) clamp(24px, 3vw, 40px);
}
/* Nothing follows the lede inside these heros, so it should not reserve room
   for a CTA row it does not have. */
.blog-index-head .hero-sub,
.blog-author-head .hero-sub { margin-bottom: 0; }

/* The lede sits at the site's hero-sub weight, not the heavier .lp-lede. */
.blog-standfirst {
  max-width: 62ch;
  margin-bottom: 26px;
}

/* Kicker: the eyebrow with a live category link in it. Tighter than the hero
   eyebrow because it carries three items, not one. */
.blog-kicker { gap: 11px; }
.blog-kicker .eyebrow-bar { margin-right: 4px; }
.blog-kicker a {
  color: var(--fg-dim);
  border-bottom: 1px solid transparent;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.blog-kicker a:hover,
.blog-kicker a:focus-visible {
  color: var(--red);
  border-bottom-color: var(--red);
}
.blog-kicker .sep { color: var(--fg-faint); }

/* Byline. A ruled strip, so authorship and dates read as a record rather than
   as a caption trailing off the headline. */
.blog-byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding-top: 20px;
  border-top: 1px solid var(--line-2);
  max-width: 720px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.blog-byline .sep { color: var(--fg-faint); }
.blog-byline a {
  color: var(--fg);
  border-bottom: 1px solid var(--red);
  transition: color .18s var(--ease);
}
.blog-byline a:hover { color: var(--red); }

/* ─── Index and category listing ─────────────────────────────────────────
   Built like .lp-faq: a 1px grid gap over a --line-2 field, so the dividers
   are the container's own background showing through. Same construction as
   the shipped accordion, which is why it reads native. */

/* A labeled rule rather than a floating caption: the line carries the label
   across to the edge of the ledger, the same device as the eyebrow bar. */
.blog-list-label {
  display: flex;
  align-items: center;
  gap: 16px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0 0 18px;
}
.blog-list-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.blog-list {
  display: grid;
  gap: 1px;
  background: var(--line-2);
  border: 1px solid var(--line-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.blog-entry {
  position: relative;
  display: grid;
  grid-template-columns: 118px minmax(0, 1fr) auto;
  align-items: stretch;
  background: var(--bg-elev);
  transition: background .25s var(--ease);
}

.blog-entry:hover,
.blog-entry:focus-within { background: var(--bg-elev-2); }

/* The date rail. Its divider is the one line on the row that turns red, so the
   hover state points at the thing that distinguishes one entry from another. */
.blog-entry-date {
  margin: 0;
  padding: 30px 24px 30px 28px;
  border-right: 1px solid var(--line);
  font-family: var(--font-mono);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color .25s var(--ease);
}
.blog-entry:hover .blog-entry-date,
.blog-entry:focus-within .blog-entry-date { border-right-color: var(--red); }

.blog-entry-md {
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg);
  line-height: 1.1;
}
.blog-entry-yr {
  font-size: 0.7rem;
  letter-spacing: 0.24em;
  color: var(--fg-muted);
  line-height: 1;
}

.blog-entry-body { padding: 28px 30px 28px 28px; }

.blog-entry-kicker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 9px;
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.blog-entry-kicker .sep { color: var(--fg-faint); }
.blog-entry-cat { color: var(--red); }
/* Sits above the title's click overlay so the topic hub stays reachable. */
a.blog-entry-cat {
  position: relative;
  z-index: 1;
  border-bottom: 1px solid transparent;
  transition: border-color .18s var(--ease);
}
a.blog-entry-cat:hover,
a.blog-entry-cat:focus-visible { border-bottom-color: var(--red); }

.blog-entry-title {
  font-family: var(--font-display);
  font-size: clamp(1.12rem, 1.7vw, 1.42rem);
  line-height: 1.2;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--fg);
  margin: 0 0 12px;
}
.blog-entry-title a { color: inherit; }
/* One overlay makes the whole row clickable while keeping a single real link
   in the tab order. */
.blog-entry-title a::after {
  content: "";
  position: absolute;
  inset: 0;
}
.blog-entry:hover .blog-entry-title,
.blog-entry:focus-within .blog-entry-title { color: var(--red); }

.blog-entry-desc {
  margin: 0;
  color: var(--fg-dim);
  font-size: 0.98rem;
  line-height: 1.7;
  max-width: 78ch;
}

/* The whole row is already a link, so a "Read the post" label would be a second
   name for the same action. One arrow at the end of the row says it instead. */
.blog-entry-go {
  display: flex;
  align-items: center;
  padding-inline: 30px 34px;
  color: var(--fg-faint);
  transition: color .25s var(--ease), transform .25s var(--ease);
}
.blog-entry:hover .blog-entry-go,
.blog-entry:focus-within .blog-entry-go {
  color: var(--red);
  transform: translateX(5px);
}

.blog-listing { padding-block: clamp(32px, 4vw, 56px) clamp(56px, 7vw, 96px); }

/* ─── Post body: reading column plus contents rail ───────────────────────
   Below 1180px the contents list is a panel above the article. Above it, the
   space to the right of the reading measure carries a sticky contents rail, so
   a nine-section article stays navigable without scrolling back to the top. */

.blog-body { padding-block: clamp(28px, 3.5vw, 44px) clamp(56px, 7vw, 96px); }

.blog-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 40px;
  align-items: start;
}

.blog-main { min-width: 0; }

@media (min-width: 1180px) {
  .blog-grid {
    grid-template-columns: minmax(0, 760px) minmax(0, 296px);
    gap: 72px;
  }
  .blog-main { grid-column: 1; grid-row: 1; }
  /* The rail must span the full row height or the sticky child has nowhere to
     travel and scrolls away with the first screen. */
  .blog-aside {
    grid-column: 2;
    grid-row: 1;
    align-self: stretch;
    min-width: 0;
  }
  .blog-toc {
    position: sticky;
    top: 104px;
    max-height: calc(100vh - 148px);
    overflow-y: auto;
  }
}

/* ─── Table of contents ──────────────────────────────────────────────── */

.blog-toc {
  border-top: 1px solid var(--line-2);
  padding-top: 18px;
}

.blog-toc-h {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 8px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.blog-toc-h::before {
  content: "";
  width: 20px;
  height: 2px;
  background: var(--red);
  flex: 0 0 auto;
}

.blog-toc ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.blog-toc li { border-bottom: 1px solid var(--line); }
.blog-toc li:last-child { border-bottom: none; }
.blog-toc a {
  display: block;
  padding: 11px 0 11px 14px;
  border-left: 2px solid transparent;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--fg-muted);
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.blog-toc a:hover,
.blog-toc a:focus-visible {
  color: var(--fg);
  border-left-color: var(--red);
}

/* ─── Prose additions ────────────────────────────────────────────────────
   landing.css styles .lp-prose p, h2, h3, ul and a. Everything the markdown
   renderer can also emit is styled here: ordered lists, rules, inline code,
   blockquotes, tables and h4. Ordered lists were previously inheriting the
   global `ul, ol { list-style: none; padding: 0 }` reset, which silently
   flattened a numbered sequence into an unbroken block of text. */

.lp-prose ol {
  counter-reset: step;
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 0 0 1.4em;
  padding: 0;
  list-style: none;
}
.lp-prose ol > li {
  counter-increment: step;
  position: relative;
  padding-left: 34px;
  color: var(--fg-dim);
  font-size: 1.02rem;
  line-height: 1.7;
}
/* The number is the content's own semantics, not decoration: the author wrote
   an ordered list. Mono red ties it to the .lp-pain-key vocabulary. */
.lp-prose ol > li::before {
  content: counter(step) ".";
  position: absolute;
  left: 0;
  top: 0.2em;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--red);
}
.lp-prose ol > li strong { color: var(--fg); font-weight: 600; }

/* Without this, a contents link lands the heading underneath the sticky nav,
   which reads as "the link did nothing". */
.lp-prose h2[id],
.lp-prose h3[id],
.lp-prose h4[id] { scroll-margin-top: 104px; }

.lp-prose h4 {
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--fg);
  margin: 30px 0 10px;
}

.lp-prose hr {
  border: 0;
  height: 1px;
  background: var(--line-2);
  margin: 48px 0;
}

.lp-prose code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  color: var(--fg);
  background: var(--bg-elev-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.12em 0.4em;
  white-space: nowrap;
}

/* A pull quote is usually a cited source on this blog, so it is set as a
   raised panel with the red rule the site uses for emphasis, not as italics. */
.lp-prose blockquote {
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-left: 3px solid var(--red);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 32px 0;
  padding: 24px 28px;
}
.lp-prose blockquote p {
  margin: 0;
  color: var(--fg);
  font-size: 1.06rem;
  line-height: 1.7;
}

/* Tables. Cells wrap rather than being held on one line, so a five column
   pricing table fits the reading measure on a laptop with no scroll at all.
   The block scroller stays as the safety net for phones, where a min-content
   table genuinely cannot fit. The page body never scrolls horizontally either
   way.

   The edge affordance is the classic two-layer gradient trick, recoloured for
   a dark surface: the `local` layers scroll with the content and cover the
   `scroll` layers, so the red edge glow appears only while there is more table
   in that direction. A dark drop shadow, the usual version of this, is
   invisible on a near-black panel. */
.lp-prose table {
  display: block;
  overflow-x: auto;
  max-width: 100%;
  border-collapse: collapse;
  margin: 32px 0;
  font-size: 0.92rem;
  border: 1px solid var(--line-2);
  background:
    linear-gradient(90deg, var(--bg-elev) 40%, rgba(12, 12, 16, 0)) left center / 26px 100% no-repeat local,
    linear-gradient(270deg, var(--bg-elev) 40%, rgba(12, 12, 16, 0)) right center / 26px 100% no-repeat local,
    linear-gradient(90deg, rgba(240, 75, 87, 0.34), rgba(240, 75, 87, 0)) left center / 20px 100% no-repeat scroll,
    linear-gradient(270deg, rgba(240, 75, 87, 0.34), rgba(240, 75, 87, 0)) right center / 20px 100% no-repeat scroll,
    var(--bg-elev);
}

.lp-prose th,
.lp-prose td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
  line-height: 1.55;
}
.lp-prose td { color: var(--fg-dim); }
.lp-prose tbody tr:last-child td { border-bottom: none; }
.lp-prose thead th {
  background: var(--bg-elev-2);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--line-3);
}
/* A red underline under every vendor name turns the table into noise. Inside
   the grid, links carry a quiet rule and take the accent only on hover. */
.lp-prose td a,
.lp-prose th a {
  border-bottom-color: var(--line-3);
  color: var(--fg);
}
.lp-prose td a:hover,
.lp-prose th a:hover { border-bottom-color: var(--red); }

/* ─── Post footer ────────────────────────────────────────────────────── */

/* AI assistance disclosure. Deliberately quiet but legible: it is a trust
   signal, not fine print to hide. */
.blog-disclosure {
  position: relative;
  font-size: 0.84rem;
  line-height: 1.7;
  color: var(--fg-muted);
  border-top: 1px solid var(--line);
  padding: 22px 0 0 18px;
  margin: 56px 0 0;
}
.blog-disclosure::before {
  content: "";
  position: absolute;
  left: 0;
  top: 31px;
  width: 9px;
  height: 1px;
  background: var(--red);
}

.blog-next {
  margin: 32px 0 0;
}
.blog-next a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg);
  border-bottom: 1px solid var(--line-3);
  padding-bottom: 6px;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
.blog-next a svg { transition: transform .2s var(--ease); }
.blog-next a:hover {
  color: var(--red);
  border-bottom-color: var(--red);
}
.blog-next a:hover svg { transform: translateX(4px); }

/* ─── Pagination ─────────────────────────────────────────────────────────
   Numbered, not just prev and next, so deep pages stay within a few clicks of
   the index. Square corners and mono caps, matching the site's buttons. */

.blog-pager {
  margin: 40px 0 0;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.blog-pager p {
  margin: 0 12px 0 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.blog-pager a,
.blog-pager span {
  min-width: 38px;
  text-align: center;
  padding: 9px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--line-2);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--fg-dim);
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.blog-pager a:hover {
  border-color: var(--red);
  color: var(--fg);
}
.blog-pager span[aria-current] {
  background: var(--red-btn);
  border-color: var(--red-btn);
  color: #fff;
}

/* ─── Author page ────────────────────────────────────────────────────── */

.blog-author-grid {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  gap: 36px;
  align-items: center;
}
.blog-author-portrait {
  width: 168px;
  height: 168px;
  object-fit: cover;
  object-position: 50% 12%;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  filter: grayscale(1) contrast(1.06);
}
.blog-author-head .hero-headline { margin-bottom: 18px; }
.blog-author-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.blog-author-links .sep { color: var(--fg-faint); }
.blog-author-links a {
  color: var(--fg-dim);
  border-bottom: 1px solid var(--line-3);
  padding-bottom: 4px;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.blog-author-links a:hover {
  color: var(--red);
  border-bottom-color: var(--red);
}

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

@media (max-width: 720px) {
  /* The date rail becomes a horizontal stamp above the entry: a 118px column
     leaves nothing for a title on a 390px screen. */
  .blog-entry { grid-template-columns: minmax(0, 1fr); }
  .blog-entry-date {
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    padding: 20px 22px 0;
    border-right: none;
  }
  .blog-entry:hover .blog-entry-date,
  .blog-entry:focus-within .blog-entry-date { border-right-color: var(--line); }
  .blog-entry-body { padding: 12px 22px 24px; }
  .blog-entry-desc { font-size: 0.94rem; }
  /* Tighter tracking keeps "Compliance and Privacy - 8 min read" on one line
     instead of orphaning the separator. */
  .blog-entry-kicker { font-size: 0.63rem; letter-spacing: 0.13em; gap: 7px; }
  /* The arrow column would steal a third of a 390px row. The row is still
     clickable; the affordance moves to the title. */
  .blog-entry-go { display: none; }

  .blog-author-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .blog-author-portrait { width: 132px; height: 132px; }

  .lp-prose th,
  .lp-prose td { padding: 11px 13px; }
  .lp-prose blockquote { padding: 20px 20px; }
  .blog-byline { gap: 8px; font-size: 0.7rem; }
}

@media (prefers-reduced-motion: reduce) {
  .blog-entry,
  .blog-entry-date,
  .blog-entry-go,
  .blog-next a,
  .blog-next a svg,
  .blog-toc a,
  .blog-pager a { transition: none; }
  .blog-entry:hover .blog-entry-go,
  .blog-entry:focus-within .blog-entry-go,
  .blog-next a:hover svg { transform: none; }
}
