/* ═══════════════════════════════════════════════════════════════════════════
   BEACON — structure RIBBON
   Phase 23c.15 skeleton: THE CHROME ONLY.

   Every section of the page is a HORIZONTAL RAIL of fixed-width cards scrolled
   sideways, with a full-width lead above the rails and single-item modules
   breaking out full width between them. Beacon is the only one of the seven
   whose modules scroll horizontally, and the only one designed around a THIN
   ARCHIVE: a rail with few cards stops short instead of leaving holes.

   Site mark .......... A LOZENGE: the initials reversed out in paper #FBF7F0
                        inside a FULLY ROUNDED forest #3B6D11 capsule. A pill,
                        not a rounded rectangle — the only rounded mark in the
                        seven, and the rounding is the differentiation
                        (§7.1/§7.1.1/§4.4.6, decided by Khalaf before the build).
   Outfit headlines + Literata body.
   Paper #FBF7F0 / ink #1C1A17 / forest #3B6D11. Class prefix: bc-.

   HOW THIS FILE IS WRITTEN — the lessons the six built themes paid for:
   - Shared-partial class names are read from the partials themselves, not
     assumed to be BEM (§3.2): .news-ticker__list, .newsletter-form,
     .search-overlay__input, .nav-drawer__link.
   - State classes are COMPOUND selectors (§5.1): .search-overlay.is-hidden and
     .nav-drawer.is-hidden. A bare .is-hidden ties on specificity with the
     element's own display declaration and loses on source order — that is what
     left ledger's overlay painted open on load.
   - MOBILE-FIRST media queries (clarion's lesson): the narrow layout is the
     base and breakpoints add to it, so nothing is undone and no !important is
     needed.
   - THE MARK'S CUSTOM PROPERTIES ARE DECLARED BESIDE EACH MARK SIZE, NOT ON
     :root. Register declared --rg-cap on :root, it resolved there once against
     the root's mark size, and the footer silently inherited header-sized values
     while both the CSS and the spec claimed one calc chain.
   - THE CAPSULE IS A FIXED BOX, NOT A GLYPH-DRIVEN ONE. Dispatch sized its mark
     halves with min-width and French "IM" measured 52.3px against English "AC"
     at 43.9px — visibly unequal, with the spec claiming they matched.
   - ONE rule set: no rule written then overridden later, no patch blocks, and
     no forced-priority declarations.
   - `picture { display: contents }` is REQUIRED by
     themes/_shared/partials/responsive_image.html.jinja so the wrapper does not
     disturb the <img> layout.
   - No dark mode. Beacon is a light theme; §4.4 #34 specifies a light footer.

   Colours are custom properties on :root so the §15 per-site override mechanism
   can reach them without editing this file.

   This file covers the CHROME ONLY. The card rails, the module overrides, the
   article variants and the category grid are later prompts.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────────
   1. Design tokens
   ─────────────────────────────────────────────────────────────────────────── */

:root {
    /* Ink */
    --ink: #1C1A17;
    --ink-soft: #43403A;
    --ink-mute: #756F65;

    /* Paper */
    --paper: #FBF7F0;
    --paper-soft: #FFFDF8;
    --paper-deep: #F1EBE0;

    /* Accent — forest */
    --accent: #3B6D11;
    --accent-soft: #5E9430;
    --accent-deep: #284C08;
    --accent-tint: rgba(59, 109, 17, 0.08);

    /* Rules */
    --rule: #DED6C7;
    --rule-soft: #EBE5D9;

    /* Type */
    --font-headline: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
    --font-body: 'Literata', Georgia, 'Times New Roman', serif;
    --font-ui: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
    --font-mono: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

    /* Scale (§4.4.4) */
    --size-display: clamp(38px, 5.5vw, 72px);
    --size-h1: clamp(36px, 5vw, 60px);
    --size-h2: 22px;
    --size-h3: 18px;
    --size-body: 18px;
    --size-meta: 13px;
    --lh-tight: 1.02;
    --lh-head: 1.25;
    --lh-body: 1.65;

    /* Layout (§4.4.1) */
    --max-width: 1360px;
    --measure: 66ch;
    --gutter: 20px;

    /* Rail geometry (§4.4.1) — declared here because the rails of Stage 2 and
       the nav's pill rail share it: a card is 280px, a double card 560px. */
    --card: 280px;
    --card-double: 560px;

    /* Vertical rhythm */
    --space-xs: 5px;
    --space-sm: 9px;
    --space-md: 17px;
    --space-lg: 30px;
    --space-xl: 48px;

    /* THE LOZENGE'S TWO CONSTANTS.

       --bc-cap is deliberately NOT declared here. Register put its equivalent on
       :root, where it resolved once against the root's mark size, and the footer
       inherited header-sized values. Each mark rule below declares
       --bc-mark-size and --bc-cap TOGETHER so every scope derives its own.

       0.710 is Outfit's OWN cap-height in em, measured by rendering the vendored
       Outfit[wght].ttf at weight 800 — 0.710 at 100px and 0.710 at 200px. Not
       chosen by eye. */
    --bc-cap-ratio: 0.710;

    /* FULLY ROUNDED, and 999px rather than a chosen corner value: it clamps to
       half the height at any size, so the capsule stays a true PILL however the
       mark scales. A fixed 6px or 8px would make it a rounded rectangle, which
       is the one thing §4.4.6 forbids — the rounding is beacon's
       differentiation from six square-cornered or containerless marks. */
    --bc-mark-radius: 999px;
}

/* ───────────────────────────────────────────────────────────────────────────
   2. Reset and base
   ─────────────────────────────────────────────────────────────────────────── */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body.bc-body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: var(--size-body);
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
}

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

