:root {
  --fg: #1f2933;
  --fg-strong: #0f172a;
  --muted: #6b7280;
  --muted-soft: #94a3b8;
  --bg: #fbfbfd;
  --surface: #ffffff;
  --surface-alt: #f5f6fa;
  --border: #e6e8ee;
  --border-strong: #d4d8e0;
  --accent: #2253c0;
  --accent-hover: #163d97;
  --accent-soft: #eaf0fc;
  --tag-bg: #eef2fb;
  --tag-fg: #2c3a64;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 4px 14px rgba(15, 23, 42, 0.08);
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --max-w: 760px;
  --max-w-wide: 1080px;
  /* Type scale tokens — centralised so individual components don't
     hard-code rem values that drift apart. The 5-step scale matches the
     bread-and-butter cases: meta/eyebrow / body / card-title / hero / display. */
  --fs-xxl: 2.25rem;
  --fs-xl: 1.5rem;
  --fs-lg: 1.18rem;
  --fs-md: 1rem;
  --fs-sm: 0.88rem;
  --fs-xs: 0.78rem;
  /* Spacing scale tokens — match the previously-scattered 0.25 / 0.5 / 1 /
     1.5 / 2 / 2.5 rem values that were sprinkled across components. New
     code should reach for these instead of inventing fresh increments. */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 1rem;
  --sp-4: 1.5rem;
  --sp-5: 2rem;
  --sp-6: 2.5rem;
  /* T7 / P2-7: per-site micro-variation knobs. Theming.apply_variant
     overrides these per slug so sister sites with the same theme still
     read as visibly distinct.
       --font-weight-base: card / heading weight (300 / 400 / 500)
       --padding-scale:    multiplier on card / post / hero padding
                           (0.85 / 1.0 / 1.15) — wraps in calc()
       --radius-base:      base corner radius for the per-slug shell
                           (4px / 8px / 12px) — fed into .post-card,
                           .post, hero img, etc. Theme-set --radius-md
                           still wins on a per-theme basis; --radius-base
                           is the *fallback* when a theme doesn't override. */
  --font-weight-base: 400;
  --padding-scale: 1.0;
  --radius-base: 8px;
  /* Theme-overridable typography. style.css uses these for body/headings;
     individual themes override the values, the structural CSS doesn't
     need to know which font is loaded. */
  --font-display: -apple-system, BlinkMacSystemFont, "Segoe UI",
    "PingFang TC", "Microsoft JhengHei", Roboto, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI",
    "PingFang TC", "Microsoft JhengHei", Roboto, sans-serif;
}

/* Dark mode applies in two cases:
   1. ``data-color-scheme="dark"`` is set on <html> — explicit operator override
   2. system prefers dark AND no explicit override is in effect (auto mode)
   When the operator forces ``data-color-scheme="light"`` the system preference
   is ignored. Resolves the asymmetry where dark always won regardless of
   site-level intent. */
