/* ═══════════════════════════════════════════════════════════════════════════
   REGISTER — structure SPLIT
   Phase 23c.11 skeleton: THE CHROME ONLY.

   Two panes of exactly equal width (1fr 1fr) below the chrome, a slow
   image-led feature pane left and a fast time-stamped live stack right.
   Neither side is subordinate — that equality is register's whole claim, and
   it is what separates it from gazette's ~62/33 main-plus-sidebar.

   Site mark .......... AN INSET CORNER: a plum rule down the LEFT of the
                        initials turning along the BOTTOM. An open bracket —
                        two sides drawn, two left open. No fill, no fourth
                        side, no box (§7.1/§7.1.1/§4.5.6, decided by Khalaf
                        before the build).
   Spectral headlines + Work Sans body.
   Paper #F4F6F7 / ink #14181B / plum #6B2B5E. Class prefix: rg-.

   HOW THIS FILE IS WRITTEN — the lessons the four 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. Writing the wide layout first forces an
     order/undo reset at narrow widths, and undoing a rule is what creates the
     pressure to reach for !important.
   - 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. Register is a light theme; §4.5 #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 two panes, the module overrides, the
   article variants and the category page are later prompts.
   ═══════════════════════════════════════════════════════════════════════════ */

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

:root {
    /* Ink */
    --ink: #14181B;
    --ink-soft: #39424A;
    --ink-mute: #6C777F;

    /* Paper */
    --paper: #F4F6F7;
    --paper-soft: #FBFCFC;
    --paper-deep: #E6EAEC;

    /* Accent — plum */
    --accent: #6B2B5E;
    --accent-soft: #8F4C82;
    --accent-deep: #4C1B42;
    --accent-tint: rgba(107, 43, 94, 0.08);

    /* Rules */
    --rule: #D3DADD;
    --rule-soft: #E4E9EB;

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

    /* Scale (§4.5.4) */
    --size-display: clamp(30px, 3.4vw, 46px);
    --size-h1: clamp(36px, 4vw, 54px);
    --size-h2: 15px;
    --size-h3: 19px;
    --size-body: 17px;
    --size-meta: 13px;
    --lh-tight: 1.1;
    --lh-head: 1.3;
    --lh-body: 1.6;

    /* Layout (§4.5.1) */
    --max-width: 1400px;
    --measure: 62ch;
    --gutter: 22px;

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

    /* ── THE INSET CORNER — the two constants ───────────────────────────
       0.660 is Spectral's OWN cap-height in em, measured by rendering the
       vendored Spectral-Bold.ttf at 100px and 200px — not chosen by eye.
       It lives here so there is ONE source for the ratio.

       --rg-cap is deliberately NOT declared here. A custom property that
       references another resolves in the scope where IT is declared, so a
       --rg-cap defined on :root would bake in the root's --rg-mark-size and
       could never be re-derived by a rule that sets a different size. That
       is exactly what shipped in this file's first draft: the footer mark
       computed 21px letters against the header's 22.44px line-height and
       header-sized insets, and the desktop masthead computed 42px letters
       against the same 22.44px. Each mark rule therefore declares
       --rg-mark-size and --rg-cap TOGETHER, so the chain resolves in the
       element's own scope.

       --rg-mark-rule is PINNED, not derived. Clarion's spec scaled its rule
       at 0.035 L, which produced a 0.63px hairline at footer size; a bracket
       has that failure mode on two arms at once, so the thickness is a
       constant and only the letters and the insets scale. */
    --rg-cap-ratio: 0.660;
    --rg-mark-rule: 2px;
}

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

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

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

body.rg-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;
}

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

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

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

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

/* ───────────────────────────────────────────────────────────────────────────
   4. Top bar (7A #2, #3, #4, #11, #12) — §4.5.2 #1
   A thin strip that is ITSELF a split: edition and date at the start, social
   at the end. The page's first statement of its own structure.
   ─────────────────────────────────────────────────────────────────────────── */

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

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

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