/* Required by _shared/partials/responsive_image.html.jinja: the <picture>
   wrapper must not become a layout box of its own. */
picture {
    display: contents;
}

a {
    color: inherit;
}

h1, h2, h3, h4 {
    margin: 0;
    font-family: var(--font-headline);
    font-weight: 700;
    line-height: var(--lh-head);
}

ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Shared partials emit .visually-hidden for screen-reader-only text. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.bc-container {
    width: 100%;
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

/* ───────────────────────────────────────────────────────────────────────────
   3. Skip link (7A #1)
   ─────────────────────────────────────────────────────────────────────────── */

.bc-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: var(--space-sm) var(--space-md);
    background: var(--accent);
    color: var(--paper);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    font-weight: 600;
    text-decoration: none;
}

.bc-skip-link:focus {
    left: 0;
}

/* ───────────────────────────────────────────────────────────────────────────
   4. Top bar (7A #2–#6, #11, #12) — §4.4.2 #1
   ─────────────────────────────────────────────────────────────────────────── */

.bc-topbar {
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
}

.bc-topbar__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    min-height: 36px;
}

.bc-topbar__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.bc-topbar__dot {
    color: var(--accent);
}

.bc-topbar__edition,
.bc-topbar__kicker {
    font-weight: 600;
    letter-spacing: 0.02em;
}

.bc-topbar__kicker {
    color: var(--accent);
}

.bc-topbar__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-md);
}

.bc-topbar__links {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.bc-topbar__link {
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    text-decoration: none;
}

.bc-topbar__link:hover,
.bc-topbar__link:focus {
    color: var(--accent);
}

.bc-topbar__social {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.bc-topbar__social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: var(--bc-mark-radius);
    color: var(--ink-soft);
    text-decoration: none;
}

.bc-topbar__social-link:hover,
.bc-topbar__social-link:focus {
    background: var(--accent-tint);
    color: var(--accent);
}

/* ───────────────────────────────────────────────────────────────────────────
   5. Masthead (7A #7–#10) — §4.4.2 #2: centred Outfit wordmark
   ─────────────────────────────────────────────────────────────────────────── */

.bc-mast {
    background: var(--paper);
}

.bc-mast__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    padding-top: var(--space-lg);
    padding-bottom: var(--space-md);
    text-align: center;
}

.bc-mast__brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-md);
    text-decoration: none;
}

/* ── THE LOZENGE, header size ────────────────────────────────────────────
   The initials reversed out in paper inside a FULLY ROUNDED forest capsule.

   --bc-mark-size and --bc-cap are declared TOGETHER, here, in this rule. A
   --bc-cap on :root would resolve there against the root's mark size and the
   footer would inherit header-sized values — exactly what shipped in register
   before computed styles caught it.

   THE BOX IS FIXED, NOT GLYPH-DRIVEN. width and height are derived from the
   measured cap-height and do not change with the letters inside them. Outfit's
   advances differ by language — AC 1.390 em, IM 1.171 em, W 1.012 em — and
   dispatch shipped visibly unequal halves for exactly that reason. Centring the
   glyphs in a fixed box makes English and French identical.

   WITH ONE LETTER THE CAPSULE KEEPS ITS FULL WIDTH and does not collapse toward
   a circle. That is deliberate: a circle is a different mark, and one-letter
   sites drifting into one would give the network two beacon marks. */
.bc-mast__mark {
    --bc-mark-size: 26px;
    --bc-cap: calc(var(--bc-mark-size) * var(--bc-cap-ratio));
    display: inline-flex;
    /* `flex: 0 0 auto` is what makes the fixed box ACTUALLY fixed. The mark is a
       flex item inside .bc-mast__brand, and a flex item SHRINKS by default:
       measured before this line existed, the masthead capsule came out 62.8px at
       most widths but 60.8px (English) and 57px (French) at 390px, because the
       row was tight. Declaring width and height is not enough when the parent
       can squeeze them — and a capsule that differs between languages is
       precisely the defect dispatch shipped, in a new guise. */
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: calc(var(--bc-cap) * 3.40);
    height: calc(var(--bc-cap) * 2.10);
    border-radius: var(--bc-mark-radius);
    background: var(--accent);
    color: var(--paper);
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: var(--bc-mark-size);
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
}

.bc-mast__wordmark {
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: clamp(30px, 4.6vw, 54px);
    line-height: var(--lh-tight);
    letter-spacing: -0.02em;
}

.bc-mast__tagline {
    margin: 0;
    color: var(--ink-mute);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    font-weight: 500;
    letter-spacing: 0.02em;
}

/* ───────────────────────────────────────────────────────────────────────────
   6. Nav (7A #13–#16) — §4.4.2 #3
   THE CHROME'S OWN RIBBON: a horizontally scrollable PILL RAIL of categories,
   with a forest active pill. It scrolls on CSS overflow alone — no script — so
   beacon's gesture is present in the chrome before any card rail exists.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-nav {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--paper-soft);
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}

.bc-nav__inner {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    min-height: 52px;
}

.bc-nav__toggle {
    display: inline-flex;
    flex: 0 0 auto;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 36px;
    height: 36px;
    padding: 0 7px;
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    background: transparent;
    cursor: pointer;
}

.bc-nav__toggle span {
    display: block;
    height: 2px;
    background: var(--ink);
}

/* The rail itself. scroll-snap and momentum scrolling are the same mechanism
   §4.4.1 specifies for the card rails, applied here to the categories. A rail
   with few pills simply does not scroll — the thin-archive property, in the
   chrome. */