[data-color-scheme="dark"],
[data-color-scheme="dark"] :root {
  --fg: #e2e8f0;
  --fg-strong: #f8fafc;
  --muted: #94a3b8;
  --muted-soft: #64748b;
  --bg: #0f172a;
  --surface: #1e293b;
  --surface-alt: #16213a;
  --border: #283347;
  --border-strong: #3b475c;
  --accent: #7aa6f5;
  --accent-hover: #a5c1f9;
  --accent-soft: #1c2a47;
  --tag-bg: #1c2a47;
  --tag-fg: #b8c8ec;
}
[data-color-scheme="dark"] .card-thumb { background: #1e2a44; }
[data-color-scheme="dark"] .post-body pre { background: #0b1220; color: #d8e1f3; }

@media (prefers-color-scheme: dark) {
  :root:not([data-color-scheme="light"]):not([data-color-scheme="dark"]) {
    --fg: #e2e8f0;
    --fg-strong: #f8fafc;
    --muted: #94a3b8;
    --muted-soft: #64748b;
    --bg: #0f172a;
    --surface: #1e293b;
    --surface-alt: #16213a;
    --border: #283347;
    --border-strong: #3b475c;
    --accent: #7aa6f5;
    --accent-hover: #a5c1f9;
    --accent-soft: #1c2a47;
    --tag-bg: #1c2a47;
    --tag-fg: #b8c8ec;
  }
  :root:not([data-color-scheme="light"]):not([data-color-scheme="dark"]) .card-thumb { background: #1e2a44; }
  :root:not([data-color-scheme="light"]):not([data-color-scheme="dark"]) .post-body pre { background: #0b1220; color: #d8e1f3; }
}

/* Accessibility: keyboard users need to see where focus is. ``:focus-visible``
   only triggers for keyboard / programmatic focus, never for click — so mouse
   users don't see persistent focus rings on buttons after clicking, which was
   the historical objection to ``:focus``. */
*:focus { outline: none; }
*:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}
a:focus-visible {
  outline-color: var(--accent);
  outline-offset: 3px;
}

/* Respect users who request reduced motion — disable hover-translate and
   smooth scroll animations entirely. The 0.01ms duration keeps transitions
   technically running (so JS expecting transitionend still fires). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.75;
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--font-display); }

a {
  color: var(--accent);
  text-decoration: none;
  transition: color 0.15s ease;
}
a:hover { color: var(--accent-hover); text-decoration: underline; }

img { max-width: 100%; height: auto; }

h1, h2, h3, h4 {
  color: var(--fg-strong);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

/* -- header --------------------------------------------------------------- */

.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
  backdrop-filter: saturate(140%) blur(8px);
}
.site-header-inner {
  max-width: var(--max-w-wide);
  margin: 0 auto;
  padding: 1rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.site-title {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--fg-strong);
  letter-spacing: -0.01em;
}
.site-title:hover { color: var(--accent); text-decoration: none; }
.site-logo { display: inline-flex; align-items: center; }
.site-logo svg { width: 32px; height: 32px; display: block; }

.site-nav { display: flex; gap: 1.25rem; }
.site-nav a {
  color: var(--muted);
  font-size: 0.92rem;
  font-weight: 500;
}
.site-nav a:hover { color: var(--fg); text-decoration: none; }

/* -- layout shell --------------------------------------------------------- */

.site-layout {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 1.25rem;
}
.site-layout--with-sidebar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 2.5rem;
  max-width: calc(var(--max-w) + 280px + 2.5rem);
}
.site-layout .site-main { padding: 2rem 0; max-width: none; margin: 0; }
.site-sidebar { padding: 2rem 0; }
@media (max-width: 760px) {
  .site-layout--with-sidebar { grid-template-columns: 1fr; gap: 0; }
}

/* -- index hero (blog home top banner) ------------------------------------ */

.index-hero {
  padding: 1.5rem 0 2.25rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2rem;
}
.index-hero-title {
  font-size: 2rem;
  margin: 0 0 0.5rem;
}
.index-hero-tagline {
  color: var(--muted);
  font-size: 1.05rem;
  margin: 0;
  max-width: 56ch;
}

.page-title { font-size: 1.5rem; margin: 0 0 1.5rem; }

/* -- article list cards --------------------------------------------------- */

.post-list { list-style: none; padding: 0; margin: 0; }
.post-card {
  background: var(--surface);
  border: 1px solid var(--border);
  /* T7: --radius-base (slug-derived) feeds the visual identity; theme
     can still override --radius-md for a per-theme baseline. Wrapped
     in calc(0px + ...) so a typo or missing var degrades to a flat
     square instead of a Jinja-style raw token leaking into CSS. */
  border-radius: calc(var(--radius-base) + 0px);
  margin-bottom: 1rem;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  overflow: hidden;
}
.post-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
}
.card-link {
  display: flex;
  gap: 1.1rem;
  /* T7: padding scales with the slug-derived knob (0.85x..1.15x). Sites
     that hash to the dense bucket feel tighter; airy bucket gives more
     breathing room. */
  padding: calc(1.1rem * var(--padding-scale)) calc(1.2rem * var(--padding-scale));
  color: inherit;
  align-items: flex-start;
}
.card-link:hover { text-decoration: none; }
.card-link:hover .card-title { color: var(--accent); }
.card-thumb {
  flex-shrink: 0;
  width: 140px;
  height: 100px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
}
.card-body { min-width: 0; flex: 1; }
.card-title {
  font-size: 1.18rem;
  margin: 0 0 0.35rem;
  color: var(--fg-strong);
  /* T7: lighter / heavier card titles depending on slug hash. Theme's
     extra_css for tech-modern / sports-energetic still wins (those set
     font-weight directly with higher selector specificity); this is the
     base layer for themes that don't override. */
  font-weight: calc(var(--font-weight-base) + 200);
  transition: color 0.15s ease;
}
.excerpt {
  color: var(--muted);
  margin: 0.35rem 0;
  font-size: 0.95rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (max-width: 540px) {
  .card-link { flex-direction: column; }
  .card-thumb { width: 100%; height: 180px; }
}

/* -- tags ----------------------------------------------------------------- */

.keywords { margin-top: 0.65rem; display: flex; flex-wrap: wrap; gap: 0.3rem; }
.tag {
  display: inline-block;
  background: var(--tag-bg);
  color: var(--tag-fg);
  padding: 2px 9px;
  border-radius: 12px;
  font-size: 0.78rem;
  font-weight: 500;
  text-decoration: none;
}
a.tag:hover { background: var(--accent-soft); color: var(--accent); text-decoration: none; }

/* -- tag listing page (/tag/{slug}/) ------------------------------------- */
.tag-page-header {
  text-align: center;
  padding: 2.5rem 0 1.5rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2rem;
}
.tag-page-header .tag-eyebrow {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--accent);
  font-weight: 700;
  margin: 0 0 0.5rem;
}
.tag-page-title {
  font-size: clamp(2rem, 4vw, 2.8rem);
  margin: 0 0 0.5rem;
  letter-spacing: -0.02em;
}
.tag-page-meta {
  color: var(--muted);
  margin: 0;
  font-size: 0.95rem;
}

/* -- per-layout body class variants --------------------------------------
   Set by _base.html as ``<body class="page-{kind} layout-{name}">``. These
   variants tune density / typography to match the layout's design intent
   without forking post.html. Magazine = airy + image-forward. News-stream
   = compact + monospace. Guide = TOC-friendly. Showcase = product-card
   like. Longform = wide measure. */

.layout-magazine .post {
  padding: 3rem 3rem 2.5rem;
}
.layout-magazine .post-title { font-size: 2.4rem; line-height: 1.15; }
.layout-magazine .post-body { font-size: 1.08rem; line-height: 1.85; }
.layout-magazine .post-body h2 { font-size: 1.6rem; margin-top: 3rem; }

.layout-news-stream .post {
  padding: 1.75rem 1.75rem 1.5rem;
  border-radius: var(--radius-md);
}
.layout-news-stream .post-title {
  font-size: 1.65rem;
  letter-spacing: 0;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
}
.layout-news-stream .post-meta {
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  font-size: 0.82rem;
}
.layout-news-stream .post-body { font-size: 1rem; line-height: 1.7; }

.layout-guide .post-toc { position: sticky; top: 5rem; }
.layout-guide .post-body h2 {
  border-left: 4px solid var(--accent);
  padding-left: 0.85rem;
  margin-left: -1rem;
}
.layout-guide .post-body h2::before {
  /* Numbered chapter marker — the guide layout is meant to feel like a
     manual, not a news article. */
  content: counter(chap) ". ";
  counter-increment: chap;
  color: var(--accent);
  font-weight: 700;
}
.layout-guide .post-body { counter-reset: chap; }