.rg-topbar__edition {
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.rg-topbar__sep {
    color: var(--ink-mute);
}

.rg-topbar__date {
    color: var(--ink-soft);
}

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

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

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

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

/* ───────────────────────────────────────────────────────────────────────────
   5. Masthead (7A #5–#10) — §4.5.2 #2
   Centred Spectral wordmark with a SPLIT DATELINE beneath. Centring is
   deliberate: a left-aligned lockup weights the page's left edge, which is the
   one thing a theme of two equal panes must not do.
   ─────────────────────────────────────────────────────────────────────────── */

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

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

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

/* ── THE INSET CORNER, header size ───────────────────────────────────────
   Two borders only — left and bottom. No top, no right, no background, no
   radius: an OPEN BRACKET, which is the point. The open corner echoes the
   page's split without illustrating it.

   line-height is set to the measured cap-height so the box is exactly as tall
   as the capitals, which puts the bottom arm on the letters' baseline rather
   than at an arbitrary distance below them. padding-left insets the letters
   from the vertical arm; padding-bottom holds them off the horizontal one.

   ONE LETTER NEEDS NO SPECIAL CASE, unlike clarion's rule, which sat between
   two letters and had to be dropped entirely at one initial. A bracket
   encloses whatever is inside it. min-width holds the bottom arm to a
   readable length so a single narrow glyph still reads as a corner rather
   than as a tick. */
.rg-mast__mark {
    --rg-mark-size: 34px;
    --rg-cap: calc(var(--rg-mark-size) * var(--rg-cap-ratio));
    display: inline-block;
    min-width: calc(var(--rg-cap) * 1.30);
    padding-left: calc(var(--rg-cap) * 0.30);
    padding-bottom: calc(var(--rg-cap) * 0.26);
    border-left: var(--rg-mark-rule) solid var(--accent);
    border-bottom: var(--rg-mark-rule) solid var(--accent);
    color: var(--ink);
    font-family: var(--font-headline);
    font-weight: 700;
    font-size: var(--rg-mark-size);
    line-height: var(--rg-cap);
    letter-spacing: 0.01em;
    text-transform: uppercase;
}

.rg-mast__wordmark {
    font-family: var(--font-headline);
    font-weight: 700;
    font-size: clamp(30px, 4.4vw, 52px);
    line-height: var(--lh-tight);
    letter-spacing: -0.01em;
}

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

/* ── The split dateline — the masthead's echo of the two panes ───────────
   Two halves either side of a plum rule. It carries the kicker (7A #5) and
   About/Contact (7A #6), so neither is duplicated in the top bar. */
.rg-mast__dateline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    width: 100%;
    margin-top: var(--space-md);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--rule);
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
}

.rg-mast__dateline-half {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.rg-mast__dateline-half--start {
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.rg-mast__dateline-rule {
    width: 1px;
    height: 14px;
    background: var(--accent);
}

.rg-mast__dateline-link {
    text-decoration: none;
}

.rg-mast__dateline-link:hover,
.rg-mast__dateline-link:focus {
    color: var(--accent);
}

/* ───────────────────────────────────────────────────────────────────────────
   6. Nav (7A #13–#16) — §4.5.2 #3
   Centred Work Sans links, plum underline on the active link.
   ─────────────────────────────────────────────────────────────────────────── */

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

.rg-nav__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    min-height: 46px;
}

.rg-nav__toggle {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 34px;
    height: 34px;
    padding: 0 6px;
    border: 1px solid var(--rule);
    background: transparent;
    cursor: pointer;
}

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

/* Mobile-first: the category list is the drawer's job below the breakpoint,
   so it is not rendered inline here. The breakpoint below turns it on. */
.rg-nav__list {
    display: none;
}

.rg-nav__link {
    display: inline-block;
    padding: var(--space-sm) 0;
    border-bottom: 2px solid transparent;
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-decoration: none;
}

.rg-nav__link:hover,
.rg-nav__link:focus {
    color: var(--accent);
}

.rg-nav__link.is-active {
    border-bottom-color: var(--accent);
    color: var(--accent);
    font-weight: 600;
}

.rg-nav__search {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 14px;
    cursor: pointer;
}

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

.rg-nav__search-icon {
    font-size: 17px;
    line-height: 1;
}

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

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

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

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

.rg-strip__inner {
    min-height: 34px;
    display: flex;
    align-items: center;
}

/* 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-sm);
    background: var(--accent);
    color: var(--paper-soft);
    font-family: var(--font-ui);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    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: #1F6B44;
    --ticker-down: #A82B24;
    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, #F7F8F9);
    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
   ─────────────────────────────────────────────────────────────────────────── */

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

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

.rg-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: 28px;
    font-weight: 700;
    line-height: var(--lh-head);
}

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

