/* =========================================================================
   DHD — phase-2 components: preview bar, rows, highlights, topics, filters,
   collections, archive, principles, about. Loaded after base.css on public pages.
   ========================================================================= */

/* ---- Preview bar (admin, pre-launch) ------------------------------------ */
/* Reuses the amber status tokens — "you're viewing a non-public state" is
   an advisory notice, not a brand accent. */
.preview-bar {
  background: var(--lic-amber-tint); color: var(--lic-amber-ink);
  border-bottom: 1px solid var(--lic-amber-border);
  font-family: var(--font-body); font-weight: 700; font-size: var(--fs-200);
  display: flex; gap: 16px; align-items: center; justify-content: center;
  padding: 10px 16px; flex-wrap: wrap;
}
.preview-bar a { color: var(--lic-amber-ink); }

/* ---- Section helpers ---------------------------------------------------- */
.section--tint { background: var(--surface); }
.section__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 8px;
}
.section__head h2 { font-size: var(--fs-800); line-height: 1.15; letter-spacing: -0.03em; color: var(--navy); margin-top: 10px; }
.eyebrow + h2, .eyebrow + h1 { margin-top: 12px; }

.page-title { font-size: var(--fs-900); line-height: 0.98; letter-spacing: -0.04em; color: var(--navy); margin-top: 14px; }
.page-intro { font-size: var(--fs-400); color: var(--secondary-text); max-width: 62ch; margin: 16px 0 0; }
/* Readable-width pages: keep the container's left edge on the wordmark, cap the
   content width left-aligned (never centre it inboard of the wordmark). */
.container.narrow { max-width: var(--maxw); }
.container.narrow > * { max-width: 900px; }

/* ---- Pills / chips (public) -------------------------------------------- */
.type-pill {
  display: inline-block; font-family: var(--font-body); font-weight: 700; font-size: var(--fs-100);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--navy);
  border: 1px solid var(--navy); border-radius: var(--radius-pill); padding: 3px 10px;
}
/* ---- Library (reference cards) ------------------------------------------ */
/* One card component (`resource_card()` in includes/ui.php) on the Library, Home "Start here" and a
   Showcase's related list. Type accent is decoration only — the type name is always written out. */
.lib-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 28px; padding-top: 22px; border-top: 1px solid var(--card-border); }
.lib-tab {
  display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 8px 16px;
  border: 1.5px solid var(--ui-border); border-radius: var(--radius-pill); background: #fff; color: var(--navy);
  font-weight: 600; font-size: var(--fs-300); text-decoration: none; white-space: nowrap;
}
.lib-tab:hover { border-color: var(--navy); }
.lib-tab__n { font-weight: 500; color: var(--meta-text); }
.lib-tab--start { border-color: var(--cyan); box-shadow: inset 0 0 0 1px var(--cyan); }
.lib-tab[aria-current="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.lib-tab[aria-current="true"] .lib-tab__n { color: var(--on-navy-body); }
.lib-filters { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-top: 16px; }
.lib-filters .search-field { flex: 1 1 260px; }
.lib-filters .topic-select { flex: 0 0 auto; }
.lib-status { margin: 14px 0 0; font-size: var(--fs-200); color: var(--meta-text); }

.lib-group { margin-top: 44px; }
.lib-group__head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; padding-bottom: 12px; border-bottom: 1px solid var(--card-border); }
.lib-group__title { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-700); letter-spacing: -0.022em; color: var(--navy); }
.lib-group__count { margin-left: 6px; font-family: var(--font-body); font-weight: 500; font-size: var(--fs-400); color: var(--meta-text); }
.lib-group__blurb { margin: 0; font-size: var(--fs-300); color: var(--meta-text); }

.lib-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 22px; }
.lib-grid--mini { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.lib-grid--mini.lib-grid--thirds { grid-template-columns: repeat(3, minmax(0, 1fr)); } /* a count divisible by 3 (6 types) → 3 × 2, not 4 + 2 */

.lib-card {
  --accent: var(--navy);
  display: flex; flex-direction: column; background: #fff; text-decoration: none; color: inherit;
  border: 1px solid var(--card-border-2); border-top: 3px solid var(--accent); border-radius: var(--radius-md);
  padding: 18px 20px 16px; transition: border-color 150ms ease-out, transform 150ms ease-out;
}
.lib-card--civic { --accent: var(--civic-blue); }
.lib-card--teal  { --accent: var(--teal-ink); }
.lib-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.lib-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.lib-card__body { display: block; flex: 1 1 auto; }
.lib-card__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.lib-card__type {
  display: inline-flex; align-items: center; gap: 9px; font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-100); line-height: 1; letter-spacing: 0.09em; text-transform: uppercase; color: var(--label-text);
}
.lib-card__icon { flex: none; width: 32px; height: 32px; border-radius: var(--radius-sm); background: var(--ice); color: var(--accent); display: grid; place-items: center; }
.lib-card__icon svg { width: 18px; height: 18px; }
.lib-card__title { display: block; margin: 14px 0 4px; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); line-height: 1.2; letter-spacing: -0.01em; color: var(--navy); }
.lib-card:hover .lib-card__title { color: var(--civic-blue); }
.lib-card__src { display: block; font-size: var(--fs-200); color: var(--meta-text); }
.lib-card__lead { display: block; margin: 12px 0 0; font-weight: 600; font-size: var(--fs-300); line-height: 1.45; color: var(--body-text); }
.lib-card__more { display: block; margin: 6px 0 0; font-size: var(--fs-300); line-height: 1.5; color: var(--secondary-text); }
.lib-card__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 16px;
  padding-top: 12px; border-top: 1px dashed var(--card-border-2);
}
.lib-chip { font-size: var(--fs-100); font-weight: 600; padding: 3px 9px; border-radius: var(--radius-pill); background: var(--ice); border: 1px solid var(--ui-border-navy); color: var(--navy); white-space: nowrap; }
.lib-card__checked { margin-left: auto; font-size: var(--fs-100); color: var(--meta-text); white-space: nowrap; }
.lib-card__ext { flex: none; width: 16px; height: 16px; color: var(--civic-blue); }
/* Compact variant: Home "Start here" and Showcase related. */
.lib-card--mini { gap: 8px; padding: 16px 16px 14px; }
.lib-card--mini .lib-card__title { margin: 0; font-size: var(--fs-500); }
.lib-card--mini .lib-card__licence { margin-top: 2px; }

.lib-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; margin: 20px 0 0; font-size: var(--fs-100); color: var(--meta-text); }
.lib-legend__label { font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--navy); }
.lib-legend__item { display: inline-flex; align-items: center; gap: 6px; }

/* Small ↗ glyph after an outbound title (Community, Jobs, Tools, admin). */
.res-row__out { color: var(--civic-blue); font-size: var(--fs-300); }

/* ---- What you'll find (Home, category cards) ------------------------------
   One card per section. Big card, quiet colours: white ground, hairline border, civic-blue icon + arrow.
   Small line above the name is the admin-editable description (wyf_descN); blank = line hidden. */
.wyf { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 16px; }
.wyf > :only-child { max-width: 440px; } /* only reachable if Admin blanks every chip but one - same auto-fit fix, see conventions.md "Front-end conventions" */
@media (min-width: 900px) { .wyf--thirds { grid-template-columns: repeat(3, minmax(0, 1fr)); } } /* 6 cards → 3 × 2, not 5 + 1 (same idea as .lib-grid--thirds) */
.wyf-card {
  display: flex; flex-direction: column; min-height: 152px; padding: 20px;
  border: 1px solid var(--card-border); border-radius: var(--radius-lg); background: #fff;
  text-decoration: none; color: var(--navy);
  transition: transform 150ms ease-out, border-color 150ms ease-out, background 150ms ease-out;
}
.wyf-card:hover { border-color: var(--civic-blue); background: var(--ice); transform: translateY(-1px); }
.wyf-card:focus-visible { border-radius: var(--radius-lg); } /* keep the corner: the global a:focus-visible sets 4px */
/* Top-aligned: the description and the name start at the same height in every card, so a name that wraps
   to two lines grows downward instead of pushing its own description up out of line with its neighbours. */
.wyf-card__icon { display: block; width: 30px; height: 30px; flex: none; margin-bottom: 18px; color: var(--civic-blue); }
.wyf-card__icon svg { display: block; }
.wyf-card__desc {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-100); letter-spacing: 0.09em; text-transform: uppercase; color: var(--label-text);
}
.wyf-card__row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-top: 6px; }
.wyf-card__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); line-height: 1.2; letter-spacing: -0.01em; }
.wyf-card__arrow {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px; margin-top: -2px; /* centres on the name's first line */
  border-radius: var(--radius-pill);
  background: var(--ice); color: var(--civic-blue); font-size: var(--fs-300); line-height: 1;
  transition: background 150ms ease-out, color 150ms ease-out;
}
.wyf-card:hover .wyf-card__arrow { background: var(--civic-blue); color: #fff; }
/* Phones: a horizontal row (~77px) instead of 4-5 tall blocks stacked. */
@media (max-width: 560px) {
  .wyf { grid-template-columns: 1fr; gap: 12px; }
  .wyf-card {
    min-height: 0; display: grid; grid-template-columns: 30px 1fr 30px; grid-template-areas: "i l g" "i n g";
    column-gap: 16px; align-items: center; padding: 14px 16px;
  }
  .wyf-card__icon { grid-area: i; margin-bottom: 0; }
  .wyf-card__desc { grid-area: l; }
  .wyf-card__row { display: contents; }
  .wyf-card__label { grid-area: n; margin-top: 2px; }
  .wyf-card__arrow { grid-area: g; margin-top: 0; }
}

/* ---- CTA band ----------------------------------------------------------- */
.cta-band { background: var(--cta-grad); border-radius: var(--radius-xl); padding: 32px; color: #fff;
  display: grid; grid-template-columns: minmax(0,1.3fr) minmax(0,1fr); gap: 32px; align-items: center; }
.cta-band--slim { padding: 26px 32px; }
.cta-band__title { font-size: var(--fs-800); line-height: 1.15; letter-spacing: -0.03em; color: #fff; }
.cta-band__title .accent { color: var(--cyan); }
.cta-band__sub { color: var(--on-navy-body); font-size: var(--fs-300); margin: 10px 0 0; }
.cta-band__capture { display: flex; gap: 10px; flex-wrap: wrap; }
.cta-band__capture .input { border-color: transparent; border-radius: var(--radius-md); flex: 1; min-width: 200px; }

/* ---- Filter bar --------------------------------------------------------- */
.filter-bar { padding: 16px 0; margin-top: 8px; }
.filter-bar__row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.filter-bar__row + .filter-bar__row { margin-top: 14px; }
.search-field { position: relative; flex: 1; min-width: 240px; display: flex; align-items: center; }
.search-field svg { position: absolute; left: 12px; color: var(--meta-text); pointer-events: none; }
.search-field .input { padding-left: 40px; border-width: 1.5px; }
.type-select, .topic-select { width: auto; min-width: 150px; padding: 9px 12px; }
.no-results { color: var(--meta-text); padding: 32px 0; text-align: center; }

/* ---- Archive ------------------------------------------------------------ */
.issue-list { margin-top: 24px; }
.issue-row { display: grid; grid-template-columns: 130px minmax(0,1fr) 120px; gap: 24px; align-items: start;
  padding: 26px 8px; border-top: 1px solid var(--navy); text-decoration: none; color: inherit;
  transition: background 150ms ease-out; }
.issue-row:last-child { border-bottom: 1px solid var(--navy); }
.issue-row:hover { background: var(--ice); }
.issue-row__num { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-700); color: var(--civic-blue); }
.issue-row__date { display: block; font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.08em; color: var(--label-text); margin-top: 4px; }
.issue-row__title { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-700); letter-spacing: -0.02em; color: var(--navy); }
.issue-row__blurb { display: block; font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); margin: 8px 0; }
.issue-row__meta { display: block; font-size: var(--fs-200); font-weight: 600; color: var(--meta-text); }
.issue-row__cta { font-weight: 700; color: var(--link-text); border-bottom: 2px solid var(--cyan); align-self: center; justify-self: end; }