.layout-showcase .post-title { font-size: 2rem; }
.layout-showcase .post::before {
  /* Product-style eyebrow above title */
  content: "FEATURED";
  display: inline-block;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  color: var(--accent);
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.layout-longform .post {
  max-width: 720px;
  margin: 0 auto;
}
.layout-longform .post-body p { margin: 1.1rem 0; }
.layout-longform .post-body { font-size: 1.1rem; }

/* -- post page ------------------------------------------------------------ */

.post {
  background: var(--surface);
  border: 1px solid var(--border);
  /* T7: --radius-base (slug-derived) plus a small additive bump so the
     post wrapper still reads as "more rounded" than the cards within
     it. Theme's --radius-lg is no longer the only knob — micro-variation
     contributes too. */
  border-radius: calc(var(--radius-base) + 4px);
  /* T7: slug-derived padding multiplier — same rationale as .card-link
     but with the larger 2.25rem base. */
  padding: calc(2.25rem * var(--padding-scale)) calc(2.25rem * var(--padding-scale)) calc(2rem * var(--padding-scale));
  box-shadow: var(--shadow-sm);
}
@media (max-width: 540px) {
  /* On phones the 2.25rem side padding eats into reading area —
     scale down so body text is closer to the edge without losing breathing
     room. Coordinated with .post-hero-placeholder's narrow-viewport margin. */
  .post { padding: 1.25rem 1.25rem 1.5rem; border-radius: var(--radius-md); }
}
.post-title {
  font-size: 2rem;
  margin: 0 0 0.6rem;
  letter-spacing: -0.02em;
}
.post-meta {
  color: var(--muted);
  font-size: 0.88rem;
  margin: 0 0 1.5rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
.post-badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 10px;
  font-size: 0.74rem;
  font-weight: 600;
  background: var(--accent-soft);
  color: var(--accent);
  letter-spacing: 0.01em;
}
.post-badge--digest { background: #fff5e0; color: #8a5a00; }
@media (prefers-color-scheme: dark) {
  .post-badge--digest { background: #3a2c14; color: #f5c577; }
}

.post-body { font-size: 1.05rem; line-height: 1.8; }
.post-body > p:first-of-type { font-size: 1.12rem; color: var(--fg); }

/* Drop cap on the first paragraph of long-enough posts. ``:has()`` makes
   the rule conditional on at least one H2 sibling existing, so short
   posts don't get an awkward giant first character. The CJK-friendly
   sizing uses 1em (one character height) rather than the typical 3em
   western drop cap so square glyphs don't dwarf the rest of the line. */
.post-body:has(h2) > p:first-of-type::first-letter {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 3em;
  line-height: 0.85;
  float: left;
  margin: 0.1em 0.18em 0 0;
  color: var(--accent);
}
@supports not selector(:has(*)) {
  /* Fallback for older browsers — apply to every post regardless. */
  .post-body > p:first-of-type::first-letter {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 3em;
    line-height: 0.85;
    float: left;
    margin: 0.1em 0.18em 0 0;
    color: var(--accent);
  }
}
.post-body h2 {
  font-size: 1.45rem;
  margin: 2.5rem 0 0.75rem;
  padding-top: 0.5rem;
  scroll-margin-top: 4rem;
}
.post-body h3 { font-size: 1.2rem; margin: 1.5rem 0 0.5rem; }
.post-body p { margin: 0.85rem 0; }
.post-body ul, .post-body ol { padding-left: 1.5rem; margin: 0.85rem 0; }
.post-body li { margin: 0.3rem 0; }
.post-body strong { color: var(--fg-strong); }
.post-body pre {
  background: #0f172a;
  color: #e2e8f0;
  padding: 1rem 1.25rem;
  border-radius: var(--radius-sm);
  overflow-x: auto;
  font-size: 0.92rem;
  line-height: 1.55;
}
.post-body code {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 0.9em;
  background: var(--surface-alt);
  padding: 1px 5px;
  border-radius: 3px;
}
.post-body pre code { background: transparent; padding: 0; }
.post-body blockquote {
  border-left: 4px solid var(--accent);
  margin: 1.5em 0;
  padding: 0.4em 1.2em;
  color: var(--muted);
  background: var(--accent-soft);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.post-body figure.post-image {
  margin: 1.75em -0.5rem;
  text-align: center;
}
.post-body figure.post-image img {
  width: 100%;
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  box-shadow: var(--shadow-sm);
}
.post-body figure.post-image figcaption {
  margin-top: 0.6em;
  font-size: 0.88rem;
  color: var(--muted);
  font-style: italic;
}

/* -- post footer (related + back link) ----------------------------------- */

.post-cta {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}
/* -- post hero placeholder (image-less posts) ---------------------------- */

.post-hero-placeholder {
  height: 200px;
  /* Pull the gradient flush with the post card's top corners by negating
     the .post container's padding (2.25rem). Below 540px the .post padding
     scales down to .post-mobile (see narrow-viewport block below) so this
     match needs to keep pace; the @media block below relaxes the negative
     margins to avoid horizontal overflow on small phones. */
  margin: -2.25rem -2.25rem 2rem;
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
@media (max-width: 540px) {
  .post-hero-placeholder { margin: -1.25rem -1.25rem 1.5rem; }
}
.post-hero-placeholder::before {
  content: "";
  position: absolute;
  top: -40%;
  right: -20%;
  width: 70%;
  height: 180%;
  background: radial-gradient(circle, rgba(255,255,255,0.18) 0%, transparent 60%);
}
.post-hero-monogram svg { width: 96px; height: 96px; box-shadow: 0 8px 32px rgba(0,0,0,0.25); border-radius: 16px; }

/* -- table of contents ---------------------------------------------------- */

.post-toc {
  background: var(--surface-alt);
  border-left: 3px solid var(--accent);
  padding: 1rem 1.25rem;
  margin: 0 0 1.5rem;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.post-toc-h {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin: 0 0 0.5rem;
  font-weight: 700;
}
.post-toc ol { padding-left: 1.4rem; margin: 0; }
.post-toc li { font-size: 0.92rem; padding: 0.18rem 0; }
.post-toc a { color: var(--fg); }
.post-toc a:hover { color: var(--accent); }

/* -- inline citation links (auto-linkified 「（來源 N）」) ----------------- */

.citation-ref {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.92em;
  border-bottom: 1px dashed currentColor;
  padding-bottom: 1px;
}
.citation-ref:hover { background: var(--accent-soft); text-decoration: none; }

/* -- post sources footer (digest) ---------------------------------------- */

.post-sources {
  margin-top: 2.5rem;
  padding: 1.5rem;
  background: var(--surface-alt);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
}
.post-sources-title { font-size: 1.05rem; margin: 0 0 0.4rem; color: var(--fg-strong); }
.post-sources-hint { font-size: 0.85rem; color: var(--muted); margin: 0 0 1rem; }
.post-sources-list { padding-left: 1.5rem; margin: 0; }
.post-sources-list li {
  padding: 0.5rem 0;
  border-top: 1px dashed var(--border);
  scroll-margin-top: 4rem;
}
.post-sources-list li:first-child { border-top: none; }
.post-sources-list li:target {
  /* When a citation link jumps here, briefly highlight to confirm the target. */
  background: var(--accent-soft);
  border-radius: 4px;
  padding-left: 0.5rem;
  margin-left: -0.5rem;
}
.post-sources-list a { color: var(--fg-strong); font-weight: 500; }
.post-sources-list a:hover { color: var(--accent); }
.post-sources-domain {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  margin-top: 2px;
}

.related {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.related-title {
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin: 0 0 1rem;
}
.related-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.6rem; }
.related-list a {
  display: block;
  padding: 0.65rem 0.9rem;
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  color: var(--fg);
  font-size: 0.95rem;
  border: 1px solid transparent;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.related-list a:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  text-decoration: none;
}

.back { margin-top: 1.5rem; color: var(--muted); font-size: 0.9rem; text-align: center; }

/* -- footer (with optional tag cloud) ------------------------------------ */

.site-footer {
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.9rem;
  margin-top: 4rem;
  padding: 2rem 1.25rem;
  text-align: center;
}
.site-footer .footer-tags {
  margin-bottom: 1.25rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  justify-content: center;
  max-width: var(--max-w);
  margin-left: auto;
  margin-right: auto;
}
.site-footer .footer-copy {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted-soft);
}

.empty {
  color: var(--muted);
  text-align: center;
  padding: 3rem 1rem;
  font-size: 0.95rem;
}

/* -- ad slots ------------------------------------------------------------- */

.ad-slot {
  margin: 1rem auto;
  max-width: var(--max-w);
  padding: 0 1.25rem;
}
.ad-slot--header {
  /* Header ad: kept slim so it doesn't dominate above-the-fold. The
     inline-styled <a> the operator pastes still controls the actual
     banner styling, but this wrapper enforces the maximum vertical
     footprint regardless of what HTML lands here. To disable per-site,
     leave ``site.ad_slots.header`` empty in the admin UI — the wrapping
     div collapses entirely (see _base.html `{% if ... %}` guard). */
  border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
  padding: 0;
  text-align: center;
  max-width: none;
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.3;
}
.ad-slot--header > * {
  /* Force any banner content to honour the slim height regardless of
     inline style. Operators can still customise colour / link / text;
     they just can't make the banner taller than 32px. */
  max-height: 32px;
  padding: 0.35rem 1rem !important;
  font-size: 0.85rem !important;
  font-weight: 500 !important;
}
.ad-slot--sidebar {
  padding: 1rem;
  background: var(--surface-alt);
  border-radius: var(--radius-md);
}
.ad-slot--between {
  padding: 1.25rem;
  background: var(--surface-alt);
  border-radius: var(--radius-md);
  list-style: none;
  text-align: center;
  margin: 1rem 0;
}
.ad-slot--in-content {
  /* Slight negative margin pulls the slot 8px outside the column edge so
     the surface-alt fill visually breaks the article rhythm. On narrow
     viewports the negative margin used to overflow the post container
     and trigger a horizontal scrollbar — clamp it to 0 below 540px. */
  margin: 2rem -0.5rem;
  padding: 1.25rem;
  background: var(--surface-alt);
  border-radius: var(--radius-md);
  text-align: center;
}
@media (max-width: 540px) {
  .ad-slot--in-content { margin: 2rem 0; }
}
.ad-slot--footer { margin: 0 auto 1.5rem; }
.ad-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  color: var(--muted-soft);
  letter-spacing: 0.08em;
  margin-bottom: 0.4rem;
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--surface);
}

/* -- landing page (landing_plus_blog) ------------------------------------ */

.hero {
  text-align: center;
  padding: 4rem 1.25rem 3rem;
  background: linear-gradient(180deg, var(--surface) 0%, var(--bg) 100%);
  border-bottom: 1px solid var(--border);
}
.hero-title {
  font-size: clamp(2rem, 5vw, 3rem);
  margin: 0 0 0.75rem;
  letter-spacing: -0.02em;
}
.hero-tagline {
  color: var(--muted);
  font-size: clamp(1rem, 2.4vw, 1.2rem);
  margin: 0 auto 1.75rem;
  max-width: 56ch;
}

/* CTA buttons. Specificity instead of ``!important`` so themes can override
   the colour token without resorting to !important escalation wars. The
   ``a.cta-button`` selector beats the ``a { color: var(--accent) }`` rule
   above by being more specific (tag + class > tag alone). */
a.cta-button,
.cta-button {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  padding: 0.75rem 1.75rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  margin: 0.25rem;
  transition: background 0.15s ease, transform 0.15s ease;
}
a.cta-button:hover,
.cta-button:hover {
  background: var(--accent-hover);
  color: #fff;
  text-decoration: none;
  transform: translateY(-1px);
}
a.cta-button--secondary,
.cta-button--secondary {
  background: var(--surface);
  color: var(--accent);
  border: 1px solid var(--accent);
}
a.cta-button--secondary:hover,
.cta-button--secondary:hover {
  background: var(--accent-soft);
  color: var(--accent);
}

.about, .latest, .cta-section {
  padding: 2.5rem 1.25rem;
  border-bottom: 1px solid var(--border);
  max-width: var(--max-w);
  margin: 0 auto;
}

/* -- layout: magazine ----------------------------------------------------- */

.mag-hero-row { margin-bottom: 2rem; }
.mag-hero {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding: 0;
  align-items: stretch;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.mag-hero:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); text-decoration: none; }
.mag-hero-img { width: 100%; height: 100%; min-height: 280px; object-fit: cover; }
.mag-hero-body { padding: 2rem 2rem 1.75rem; display: flex; flex-direction: column; justify-content: center; }
.mag-eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 0.5rem;
}
.mag-hero-title { font-size: 1.75rem; margin: 0 0 0.5rem; line-height: 1.2; color: var(--fg-strong); }
@media (max-width: 720px) {
  .mag-hero { grid-template-columns: 1fr; }
  .mag-hero-img { min-height: 180px; }
}

.mag-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.25rem;
}
.mag-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.mag-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.mag-card-link { padding: 0; flex-direction: column; align-items: stretch; gap: 0; }
.mag-thumb { width: 100%; height: 160px; object-fit: cover; }
.mag-card-body { padding: 1rem 1.1rem 1.1rem; }
.mag-card-title { font-size: 1rem; margin: 0 0 0.4rem; color: var(--fg-strong); }