.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);
    background: var(--paper-soft);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 15px;
}

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

.newsletter-button {
    flex: 0 0 auto;
    padding: var(--space-sm) var(--space-lg);
    border: 0;
    background: var(--accent);
    color: var(--paper-soft);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.04em;
    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.5.2 #34
   Light footer split into TWO EQUAL HALVES of 2 columns each, plum rules.
   The split restated at the foot of the page.
   ─────────────────────────────────────────────────────────────────────────── */

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

.rg-footer__inner {
    padding-top: var(--space-lg);
    padding-bottom: var(--space-lg);
}
/* Mobile-first: one column stacked. The breakpoint below establishes the two
   equal halves. */
.rg-footer__halves {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-lg);
}

.rg-footer__half {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-lg);
}

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

/* ── THE INSET CORNER, footer size ───────────────────────────────────────
   THE FORM IS KEPT, not changed. A bracket stays a bracket when it shrinks —
   unlike courier's dropped initial, which needs two lines to drop into and so
   became a run-in initial in the footer.

   What changes is only the letters and the insets, through the same --rg-cap
   chain. BOTH ARMS STAY PINNED at the header's 2px: clarion's scaled rule
   thinned to a 0.63px hairline at footer size, and a bracket would have hit
   that on two arms at once. §7.1.1 requires the mark to survive its small
   use; pinning is what makes it survive. */
.rg-footer__mark {
    --rg-mark-size: 21px;
    --rg-cap: calc(var(--rg-mark-size) * var(--rg-cap-ratio));
    display: inline-block;
    min-width: calc(var(--rg-cap) * 1.30);
    padding-left: calc(var(--rg-cap) * 0.30);
    padding-bottom: calc(var(--rg-cap) * 0.26);
    border-left: var(--rg-mark-rule) solid var(--accent);
    border-bottom: var(--rg-mark-rule) solid var(--accent);
    color: var(--ink);
    font-family: var(--font-headline);
    font-weight: 700;
    font-size: var(--rg-mark-size);
    line-height: var(--rg-cap);
    letter-spacing: 0.01em;
    text-transform: uppercase;
}

.rg-footer__wordmark {
    font-family: var(--font-headline);
    font-size: 21px;
    font-weight: 700;
    line-height: var(--lh-tight);
}

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

.rg-footer__heading {
    margin-bottom: var(--space-sm);
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: var(--size-h2);
    font-weight: 600;
    letter-spacing: 0.04em;
}

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

.rg-footer__links li,
.rg-footer__social li {
    margin-bottom: var(--space-xs);
}

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

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

.rg-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);
}

.rg-footer__copy,
.rg-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.08em;
    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: 14px;
}

/* ───────────────────────────────────────────────────────────────────────────
   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(20, 24, 27, 0.92);
}

.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-bottom: 2px solid var(--accent-soft);
    background: transparent;
    color: var(--paper-soft);
    font-family: var(--font-headline);
    font-size: 24px;
}

.search-overlay__input:focus {
    border-bottom-color: var(--paper-soft);
    outline: none;
}

.search-overlay__submit,
.search-overlay__close {
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--paper-soft);
    background: transparent;
    color: var(--paper-soft);
    font-family: var(--font-ui);
    font-size: 14px;
    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(20, 24, 27, 0.92);
}

.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: 700;
    text-decoration: none;
}

.nav-drawer__close {
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--rule);
    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 (clarion's lesson)
   Everything above is the narrow layout. These add to it; nothing here undoes
   a rule written earlier, which is what keeps !important out of the file.
   ─────────────────────────────────────────────────────────────────────────── */

@media (min-width: 721px) {
    .rg-footer__half {
        grid-template-columns: 1fr 1fr;
    }
}

