/* Blog — the reading and listing surface. Loaded AFTER /site.css, which owns
   the shared header, footer and design tokens (--lb-*, --font-display,
   --font-body). Both are external and cached once for the whole blog.

   WHY EXTERNAL (bd orgalife-dgsj (was filed as orgalife-8rsc)). This stylesheet used to be a ~5KB template
   literal inlined into every generated page, with its own private copies of the
   colour tokens and its own font stack — 'DM Sans' + 'Playfair Display' against
   the rest of the site's Outfit + Plus Jakarta Sans. Two consequences, and the
   second is the one the owner's wife actually saw: ~1.5MB of duplicated CSS
   across 315 articles, and a blog that did not look like the product it belongs
   to. The old comment justifying the inline copy said "this CSS is inlined into
   all 315 generated articles and has no cascade to inherit a token from" — which
   was true, and the fix was to give it one rather than to keep copying. */

body {
  font-family: var(--font-body);
  background: var(--lb-cream);
  color: var(--lb-text);
  max-width: 1080px;
  margin: 0 auto;
  padding: 40px 24px 80px;
  line-height: 1.7;
}
* { box-sizing: border-box; }
a { color: var(--lb-rose-dark); }

/* The READING COLUMN. Long-form prose wants a measure of roughly 65-75
   characters; the page shell is wider than that because the header, the card
   grid and the related-articles strip all want the room. So the column is set
   here rather than on <body>, which is what the old 720px body width was doing
   by accident — it constrained the grid too.

   THAT CLAIM WAS FALSE FOR AS LONG AS IT HAD BEEN WRITTEN, and it took measuring
   to see. 44rem at the old 16px body ran a MEDIAN of 78 characters per line and
   a maximum of 90 — above the top of the range this very comment states, on
   1,400-2,600 word articles. A comment asserting an invariant does not enforce
   it, so the number is now measured on a real built article by PATH BL in
   scripts/verify-modal-focus.mjs and the range is a gate.

   THE FIX WAS THE TYPE SIZE, NOT THE COLUMN. Characters per line is width
   divided by average character width, so either lever moves it; raising the
   size to 1.125rem lands the median at ~69 AND makes the prose more comfortable,
   where narrowing the column to ~38rem would have hit the same number while
   leaving 16px type on a 2,600-word article. */
.blog-main { max-width: 44rem; margin: 0 auto; }
.blog-wide { max-width: 100%; }

/* ===== Reading progress =====
   Fixed, 3px, and driven by public/blog-progress.js. Not decoration: these are
   1,400-2,600 word articles and the single most common question a reader has
   on one is "how much of this is left". */
.read-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0;
  background: linear-gradient(90deg, var(--lb-rose), var(--lb-lavender));
  z-index: 50; transition: width 0.1s linear;
}

/* ===== Article ===== */
.crumbs, .meta { color: var(--lb-text-hint); font-size: 14px; }
.crumbs { margin: 0 0 1.5rem; }
.crumbs a, .meta a { color: var(--lb-text-muted); }