/* -- layout: longform ----------------------------------------------------- */

.lf-hero {
  padding: 4rem 0 3rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2.5rem;
}
.lf-hero-title {
  font-size: clamp(2.5rem, 6vw, 3.5rem);
  margin: 0 0 0.75rem;
  letter-spacing: -0.025em;
  line-height: 1.05;
}
.lf-hero-tagline { color: var(--muted); font-size: 1.15rem; margin: 0; max-width: 60ch; line-height: 1.55; }

.lf-list { list-style: none; padding: 0; margin: 0; }
.lf-essay {
  border-bottom: 1px solid var(--border);
  padding: 2rem 0;
}
.lf-essay-link {
  display: grid;
  grid-template-columns: 1fr 200px;
  gap: 2rem;
  padding: 0;
  align-items: start;
  color: inherit;
}
.lf-essay-link:hover { text-decoration: none; }
.lf-essay-link:hover .lf-essay-title { color: var(--accent); }
.lf-essay-body { min-width: 0; }
.lf-eyebrow {
  font-size: 0.78rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 0.5rem;
}
.lf-essay-title { font-size: 1.65rem; margin: 0 0 0.6rem; line-height: 1.25; transition: color 0.15s ease; }
.lf-essay-excerpt { color: var(--muted); margin: 0; font-size: 1rem; line-height: 1.6; }
.lf-essay-thumb { width: 200px; height: 150px; object-fit: cover; border-radius: var(--radius-sm); }
@media (max-width: 720px) {
  .lf-essay-link { grid-template-columns: 1fr; }
  .lf-essay-thumb { width: 100%; height: 220px; order: -1; }
}