/* ---- Principles page ---------------------------------------------------- */
.principles-hero {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--hero-grad); background-size: 200% 200%;
  animation: heroPan 22s ease-in-out infinite; color: #fff; padding: 76px 0;
}
.principles-hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(rgba(255,255,255,0.16) 1.3px, transparent 1.4px);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(120% 120% at 100% 0%, #000 30%, transparent 72%);
          mask-image: radial-gradient(120% 120% at 100% 0%, #000 30%, transparent 72%);
  pointer-events: none;
}
.principles-hero .container { position: relative; }
@media (prefers-reduced-motion: reduce) { .principles-hero { animation: none; } }
.principles-hero__h1 { font-size: var(--fs-900); line-height: 1.0; letter-spacing: -0.04em; color: #fff; max-width: 24ch; margin: 16px 0 0; }
.principles-hero__sub { color: var(--on-navy-body); font-size: var(--fs-400); line-height: 1.6; max-width: 60ch; margin: 18px 0 0; }
.principle-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px,1fr)); gap: 20px; }
.principle-grid > :only-child { max-width: 440px; } /* auto-fit + one card = full-width card - see conventions.md "Front-end conventions" */
.principle-card { border: 1px solid var(--card-border); border-radius: var(--radius-xl); overflow: hidden; background: #fff; }
.principle-card__head { height: 132px; display: flex; align-items: center; padding: 0 24px; }
.principle-card__head--navy { background: var(--navy); color: #fff; }
.principle-card__head--ice { background: var(--ice); color: var(--navy); }
.principle-card__head--teal { background: var(--teal-grad); color: #fff; }
.principle-card__icon { width: 38px; height: 38px; display: inline-flex; }
.principle-card__icon svg { width: 100%; height: 100%; }
.principle-card__body { padding: 22px 24px 26px; }
.principle-card__body h2 { font-size: var(--fs-600); letter-spacing: -0.02em; color: var(--navy); }
.principle-card__body p { font-size: var(--fs-300); line-height: 1.65; color: var(--secondary-text); margin: 10px 0 0; }
/* Qualified with the element type: ".principle-card__body p" (a class+type
   selector) otherwise outranks the plain class below it and wins the colour. */
p.principle-card__source { color: var(--lic-amber-ink); border-left: 3px solid var(--ui-border); padding-left: 12px; margin-top: 16px !important;
  font-style: italic; }

/* ---- About -------------------------------------------------------------- */
.about-grid { display: grid; grid-template-columns: minmax(0,1.3fr) minmax(0,1fr); gap: 48px; align-items: start; }
.about-grid--single { grid-template-columns: minmax(0, 1fr); } /* no cards: one reading column */
.about-grid--single .about-main { max-width: 760px; }
.about-lead { font-size: var(--fs-600); line-height: 1.7; color: var(--body-text); max-width: 60ch; margin: 16px 0 0; }
.about-body { font-size: var(--fs-400); line-height: 1.7; color: var(--secondary-text); max-width: 60ch; margin: 16px 0 0; }
.about-body a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--lic-green);
  text-underline-offset: 3px;
}
.about-covers { margin: 20px 0 0; padding-left: 0; list-style: none; max-width: 60ch; display: flex; flex-direction: column; gap: 12px; }
.about-covers li { font-size: var(--fs-400); line-height: 1.65; color: var(--secondary-text); }
.about-covers strong { color: var(--navy); }
.about-fine-print { font-size: var(--fs-200); line-height: 1.5; color: var(--secondary-text); margin: 16px 0 0; }
.about-actions { display: flex; gap: 20px; align-items: center; margin-top: 28px; }
.about-side { display: flex; flex-direction: column; gap: 20px; }

/* Contact page */
.contact-form { display: flex; flex-direction: column; gap: 20px; max-width: 560px; margin-top: 32px; }
.contact-form textarea.input { resize: vertical; min-height: 140px; }
.contact-msg { max-width: 560px; margin-top: 32px; }
.contact-alt { max-width: 560px; margin: 32px 0 0; font-size: var(--fs-300); line-height: 1.65; color: var(--secondary-text); }
/* About: link cards in the right column (icon, title, one line, arrow) */
.side-link {
  display: flex; align-items: center; gap: 14px;
  border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 18px 20px;
  text-decoration: none; color: var(--navy); background: #fff;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.side-link:hover { border-color: var(--civic-blue); background: var(--ice); }
.side-link > svg { flex: 0 0 auto; color: var(--civic-blue); }
.side-link__text { flex: 1 1 auto; min-width: 0; }
.side-link__title { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); line-height: 1.25; }
.side-link__desc { display: block; margin-top: 3px; font-size: var(--fs-300); line-height: 1.5; color: var(--secondary-text); }
.side-link__arrow { flex: 0 0 auto; color: var(--civic-blue); }

/* ---- Responsive (phase 2) ---------------------------------------------- */
@media (max-width: 980px) {
  .lib-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lib-grid--mini, .lib-grid--mini.lib-grid--thirds { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .cta-band, .about-grid { grid-template-columns: 1fr; }
  .page-title, .principles-hero__h1 { font-size: var(--fs-850); }
}
@media (max-width: 640px) {
  .lib-grid, .lib-grid--mini, .lib-grid--mini.lib-grid--thirds { grid-template-columns: 1fr; }
  .lib-tabs { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 6px; margin-right: calc(var(--gutter) * -1); }
  .lib-filters .search-field, .lib-filters .topic-select { flex: 1 1 100%; }
  .issue-row { grid-template-columns: 1fr; gap: 8px; }
  .issue-row__cta { justify-self: start; }
}

/* ---- Foundations page --------------------------------------------------- */
.fn-hero {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--hero-grad); background-size: 200% 200%;
  animation: heroPan 22s ease-in-out infinite; color: #fff; padding: 76px 0;
}
.fn-hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(rgba(255,255,255,0.16) 1.3px, transparent 1.4px);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(120% 120% at 100% 0%, #000 30%, transparent 72%);
          mask-image: radial-gradient(120% 120% at 100% 0%, #000 30%, transparent 72%);
  pointer-events: none;
}
.fn-hero .container { position: relative; }
@media (prefers-reduced-motion: reduce) { .fn-hero { animation: none; } }
.fn-hero__h1 { font-size: var(--fs-900); line-height: 1.0; letter-spacing: -0.04em; color: #fff; max-width: 28ch; margin: 16px 0 0; }
.fn-hero__sub { color: var(--on-navy-body); font-size: var(--fs-400); line-height: 1.6; max-width: 62ch; margin: 18px 0 0; }
.fn-series-nav {
  display: grid; grid-template-columns: 1fr 1fr; gap: 20px;
  margin-top: 48px; padding-top: 28px; border-top: 1px solid var(--card-border);
}
.fn-series-nav__link {
  display: flex; flex-direction: column; gap: 4px; padding: 16px 20px;
  border: 1px solid var(--card-border); border-radius: var(--radius-lg);
  text-decoration: none; color: inherit;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.fn-series-nav__link:hover { border-color: var(--civic-blue); background: var(--ice); }
.fn-series-nav__label { font-size: var(--fs-200); font-weight: 700; color: var(--civic-blue); }
.fn-series-nav__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); }
.fn-series-nav__next { text-align: right; }
@media (max-width: 900px) {
  .fn-hero__h1 { font-size: var(--fs-850); }
}
@media (max-width: 640px) {
  .fn-series-nav { grid-template-columns: 1fr; }
}

/* =========================================================================
   Showcase — featured band, index tiles, and the breakdown detail page.
   ========================================================================= */

/* ---- Showcase cards (Home + index) — article cards with a thumbnail ----- */
/* Every small card is one height (owner 2026-10-07): grid-auto-rows: 1fr makes each row as tall as the tallest, not just the cards in the same row. */
.sc-cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); grid-auto-rows: 1fr; gap: 22px; margin-top: 24px; }
.sc-cards-grid > :only-child { max-width: 440px; } /* auto-fit stretches a lone card to fill the row - cap it, same fix as .sc-related below */
.sc-card2 {
  display: flex; flex-direction: column; background: #fff;
  border: 1px solid var(--card-border); border-radius: var(--radius-xl); overflow: hidden;
  text-decoration: none; color: inherit;
  transition: transform 150ms ease-out, border-color 150ms ease-out;
}
.sc-card2:hover { transform: translateY(-4px); border-color: var(--civic-blue); }
.sc-card2.is-soon { opacity: 0.82; }
/* Thumbnail from a stored 'image' path (an entry that carries its own picture). Every other card uses the generated
   .sc-thumb below. */
.sc-card2__thumb {
  position: relative; aspect-ratio: 16 / 9; display: flex; align-items: center; justify-content: center;
  overflow: hidden; background: var(--hero-grad);
}
.sc-card2__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sc-card2__thumb::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,0.16) 1.1px, transparent 1.2px);
  background-size: 20px 20px;
  -webkit-mask-image: radial-gradient(120% 120% at 100% 0%, #000 15%, transparent 72%);
          mask-image: radial-gradient(120% 120% at 100% 0%, #000 15%, transparent 72%);
}
.sc-card2__thumb:has(img)::before { display: none; }
/* ---- Card thumbnail from the Thumbnail system (owner decision 2026-10-06; markup: showcase_thumb_html in includes/ui.php) ----
   One signal per axis, so a grid of 17 stays calm: the GROUND is the entry's domain (includes/thumbnails.php
   THUMB_DOMAIN_GROUND), the way the picture SITS is its kind (peek / specimen / window). No chip and no text on the
   image - the card body already carries both. The picture is the real After side of the entry's own mockup, 400px
   wide exactly as the detail page draws it, rebuilt on every request and scaled to the card with container query
   units. Its header bar is hidden and its numbered pins are dropped in PHP: at this size they are not readable and only add noise. */
.sc-thumb { position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden; container-type: inline-size; background: var(--footer-ground); }
.sc-thumb__ground { position: absolute; inset: 0; }
.sc-thumb__ground .thumbsys { position: absolute; inset: 0; width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
.sc-thumb__fallback { position: absolute; inset: 0; z-index: 6; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,0.92); }
.sc-thumb__mini { position: absolute; z-index: 6; top: 13%; width: 400px; transform-origin: 0 0; pointer-events: none; user-select: none; }
.sc-thumb__mini .mock-head { display: none; }
.sc-thumb__mini .screen { border: 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; min-height: 300px; }   /* always taller than the frame, so a short mockup (Reading age, Consent) still bleeds off the bottom edge like every other card */
.sc-thumb--peek .sc-thumb__mini, .sc-thumb--window .sc-thumb__mini { left: 8%; transform: scale(0.8); }   /* fallback: a fixed 80% where the container-unit maths below is not supported */
.sc-thumb--window .sc-thumb__mini::before {
  content: ""; display: block; height: 16px; background-color: var(--disabled-bg);
  background-image: radial-gradient(circle at 10px 8px, var(--ui-border) 3px, transparent 3.5px), radial-gradient(circle at 22px 8px, var(--ui-border) 3px, transparent 3.5px), radial-gradient(circle at 34px 8px, var(--ui-border) 3px, transparent 3.5px);
}
.sc-thumb--window .sc-thumb__mini .screen { border-radius: 0; }
/* The bottom 30% of the picture fades into the dark ground. Without it the white window runs straight into the white card body and the
   card has no edge between picture and text (owner picked this of five options on 2026-10-06; the others were a line, a gradient strip
   and a tinted body). Navy = --navy, as --hero-scrim. Peek and window only: a component (specimen) is shown whole and never reaches the edge. */
.sc-thumb--peek::after, .sc-thumb--window::after {
  content: ""; position: absolute; z-index: 7; left: 0; right: 0; bottom: 0; height: 30%; pointer-events: none;
  background: linear-gradient(rgba(11, 47, 94, 0), rgba(11, 47, 94, 0.92));
}
@supports (scale: calc(tan(atan2(86cqw, 400px)))) {
  .sc-thumb--peek .sc-thumb__mini   { left: 7cqw;  transform: none; scale: calc(tan(atan2(86cqw, 400px))); }
  .sc-thumb--window .sc-thumb__mini { left: 14cqw; transform: none; scale: calc(tan(atan2(100cqw, 400px))); }
}
/* Component: one part, whole, in a dashed measuring frame - never cropped */
.sc-thumb--specimen .sc-thumb__spec {
  position: absolute; z-index: 6; left: 50%; top: 53%; transform: translate(-50%, -50%); background: #fff; border-radius: 0.8em;
  padding: 1.05em 1.45em; display: grid; grid-template-columns: auto auto; gap: 0.8em 1.7em; font-size: 12px;
}
@supports (font-size: 1cqw) { .sc-thumb--specimen .sc-thumb__spec { font-size: 3.9cqw; } }
.sc-thumb--specimen .sc-thumb__spec .rs { font-size: 1em; gap: 0.5em; }
.sc-thumb--specimen .sc-thumb__spec .rs__mark { width: 0.85em; height: 0.85em; }
.sc-thumb--specimen .sc-thumb__spec::before { content: ""; position: absolute; inset: -0.9em; border: 1.5px dashed rgba(255,255,255,0.55); border-radius: 1.1em; pointer-events: none; }
.sc-card2--gen .sc-card2__thesis { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Phone: a compact row (picture left, title right) instead of a 440px-tall card - 17 entries read as one short list.
   Every row is as tall as the tallest one (the grid-auto-rows: 1fr above, 135px today) so the list reads as even steps, not a ragged one
   (owner 2026-10-07: "same height"); nothing is clamped, so no title or standard code is cut.
   Not on Home: its Showcase teaser is only 3 cards and keeps the full-size card on a phone (owner 2026-10-07, "keep the big card for me"),
   marked with .sc-cards-grid--big, so every rule below is scoped to the grids that are NOT --big. */
@media (max-width: 640px) {
  .sc-cards-grid { gap: 12px; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen { flex-direction: row; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-thumb { aspect-ratio: auto; width: 112px; flex: none; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-card2__body { padding: 12px 14px; gap: 4px; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-card2__standard { font-size: var(--fs-500); }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-card2__thesis, .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-card2__tags, .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-card2__cta { display: none; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-card2--gen .sc-card2__foot { padding-top: 0; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--peek .sc-thumb__mini   { left: 4%; top: 22%; transform: scale(0.26); }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--window .sc-thumb__mini { left: 8%; top: 20%; transform: scale(0.26); }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--specimen .sc-thumb__spec { font-size: 7px; }
  .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--peek::after, .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--window::after { display: none; }   /* no stacked edge in a row: the picture sits beside the text */
  @supports (scale: calc(tan(atan2(86cqw, 400px)))) {
    .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--peek .sc-thumb__mini   { left: 4cqw; top: 22%; transform: none; scale: calc(tan(atan2(92cqw, 400px))); }
    .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--window .sc-thumb__mini { left: 8cqw; top: 20%; transform: none; scale: calc(tan(atan2(100cqw, 400px))); }
  }
  @supports (font-size: 1cqw) { .sc-cards-grid:not(.sc-cards-grid--big) .sc-thumb--specimen .sc-thumb__spec { font-size: 6.2cqw; } }
}
/* Body */
.sc-card2__body { display: flex; flex-direction: column; gap: 8px; padding: 20px 22px 22px; flex: 1; }
.sc-card2__code { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--civic-blue); }
.sc-card2__standard { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); line-height: 1.15; letter-spacing: -0.025em; color: var(--navy); }
.sc-card2__thesis { font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); }
.sc-card2__tags { display: flex; flex-wrap: wrap; gap: 6px; }
.sc-card2__foot { margin-top: auto; padding-top: 14px; display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.sc-card2__cta { font-weight: 700; font-size: var(--fs-200); color: var(--link-text); border-bottom: 2px solid var(--cyan); padding-bottom: 1px; }
.sc-soon { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--meta-text);
  border: 1.5px solid var(--ui-border); border-radius: var(--radius-pill); padding: 4px 11px; }

/* ---- Showcase index: the lead row (owner decision 2026-10-07: one large card, the rest small and one height) -------------------
   The first entry in curated order (showcase_lead() in includes/ui.php; showcase.php decides when it shows). Text on the left, on the
   right the entry's real Before / After, inert, on the SAME dark ground its card picture uses for its domain. One link, like a card. */
.sc-start { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); margin-top: 24px; background: #fff; border: 1px solid var(--card-border);
  border-radius: var(--radius-xl); overflow: hidden; text-decoration: none; color: inherit; transition: border-color 150ms ease-out; }
.sc-start:hover { border-color: var(--civic-blue); }
.sc-start + .sc-cards-grid { margin-top: 22px; }
.sc-start__text { padding: 36px 36px 32px; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 4px; }
.sc-start__flag { display: inline-flex; align-items: center; gap: 12px; margin-bottom: 12px; font: 700 var(--fs-100)/1 var(--font-display);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--navy); }
.sc-start__flag::before { content: ""; width: 28px; height: 2px; background: var(--cyan); }
.sc-start__code { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--civic-blue); }
.sc-start__standard { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-850); line-height: 1.05; letter-spacing: -0.035em; color: var(--navy); margin-top: 6px; }
.sc-start__thesis { display: block; font-size: var(--fs-400); line-height: 1.65; color: var(--secondary-text); margin-top: 14px; max-width: 46ch; }
.sc-start__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 16px; }
.sc-start__btn { margin-top: 22px; }
.sc-start__stage { position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: center; justify-content: center;
  padding: 32px 28px; min-height: 360px; background: var(--footer-ground); }