@media (min-width: 961px) {
    /* The nav's category list replaces the drawer at this width. */
    .rg-nav__toggle {
        display: none;
    }

    .rg-nav__list {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        gap: var(--space-lg);
        flex: 1 1 auto;
    }

    /* TWO EQUAL HALVES, divided by a plum rule — the footer's restatement of
       the split. 1fr 1fr, never a subordinate side. */
    .rg-footer__halves {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-xl);
    }

    .rg-footer__half + .rg-footer__half {
        padding-left: var(--space-xl);
        border-left: 1px solid var(--accent-soft);
    }

    /* The mark grows with the masthead at desktop width. Only --rg-mark-size
       changes: --rg-cap and both insets follow from it through the one calc
       chain, and the rule thickness stays pinned. */
    .rg-mast__mark {
        --rg-mark-size: 42px;
    }
}

/* ───────────────────────────────────────────────────────────────────────────
   14. Full-width interruptions — §4.5.1
   The ONLY things outside the panes: the homepage_* ads (#23/#24/#25), the
   mid-page newsletter (#19) and the topic cluster rows (#20).
   ─────────────────────────────────────────────────────────────────────────── */

.rg-full {
    padding: var(--space-lg) 0;
}

.rg-full--newsletter {
    background: var(--accent-tint);
    border-top: 2px solid var(--accent);
    border-bottom: 1px solid var(--rule);
}

.rg-full--cat-header {
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--rule);
}

/* ───────────────────────────────────────────────────────────────────────────
   15. THE SPLIT — two panes of EQUAL editorial weight (§4.5.1)
   MOBILE-FIRST: the base is ONE column and the panes arrive at 1025px. Stacked,
   the order is LEFT PANE THEN RIGHT, which is already the source order — so no
   `order` property is set anywhere and nothing written above is undone. That is
   what keeps !important out of this file (clarion's lesson).
   ─────────────────────────────────────────────────────────────────────────── */

.rg-split {
    position: relative;
}

.rg-split__inner {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-xl);
    align-items: start;
    padding-top: var(--space-lg);
    padding-bottom: var(--space-lg);
}

/* A pane is a column of full modules, never a widget rail. */
.rg-pane {
    display: flex;
    flex-direction: column;
    gap: var(--space-lg);
    min-width: 0;
}

/* MIRRORED LABELS — identical element, size and weight on both sides. The only
   difference is the word, which is the whole point: `home.featured` against
   `home.live_stack`. */
.rg-pane__label {
    margin: 0;
    padding-bottom: var(--space-sm);
    border-bottom: 2px solid var(--accent);
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: var(--size-h2);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* EACH PANE CLOSES ITSELF. When one pane's data runs out first, the column ends
   on a drawn line rather than on absence — the difference between reading as
   finished and reading as broken. */
.rg-pane__close {
    display: block;
    width: 100%;
    height: 1px;
    margin-top: auto;
    background: var(--rule);
}

.rg-pane__ad {
    margin: var(--space-sm) 0;
}

/* ───────────────────────────────────────────────────────────────────────────
   16. Modules inside a pane
   ─────────────────────────────────────────────────────────────────────────── */

.rg-module {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    min-width: 0;
}

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

.rg-module__heading {
    flex: 0 1 auto;
    min-width: 0;
    overflow-wrap: break-word;
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-h3);
    font-weight: 700;
    line-height: var(--lh-head);
}

.rg-rule {
    flex: 1 1 auto;
    height: 1px;
    min-width: var(--space-lg);
    background: var(--accent-soft);
}

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

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

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

/* ───────────────────────────────────────────────────────────────────────────
   17. Rows — the shared listing shape. Every row carries its own image (§4.0).
   ─────────────────────────────────────────────────────────────────────────── */

.rg-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

/* NO RULE BETWEEN ROWS OF THE SAME KIND (polish audit R1, shortlist item 2).
   Fifty of these fell on one homepage. Between entries of the same kind the
   thumbnail column and the space already separate; a rule is only earned at a
   change of kind, which .rg-pane__label still marks. */
.rg-row {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm);
    min-width: 0;
    padding-bottom: var(--space-md);
}