.bc-nav__rail {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: var(--space-sm);
    min-width: 0;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.bc-nav__rail::-webkit-scrollbar {
    display: none;
}

.bc-nav__item {
    flex: 0 0 auto;
    scroll-snap-align: start;
}

.bc-pill {
    display: inline-block;
    padding: var(--space-xs) var(--space-md);
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.bc-pill:hover,
.bc-pill:focus {
    border-color: var(--accent);
    color: var(--accent);
}

.bc-pill.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--paper);
    font-weight: 600;
}

.bc-nav__search {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    background: transparent;
    color: var(--ink);
    cursor: pointer;
}

.bc-nav__search:hover,
.bc-nav__search:focus {
    border-color: var(--accent);
    color: var(--accent);
}

.bc-nav__search-icon {
    font-size: 18px;
    line-height: 1;
}

/* ───────────────────────────────────────────────────────────────────────────
   7. The two full-width strips (7A #17, #18) — §4.4.2 #5, #6
   ─────────────────────────────────────────────────────────────────────────── */

.bc-strip {
    border-bottom: 1px solid var(--rule);
}

.bc-strip--ticker {
    background: var(--paper);
}

.bc-strip--stocks {
    background: var(--paper-deep);
}

.bc-strip__inner {
    display: flex;
    align-items: center;
    min-height: 38px;
}

/* Breaking news ticker — §3.2 exact names from _shared/partials/ticker.html.jinja */
.news-ticker {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    width: 100%;
    overflow: hidden;
}

.news-ticker__label {
    flex: 0 0 auto;
    padding: 3px var(--space-md);
    border-radius: var(--bc-mark-radius);
    background: var(--accent);
    color: var(--paper);
    font-family: var(--font-ui);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.news-ticker__track {
    flex: 1 1 auto;
    overflow: hidden;
}

.news-ticker__list {
    display: flex;
    align-items: center;
    gap: var(--space-xl);
    white-space: nowrap;
}

.news-ticker__item {
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.news-ticker__link {
    color: var(--ink-soft);
    text-decoration: none;
}

.news-ticker__link:hover,
.news-ticker__link:focus {
    color: var(--accent);
}

/* Stock ticker — §3.2 exact names from _shared/partials/stock_ticker.html.jinja */
.stock-ticker {
    /* The mount is empty in the HTML: stock_ticker.js injects the track and items at
       runtime, and it deliberately renders the twelve items twice so the marquee can
       wrap seamlessly. That only reads as one line if this box clips it. */
    --ticker-up: #26694B;
    --ticker-down: #A93026;
    position: relative;
    overflow: hidden;
    width: 100%;
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    font-variant-numeric: tabular-nums;
}

.stock-ticker-track {
    display: inline-flex;
    flex-wrap: nowrap;
    white-space: nowrap;
    animation: stock-ticker-scroll 40s linear infinite;
}

.stock-ticker:hover .stock-ticker-track {
    animation-play-state: paused;
}

.stock-ticker-item {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-xs);
    padding: 0 var(--space-lg);
    color: var(--ink-soft);
}

.stock-ticker-name {
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink);
}

.stock-ticker-price {
    font-weight: 500;
}

.stock-ticker-change.up {
    color: var(--ticker-up);
    font-weight: 600;
}

.stock-ticker-change.down {
    color: var(--ticker-down);
    font-weight: 600;
}

.stock-ticker-updated {
    position: absolute;
    top: 0;
    right: 0;
    display: flex;
    align-items: center;
    height: 100%;
    padding: 0 var(--space-sm);
    background: var(--paper-soft, #FAF7F2);
    border-left: 1px solid var(--rule);
    color: var(--ink-mute);
    font-size: 10px;
    pointer-events: none;
}

@keyframes stock-ticker-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
    /* No scrolling, so the row has to be reachable by hand instead: the track becomes a
       normal flex row the reader can swipe, rather than a clipped smear. */
    .stock-ticker {
        overflow-x: auto;
    }

    .stock-ticker-track {
        animation: none;
    }

    .stock-ticker-updated {
        position: static;
        height: auto;
        border-left: 0;
    }
}
/* ───────────────────────────────────────────────────────────────────────────
   8. Main
   ─────────────────────────────────────────────────────────────────────────── */

.bc-main {
    display: block;
    padding-bottom: var(--space-xl);
}

/* ───────────────────────────────────────────────────────────────────────────
   9. Newsletter band (7B #1) — §4.4.2 #33
   §3.2 exact names: the partial emits .newsletter-form, NOT .newsletter__form.
   Herald lost ~200 lines of CSS to that assumption.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-newsletter-band {
    padding: var(--space-xl) 0;
    background: var(--accent-tint);
    border-top: 2px solid var(--accent);
}

.newsletter-inner {
    max-width: 640px;
    margin: 0 auto;
    text-align: center;
}

.newsletter-heading {
    font-family: var(--font-headline);
    font-size: 30px;
    font-weight: 800;
    line-height: var(--lh-head);
}

.newsletter-subline {
    margin: var(--space-sm) 0 var(--space-md);
    color: var(--ink-soft);
    font-size: 16px;
}

.newsletter-form {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-sm);
}

.newsletter-label {
    flex: 0 0 100%;
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.newsletter-input {
    flex: 1 1 260px;
    min-width: 0;
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    background: var(--paper-soft);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 16px;
}

.newsletter-input:focus {
    border-color: var(--accent);
    outline: none;
}

.newsletter-button {
    flex: 0 0 auto;
    padding: var(--space-sm) var(--space-lg);
    border: 0;
    border-radius: var(--bc-mark-radius);
    background: var(--accent);
    color: var(--paper);
    font-family: var(--font-ui);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}

.newsletter-button:hover,
.newsletter-button:focus {
    background: var(--accent-deep);
}

.newsletter-status {
    flex: 0 0 100%;
    color: var(--ink-soft);
    font-size: var(--size-meta);
}

/* ───────────────────────────────────────────────────────────────────────────
   10. Footer (7B #2–#11) — §4.4.2 #34: 4 columns, warm paper-deep, forest
   headings.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-footer {
    background: var(--paper-deep);
    border-top: 2px solid var(--accent);
}

.bc-footer__inner {
    padding-top: var(--space-lg);
    padding-bottom: var(--space-lg);
}
/* Mobile-first: one column stacked; the breakpoint below establishes the four. */
.bc-footer__columns {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-lg);
}