/* -- layout: news-stream ------------------------------------------------- */

.ns-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 2rem;
}
.ns-h { font-size: 1.6rem; margin: 0 0 0.4rem; }
.ns-tagline { color: var(--muted); margin: 0 0 1.5rem; font-size: 0.95rem; }
.ns-list { list-style: none; padding: 0; margin: 0; }
.ns-item { border-bottom: 1px dashed var(--border); }
.ns-link {
  display: grid;
  grid-template-columns: 50px 1fr;
  gap: 1rem;
  padding: 0.85rem 0;
  color: inherit;
  align-items: start;
}
.ns-link:hover { text-decoration: none; }
.ns-link:hover .ns-title { color: var(--accent); }
.ns-time {
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  padding-top: 4px;
}
.ns-title { font-size: 1.05rem; margin: 0 0 0.25rem; line-height: 1.35; transition: color 0.15s ease; }
.ns-excerpt { color: var(--muted); margin: 0; font-size: 0.85rem; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

.ns-ticker {
  background: var(--surface-alt);
  border-radius: var(--radius-md);
  padding: 1.25rem 1.1rem;
  height: fit-content;
  position: sticky;
  top: 5rem;
}
.ns-ticker-h { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--accent); margin: 0 0 0.85rem; }
.ns-ticker-list { padding-left: 0; margin: 0; list-style: none; counter-reset: tk; }
.ns-ticker-list li {
  counter-increment: tk;
  padding: 0.4rem 0;
  font-size: 0.85rem;
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 0.5rem;
  border-top: 1px solid var(--border);
}
.ns-ticker-list li:first-child { border-top: none; }
.ns-ticker-list a { color: var(--fg); }
.ns-ticker-date { color: var(--muted); font-family: ui-monospace, monospace; font-size: 0.75rem; }
@media (max-width: 760px) {
  .ns-grid { grid-template-columns: 1fr; }
  .ns-ticker { position: static; }
}

/* -- layout: showcase ----------------------------------------------------- */

.sc-hero {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  color: white;
  padding: 5rem 1.25rem 4rem;
  text-align: center;
  margin: -2rem -1.25rem 2.5rem;
  border-radius: 0;
}
.sc-hero-title { font-size: clamp(2.25rem, 5vw, 3.25rem); color: white; margin: 0 0 0.75rem; letter-spacing: -0.02em; }
.sc-hero-tagline { color: rgba(255,255,255,0.9); font-size: clamp(1rem, 2vw, 1.2rem); margin: 0 auto 2rem; max-width: 56ch; }
.sc-hero .cta-button { background: white; color: var(--accent) !important; }
.sc-hero .cta-button:hover { background: var(--accent-soft); }

.sc-filters { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1.5rem; }

.sc-wall {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem;
}
.sc-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.sc-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.sc-card-link { flex-direction: column; padding: 0; gap: 0; align-items: stretch; }
.sc-card-img { width: 100%; height: 180px; object-fit: cover; }
.sc-card-img--placeholder { background: linear-gradient(135deg, var(--accent-soft), var(--surface-alt)); }
.sc-card-body { padding: 1.1rem 1.25rem 1.25rem; }
.sc-card-title { font-size: 1.1rem; margin: 0 0 0.5rem; color: var(--fg-strong); }

/* -- layout: fixture ------------------------------------------------------ */

.fx-hero {
  background: var(--accent); color: white;
  padding: 2rem 2.25rem; margin: 0 0 2rem;
  border-radius: var(--radius-lg);
}
.fx-hero-label {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.1em;
  opacity: 0.85; margin-bottom: 0.75rem;
}
.fx-hero-link { color: white; display: block; padding: 0; }
.fx-hero-link:hover { text-decoration: none; }
.fx-hero-link:hover .fx-hero-title { opacity: 0.9; }
.fx-hero-title {
  font-size: clamp(1.6rem, 3vw, 2.2rem); margin: 0 0 0.5rem;
  letter-spacing: -0.01em; transition: opacity 0.15s;
}
.fx-hero-time {
  display: inline-block; font-family: ui-monospace, monospace;
  font-size: 0.95rem; padding: 0.2rem 0.6rem;
  background: rgba(255,255,255,0.18); border-radius: var(--radius-sm);
  margin-bottom: 0.5rem;
}
.fx-hero-excerpt { margin: 0.5rem 0 0; opacity: 0.95; max-width: 60ch; }