.sc-start__mock { position: relative; z-index: 2; width: 100%; max-width: 640px; }
.sc-start__mock .compare { background: transparent; border: 0; padding: 0; margin: 0; width: 100%; }
.sc-start__mock .compare__row { gap: 14px; flex-wrap: nowrap; justify-content: stretch; }
.sc-start__mock .compare__col { flex: 1 1 0; min-width: 0; max-width: none; width: auto; }
.sc-start__mock .compare__label:not(.is-after) { background: rgba(255, 255, 255, 0.14); color: #fff; border-color: rgba(255, 255, 255, 0.45); }   /* the Before pill, readable on the dark ground */
.sc-start__pic { position: relative; z-index: 2; width: 100%; max-width: 480px; }
@media (max-width: 960px) {
  .sc-start { grid-template-columns: 1fr; }
  .sc-start__stage { order: -1; min-height: 0; padding: 20px; }
}
@media (max-width: 640px) {
  .sc-start__text { padding: 22px 20px; }
  .sc-start__standard { font-size: var(--fs-800); }
  /* Before + After stacked would make the lead ~1,270px tall on a phone. Instead the stage peeks like a card picture: the After side only,
     cropped, with the same bottom fade as the cards (owner decision 2026-10-07, "8a"): ~590px for the whole lead. */
  .sc-start__stage { padding: 20px 16px 0; max-height: 240px; align-items: flex-start; }
  .sc-start__mock .compare__col:first-child { display: none; }
  .sc-start__stage::after { content: ""; position: absolute; z-index: 3; left: 0; right: 0; bottom: 0; height: 30%; pointer-events: none;
    background: linear-gradient(rgba(11, 47, 94, 0), rgba(11, 47, 94, 0.92)); }
}

/* ---- Home "Featured" Showcase card (templates/home.php, section 2b) ---------------------------
   One real card's interactive mockup, centred, above its code/title/thesis - built for Home only,
   the detail page keeps its own .sc-mockup/.sc-callouts layout untouched. .compare's own light-grey
   background (--surface) runs the full width of the card (owner feedback: it read as a narrow tray
   floating in a lot of empty white otherwise); .compare__row's two fixed-400px columns don't
   self-centre on their own - they pack to the left inside whatever width the row gives them, both
   side by side and when they wrap onto two lines - so that row is centred inside the now-full-width
   .compare. Neither the real .compare/.screen/.hot component nor its behaviour on the Showcase
   detail pages is touched. */
.feat-card { border: 1px solid var(--card-border); border-radius: var(--radius-lg); background: #fff; overflow: hidden; margin-top: 22px; }
/* 2026-10-07 (owner): picture and title must not read as one block. The mockup now sits on a light (--ice) band that runs edge to
   edge of the card, a rule divides it from the text, and the text gets its own padding. The .compare tray inside is made
   transparent so there is one band, not a tray inside a card inside a band. */
.feat-card--stacked .feat-card__mockup { padding: 32px 20px 14px; background: var(--ice); border-bottom: 1px solid var(--card-border-2); }
.feat-card--stacked .feat-card__mockup .compare { width: 100%; background: transparent; border: 0; border-radius: 0; padding: 0; }
.feat-card--stacked .feat-card__mockup .compare__row { justify-content: center; }
.feat-card--stacked .feat-card__body { padding: 26px 28px 28px; }
.feat-code { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--civic-blue); }
.feat-standard { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-700); line-height: 1.15; letter-spacing: -0.025em; color: var(--navy); margin: 4px 0 0; }
.feat-thesis { font-size: var(--fs-400); line-height: 1.6; color: var(--secondary-text); margin: 10px 0 0; max-width: 60ch; }
.feat-card .btn { margin-top: 18px; }

/* ---- Showcase detail hero ---------------------------------------------- */
/* The hero's ground is set inline from the entry's domain (thumb_showcase_ground_css, includes/thumbnails.php), the same
   ground as its card; this default only covers a page rendered without one. Its muted text is --on-navy-strong (not -body):
   the Portal ground runs to civic blue, where -body would drop under 4.5:1 on a tablet-width hero. */
.sc-hero { color: #fff; padding: 64px 0 56px; position: relative; overflow: hidden; isolation: isolate; background: var(--hero-grad); }
.sc-hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(rgba(255,255,255,0.14) 1.2px, transparent 1.3px);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(120% 120% at 100% 0%, #000 25%, transparent 72%);
          mask-image: radial-gradient(120% 120% at 100% 0%, #000 25%, transparent 72%);
}
.sc-back { display: block; color: var(--cyan); text-decoration: none; font-weight: 700; font-size: var(--fs-200); }
.sc-hero__code { display: inline-flex; align-items: center; gap: 8px; color: var(--on-navy-strong);
  font-weight: 700; font-size: var(--fs-100); letter-spacing: 0.08em; text-transform: uppercase; margin: 24px 0 0; }
.sc-hero__h1 { font-size: var(--fs-900); line-height: 1.02; letter-spacing: -0.035em; color: #fff; margin: 12px 0 0; max-width: 20ch; }
.sc-hero__thesis { color: var(--on-navy-strong); font-size: var(--fs-500); line-height: 1.65; max-width: 60ch; margin: 18px 0 0; }
.sc-hero__meta { display: flex; gap: 6px; margin: 18px 0 0; flex-wrap: wrap; }
/* Quiet pills (owner 2026-10-07: "chips too big", six of them stacked to ~260px on a phone): no outline, a faint white fill,
   lighter weight, thinner padding. The fill stays at 10% so white text keeps 4.5:1 on the lightest end of every domain ground. */
.sc-tag { font-size: var(--fs-100); font-weight: 600; letter-spacing: 0.02em; color: #fff;
  background: rgba(255, 255, 255, 0.10); border-radius: var(--radius-pill); padding: 3px 10px; }

/* ---- Showcase detail body ---------------------------------------------- */
/* .sc-hero (the coloured band above) stays left-aligned to the wordmark, like any other
   page hero. Below it the reading column is centred within the page, same as Articles'
   and Foundations' .post — those merge their width cap onto the .container element itself
   (so .container's own margin: auto centres them); here the cap sits on each child instead
   (.sc-body stays full width so .sc-hero's content can still reach the wordmark edge), so
   the children get their own margin: auto to match. */
.sc-body { max-width: var(--maxw); }
.sc-body > * { max-width: 880px; margin-left: auto; margin-right: auto; }
.sc-block { padding: 44px 0; border-top: 1px solid var(--card-border); }
.sc-block:first-child { border-top: 0; }
.sc-lead { font-size: var(--fs-500); line-height: 1.7; color: var(--body-text); margin: 14px 0 0; }
.sc-h2 { font-size: var(--fs-800); line-height: 1.15; letter-spacing: -0.03em; color: var(--navy); margin: 8px 0 0; }
.sc-context { font-size: var(--fs-400); line-height: 1.7; color: var(--secondary-text); margin: 12px 0 0; max-width: 62ch; }
.sc-points { margin: 18px 0 0; padding-left: 0; list-style: none; }
.sc-points li { position: relative; padding: 8px 0 8px 26px; border-bottom: 1px solid var(--card-border); font-size: var(--fs-300); color: var(--secondary-text); }
.sc-points li::before { content: ""; position: absolute; left: 0; top: 15px; width: 10px; height: 10px; border-radius: 2px; background: var(--cyan); }
.sc-source { margin: 20px 0 0; font-size: var(--fs-200); color: var(--meta-text); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.sc-shots { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 24px 0 0; }
.sc-shot { margin: 0; }
.sc-shot__ph { aspect-ratio: 16/10; border: 1.5px dashed var(--ui-border); border-radius: var(--radius-lg); background: var(--ice);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; color: var(--meta-text);
  font-size: var(--fs-200); font-weight: 600; }
.sc-shot__img { width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: var(--radius-lg); border: 1px solid var(--card-border); display: block; }
.sc-shot figcaption { font-size: var(--fs-200); line-height: 1.5; color: var(--meta-text); margin-top: 10px; }

.sc-verdict { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 28px 0 0; }
.sc-verdict__col { border-radius: var(--radius-lg); padding: 20px; border: 1px solid var(--card-border); }
.sc-verdict__col h3 { display: flex; align-items: center; gap: 8px; font-size: var(--fs-300); margin: 0 0 12px; }
.sc-verdict__col ul { margin: 0; padding-left: 18px; }
.sc-verdict__col li { font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); padding: 4px 0; }
.sc-verdict__col--works { border-top: 3px solid var(--lic-green); }
.sc-verdict__col--works h3 { color: var(--lic-green); }
.sc-verdict__col--fails { border-top: 3px solid var(--lic-red); }
.sc-verdict__col--fails h3 { color: var(--lic-red); }

.sc-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap: 18px; margin: 22px 0 0; }
.sc-cards > :only-child { max-width: 440px; } /* same auto-fit fix as .sc-cards-grid above - see conventions.md "Front-end conventions" */
.sc-card { border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 22px; }
.sc-card__n { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); color: var(--civic-blue); }
.sc-card h3 { font-size: var(--fs-500); color: var(--navy); margin: 8px 0 0; }
.sc-card p { font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); margin: 8px 0 0; }

.sc-proposals { display: flex; flex-direction: column; gap: 14px; margin: 22px 0 0; }
.sc-proposal { border-left: 3px solid var(--cyan); background: var(--surface); border-radius: 0 10px 10px 0; padding: 18px 20px; }
.sc-proposal h3 { font-size: var(--fs-500); color: var(--navy); }
.sc-proposal p { font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); margin: 6px 0 0; }

/* ---- Showcase, annotated layout: mockup, numbered callouts, free blocks, related ----------------------------
   The mockup is the site's own drawing, numbers included; the numbered list under it is its text version.
   Numbers come from a CSS counter so they always match the order in the list. Spec: Admin -> Design system. */
.sc-mockup { margin: 22px 0 0; }
.sc-mockup img { display: block; width: 100%; height: auto; border: 1px solid var(--card-border); border-radius: var(--radius-lg); background: #fff; }
.sc-mockup figcaption { font-size: var(--fs-200); line-height: 1.5; color: var(--meta-text); margin-top: 10px; }
.sc-callouts { list-style: none; margin: 24px 0 0; padding: 0; display: grid; gap: 14px; counter-reset: sc-callout; }
.sc-callout { counter-increment: sc-callout; display: grid; grid-template-columns: 30px 1fr; gap: 16px; align-items: start;
  border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 18px 20px; }
.sc-callout::before { content: counter(sc-callout); display: grid; place-items: center; width: 30px; height: 30px; border-radius: var(--radius-pill);
  background: var(--navy); color: #fff; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-200); }
.sc-callout h3 { font-size: var(--fs-500); line-height: 1.25; color: var(--navy); margin: 3px 0 0; }
.sc-callout p { font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); margin: 6px 0 0; }
.sc-callout p.sc-callout__std { margin-top: 10px; }
.sc-callout.is-active { border-color: var(--cyan); background: #F2FDFB; }
.sc-blocks { margin-top: 0; }

/* The floating note of an interactive mockup: a click on a numbered .hot opens it right under that number and it
   may cover rows below (owner accepted that). It lives inside .compare, not inside .screen, because .screen clips
   its overflow. The full .sc-callouts list below the mockup stays as the text version.
   Navy ground + --elevation-float shadow so it reads as a layer above the (light) mocked-up UI; it is the one
   component in the system with a shadow (conventions.md "Front-end conventions").
   assets/js/showcase-mockup-compare.js builds it, places it and sets --tip-arrow (the pointer's x position). */
.sc-tip { position: absolute; z-index: 5; box-sizing: border-box; width: min(360px, calc(100% - 16px)); margin: 0;
  padding: 14px 16px; background: var(--navy); border: 0; border-radius: var(--radius-lg); box-shadow: var(--elevation-float); }
.sc-tip__head { display: flex; align-items: flex-start; gap: 10px; padding-right: 34px; }   /* room for the close button */
.sc-tip[hidden] { display: none; }
.sc-tip::before { content: ""; position: absolute; top: -8px; left: var(--tip-arrow, 50%); width: 14px; height: 14px; margin-left: -7px;
  background: var(--navy); transform: rotate(45deg); }
.sc-tip__n { flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: var(--radius-pill);
  background: var(--cyan); color: var(--cyan-ink); font-family: var(--font-display); font-weight: 700; font-size: var(--fs-200); }
.sc-tip h3 { font-size: var(--fs-400); line-height: 1.3; color: #fff; margin: 3px 0 0; }
.sc-tip p { font-size: var(--fs-200); line-height: 1.5; color: var(--on-navy-body); margin: 8px 0 0; }
.sc-tip p.sc-callout__std { margin-top: 8px; }
.sc-tip p.sc-callout__std[hidden] { display: none; }
.sc-tip__close { position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 34px; height: 34px; padding: 0;
  border: 0; border-radius: 50%; background: transparent; color: #fff; cursor: pointer; }
.sc-tip__close:hover { background: rgba(255, 255, 255, 0.14); }
.sc-tip__close:focus-visible { border-radius: 50%; }
.sc-tip__close svg { width: 14px; height: 14px; }
/* The site's back-to-top button sits bottom-right and would cover a note near the bottom of a phone screen. */
html.sc-tip-open .back-to-top { visibility: hidden; }

/* ---- Interactive "compare" mockups (mockup.type = 'medication_schedule' | 'tap_target_size') ------------------
   Before and After are both server-rendered as their own bordered "screen", shown side by side (or stacked, if
   a type declares .compare__col--wide - flex-wrap handles which, no JS branching needed). There is no show/hide toggle;
   assets/js/showcase-mockup-compare.js opens the floating .sc-tip note for a clicked number. position: relative is
   the anchor that note is placed against. */
.compare { position: relative; border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 20px; background: var(--surface); }
.compare__row { display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start; }
.compare__col { display: flex; flex-direction: column; gap: 10px; width: 400px; flex: 0 0 400px; }
.compare__col--wide { width: 100%; flex: 1 1 100%; }
/* Below ~560px there is no room for a fixed 400px column (confirmed overflow/clipping on real
   phones) - stack Before/After full width, same as .compare__col--wide already does by choice. */
@media (max-width: 560px) { .compare__col { width: 100%; flex: 1 1 100%; } }
.screen { border: 1px solid var(--card-border-2); border-radius: var(--radius-lg); overflow: hidden; background: #fff; }
/* Right-aligned so it reads under the "After" column - the interactive side the numbers actually
   sit on - instead of floating vague under the whole Before/After pair (owner feedback 2026-09-30). */
.sc-mockup__note { font-size: var(--fs-200); line-height: 1.5; color: var(--meta-text); margin-top: 10px; text-align: right; }
.mock-head { background: var(--hero-grad); color: #fff; padding: 12px 14px; }
/* The "① Common pattern" / "② Meets the minimum" pill - sits above each screen, OUTSIDE its border, on
   the light .compare background - so it reads as our annotation, never as part of the mocked-up UI
   (owner feedback 2026-09-23: putting it inside the screen's own header made it look like it belonged to
   the fake product screen, not to us). Still one pill per screen (showcase_compare_label_html()), so
   which screen it belongs to stays unambiguous, side by side or stacked (.compare__col--wide). */
.compare__label { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-200);
  padding: 5px 12px; border-radius: var(--radius-pill); border: 1px solid var(--ui-border-navy); color: var(--navy); align-self: flex-start; }
.compare__label.is-after { background: var(--cyan); color: var(--cyan-ink); border-color: transparent; }
.mock-head h3 { font-size: var(--fs-400); margin: 0; font-family: var(--font-display); }
.screen__body { background: #fff; }
.med { display: flex; gap: 14px; align-items: flex-start; padding: 16px 20px; border-top: 1px solid var(--hairline); }
.med:first-child { border-top: 0; }
.med__icon { flex: none; width: 34px; height: 34px; border-radius: 50%; background: var(--ice); color: var(--civic-blue); display: grid; place-items: center;
  margin-top: 2px; font-family: var(--font-display); font-weight: 700; font-size: 11px; }
.med__body { min-width: 0; flex: 1; }
.med__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Plain inline flow, not a grid: a grid pins the trailing hotspot beside the text's FIRST line
   regardless of where the text actually ends, which reads wrong on a wrapped row (owner-reported
   2026-09-29 - a number landing mid-sentence instead of at the end). showcase_medication_mockup_html()'s
   $hot() puts a non-breaking space before the button instead, so the badge still can't strand alone on
   its own line (the original bug this was fixing) - the browser wraps the last word and the badge
   together onto the next line if they don't both fit, keeping the badge at the text's true end. */
.med__row { margin-top: 5px; font-size: var(--fs-300); color: var(--secondary-text); }
.med__row .sep { color: var(--card-border-2); }
.chip--dot { display: inline-flex; align-items: center; gap: 5px; }
.chip--dot::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--civic-blue); }
/* "Before" pattern: colour is the only signal for as-needed - a deliberate WCAG 1.4.1 failure, shown for comparison. */
.chip--coloronly { background: #FBECEA; color: var(--lic-red); }
.hot { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%;
  background: var(--navy); color: #fff; font-family: var(--font-display); font-weight: 700; font-size: 11px; line-height: 1; border: 0; cursor: pointer; flex: none; padding: 0; }
/* The visible dot stays 22px; the invisible ring makes the tap target 44px. */
.hot::after { content: ""; position: absolute; inset: -11px; border-radius: 50%; }
.hot:hover { background: var(--civic-blue); }
.hot[aria-expanded="true"] { background: var(--cyan); color: var(--cyan-ink); }
.hot:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 50%; }

/* Tap-target-size compare mockup (mockup.type = 'tap_target_size') - each row draws the real UI
   element as a token-coloured box at its literal pixel size (inline style), so a Before/After
   size difference is visible, not just described. Shares .compare / .screen / .hot / .sc-callout
   with the medication mockup (assets/js/showcase-mockup-compare.js). */
/* .tts-row is display:contents (no box of its own) so its two children become direct items of the
   .tts-body grid below - this is what lets every row's swatch share ONE column (sized to the widest
   swatch in this screen), instead of each row wrapping its swatch/label apart independently at
   different widths (owner-reported: made the list read as jumbled, not aligned - 2026-09-29). */
.tts-body { padding: 16px 14px; display: grid; grid-template-columns: max-content 1fr; align-items: center; column-gap: 16px; row-gap: 14px; }
.tts-row { display: contents; }
.tts-boxes { display: flex; align-items: flex-end; flex-wrap: wrap; }
.tts-box { display: inline-block; background: var(--ice); border: 1.5px solid var(--civic-blue); border-radius: var(--radius-sm); }
.tts-row__body { min-width: 0; }
.tts-row__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-400); color: var(--navy); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tts-row__note { font-size: var(--fs-200); color: var(--meta-text); margin-top: 3px; }

/* Status-list compare mockup (mockup.type = 'status_list') - Before marks a reading's status with
   colour alone (a plain dot); After adds a shape (circle/triangle, drawn with CSS borders, no images)
   and a word next to the same colour - the exact contrast SC 1.4.1 is about. Shares .compare / .screen
   / .hot / .sc-callout with the other interactive mockups (assets/js/showcase-mockup-compare.js). */
.status-row { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 36px 12px 20px; border-top: 1px solid var(--hairline); }
.status-row:first-child { border-top: 0; }
/* Alternating shading (mockup.readings[].group / "Separate rows with spacing or shading" callout) -
   a plain PHP row counter, not an nth-child rule, since .status-group-head rows would throw off CSS
   structural counting (owner-reported 2026-09-29). */
.status-row--alt { background: var(--surface); }
/* An optional section heading above a run of readings that share mockup.readings[].group - e.g. lab
   results grouped by panel instead of one flat alphabetical list. */
.status-group-head { padding: 14px 20px 4px; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-200);
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--label-text); }
.status-group-head:first-child { padding-top: 4px; }
.status-row__body { min-width: 0; }
.status-row__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); color: var(--navy); }
.status-row__value { font-size: var(--fs-300); color: var(--secondary-text); margin-top: 2px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* mockup.valueEmphasis flips which of the two is the bold/primary text - see showcase_status_list_mockup_html(). */
.status-row__label--meta { font-weight: 400; font-size: var(--fs-200); color: var(--meta-text); }
.status-row__value--emph { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); margin-top: 0; }
/* Groups the badge with its status word as one flex child, pinned to a fixed-width box on the row's
   right side (not sized to its own content) so the word's own LEFT edge lands at the same x on every
   row, regardless of word length - GOV.UK's table guidance is explicit that only numbers get
   right-aligned for magnitude comparison; text (a status word is text, not a number) stays left-aligned,
   which is also what reads as a neat, scannable column down a list (owner-asked 2026-09-29: right-aligning
   "High"/"Normal"/"Low" left a ragged, ungainly LEFT edge instead). Fixed-width, not auto, is what keeps
   this box's own left edge constant regardless of the word inside it. Width hugs the widest word
   ("Normal" - icon + gap + text measures ~66px) instead of leaving room to spare - the box's right edge
   stays pinned near the row's own edge either way, so a wider box only pushed the word further LEFT,
   away from the edge (owner-reported 2026-09-29: wanted the word closer to the number/edge, not the
   number moved on its own - the fix two commits ago). */