.rg-row__thumb-link {
    display: block;
    flex: 0 0 84px;
    width: 84px;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

.rg-row__thumb-link--lead {
    flex-basis: 132px;
    width: 132px;
}

.rg-row__thumb-link--video {
    aspect-ratio: 16 / 9;
}

.rg-thumb {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.rg-thumb--square {
    aspect-ratio: 1 / 1;
}

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

.rg-row__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

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

.rg-row__title a {
    text-decoration: none;
}

.rg-row__title a:hover,
.rg-row__title a:focus {
    color: var(--accent);
}

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

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

.rg-row__author {
    color: var(--ink-soft);
    font-family: var(--font-ui);
    font-size: 12px;
    font-weight: 600;
}

.rg-row--lead .rg-row__title {
    font-size: 22px;
    font-weight: 700;
}

.rg-row__numeral,
.rg-row__rank {
    flex: 0 0 auto;
    min-width: 28px;
    color: var(--accent);
    font-family: var(--font-headline);
    font-size: 20px;
    font-weight: 700;
    line-height: 1.2;
}

.rg-headshot {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--paper-deep);
    border: 1px solid var(--rule);
}
/* ───────────────────────────────────────────────────────────────────────────
   18. Feature blocks, cards and the 2×2 picks grid
   ─────────────────────────────────────────────────────────────────────────── */

.rg-feature {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    min-width: 0;
}

.rg-feature__media {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

.rg-feature__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.rg-feature__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 24px;
    font-weight: 700;
    line-height: var(--lh-head);
    overflow-wrap: break-word;
}

.rg-feature__title--lead {
    font-size: var(--size-display);
    line-height: var(--lh-tight);
}

.rg-feature__title a {
    text-decoration: none;
}

.rg-feature__title a:hover,
.rg-feature__title a:focus {
    color: var(--accent);
}

.rg-feature__deck {
    margin: 0;
    color: var(--ink-soft);
    font-size: 16px;
    line-height: var(--lh-body);
}

.rg-grid2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-md);
}

.rg-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.rg-card__media {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

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

.rg-card__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 16px;
    font-weight: 500;
    line-height: var(--lh-head);
    overflow-wrap: break-word;
}

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

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

/* ───────────────────────────────────────────────────────────────────────────
   19. Hero 1 and Hero 2 — SAME display size in both panes (§4.5.4)
   A smaller Hero 2 would demote the right pane in one stroke, so the size token
   is shared and only the image ratio differs: 4:3 left (#7), 16:9 right (#8).
   ─────────────────────────────────────────────────────────────────────────── */

.rg-hero {
    position: relative;
    min-width: 0;
}

.rg-hero .hero-carousel__slide {
    display: none;
    flex-direction: column;
    gap: var(--space-sm);
}

.rg-hero .hero-carousel__slide.is-active {
    display: flex;
}

.rg-hero__media {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

.rg-hero__media--wide {
    aspect-ratio: 16 / 9;
}

.rg-hero__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.rg-hero__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    min-width: 0;
}

.rg-hero__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-display);
    font-weight: 700;
    line-height: var(--lh-tight);
    overflow-wrap: break-word;
}

.rg-hero__title a {
    text-decoration: none;
}

.rg-hero__title a:hover,
.rg-hero__title a:focus {
    color: var(--accent);
}

.rg-hero__deck {
    margin: 0;
    color: var(--ink-soft);
    font-size: 17px;
    line-height: var(--lh-body);
}

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

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

.rg-carousel__prev,
.rg-carousel__next {
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--rule);
    background: var(--paper-soft);
    color: var(--ink);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}

.rg-carousel__prev:hover,
.rg-carousel__prev:focus,
.rg-carousel__next:hover,
.rg-carousel__next:focus {
    border-color: var(--accent);
    color: var(--accent);
}

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

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

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

/* ───────────────────────────────────────────────────────────────────────────
   20. Photo essay, video, long-read, investigation, inline newsletter
   ─────────────────────────────────────────────────────────────────────────── */

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

.rg-photo__link {
    display: block;
    position: relative;
    width: 100%;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    text-decoration: none;
}

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

/* A LIGHT theme's overlay: a soft ink scrim for contrast, not a mood. */
.rg-photo__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: var(--space-md);
    background: rgba(20, 24, 27, 0.66);
    color: var(--paper-soft);
}

.rg-photo__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 21px;
    font-weight: 700;
    line-height: var(--lh-head);
}

.rg-photo__deck {
    margin: var(--space-xs) 0 0;
    font-size: 14px;
}