.fx-list-heading { font-size: 1.35rem; margin: 0 0 1.25rem; }
.fx-list { list-style: none; padding: 0; margin: 0; }
.fx-item { border-bottom: 1px solid var(--border); }
.fx-item:last-child { border-bottom: none; }
.fx-link {
  display: grid; grid-template-columns: 72px 1fr; gap: 1.25rem;
  padding: 1rem 0.5rem; color: inherit; align-items: center;
}
.fx-link:hover { text-decoration: none; background: var(--surface-alt); }
.fx-link:hover .fx-title { color: var(--accent); }
.fx-date {
  text-align: center; padding: 0.5rem 0;
  background: var(--surface-alt); border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.fx-date-d {
  font-size: 1.6rem; font-weight: 700; color: var(--fg-strong);
  font-family: var(--font-display); line-height: 1;
}
.fx-date-m {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--muted); margin-top: 0.25rem;
}
.fx-title { font-size: 1.05rem; margin: 0 0 0.25rem; transition: color 0.15s; }
.fx-excerpt { color: var(--muted); margin: 0; font-size: 0.88rem; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* -- layout: ranking ------------------------------------------------------ */

.rk-header { text-align: center; margin-bottom: 2rem; }
.rk-h { font-size: clamp(1.8rem, 3.5vw, 2.5rem); margin: 0 0 0.5rem; }
.rk-tagline { color: var(--muted); margin: 0; max-width: 60ch; margin-left: auto; margin-right: auto; }

.rk-list { list-style: none; padding: 0; margin: 0; counter-reset: rk; }
.rk-item { margin-bottom: 1.25rem; }
.rk-link {
  display: grid; grid-template-columns: 90px 140px 1fr; gap: 1.5rem;
  align-items: center; padding: 1.25rem 1.5rem; color: inherit;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: transform 0.15s, box-shadow 0.15s;
}
.rk-link:hover { transform: translateX(4px); box-shadow: var(--shadow-md); text-decoration: none; }
.rk-rank {
  display: flex; align-items: baseline; justify-content: center;
  font-family: var(--font-display); color: var(--accent);
  line-height: 1;
}
.rk-rank-hash { font-size: 1.25rem; opacity: 0.5; margin-right: 0.15rem; }
.rk-rank-num { font-size: 3rem; font-weight: 800; }
.rk-img { width: 140px; height: 90px; object-fit: cover; border-radius: var(--radius-sm); }
.rk-img--placeholder { background: linear-gradient(135deg, var(--accent-soft), var(--surface-alt)); }
.rk-body { min-width: 0; }
.rk-title { font-size: 1.2rem; margin: 0 0 0.35rem; color: var(--fg-strong); }
.rk-excerpt { color: var(--muted); margin: 0; font-size: 0.9rem; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

.rk-item--podium .rk-link { border-width: 2px; }
.rk-item--podium-1 .rk-link { border-color: #f1c40f; background: linear-gradient(to right, rgba(241,196,15,0.08), var(--surface)); }
.rk-item--podium-2 .rk-link { border-color: #bdc3c7; background: linear-gradient(to right, rgba(189,195,199,0.12), var(--surface)); }
.rk-item--podium-3 .rk-link { border-color: #cd7f32; background: linear-gradient(to right, rgba(205,127,50,0.08), var(--surface)); }
.rk-item--podium .rk-rank-num { font-size: 3.5rem; }

@media (max-width: 640px) {
  .rk-link { grid-template-columns: 64px 1fr; padding: 1rem; gap: 0.9rem; }
  .rk-img { display: none; }
  .rk-rank-num { font-size: 2.25rem; }
  .rk-item--podium .rk-rank-num { font-size: 2.5rem; }
}

/* -- layout: guide -------------------------------------------------------- */

.gd-header { text-align: center; max-width: 48rem; margin: 0 auto 2.5rem; }
.gd-h { font-size: clamp(2rem, 4vw, 2.75rem); margin: 0 0 0.75rem; letter-spacing: -0.015em; }
.gd-tagline { color: var(--muted); font-size: 1.05rem; margin: 0; }

.gd-toc {
  background: var(--surface-alt); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 1.5rem 1.75rem;
  margin-bottom: 3rem;
}
.gd-toc-h {
  font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); margin: 0 0 0.75rem;
}
.gd-toc-list { list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.45rem 1.5rem;
}
.gd-toc-list a { color: var(--fg); font-size: 0.95rem; }
.gd-toc-list a:hover { color: var(--accent); }

.gd-chapters { list-style: none; padding: 0; margin: 0; }
.gd-chapter {
  padding: 2rem 0; border-top: 1px solid var(--border);
}
.gd-chapter:first-child { border-top: none; padding-top: 0; }
.gd-chapter-num {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.15em;
  color: var(--accent); font-weight: 700; margin-bottom: 0.6rem;
  font-family: var(--font-display);
}
.gd-chapter-link { display: block; padding: 0; color: inherit; }
.gd-chapter-link:hover { text-decoration: none; }
.gd-chapter-link:hover .gd-chapter-title { color: var(--accent); }
.gd-chapter-link:hover .gd-chapter-cta { transform: translateX(3px); }
.gd-chapter-title { font-size: 1.5rem; margin: 0 0 0.75rem; transition: color 0.15s; }
.gd-chapter-excerpt { color: var(--muted); font-size: 1rem; margin: 0 0 0.75rem; max-width: 60ch; line-height: 1.6; }
.gd-chapter-cta {
  display: inline-block; color: var(--accent); font-weight: 500;
  transition: transform 0.15s;
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 1.25rem;
}
.section-head h2 { margin: 0; font-size: 1.4rem; }
.more-link { font-size: 0.9rem; }
.cta-section { text-align: center; border-bottom: none; padding-bottom: 4rem; }
.cta-section h2 { margin-top: 0; font-size: 1.5rem; }
.cta-section p { color: var(--muted); margin: 0 0 1.5rem; }

/* -- entity layouts ------------------------------------------------------- */

.entity-table-wrap { overflow-x: auto; margin-bottom: 2rem; }
.entity-table {
  width: 100%; border-collapse: collapse;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); overflow: hidden;
}
.entity-table th, .entity-table td { padding: 0.7rem 0.9rem; text-align: left; font-size: 0.92rem; }
.entity-table thead { background: var(--surface-alt); }
.entity-table th { color: var(--fg-strong); font-weight: 600; border-bottom: 1px solid var(--border); }
.entity-table tbody tr { border-top: 1px solid var(--border); transition: background 0.1s; }
.entity-table tbody tr:hover { background: var(--accent-soft); }
.entity-row-link { color: var(--accent); font-weight: 500; white-space: nowrap; }

.entity-grid {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1.25rem;
}
.entity-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); overflow: hidden;
  transition: transform 0.15s, box-shadow 0.15s;
}
.entity-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.entity-card-link { padding: 0; flex-direction: column; gap: 0; align-items: stretch; }
.entity-card-img { width: 100%; height: 140px; object-fit: cover; background: var(--surface-alt); }
.entity-card-body { padding: 0.9rem 1rem 1rem; }
.entity-card-title { font-size: 1.05rem; margin: 0 0 0.3rem; color: var(--fg-strong); }
.entity-card-sub { color: var(--muted); margin: 0; font-size: 0.85rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

.entity-ranking { list-style: none; padding: 0; margin: 0; }
.entity-rank-row { margin-bottom: 1rem; }
.entity-rank-link {
  display: grid; grid-template-columns: 60px 100px 1fr auto; gap: 1rem;
  padding: 1rem 1.25rem; align-items: center; color: inherit;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); transition: transform 0.15s, box-shadow 0.15s;
}
.entity-rank-link:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); text-decoration: none; }
.entity-rank-num {
  font-size: 2.5rem; font-weight: 800; color: var(--accent);
  line-height: 1; text-align: center; font-family: var(--font-display);
}
.entity-rank-img { width: 100px; height: 70px; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-alt); }
.entity-rank-body { min-width: 0; }
.entity-rank-title { font-size: 1.15rem; margin: 0 0 0.25rem; color: var(--fg-strong); }
.entity-rank-sub { color: var(--muted); margin: 0; font-size: 0.88rem; }
.entity-rank-cta { color: var(--accent); font-weight: 500; white-space: nowrap; }
@media (max-width: 600px) {
  .entity-rank-link { grid-template-columns: 50px 1fr; }
  .entity-rank-img { display: none; }
  .entity-rank-cta { display: none; }
}