.status-row__status { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 72px; }
/* Same fix as .consent-row .hot: pinned to the row's own right edge (in the wider padding
   .status-row reserves), not part of .status-row__status's flow. Scoped to .status-row__status
   only - .status-row__value can carry its own hotspot too (coValue) and that one stays inline,
   right after the reading, since it isn't competing for a shared right-aligned edge. Nudged in
   from the literal edge (owner-reported 2026-09-30) to the same right:6px .consent-row .hot
   already uses, after an earlier pass had pushed it out to right:0 (owner-reported 2026-09-29). */
.status-row__status .hot { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); }
.status-badge { flex: none; display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: var(--fs-200); }
.status-badge--ok { color: var(--lic-green); }
.status-badge--high { color: var(--lic-red); }
.status-badge--low { color: var(--lic-amber-ink); }
.status-badge__mark { flex: none; width: 0; height: 0; }
.status-badge--ok .status-badge__mark { width: 10px; height: 10px; border-radius: 50%; background: var(--lic-green); }
.status-badge--high .status-badge__mark { border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 10px solid var(--lic-red); }
.status-badge--low .status-badge__mark { border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 10px solid var(--lic-amber-border); }
/* Before: colour alone, no shape and no word - the dot itself carries the same border-drawn shape,
   just filled instead of outlined, so it never looks like a fourth, unrelated marker. */
.status-badge--dotonly { width: 10px; height: 10px; border-radius: 50%; }
.status-badge--dotonly.status-badge--ok { background: var(--lic-green); }
.status-badge--dotonly.status-badge--high { background: var(--lic-red); }
.status-badge--dotonly.status-badge--low { background: var(--lic-amber-border); }

/* Error-summary compare mockup (mockup.type = 'error_summary') - the same fields both sides; the After
   screen adds a focusable summary box above them. Shares .compare / .screen / .hot with the others. */
.es-body { padding: 16px 20px; display: grid; gap: 14px; }
.es-field__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); color: var(--navy); }
.es-field--error .es-field__label { border-left: 3px solid var(--lic-red); padding-left: 10px; margin-left: -13px; }
.es-field__error { font-size: var(--fs-200); color: var(--lic-red); margin-top: 3px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.es-summary { border: 1.5px solid var(--lic-red); border-radius: var(--radius-md); padding: 14px 16px; margin-bottom: 4px; background: var(--lic-red-tint); }
.es-summary__title { font-family: var(--font-display); font-weight: 700; color: var(--lic-red); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.es-summary__list { margin: 8px 0 0; padding-left: 18px; font-size: var(--fs-300); color: var(--lic-red); display: grid; gap: 4px; }
.es-summary__list li { text-decoration: underline; }

/* Text-compare mockup (mockup.type = 'text_compare') - a dense/jargon line (Before) next to its plain-
   language rewrite (After), both full width so the prose has room. Shares .compare / .compare__col--wide / .hot. */
.tc-body { padding: 16px 20px; display: grid; gap: 14px; }
.tc-line { font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); margin: 0; }

/* Consent-screen compare mockup (mockup.type = 'consent_screen') - each choice at its Before vs After
   visual weight: a button vs a plain link, a toggle on vs off, present vs hidden. Shares .compare /
   .screen / .hot. */
.consent-row { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 36px 12px 20px; border-top: 1px solid var(--hairline); }
.consent-row:first-child { border-top: 0; }
.consent-row__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); color: var(--navy); }
.consent-row__control { display: inline-flex; align-items: center; }
.consent-row--action { justify-content: flex-start; }   /* a button row has no label: the button itself sits where the label would */
/* The hotspot is taken out of the row's own flex flow (owner-reported 2026-09-29: it was claiming layout
   width, which is what pushed the Button/toggle away from the screen's true right edge - with no number,
   the control sits flush right against its own padding, exactly as the real UI would, instead of sharing
   space with the number). Pinned to the row's own right edge via position:absolute in the extra padding
   this rule reserves (36px instead of the usual 20px - just enough for the badge plus a gap on each side,
   confirmed against the badge's own ~22px width so it neither overlaps the control's text nor gets clipped
   by .screen's overflow:hidden). Taking it fully outside .screen's box - not just into its own padding -
   is the bigger systemic change flagged separately. */
.consent-row .hot { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); }
.consent-mark { flex: none; display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-200); font-weight: 700; }
.consent-mark--primary { padding: 6px 14px; border-radius: var(--radius-pill); background: var(--navy); color: #fff; }
.consent-mark--secondary { color: var(--secondary-text); font-weight: 400; text-decoration: underline; }
.consent-mark--on, .consent-mark--off { gap: 7px; }
.consent-mark--on { color: var(--lic-green); }
.consent-mark--on::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--lic-green); }
.consent-mark--off { color: var(--meta-text); font-weight: 400; }
.consent-mark--off::before { content: ""; width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid var(--card-border-2); background: #fff; }
.consent-mark--hidden { color: var(--meta-text); font-weight: 400; font-style: italic; }

/* Range-value mockup (mockup.type = 'range_value') - a bare number (Before) vs a horizontal reference-
   range bar with a marker, plus a plain-language reading (After). Shares .compare / .screen / .hot. */
.range-row { padding: 14px 20px; border-top: 1px solid var(--hairline); }
.range-row:first-child { border-top: 0; }
.range-row__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); color: var(--navy); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.range-row__value { font-size: var(--fs-300); color: var(--secondary-text); margin-top: 4px; }
.range-row__reading { font-size: var(--fs-200); color: var(--meta-text); margin-top: 3px; }
/* When a row's callout points at the bar itself (or its reference-range block) rather than the label -
   see SHOWCASE_RANGE_CALLOUT_POS - the number sits right after the bar instead of by the label, so it
   reads as annotating the bar shape/range block it's actually about (owner-reported 2026-09-29). */