.bc-footer__brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    text-decoration: none;
}

/* ── THE LOZENGE, footer size ────────────────────────────────────────────
   THE FORM IS KEPT, not changed. A filled capsule is the shape most likely to
   survive small: there is no hairline to thin (clarion's 0.63px rule) and no
   offset to muddy. Unlike courier's dropped initial, which needs two lines to
   drop into, nothing about this mark depends on its size.

   --bc-mark-size and --bc-cap are declared TOGETHER again, in this rule, so the
   footer derives its own values. That is the whole reason --bc-cap is not on
   :root. The radius stays 999px, so the small capsule is as fully rounded as
   the large one. */
.bc-footer__mark {
    --bc-mark-size: 17px;
    --bc-cap: calc(var(--bc-mark-size) * var(--bc-cap-ratio));
    display: inline-flex;
    /* Same guard as the masthead, and the footer needed it more: the four-column
       footer at 1021px squeezed this capsule to 35.8px in English and 34px in
       French against its declared 41px. Two languages, two different marks —
       exactly what a fixed box is supposed to prevent. */
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: calc(var(--bc-cap) * 3.40);
    height: calc(var(--bc-cap) * 2.10);
    border-radius: var(--bc-mark-radius);
    background: var(--accent);
    color: var(--paper);
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: var(--bc-mark-size);
    line-height: 1;
    letter-spacing: 0.01em;
    text-transform: uppercase;
}

.bc-footer__wordmark {
    font-family: var(--font-headline);
    font-size: 21px;
    font-weight: 800;
    line-height: var(--lh-tight);
    letter-spacing: -0.02em;
}

.bc-footer__tagline {
    margin: var(--space-sm) 0 0;
    color: var(--ink-mute);
    font-size: var(--size-meta);
}

.bc-footer__heading {
    margin-bottom: var(--space-sm);
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.bc-footer__heading--spaced {
    margin-top: var(--space-md);
}

.bc-footer__links li {
    margin-bottom: var(--space-xs);
}

.bc-footer__links a,
.bc-footer__social-link {
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: 15px;
    text-decoration: none;
}

.bc-footer__links a:hover,
.bc-footer__links a:focus,
.bc-footer__social-link:hover,
.bc-footer__social-link:focus {
    color: var(--accent);
}

.bc-footer__bottom {
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--rule);
    color: var(--ink-mute);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.bc-footer__copy,
.bc-footer__meta {
    margin: 0 0 var(--space-xs);
}

/* ───────────────────────────────────────────────────────────────────────────
   11. Ad slots — §3.2 exact names from _shared/partials/ad_slot.html.jinja
   ─────────────────────────────────────────────────────────────────────────── */

.ad-slot {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    min-height: 90px;
    padding: var(--space-md);
    background: var(--paper-soft);
    border: 1px solid var(--rule);
    text-align: center;
}

.ad-slot__label {
    color: var(--ink-mute);
    font-family: var(--font-ui);
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.ad-slot__video {
    max-width: 100%;
}

.ad-slot--house {
    background: var(--accent-tint);
    border-color: var(--accent-soft);
}

.house-ad {
    font-family: var(--font-ui);
    font-size: 15px;
}

/* ───────────────────────────────────────────────────────────────────────────
   12. Search overlay and nav drawer
   §5.1 — THE HIDDEN STATE IS A COMPOUND SELECTOR, from the first line.
   A bare `.is-hidden { display: none }` has specificity (0,1,0), exactly the
   same as `.search-overlay { display: flex }`, and loses on source order. That
   defect shipped in ledger and left the overlay painted open on load.
   §3.2 exact names read from the partials themselves.
   ─────────────────────────────────────────────────────────────────────────── */

.search-overlay {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 12vh var(--gutter) 0;
    background: rgba(28, 26, 23, 0.93);
}

.search-overlay.is-hidden {
    display: none;
}

.search-overlay__inner {
    width: 100%;
    max-width: 620px;
}

.search-overlay__form {
    display: flex;
    gap: var(--space-sm);
}

.search-overlay__label {
    display: block;
    margin-bottom: var(--space-sm);
    color: var(--paper);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    letter-spacing: 0.04em;
}

.search-overlay__input {
    flex: 1 1 auto;
    min-width: 0;
    padding: var(--space-md);
    border: 0;
    border-radius: var(--bc-mark-radius);
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-headline);
    font-size: 22px;
}

.search-overlay__input:focus {
    outline: 2px solid var(--accent-soft);
}

.search-overlay__submit,
.search-overlay__close {
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--paper);
    border-radius: var(--bc-mark-radius);
    background: transparent;
    color: var(--paper);
    font-family: var(--font-ui);
    font-size: 15px;
    cursor: pointer;
}

.search-overlay__submit:hover,
.search-overlay__submit:focus,
.search-overlay__close:hover,
.search-overlay__close:focus {
    background: var(--accent);
    border-color: var(--accent);
}

.search-overlay__close {
    margin-top: var(--space-md);
}