.blog-h1 {
  font-family: var(--font-display);
  color: var(--lb-rose-dark);
  font-size: clamp(2rem, 1.4rem + 2.2vw, 2.85rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0.35rem 0 0.6rem;
}
/* Prose size. 1rem is a UI size; this is an essay. See the measure note above —
   this is the lever that fixed the line length, and it is set on the container
   so headings (sized in rem) keep their scale relative to the page rather than
   drifting with the paragraphs. */
.article-body { font-size: 1.125rem; }
.article-body h2 {
  font-family: var(--font-display);
  font-size: 1.65rem; line-height: 1.3; color: var(--lb-rose-dark);
  margin: 2.4em 0 0.6em;
  scroll-margin-top: 1.5rem;
}
.article-body h3 { font-family: var(--font-display); font-size: 1.25rem; margin: 1.9em 0 0.5em; scroll-margin-top: 1.5rem; }
.article-body p { margin: 0 0 1.15em; }
.article-body ul, .article-body ol { margin: 0 0 1.3em; padding-left: 1.3em; }
.article-body li { margin: 0.35em 0; }
.article-body strong { color: var(--lb-text); font-weight: 600; }

/* THE PROSE RULES ARE SCOPED TO .article-body, NOT TO `article`, and that is
   not cosmetic. postCard() renders each hub card as <article class="post-card">
   — correct HTML — so every `article p`/`article h2` rule here also styled the
   CARDS. The visible symptom was the card descriptions rendering at lead-
   paragraph size and colour, because `article > p:first-of-type` matched them.
   Found by screenshotting the built hub; no unit gate reads computed style. */

/* The lead paragraph carries the article's promise, so it is the biggest and the
   MOST legible thing in the body — not the least.
   It used to be 1.12rem in --lb-text-muted, which on these articles meant the
   longest paragraph on the page (often ten or more lines) was also the lowest
   contrast one, and after the prose moved to 1.125rem it was no longer even the
   biggest. Emphasis here is size and weight, never fading — the same rule the
   taste ledger states for attention in the app. */
.article-body > p:first-of-type {
  font-size: 1.3rem; color: var(--lb-text); line-height: 1.55; margin-bottom: 1.5rem;
}

.article-body hr { border: 0; border-top: 1px solid var(--lb-border); margin: 2.6em 0; }
.article-body pre {
  background: var(--lb-white); border: 1px solid var(--lb-border);
  border-radius: 10px; padding: 14px 16px; overflow-x: auto; font-size: 14px;
}
.article-body blockquote {
  margin: 1.6em 0; padding: 0.2em 0 0.2em 1.15em;
  border-left: 3px solid var(--lb-lavender); color: var(--lb-text-muted);
}

.article-head { margin-bottom: 2rem; }
.article-meta { display: flex; flex-wrap: wrap; gap: 0.4rem 0.9rem; align-items: center; font-size: 14px; color: var(--lb-text-hint); margin: 0.5rem 0 0; }

/* ===== Category chips =====
   One hue per category rather than one grey for all six. A chip that is the
   same colour everywhere carries no information; the point of a taxonomy the
   reader can see is that they can tell two of them apart at a glance. */
.badge {
  display: inline-block; border-radius: 999px; padding: 3px 13px;
  font-size: 12.5px; font-weight: 600; text-decoration: none;
  background: var(--lb-rose-light); color: var(--lb-rose-dark);
}
.badge:hover { filter: brightness(0.96); }
.badge[data-cat="body-and-health"]        { background: #FBE4EC; color: #8A2F55; }
.badge[data-cat="nutrition"]              { background: #E3F2E4; color: #2C6135; }
.badge[data-cat="mind-and-productivity"]  { background: #EAE4F7; color: #4A2F86; }
.badge[data-cat="routine-engineering"]    { background: #E4EDF9; color: #23507F; }
.badge[data-cat="finances"]               { background: #FCF0DC; color: #7A5312; }
.badge[data-cat="levebase-ecosystem"]     { background: #E5F1F2; color: #1F5F63; }

/* The six chips are the ONE place in this file that cannot be themed by token:
   each is a hue/ink pair chosen together, and only three of the six have an
   equivalent in the shared palette. Left alone, a dark page would carry six pastel
   islands with near-black text — the "hardcoded hex does not flip" failure the
   charter names, on the most visible element of the hub.
   FOUR OF THE SIX ARE DERIVED, not invented: nutrition / mind / routine / finances
   reuse src/style.css's own night pairs verbatim (--sage-light/-dark,
   --lavender-light/-dark, --indigo-light/-dark, --amber-light/-dark). The pink and
   the teal have no counterpart in the app palette and are built in the same shape —
   a desaturated dark surface, a light ink of the same hue. Every pair is measured by
   src/public-theme-contrast.test.js, which reads the surface and the ink out of each
   rule's own declarations; the weakest reads 6.92:1 against a 4.5 floor. */
@media (prefers-color-scheme: dark) {
  .badge[data-cat="body-and-health"]        { background: #33202A; color: #F2A8C2; }
  .badge[data-cat="nutrition"]              { background: #1D2E27; color: #8FD3B0; }
  .badge[data-cat="mind-and-productivity"]  { background: #281E33; color: #C9A6EC; }
  .badge[data-cat="routine-engineering"]    { background: #1E2940; color: #93B4F5; }
  .badge[data-cat="finances"]               { background: #332717; color: #E8A562; }
  .badge[data-cat="levebase-ecosystem"]     { background: #172E2F; color: #7FCFD4; }
  /* brightness(0.96) darkens, which is the wrong direction on a dark surface. */
  .badge:hover { filter: brightness(1.12); }
}

/* ===== Table of contents =====
   Rendered only for articles with enough H2s to need one (blog-lib decides).
   <details> so it costs nothing on mobile and is closed by default — an
   always-open 8-item list between the headline and the first paragraph is the
   thing that makes a blog feel like documentation. */
.toc {
  border: 1px solid var(--lb-border); border-radius: 14px;
  background: var(--lb-white); padding: 0.85rem 1.1rem; margin: 0 0 2rem;
}
.toc > summary { cursor: pointer; font-weight: 600; font-size: 14px; color: var(--lb-rose-dark); }
.toc ol { margin: 0.7rem 0 0.2rem; padding-left: 1.2rem; font-size: 14.5px; }
.toc li { margin: 0.3em 0; }
.toc a { color: var(--lb-text-muted); text-decoration: none; }
.toc a:hover { color: var(--lb-rose-dark); text-decoration: underline; }

/* ===== Hub: the featured lead ===== */
.blog-intro { color: var(--lb-text-muted); max-width: 46rem; margin: 0 0 1.4rem; font-size: 1.05rem; }
.cat-nav { display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 0 0 1.8rem; }

.featured {
  display: block; text-decoration: none; color: inherit;
  background: var(--lb-white); border: 1px solid var(--lb-border);
  border-radius: 18px; padding: 1.9rem 2rem; margin: 0 0 1.6rem;
}
.featured:hover { border-color: var(--lb-rose-dark); }
.featured .featured-label { font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--lb-text-hint); }
.featured h2 { font-family: var(--font-display); font-size: clamp(1.4rem, 1rem + 1.6vw, 2rem); line-height: 1.2; color: var(--lb-rose-dark); margin: 0.5rem 0 0.5rem; }
.featured p { margin: 0 0 0.8rem; color: var(--lb-text-muted); }

/* ===== Hub: the card grid ===== */
.post-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(276px, 1fr)); gap: 18px; margin: 0 0 2.5rem; }
.post-card {
  display: flex; flex-direction: column;
  background: var(--lb-white); border: 1px solid var(--lb-border);
  border-radius: 16px; padding: 20px 22px;
}
.post-card:hover { border-color: var(--lb-rose-dark); }
.post-card h2 { font-family: var(--font-display); font-size: 1.1rem; line-height: 1.32; margin: 0.6rem 0 0.45rem; }
.post-card h2 a { color: var(--lb-rose-dark); text-decoration: none; }
.post-card h2 a:hover { text-decoration: underline; }
.post-card p { margin: 0 0 0.9rem; font-size: 14.5px; color: var(--lb-text-muted); }
.post-card .meta { margin-top: auto; }

/* ===== Pagination =====
   The hub used to render every published article into one document — 315 items
   and 148KB on /blog/, which is most of a megabyte of HTML a phone parses before
   it can show the first headline. */
.pager { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; justify-content: center; margin: 2rem 0 0; }
.pager a, .pager span {
  min-width: 2.4rem; text-align: center; padding: 8px 12px;
  border: 1px solid var(--lb-border); border-radius: 10px;
  text-decoration: none; font-size: 14px; background: var(--lb-white);
}
.pager a:hover { border-color: var(--lb-rose-dark); }
.pager [aria-current="page"] { background: var(--lb-accent-fill); color: var(--lb-on-accent); border-color: var(--lb-accent-fill); font-weight: 600; }
.pager .pager-gap { border: 0; background: none; color: var(--lb-text-hint); min-width: 1.2rem; padding: 8px 2px; }

/* ===== Related ===== */
.related { margin: 3rem 0 0; }
.related h2 { font-family: var(--font-display); font-size: 1.2rem; color: var(--lb-rose-dark); margin: 0 0 0.9rem; }

/* ===== Search ===== */
.search-box {
  width: 100%; padding: 12px 16px; font-size: 16px; font-family: inherit;
  color: var(--lb-text); background: var(--lb-white);
  border: 1px solid var(--lb-border); border-radius: 12px; margin: 0 0 1.4rem;
}
.search-box:focus { outline: none; border-color: var(--lb-rose); box-shadow: 0 0 0 3px var(--lb-rose-light); }
.search-status { color: var(--lb-text-muted); font-size: 14px; margin: 0 0 12px; }
mark { background: var(--lb-rose-light); color: var(--lb-rose-dark); padding: 0 2px; border-radius: 3px; }

/* ===== CTA + newsletter ===== */
.cta {
  background: var(--lb-white); border: 1px solid var(--lb-border);
  border-radius: 16px; padding: 22px 24px; margin-top: 3em;
}
.cta a.btn {
  display: inline-block; background: var(--lb-accent-fill); color: var(--lb-on-accent);
  border-radius: 999px; padding: 10px 22px; text-decoration: none;
  font-weight: 600; margin-top: 10px;
}
.capture { background: var(--lb-white); border: 1px solid var(--lb-border); border-radius: 16px; padding: 22px 24px 20px; margin-top: 1.5em; }
.capture h2 { font-family: var(--font-display); margin: 0 0 6px; font-size: 1.2rem; color: var(--lb-rose-dark); }
.capture p { margin: 0 0 14px; font-size: 15px; color: var(--lb-text-muted); }
.capture-form { display: flex; gap: 8px; flex-wrap: wrap; }
.capture-form input[type="email"] { flex: 1 1 220px; min-width: 0; padding: 11px 14px; font-family: inherit; font-size: 16px; color: var(--lb-text); background: var(--lb-cream); border: 1px solid var(--lb-border); border-radius: 999px; }
.capture-form input[type="email"]:focus { outline: none; border-color: var(--lb-rose); box-shadow: 0 0 0 3px var(--lb-rose-light); }
.capture-form button { flex: 0 0 auto; background: var(--lb-accent-fill); color: var(--lb-on-accent); border: 0; border-radius: 999px; padding: 11px 22px; font-family: inherit; font-size: 15px; font-weight: 600; cursor: pointer; }
.capture-form button:disabled { opacity: 0.6; cursor: default; }
.capture-status { margin: 12px 0 0; font-size: 14px; font-weight: 500; }
.capture-status[data-kind="ok"] { color: var(--lb-sage-dark); }
.capture-status[data-kind="err"] { color: var(--lb-danger-dark); }
.capture-status[data-kind="pending"] { color: var(--lb-text-muted); }
.capture-fine { margin: 12px 0 0; font-size: 12px; color: var(--lb-text-hint); }
.hp-field { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

/* [hidden] must actually hide — the same global rule src/style.css and
   src/landing.css carry, for the same reason: any author `display` rule beats
   the UA stylesheet's [hidden]{display:none}, and this file sets display on
   .post-grid, .pager, .capture-form and more. */
[hidden] { display: none !important; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 640px) {
  /* A phone column is ~354px, so the same 1.125rem lands near 35 characters per
     line — short, but short is the correct failure direction for a hand-held
     screen, and shrinking the type to lengthen the line trades comfort for a
     number. 1.0625rem is the compromise: still larger than the old 1rem. */
  .article-body { font-size: 1.0625rem; }
  .article-body > p:first-of-type { font-size: 1.18rem; }
  body { padding: 28px 18px 64px; }
  .featured { padding: 1.4rem 1.4rem; }
}