.range-row__bar-wrap { display: flex; align-items: center; gap: 8px; }
.range-row__bar-wrap .range-bar { flex: 1 1 auto; }
.range-bar { position: relative; height: 10px; border-radius: var(--radius-pill); background: var(--ice); margin: 10px 0 2px; }
.range-bar__block { position: absolute; top: 0; bottom: 0; border-radius: var(--radius-pill); background: var(--lic-green-tint); border: 1px solid var(--lic-green); }
.range-bar__marker { position: absolute; top: 50%; width: 12px; height: 12px; border-radius: 50%; background: var(--navy); border: 2px solid #fff; transform: translate(-50%, -50%); }
/* The reference range's two ends are printed as numbers under the bar (2026-10-09 review: a bar with no scale cannot be checked), and every row keeps the
   same track width whether or not its number sits at the end of the bar (it used to take space from the track on one row only). */
.range-row__bar-wrap { position: relative; padding-right: 30px; }
.range-row__bar-wrap .hot { position: absolute; right: 0; top: 3px; }
.range-row .range-bar { margin-bottom: 22px; }
.range-bar__tick { position: absolute; top: 15px; transform: translateX(-50%); font-family: var(--font-body); font-size: 11px; line-height: 1; color: var(--meta-text); white-space: nowrap; }

/* ---- Device frames (mockup.frame = 'phone' | 'window', 2026-10-09 review) -------------------------------------------------------------
   showcase_mockup_parts() adds .screen--phone / .screen--window to every .screen of a mockup; this is the whole of the frame, so every type, and
   the card thumbnail cut from its After side, picks it up. The title bar turns light (a phone's app bar, a window's title bar) instead of the navy
   gradient the unframed look uses; the bezel / rounded corners only apply inside .compare, so a thumbnail keeps its own crop. */
.screen--phone::before { content: "9:41"; display: block; padding: 8px 20px 0; background: #fff; font-family: var(--font-display); font-weight: 700; font-size: 11px; color: var(--navy); }
.screen--phone .mock-head { background: #fff; color: var(--navy); padding: 6px 20px 10px; }
.screen--phone .mock-head h3 { font-size: var(--fs-500); color: var(--navy); }
.compare .screen--phone { border: 6px solid var(--footer-ground); border-radius: 30px; width: 100%; max-width: 360px; margin: 0 auto; }
.screen--window .mock-head { display: flex; align-items: center; gap: 12px; background: var(--surface); color: var(--navy); border-bottom: 1px solid var(--card-border); padding: 9px 14px; }
.screen--window .mock-head::before { content: ""; flex: none; width: 45px; height: 10px; background: radial-gradient(circle at 5px 5px, var(--card-border-2) 4.5px, transparent 5px) 0 0 / 15px 10px repeat-x; }
.screen--window .mock-head h3 { font-size: var(--fs-300); color: var(--navy); }

/* Medication name: the text sits in one span so a Tall Man <b> is not a flex item of its own (it was spaced out like "hydr OXY zine"). */
.med__name > span { min-width: 0; }

/* Status list: an alert QUEUE (mockup.layout = 'queue') draws its status as a coloured bar down the row's left edge; the After side adds the badge. */
.status-row--queue { border-left: 5px solid transparent; padding-left: 15px; }
.status-row--q-high { border-left-color: var(--lic-red); }
.status-row--q-low { border-left-color: var(--lic-amber-border); }
.status-row--queue .status-row__status { flex-basis: 112px; }
.status-summary { display: grid; gap: 2px; padding: 12px 20px; background: var(--ice); border-bottom: 1px solid var(--card-border); font-size: var(--fs-300); color: var(--secondary-text); }
.status-summary strong { font-family: var(--font-display); font-size: var(--fs-400); color: var(--navy); }
.status-row__link { margin-left: 8px; font-family: var(--font-body); font-weight: 400; font-size: var(--fs-200); color: var(--link-text); text-decoration: underline; }
.status-badge--none { color: var(--meta-text); }
.status-badge--none .status-badge__mark { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid var(--meta-text); }

/* Consent screen: real switches (the word On / Off is printed beside the track), buttons of the same weight, a small note. */
.consent-body { padding: 2px 0 8px; }
.consent-switch { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0; border: 0; background: none; cursor: pointer; font-family: var(--font-body); font-weight: 700; font-size: var(--fs-200); color: var(--navy); }
.consent-switch__trk { position: relative; flex: none; width: 44px; height: 26px; border-radius: 13px; border: 2px solid var(--ui-border); background: #fff; }
.consent-switch__trk::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--ui-border); transition: left 0.15s; }
.consent-switch[aria-checked="true"] .consent-switch__trk { background: var(--navy); border-color: var(--navy); }
.consent-switch[aria-checked="true"] .consent-switch__trk::after { left: 20px; background: #fff; }
.consent-switch:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: var(--radius-sm); }
.consent-actions { display: flex; flex-wrap: wrap; gap: 10px; padding: 14px 20px 6px; border-top: 1px solid var(--hairline); }
.consent-act { position: relative; flex: 1 1 40%; min-width: 0; }
.consent-act--link { flex-basis: 100%; }
.consent-btn { display: block; width: 100%; min-height: 44px; padding: 0 14px; border-radius: var(--radius-md); border: 2px solid var(--navy); font-family: var(--font-body); font-weight: 700; font-size: var(--fs-300); cursor: default; }
.consent-btn--primary { background: var(--navy); color: #fff; }
.consent-btn--equal { background: #fff; color: var(--navy); }
.consent-link { display: block; width: 100%; min-height: 44px; padding: 0; border: 0; background: none; font-family: var(--font-body); font-size: var(--fs-200); color: var(--secondary-text); text-decoration: underline; cursor: default; }
.consent-act .hot { position: absolute; right: -8px; top: -9px; box-shadow: 0 0 0 2px #fff; }
.consent-note { position: relative; margin: 0; padding: 8px 40px 14px 20px; font-size: var(--fs-200); line-height: 1.5; color: var(--meta-text); }
.consent-note__lnk { color: var(--link-text); text-decoration: underline; }
.consent-note .hot { position: absolute; right: 6px; top: 6px; }

/* Tap targets: "Show the 24px test circles" (assets/js/showcase-mockup-compare.js puts .is-areas on .compare). WCAG 2.5.8's Spacing exception: a 24px
   circle centred on a small target must touch no other target; where two circles meet, both are drawn red. */
.tts-tools { margin-bottom: 10px; }
.tts-toggle { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; border-radius: var(--radius-pill); border: 1.5px solid var(--ui-border-navy); background: #fff; color: var(--navy); font-family: var(--font-display); font-weight: 700; font-size: var(--fs-200); cursor: pointer; }
.tts-toggle[aria-pressed="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }
.tts-toggle:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.tts-box { position: relative; }
.is-areas .tts-box::after { content: ""; position: absolute; left: 50%; top: 50%; width: 24px; height: 24px; border-radius: 50%; transform: translate(-50%, -50%); border: 2px dashed var(--civic-blue); background: rgba(22, 104, 196, 0.12); pointer-events: none; }
.is-areas .tts-box--clash::after { border-color: var(--lic-red); background: rgba(163, 39, 23, 0.18); }

/* Text compare with word counts (mockup.showCounts): a small chip after every sentence; over 25 words it also says "long" (shape + word, not colour alone). */
.wc { display: inline-block; margin-left: 4px; padding: 1px 7px; border-radius: 6px; background: var(--surface); color: var(--meta-text); font-family: var(--font-body); font-weight: 700; font-size: var(--fs-200); white-space: nowrap; }
.wc--long { background: var(--lic-amber-tint); color: var(--lic-amber-ink); }

/* Source compare (mockup.type = 'source_compare', medication reconciliation): Before = a blended list that looks finished, After = a table with a column per source. */
.src-blendhead { padding: 12px 20px 4px; }
.src-blend { padding: 10px 20px; border-top: 1px solid var(--hairline); }
.src-blendhead + .src-blend { border-top: 0; }
.src-blend__name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); color: var(--navy); }
.src-blend__text { font-size: var(--fs-300); color: var(--secondary-text); }
.src-body { padding: 14px 16px 16px; }
.src-need { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 0 0 10px; font-size: var(--fs-300); color: var(--secondary-text); }
.src-need strong { font-family: var(--font-display); font-size: var(--fs-400); color: var(--navy); }
.src-scroll { overflow-x: auto; }
.src-table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: var(--fs-300); }
.src-table th, .src-table td { text-align: left; vertical-align: top; padding: 9px 10px; border-top: 1px solid var(--hairline); }
.src-table thead th { border-top: 0; background: var(--ice); color: var(--navy); font-family: var(--font-display); font-size: var(--fs-200); }
.src-table tbody th { font-family: var(--font-display); color: var(--navy); }
.src-x { background: var(--lic-amber-tint); color: var(--lic-amber-ink); font-weight: 700; }
.src-none { color: var(--meta-text); }
.src-status { min-width: 150px; }
.src-status .status-badge { display: flex; align-items: flex-start; }
.src-status .status-badge__mark { margin-top: 3px; }
.src-choose { display: inline-flex; align-items: center; min-height: 44px; margin-top: 6px; padding: 0 14px; border-radius: var(--radius-pill); border: 1.5px solid var(--navy); background: #fff; color: var(--navy); font-family: var(--font-body); font-weight: 700; font-size: var(--fs-200); cursor: pointer; }
.src-choose:hover { background: var(--ice); }
.src-choose:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ---- New interactive mockup types: trend_chart, patient_tiles, alert_list, form_screen ----------------------------
   Share .compare / .screen / .mock-head / .hot / .sc-tip / .sc-callout with the types above. Tokens only, no shadow. */
/* ---- Trend chart (mockup.type = 'trend_chart') ------------------------------------------------------------------ */
.tr-body { padding: 14px 16px 16px; }
.tr-cap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 8px; font-size: var(--fs-200); line-height: 1.4; color: var(--meta-text); }
.tr-svg { display: block; width: 100%; height: auto; }
.tr-svg text { font-family: var(--font-body); }
.tr-grid { stroke: var(--card-border); stroke-width: 0.5; }
.tr-axis { fill: var(--meta-text); font-size: 10px; }
.tr-axis--strong { fill: var(--navy); font-weight: 700; }
.tr-line { fill: none; stroke-width: 1.25; }
.tr-line--sys { stroke: var(--civic-blue); }
.tr-line--dia { stroke: var(--teal-ink); }
/* Dots style only: a faint single-series trend cue under the dots, much lighter than .tr-line so it doesn't read as
   the two-line clinical chart Before is showing (owner request 2026-09-30 - make the dots chart read as a trend
   at a glance, without reviving the format the card's own cited review found patients understood less well). */
.tr-line--soft { fill: none; stroke: var(--civic-blue); stroke-opacity: 0.38; stroke-width: 1.5; stroke-linejoin: round; }
.tr-dot--sys { fill: var(--civic-blue); }
.tr-dot--dia { fill: var(--teal-ink); }
.tr-fine { margin: 6px 0 0; font-size: 11px; line-height: 1.4; color: var(--meta-text); }
.tr-bar { fill: var(--civic-blue); }
.tr-bar--ok { fill: var(--lic-green); }
.tr-bar--high { fill: var(--lic-red); }
.tr-bar--low { fill: var(--lic-amber-border); }
.tr-band { fill: var(--lic-green-tint); fill-opacity: 0.55; stroke: var(--lic-green); stroke-width: 1; }
.tr-band-label { fill: var(--lic-green); font-size: 10.5px; font-weight: 700; }
.tr-mark--ok { fill: var(--lic-green); }
.tr-mark--high { fill: var(--lic-red); }
.tr-mark--low { fill: var(--lic-amber-border); }
.tr-baseline { stroke: var(--ui-border); stroke-width: 1; }
/* No border-top divider: the latest-reading line reads as part of the same chart/legend unit below it,
   not a separate section - PMC6785326 found integrated context outperforms a separated legend/text
   block (owner-reported 2026-09-29, patient-trend-chart). */
.tr-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.tr-status__val { font-size: var(--fs-300); color: var(--secondary-text); }
.tr-legend { display: flex; align-items: center; gap: 4px 16px; flex-wrap: wrap; margin: 8px 0 0; font-size: var(--fs-100); color: var(--meta-text); }
.tr-legend span { display: inline-flex; align-items: center; gap: 6px; }
.tr-key { display: inline-block; flex: none; }
.tr-key--bar { width: 10px; height: 10px; background: var(--civic-blue); }
.tr-key--dot { width: 10px; height: 10px; border-radius: 50%; background: var(--civic-blue); }
.tr-key--tri { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 9px solid var(--lic-red); }
.tr-key--tri-down { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 9px solid var(--lic-amber-border); }
.tr-key--dot-ok { width: 10px; height: 10px; border-radius: 50%; background: var(--lic-green); }
.tr-key--band { width: 14px; height: 8px; background: var(--lic-green-tint); border: 1px solid var(--lic-green); }
.tr-key-line { stroke-width: 2; }
.tr-key-line--sys { stroke: var(--civic-blue); }
.tr-key-line--dia { stroke: var(--teal-ink); }

/* ---- Patient tiles (mockup.type = 'patient_tiles') - a wide mockup: use .compare__col--wide -------------------- */
.pt-body { padding: 14px 16px 16px; }
.pt-note { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 10px; font-size: var(--fs-200); line-height: 1.4; color: var(--meta-text); }
.pt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.pt-grid > :only-child { max-width: 440px; }   /* lone-item guard, conventions.md */
.pt-tile { min-width: 0; border: 1px solid var(--card-border-2); border-radius: var(--radius-md); padding: 10px 12px; background: #fff; }
.pt-tile__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; font-family: var(--font-display); font-weight: 700; color: var(--navy); font-size: var(--fs-300); }
.pt-tile__id { font-weight: 400; font-size: var(--fs-100); color: var(--meta-text); }
/* Before: dense, abbreviations, every tile identical; a breach is only a faint tint (colour alone, the failure). */
.pt-tile--dense { padding: 8px 10px; }
.pt-tile--dense .pt-tile__head { font-size: var(--fs-100); letter-spacing: 0.02em; }
.pt-tile--tint { background: var(--lic-red-tint); }
.pt-dense { display: flex; flex-wrap: wrap; gap: 2px 8px; margin: 5px 0 0; font-size: 11px; line-height: 1.35; color: var(--secondary-text); }
/* After: room name, three labelled values, details one tap away; a breach = colour + icon + words. */
.pt-tile--alert { border-color: var(--lic-red); border-left-width: 4px; }
.pt-vitals { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 3px; }
.pt-vital { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: var(--fs-200); color: var(--secondary-text); }
.pt-vital b { color: var(--navy); font-weight: 700; }
.pt-vital__label { display: inline-flex; align-items: center; gap: 6px; }
.pt-alert { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; padding: 3px 10px; border-radius: var(--radius-pill); background: var(--lic-red-tint); color: var(--lic-red); font-weight: 700; font-size: var(--fs-200); }
.pt-alert__mark { flex: none; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 10px solid var(--lic-red); }
.pt-more { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; font-size: var(--fs-200); font-weight: 600; color: var(--link-text); text-decoration: underline; }

/* ---- Alert list (mockup.type = 'alert_list') --------------------------------------------------------------------- */
.al-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px; border-top: 1px solid var(--hairline); }
.al-row:first-child { border-top: 0; }
.al-row__body { min-width: 0; flex: 1; }
.al-row__text { font-size: var(--fs-300); line-height: 1.4; color: var(--body-text); }
.al-row__text b { font-family: var(--font-display); color: var(--navy); }
.al-row__meta { margin-top: 2px; font-size: var(--fs-100); line-height: 1.4; color: var(--meta-text); }
.al-row__limit { margin-top: 3px; font-size: var(--fs-200); line-height: 1.4; color: var(--secondary-text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Before: one flat state. Every alert gets the same red dot and weight - colour is the only signal. */
.al-dot { flex: none; width: 10px; height: 10px; margin-top: 6px; border-radius: 50%; background: var(--lic-red); }
.al-row--flat { border-left: 3px solid var(--lic-red); }
/* After: three tiers, each with a colour, a shape and a word (never colour alone). */
.al-tier { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 14px; border-top: 1px solid var(--card-border-2); font-family: var(--font-display); font-weight: 700; font-size: var(--fs-200); }
.al-tier:first-child { border-top: 0; }
.al-tier--urgent { background: var(--lic-red-tint); color: var(--lic-red); }
.al-tier--review { background: var(--lic-amber-tint); color: var(--lic-amber-ink); }
.al-tier--info { background: var(--surface); color: var(--meta-text); }
.al-shape { flex: none; }
.al-shape--tri { width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 10px solid var(--lic-red); }
.al-shape--dia { width: 9px; height: 9px; background: var(--lic-amber-border); transform: rotate(45deg); }
.al-shape--ring { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--ui-border); background: #fff; }
.al-row--urgent { border-left: 4px solid var(--lic-red); }
.al-row--review { border-left: 4px solid var(--lic-amber-border); }
.al-row--info { padding-top: 7px; padding-bottom: 7px; }
.al-row--info .al-row__text { font-size: var(--fs-200); color: var(--meta-text); }
/* A row with a number and a status (the Reading status component): they sit on the right, the number at full size. */
.al-row__right { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; text-align: right; }
.al-row__status { display: inline-flex; align-items: center; gap: 6px; }
.al-row__num { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); line-height: 1.2; color: var(--navy); }
/* Square tier shapes (mockup option tierShapes), so a tier never looks like a Reading status triangle or circle */
.al-shape--sq { width: 9px; height: 9px; background: var(--lic-red); }
.al-shape--sqr { width: 9px; height: 9px; border: 1.5px solid var(--ui-border); background: #fff; }
.al-row--info .al-row__text b { color: var(--meta-text); font-weight: 600; }

/* ---- Form screen (mockup.type = 'form_screen') - drawn with plain divs, no real form controls ---------------------- */
.fm-body { padding: 16px 18px 18px; display: grid; gap: 16px; }
/* An optional section break before a field that isn't really the same kind of thing as the ones above it
   (mockup.formFields[].divider) - e.g. a step that carries known data forward next to a field that asks
   the reader to create something new (owner-reported 2026-09-29, redundant-entry's "New password"). */
.fm-divider { margin-top: 4px; padding-top: 16px; border-top: 1px solid var(--hairline); font-family: var(--font-display);
  font-weight: 700; font-size: var(--fs-200); text-transform: uppercase; letter-spacing: 0.04em; color: var(--label-text); }
.fm-label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); color: var(--navy); }
.fm-input { display: flex; align-items: center; min-height: 44px; margin-top: 6px; padding: 8px 12px; border: 1.5px solid var(--ui-border); border-radius: var(--radius-sm); background: #fff; font-size: var(--fs-300); color: var(--body-text); }
.fm-input--empty { color: var(--placeholder); }
.fm-note { margin-top: 6px; font-size: var(--fs-200); line-height: 1.45; color: var(--meta-text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.fm-note--block { color: var(--lic-red); }
.fm-code { display: flex; gap: 6px; margin-top: 6px; }
.fm-code__box { display: grid; place-items: center; width: 100%; max-width: 40px; min-height: 44px; border: 1.5px solid var(--ui-border); border-radius: var(--radius-sm); background: #fff; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-400); color: var(--navy); }
.fm-input--code { letter-spacing: 0.2em; font-family: var(--font-display); font-weight: 700; color: var(--navy); }
.fm-captcha { margin-top: 6px; display: grid; gap: 8px; }
.fm-captcha__plate { display: flex; align-items: center; justify-content: center; min-height: 52px; border: 1px solid var(--card-border-2); border-radius: var(--radius-sm); background: var(--ice);
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); font-style: italic; letter-spacing: 0.22em; color: var(--secondary-text); text-decoration: line-through wavy var(--ui-border); }
.fm-link { margin-top: 6px; font-size: var(--fs-300); color: var(--link-text); text-decoration: underline; }
.fm-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; margin-top: 6px; padding: 0 18px; border-radius: var(--radius-sm); font-family: var(--font-display); font-weight: 700; font-size: var(--fs-300); background: #fff; color: var(--navy); border: 1.5px solid var(--ui-border); }
.fm-btn--primary { background: var(--navy); color: #fff; border-color: var(--navy); }
.fm-summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; min-height: 44px; margin-top: 6px; padding: 8px 12px; border: 1px solid var(--card-border-2); border-radius: var(--radius-sm); background: var(--surface); font-size: var(--fs-300); color: var(--body-text); }
.fm-summary a, .fm-summary span.fm-change { color: var(--link-text); text-decoration: underline; font-weight: 600; }
.fm-check { flex: none; width: 18px; height: 18px; border: 1.5px solid var(--ui-border); border-radius: 4px; background: #fff; display: inline-block; position: relative; }
.fm-check.is-on { background: var(--navy); border-color: var(--navy); }
.fm-check.is-on::after { content: ""; position: absolute; left: 5px; top: 1px; width: 5px; height: 10px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.fm-text { margin-top: 6px; font-size: var(--fs-300); line-height: 1.5; color: var(--secondary-text); }
.fm-actions { padding-top: 2px; }

/* Related: cards share the row (auto-fit, no empty right half); the licence chip is pinned to the bottom so a row lines up. */
.sc-related { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin-top: 22px; }
.sc-related > :only-child { max-width: 440px; } /* .sc-more is always also .sc-cards-grid, covered above */
.lib-card__why { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
  font-size: var(--fs-300); line-height: 1.5; color: var(--secondary-text); }
.lib-card--related .lib-card__licence { margin-top: auto; padding-top: 6px; }

@media (max-width: 760px) {
  .feat-showcase { grid-template-columns: 1fr; gap: 28px; padding: 28px; }
  .feat-showcase__aside { border-left: 0; border-top: 1px solid rgba(255,255,255,0.16); padding-left: 0; padding-top: 24px; }
  .sc-shots, .sc-verdict { grid-template-columns: 1fr; }
  .sc-hero__h1 { font-size: var(--fs-850); }
}

/* =========================================================================
   Writing — Foundations index (featured lead + row list) + article detail (.post-*)
   ========================================================================= */
/* Latest article gets a distinct, larger treatment — a "front page" lead,
   not just the first item in a grid of equal boxes. */
.post-feature {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--card-border); border-left: 4px solid var(--civic-blue);
  border-radius: var(--radius-xl); background: var(--surface);
  padding: 34px 38px; margin-top: 28px;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.post-feature:hover { border-color: var(--civic-blue); background: var(--ice); }
.post-feature__eyebrow { display: block; font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--civic-blue); }
.post-feature__title { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-800); line-height: 1.1; letter-spacing: -0.03em; color: var(--navy); margin-top: 10px; max-width: 34ch; }
.post-feature__excerpt { display: block; font-size: var(--fs-400); line-height: 1.6; color: var(--secondary-text); margin-top: 12px; max-width: 62ch; }
.post-feature__meta { display: flex; align-items: center; gap: 8px; margin-top: 22px; font-size: var(--fs-200); font-weight: 600; color: var(--meta-text); }
.post-feature__cta { margin-left: auto; color: var(--civic-blue); font-weight: 700; }

/* Remaining articles read as an editorial index list (same row language as
   the Library/Newsletter rows) rather than a second row of boxy cards. */
.post-list { margin-top: 4px; border-top: 1px solid var(--card-border); }
.post-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 24px;
  padding: 22px 6px; border-bottom: 1px solid var(--card-border);
  border-left: 3px solid transparent; text-decoration: none; color: inherit;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.post-row:hover { border-left-color: var(--cyan); background: var(--ice); }
.post-row__main { min-width: 0; flex: 1; }
.post-row__title { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); letter-spacing: -0.02em; color: var(--navy); }
.post-row:hover .post-row__title { color: var(--civic-blue); }
.post-row__excerpt { display: block; font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); margin-top: 6px; max-width: 60ch; }
.post-row__meta { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; font-size: var(--fs-200); font-weight: 600; color: var(--meta-text); white-space: nowrap; }
.post-row__cta { color: var(--civic-blue); font-weight: 700; }

/* Foundations index: the 3 domain-definition articles read differently from the 9 learning-
   path topics above (a short reference definition, not a step in an order), so they get their
   own labelled section and a card grid instead of another row list - only when both groups
   exist (foundations.php $showGroups), so the page looks unchanged with just one kind published. */
.fn-section-head { font-size: var(--fs-700); letter-spacing: -0.02em; color: var(--navy); margin: 34px 0 14px; }
.fn-domains { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 4px; }
.fn-domain-card {
  display: flex; flex-direction: column; gap: 8px; padding: 20px; border: 1px solid var(--card-border);
  border-radius: var(--radius-md); text-decoration: none; color: inherit;
  transition: border-color 150ms ease-out, background 150ms ease-out;
}
.fn-domain-card:hover { border-color: var(--civic-blue); background: var(--ice); }
.fn-domain-card__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); letter-spacing: -0.02em; color: var(--navy); }
.fn-domain-card:hover .fn-domain-card__title { color: var(--civic-blue); }
.fn-domain-card__excerpt { font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); }
.fn-domain-card__cta { margin-top: auto; padding-top: 6px; font-size: var(--fs-200); font-weight: 700; color: var(--civic-blue); }
@media (max-width: 860px) { .fn-domains { grid-template-columns: 1fr; } }

/* Foundations index (owner-chosen layout A, 2026-09-30, 2_design/Foundations-topics-layout-proposal.html): the learning path
   on the left, focus areas and guides in a rail on the right so they are not buried under a long list. Grid areas keep the
   rail before the list on a phone. Compact rows: title + one line. */
.fn-cols { display: grid; grid-template-columns: minmax(0, 1fr) 340px; grid-template-areas: "feature rail" "path rail";
  column-gap: 40px; align-items: start; }
.fn-cols .post-feature { grid-area: feature; }
.fn-cols .fn-path { grid-area: path; }
.fn-cols .fn-rail { grid-area: rail; position: sticky; top: 24px; display: flex; flex-direction: column; gap: 14px; }
.fn-rail__head { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); margin: 0; letter-spacing: -0.02em; }
.fn-rail .fn-domain-card { padding: 14px 16px; gap: 4px; }
.fn-rail .fn-domain-card__excerpt { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--fs-200); }
.fn-guides { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--card-border); }
.fn-guides a { display: block; padding: 12px 4px; border-bottom: 1px solid var(--card-border); font-family: var(--font-display); font-weight: 700; color: var(--navy); text-decoration: none; }
.fn-guides a:hover { color: var(--civic-blue); }
.fn-guides small { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-family: var(--font-body); font-weight: 400; font-size: var(--fs-200); color: var(--meta-text); margin-top: 2px; }
.fn-path .post-row { padding-top: 14px; padding-bottom: 14px; }
.fn-path .post-row__title { font-size: var(--fs-500); }
.fn-path .post-row__excerpt { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; margin-top: 2px; font-size: var(--fs-200); }
.fn-path .post-row__cta { display: none; }
@media (max-width: 900px) {
  .fn-cols { grid-template-columns: minmax(0, 1fr); grid-template-areas: "feature" "rail" "path"; row-gap: 24px; }
  .fn-cols .fn-rail { position: static; }
}
/* No focus area and no guide published: the learning path takes the full width, as before. */
.fn-cols--single { grid-template-columns: minmax(0, 1fr); grid-template-areas: "feature" "path"; }