.nav-drawer {
    position: fixed;
    inset: 0;
    z-index: 95;
    display: flex;
    background: rgba(28, 26, 23, 0.93);
}

.nav-drawer.is-hidden {
    display: none;
}

.nav-drawer__inner {
    width: min(86vw, 360px);
    height: 100%;
    padding: var(--space-lg) var(--space-md);
    background: var(--paper);
    overflow-y: auto;
}

.nav-drawer__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--rule);
}

.nav-drawer__brand {
    font-family: var(--font-headline);
    font-size: 20px;
    font-weight: 800;
    text-decoration: none;
}

.nav-drawer__close {
    padding: var(--space-xs) var(--space-md);
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    background: transparent;
    color: var(--ink);
    font-size: 16px;
    cursor: pointer;
}

.nav-drawer__item {
    border-bottom: 1px solid var(--rule-soft);
}

.nav-drawer__link,
.nav-drawer__search-trigger {
    display: block;
    width: 100%;
    padding: var(--space-md) 0;
    border: 0;
    background: transparent;
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 16px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.nav-drawer__link:hover,
.nav-drawer__link:focus,
.nav-drawer__search-trigger:hover,
.nav-drawer__search-trigger:focus {
    color: var(--accent);
}

/* ───────────────────────────────────────────────────────────────────────────
   13. Breakpoints — MOBILE-FIRST
   Everything above is the narrow layout. These blocks only add.
   ─────────────────────────────────────────────────────────────────────────── */

@media (min-width: 721px) {
    .bc-footer__columns {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 1021px) {
    .bc-nav__toggle {
        display: none;
    }

    .bc-footer__columns {
        grid-template-columns: repeat(4, 1fr);
    }

    /* The mark grows with the masthead at desktop width. Only --bc-mark-size
       changes: --bc-cap is re-derived from it IN THIS RULE, and the radius stays
       999px so the capsule is as fully rounded large as it is small. */
    .bc-mast__mark {
        --bc-mark-size: 34px;
        --bc-cap: calc(var(--bc-mark-size) * var(--bc-cap-ratio));
    }
}

/* ───────────────────────────────────────────────────────────────────────────
   14. THE FULL-WIDTH LEAD (#7) — §4.4.2 #7
   21:9 image, Outfit display headline, Literata deck below, carousel dots under
   it. A JS carousel, deliberately distinct from every rail below it.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-lead {
    position: relative;
    display: block;
    padding-bottom: var(--space-lg);
    border-bottom: 1px solid var(--rule);
}

.bc-lead .hero-carousel__slide {
    display: none;
}

.bc-lead .hero-carousel__slide.is-active {
    display: block;
}

.bc-lead__media {
    display: block;
    width: 100%;
    aspect-ratio: 21 / 9;
    overflow: hidden;
}

.bc-lead__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.bc-lead__body {
    padding-top: var(--space-md);
}

.bc-lead__title {
    margin: var(--space-xs) 0 0;
    max-width: 22ch;
    font-family: var(--font-headline);
    font-size: var(--size-display);
    font-weight: 800;
    line-height: var(--lh-tight);
    letter-spacing: -0.02em;
    overflow-wrap: break-word;
}

.bc-lead__title a {
    text-decoration: none;
}

.bc-lead__title a:hover,
.bc-lead__title a:focus {
    color: var(--accent);
}

.bc-lead__deck {
    margin: var(--space-sm) 0 0;
    max-width: var(--measure);
    color: var(--ink-soft);
    font-family: var(--font-body);
    font-size: 19px;
    line-height: var(--lh-body);
}

/* ───────────────────────────────────────────────────────────────────────────
   15. THE RAILS — §4.4.1
   (a) NATIVE SCROLLING. `overflow-x: auto` plus scroll-snap, exactly as 4.4.1
       specifies. main.js only calls scrollBy(); it does not own the position.
   (d) TOUCH AND TRACKPAD. `overscroll-behavior-x: contain` stops a horizontal
       fling chaining to the page or firing back-navigation. `touch-action` is
       DELIBERATELY LEFT ALONE: setting `pan-x` here would block a vertical swipe
       that begins on a card, which is the classic way a sideways rail eats the
       page's vertical scroll. At the default the browser resolves the gesture by
       direction, so a vertical swipe scrolls the page even when it starts on a
       rail.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-rail {
    padding: var(--space-lg) 0;
    border-bottom: 1px solid var(--rule);
}

.bc-rail__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
}

.bc-rail__heading {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-h2);
    font-weight: 600;
    line-height: var(--lh-head);
    letter-spacing: -0.01em;
}

.bc-rail__controls {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.bc-rail__more {
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    font-weight: 500;
    text-decoration: none;
}

/* (b) THE CONTROLS ARE HIDDEN UNLESS THE RAIL CAN ACTUALLY SCROLL.
   A COMPOUND selector against the rail (§5.1), not a bare utility: main.js adds
   `is-scrollable` only when scrollWidth exceeds clientWidth, so a short rail —
   the normal case for a thin archive — shows no buttons to press that would do
   nothing. The buttons are real <button> elements in DOM order, so when they do
   appear they are keyboard-reachable without a tabindex. */
.bc-rail:not(.is-scrollable) .bc-rail__controls .bc-rail__btn {
    display: none;
}

.bc-rail__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    background: var(--paper-soft);
    color: var(--ink);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}

.bc-rail__btn:hover,
.bc-rail__btn:focus {
    border-color: var(--accent);
    color: var(--accent);
}

.bc-rail__btn:disabled {
    opacity: 0.35;
    cursor: default;
}

.bc-rail__track {
    display: flex;
    gap: var(--gutter);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: var(--space-xs);
}

.bc-rail__track::-webkit-scrollbar {
    display: none;
}

/* The scroller is focusable so a keyboard user can scroll it with the arrow
   keys — the native behaviour the buttons only supplement. */
.bc-rail__track:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* ───────────────────────────────────────────────────────────────────────────
   16. CARDS — and (c), the answer to a rail with too few items
   `flex: 1 0 var(--card)` is the whole mechanism. When the row OVERFLOWS the
   basis holds and every card is 280px, as §4.4.1 specifies. When it does NOT
   overflow the cards GROW to fill the width, so four cards in a rail sized for
   six become four wider cards rather than four narrow cards beside a gap.

   This matters more for beacon than for any other theme: voicemauritiusnews has
   the thinnest archive of the fourteen, and RIBBON was chosen partly because
   rails flatter a smaller library. A rail that looked empty would defeat the
   reason the theme exists. Measured on a synthesised short dataset, not reasoned
   about.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-card {
    display: flex;
    flex: 1 0 var(--card);
    flex-direction: column;
    gap: var(--space-sm);
    min-width: 0;
    scroll-snap-align: start;
}

.bc-card--double {
    flex-basis: var(--card-double);
}

.bc-card--compact {
    gap: var(--space-xs);
}

.bc-card__media {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: 10px;
}

.bc-card__media--thumb {
    width: 84px;
    flex: 0 0 84px;
}

.bc-card__media--video {
    position: relative;
}

.bc-card__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.bc-card__image--empty {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--paper-deep);
}

