/* =========================================================================
   Page — the developer blog ({en,de}/blog.html, {en,de}/blog-post.html)
   -------------------------------------------------------------------------
   ONE FILE FOR TWO PAGES, and the reason is `apps.css`'s: `pages/` is split so
   two page BRANCHES do not edit one file, and these two ship in one branch as
   one surface. The index card and the article body are the same typography
   rendered at two sizes; splitting them would be two places to keep a reading
   measure in step.

   The grammar is DESIGN_TOKENS.md §9:

   DEPTH (§9.1). A card rests on `--doc-panel`. What recedes inside it — a code
   block, a quote's rule — uses `--sd-sunk`, which is between the page ground and
   the surface in BOTH themes. No shadows.

   COLOUR (§9.3). An article carries a category and any number of tags, and
   EVERY ONE OF THEM IS A FACET — something the post IS. None gets a semantic
   colour, so an index of twelve cards carrying four chips each has zero tinted
   areas rather than forty-eight. There is no state on this surface to spend an
   accent on: a published post is the only kind of post a reader can see.

   MEASURE. An article column is capped at 68ch. A line of prose that runs the
   width of a 1400 px window is not a line anybody finishes.
   ========================================================================= */

/* ---- Shared rows ---------------------------------------------------------- */

.blog-subscribe,
.blog-active-filter {
  margin: 0 0 16px;
  color: var(--doc-ink-soft);
  font-size: 14px;
}

.blog-feed-link,
.blog-clear-filter {
  font-weight: 600;
}

.blog-count {
  margin: 0 0 16px;
  color: var(--doc-ink-soft);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.blog-count:empty {
  display: none;
}

/* ---- The index list ------------------------------------------------------- */

.blog-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.blog-post-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.blog-card-title {
  margin: 0;
  font-size: 21px;
  line-height: 1.3;
}

.blog-card-link {
  color: var(--doc-ink);
  text-decoration: none;
}

.blog-card-link:hover,
.blog-card-link:focus-visible {
  color: var(--sd-secondary);
  text-decoration: underline;
}

/* No `color` here: `.card > p` in `card.css` is (0,1,1) and this is (0,1,0), so
   a colour written here would do nothing while looking as though it did
   (L-FE-49). The token it resolves to, `--doc-ink-soft`, is the weight a
   summary wants anyway. */
.blog-summary {
  margin: 0;
  line-height: 1.6;
  max-width: 68ch;
}

/* ---- The meta line -------------------------------------------------------- *
 * Author · date · reading time, separated by a rule rather than by a character
 * a screen reader reads out. `::before` on every item but the first gives the
 * separator no text node at all.
 * ------------------------------------------------------------------------- */

.blog-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin: 0;
  font-size: 13px;
}

.blog-meta > * + *::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 12px;
  margin-right: 14px;
  vertical-align: -2px;
  background: var(--sd-border);
}

.blog-author {
  font-weight: 600;
  color: var(--sd-text);
}

/* §9.5 — a date and a count of minutes are figures a reader compares down a
   column of cards, so they line up as columns. */
.blog-date,
.blog-reading {
  color: var(--doc-ink-soft);
  font-variant-numeric: tabular-nums;
}

/* ---- Facets --------------------------------------------------------------- */

.blog-facets {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.blog-facet-link {
  text-decoration: none;
}

.blog-facet-link:hover,
.blog-facet-link:focus-visible {
  border-color: var(--sd-secondary);
  color: var(--sd-text);
}

/* A tag is a slug — an identifier, never prose — so it is set in the face that
   says so. §9.5: `--mono` where characters are compared one by one. */
.blog-tag {
  font-family: var(--mono);
  font-size: 11.5px;
}

.blog-language {
  margin: 0;
  font-size: 13px;
}

/* ---- The article ---------------------------------------------------------- */

.blog-breadcrumb {
  padding: 20px 0 0;
  font-size: 13px;
  color: var(--doc-ink-soft);
}

.blog-breadcrumb ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
}