.entity-detail {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 2.25rem; box-shadow: var(--shadow-sm);
}
.entity-detail-eyebrow {
  font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--accent); margin: 0 0 0.5rem; font-weight: 700;
}
.entity-detail-title { font-size: 2rem; margin: 0 0 1rem; }
.entity-detail-hero {
  width: 100%; max-height: 360px; object-fit: cover;
  border-radius: var(--radius-md); margin-bottom: 1.5rem;
}
.entity-detail-fields {
  display: grid; grid-template-columns: max-content 1fr; gap: 0.75rem 1.5rem;
  margin: 1.5rem 0;
}
.entity-detail-fields dt {
  color: var(--muted); font-size: 0.88rem; font-weight: 500;
  white-space: nowrap;
}
.entity-detail-fields dd { margin: 0; color: var(--fg); }
.entity-detail-source { font-size: 0.85rem; color: var(--muted); margin-top: 1.5rem; }
@media (max-width: 540px) {
  .entity-detail-fields { grid-template-columns: 1fr; gap: 0.25rem 0; }
  .entity-detail-fields dt { margin-top: 0.75rem; }
}

/* ==========================================================================
   Layout-specific theming.

   Each ``layout`` value on ``sites`` paints a different first-impression for
   the user — without these rules every site renders with a white sticky
   header and identical footer, which makes a 13-site network feel like one
   site repainted. The accent colour comes from ``palette_overrides``; we
   just decide *where* it goes per layout.
   ========================================================================== */

/* news-stream — sports / breaking news. Stadium-board feel: dark navy
   surface, accent (gold for worldcup) for text + border. Uses
   ``--accent-soft`` for background which the worldcup palette overrides
   to a deep navy; default theme keeps it light blue and still reads as
   a "broadcast" bar. */
.layout-news-stream .site-header {
  background: var(--accent-soft);
  color: var(--accent);
  border-bottom: 4px solid var(--accent);
  backdrop-filter: none;
}
.layout-news-stream .site-header a,
.layout-news-stream .site-header .site-title {
  color: var(--accent);
  font-weight: 700;
}
.layout-news-stream .site-header a:hover { color: var(--accent-hover); }
.layout-news-stream .site-footer {
  background: var(--accent-soft);
  color: var(--accent);
  border-top: 2px solid var(--accent);
}
.layout-news-stream .site-footer a { color: var(--accent); }

/* magazine — travel / lifestyle. Editorial feel: thick accent underscore on
   a warm-tinted bar, generous typographic spacing. */
.layout-magazine .site-header {
  background: var(--surface-alt);
  border-bottom: 4px solid var(--accent);
  backdrop-filter: none;
}
.layout-magazine .site-header-inner { padding-block: 1.5rem; }
.layout-magazine .site-title {
  letter-spacing: -0.02em;
  font-weight: 700;
}
.layout-magazine .site-footer {
  background: var(--surface-alt);
  border-top: 1px solid var(--accent-soft);
}

/* showcase — AI tools / product galleries. Glassy gradient header with
   accent bleed; minimalist, tech-forward aesthetic. */
.layout-showcase .site-header {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--accent-soft) 60%, var(--surface)),
    var(--surface)
  );
  border-bottom: 1px solid var(--accent-soft);
}
.layout-showcase .site-title {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 700;
}
.layout-showcase .site-footer {
  background: var(--surface-alt);
}

/* longform — finance / serious analysis. Quiet, classical: black/grey
   monolithic header, no accent here — accent reserved for emphasis inside
   the article. */
