/* Phase 2 article-line surfaces: UI-018 blog list, UI-019 article page and
   UI-020 author page on the M11-B2 contract. Frozen target:
   docs/design/ui-references/20260915-m11/index.html. Loads after
   content.css; tokens resolve via tokens.css. The shared layered head and
   press-card language live in public.css. */

/* ---------- UI-018 blog list ---------- */

.blog-header {
  display: grid;
  gap: var(--space-2);
}
.blog-positioning {
  color: var(--color-text-muted);
  font-size: var(--text-body);
}

/* The single featured latest article: the strong-frame block above the card
   grid (frozen UI-018 composition; the inner card drops its top rule). */
.featured {
  border: 1px solid var(--color-border-strong);
  border-top: 3px solid var(--color-accent);
  padding: 1.2rem 1.4rem;
  margin-bottom: 1.6rem;
}
.featured > .tag { display: block; margin-bottom: 0.5rem; }
.featured .press-card { border-top: 0; padding-top: 0.5rem; }
.featured .press-card h2 { font-size: 1.25rem; }
.featured .press-card p { font-size: 0.9rem; margin: 0 0 0.6rem; color: var(--color-text-muted); }

/* Blog-list rhythm (owner round 2026-09-21, de-crowding): the filter row
   becomes its own band under a rule; the featured block and the card grid
   step at the same 3rem section rhythm as the product pages; cards read as
   two wide editorial columns instead of three cramped ones. Scoped to
   .blog-list so the home hero, author page and product-related grids keep
   the shared press-card spacing. */
.blog-list .chips {
  gap: 0.8rem;
  padding-bottom: 1.6rem;
  margin-bottom: 3rem;
  border-bottom: 1px solid var(--color-border-strong);
}
.blog-list .chip { padding: 0.42rem 0.95rem; }
.blog-list .chip-divider { margin: 0 0.9rem; }

/* Owner round 2026-09-23 (revised): iPad widths (640-1023px) get a tidy
   two-row layout instead — columns on row 1, authors on row 2, separated by
   a full-width hairline (the old vertical divider reused as the break) — so
   every filter stays visible; the first cut (a single-line carousel at these
   widths) hid the author chips behind the fade and the owner read that as
   lost text. Below 640px the row genuinely cannot fit, so the filters become
   a single-line snap carousel — touch-scrollable, scrollbar hidden, fade
   masks at both ends. The row bleeds one --space-4 gutter into the container
   padding so the resting first chip stays on the page grid;
   scroll-padding-inline keeps snap stops on that same line. Desktop
   (>=1024px) keeps the wrap layout untouched. Pure CSS: the chips stay plain
   links, so touch and keyboard reachability are native. */
@media (min-width: 640px) and (max-width: 1023px) {
  .blog-list .chips { gap: 0.65rem; }
  .blog-list .chip-divider {
    flex-basis: 100%;
    width: auto;
    height: 1px;
    margin: 0.2rem 0 0.7rem;
    align-self: auto;
  }
}
@media (max-width: 639px) {
  .blog-list .chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--space-4);
    scrollbar-width: none;
    margin-inline: calc(var(--space-4) * -1);
    padding-inline: var(--space-4);
    -webkit-mask-image: linear-gradient(
      to right,
      transparent,
      #000 var(--space-4),
      #000 calc(100% - var(--space-4)),
      transparent
    );
    mask-image: linear-gradient(
      to right,
      transparent,
      #000 var(--space-4),
      #000 calc(100% - var(--space-4)),
      transparent
    );
  }
  .blog-list .chips::-webkit-scrollbar { display: none; }
  .blog-list .chips .chip {
    flex: none;
    white-space: nowrap;
    scroll-snap-align: start;
  }
  .blog-list .chips .chip-divider { flex: none; }
}
.blog-list .featured { padding: 1.8rem 2rem 2rem; margin-bottom: 3rem; }
.blog-list .featured > .tag { margin-bottom: 1.1rem; }
.blog-list .featured .press-card { padding-top: 0.6rem; }
.blog-list .featured .press-card h2 {
  font-size: 1.55rem;
  line-height: 1.32;
  margin: 0.6rem 0 0.8rem;
}
.blog-list .featured .press-card p {
  font-size: 0.98rem;
  line-height: 1.7;
  margin: 0 0 1.2rem;
  max-width: 62ch;
}
.blog-list .featured .press-card .meta {
  gap: 0.8rem;
  row-gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--color-border-strong);
}
.blog-list .cardgrid { grid-template-columns: repeat(2, 1fr); gap: 2.6rem 3rem; }
.blog-list .press-card { padding-top: 1.2rem; }
.blog-list .press-card .no { font-size: 0.86rem; }
.blog-list .press-card h2 {
  font-size: 1.3rem;
  line-height: 1.4;
  margin: 0.6rem 0 0.7rem;
}
.blog-list .press-card p {
  color: var(--color-text-muted);
  font-size: 0.95rem;
  line-height: 1.7;
  margin: 0 0 1rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.blog-list .press-card .meta { gap: 0.8rem; row-gap: 0.5rem; flex-wrap: wrap; }
@media (max-width: 640px) {
  /* Scoped override: the shared .cardgrid 1-col breakpoint (public.css) is
     less specific than .blog-list .cardgrid, so the mobile collapse is
     restated here. */
  .blog-list .cardgrid { grid-template-columns: 1fr; gap: 2.2rem; }
  .blog-list .chips { margin-bottom: 2.2rem; padding-bottom: 1.2rem; }
  .blog-list .featured { padding: 1.4rem 1.2rem 1.6rem; margin-bottom: 2.2rem; }
  .blog-list .featured .press-card h2 { font-size: 1.3rem; }
}

/* ---------- UI-019 article page ---------- */

/* Owner preview round 2026-09-23: the body drops the 85ch centered measure
   and rides the full article container (72rem, below) flush with the hero,
   figures and product cards — a look-and-decide state. The shared 70ch legal
   measure stays untouched for the legal pages. */
.article-body {
  max-width: none;
}
.article-page > .stale-bar {
  max-width: none;
}

/* Mono dates strip under the page head (published / updated / as-of). */
.dates {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.4rem;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--color-text-muted);
  margin-top: 1rem;
}
.dates b { color: var(--color-text); white-space: nowrap; }