/* Glossary (glossary.php; owner-chosen option A of 2_design/Glossary-page-proposal.html, 2026-09-30): a dictionary, A to Z, with a
   letter jump bar. Two columns on a wide screen (the term, then its meaning), one on a phone. */
.gl-jump { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 0; }
.gl-jump a, .gl-jump span { display: inline-grid; place-items: center; min-width: 32px; min-height: 44px; padding: 0 6px; border-radius: var(--radius-sm);
  font-family: var(--font-display); font-weight: 700; color: var(--navy); text-decoration: none; }
.gl-jump a:hover { background: var(--ice); }
.gl-jump span { color: var(--placeholder); }
.gl-letter { font-size: var(--fs-800); letter-spacing: -0.03em; color: var(--navy); margin: 36px 0 6px; padding-top: 6px; border-top: 1px solid var(--card-border); scroll-margin-top: 16px; }
.gl-list { margin: 0; }
.gl-term { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 8px 32px; padding: 18px 0; border-bottom: 1px solid var(--hairline); scroll-margin-top: 16px; }
.gl-term:target { background: var(--ice); }
.gl-term dt { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); letter-spacing: -0.02em; }
.gl-abbr { display: block; margin-top: 4px; font-size: var(--fs-200); color: var(--label-text); font-weight: 700; letter-spacing: 0.04em; }
.gl-term dd { margin: 0; min-width: 0; }
.gl-term p { margin: 0 0 8px; color: var(--secondary-text); max-width: 64ch; }
.gl-design { font-size: var(--fs-200); color: var(--meta-text); }
.gl-design b { color: var(--navy); }
.gl-related { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 0; padding: 0; list-style: none; }
.gl-related a { font-size: var(--fs-200); font-weight: 600; color: var(--link-text); }
.gl-related__kind { font-weight: 400; color: var(--meta-text); }
.gl-note { margin: 40px 0 0; font-size: var(--fs-200); color: var(--meta-text); max-width: 70ch; }
@media (max-width: 700px) { .gl-term { grid-template-columns: 1fr; gap: 4px; } }

.post { max-width: 720px; }
.post__back { display: block; width: fit-content; margin-bottom: 18px; }
.post__title { font-size: var(--fs-850); line-height: 1.02; letter-spacing: -0.03em; color: var(--navy); margin: 6px 0 0; }
.post__meta { color: var(--meta-text); font-size: var(--fs-200); margin: 14px 0 0; }
.post__lead { font-size: var(--fs-500); line-height: 1.6; color: var(--navy); font-weight: 600; margin: 22px 0 0; }
.post__body { margin-top: 22px; }
.post__body p { font-size: var(--fs-400); line-height: 1.75; color: var(--body-text, var(--secondary-text)); margin: 0 0 18px; }
.post__body h2 { font-family: var(--font-display); font-size: var(--fs-700); letter-spacing: -0.02em; color: var(--navy); margin: 34px 0 14px; }
.post__body ul, .post__body ol { margin: 0 0 18px; padding-left: 22px; }
.post__body li { font-size: var(--fs-400); line-height: 1.7; color: var(--body-text, var(--secondary-text)); margin: 0 0 6px; }
.post__body a { overflow-wrap: anywhere; } /* a long address typed as plain text must wrap, not push the page sideways on a phone */
/* Newsletter issue body (issue_body_html() in includes/ui.php; owner-approved proposal 2_design/Newsletter-issue-page-proposal.html).
   A source line is a quiet row (SOURCE + a chip saying what kind of source + the link); "Try this week" is the one box the reader should act on. */
.post__body .post-source { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: var(--fs-200); line-height: 1.5; color: var(--meta-text); margin: -6px 0 24px; }
.post-source__label { font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; color: var(--label-text); }
.post__body .post-source a { font-weight: 600; }
.post-try { border: 2px solid var(--cyan); border-radius: var(--radius-md); background: var(--ice); padding: 18px 20px; margin: 30px 0;
  font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); }
.post-try__label { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); color: var(--navy); margin-bottom: 6px; }
/* "Further reading" as a closed-by-default accordion (foundations.php render_foundation_body())
   - a citation list can run to 20+ items, which reads as more of the page than the article
   itself; collapsed, the article stays short regardless of source count. Same disclosure pattern
   as Admin's .review__lib / .admin-side__paused (includes/admin_layout.php, admin.css) - a plain
   <details>, no JS. Open, the citations show at a smaller "note" size so they read as reference
   material, not body copy. Owner-approved proposal: 2_design/Foundations-domains-and-further-
   reading-proposal.html. */
.fr-acc { border: 1px solid var(--hairline); border-radius: var(--radius-md); margin: 34px 0 18px; background: var(--surface); }
.fr-acc summary {
  cursor: pointer; list-style: none; padding: 14px 18px; display: flex; align-items: baseline; gap: 8px;
  font-family: var(--font-display); font-size: var(--fs-700); letter-spacing: -0.02em; color: var(--navy);
}
.fr-acc summary::-webkit-details-marker { display: none; }
.fr-acc summary::after { content: "▾"; margin-left: auto; font-size: 12px; color: var(--civic-blue); }
.fr-acc[open] summary::after { content: "▴"; }
.fr-acc__count { font-family: var(--font-body); font-weight: 600; font-size: var(--fs-200); color: var(--meta-text); }
.fr-acc__inner { padding: 0 18px 18px; }
.fr-acc__inner ul, .fr-acc__inner ol { margin: 0; padding-left: 20px; }
.fr-acc__inner li { font-size: var(--fs-200); line-height: 1.6; color: var(--meta-text); margin: 0 0 8px; }
.post-figure { margin: 26px 0; }
/* max-width caps a diagram close to its own drawn size instead of stretching it to the full 720px
   reading column (found 2026-09-30 on the Foundations #0 product-types table, drawn at 448px but
   rendered ~60% larger); a wider photo still grows to fill the column on narrow viewports. */
.post-figure img { width: 100%; max-width: 480px; height: auto; border-radius: var(--radius-md); display: block; margin: 0 auto; }
.post-figure figcaption { font-size: var(--fs-200); color: var(--meta-text); margin-top: 8px; }
.post-callout { border-left: 3px solid var(--cyan); background: var(--surface); border-radius: 0 10px 10px 0;
  padding: 16px 18px; margin: 22px 0; font-size: var(--fs-300); line-height: 1.6; color: var(--secondary-text); }

/* =========================================================================
   Articles + Further reading (Home teaser and the Articles index share these).
   Two visual languages, on purpose: a CARD is something this site wrote and opens
   inside the site; a plain ↗ ROW is someone else's work and opens the original.
   ========================================================================= */

/* Lead block = the 3 newest articles: one large "Latest" card (2/3) + two compact cards (1/3). The lead spans
   both rows, so it is as tall as the two compact cards together; with 1 or 2 articles it adapts. The 2:1 split
   keeps the block on the same 3-column lines as anything under it. */
.page-intro .link-tertiary { white-space: nowrap; } /* "Further reading ↓" must not break across lines */
.art-block { display: grid; grid-template-columns: 2fr 1fr; grid-template-rows: auto auto; gap: 22px; margin-top: 28px; }
.art-block > .art-card--lead { grid-row: 1 / span 2; }
.art-block--1 { grid-template-columns: 1fr; }
.art-block--1 > .art-card--lead { grid-row: auto; }
.art-block--2 > .art-card--side { grid-row: 1 / span 2; }