.layout-longform .site-header {
  background: var(--fg-strong);
  color: var(--surface);
  border-bottom: 1px solid var(--fg-strong);
  backdrop-filter: none;
}
.layout-longform .site-header a,
.layout-longform .site-header .site-title {
  color: var(--surface);
  font-family: var(--font-display);
  letter-spacing: 0.01em;
}
.layout-longform .site-header a:hover { color: var(--accent-soft); }
.layout-longform .site-footer {
  background: var(--fg-strong);
  color: var(--muted-soft);
  border-top: 0;
}
.layout-longform .site-footer a { color: var(--surface); }

/* guide — fitness / how-to. Friendly accent-tinted soft bar; rounded,
   approachable, action-oriented. */
.layout-guide .site-header {
  background: var(--accent-soft);
  border-bottom: 1px solid var(--accent);
}
.layout-guide .site-header .site-title {
  color: var(--accent-hover);
  font-weight: 700;
}
.layout-guide .site-footer {
  background: var(--accent-soft);
  color: var(--accent-hover);
  border-top: 1px dashed var(--accent);
}

/* fixture — sports schedule / prediction. Stadium-board look: dark base
   with a high-contrast accent rule. Differentiates the prediction site
   from its sister news-stream sibling. */
.layout-fixture .site-header {
  background: var(--fg-strong);
  color: var(--surface);
  border-bottom: 4px solid var(--accent);
  backdrop-filter: none;
}
.layout-fixture .site-header a,
.layout-fixture .site-header .site-title {
  color: var(--surface);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}
.layout-fixture .site-header a:hover { color: var(--accent); }
.layout-fixture .site-footer {
  background: var(--fg-strong);
  color: var(--muted-soft);
  border-top: 2px solid var(--accent);
}
.layout-fixture .site-footer a { color: var(--accent); }

/* -- site hero visual (B1) ---------------------------------------------- */
/*
 * Three-tier home hero (resolved server-side in site_generator/hero.py):
 *   site.assets.hero_image  →  first post.hero_image  →  SVG gradient
 * Templates wrap the macro call in their own ``X-hero-visual`` div so each
 * layout can decide aspect / placement, but the inner img/svg styling is
 * shared here. ``object-fit: cover`` so non-16:9 images crop instead of
 * letterbox; the SVG fills the container thanks to its
 * ``preserveAspectRatio="xMidYMid slice"``.
 */
.site-hero-img,
.site-hero-svg {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.site-hero-svg { min-height: 220px; }

/* Default blog (.index-hero): visual stacks above text, modest height. */
.index-hero--with-visual { padding: 0 0 2rem; border-bottom: 1px solid var(--border); margin-bottom: 2rem; }
.index-hero-visual {
  width: 100%;
  aspect-ratio: 16 / 5;
  overflow: hidden;
  border-radius: var(--radius-lg, 8px);
  margin-bottom: 1.5rem;
  background: var(--surface-alt, #f1f5f9);
}
.index-hero-text { padding: 0; }
.index-hero--with-visual .index-hero-title { font-size: clamp(1.75rem, 4vw, 2.5rem); }

/* Landing (.hero): centred text overlays full-bleed visual. */
.hero--with-visual { position: relative; padding: 0; background: none; }
.hero-visual {
  position: absolute; inset: 0;
  overflow: hidden;
  z-index: 0;
}
.hero-visual::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.45) 100%);
}
.hero--with-visual .hero-text {
  position: relative; z-index: 1;
  padding: 5rem 1.5rem 4rem;
  color: white;
  text-align: center;
  min-height: 360px;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
}
.hero--with-visual .hero-title { color: white; text-shadow: 0 2px 12px rgba(0,0,0,0.35); }
.hero--with-visual .hero-tagline { color: rgba(255,255,255,0.92); }

/* Longform (.lf-hero): visual on the right, text on the left, magazine-style. */
.lf-hero--with-visual {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  align-items: center;
}
@media (min-width: 768px) {
  .lf-hero--with-visual { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
}
.lf-hero-visual {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-lg, 8px);
  background: var(--surface-alt, #f1f5f9);
  order: 2;
}
.lf-hero-text { order: 1; }

/* Showcase (.sc-hero): visual fills the band, accent overlay keeps the
 * theme colour readable on top of any image. */
.sc-hero--with-visual { position: relative; padding: 0; background: none; overflow: hidden; }
.sc-hero-visual { position: absolute; inset: 0; }
.sc-hero-visual::after {
  content: ""; position: absolute; inset: 0;
  /* Solid-rgba fallback first: browsers without color-mix() (Safari < 16.2,
   * Chrome < 111, Firefox < 113) drop unknown values from a `background:`
   * shorthand, which without a fallback would leave the overlay fully
   * transparent and the hero text unreadable on top of a real photo.
   * The fallback uses near-black with 0.45 alpha — slightly darker than the
   * accent overlay but always readable. Modern browsers use the second rule. */
  background: linear-gradient(135deg, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.55));
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 75%, transparent), color-mix(in srgb, var(--accent-hover) 75%, transparent));
}
.sc-hero--with-visual .sc-hero-text {
  position: relative; z-index: 1;
  padding: 5rem 1.25rem 4rem;
  text-align: center;
  min-height: 320px;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
}

/* Showcase B3 redesign: section heads + compact "more" list. The featured
 * row uses a wider min-card (380px) to differentiate from the latest row;
 * the compact list at the bottom is a flat link list (no card chrome) so
 * the hierarchy reads featured > latest > more at a glance. */
.sc-section { margin-top: 3rem; }
.sc-section-h {
  font-size: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin: 0 0 1.25rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}
.sc-wall--featured { grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); }
.sc-list-compact { list-style: none; padding: 0; margin: 0; }
.sc-list-compact-item { border-bottom: 1px solid var(--border); }
.sc-list-compact-link {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  padding: 0.85rem 0;
  text-decoration: none; color: var(--fg);
}
.sc-list-compact-link:hover { color: var(--accent); }
.sc-list-compact-title { flex: 1; }
.sc-list-compact-date { color: var(--muted); font-size: 0.85rem; white-space: nowrap; }