.blog-breadcrumb li + li::before {
  content: "/";
  margin-right: 8px;
  color: var(--sd-muted);
}

.blog-article-column {
  max-width: 76ch;
}

.blog-page-heading {
  margin: 0 0 16px;
  font-size: 34px;
  line-height: 1.2;
  color: var(--doc-ink);
}

.blog-lede {
  margin: 16px 0 0;
  font-size: 18px;
  line-height: 1.6;
  color: var(--sd-text-soft);
}

.blog-body {
  margin-top: 32px;
}

.blog-paragraph {
  margin: 0 0 18px;
  line-height: 1.75;
  color: var(--sd-text-soft);
}

.blog-heading {
  margin: 36px 0 12px;
  line-height: 1.3;
  color: var(--doc-ink);
}

.blog-list {
  margin: 0 0 18px;
  padding-left: 22px;
  line-height: 1.75;
  color: var(--sd-text-soft);
}

.blog-list li {
  margin-bottom: 6px;
}

/* A quote is set into the page rather than raised off it: the recess ground and
   ONE hairline on the leading edge (§9.1, §9.2). No shadow, no second border. */
.blog-quote {
  margin: 0 0 18px;
  padding: 14px 18px;
  border-left: 3px solid var(--sd-secondary);
  background: var(--sd-sunk);
  border-radius: 0 var(--radius) var(--radius) 0;
}

.blog-quote p {
  margin: 0 0 10px;
  line-height: 1.7;
  color: var(--sd-text-soft);
}

.blog-quote p:last-child {
  margin-bottom: 0;
}

.blog-rule {
  margin: 32px 0;
  border: 0;
  border-top: 1px solid var(--doc-line);
}

/* A code block scrolls inside itself, so a long line never makes the page body
   scroll sideways (guideline §9, audit rule H-5). */
.blog-code {
  margin: 0 0 18px;
  padding: 16px 18px;
  background: var(--doc-code-bg);
  border: 1px solid var(--doc-line);
  border-radius: var(--radius);
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.65;
  color: var(--doc-ink);
}

.blog-code code {
  font-family: inherit;
  white-space: pre;
}

.blog-code-inline {
  font-family: var(--mono);
  font-size: .92em;
  padding: 1px 5px;
  background: var(--sd-sunk);
  border: 1px solid var(--sd-divider);
  border-radius: 4px;
  color: var(--doc-ink);
  /* An identifier inside a sentence must be able to break, or a long one makes
     the column wider than the page (H-5, from the other direction). */
  word-break: break-word;
}

.blog-link {
  color: var(--sd-secondary);
}

/* A paragraph that is only a link to a file (`blocks.js`, U-860). Two lines —
   label and the author's platform-and-size note — so `.btn`'s fixed height
   and single line are lifted; at 320 px the note wraps inside the button. */
.blog-download {
  margin: 0 0 18px;
}

.blog-download-button {
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  height: auto;
  max-width: 100%;
  padding: 10px 18px;
  line-height: 1.3;
  text-align: left;
}

.blog-download-note {
  font-size: 13px;
  font-weight: 400;
}

.blog-back {
  margin: 40px 0 0;
}

/* ---- Continuation --------------------------------------------------------- */

.blog-more {
  display: flex;
  justify-content: center;
  margin-top: 32px;
}

.blog-more[hidden] {
  display: none;
}

/* ---- The no-JavaScript fallback ------------------------------------------- */

.blog-fallback {
  padding: 24px;
  background: var(--sd-sunk);
  border: 1px solid var(--doc-line);
  border-radius: var(--radius-lg);
}

.blog-fallback p {
  margin: 0 0 12px;
  color: var(--sd-text-soft);
  line-height: 1.65;
  max-width: 68ch;
}

.blog-fallback .cta-actions {
  margin-top: 20px;
}

/* ---- Narrow ---------------------------------------------------------------- */

@media (max-width: 640px) {
  .blog-page-heading {
    font-size: 27px;
  }

  .blog-card-title {
    font-size: 19px;
  }

  .blog-lede {
    font-size: 16px;
  }
}