/* Materially stale (MR-020): the amber bar states the freshness fact and the
   actions that re-verify it; the route stays readable but noindex. */
.stale-bar {
  background: var(--color-action-accent);
  color: var(--color-accent-ink);
  font-size: 0.84rem;
  font-weight: var(--weight-semibold);
  padding: 0.5rem 1rem;
  margin: 1.2rem 0;
}
.stale-bar a { color: inherit; }

/* M14: the page-level hero slot is the reference typographic art plate
   (aria-hidden; renderArtPlate paints the serial, label and note). */
.article-hero-typographic {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9; /* DS heroContract reservedAspectRatio (owner 2026-09-04) */
  width: 100%;
  margin-block: var(--space-5);
  overflow: hidden;
  border: 2px solid var(--color-text);
  background: var(--color-accent);
  color: var(--color-accent-ink);
  padding: var(--space-4);
  box-shadow: var(--shadow-press);
}
.article-hero-typographic .art-plate-serial,
.article-hero-typographic .art-plate-note {
  position: absolute;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.article-hero-typographic .art-plate-serial { left: var(--space-4); top: 0.8rem; }
.article-hero-typographic .art-plate-note { right: var(--space-4); bottom: 0.8rem; max-width: 18rem; text-align: right; }
.article-hero-typographic .art-plate-label {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 6vw, 4.8rem);
  font-weight: var(--weight-bold);
  line-height: 0.95;
  max-width: 8ch;
  text-align: center;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.article-hero-typographic::before,
.article-hero-typographic::after {
  content: "";
  position: absolute;
  background: var(--color-text);
}
.article-hero-typographic::before {
  width: 42%;
  height: 2px;
  left: 7%;
  top: 27%;
}
.article-hero-typographic::after {
  width: 2px;
  height: 58%;
  right: 17%;
  top: 16%;
}

/* Reference article body: 1.02rem/1.8 reading rhythm with display h2s. */
.article-body {
  font-size: 1.02rem;
  line-height: 1.8;
}
.article-body h2 {
  margin: 1.5rem 0 0.45rem;
  font-family: var(--font-display);
  font-size: 1.55rem;
  line-height: var(--leading-heading);
}
/* renderSafeMarkdown maps markdown ##/### to h3/h4 (level = hashes + 1), so
   the display treatment lives on h3 (section) and h4 (subsection) — the h2
   rule stays for any future direct h2 sources. */
.article-body h3 {
  margin: 1.5rem 0 0.45rem;
  font-family: var(--font-display);
  font-size: 1.55rem;
  line-height: var(--leading-heading);
}
.article-body h4 {
  margin: 1.2rem 0 0.4rem;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: var(--weight-semibold);
  line-height: var(--leading-heading);
}
.article-body h2:first-child {
  margin-top: 0;
}
.article-body p {
  margin: 0 0 var(--space-4);
}
.article-body ul {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
}

/* Sources block: the article's product citations in one mono panel. R9: it
   collapses into the end-of-article <details>, closed by default. */
.srcblock {
  border: 1px solid var(--color-border);
  padding: 1rem 1.2rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--color-text-muted);
  margin: 1.6rem 0 0;
}
.srcblock a { color: var(--color-accent-text); }
.srcblock-details { margin: var(--space-8) 0 0; }
.srcblock-details summary { cursor: pointer; font-family: var(--font-mono); font-size: 0.72rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--color-text-muted); }
.srcblock-details[open] summary { margin-bottom: 0.8rem; }
.srcblock-details .srcblock { margin: 0; }

/* Linked-product intro cards (owner revision 2026-09-21, R10): one card per
   mentioned product — name/institution, the first two key facts, and the
   visit CTA (the shared apply-cta component restyled card-local). */
.article-products { margin-top: var(--space-8); }
.article-product-grid { display: grid; gap: var(--space-5); }
/* Owner widen round 2026-09-23: the cards ride the widened container, so the
   grid steps 2-up at lg and 3-up at the 2xl shell — the same 3/2/1 rhythm as
   the product-list grid. Below 1024px it stays the single column. */