.rg-video {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.rg-video__link {
    display: block;
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
}

.rg-video__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.rg-video__glyph {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(107, 43, 94, 0.88);
    color: var(--paper-soft);
    font-size: 16px;
}

.rg-video__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 19px;
    font-weight: 700;
    line-height: var(--lh-head);
}

.rg-video__title a {
    text-decoration: none;
}

.rg-video__list {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    margin-top: var(--space-md);
}

.rg-longread {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding-left: var(--space-md);
    border-left: 3px solid var(--accent);
}

.rg-longread__quote {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 21px;
    font-style: italic;
    line-height: 1.4;
}

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

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

.rg-longread__media {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    overflow: hidden;
}

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

.rg-investigation {
    padding: var(--space-md);
    background: var(--accent-tint);
    border-top: 3px solid var(--accent);
}

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

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

.rg-investigation__body {
    margin: var(--space-sm) 0 0;
    color: var(--ink-soft);
    font-size: 15px;
    line-height: var(--lh-body);
}

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

/* ───────────────────────────────────────────────────────────────────────────
   21. Topic cluster rows (#20) — split rows below the panes
   ─────────────────────────────────────────────────────────────────────────── */

.rg-clusterrow {
    padding: var(--space-lg) 0;
    border-top: 1px solid var(--rule);
}

.rg-clusterrow__header {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.rg-clusterrow__heading {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 21px;
    font-weight: 700;
    line-height: var(--lh-head);
}

.rg-clusterrow__more {
    flex: 0 0 auto;
    color: var(--accent);
    font-family: var(--font-ui);
    font-size: var(--size-meta);
    text-decoration: none;
}

.rg-clusterrow__split {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-lg);
}

.rg-clusterrow__half {
    min-width: 0;
}

/* THE LEAD IMAGE IS SIZED BY THE TEXT HALF, not by its own width (4.5.2 #20,
   REVISED 2026-09-19).

   The grid stretches both halves to the row's height, so the row is as tall as
   whichever half has more content. Previously the lead image carried
   `aspect-ratio: 4/3` against its own width — 497px at 1440 — while three rows of
   headlines came to roughly 310px, and the difference showed as white beside the
   text. Here the media instead FLEXES to absorb whatever height is left after the
   lead's own headline, deck and timestamp, so it ends level with the text half
   rather than dictating the row.

   These are the cluster's OWN classes rather than a modifier on
   .rg-feature__media, so the 4:3 ratio that governs every other feature image is
   left intact and nothing is overridden.

   min-height is the floor: with a very short text half the picture stops
   shrinking rather than becoming a strip. */
.rg-clusterrow__half--media {
    display: flex;
}

.rg-cluster {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: var(--space-sm);
    min-width: 0;
}

/* `flex-basis: 0`, not `auto`, and the picture is taken out of flow.

   With `flex: 1 1 auto` the media's base size is its CONTENT height — the image's
   intrinsic height at 100% width — so the picture still sized the box, just by its
   height instead of its width. Landscape sources hid it (663px wide at ratio 1.504
   is a 441px box) and PORTRAIT sources exposed it: at ratio 0.562 the same column
   gives a 1180px box, and the French clusters measured 1159-1343px tall with the
   gap beside them at 840-1343px — worse than the 4:3 ratio this replaced.

   `flex-basis: 0` means the media contributes NO intrinsic height, and absolute
   positioning stops the image pushing the box open. The text half then sets the
   row height for any aspect ratio, which is what the spec asks for. */
.rg-cluster__media {
    display: block;
    position: relative;
    flex: 1 1 0;
    min-height: 220px;
    overflow: hidden;
}

.rg-cluster__image {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ───────────────────────────────────────────────────────────────────────────
   22. Category page
   ─────────────────────────────────────────────────────────────────────────── */

.rg-cat__header {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-top: var(--space-sm);
}

.rg-cat__heading {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-display);
    font-weight: 700;
    line-height: var(--lh-tight);
}

/* ───────────────────────────────────────────────────────────────────────────
   23. Article variants (§8 unified geometry, register voice)
   ─────────────────────────────────────────────────────────────────────────── */

.rg-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. */
.rg-article__hero {
    margin: 0 0 var(--space-lg);
    width: 100%;
}

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

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