.bc-card__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-h3);
    font-weight: 600;
    line-height: var(--lh-head);
    overflow-wrap: break-word;
}

.bc-card__title--lead {
    font-size: 26px;
    font-weight: 700;
}

.bc-card__title--quote {
    font-style: italic;
}

.bc-card__title a {
    text-decoration: none;
}

.bc-card__title a:hover,
.bc-card__title a:focus {
    color: var(--accent);
}

.bc-card__deck {
    margin: 0;
    color: var(--ink-soft);
    font-family: var(--font-body);
    font-size: 15px;
    line-height: var(--lh-body);
}

.bc-card__byline {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.bc-card__author {
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: 13px;
    font-weight: 600;
}

.bc-headshot {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    border-radius: var(--bc-mark-radius);
    background: var(--paper-deep);
    border: 1px solid var(--rule);
}

/* Numbered cards (#17, #18): the numeral and the thumbnail sit side by side, and
   the headline runs beneath them. */
.bc-card--numbered {
    display: grid;
    grid-template-columns: auto 84px;
    align-items: center;
    gap: var(--space-sm);
}

.bc-card--numbered .bc-card__title {
    grid-column: 1 / -1;
}

.bc-card__numeral {
    font-family: var(--font-headline);
    font-size: 40px;
    font-weight: 800;
    line-height: 1;
    color: var(--accent);
}

.bc-card__slide {
    display: none;
    flex-direction: column;
    gap: var(--space-sm);
}

.bc-card__slide.is-active {
    display: flex;
}
.bc-video__glyph {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--bc-mark-radius);
    background: rgba(59, 109, 17, 0.9);
    color: var(--paper);
    font-size: 16px;
}

.bc-meta {
    display: inline-block;
    color: var(--ink-mute);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.bc-kicker {
    display: inline-block;
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.bc-kicker--reverse {
    color: var(--paper);
}

.bc-empty {
    margin: 0;
    color: var(--ink-mute);
    font-size: 16px;
}

/* ───────────────────────────────────────────────────────────────────────────
   17. THE CAROUSEL CONTROLS (Hero 1 and Hero 2)
   Distinct classes from the rail controls, because they are driven by a
   different script and must never be confused with them.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-carousel__controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-top: var(--space-md);
}

.bc-carousel__nav {
    display: flex;
    gap: var(--space-xs);
}

.bc-carousel__btn {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    background: var(--paper-soft);
    color: var(--ink);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}

.bc-carousel__btn:hover,
.bc-carousel__btn:focus {
    border-color: var(--accent);
    color: var(--accent);
}

.bc-carousel__dots {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.bc-carousel__dot {
    width: 9px;
    height: 9px;
    padding: 0;
    border: 1px solid var(--accent);
    border-radius: var(--bc-mark-radius);
    background: transparent;
    cursor: pointer;
}

.bc-carousel__dot.is-active {
    background: var(--accent);
}

/* ───────────────────────────────────────────────────────────────────────────
   18. FULL-WIDTH BREAKOUTS between rails — §4.4.1
   Single-item modules go full width, which is what stops the page becoming an
   undifferentiated stack of strips.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-breakout {
    padding: var(--space-lg) 0;
    border-bottom: 1px solid var(--rule);
}

.bc-breakout--ad {
    padding: var(--space-md) 0;
}

.bc-breakout--investigation {
    background: var(--accent-tint);
    border-top: 4px solid var(--accent);
}

.bc-breakout--newsletter {
    background: var(--paper-deep);
}

.bc-breakout--photo,
.bc-breakout--cat-header {
    padding: 0;
}

.bc-breakout--cat-header {
    padding: var(--space-lg) 0;
}

.bc-photo {
    position: relative;
    margin: 0;
}

.bc-photo__link {
    display: block;
    position: relative;
    width: 100%;
    aspect-ratio: 21 / 9;
    overflow: hidden;
    text-decoration: none;
}

.bc-photo__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* A light theme's overlay: a restrained ink scrim for contrast, not a mood. */
.bc-photo__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: var(--space-lg) 0;
    background: rgba(28, 26, 23, 0.66);
    color: var(--paper);
}

.bc-photo__title {
    margin: var(--space-xs) 0 0;
    font-family: var(--font-headline);
    font-size: 30px;
    font-weight: 800;
    line-height: var(--lh-head);
}

.bc-photo__deck {
    margin: var(--space-xs) 0 0;
    max-width: var(--measure);
    font-size: 15px;
}

.bc-investigation__label {
    display: block;
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.bc-investigation__title {
    margin: var(--space-xs) 0 0;
    font-family: var(--font-headline);
    font-size: 30px;
    font-weight: 800;
    line-height: var(--lh-head);
}

.bc-investigation__body {
    margin: var(--space-sm) 0 0;
    max-width: var(--measure);
    color: var(--ink-soft);
    line-height: var(--lh-body);
}

.bc-longread__quote {
    margin: var(--space-md) 0;
    padding-left: var(--space-md);
    border-left: 4px solid var(--accent);
    max-width: var(--measure);
    font-family: var(--font-body);
    font-size: 22px;
    font-style: italic;
    line-height: 1.45;
}

.bc-longread__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 28px;
    font-weight: 700;
    line-height: var(--lh-head);
}

.bc-longread__title a {
    text-decoration: none;
}

.bc-longread__media {
    display: block;
    width: 100%;
    max-width: 720px;
    margin-top: var(--space-md);
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: 10px;
}

.bc-longread__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.bc-newsletter-inline {
    display: block;
}

/* ───────────────────────────────────────────────────────────────────────────
   19. CATEGORY PAGE — a GRID, not rails (§4.4.5)
   A rail scrolls sideways without end, so "page 2 of 6" has nowhere to live in
   it. The cards are the same .bc-card; only the container changes.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--card)), 1fr));
    gap: var(--space-lg) var(--gutter);
    padding: var(--space-lg) 0;
}

/* Inside the grid a card must not stretch on a flex basis — the grid track owns
   the width. */
.bc-grid .bc-card {
    flex: 0 0 auto;
}

.bc-cat__heading {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-h1);
    font-weight: 800;
    line-height: var(--lh-tight);
    letter-spacing: -0.02em;
}