@media (min-width: 1024px) {
  .article-product-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1536px) {
  .article-product-grid { grid-template-columns: repeat(3, 1fr); }
}
.article-product-card { border: 1px solid var(--color-border-strong); border-top: 3px solid var(--color-text);
  padding: 1.1rem 1.2rem; }
.apc-head { display: flex; gap: 1rem; align-items: flex-start; }
/* Uniform card-frame slot (owner 2026-09-22 晚): the same fixed
   5.25rem × 1.586 (ID-1) cover rectangle as the list thumbs. */
.apc-thumb { flex: 0 0 auto; width: 5.25rem; aspect-ratio: 1.586; }
/* Institution-mark slot (owner round 2026-09-23): the 4.5×2.25rem
   alignment-box footprint (the base .inst-logo box) — the
   .inst-logo body styles live in content.css, already loaded on articles;
   the list rows carry their own slot overrides in product-rows.css. */
.apc-thumb--inst { width: 4.5rem; aspect-ratio: auto; }
.apc-title h3 { margin: 0; font-size: 1.05rem; line-height: 1.4; }
.apc-inst { margin: 0.2rem 0 0; font-size: var(--text-caption); color: var(--color-text-muted); }
.apc-facts { list-style: none; margin: 0.8rem 0 0; padding: 0; }
.apc-facts li { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.85rem;
  border-bottom: 1px dashed var(--color-border); padding: 0.3rem 0; }
.apc-facts .k { color: var(--color-text-muted); }
/* The shared apply-cta block drops its panel chrome inside the card. */
.article-product-card .apply-cta { border: 0; box-shadow: none; background: none; padding: 0; margin-top: 0.9rem; }
.article-product-card .apply-cta .btn { background: var(--color-surface); color: var(--color-text);
  border: 2px solid var(--color-text); box-shadow: none; }
.article-product-card .apply-cta .btn:hover { border-color: var(--color-accent-text); }
.article-product-card .apply-cta-note { margin: 0.5rem 0 0; font-size: var(--text-caption); color: var(--color-text-muted); }

/* Previous / next neighbors (navigation, so discovery-set articles only). */
.prevnext {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.86rem;
  margin-top: 2rem;
}
.article-adjacent-link {
  color: var(--color-accent-text);
  font-size: var(--text-label);
  text-decoration: none;
}
.article-adjacent-link:hover {
  color: var(--color-text);
}

/* ---------- UI-020 author page ---------- */

.profile-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.6rem;
  margin-bottom: var(--space-6);
}
.profile-cols h2 {
  font-family: var(--font-display);
  font-size: 1.05rem;
  border-bottom: 2px solid var(--color-text);
  padding-bottom: 0.4rem;
  margin-bottom: 0.7rem;
}
.profile-cols p {
  font-size: 0.9rem;
  color: var(--color-text-muted);
}
@media (max-width: 1024px) {
  .profile-cols { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .profile-cols { grid-template-columns: 1fr; }
}

/* ---------- UI-018/020 applied filter chips (shared with UI-016) ---------- */

.filter-chip {
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: var(--space-1) var(--space-4);
  border: 2px solid var(--color-text);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-label);
  text-decoration: none;
}
.filter-chip:hover {
  background: var(--color-accent-soft);
}
.filter-chip-active {
  /* Restrained selected state (行式 ledger refine 2026-09-24): the coral
     outline replaces the solid coral fill — the shared 2px frame
     vocabulary, selection read from the border color instead of a fill. */
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-accent);
}

/* PD-R8 article imagery (PRD-038): chosen hero covers, inline figures, and
   card heroes render as fixed-ratio images; the slot keeps its 16:9 shape so
   CLS stays bounded. Articles without images keep the typographic plate. */
.article-hero-image {
  display: block;
  width: 100%;
  /* The img width/height attributes pin the box as a presentational hint
     unless height is reset here; aspect-ratio then shapes the 16:9 slot. */
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius, 8px);
  margin: 0 0 var(--space-4, 1rem);
}

.article-figure {
  margin: var(--space-5, 1.5rem) 0;
}

.article-figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius, 8px);
}

.article-figure figcaption {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  color: var(--ink-muted, #5a5a5a);
}

.press-card .card-hero {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px 8px 0 0;
  margin: 0 0 0.75rem;
}

/* Insights-only container widen. :has() keeps home / product-list / method
   and the blog-closed page on the shared tokens (do not bump those). */
.container:has(> .block.blog-list) {
  max-width: 75rem;
}
/* Owner round 2026-09-23 (revised): both article containers (the body
   container and the layered head's own sibling container, matched by the
   adjacent-sibling :has()) match the category list pages' content container
   (72rem) — the first cut rode the wider header shell and read too wide.
   The reading measure stays 75ch on .article-body above; :has() keeps home /
   product-list / method and the blog-closed page on the shared tokens. */
.container.container-narrow:has(.article-page),
.layered-article:has(+ .container .article-page) .container.container-narrow {
  max-width: var(--size-container-content);
}