.art-card {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: #fff; border: 1px solid var(--card-border); border-radius: var(--radius-xl); padding: 24px 26px;
  transition: transform 150ms ease-out, border-color 150ms ease-out;
}
.art-card:hover { transform: translateY(-3px); border-color: var(--civic-blue); }
.art-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.art-card--lead { background: var(--surface); border-left: 4px solid var(--civic-blue); padding: 34px 36px; }
.art-card__top { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.art-card--lead .chip { background: #fff; }
/* On Home the Articles teaser sits on a --surface ground (2026-10-07), the same colour as the lead card: the lead turns white
   there so it does not vanish into the section, and its chips take --ice so they stay visible on it. */
.section--tint .art-card--lead { background: #fff; }
.section--tint .art-card--lead .chip { background: var(--ice); }
.art-card__label { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--civic-blue); }
.art-card__meta { font-size: var(--fs-200); font-weight: 600; color: var(--meta-text); }
.art-card__title { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); line-height: 1.2; letter-spacing: -0.02em; color: var(--navy); margin-top: 8px; }
.art-card:hover .art-card__title { color: var(--civic-blue); }
.art-card--lead .art-card__title { font-size: var(--fs-800); line-height: 1.1; letter-spacing: -0.03em; margin-top: 10px; max-width: 24ch; }
/* Excerpts are always clamped, so a long one never turns a card into a wall of text. */
.art-card__excerpt, .art-row__excerpt { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.art-card__excerpt { font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); margin-top: 8px; }
.art-card--lead .art-card__excerpt { font-size: var(--fs-400); line-height: 1.6; margin-top: 14px; max-width: 64ch; -webkit-line-clamp: 4; }
.art-card__foot { margin-top: auto; padding-top: 18px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.art-card__cta, .art-row__cta { margin-left: auto; font-weight: 700; font-size: var(--fs-200); color: var(--link-text); border-bottom: 2px solid var(--cyan); padding-bottom: 1px; white-space: nowrap; }

/* Articles index: heading over the block (only when Further reading follows) and the list for the 4th article on. */
.art-zone { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 44px; padding-bottom: 12px; border-bottom: 1px solid var(--card-border); }
.art-zone h2 { font-size: var(--fs-700); letter-spacing: -0.02em; color: var(--navy); }
.art-zone span { font-size: var(--fs-200); font-weight: 600; color: var(--meta-text); }
.art-zone + .art-block { margin-top: 24px; }
.art-zone + .lib-tabs { border-top: 0; margin-top: 0; padding-top: 22px; }   /* the zone heading already has the rule */
.art-zone + .lib-filters { margin-top: 22px; }
/* One shared left rail: article rows (date column) and Further-reading groups (topic column) use the same width,
   so the text beside them starts on the same vertical line. */
.art-list, .reading { --rail: 180px; --rail-gap: 32px; }
.art-list { margin-top: 34px; border-top: 1px solid var(--card-border); }
.art-row {
  position: relative; display: grid; grid-template-columns: var(--rail) minmax(0, 1fr) auto; gap: 8px var(--rail-gap); align-items: baseline;
  padding: 22px 0; border-bottom: 1px solid var(--card-border); text-decoration: none; color: inherit;
}
/* Hover tint reaches past the text edge, so the title never shifts off the page margin. */
.art-row::before { content: ""; position: absolute; inset: 0 -14px; background: var(--ice); border-radius: var(--radius-md); opacity: 0; transition: opacity 150ms ease-out; z-index: 0; }
.art-row:hover::before { opacity: 1; }
.art-row > * { position: relative; z-index: 1; }
.art-row:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 6px; }
.art-row__meta { display: grid; gap: 2px; font-size: var(--fs-200); font-weight: 600; color: var(--meta-text); }
.art-row__date { color: var(--navy); }
.art-row__meta .chip { justify-self: start; margin-top: 4px; }
.lib-status + .art-list { margin-top: 18px; }
.post__tags { margin: 14px 0 0; display: flex; flex-wrap: wrap; gap: 6px 8px; }
.art-row__by { font-weight: 500; }
.art-row__title { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); line-height: 1.2; letter-spacing: -0.02em; color: var(--navy); }
.art-row:hover .art-row__title { color: var(--civic-blue); }
.art-row__excerpt { font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); margin-top: 6px; max-width: 64ch; }

/* Further reading — link-outs to other people's work. Deliberately quiet: no cards, no lift, a plain list under a
   hairline, grouped by topic (label in the left column), no dates. The ↗ + the host name say "this leaves the site";
   the licence chip is the small tinted one (.lic--mini, base.css) — the same chip the Library uses. */
.reading { margin-top: 72px; padding-top: 28px; border-top: 1px solid var(--card-border); }
.reading__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px 24px; flex-wrap: wrap; margin-bottom: 14px; }
.reading__title { font-family: var(--font-display); font-size: var(--fs-500); letter-spacing: -0.01em; color: var(--navy); margin: 0; }
.reading__intro { font-size: var(--fs-300); color: var(--meta-text); margin: 0; }
.reading__group { display: grid; grid-template-columns: var(--rail) minmax(0, 1fr); gap: 4px var(--rail-gap); border-top: 1px solid var(--card-border); padding-top: 16px; }
.reading__group + .reading__group { margin-top: 18px; }
.reading__group--plain { grid-template-columns: 1fr; }
.reading__topic { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--navy); padding-top: 17px; margin: 0; }
.reading-list { list-style: none; margin: 0; padding: 0; }
.reading-list--flat { margin-top: 20px; border-top: 1px solid var(--card-border); }
.reading-list--flat .reading-row:last-child { border-bottom: 1px solid var(--card-border); }
/* One compact row: title on its own line, then a single clamped line carrying credit + note + chips together,
   so a row reads as ~2 lines instead of stacking title/credit/note/tags as four separate blocks. */
.reading-row { padding: 12px 0; }
.reading-row + .reading-row { border-top: 1px solid var(--hairline); }
.reading-row__title { font-weight: 600; font-size: var(--fs-400); line-height: 1.4; color: var(--link-text); text-decoration: none; }
.reading-row__title:hover { color: var(--navy); text-decoration: underline; }
.reading-row__line { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); margin: 4px 0 0; max-width: 72ch; }
.reading-row__meta { color: var(--meta-text); font-weight: 600; }
.reading-row__chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 6px 0 0; }

/* Further reading teaser (on /articles): one domain group = heading + one random row + a "More" link. */
.reading-teaser__group { border-top: 1px solid var(--card-border); padding-top: 16px; margin-top: 18px; }
.reading-teaser__group:first-child { margin-top: 0; }
.reading-teaser__group .reading__topic { padding-top: 0; }
.reading-teaser__n { font-family: var(--font-body); font-size: var(--fs-200); font-weight: 600; text-transform: none; letter-spacing: normal; color: var(--meta-text); }
.reading-teaser__more { display: inline-block; margin-top: 10px; font-weight: 700; font-size: var(--fs-200); color: var(--link-text); text-decoration: none; border-bottom: 2px solid var(--cyan); padding-bottom: 1px; }
.reading-teaser__more:hover { color: var(--navy); }

/* Breadcrumb (visible trail, e.g. Home / Articles / Further reading) - separate from the hidden BreadcrumbList schema. */
.crumb { font-size: var(--fs-200); color: var(--meta-text); margin-bottom: 14px; }
.crumb a { color: var(--meta-text); text-decoration: none; font-weight: 600; }
.crumb a:hover { color: var(--civic-blue); }
.crumb__sep { margin: 0 6px; }

@media (max-width: 860px) {
  .art-block { grid-template-columns: 1fr; grid-template-rows: auto; }
  .art-block > .art-card--lead, .art-block--2 > .art-card--side { grid-row: auto; }
  .art-card--lead { padding: 26px 24px; }
  .art-card--lead .art-card__title { font-size: var(--fs-700); }
  .art-row { grid-template-columns: 1fr; gap: 6px; }
  .art-row__meta { display: flex; gap: 10px; }
  .art-row__cta { display: none; }
  .reading__group { grid-template-columns: 1fr; gap: 0; }
  .reading__topic { padding-top: 0; }
}

@media (max-width: 560px) {
  .post__title { font-size: var(--fs-800); }
  .post-feature { padding: 26px 24px; }
  .post-feature__title { font-size: var(--fs-700); }
  .post-row { flex-direction: column; align-items: flex-start; gap: 8px; }
  .post-row__meta { white-space: normal; }
}

/* =========================================================================
   System / error pages (404, 403, 500) — branded, self-contained
   ========================================================================= */
.errpage { min-height: 100vh; background: #fff; display: flex; }
.errpage__wrap { margin: auto; width: 100%; max-width: var(--maxw); padding: 48px var(--gutter); position: relative; }
.errpage .wordmark { display: inline-block; margin-bottom: 56px; }
.errpage__box { max-width: 560px; position: relative; z-index: 1; }
.errpage__code {
  display: block; font-family: var(--font-display); font-weight: 700;
  font-size: 132px; line-height: 0.9; letter-spacing: -0.05em; color: var(--ice);
  margin-bottom: 8px; user-select: none;
}
.errpage h1 { font-size: var(--fs-850); line-height: 1.05; letter-spacing: -0.035em; color: var(--navy); margin: 14px 0 0; }
.errpage p { font-size: var(--fs-400); line-height: 1.65; color: var(--secondary-text); margin: 14px 0 0; max-width: 48ch; }
.errpage__actions { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }
@media (max-width: 560px) {
  .errpage__code { font-size: 96px; }
  .errpage h1 { font-size: var(--fs-800); }
  .errpage .wordmark { margin-bottom: 36px; }
}

/* =========================================================================
   Legal / policy pages (privacy, disclaimer, sourcing)
   ========================================================================= */
.legal { margin-top: 8px; }
.legal h2 { font-size: var(--fs-600); letter-spacing: -0.02em; color: var(--navy); margin: 36px 0 0; }
.legal p { font-size: var(--fs-400); line-height: 1.7; color: var(--secondary-text); margin: 12px 0 0; max-width: 68ch; }
.legal ul { margin: 12px 0 0; padding-left: 20px; max-width: 68ch; }
.legal li { font-size: var(--fs-400); line-height: 1.7; color: var(--secondary-text); margin: 6px 0; }
.legal a { color: var(--link-text); }
.legal strong { color: var(--navy); }
.legal__updated { color: var(--meta-text); font-size: var(--fs-200); margin: 8px 0 0; }

/* Newsletter capture messages (injected by site.js). The subscribe forms sit on
   navy grounds (hero + CTA band), so style for readable contrast there. */
.subscribe-msg {
  display: inline-block; font-size: var(--fs-200); font-weight: 700; line-height: 1.4;
  margin: 12px 0 0; max-width: 460px; padding: 9px 13px; border-radius: var(--radius-sm);
}
.subscribe-msg--ok { background: rgba(37, 224, 192, 0.16); color: var(--on-navy-ok); }
.subscribe-msg--error { background: rgba(255, 255, 255, 0.14); color: var(--on-navy-error); }
/* Honeypot: off-screen text field real users never fill; bots do (dropped server-side). */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

/* =========================================================================
   Jobs (toggleable section)
   ========================================================================= */
.job-list { margin-top: 28px; border-top: 1px solid var(--card-border); }
.job-row {
  display: flex; align-items: center; gap: 16px; justify-content: space-between;
  padding: 20px 0; border-bottom: 1px solid var(--card-border); text-decoration: none;
}
.job-row:hover .job-row__title { color: var(--civic-blue); }
.job-row__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); display: block; }
.job-row__note { color: var(--secondary-text); font-size: var(--fs-300); font-style: italic; display: block; margin-top: 4px; }
.job-row__meta { color: var(--meta-text); font-size: var(--fs-200); display: block; margin-top: 6px; }
.job-row__type { flex: 0 0 auto; }

/* =========================================================================
   Tools & templates + Community cards (shared grid)
   ========================================================================= */
.tool-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 18px; margin-top: 28px; }
.tool-card {
  display: flex; flex-direction: column; gap: 10px; text-decoration: none;
  background: #fff; border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 20px;
  transition: border-color .12s, transform .12s;
}
.tool-card:hover { border-color: var(--navy); transform: translateY(-2px); }
.tool-card__top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tool-card__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); letter-spacing: -0.02em; color: var(--navy); }
.tool-card__desc { color: var(--secondary-text); font-size: var(--fs-300); line-height: 1.55; }
.community-card__icon { color: var(--civic-blue); display: inline-flex; }

.community-feature { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 18px; margin-top: 28px; }
.community-feature > :only-child { max-width: 440px; } /* one featured link = full-width card without this - see conventions.md "Front-end conventions" */
.community-cta {
  display: flex; gap: 16px; align-items: flex-start; text-decoration: none;
  border-radius: var(--radius-xl); padding: 26px; color: #fff; transition: transform .12s;
}
.community-cta:hover { transform: translateY(-2px); }
.community-cta--navy { background: var(--hero-grad, var(--navy)); }
.community-cta--teal { background: linear-gradient(135deg, var(--teal-mid), var(--navy)); }
.community-cta__icon { color: var(--cyan); flex: 0 0 auto; }
.community-cta__label { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); color: #fff; display: block; }
.community-cta__desc { color: var(--on-navy-body); font-size: var(--fs-300); line-height: 1.55; display: block; margin-top: 6px; }