.rg-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. */
.rg-article__hero,
.rg-article-v3__hero {
    max-width: var(--max-width);
    margin-left: auto;
    margin-right: auto;
    padding: 0 var(--gutter);
}

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

.rg-article__header,
.rg-article-v2__header,
.rg-article-v3__header {
    max-width: var(--measure);
    margin: 0 auto var(--space-lg);
}

.rg-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.06em;
    text-transform: uppercase;
    text-decoration: none;
}

.rg-article__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: var(--size-h1);
    font-weight: 700;
    line-height: var(--lh-tight);
    overflow-wrap: break-word;
}

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

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

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

.rg-article__main,
.rg-article-v2__main,
.rg-article-v3__column {
    min-width: 0;
    max-width: var(--measure);
    margin: 0 auto;
}

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

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

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

.rg-article__body img {
    display: block;
    width: 100%;
    height: auto;
    margin: var(--space-md) 0;
}

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

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

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

.rg-article-v2__hero-image {
    display: block;
    width: 100%;
    height: auto;
}

/* The V2 rail is NOT sticky — same rule as the panes, for the same Phase 7c
   reason. */
.rg-article-v2__rail {
    min-width: 0;
}

.rg-article-v2__related {
    margin-top: var(--space-xl);
}

/* ───────────────────────────────────────────────────────────────────────────
   24. Shared partial classes on article and listing pages — §3.2 EXACT names,
   read from the partials themselves rather than assumed to be BEM.
   ─────────────────────────────────────────────────────────────────────────── */

.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: 3px solid var(--accent-soft);
}

.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: var(--size-h2);
    font-weight: 600;
    letter-spacing: 0.04em;
}

.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: 700;
}

.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-sm);
    background: var(--accent-tint);
    border: 1px solid var(--accent-soft);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 12px;
    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-sm);
    border: 1px solid var(--rule);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 12px;
    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);
}

.article-related,
.article-v3-related {
    margin-top: var(--space-xl);
    padding-top: var(--space-lg);
    border-top: 2px solid var(--accent);
}

.related-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-lg);
}

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

.article-card__image-link {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

.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.06em;
    text-transform: uppercase;
}

.article-card__title {
    margin: 0;
    font-family: var(--font-headline);
    font-size: 18px;
    font-weight: 500;
    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: 700;
}

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

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

.pagination-prev,
.pagination-next {
    padding: var(--space-xs) var(--space-md);
    border: 1px solid var(--rule);
    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-sm);
    background: var(--accent-tint);
    font-family: var(--font-ui);
    font-size: 12px;
}

/* ───────────────────────────────────────────────────────────────────────────
   25. 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 row collapses. ONE rule, not a copy of the
   macro's gate in every template.
   ─────────────────────────────────────────────────────────────────────────── */

.rg-row__thumb-link:empty,
.rg-feature__media:empty,
.rg-cluster__media:empty,
.rg-card__media:empty,
.rg-hero__media:empty,
.rg-photo__link:empty,
.rg-video__link:empty,
.rg-longread__media:empty,
.article-card__image-link:empty {
    background: var(--paper-deep);
    border: 1px solid var(--rule);
}

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

@media (min-width: 681px) {
    .related-grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .rg-clusterrow__split {
        grid-template-columns: 1fr 1fr;
    }
}

@media (min-width: 1025px) {
    /* THE TWO PANES — exactly 1fr each. Equal, never 60/40, never a rail. */
    .rg-split__inner {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-xl);
    }

    /* THE DIVIDING RULE IS DRAWN ON THE CONTAINER, not on a pane, so it spans
       the FULL HEIGHT of the taller pane. When one pane's data runs out first,
       its white space sits inside a ruled column instead of beside a rule that
       stopped early — the difference between reading as designed and reading as
       broken. */
    .rg-split::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 1px;
        background: var(--accent-soft);
    }

    /* V1's right rail and V2's left rail arrive at the same width the panes do. */
    .rg-article__grid {
        grid-template-columns: minmax(0, var(--measure)) 260px;
        justify-content: center;
    }

    .rg-article-v2__grid {
        grid-template-columns: 260px minmax(0, var(--measure));
        justify-content: center;
    }

    .rg-article__main,
    .rg-article-v2__main {
        margin: 0;
    }
}