/* ───────────────────────────────────────────────────────────────────────────
   20. Article variants (§8 unified geometry, beacon voice)
   ─────────────────────────────────────────────────────────────────────────── */

.bc-article {
    display: block;
    padding-bottom: var(--space-xl);
}

/* Article hero — copied from the five live themes (2026-10-01). The cap sits on the
   IMAGE, so object-fit: cover crops from the centre. It used to sit on the figure, whose
   height never resolved, so a portrait photo was clipped from the top.
   v1: broadsheet .article-v1__hero-image (and gazette/magazine .{gz,mg}-article--v1).
   v3: the live themes' shared .article-v3__hero rules, 320px under 768px. */
.bc-article__hero {
    margin: 0 0 var(--space-lg);
    width: 100%;
}

.bc-article__hero-image {
    display: block;
    width: 100%;
    max-height: 80vh;
    object-fit: cover;
}

.bc-article-v3__hero {
    margin: 0 0 var(--space-lg);
    width: 100%;
    max-height: 600px;
    overflow: hidden;
}

.bc-article-v3__hero-image {
    display: block;
    width: 100%;
    height: auto;
    max-height: 600px;
    object-fit: cover;
}

/* Hero no wider than the theme's content container (2026-10-03): the same box as the
   container — max-width, centred, gutter padding — so a small photo is not stretched to
   the full screen width. The image keeps its centred crop and height cap above. v2 unchanged. */
.bc-article__hero,
.bc-article-v3__hero {
    max-width: var(--max-width);
    margin-left: auto;
    margin-right: auto;
    padding: 0 var(--gutter);
}

@media (max-width: 768px) {
    .bc-article-v3__hero { max-height: 320px; }
    .bc-article-v3__hero-image { max-height: 320px; }
}

.bc-article__header {
    max-width: var(--measure);
    margin: var(--space-md) 0 var(--space-lg);
}

.bc-article__category {
    display: inline-block;
    margin-bottom: var(--space-sm);
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
}

.bc-article__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-h1);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    overflow-wrap: break-word;
}

.bc-article__deck {
    margin: var(--space-sm) 0 0;
    color: var(--ink-soft);
    font-family: var(--font-body);
    font-size: 20px;
    line-height: var(--lh-body);
}

.bc-article__byline {
    margin-top: var(--space-md);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--rule);
}

.bc-article__grid,
.bc-article-v2__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-xl);
    align-items: start;
}

.bc-article__main,
.bc-article__column {
    min-width: 0;
    max-width: var(--measure);
}

.bc-article__body {
    font-family: var(--font-body);
    font-size: var(--size-body);
    line-height: var(--lh-body);
}

.bc-article__body p {
    margin: 0 0 var(--space-md);
}

.bc-article__body h2,
.bc-article__body h3 {
    margin: var(--space-lg) 0 var(--space-sm);
    font-family: var(--font-headline);
}

.bc-article__body img {
    display: block;
    width: 100%;
    height: auto;
    margin: var(--space-md) 0;
    border-radius: 10px;
}

.bc-article__body a {
    color: var(--accent);
}

.bc-article__body blockquote {
    margin: var(--space-lg) 0;
    padding-left: var(--space-md);
    border-left: 4px solid var(--accent);
    font-style: italic;
}

/* The V2 rail is NOT sticky — beacon already asks the reader to scroll sideways
   in places, and pinning a column while they do is the Phase 7c gazette pivot
   waiting to happen. */
.bc-article__rail {
    min-width: 0;
}

.bc-article-v2__hero {
    max-width: var(--measure);
    margin: 0 0 var(--space-lg);
}