@media (max-width: 560px) {
  .job-row { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* Reduced motion: no hover lift on cards (the border colour still changes). */
@media (prefers-reduced-motion: reduce) {
  .lib-card:hover, .sc-card2:hover, .art-card:hover, .tool-card:hover, .community-cta:hover, .wyf-card:hover { transform: none; }
}

/* =========================================================================
   Digital health DESIGN checklist (/foundations/checklist.php)
   Layout iterated in 2_design/Foundations-checklist-page-proposal.html - see
   docs/SOT/ROADMAP.md "Digital health DESIGN checklist" for the owner review
   history (placement, per-item sizing, no numbering, the Download-PDF mechanism).
   ========================================================================= */
.chk-hero {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--hero-grad); background-size: 200% 200%; animation: heroPan 22s ease-in-out infinite;
  color: #fff; padding: 64px 0;
}
.chk-hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: radial-gradient(rgba(255,255,255,0.16) 1.3px, transparent 1.4px); background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(120% 120% at 100% 0%, #000 30%, transparent 72%);
          mask-image: radial-gradient(120% 120% at 100% 0%, #000 30%, transparent 72%);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) { .chk-hero { animation: none; } }
.chk-hero__h1 { font-size: var(--fs-900); line-height: 1.02; letter-spacing: -0.04em; color: #fff; max-width: 22ch; margin: 16px 0 0; }
.chk-hero__sub { color: var(--on-navy-body); font-size: var(--fs-500); line-height: 1.6; max-width: 56ch; margin: 18px 0 0; }
.chk-hero__more { margin: 22px 0 0; font-size: var(--fs-300); color: #fff; font-weight: 600; }
@media (max-width: 900px) { .chk-hero__h1 { font-size: var(--fs-850); } }

.chk-callout { max-width: 760px; margin-top: 32px; }
.chk-intro { margin-top: 24px; max-width: 74ch; color: var(--secondary-text); font-size: var(--fs-400); line-height: 1.7; }

.chk-toc { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.chk-toc a { display: inline-flex; align-items: center; font-size: var(--fs-100); font-weight: 600; padding: 5px 12px; border-radius: var(--radius-pill); background: var(--ice); color: var(--secondary-text); text-decoration: none; }
.chk-toc a:hover { background: var(--chip-hover-bg); color: var(--navy); }

.chk-dl {
  display: flex; flex-wrap: wrap; align-items: center; gap: 18px;
  border: 1.5px solid var(--civic-blue); border-radius: var(--radius-lg); background: var(--ice);
  padding: 22px 26px; margin-top: 28px; max-width: 720px;
}
.chk-dl--repeat { margin-top: 32px; }
.chk-dl__icon { flex: none; width: 48px; height: 48px; border-radius: 50%; background: #fff; display: grid; place-items: center; color: var(--civic-blue); }
.chk-dl__icon svg { width: 24px; height: 24px; }
.chk-dl__body { flex: 1; min-width: 200px; }
.chk-dl__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); }
.chk-dl__desc { font-size: var(--fs-300); color: var(--secondary-text); margin-top: 4px; }
.chk-dl__btn { flex: none; }

.chk-list { display: grid; gap: 16px; margin-top: 28px; }
.chk-item { border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 24px 26px; display: grid; grid-template-columns: 44px 1fr; gap: 16px; align-items: start; }
.chk-item__side { grid-column: 1; }
.chk-item__icon { width: 44px; height: 44px; border-radius: 50%; background: var(--ice); color: var(--civic-blue); display: grid; place-items: center; }
.chk-item__body { grid-column: 2; min-width: 0; }
.chk-item__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-600); color: var(--navy); letter-spacing: -0.01em; }
.chk-item__q { font-size: var(--fs-400); color: var(--secondary-text); font-style: italic; margin: 4px 0 0; max-width: 64ch; }
.chk-item__content { margin-top: 16px; }
.chk-item__content p, .chk-item__content ul, .chk-item__content ol { font-size: var(--fs-300); color: var(--body-text); line-height: 1.55; margin: 10px 0 0; }
.chk-item__content ul, .chk-item__content ol { padding-left: 0; list-style: none; display: grid; gap: 7px; }
.chk-item__content ul li, .chk-item__content ol li { display: flex; gap: 9px; align-items: flex-start; }
.chk-item__content ul li::before, .chk-item__content ol li::before { content: "☐"; flex: none; color: var(--ui-border); font-size: 15px; line-height: 1.4; }
.chk-item__content .post-callout { margin-top: 14px; font-size: var(--fs-200); color: var(--meta-text); background: none; border: 0; padding: 0; }
.chk-item__content .post-callout strong { color: var(--label-text); font-weight: 700; text-transform: uppercase; font-size: 11px; letter-spacing: 0.06em; }
.chk-item__links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }

.chk-closing { border: 1.5px dashed var(--lic-amber-border); border-radius: var(--radius-lg); background: #fff; padding: 22px 26px; margin-top: 28px; max-width: 760px; }
.chk-closing__lbl { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--lic-amber-ink); }
.chk-closing p { font-size: var(--fs-300); color: var(--secondary-text); margin: 8px 0 0; line-height: 1.6; }

@media (max-width: 560px) {
  .chk-item { grid-template-columns: 36px 1fr; padding: 18px; }
  .chk-item__icon { width: 36px; height: 36px; }
}

/* =========================================================================
   Search (/search) - docs/SOT/IMPROVE.md "Search - plan"; layout iterated in 2_design/Search-proposal.html.
   Reuses .lib-filters / .search-field (the form), .lib-tab (jump links), .lib-group (a section's heading),
   .reading-row (a link-out row) and the tag / licence chips. New here: the band label, the own-content row, <mark>.
   ========================================================================= */
.search-page .lib-tabs { margin-top: 20px; padding-top: 18px; }
.search-page .lib-group__title { scroll-margin-top: 16px; }
/* "Written for this site" / "Links to other sites": says which rows open inside the site and which leave it. */
.srch-band { margin: 48px 0 0; font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--label-text); }
.srch-band + .lib-group { margin-top: 14px; }
.srch-try + .srch-band { margin-top: 40px; }
.srch-list { list-style: none; margin: 0; padding: 0; }
.srch-row { position: relative; padding: 18px 0; border-bottom: 1px solid var(--hairline); }
/* Hover tint reaches past the text edge so the title never shifts off the page margin (same idea as .art-row). */
.srch-row::before { content: ""; position: absolute; inset: 0 -14px; background: var(--ice); border-radius: var(--radius-md); opacity: 0; z-index: 0; }
.srch-row:hover::before { opacity: 1; }
.srch-row > * { position: relative; z-index: 1; }
.srch-row__title { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); line-height: 1.25; letter-spacing: -0.015em; color: var(--navy); text-decoration: none; }
.srch-row:hover .srch-row__title { color: var(--civic-blue); }
.srch-row__line { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); margin: 6px 0 0; max-width: 72ch; }
.srch-row__chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0 0; }
.search-page mark { background: var(--chip-hover-bg); color: inherit; font-weight: 600; border-radius: 3px; padding: 0 2px; }
/* No results / empty box */
.srch-msg { margin-top: 40px; max-width: 62ch; }
.srch-msg strong { display: block; font-family: var(--font-display); font-size: var(--fs-600); line-height: 1.25; letter-spacing: -0.015em; color: var(--navy); }
.srch-msg p { margin: 8px 0 0; color: var(--secondary-text); }
.srch-try { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 20px; font-size: var(--fs-200); color: var(--meta-text); }
.srch-try .chip { font-size: var(--fs-200); padding: 5px 12px; }
.srch-browse { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 14px; }
.srch-browse > :only-child { max-width: 440px; }   /* the tile count follows which sections exist: keep a lone tile from stretching */
.srch-tile { display: block; border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 18px 20px; text-decoration: none; color: inherit; }
.srch-tile:hover { border-color: var(--civic-blue); background: var(--ice); }
.srch-tile b { display: block; font-family: var(--font-display); font-size: var(--fs-500); letter-spacing: -0.015em; color: var(--navy); }
.srch-tile span { display: block; font-size: var(--fs-300); line-height: 1.55; color: var(--secondary-text); margin-top: 4px; }
@media (max-width: 640px) {
  .search-page .lib-filters .btn { flex: 1 1 100%; }
  .srch-browse { grid-template-columns: 1fr; }
  .search-page .lib-group__title { font-size: var(--fs-600); }
}

/* ---- Showcase component pages (kind = component) -------------------------------------------------------------
   The Reading status component itself (.rs), its live specimen (.spec-demo), the spec tables, do / don't and the
   code block. Colours are tokens only. The contrast table on the page reads the SAME tokens from base.css :root,
   so a state's colour here and in SHOWCASE_SPECIMENS (includes/showcase-spec.php) must stay in step.
   The marks are inline SVG that take the text colour, so they survive forced-colour modes. */
.rs { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: var(--fs-200); line-height: 1.3; white-space: nowrap; }
.rs__mark { flex: none; width: 12px; height: 12px; display: block; }
.rs--normal { color: var(--lic-green); }
.rs--high { color: var(--lic-red); }
.rs--low { color: var(--lic-amber-ink); }
.rs--low .rs__mark { color: var(--lic-amber-border); }   /* the Low shape is the lighter amber; its word is the darker one */
.rs--none { color: var(--meta-text); }
.rs--lg { font-size: var(--fs-300); gap: 8px; }
.rs--lg .rs__mark { width: 14px; height: 14px; }

.spec-h3 { font-family: var(--font-display); font-size: var(--fs-500); letter-spacing: -0.015em; color: var(--navy); margin: 26px 0 0; }
.spec-p { margin: 10px 0 0; color: var(--secondary-text); }
.spec-list { margin: 12px 0 0; padding-left: 20px; color: var(--secondary-text); }
.spec-list li { margin-top: 8px; }
.spec-links { margin: 10px 0 0; padding: 0; list-style: none; }
.spec-links li { margin-top: 8px; color: var(--secondary-text); }
.spec-kind { font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--meta-text); margin-left: 6px; }

.spec-tablewrap { margin-top: 18px; overflow-x: auto; border: 1px solid var(--card-border); border-radius: var(--radius-lg); }
.spec-table { width: 100%; min-width: 640px; border-collapse: collapse; font-size: var(--fs-200); }
.spec-table th, .spec-table td { text-align: left; vertical-align: top; padding: 10px 14px; border-bottom: 1px solid var(--card-border); color: var(--secondary-text); }
.spec-table thead th { background: var(--ice); color: var(--navy); font-family: var(--font-display); font-size: var(--fs-100); }
.spec-table tbody th { color: var(--navy); font-weight: 700; }
.spec-table tr:last-child > * { border-bottom: 0; }
.spec-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.spec-fail { color: var(--lic-red); }

/* parts of a screen */
.spec-parts { margin: 16px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.spec-parts li { border: 1px solid var(--card-border); border-radius: var(--radius-md); padding: 12px 16px; }
.spec-parts b { display: block; font-family: var(--font-display); color: var(--navy); }
.spec-parts span:not(.spec-badge) { display: block; margin-top: 4px; font-size: var(--fs-200); color: var(--secondary-text); }
.spec-badge { display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: var(--radius-sm); font-family: var(--font-body); font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; background: var(--navy); color: #fff; vertical-align: middle; }
.spec-badge--planned { background: #fff; color: var(--meta-text); border: 1px solid var(--ui-border); }

/* live specimen */
.spec-defs { position: absolute; width: 0; height: 0; }
.spec-demo { margin-top: 18px; border: 1px solid var(--card-border-2); border-radius: var(--radius-lg); overflow: hidden; background: #fff; }
.spec-demo__bar { background: var(--surface); padding: 12px 16px; border-bottom: 1px solid var(--card-border-2); min-height: 8px; }
.spec-view { border: 0; margin: 0; padding: 0; min-width: 0; }
.spec-view legend { padding: 0; margin-bottom: 6px; font-size: var(--fs-100); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--meta-text); }
.spec-view__opts { display: flex; flex-wrap: wrap; gap: 6px; }
.spec-view label { position: relative; display: inline-flex; }
.spec-view input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.spec-view label span { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; border: 1px solid var(--ui-border); border-radius: var(--radius-sm); background: #fff; font-size: var(--fs-200); font-weight: 600; color: var(--navy); }
.spec-view input:checked + span { background: var(--navy); border-color: var(--navy); color: #fff; }
.spec-view input:focus-visible + span { outline: 2px solid var(--focus-ring); outline-offset: 2px; box-shadow: 0 0 0 3px var(--focus-halo); }
.spec-stage.is-gray { filter: grayscale(1); }
.spec-stage.is-deut { filter: url(#spec-deut); }
.spec-demo__cols { display: grid; grid-template-columns: 1fr 1fr; }
.spec-demo__col { padding: 16px 18px 6px; }
.spec-demo__col + .spec-demo__col { border-left: 1px solid var(--card-border); }
.spec-demo__h { font-family: var(--font-display); font-size: var(--fs-200); color: var(--navy); margin: 0 0 6px; }
.spec-demo__h small { font-family: var(--font-body); font-weight: 600; color: var(--meta-text); margin-left: 6px; }
.spec-demo__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 0; border-top: 1px solid var(--hairline); }
.spec-demo__h + .spec-demo__row { border-top: 0; }
.spec-demo__lbl { display: block; font-size: var(--fs-200); color: var(--meta-text); }
.spec-demo__val { display: block; font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); line-height: 1.3; }
.spec-demo__foot { margin: 0; padding: 10px 18px 14px; font-size: var(--fs-200); color: var(--meta-text); border-top: 1px solid var(--hairline); }
/* the "before": a coloured dot and nothing else */
.spec-dot { display: inline-block; flex: none; width: 10px; height: 10px; border-radius: 50%; }
.spec-dot--normal { background: var(--lic-green); }
.spec-dot--high { background: var(--lic-red); }
.spec-dot--low { background: var(--lic-amber-border); }
.spec-dot--none { background: var(--ui-border); }

/* anatomy */
.spec-anat { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; align-items: start; margin-top: 18px; }
.spec-anat__fig { background: var(--surface); border: 1px solid var(--card-border); border-radius: var(--radius-lg); padding: 24px 18px; display: flex; justify-content: center; }
.spec-anat__row { display: inline-flex; align-items: flex-end; gap: 16px; background: #fff; border: 1px solid var(--card-border-2); border-radius: var(--radius-md); padding: 16px 20px; }
.spec-anat__part { display: inline-flex; flex-direction: column; align-items: center; gap: 8px; }
.spec-anat__n { width: 24px; height: 24px; border-radius: 50%; background: var(--navy); color: #fff; font-size: var(--fs-100); font-weight: 700; display: grid; place-items: center; }
.spec-anat__val { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); }
.spec-anat__list { margin: 0; padding-left: 20px; color: var(--secondary-text); font-size: var(--fs-300); }
.spec-anat__list li { margin-top: 8px; }
.spec-anat__list li:first-child { margin-top: 0; }

/* do / don't */
.spec-dd { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 18px; }
.spec-dd__c { border: 1px solid var(--card-border); border-radius: var(--radius-lg); overflow: hidden; background: #fff; }
.spec-dd__demo { display: flex; align-items: center; gap: 14px; padding: 22px 18px; min-height: 76px; }
.spec-dd__val { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-500); color: var(--navy); }
.spec-dd__cap { margin: 0; padding: 10px 14px; font-size: var(--fs-200); border-top: 1px solid var(--card-border); color: var(--secondary-text); }
.spec-dd__cap strong { color: var(--navy); }
.spec-dd__c--do .spec-dd__cap { background: var(--lic-green-tint); }
.spec-dd__c--dont .spec-dd__cap { background: var(--lic-red-tint); }
.spec-fakebtn { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--ui-border); border-radius: var(--radius-pill); padding: 5px 12px; font-weight: 700; font-size: var(--fs-200); color: var(--lic-red); background: var(--lic-red-tint); }

/* code */
.spec-code { margin: 16px 0 0; background: var(--footer-ground); color: var(--on-navy-strong); border-radius: var(--radius-md); padding: 16px 18px; font-family: ui-monospace, Consolas, monospace; font-size: var(--fs-200); line-height: 1.6; overflow-x: auto; }
.spec-code:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; box-shadow: 0 0 0 3px var(--focus-halo); }
#take .callout { margin-top: 18px; }

@media (max-width: 760px) {
  .spec-demo__cols, .spec-anat, .spec-dd { grid-template-columns: 1fr; }
  .spec-demo__col + .spec-demo__col { border-left: 0; border-top: 1px solid var(--card-border); }
}

/* "Download PDF" (checklist.php) is a plain window.print() button, not a route/file - this is
   what makes that print (or the browser's own Print > Save as PDF) come out clean: hide the
   site chrome and the page's own download affordances, keep only the checkpoints themselves. */
@media print {
  .preview-bar, .site-header, .site-footer, .back-to-top, .skip-link, .colour-strip,
  .chk-hero__more, .chk-toc, .chk-dl { display: none !important; }
  .chk-hero { background: none !important; color: var(--navy) !important; padding: 0 0 24px; }
  .chk-hero::before { display: none; }
  .chk-hero__sub { color: var(--secondary-text) !important; }
  .chk-item { break-inside: avoid; }
}