.bc-article-v2__hero-image {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 10px;
}

.bc-article__related {
    margin-top: var(--space-xl);
}

/* ───────────────────────────────────────────────────────────────────────────
   21. Shared partial classes — §3.2 EXACT names, read from the partials
   ─────────────────────────────────────────────────────────────────────────── */

.breadcrumbs {
    margin: var(--space-md) 0;
    color: var(--ink-mute);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.breadcrumbs-list,
.breadcrumbs__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

.breadcrumbs-item,
.breadcrumbs__item {
    display: inline;
}

.article-byline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.byline-author-name {
    font-weight: 600;
}

.byline-sep,
.byline-date {
    color: var(--ink-mute);
}

.article-tldr,
.article-key-takeaways,
.article-faq,
.article-qa,
.article-entities,
.article-topics,
.article-tags {
    margin: var(--space-lg) 0;
    padding: var(--space-md);
    background: var(--paper-soft);
    border-left: 4px solid var(--accent);
    border-radius: 0 10px 10px 0;
}

.tldr-heading,
.kt-heading,
.faq-heading,
.qa-heading,
.entities-heading,
.entities-group__heading,
.related-heading,
.article-rail__heading,
.article-v2-rail__entity-group-heading,
.article-tags__heading,
.article-v3-related__heading,
.social-share__label {
    margin: 0 0 var(--space-sm);
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.tldr-body {
    margin: 0;
    line-height: var(--lh-body);
}

.kt-list,
.faq-list,
.qa-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.kt-list li {
    padding-left: var(--space-md);
    border-left: 2px solid var(--rule);
}

.faq-question,
.qa-question {
    font-family: var(--font-headline);
    font-weight: 600;
}

.faq-answer,
.qa-answer {
    margin: var(--space-xs) 0 0;
    color: var(--ink-soft);
}

.entities-list,
.article-tags__list,
.article-rail__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

.entity-chip,
.entity-person,
.entity-org,
.entity-tag,
.article-tags__link,
.article-rail__chip {
    display: inline-block;
    padding: 3px var(--space-md);
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 13px;
    text-decoration: none;
}

.article-rail,
.article-v2-rail {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
    min-width: 0;
}

.article-rail__section,
.article-v2-rail__section {
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--rule);
}

.social-share__list,
.article-rail__share-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

.social-share__link,
.article-rail__share-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-xs) var(--space-md);
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 13px;
    text-decoration: none;
}

.social-share__link:hover,
.social-share__link:focus,
.article-rail__share-btn:hover,
.article-rail__share-btn:focus {
    border-color: var(--accent);
    color: var(--accent);
}

/* Related articles render as a RAIL (4.4.5) — the same scroll-snap track the
   homepage uses, so the reader lands back in beacon's grammar. */
.article-related,
.article-v3-related {
    padding-top: var(--space-lg);
    border-top: 2px solid var(--accent);
}

.related-grid {
    display: flex;
    gap: var(--gutter);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.related-grid::-webkit-scrollbar {
    display: none;
}

.article-card {
    display: flex;
    flex: 1 0 var(--card);
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
    scroll-snap-align: start;
}

.article-card__image-link {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: 10px;
}

.article-card__image-link img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.article-card__category {
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.article-card__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 17px;
    font-weight: 600;
    line-height: var(--lh-head);
}

.article-card__title a {
    text-decoration: none;
}

.article-card__deck,
.article-card__byline {
    margin: 0;
    color: var(--ink-soft);
    font-size: 14px;
}

.article-v3-related__list {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.article-v3-related__item {
    display: flex;
    gap: var(--space-sm);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--rule-soft);
}

.article-v3-related__num {
    color: var(--accent);
    font-family: var(--font-headline);
    font-weight: 800;
}

.article-v3-related__link {
    text-decoration: none;
}

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding: var(--space-md) 0 var(--space-xl);
    border-top: 1px solid var(--rule);
    font-family: var(--font-ui);
    font-size: 15px;
}

.pagination-prev,
.pagination-next {
    padding: var(--space-xs) var(--space-md);
    border: 1px solid var(--rule);
    border-radius: var(--bc-mark-radius);
    text-decoration: none;
}

.pagination-disabled {
    color: var(--ink-mute);
}

.sponsored-badge {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--bc-mark-radius);
    background: var(--accent-tint);
    font-family: var(--font-ui);
    font-size: 13px;
}

/* ───────────────────────────────────────────────────────────────────────────
   22. THE SINGLE :empty GUARD (lesson 4, proved on ledger)
   responsive_image.html.jinja rejects whitespace-only, bare "/" and blob: URLs
   INSIDE the macro, which a `{% if art.image_url %}` truthiness test does not
   catch — so the link renders with nothing in it. The link owns the dimensions,
   so one rule paints the frame and no card collapses.
   ─────────────────────────────────────────────────────────────────────────── */

.bc-card__media:empty,
.bc-lead__media:empty,
.bc-photo__link:empty,
.bc-longread__media:empty,
.article-card__image-link:empty {
    background: var(--paper-deep);
    border: 1px solid var(--rule);
}

/* ───────────────────────────────────────────────────────────────────────────
   23. Stage 2 breakpoints — MOBILE-FIRST
   Nothing here undoes a rule above; each block only adds.
   ─────────────────────────────────────────────────────────────────────────── */

@media (min-width: 721px) {
    .bc-lead__body {
        padding-top: var(--space-lg);
    }
}

@media (min-width: 1021px) {
    .bc-article__grid {
        grid-template-columns: minmax(0, var(--measure)) 300px;
    }

    .bc-article-v2__grid {
        grid-template-columns: 300px minmax(0, var(--measure));
    }
}
