/** base.css — shared structural rules for all titles.
    Do not add @import or brand colours here.
    Override with a {title}-overrides.css file that redefines the variables below. **/


/** COLOR AND FONT VARIABLES — override in {title}-overrides.css **/

:root {
    /* Semantic text colors */
    --main-color:              #1a1a1a;
    --second-color:            #2e2e2e;
    --third-color:             #1a1a1a;
    --forth-color:             #777777;
    --boxout-color:            #f0f0f0;
    --main-color-dark:         #f0f0f0;
    --second-color-dark:       #e0e0e0;
    --third-color-dark:        #e0e0e0;
    --forth-color-dark:        #aaaaaa;
    --boxout-color-dark:       #1e1e1e;

    /* Brand accent — must be defined in the override file */
    --accent:                  #e5001c;
    --accent-dark:             #ff2d45;

    /* Boxout border colour follows accent unless overridden */
    --boxout-border-color:     var(--accent);
    --boxout-border-color-dark:var(--accent-dark);

    /* Font scale */
    --font-smallest:           13px;
    --font-small:              15px;
    --font-standard:           17px;
    --font-medium:             22px;
    --font-large:              26px;
    --font-x-large:            32px;
    --font-xx-large:           42px;

    /* Font weights */
    --font-weight-exlight:     200;
    --font-weight-light:       300;
    --font-weight-standard:    400;
    --font-weight-bold:        600;
    --font-weight-x-bold:      700;
    --font-weight-xx-bold:     900;

    /* Font families — default: Barlow / Barlow Condensed (FFT).
       Override in title file. The chosen fonts' @font-face are INLINED at the bottom of the
       override file (the reader's importer can't follow @import — see /* FONTS */ block there). */
    --font-family-main:         "Barlow", "Helvetica Neue", Arial, sans-serif;
    --font-family-secondary:    "Barlow", "Helvetica Neue", Arial, sans-serif;
    --font-family-condensed:    "Barlow Condensed", "Arial Narrow", sans-serif;
    --font-family-main-display: "Barlow Condensed", "Arial Narrow", sans-serif;

    /* Layout */
    --side-pad:                1.25rem;
    --link-color:              #000000;

    /* ── STANDFIRST — default: FFT colored pill ── */
    --standfirst-display:      inline-block;
    --standfirst-font:         var(--font-family-condensed);
    --standfirst-size:         var(--font-smallest);
    --standfirst-weight:       500;
    --standfirst-fg:           #fff;
    --standfirst-bg:           var(--accent);
    --standfirst-tracking:     0.14em;
    --standfirst-transform:    uppercase;
    --standfirst-padding:      4px 1.1rem;   /* ends must clear the 20px pill radius (CM 24-1) */
    --standfirst-radius:       20px;
    --standfirst-margin:       1rem 0 0.75rem var(--side-pad);

    /* ── HEADLINE — default: FFT condensed, no transform ── */
    --headline-weight:         var(--font-weight-x-bold);
    --headline-transform:      none;
    --headline-tracking:       -0.01em;
    --headline-line-height:    1.02;

    /* ── LEAD / DECK ── */
    --lead-font:               var(--font-family-main);
    --lead-weight:             var(--font-weight-standard);
    --lead-style:              normal;
    --lead-line-height:        1.4;
    --lead-color:              var(--second-color);

    /* ── PULL QUOTE — default: FFT condensed bold italic, left-aligned ── */
    --pull-quote-font:         var(--font-family-condensed);
    --pull-quote-weight:       var(--font-weight-xx-bold);
    --pull-quote-style:        italic;
    --pull-quote-color:        var(--accent-on-light, var(--accent));   /* luminance-safe on white */
    --pull-quote-align:        left;
    --pull-quote-padding:      1.25rem var(--side-pad);
    --pull-quote-margin:       1.75rem 0 1.5rem;
    --pull-quote-border-width: 2px;
    --pull-quote-border-color: var(--accent);

    /* ── DROPCAP ── */
    --dropcap-size:            4.4em;
    --dropcap-weight:          var(--font-weight-xx-bold);

    /* ── BOXOUT BORDER — default: top-only (FFT style) ── */
    --boxout-border:           0;
    --boxout-border-top:       3px solid var(--boxout-border-color);

    /* ── TOC SECTION HEADER — default: thin bottom rule + colored span bg (FFT) ── */
    --toc-section-border-bottom:  1px solid var(--main-color);
    --toc-section-border-pb:      0.6rem;
    --toc-section-span-display:   inline-block;
    --toc-section-span-font:      var(--font-family-condensed);
    --toc-section-span-size:      var(--font-small);
    --toc-section-span-weight:    var(--font-weight-x-bold);
    --toc-section-span-tracking:  0.2em;
    --toc-section-span-bg:        var(--accent);
    --toc-section-span-fg:        #fff;
    --toc-section-span-padding:   5px 12px 6px;

    /* ── TOC TYPOGRAPHY ── */
    --toc-title-font:          var(--font-family-condensed);
    --toc-title-weight:        var(--font-weight-x-bold);
    --toc-title-transform:     uppercase;
    --toc-title-tracking:      0;
    --toc-sell-font:           var(--font-family-main);
    --toc-sell-weight:         var(--font-weight-standard);
    --toc-sell-style:          normal;
    --toc-placeholder-bg:      #f2f2f2;
}


/** STANDARD SOURCE STYLING **/

.masthead   { display: none; }
.backtotop  { display: none; }
.ld_bold    { font-weight: 700; }
.ld_italic  { font-style: italic; }


/** MAGCLONER STYLING **/

.flexy { display: flex; flex-direction: column; }
.flexy > * { order: 2; }
.flexy .article-standfirst { order: 1; }

body.connect-mobile-edition { padding-top: 64px; padding-bottom: 64px; }
.flexy { margin: 0; padding: 0; padding-top: 64px; width: 100%; word-wrap: break-word;
         padding-bottom: 64px; margin-left: auto; margin-right: auto; box-sizing: border-box; }

a { color: var(--link-color); }

.article-standfirst .ld_bold  { font-weight: unset; }
.article-full-lead .ld_bold   { font-weight: var(--font-weight-x-bold); }
.articleImageCredit .ld_bold  { font-weight: var(--font-weight-standard); }
.article-full-byline .ld_bold { font-weight: var(--font-weight-bold); }
.article-full-subhead .ld_bold{ font-weight: var(--font-weight-standard); }
.article-full-lead .ld_italic { font-style: italic; }


/** HEADER STYLES **/

.article-standfirst {
    display: var(--standfirst-display);
    font-family: var(--standfirst-font);
    font-size: var(--standfirst-size);
    font-weight: var(--standfirst-weight);
    color: var(--standfirst-fg);
    background: var(--standfirst-bg);
    line-height: 1;
    letter-spacing: var(--standfirst-tracking);
    text-transform: var(--standfirst-transform);
    text-decoration: none;
    padding: var(--standfirst-padding);
    margin: var(--standfirst-margin);
    border-radius: var(--standfirst-radius);
    text-align: left;
}

.article-full-headline {
    font-family: var(--font-family-main-display);
    font-size: var(--font-xx-large);
    font-weight: var(--headline-weight);
    color: var(--third-color);
    line-height: var(--headline-line-height);
    letter-spacing: var(--headline-tracking);
    text-transform: var(--headline-transform);
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 0.875rem;
    text-align: left;
}

/* Headline typographic fidelity (phase-3c reads it from the print spans, tags the <h2>):
   .hl-caps  — the print headline is a SHORT all-caps display line → reproduce the caps (long caps
               "shout" on digital, so phase-3c only flags ≤25-char headlines).
   .hl-serif / .hl-sans — the print headline's FACE. A title can offer a serif AND a sans display
               variant (--headline-font-serif / --headline-font-sans); the var() fallback chain means
               a title that defines only one (or neither) falls back to its single display font, so
               this is a safe no-op until a title opts in. (WCM: most heads are serif/Playfair, but
               features like "The boy who broke cricket" are a chunky sans → --headline-font-sans.) */
.article-full-headline.hl-caps, .hero-headline.hl-caps { text-transform: uppercase; }
/* .hl-italic — the print headline is an ITALIC display line (TEG "This Month") → reproduce it.
   3c reads the face from the PDF font name, same as the subhead italic read. */
.article-full-headline.hl-italic, .hero-headline.hl-italic { font-style: italic; }
/* `.article-hero .hero-headline` (below) sets the hero font with specificity (0,2,0) AND is defined
   later, so the hero variants must out-specify it — qualify with `.article-hero` → (0,3,0). The
   non-scrim `.article-full-headline` is (0,1,0) so a single compound class already wins there. */
.article-full-headline.hl-serif,
.article-hero .hero-headline.hl-serif {
    font-family: var(--headline-font-serif, var(--font-family-main-display));
}
.article-full-headline.hl-sans,
.article-hero .hero-headline.hl-sans {
    font-family: var(--headline-font-sans, var(--font-family-main-display));
}

.article-full-lead {
    font-family: var(--lead-font);
    font-size: var(--font-medium);
    font-weight: var(--lead-weight);
    font-style: var(--lead-style);
    color: var(--lead-color);
    line-height: var(--lead-line-height);
    text-decoration: normal;
    padding: 0 var(--side-pad);
    margin: 0 0 1.25rem;
    text-align: left;
}

.article-full-subhead {
    font-family: var(--font-family-condensed);
    font-size: var(--font-medium);
    font-weight: var(--font-weight-x-bold);
    color: var(--second-color);
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: normal;
    padding: 0 var(--side-pad);
    margin: 0 0 0.875rem;
    text-align: left;
}

.article-full-byline {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    color: var(--forth-color);
    line-height: 1.3;
    letter-spacing: 0.04em;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 1.25rem;
    text-align: left;
}
.article-full-byline .ld_bold {
    color: var(--main-color);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}


/** STANDARD BODY STYLING **/

.article-full-body {
    font-family: var(--font-family-main);
    font-size: var(--font-standard);
    font-weight: var(--font-weight-standard);
    color: var(--main-color);
    line-height: 1.65;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 1.25rem;
    text-align: left;
}

.article-headline {
    font-family: var(--font-family-main-display);
    font-size: var(--font-x-large);
    font-weight: var(--font-weight-xx-bold);
    color: var(--main-color);
    line-height: 1.05;
    letter-spacing: -0.01em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 1.5rem 0 0.625rem;
    text-align: left;
}

.article-subhead {
    font-family: var(--font-family-condensed);
    font-size: var(--font-medium);
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
    line-height: 1.2;
    /* Render the sub-head's CAPTURED (printed) case — phase-3 captures exact case, so forcing
       uppercase was unfaithful (APM/WBG print sentence-case section heads). A title that genuinely
       wants caps can re-add it via its own override. */
    text-transform: none;
    letter-spacing: 0.04em;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 1.25rem 0 0.5rem;
    text-align: left;
}

.article-subsubhead {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
    line-height: 1.3;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 1.25rem 0 0.5rem;
    text-align: left;
}

.article-superheader {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
    line-height: 1.3;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 0.75rem;
    text-align: left;
}

.article-crosshead {
    font-family: var(--font-family-condensed);
    font-size: var(--font-large);
    font-weight: var(--font-weight-xx-bold);
    color: var(--main-color);
    line-height: 1.1;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 2rem 0 0.625rem;
    text-align: left;
}

.article-byline {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    color: var(--forth-color);
    line-height: 1.3;
    letter-spacing: 0.04em;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 0.625rem;
    text-align: left;
}

.article-body {
    font-family: var(--font-family-main);
    font-size: var(--font-standard);
    font-weight: var(--font-weight-standard);
    color: var(--main-color);
    line-height: 1.65;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 1.25rem;
    text-align: left;
}

.article-pull-quote {
    font-family: var(--pull-quote-font);
    font-size: var(--font-large);
    font-weight: var(--pull-quote-weight);
    font-style: var(--pull-quote-style);
    color: var(--pull-quote-color);
    line-height: 1.2;
    text-decoration: none;
    padding: var(--pull-quote-padding);
    margin: var(--pull-quote-margin);
    text-align: var(--pull-quote-align);
    border-top: var(--pull-quote-border-width) solid var(--pull-quote-border-color);
    border-bottom: var(--pull-quote-border-width) solid var(--pull-quote-border-color);
    overflow: hidden; /* BFC: prevents border lines from bleeding through adjacent floats */
}

/* Boxed pull-quote (phase-3 style="boxed"): by DEFAULT it renders the SAME as a clean pull-quote —
   NO accent block. The solid-block treatment (each line on an accent fill, FFT feature = red blocks)
   is an OPT-IN per title: a title that wants it adds the `.pull-quote-boxed` / `.pq-text` block rules
   in its own overrides file (see FourFourTwo-overrides.css). Most titles don't want a background, so
   boxed-follows-clean is the safe default (Patrick: "unless customised specifically, boxed should
   follow clean"). The `.pq-text` span phase-4 wraps the boxed text in is just inert inline text here,
   inheriting the clean pull-quote styling. */

/* Desktop/tablet: a left-aligned pull-quote leaves a big right-hand gap on a wide column, so CENTRE
   it (NOT justified — no edge-fill) and balance line lengths for even-ish rows. Mobile keeps the
   left alignment (--pull-quote-align) and full width. Applies to clean + boxed; auto side margins
   centre the block. *Triggered by:* FFT 392 Alex Scott (left-ragged boxed quote, lots of whitespace). */
@media (min-width: 640px) and (max-resolution: 2dppx) {
    .article-pull-quote {
        text-align: center;
        text-wrap: balance;          /* even-ish line lengths (graceful no-op where unsupported) */
        margin-left: auto;
        margin-right: auto;
    }
}

.article-pull-quote-credit {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-bold);
    color: var(--forth-color);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: -0.75rem 0 1.75rem;
    text-align: left;
}

.article-callout {
    font-family: var(--pull-quote-font);
    font-size: var(--font-large);
    font-weight: var(--pull-quote-weight);
    font-style: var(--pull-quote-style);
    color: var(--accent);
    line-height: 1.2;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0.5rem 0 1rem;
    text-align: left;
}


/** DROPCAP **/

.dropcap::first-letter {
    float: left;
    font-size: var(--dropcap-size);
    font-family: var(--font-family-main-display);
    font-weight: var(--dropcap-weight);
    line-height: 0.82;
    margin-right: 0.06em;
    margin-top: 0.08em;
    width: auto;
    font-style: normal !important;
    color: var(--accent);
    text-transform: uppercase;
}
.dropcap { text-indent: unset; }


/** IMAGE & VIDEO STYLING **/

.article-in-image {
    max-width: 100%;
    display: block;
    height: auto;
    padding: 0;
    margin: 1rem 0 0.5rem;
    text-align: center;
}
.article-in-image > img {
    max-width: 100%;
    height: auto;
    display: inline-block;
    margin: 0 0 0.5rem;
}

video[poster] { height: 100%; width: 100%; }
.article-in-video { display: block; margin-left: 5%; margin-right: 5%; text-align: center;
                    padding-bottom: 50%; width: 90%; margin-bottom: 10px; height: auto; position: relative; }
.article-in-video > iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; }

.articleImageCaption {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    color: var(--forth-color);
    line-height: 1.4;
    text-transform: none;
    padding: 0 var(--side-pad);
    margin: 0 0 1rem;
    text-align: left;
}
.articleImageCaption .ld_bold {
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.articleVideoCaption {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    color: var(--forth-color);
    line-height: 1.4;
    padding: 0 var(--side-pad);
    margin: 0 0 1rem;
    text-align: left;
}
.articleImageCredit {
    font-family: var(--font-family-condensed);
    font-size: var(--font-smallest);
    font-weight: var(--font-weight-standard);
    color: var(--forth-color);
    line-height: 1.2;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    padding: 0 var(--side-pad);
    margin: 0 0 0.75rem;
    text-align: right;
}


/** HERO IMAGES — pipeline additions **/

.article-hero-landscape,
.article-hero-portrait,
.article-hero-stitched {
    margin: 0 0 1.25rem;
}
.article-hero-landscape img,
.article-hero-portrait img,
.article-hero-stitched img {
    max-width: 100%;
    height: auto;
    display: block;
}
.article-hero-landscape img {
    max-height: 75vh;
    object-fit: cover;
    object-position: center top;
}
/* Narrow hero images: full-bleed container with grey fill; image centres within it.
   Flex is used rather than margin: 0 auto on the img because margin: auto on a replaced element
   doesn't reliably centre in all viewer contexts. flex-direction: COLUMN so a hero <img> + its
   <div class="articleImageCaption"> sibling STACK (image, then caption beneath) — the previous
   row layout pushed the caption off to the right, largely off-page (Boxing News 12-1/74-1 and
   others, cross-title). */
.article-hero-landscape { background: #f2f2f2; margin-left: calc(-1 * var(--side-pad)); margin-right: calc(-1 * var(--side-pad)); display: flex; flex-direction: column; align-items: center; }
.article-hero-landscape .articleImageCaption { align-self: stretch; text-align: center; margin-top: 0.5rem; }

/* ── Hero: single-DOM responsive scrim (Option 2, 2026-06-05) ──────────────────
   ONE copy of the title text + ONE image; CSS repositions the SAME nodes per
   breakpoint. No duplicate DOM, nothing hidden — so a reader that ignores the
   media queries (e.g. an epub editor) still shows the hero exactly once.
   DOM order is text-then-media. Mobile-first = scrim (dark block, image on top
   via flex order, white text below). Desktop (>=640) flips a plain --scrim hero
   to header-above-image, dark-on-light; --desktop keeps the scrim look on desktop
   too; --portrait lays a tall hero beside the text on desktop.

   ── DECISION TABLE (single source of truth, 2026-06-30) ──────────────────────
   The treatment is chosen by viewport width × DPR × hero-shape, partitioned with
   a SINGLE DPR boundary at 2.5dppx so the cells are gap-free AND non-overlapping
   (no half-apply possible across the light↔dark boundary):

     width < 640px (any DPR) ............... T0 base mobile scrim (dark, stacked)
     width ≥ 640 AND DPR < 2.5 ............. T1 desktop FLIP (light, dark-on-light)
       · plain → header-above-image
       · --portrait / --very-tall → image beside text (light, uncropped)
     DPR ≥ 2.5 (real phone OR in-app webview, which misreports width≈980):
       · orientation landscape ............ T2 side-by-side (dark, image right)
       · orientation portrait + --tall .... T3 top-anchored immersive (dark)
       · --very-tall (squarish+ viewport) . T4 side-by-side (dark)
       · orientation portrait + plain ..... T0 base scrim (dark, stacked)

   WHY DPR (not width) splits desktop from phone: the in-app webview reports a
   WIDE innerWidth (~980) at DPR 3 — DPR is the only reliable "really a phone"
   signal, so the flip's upper bound MUST stay below 2.5 or the webview wrongly
   flips to desktop. The 2.49/2.5 split closes the old DPR-2.0–2.5 gap (a Windows
   monitor at ~225% scaling fell through every query → base scrim black bars on a
   wide pane, RM 62/66/72). Self-containment is achieved by the non-overlapping
   partition — do NOT duplicate bg/text colours into T2/T3/T4: the dark treatments
   correctly inherit base white text + the v11 --panel-fg override; hardcoding
   colours there would break v11 white-panel heroes. */

.article-hero { margin: 0 calc(-1 * var(--side-pad)) 1.5rem; }

/* Base (mobile) = scrim. The panel colour is var(--panel-bg) with a #0a0a0a fallback, so a hero WITHOUT
   a captured panel renders exactly as before; phase-4 sets --panel-bg/--panel-fg + .article-hero--panel
   only when print supplies a colour (see _decide_hero_panel). */
.article-hero--scrim { display: flex; flex-direction: column; background: var(--panel-bg, #0a0a0a); }
.article-hero--scrim .article-hero__media { order: 1; position: relative; overflow: hidden; }
.article-hero--scrim .article-hero__media > img { width: 100%; display: block; height: auto;
                             max-height: 68vh; object-fit: cover; object-position: top; }
.article-hero--scrim .article-hero__media::after { content: ''; position: absolute; bottom: 0;
                             left: 0; right: 0; height: 44%; pointer-events: none;
                             background: linear-gradient(to bottom, transparent, var(--panel-bg, #0a0a0a)); }
.article-hero--scrim .article-hero__text { order: 2; background: var(--panel-bg, #0a0a0a); color: #fff;
                             padding: 8px calc(2 * var(--side-pad)) 28px; margin-top: -1px; }
/* coloured panel → HARD edge (no fade between a solid colour and the photo) */
.article-hero--scrim.article-hero--hard .article-hero__media::after { display: none; }
/* panel furniture text uses the luminance-correct panel fg (white panels need dark eyebrow/lead/byline) */
.article-hero--scrim.article-hero--panel .hero-eyebrow,
.article-hero--scrim.article-hero--panel .hero-lead,
.article-hero--scrim.article-hero--panel .hero-byline { color: var(--panel-fg, #fff); opacity: 1; }

.article-hero .hero-eyebrow { font-size: 10px; font-weight: 700; letter-spacing: 0.14em;
                             text-transform: uppercase; margin: 0 0 8px; opacity: 0.7;
                             font-family: var(--font-family-condensed); }
/* NO blanket text-transform:uppercase (Patrick, CM 56-1): case renders AS CAPTURED from print.
   A genuinely all-caps SHORT print headline still uppercases via .hl-caps (the 3c read); a LONG
   captured-caps headline is sentence-cased by phase-4 (caps that long is a print-font artefact
   that shouts on digital). */
.article-hero .hero-headline { font-family: var(--font-family-main-display); font-size: 2.6em;
                             font-weight: 700; line-height: 0.96; margin: 0 0 12px;
                             letter-spacing: -0.01em; }
.article-hero .hero-lead { font-family: var(--font-family-main); font-size: 1em; line-height: 1.5; margin: 0; }
.article-hero .hero-byline { font-family: var(--font-family-condensed); font-size: 11px;
                             font-weight: 400; margin: 8px 0 0; }
/* scrim mode → white text on the dark panel */
.article-hero--scrim .hero-eyebrow,
.article-hero--scrim .hero-headline,
.article-hero--scrim .hero-lead { color: #fff; }
.article-hero--scrim .hero-lead { opacity: 0.88; }
.article-hero--scrim .hero-byline { color: rgba(255,255,255,0.6); }

/* Desktop: a plain --scrim hero flips to header-above-image, dark-on-light.
   Upper bound is 2.49dppx (not 2dppx) so a Windows monitor at ~225% scaling
   (DPR 2.0–2.5, a wide DESKTOP pane) flips instead of falling into the old gap
   below the 2.5dppx phone treatments. Stays below 2.5 so the in-app webview
   (DPR 3, misreported width≈980) does NOT flip — it gets the phone treatments. */
@media (min-width: 640px) and (max-resolution: 2.49dppx) {
  .article-hero--scrim:not(.article-hero--desktop) { display: block; background: transparent; }
  .article-hero--scrim:not(.article-hero--desktop) .article-hero__text { background: transparent;
                             /* .article-hero is full-bleed (margin: 0 calc(-1*--side-pad)). The text
                                must re-inset by 2×--side-pad: one --side-pad cancels the negative
                                margin (back to the page edge), the second matches the BODY column's
                                --side-pad inset. With only 1×, the head block aligned to the page edge,
                                sitting one --side-pad LEFT of the body copy (NGK 48-1 headline; the
                                earlier FFT 14-1/30-1/31-1 fix stopped the clip but under-inset by one). */
                             padding: 0 calc(2 * var(--side-pad)); margin: 0 0 1rem; }
  /* On desktop a plain scrim hero flips to the SAME header-above-image, dark-on-light treatment as a
     non-scrim hero, so its head text must match the non-scrim sizes — the small scrim-overlay sizes
     (hero-lead 1em, hero-byline 11px) made the lead/byline look shrunken vs articles with a non-scrim
     hero (FFT 14-1). Mirror .article-full-lead (--font-medium) / .article-full-byline (--font-small)
     / .article-standfirst (--standfirst-size). Mobile keeps the compact overlay sizes (unchanged). */
  .article-hero--scrim:not(.article-hero--desktop) .hero-eyebrow { color: var(--accent-on-light, var(--accent)); opacity: 1; font-size: var(--standfirst-size); }
  .article-hero--scrim:not(.article-hero--desktop) .hero-headline { color: var(--main-color); }
  /* a DARK PANEL hero's per-word headline colours are light (set for the dark mobile panel) and would be
     illegible on the desktop flip's white header — revert those to the header colour. A LIGHT panel
     (--panel-light) keeps its captured colours: they're contrast-checked as legible on white by phase-3c,
     so the flip (dark-on-white) shows them faithfully (38-1 green #426a59, 84-1 blue #006b92). */
  .article-hero--scrim.article-hero--panel:not(.article-hero--panel-light):not(.article-hero--desktop) .hero-headline .hl-run { color: var(--main-color) !important; }
  .article-hero--scrim:not(.article-hero--desktop) .hero-lead { color: var(--second-color); opacity: 1; font-size: var(--font-medium); line-height: 1.4; }
  .article-hero--scrim:not(.article-hero--desktop) .hero-byline { color: var(--third-color); font-size: var(--font-small); }
  .article-hero--scrim:not(.article-hero--desktop) .article-hero__media { background: #f2f2f2;
                             display: flex; justify-content: center; }
  .article-hero--scrim:not(.article-hero--desktop) .article-hero__media::after { display: none; }
  .article-hero--scrim:not(.article-hero--desktop) .article-hero__media > img { max-height: 70vh; object-fit: contain; }

  /* Portrait hero on desktop: image beside the text (text left, image right). The head block is
     vertically CENTRED beside the image (align-items:center) so a short head doesn't sit at the top
     with a big empty gap below it next to a tall image (RM 72-1: head ~223px vs a 691px very-tall
     image left ~468px of white). The float image is also capped (max-height below) so a very-tall
     image can't tower into an overkill hero. */
  .article-hero--scrim.article-hero--portrait:not(.article-hero--desktop) { display: flex;
                             flex-direction: row; gap: 20px; align-items: center; }
  .article-hero--scrim.article-hero--portrait:not(.article-hero--desktop) .article-hero__text { order: 1; flex: 1; }
  .article-hero--scrim.article-hero--portrait:not(.article-hero--desktop) .article-hero__media { order: 2;
                             flex: 0 0 42%; max-width: 42%; margin: 0; background: transparent; }
  /* cap a portrait/very-tall float image so it doesn't dominate the column (overrides the plain-flip 70vh) */
  .article-hero--scrim.article-hero--portrait:not(.article-hero--desktop) .article-hero__media > img { max-height: 56vh; }
}

/* LANDSCAPE PHONE scrim hero: a short, wide viewport can't fit the stacked image-over-text scrim, so
   lay it SIDE-BY-SIDE — the image FILLS the hero (cover) and the title sits over a scrim that fades in
   from the LEFT edge (the mobile bottom-fade rotated 90°). Targets landscape + high DPR, so desktop
   (DPR<=2, incl. landscape tablet) and portrait phones are untouched. CSS-only; reuses the single-DOM
   nodes. Tunables: text side (left), object-position (center — lean 'right center' if the subject sits
   left), and the scrim width/stops. NOTE: needs the dev to serve our CSS, and it renders zoomed until
   the app's viewport is fixed (the LAYOUT is already correct). */
/* + short-landscape alternative (<=500px tall = a phone on its side at any DPR). */
@media (orientation: landscape) and (min-resolution: 2.5dppx), (orientation: landscape) and (max-height: 500px) {
  /* Side-by-side: the FULL portrait image hugs the RIGHT EDGE (shown UNCROPPED, object-fit: contain), and
     the text panel GROWS to fill everything to its left, with a soft scrim fading into the image's LEFT
     edge WHEREVER it falls. So there's never a black gap to the right of the image, nor a hard black line
     on both sides (the old centred-in-60% layout left a big black band on the right). No crop ⇒ subject
     never cut. min-height (not fixed) so a LONG headline/lead GROWS the hero instead of clipping (FFT 44). */
  .article-hero--scrim { display: flex; flex-direction: row; align-items: stretch; min-height: 72vh;
                             overflow: hidden; background: var(--panel-bg, #0a0a0a); }
  /* text panel GROWS to fill the space left of the image (flex:1), so the image sits flush right. */
  .article-hero--scrim .article-hero__text { order: 0; flex: 1 1 0; min-width: 0;
                             background: var(--panel-bg, #0a0a0a); margin: 0; z-index: 1;
                             display: flex; flex-direction: column; justify-content: center;
                             padding: 28px var(--side-pad) 28px calc(2 * var(--side-pad)); }
  /* media SHRINKS to the image (flex:0 1 auto + img height:72vh ⇒ the box width == the image width), so
     the box's LEFT edge IS the image's left edge ⇒ the fade always meets it. Capped at 65% so a wide
     landscape image can't crowd out the text. height:72vh ≈ the app's usable landscape height (dev Q F). */
  .article-hero--scrim .article-hero__media { order: 1; flex: 0 1 auto; min-width: 0; max-width: 65%;
                             position: relative; overflow: hidden; display: flex;
                             align-items: center; justify-content: flex-end; }
  .article-hero--scrim .article-hero__media > img { width: auto; max-width: 100%; height: 72vh;
                             max-height: 72vh; object-fit: contain; object-position: right center; display: block; }
  /* scrim fade: a FIXED-WIDTH dark edge at the image's LEFT → transparent (box-left == image-left here). */
  .article-hero--scrim .article-hero__media::after { content: ''; position: absolute; inset: 0 auto 0 0;
                             width: 90px; height: auto;
                             background: linear-gradient(to right, var(--panel-bg, #0a0a0a), transparent); }
  .article-hero--scrim .hero-headline { font-size: 2.2em; }   /* a touch smaller so it fits the short height */
  /* Contributor headshot: keep it OUT of the LANDSCAPE side-by-side scrim only. In this short, narrow
     side-by-side head column a head-shot floats awkwardly at the text/image fade boundary (RM 62-1).
     On the PORTRAIT scrims (text-at-top --tall / text-at-bottom base) the head block is full-width on
     the panel and the head-shot sits fine beside the headline, so it's left alone there — and the
     desktop flip keeps it too. Hiding (not relocating) because the hero is one responsive DOM. */
  .article-hero--scrim .header-headshot { display: none; }
}

/* PORTRAIT PHONE, TALL hero (h/w ≥ 1.2, set by phase4 as .article-hero--tall): top-anchored IMMERSIVE
   scrim — a solid black text area at the top, then the image STARTS where the black ends (its top/face
   is never hidden behind the black), with a soft scrim fading the join. Gated to portrait orientation +
   high DPR, so it never clashes with the desktop flip (DPR≤2) or the landscape side-by-side (orientation
   landscape). A square/landscape hero is NOT --tall, so it keeps the text-below scrim (variety + the
   bottom-nav overlap only happens with tall images that push text to the very bottom). */
/* + narrow-portrait alternative: a portrait viewport <=639px wide is a PHONE SHAPE regardless of
   DPR — budget Androids report devicePixelRatio 2.0 and were falling through to the base scrim
   (Patrick, TEG web-reader test at DPR 2.0). A desktop pane is never narrow-portrait, so the
   Windows-scaling (DPR 2.0-2.49, WIDE window) collision this floor guards against stays excluded. */
@media (orientation: portrait) and (min-resolution: 2.5dppx), (orientation: portrait) and (max-width: 639px) {
  /* Hero grows to fit the WHOLE image — text on top, image at its natural height below. NO
     max-height:100vh / overflow:hidden cap: that squeezed a very-tall image (RM 72-1, 824×1400, h/w 1.70)
     into the leftover space and CLIPPED its bottom — it could never show in full. The user scrolls
     through a tall image; nothing is cropped. */
  .article-hero--scrim.article-hero--tall { display: flex; flex-direction: column;
                             background: var(--panel-bg, #0a0a0a); }
  .article-hero--scrim.article-hero--tall .article-hero__text { order: 0; position: relative; z-index: 2;
                             background: var(--panel-bg, #0a0a0a); margin: 0;
                             /* 28px = the app's measured top gap on portrait (landscape's is 40px → ~12px
                                tighter there, acceptable). Adjust if the app changes its chrome inset. */
                             padding: 28px calc(2 * var(--side-pad)) 14px; }
  .article-hero--scrim.article-hero--tall .article-hero__media { order: 1; position: relative; }
  .article-hero--scrim.article-hero--tall .article-hero__media > img { width: 100%; height: auto;
                             max-height: none; object-fit: contain; display: block; }
  /* the image fades IN from the black above (top edge) — overrides the base bottom-fade ::after */
  .article-hero--scrim.article-hero--tall .article-hero__media::after { content: ''; position: absolute;
                             top: 0; left: 0; right: 0; bottom: auto; height: 72px;
                             background: linear-gradient(to bottom, var(--panel-bg, #0a0a0a) 0%, transparent 100%); }
}

/* VERY TALL + THIN hero (phase4 `.article-hero--very-tall`, h/w ≥ VERY_TALL_HW 1.4) → SIDE-BY-SIDE
   (text scrim left, image contained right) so the tall image shows in full instead of being cropped.
   GATED to HIGH-DPR (min-resolution > 2) so it's a PHONE-LANDSCAPE treatment ONLY: on the LOW-DPR
   desktop/tablet/web-reader branch the established desktop flip's `--portrait` sub-rule already lays a
   portrait hero beside the text (light, no crop), so applying this dark side-by-side there fought the
   flip — black panel (this rule) + dark-on-light text (the flip) = illegible (RM 72-1), plus the
   headshot+image both floated right (66-1). High-DPR-only defers desktop to the flip and keeps the
   immersive dark side-by-side for phone landscape. Aspect gate excludes a tall portrait phone (keeps the
   stacked immersive scrim). 3-class selector beats the base scrim; image hugs the right, fade meets its left.
   DPR floor is 2.5 (was 2.01) so it aligns with the other phone gates: in band L (DPR < 2.5) a very-tall
   hero defers to the flip's --portrait sub-rule (light, image-beside-text, uncropped) — matching this
   rule's documented "phone-only, defer desktop to the flip" intent and leaving NO overlap with the flip
   (the overlap was the 72-1 black-bg+dark-text half-apply). */
@media (min-aspect-ratio: 3/5) and (min-resolution: 2.5dppx), (min-aspect-ratio: 3/5) and (max-height: 500px) {
  /* No forced min-height: the IMAGE drives the hero height (it's the tallest item), so the panel ends
     exactly where the image does — no letterbox. The image is its natural size, capped at 80vh tall and
     60% wide (so the text always has room on the left). */
  .article-hero--scrim.article-hero--portrait.article-hero--very-tall {
                             display: flex; flex-direction: row; align-items: stretch;
                             overflow: hidden; background: var(--panel-bg, #0a0a0a); }
  .article-hero--scrim.article-hero--portrait.article-hero--very-tall .article-hero__text {
                             order: 0; flex: 1 1 0; min-width: 0; background: var(--panel-bg, #0a0a0a);
                             margin: 0; z-index: 1; display: flex; flex-direction: column;
                             justify-content: center; padding: 28px var(--side-pad) 28px calc(2 * var(--side-pad)); }
  .article-hero--scrim.article-hero--portrait.article-hero--very-tall .article-hero__media {
                             order: 1; flex: 0 1 auto; min-width: 0; max-width: 60%; position: relative;
                             overflow: hidden; display: flex; align-items: center; justify-content: flex-end; }
  .article-hero--scrim.article-hero--portrait.article-hero--very-tall .article-hero__media > img {
                             width: auto; max-width: 100%; height: auto; max-height: 80vh;
                             object-fit: contain; object-position: right center; display: block; }
  /* :not(--hard) → a coloured panel (96-1) keeps its HARD vertical edge (the --hard display:none rule wins);
     other panels get a soft fade from the panel colour into the image's left edge. */
  .article-hero--scrim.article-hero--portrait.article-hero--very-tall:not(.article-hero--hard) .article-hero__media::after {
                             content: ''; position: absolute; inset: 0 auto 0 0; width: 90px; height: auto;
                             background: linear-gradient(to right, var(--panel-bg, #0a0a0a), transparent); }
}

/* Tag styling retained for the (separate, currently-unused) spread-hero path. */
.hero-top-tags { position: absolute; top: 14px; left: calc(2 * var(--side-pad)); right: calc(2 * var(--side-pad)); z-index: 1; display: flex; }
.hero-tag { background: var(--accent); color: #fff; font-size: 10px; font-weight: 700;
            padding: 4px 10px; letter-spacing: 0.1em; text-transform: uppercase;
            font-family: var(--font-family-condensed); }

/* Portrait float hero — tall image right, text left */
.article-hero-portrait-float { display: flex; flex-direction: row; gap: 20px;
                                margin-bottom: 1.5rem; align-items: flex-start; }
.portrait-float-img { flex: 0 0 42%; max-width: 42%; }
.portrait-float-img img { width: 100%; height: auto; display: block; }
.portrait-float-text { flex: 1; padding: 4px 0; }

/* Spread / stitched hero */
.article-spread-hero { margin: -64px -1.5rem 0; }
.spread-hero-img-wrap { position: relative; overflow: hidden; background: #0a0a0a; }
.spread-hero-img-wrap img { width: 100%; display: block; max-height: 52vw;
                             object-fit: cover; object-position: center; }
.spread-hero-img-wrap .hero-top-tags { position: absolute; top: 14px; left: 14px; }
.spread-hero-text { padding: 20px 1.5rem 0; }


/** INLINE IMAGE SHAPES **/

.article-in-image.shape-circle { display: flex; flex-direction: column; align-items: center; }
.article-in-image.shape-circle img { border-radius: 50%; width: 180px; height: 180px; object-fit: cover; }
.article-in-image.shape-rounded img { border-radius: 12px; }
.article-in-image.portrait-float { float: right; max-width: 38%; margin: 4px 0 16px 14px;
                                    clear: right; }
.article-in-image.portrait-float img { display: block; max-height: 380px;
                                        width: auto; max-width: 100%; height: auto;
                                        margin: 0 auto; }

.article-in-image.contained { float: right; width: 44%; margin: 4px 0 16px 14px; clear: right; }
.article-in-image.contained img { width: 100%; height: auto; }
.article-in-image.inline-float-right { float: right; max-width: min(44%, 400px); margin: 4px 0 16px 14px; clear: right; }
.article-in-image.inline-float-right img { display: block; width: auto; max-width: 100%; height: auto;
                                           max-height: 380px; object-fit: contain; margin: 0 auto; }

/* Lone float at end of article: center instead of hanging right */
.article-in-image.portrait-float:last-child,
.article-in-image.contained:last-child,
.article-in-image.inline-float-right:last-child { float: none; width: 50%; margin: 16px auto; display: block; }

/* A contributor byline headshot floats LEFT (beside its byline), on the OPPOSITE side from a
   right-floating lead image, so the two don't stack vertically and drop the headshot away from the
   name (WCM 23-1: the trophy lead-float pushed Ben Gardner's headshot below his byline). Its left
   edge aligns with the body text (margin-left = --side-pad). The headshot shows in its NATURAL shape
   (square photos render square) — overriding shape-circle's forced 50% crop, which the AI's
   display_shape often gets wrong (WCM 23-1's are clearly square in print). Overrides portrait-float. */
.article-in-image.contributor-byline-float {
    float: left; clear: left;
    width: auto; max-width: 88px; margin: 2px 14px 6px var(--side-pad);
}
.article-in-image.contributor-byline-float img {
    width: auto; height: auto; max-width: 88px; max-height: 88px;
    border-radius: 4px; object-fit: contain;   /* natural shape, not a forced circle */
}
.article-in-image.contributor-byline-float:last-child {
    float: left; width: auto; margin: 2px 14px 6px var(--side-pad);
}

/* Photo-feature card: an Image_Asset carrying a substantial attached panel (nested Boxout or
   rich caption). The image goes full-width (never floated) and the panel renders as a readable
   block beneath. Portrait images are height-capped (max-height) so they don't fill the screen. */
.article-feature-card { clear: both; width: 100%; margin: 20px 0; }
.article-feature-card img { display: block; width: auto; max-width: 100%; height: auto;
                            max-height: 70vh; margin: 0 auto; }
.article-image-feature { border-top: 3px solid var(--accent, #333); background: #f6f6f6;
                         padding: 14px 18px 16px; font-family: var(--font-family-main); }
.article-image-feature .feature-heading { font-family: var(--font-family-main-display, var(--font-family-main));
                                          color: var(--accent-on-light, var(--accent, #1a1a1a)); font-weight: 700;
                                          font-size: 1.15rem; line-height: 1.15; margin: 0 0 8px;
                                          text-transform: uppercase; letter-spacing: .02em; }
.article-image-feature .feature-body { margin: 0 0 8px; line-height: 1.5; }
.article-image-feature .feature-body:last-of-type { margin-bottom: 0; }
.article-image-feature .feature-credit { font-style: italic; font-size: 0.8rem; color: #777;
                                         margin: 8px 0 0; }
/* Portrait image-led feature: a tall image leaves horizontal room, so on desktop place the panel
   BESIDE it (image left, text right) — matches the print layout (e.g. FFT 'Pin badge heaven').
   Mobile keeps the default stacked image-over-text. Only the accent rule moves from top to left. */
@media (min-width: 640px) and (max-resolution: 2dppx) {
  .article-feature-card.portrait { display: flex; flex-direction: row; gap: 0; align-items: stretch; }
  .article-feature-card.portrait > img { max-width: 45%; max-height: 80vh; margin: 0; flex: 0 0 auto; }
  .article-feature-card.portrait .article-image-feature { flex: 1 1 0; }   /* keeps the accent top-rule, sits flush against the image */
}

/* Lone image at a page break (set by phase4 _handle_page_break_images): centred block, never
   floated — stops an end-of-page image wrapping the next page's unrelated text. */
.article-in-image.page-centered { float: none; clear: both; width: auto; max-width: 60%;
                                  margin: 16px auto; display: block; }
.article-in-image.page-centered img { display: block; width: auto; max-width: 100%; height: auto;
                                      max-height: 60vh; margin: 0 auto; }


/* Solo: lonely float demoted to centred block by phase4 post-processing */
.article-in-image.solo {
    float: none; clear: both; display: block; width: fit-content; max-width: 65%; margin: 16px auto;
}
/* Tall-image ceiling (Patrick, 2026-07-13): no inline image runs taller than ~two-thirds of the
   viewport — a tall portrait SHRINKS (width narrows, centred in the column) instead of becoming an
   endless scroll. width:auto is essential: the old width:100% + max-height pair DISTORTS a portrait
   once the cap bites. Self-gating — images under the ceiling render exactly as before. */
.article-in-image.solo img { display: block; width: auto; max-width: 100%; height: auto;
    max-height: 66vh; margin-left: auto; margin-right: auto; }
.gallery-viewer.gallery-inset .article-in-image img { max-height: 62vh; }

/* Boxout images: float right within the boxout; overflow:hidden on boxout creates BFC to contain float */
.article-boxout .article-in-image.portrait-float {
    float: right; max-width: 42%; margin: 4px 0 8px 12px; clear: right;
}
.article-boxout .article-in-image.portrait-float img {
    display: block; max-height: 220px; width: auto; max-width: 100%; height: auto; margin: 0 auto;
}
.article-boxout .article-in-image.contained {
    float: right; max-width: 44%; margin: 4px 0 8px 12px; clear: right;
}
.article-boxout .article-in-image.contained img {
    display: block; max-height: 220px; width: auto; max-width: 100%; height: auto; margin: 0 auto;
}
.article-boxout .article-in-image.inline-float-right {
    float: right; max-width: min(44%, 300px); margin: 4px 0 8px 12px; clear: right;
}
.article-boxout .article-in-image.inline-float-right img {
    display: block; max-height: 220px; width: 100%; height: auto;
}
/* Lone image at bottom of boxout: centre instead of hanging right */
.article-boxout .article-in-image.portrait-float:last-child,
.article-boxout .article-in-image.contained:last-child,
.article-boxout .article-in-image.inline-float-right:last-child {
    float: none; width: 55%; margin: 8px auto; display: block; clear: both;
}
.article-boxout .article-in-image.portrait-float:last-child img,
.article-boxout .article-in-image.contained:last-child img,
.article-boxout .article-in-image.inline-float-right:last-child img {
    width: 100%; height: auto; max-height: 220px;
}
/* Boxout with table + image: CSS Grid so image + caption align top with subhead/table.
   minmax(0, 1fr) lets the table column shrink below content min-width so the image
   column (min 80px) is never crowded out by a wide multi-column table. */
.article-boxout:has(table):has(.article-in-image) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(80px, 35%);
    column-gap: 12px;
    align-items: start;
}
.article-boxout:has(table):has(.article-in-image) .article-in-image.portrait-float,
.article-boxout:has(table):has(.article-in-image) .article-in-image.contained,
.article-boxout:has(table):has(.article-in-image) .article-in-image.inline-float-right {
    float: none; clear: none; margin: 0; width: 100%; max-width: 100%;
    grid-column: 2; grid-row: 1 / span 10;
}
.article-boxout:has(table):has(.article-in-image) .article-in-image.portrait-float img,
.article-boxout:has(table):has(.article-in-image) .article-in-image.contained img,
.article-boxout:has(table):has(.article-in-image) .article-in-image.inline-float-right img {
    display: block; width: auto; max-width: 100%; max-height: 220px; height: auto; margin: 0 auto;
}
/* WIDE table (phase-4 `boxout-wide-table`, ≥6 cols): side-by-side would overflow the grid column and
   overlap the image (WCM 64-1), so STACK — table full-width, image centred BELOW it. The extra class
   out-specifies the grid rule above ((0,3,1) > (0,2,1)). Narrow table+image boxouts keep side-by-side. */
.article-boxout.boxout-wide-table:has(table):has(.article-in-image) { display: block; }
.article-boxout.boxout-wide-table:has(table):has(.article-in-image) .article-in-image {
    grid-column: auto; grid-row: auto; float: none; clear: both;
    width: 100%; max-width: 100%; margin: 14px auto 0;
}
.article-boxout.boxout-wide-table:has(table):has(.article-in-image) .article-in-image img {
    max-height: 320px; margin: 0 auto;
}


/** CAROUSEL — multi-image gallery **/

/* Explicit gallery container — phase 4 wraps gallery runs in .gallery-viewer (decision in the
   markup). carousel.js upgrades it to .img-carousel (the full arrow carousel) in browser / web-reader
   / QA. Where that JS can't run (the in-app webview strips injected DOM + leaves .style undefined,
   so carousel.js restore-on-strip removes .img-carousel) this :not(.img-carousel) state IS the
   gallery: a one-image-per-frame swipeable snap strip. Everything below is scoped to that fallback
   state, so it is a provable no-op once the JS carousel takes over. */
.gallery-viewer:not(.img-carousel) { display: flex; overflow-x: auto; gap: 8px;
    scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; clear: both;
    align-items: stretch; /* slides share the tallest height so a short image centres in a grey frame */
    touch-action: pan-x pan-y;   /* horizontal swipe drives the gallery; vertical still scrolls the PAGE */
    overscroll-behavior-x: auto; /* at the LAST image a further horizontal swipe chains to the reader's
                                    page-turn (so you can't get stuck); the snap keeps mid-gallery swipes here */
    margin: 1.25rem calc(-1 * var(--side-pad)); padding: 0 var(--side-pad); }
/* PEEKING slides (88%, centre-snapped): the neighbouring image visibly pokes in at the edge — the
   strongest "there's more, swipe" signpost (standard carousels bury content; <1% click-through).
   Each slide is a grey frame that vertically centres its image, so a short image leaves no white
   gap below it. Fallback only — the JS .carousel-slide centres on its own dark box. */
.gallery-viewer:not(.img-carousel) > .article-in-image { flex: 0 0 88%; scroll-snap-align: center;
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    background: #f1f1f1; border-radius: 2px;
    float: none !important; width: auto !important; height: auto !important; margin: 0 !important;
    aspect-ratio: unset !important; }
.gallery-viewer:not(.img-carousel) > .article-in-image img { width: auto; max-width: 100%; height: auto;
    display: block; max-height: 60vh; object-fit: contain; }
/* Dot indicator — a markup sibling (<div class="gallery-dots">) emitted by phase4, so it survives the
   in-app reader's DOM stripping (a JS-built one would be stripped). carousel.js highlights the current
   dot on scroll where it can; if that doesn't run, the dots still show the image COUNT. Hidden when the
   JS carousel enhances (it builds its own dots) and on desktop (galleries enhance or float there). */
.gallery-dots { display: flex; justify-content: center; gap: 6px; margin: 8px 0 4px; }
.gallery-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(0,0,0,0.22);
    flex: 0 0 auto; transition: background 0.2s; }
.gallery-dot.active { background: var(--accent, #555); }
.img-carousel + .gallery-dots, .feature-carousel + .gallery-dots { display: none; }
/* Swipe affordance beside the dots (fallback strip only — the JS carousel has arrows). */
.gallery-viewer:not(.img-carousel) + .gallery-dots::after { content: "\276F"; font-size: 10px;
    color: var(--accent-on-light, #888); margin-left: 5px; line-height: 1; opacity: .8;
    align-self: center; }
@media (min-width: 640px) and (max-resolution: 2dppx) { .gallery-dots { display: none; } }

/* MINI-GRID (Stage-2 inline anchoring): 2–3 page-anchored images at one stop render as a compact
   grid — every photo visible with its page's text, no swiping. Text-width, rounded cells; the
   third image spans the full row. */
.article-mini-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
    margin: 1.1rem var(--side-pad); clear: both; }
.article-mini-grid .mini-grid-cell { display: flex; flex-direction: column; position: relative; }
/* Subtle tap-to-enlarge chip (carousel.js adds it to each grid's FIRST cell only). */
.mg-zoom-hint { position: absolute; top: 6px; left: 6px; width: 24px; height: 24px;
    display: flex; align-items: center; justify-content: center; border-radius: 50%;
    background: rgba(0,0,0,0.38); color: rgba(255,255,255,0.9); pointer-events: none; }
.article-mini-grid .mini-grid-cell img { width: 100%; height: 150px; object-fit: cover;
    border-radius: 7px; display: block; }
.article-mini-grid .mini-grid-cell:nth-child(odd):last-child { grid-column: 1 / -1; }
.article-mini-grid .mini-grid-cell:nth-child(odd):last-child img { height: 210px; }
/* Cells are UNIFORM height (mixed shapes ragged the grid); each image's crop window sits on its
   subject via the phase-4 focal object-position, and the tap-to-open lightbox shows the full
   uncropped image. */
.article-mini-grid .articleImageCaption { font-size: 11px; opacity: .75; padding: 3px 2px 0;
    text-align: left; }
.article-mini-grid .mini-grid-cell img { cursor: pointer; }
@media (min-width: 640px) and (max-resolution: 2.49dppx) {
    .article-mini-grid .mini-grid-cell img { height: 220px; }
    .article-mini-grid .mini-grid-cell:nth-child(odd):last-child img { height: 280px; }
}

/* Lightbox (carousel.js enhancement on mini-grid cells): fullscreen dark overlay, the FULL
   uncropped image contained, caption below, tap anywhere / × to close, ‹ › within the grid.
   Enhancement-only — where JS doesn't run the grid stays a static (still complete) layout. */
.mg-lightbox { position: fixed; inset: 0; z-index: 99998; background: rgba(8,8,10,.93);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 4vh 4vw; }
.mg-lightbox img { max-width: 92vw; max-height: 78vh; width: auto; height: auto;
    object-fit: contain; border-radius: 6px; }
.mg-lightbox .mg-cap { color: #ddd; font-size: 13px; margin-top: 10px; max-width: 80ch;
    text-align: center; }
.mg-lightbox .mg-x { position: absolute; top: 14px; right: 18px; color: #fff; font-size: 26px;
    background: none; border: none; cursor: pointer; line-height: 1; }
.mg-lightbox .mg-prev, .mg-lightbox .mg-next { position: absolute; top: 50%;
    transform: translateY(-50%); color: #fff; font-size: 30px; background: rgba(255,255,255,.12);
    border: none; border-radius: 50%; width: 44px; height: 44px; cursor: pointer; }
.mg-lightbox .mg-prev { left: 10px; }
.mg-lightbox .mg-next { right: 10px; }

/* INSET gallery (scrim → inset; Patrick, image-led-titles design 2026-07-13): the image run after an
   immersive scrim renders TEXT-WIDTH with side padding instead of full-bleed — the BBC-Sport-style
   framed image that breaks the "scrim then endless full-bleed image" wall. The class stays on the
   container through JS enhancement, so it constrains the fallback strip AND the arrow carousel. */
.gallery-viewer.gallery-inset { margin-left: var(--side-pad) !important;
    margin-right: var(--side-pad) !important;
    padding-left: 0 !important; padding-right: 0 !important; border-radius: 6px; }

/* Float gallery (phase 4 marks a 2–3 image run with text around it as .gallery-float). On DESKTOP
   the wrapper becomes display:contents so its float children rejoin the article flow and the body
   copy wraps beside them; each image floats right and clears the previous (a tidy right column).
   On mobile it stays a plain .gallery-viewer (scroll-snap strip / carousel — carousel.js skips
   .gallery-float on desktop, see carousel.js). Selectors match the DOM tree, so the child combinator
   still works under display:contents. */
@media (min-width: 640px) and (max-resolution: 2dppx) {
    .gallery-viewer.gallery-float { display: contents; }
    /* !important to beat the .gallery-viewer:not(.img-carousel) scroll-snap fallback (which forces
       float:none !important on gallery children at all widths) — on desktop these float instead. */
    .gallery-viewer.gallery-float > .article-in-image { float: right !important; clear: right !important;
        width: 38% !important; max-width: 38% !important; margin: 4px 0 16px 18px !important;
        aspect-ratio: unset !important;
        /* undo the mobile fallback's grey centred frame — on desktop these are plain floated images */
        display: block !important; background: transparent !important; border-radius: 0 !important; }
    .gallery-viewer.gallery-float > .article-in-image img { width: 100% !important; height: auto !important;
        display: block !important; max-height: 60vh !important; object-fit: contain !important; }
}

.img-carousel { margin: 1.25rem 0; overflow: hidden; clear: both; min-height: 200px; }
.carousel-img-wrap { position: relative; }
.carousel-track { display: flex; transition: transform 0.3s ease; }
.carousel-slide { flex: 0 0 100%; min-width: 0; background: #111; min-height: 200px;
                  display: flex; align-items: center; justify-content: center; }
.carousel-slide img { width: auto; max-width: 100%; max-height: 52vh; height: auto;
                      display: block; margin: 0 auto; }
.img-carousel .article-in-image { float: none !important; width: 100% !important;
                                   height: auto !important; margin: 0 !important;
                                   aspect-ratio: unset !important; overflow: visible !important; }
.img-carousel .article-in-image img { width: auto !important; max-width: 100% !important;
                                   height: auto !important; max-height: 52vh !important;
                                   object-fit: unset !important; display: block !important;
                                   margin: 0 auto !important; }
/* The enhanced carousel shows each slide's caption in its OWN bottom bar (.carousel-caption), so hide
   the in-slide .articleImageCaption — otherwise the caption rendered TWICE (once on the photo, once in
   the bar). Scoped to .img-carousel, so the JS-off scroll-snap fallback (no bar) still shows it. */
.img-carousel .carousel-slide .articleImageCaption { display: none; }
.carousel-scrim { position: absolute; bottom: 0; left: 0; right: 0;
                  background: linear-gradient(transparent, rgba(0,0,0,0.82) 60%, rgba(0,0,0,0.88));
                  padding: 36px 12px 9px; }
.carousel-caption { font-family: var(--font-family-condensed); font-size: 11px;
                    color: rgba(255,255,255,0.82); text-align: center; margin: 0 0 7px; line-height: 1.4; }
.carousel-ui { display: flex; align-items: center; justify-content: space-between; }
.carousel-btn { background: none; border: 1.5px solid rgba(255,255,255,0.45); border-radius: 50%;
                width: 28px; height: 28px; font-size: 18px; cursor: pointer; color: #fff;
                display: flex; align-items: center; justify-content: center;
                padding: 0 0 2px; line-height: 1; flex-shrink: 0; }
.carousel-btn:hover { background: rgba(255,255,255,0.15); border-color: rgba(255,255,255,0.9); }
.carousel-dots { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: center; }
.carousel-dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,0.4);
                cursor: pointer; transition: background 0.2s; flex-shrink: 0; }
.carousel-dot.active { background: var(--accent); }


/** FEATURE GALLERY — a run of ≥2 photo-feature cards shown ONE AT A TIME with side arrows, so each
    impact image keeps its breathing room (phase4 _wrap_feature_galleries). Unlike .img-carousel,
    each slide keeps the WHOLE card (image + heading/blurb panel below). carousel.js enhances it to
    .feature-carousel; without JS it degrades to a horizontal scroll-snap strip. The arrow box uses
    the per-article --accent / --standfirst-fg, so it is inherently per-title (FFT Upfront accent is
    yellow → yellow box + black arrow); a {Title}-overrides.css can restyle further. **/
/* Same one-per-frame in-app fallback as .gallery-viewer, but each frame is the WHOLE feature card
   (image + heading/blurb panel). Scoped to :not(.feature-carousel) so the JS arrow carousel is
   untouched wherever it runs. */
.feature-gallery:not(.feature-carousel) { display: flex; overflow-x: auto; gap: 14px;
    scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; clear: both; margin: 1.5rem 0;
    align-items: flex-start; touch-action: pan-x pan-y; overscroll-behavior-x: auto; }
/* One card per frame (the .gallery-dots sibling shows there are more; page-turn chains past the last). */
.feature-gallery:not(.feature-carousel) > .article-feature-card { flex: 0 0 100%; scroll-snap-align: center; margin: 0; }

.feature-carousel { position: relative; clear: both; margin: 1.5rem 0; overflow: hidden; }
.feature-carousel-wrap { position: relative; }
.feature-carousel .carousel-track { display: flex; transition: transform 0.3s ease; align-items: flex-start; }
.feature-carousel-slide { flex: 0 0 100%; min-width: 0; }
.feature-carousel-slide > .article-feature-card { margin: 0; }
/* Side arrows: accent box, luminance-correct arrow. JS centres `top` on the current card's image;
   50% is the pre-measure fallback. */
.feature-carousel-btn { position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
    width: 44px; height: 44px; border: none; cursor: pointer; padding: 0 0 3px;
    font-size: 1.7rem; line-height: 1; display: flex; align-items: center; justify-content: center;
    background: var(--accent, #222); color: var(--standfirst-fg, #fff);
    box-shadow: 0 1px 4px rgba(0,0,0,0.25); }
.feature-carousel-btn.prev { left: 0; }
.feature-carousel-btn.next { right: 0; }
.feature-carousel-btn:hover { filter: brightness(0.92); }
.feature-carousel-dots { display: flex; gap: 7px; align-items: center; justify-content: center;
    flex-wrap: wrap; padding: 10px 0 0; }
.feature-carousel-dots .carousel-dot { width: 8px; height: 8px; background: rgba(0,0,0,0.22); }
.feature-carousel-dots .carousel-dot.active { background: var(--accent); }


/** PUZZLE WRAPPER — name → blurb → interactive widget, centred + brand font.
   phase-4 wraps each (non-quiz) puzzle in .article-puzzle, pulling the puzzle's title+blurb <body>
   out to render BEFORE the widget (it's emitted after the grid in the XML). The brand font here also
   fixes the crossword clues (which had no font of their own and fell back to a serif default). **/
.article-puzzle { font-family: var(--font-family-main); text-align: center; margin: 1.5rem auto;
  clear: both; padding: 0 var(--side-pad); }
.article-puzzle-title { font-family: var(--font-family-main-display); font-weight: var(--font-weight-x-bold, 800);
  font-size: 1.5rem; line-height: 1.15; color: var(--main-color); margin: 0 0 0.3em; }
.article-puzzle-intro { font-weight: 600; color: var(--main-color); margin: 0 auto 0.7em;
  max-width: 34em; line-height: 1.4; }
.article-puzzle .crossword-widget, .article-puzzle .sudoku-widget, .article-puzzle .wordsearch-widget,
.article-puzzle .missingletters-widget, .article-puzzle .jumble-widget, .article-puzzle .spellitout-widget,
.article-puzzle .missingmaths-widget { margin-left: auto; margin-right: auto; text-align: left; }

/** QUIZ — numbered question list (Puzzle type="quiz"); answers render separately as body **/
/* Inset to match body elements (which all use padding: 0 var(--side-pad)); without this the quiz
   numbers/questions sat ~20px wider than the surrounding copy on both edges. The number circle
   (absolute, left:0 of .quiz-q) then aligns with the body text's left edge. */
.article-quiz { margin: 1.25rem 0; padding: 0 var(--side-pad); clear: both; }
.article-quiz .quiz-list { list-style: none; margin: 0; padding: 0; counter-reset: none; }
.article-quiz .quiz-q { position: relative; padding: 0.55em 0 0.55em 2.6em; line-height: 1.4;
    border-bottom: 1px solid rgba(0,0,0,0.08); font-family: var(--font-family-main); }
.article-quiz .quiz-q:last-child { border-bottom: none; }
/* Number in an accent-filled circle with luminance-correct text — per-article --accent drives the
   colour, so it's inherently per-title (FFT Upfront quiz: yellow accent → yellow circle, black
   number, matching the print; a dark-accent title → coloured circle, white number). */
.article-quiz .quiz-n { position: absolute; left: 0; top: 0.45em;
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.9em; height: 1.9em; border-radius: 50%;
    background: var(--accent); color: var(--standfirst-fg, #fff);
    font-family: var(--font-family-main-display); font-weight: 700; font-size: 0.85em; }
/* Answer reveal: native <details>, no JS. A grey rounded "Reveal" button; on click the button is
   hidden and the answer appears in its place. */
.article-quiz .quiz-a { margin-top: 0.4em; }
.article-quiz .quiz-a summary { display: inline-block; cursor: pointer; list-style: none;
    background: #e8e8e8; color: #333; border-radius: 14px; padding: 3px 14px;
    font-family: var(--font-family-condensed); font-size: 0.78em; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em; }
.article-quiz .quiz-a summary:hover { background: #dcdcdc; }
.article-quiz .quiz-a summary::-webkit-details-marker { display: none; }
.article-quiz .quiz-a[open] summary { display: none; }   /* answer replaces the button */
.article-quiz .quiz-answer { font-weight: 700; color: var(--main-color); }
/* Question-associated images (quiz_images.json) under the question — a single photo for "name this
   player", or a face grid for "name these four managers". Count- and width-aware: 2-up on mobile (4
   → clean 2×2), up to 4-up on desktop, natural aspect (no forced crop), each capped so a bigger/
   landscape image from a different design isn't squashed into a tiny fixed cell. A lone image shows
   larger. flex-basis + cap handles any count (1/2/3/4/6…) gracefully — it wraps, never a fixed row. */
.article-quiz .quiz-q-images { display: flex; flex-wrap: wrap; gap: 8px; margin: 0.5em 0 0.2em; }
.article-quiz .quiz-q-img { flex: 1 1 calc(50% - 4px); max-width: 160px; }   /* mobile: 2 per row */
.article-quiz .quiz-q-img img { display: block; width: 100%; height: auto; border-radius: 6px; }
.article-quiz .quiz-q-images.single .quiz-q-img { flex: 0 1 auto; max-width: 280px; }  /* lone image larger */
@media (min-width: 640px) and (max-resolution: 2dppx) {
    .article-quiz .quiz-q-img { flex-basis: calc(25% - 6px); max-width: 132px; }   /* desktop: up to 4 per row */
}

/* Step-by-step (recipe/craft/model how-to) — a numbered sequence consolidated by phase-4's
   _group_step_sequences into one consistent ordered block (NGK 48-1 "Make It"). Mobile: a single
   column of numbered cards; ≥640px: a 2-up grid so the steps read compactly. */
.article-steps { margin: 1.4rem 0; padding: 0 var(--side-pad); clear: both;
    display: grid; grid-template-columns: 1fr; gap: 1.1rem; }
.article-step { position: relative; }
/* Uniform media height so adjacent steps in the 2-up grid align (their source photos vary in aspect).
   A 4:3 cover-crop standardises the tiles; the step action is centred so the crop is safe. */
.article-step-media img { display: block; width: 100%; height: auto; border-radius: 12px; margin: 0;
    aspect-ratio: 4 / 3; object-fit: cover; }
/* Number badge: accent-filled circle, luminance-correct text — per-article --accent drives it, so it
   is inherently per-title (NGK Make It: yellow accent → yellow circle, black number, matching print). */
.article-step-n { position: absolute; top: 8px; left: 8px; z-index: 2;
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.9em; height: 1.9em; border-radius: 50%;
    background: var(--accent); color: var(--standfirst-fg, #fff);
    font-family: var(--font-family-main-display); font-weight: 700; font-size: 1em;
    box-shadow: 0 1px 3px rgba(0,0,0,0.35); }
.article-step-text { margin-top: 0.5em; font-family: var(--font-family-main);
    font-size: var(--font-standard, 16px); line-height: 1.45; }
@media (min-width: 640px) and (max-resolution: 2dppx) {
    .article-steps { grid-template-columns: 1fr 1fr; gap: 1.3rem; }
}

/* Section-opener contents (TEG 69-1 "In Season") — tappable entry cards linking to the section's
   articles: number-matched teaser thumb + accent page-number + title + sell. Per-article --accent
   drives the number colour ⇒ inherently per-title. */
.section-toc { margin: 1em 0; padding: 0 var(--side-pad); }
a.section-toc-entry { display: flex; align-items: center; gap: 14px; padding: 12px 0;
    text-decoration: none; color: var(--main-color);
    border-bottom: 1px solid rgba(127,127,127,.28); }
.section-toc a.section-toc-entry:last-child { border-bottom: none; }
.section-toc-thumb { width: 88px; height: 66px; object-fit: cover; border-radius: 6px;
    flex: 0 0 auto; }
.section-toc-num { font-family: var(--font-family-main-display); font-weight: 700;
    color: var(--accent-on-light); font-size: 1.5rem; min-width: 2ch; text-align: right;
    flex: 0 0 auto; }
.section-toc-text { display: flex; flex-direction: column; gap: 2px; }
.section-toc-title { font-family: var(--font-family-main-display); font-weight: 700;
    font-size: 1.05rem; line-height: 1.25; }
.section-toc-sell { font-family: var(--font-family-main); font-size: .9rem; opacity: .75;
    line-height: 1.3; }

/* Head-to-head DEBATE — two writers each arguing a different pick, laid out as two columns
   (FFT 392 27-1 "Who is the best manager…"). Stacked on mobile, side-by-side on desktop; each
   column carries an accent top rule, a small writer headshot, a display-font pick heading, the
   pick's photo, then that writer's case. Per-article --accent drives it ⇒ inherently per-title. */
.article-debate { margin: 1.4rem 0; padding: 0 var(--side-pad); clear: both;
    display: flex; flex-direction: column; gap: 1.6rem; }
.article-debate .debate-column { flex: 1; min-width: 0; border-top: 3px solid var(--accent);
    padding-top: 0.85rem; }
/* CENTRED header: headshot, name/role/handle and the pick stacked + centred at the top. */
.article-debate .debate-head { text-align: center; margin-bottom: 0.55rem; }
.article-debate .debate-headshot { float: none !important; clear: none !important; display: block;
    width: 72px; height: 72px; margin: 0 auto 0.45rem !important; }
.article-debate .debate-headshot img { width: 72px; height: 72px; object-fit: cover; }
.article-debate .debate-writer { margin: 0; font-family: var(--font-family-main);
    font-size: var(--font-small, 14px); line-height: 1.35; }
.article-debate .debate-pick { margin: 0.3rem 0 0; font-family: var(--font-family-main-display);
    font-weight: 700; font-size: 1.6rem; line-height: 1.12; color: var(--accent-on-light, #1a1a1a); }
/* The pick's photo FLOATS RIGHT; the argument text wraps beside it so the column fills (no white
   space below a block image). Each column is a flex item ⇒ its own BFC ⇒ the float is contained. */
.article-debate .debate-column > .article-in-image:not(.debate-headshot) { float: right !important;
    clear: right; width: 44%; max-width: 300px; margin: 0.1rem 0 0.6rem 1rem !important; }
/* width:auto + max-width keeps RATIO when the inherited max-height (from .portrait-float img) clamps a
   tall photo — plain width:100% there stretched the image wide (e.g. the full-width manager shot in-app). */
.article-debate .debate-column > .article-in-image:not(.debate-headshot) img { width: auto; max-width: 100%;
    height: auto; max-height: 380px; object-fit: contain; margin: 0 auto; display: block; }
.article-debate .debate-column .article-full-body:first-of-type { margin-top: 0; }
@media (min-width: 640px) and (max-resolution: 2dppx) {
    .article-debate { flex-direction: row; gap: 2rem; align-items: flex-start; }
}
/* Narrow phones: a 44% float would crush the text → full-width centred block instead. */
@media (max-width: 520px), (min-resolution: 2.5dppx) {
    .article-debate .debate-column > .article-in-image:not(.debate-headshot) { float: none !important;
        width: 100%; max-width: none; margin: 0.3rem auto 0.6rem !important; }
}

/* "TOP TIP" callout — a friendly rounded accent card echoing the printed tip roundel, distinct from a
   plain rectangular info boxout. Per-article --accent drives it, so it's inherently per-title. The
   leading tip label (bold) is tinted with the accent. */
.article-boxout.article-tip { border: 2px solid var(--accent); border-radius: 18px;
    background: color-mix(in srgb, var(--accent) 12%, #fff); }
.article-boxout.article-tip .ld_bold:first-child,
.article-boxout.article-tip b:first-child { color: var(--accent-on-light, var(--accent));
    text-transform: uppercase; letter-spacing: 0.03em; }


/** TABLE OF CONTENTS **/

.toc-issue-label {
    font-family: var(--font-family-condensed);
    font-size: var(--font-x-large);
    font-weight: var(--font-weight-x-bold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #888888;
    margin: 1rem 0 1.5rem;
    padding: 0;
    line-height: 1;
}

.toc-wrapper {
    padding: 0 0 2rem;
}

.toc-card-grid {
    display: block;
    margin-bottom: 1rem;
}

.toc-section-header {
    display: block;
    border-bottom: var(--toc-section-border-bottom);
    margin: 1.5rem 0 0.6rem;
    padding-bottom: var(--toc-section-border-pb);
    grid-column: 1 / -1;
}
.toc-section-header span {
    display: var(--toc-section-span-display);
    font-family: var(--toc-section-span-font);
    font-size: var(--toc-section-span-size);
    font-weight: var(--toc-section-span-weight);
    letter-spacing: var(--toc-section-span-tracking);
    text-transform: uppercase;
    color: var(--sa-on-bg, var(--toc-section-span-fg));
    background: var(--sa, var(--toc-section-span-bg));
    padding: var(--toc-section-span-padding);
    line-height: 1;
}

/* Placeholder thumbnail — logo on grey bg */
.toc-img-placeholder {
    background: var(--toc-placeholder-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}
.toc-img-placeholder img {
    object-fit: contain !important;
    object-position: center !important;
    padding: 14% !important;
    opacity: 0.55;
}

.toc-card {
    display: flex;
    text-decoration: none;
    color: inherit;
    background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.15s;
}
.toc-card:active { background: rgba(0,0,0,0.04); }

/* Feature card — full-width with large hero above, text below */
.toc-feature {
    flex-direction: column;
    margin: 0 0 1px;
}
.toc-feature-img {
    width: 100%;
    aspect-ratio: 16/9;
    overflow: hidden;
    flex-shrink: 0;
}
.toc-feature-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}
.toc-feature-body {
    padding: 0.6rem 1.5rem 0.8rem;
    flex: 1;
}
.toc-feature-body .toc-title {
    font-size: var(--font-large);
}
.toc-feature-body .toc-sell {
    font-size: var(--font-small);
    margin: 0.3rem 0 0.5rem;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    display: -webkit-box;
    overflow: hidden;
}

/* Standard card — thumbnail left, text right */
.toc-standard {
    flex-direction: row;
    align-items: center;
    padding: 0.6rem 1.5rem 0.6rem 0;
    margin: 0;
    border-bottom: 1px solid rgba(0,0,0,0.07);
    gap: 0.75rem;
}
.toc-thumb {
    width: 72px;
    height: 72px;
    object-fit: cover;
    object-position: center top;
    flex-shrink: 0;
    display: block;
}
.toc-standard-body {
    flex: 1;
    min-width: 0;
}
.toc-standard-body .toc-title {
    font-size: var(--font-standard);
}
.toc-standard-body .toc-sell {
    font-size: 13px;
    margin: 0.2rem 0 0;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    display: -webkit-box;
    overflow: hidden;
}

/* Compact card — thumbnail + title + page */
.toc-compact {
    flex-direction: row;
    align-items: center;
    padding: 0.45rem 1.5rem 0.45rem 0;
    border-bottom: 1px solid rgba(0,0,0,0.05);
    gap: 0.75rem;
}
.toc-compact .toc-thumb {
    width: 56px;
    height: 56px;
    flex-shrink: 0;
}
.toc-compact .toc-title {
    font-size: var(--font-standard);
    flex: 1;
    min-width: 0;
}
.toc-compact .toc-page {
    flex-shrink: 0;
}

/* Shared title / sell / page */
.toc-title {
    font-family: var(--toc-title-font);
    font-weight: var(--toc-title-weight);
    color: var(--main-color);
    margin: 0;
    line-height: 1.2;
    text-transform: var(--toc-title-transform);
    letter-spacing: var(--toc-title-tracking);
}
.toc-sell {
    font-family: var(--toc-sell-font);
    font-weight: var(--toc-sell-weight);
    font-style: var(--toc-sell-style);
    color: var(--second-color);
    line-height: 1.4;
    padding: 0;
    margin: 0;
}
.toc-feature-variant {
    display: block;
    font-family: var(--font-family-condensed);
    font-size: var(--font-smallest);
    font-weight: var(--font-weight-x-bold);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 0.2rem;
}
.toc-page {
    font-family: var(--font-family-condensed);
    font-size: var(--font-smallest);
    font-weight: var(--font-weight-bold);
    color: var(--accent);
    letter-spacing: 0.1em;
    flex-shrink: 0;
    margin-left: 0.5rem;
}
.toc-feature-body .toc-page {
    display: block;
    margin-left: 0;
    margin-bottom: 0.5rem;
}

/* TOC card dark-theme tweaks (class-scoped — see the THEMES note below). */
.darktheme .toc-section-header span { background: var(--sa, var(--toc-section-span-bg)); color: var(--sa-on-bg, var(--toc-section-span-fg)); }
.darktheme .toc-standard { border-bottom-color: rgba(255,255,255,0.07); }
.darktheme .toc-compact { border-bottom-color: rgba(255,255,255,0.05); }
.darktheme .toc-card:active { background: rgba(255,255,255,0.06); }
.darktheme .toc-title { color: var(--main-color-dark); }
.darktheme .toc-sell { color: var(--second-color-dark); }
.darktheme .toc-issue-label { color: var(--forth-color-dark); }
.darktheme .toc-page { color: var(--accent); }
.darktheme .toc-img-placeholder { background: #1e1e1e; }
/* Sepia TOC: borders/dividers warm rather than cool. */
.sepiatheme .toc-standard { border-bottom-color: rgba(91,70,54,0.12); }
.sepiatheme .toc-compact { border-bottom-color: rgba(91,70,54,0.09); }
.sepiatheme .toc-card:active { background: rgba(91,70,54,0.06); }
.sepiatheme .toc-img-placeholder { background: #e7dcc2; }

/* Desktop grid layout */
@media (min-width: 640px) and (max-resolution: 2dppx) {
    .toc-card-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 12px;
        row-gap: 0;
        margin-bottom: 1.25rem;
    }

    .toc-feature {
        grid-column: span 1;
        flex-direction: column;
    }
    .toc-feature-img {
        width: 100%;
        height: 220px;
        min-height: 220px;
        aspect-ratio: unset !important;
        background: #e8e8e8;
    }
    .toc-feature-img img {
        width: 100%;
        height: 100%;
        min-height: 220px;
        object-fit: cover;
        object-position: center top;
        display: block;
    }
    .toc-feature-body {
        padding: 0.65rem 0.9rem 0.8rem;
    }
    .toc-feature-body .toc-title {
        font-size: var(--font-medium);
    }
    .toc-feature-body .toc-sell {
        font-size: 13px;
        -webkit-line-clamp: 2;
        margin-top: 0.2rem;
    }

    /* Single-card section: full-width row for any card type */
    .toc-card-grid:not(:has(.toc-card ~ .toc-card)) .toc-feature,
    .toc-card-grid:not(:has(.toc-card ~ .toc-card)) .toc-standard,
    .toc-card-grid:not(:has(.toc-card ~ .toc-card)) .toc-compact {
        grid-column: 1 / -1;
        flex-direction: row;
        align-items: center;
    }
    .toc-card-grid:not(:has(.toc-card ~ .toc-card)) .toc-feature .toc-feature-img {
        width: 240px;
        height: 160px;
        min-height: 160px;
        flex-shrink: 0;
    }
    .toc-card-grid:not(:has(.toc-card ~ .toc-card)) .toc-feature .toc-feature-body {
        flex: 1;
        padding: 0.75rem 1.25rem;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    .toc-card-grid:not(:has(.toc-card ~ .toc-card)) .toc-feature .toc-feature-body .toc-title {
        font-size: var(--font-large);
    }

    .toc-standard { align-items: flex-start; }
    .toc-standard-body { align-self: center; }
    .toc-thumb { width: 88px; height: 88px; }
    .toc-compact .toc-thumb { width: 88px; height: 88px; }
}


/** PAGE JUMP **/

p.article-page-jump { font-family: var(--font-family-condensed); font-size: var(--font-small);
                       font-weight: var(--font-weight-bold); text-align: right;
                       color: var(--forth-color); letter-spacing: 0.06em;
                       text-transform: uppercase; margin: 12px 0 4px; padding: 0 var(--side-pad); }
p.article-page-jump a { color: var(--accent); text-decoration: none; }
p.article-page-jump a:hover { text-decoration: underline; }


/** CONTRIBUTOR / HEADSHOT COMPONENTS — pipeline additions **/

.byline-with-headshot { display: flex; align-items: center; gap: 12px;
                         margin: 0 1.5rem 1.25rem; }
.byline-with-headshot .article-full-byline { padding: 0; margin: 0; }
.headline-headshot-row { display: flex; align-items: flex-start; gap: 14px; }
.headline-headshot-text { flex: 1; min-width: 0; }
.header-headshot { width: 100px; height: 100px; object-fit: cover; border-radius: 50%; flex-shrink: 0; margin-top: 2px; margin-right: var(--side-pad); }
.byline-headshot { width: 48px; height: 48px; border-radius: 50%;
                   object-fit: cover; flex-shrink: 0; }

.sign-off-with-headshot { display: flex; gap: 12px; align-items: center; margin-top: 1.25rem;
                           padding: 0 var(--side-pad); }
.sign-off-with-headshot .byline-headshot { width: 52px; height: 52px; }

/* Centred-header treatment: a SMALL image sits ABOVE the headline (WCM 5-1 editor's letter,
   WCM 23-1 "Re:View", and the Times-style columnist opener). The image is centred at the top,
   the head block (standfirst/headline/lead/byline) is centred beneath it, and the body then flows
   NORMALLY (left-aligned, dropcap at the true first paragraph — no leading float). Phase-4 emits
   this only when a start-page Image_Asset slot is ≤30% of the page and predominantly above the
   headline; see phase4 _find_centered_header. */
.article-header-centered { text-align: center; padding: 0 var(--side-pad); margin: 0 0 0.4rem; }
.article-header-centered-img { margin: 0.2rem auto 0.9rem; max-width: 62%; }
.article-header-centered-img img {
    display: block; margin: 0 auto;
    max-width: 100%; width: auto; height: auto; max-height: 240px;
    border-radius: 6px;
}
/* A headshot / byline portrait renders at the USUAL small headshot size (~110px), not the larger
   lead-image cap above — e.g. the WCM 5-1 editor portrait. */
.article-header-centered-img.headshot { width: 110px; max-width: 110px; }
/* A WIDE panorama / stitched DPS above the headline (CM 24-1) is the showpiece — full width. */
.article-header-centered-img.wide { max-width: 100%; }
.article-header-centered-img.wide img { max-height: none; width: 100%; }
.article-header-centered-img.headshot img { max-height: 150px; border-radius: 4px; }
/* A circular headshot stays circular (fixed square box, cover-cropped); a natural photo keeps its
   own aspect via the rule above. */
.article-header-centered-img.shape-circle { width: 110px; height: 110px; max-width: 110px; }
.article-header-centered-img.shape-circle img {
    width: 100%; height: 100%; object-fit: cover; border-radius: 50%; max-height: none;
}
.article-header-centered .article-full-headline,
.article-header-centered .article-full-lead,
.article-header-centered .article-full-byline {
    text-align: center; padding-left: 0; padding-right: 0;
}
/* The STANDFIRST keeps its own padding — it's an inline-block PILL, centred by the parent's
   text-align; zeroing its sides let the 20px radius clip the text (CM 24-1 "N | Plan of the month"). */
.article-header-centered .article-standfirst { text-align: center; }
.article-header-centered .article-full-headline { text-wrap: balance; }

/* Numbered roundup — a "this month's products" list: each item = number badge + image + name/blurb,
   paired by the printed number (phase3b.run_roundup) instead of a wall of text + scattered images. */
.article-roundup { margin: 1rem var(--side-pad) 1.5rem; }
.roundup-item {
    display: grid;
    grid-template-columns: auto 96px 1fr;
    gap: 12px 14px;
    align-items: start;
    padding: 0.9rem 0;
    border-top: 1px solid color-mix(in srgb, var(--main-color, #222) 12%, transparent);
}
.roundup-item:first-child { border-top: none; }
.roundup-num {
    font-family: var(--font-family-condensed);
    font-weight: var(--font-weight-x-bold);
    font-size: 1.4rem;
    line-height: 1;
    color: var(--accent, #888);
}
.roundup-img { width: 96px; height: auto; border-radius: 4px; }
.roundup-item:not(:has(.roundup-img)) { grid-template-columns: auto 1fr; }  /* no image → 2 cols */
.roundup-text { min-width: 0; }
.roundup-name {
    margin: 0 0 0.25rem;
    font-family: var(--font-family-condensed);
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
}
.roundup-text .article-full-body { margin: 0 0 0.4rem; padding: 0; }

/* Author-bio card — a byline-matched bio at the article end (headshot left, bio text right).
   Readable body-style text (NOT the uppercase condensed pull-quote-credit treatment), set off by a
   subtle accent rule + tint so it reads as an "about the author" box. */
.article-author-bio {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    margin: 2rem var(--side-pad) 1rem;
    padding: 1rem 1.1rem;
    border-top: 3px solid var(--accent, #888);
    background: color-mix(in srgb, var(--accent, #888) 6%, transparent);
    border-radius: 4px;
}
.article-author-bio .author-bio-headshot {
    /* Keep the image's natural (as-extracted / as-printed) shape — fixed width, auto height,
       no circular crop. A gentle radius just matches the card corners. */
    width: 84px; height: auto;
    border-radius: 4px; flex-shrink: 0;
}
.article-author-bio-text {
    margin: 0;
    font-family: var(--font-family-main);
    font-size: var(--font-small);
    line-height: 1.5;
    color: var(--main-color);
    text-transform: none;       /* override any inherited credit casing */
    letter-spacing: normal;
    font-weight: normal;
}
.article-author-bio-text .ld_bold { font-weight: var(--font-weight-bold); }

/* Editorial float headshot — editor's letter portrait circled and floated into body copy */
.editorial-float-headshot {
    float: right;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    overflow: hidden;
    shape-outside: circle(50%);
    margin: 0 0 12px 16px;
    flex-shrink: 0;
}
.editorial-float-headshot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
}

.subhead-with-headshot { display: flex; align-items: center; gap: 12px;
                          margin: 1.25rem 1.5rem 0.5rem; }
.subhead-headshot { width: 52px; height: 52px; border-radius: 50%;
                    object-fit: cover; flex-shrink: 0; }
.subhead-with-headshot p.article-subhead { margin: 0; padding: 0; }

.contributor-strip { display: flex; flex-wrap: wrap; gap: 10px;
                     margin: 1rem 1.5rem 1.25rem; }
.contributor-strip-img { width: 52px; height: 52px; border-radius: 50%; object-fit: cover; }

/* Float-based so body paragraphs wrap freely around the headshot. */
.contributor-entry { margin: 12px 0; padding: 0 var(--side-pad); }
.contributor-entry::after { content: ""; display: table; clear: both; }
.contributor-entry .contributor-headshot { float: left; width: 56px; height: 56px;
    object-fit: cover; border-radius: 50%; margin: 2px 12px 6px 0; }
.contributor-entry-text { }
.contributor-entry-text p { padding: 0; }

.secondary-image-strip { display: flex; flex-wrap: wrap; gap: 12px; margin: 1.25rem 0;
                          justify-content: center; }
.secondary-image-strip .article-in-image { margin: 0; }


/** PRODUCT ITEMS **/

.product-item { overflow: hidden; margin-bottom: 1.5rem; clear: both; }
.product-item .article-in-image.portrait-float img,
.product-item .article-in-image.contained img,
.product-item .article-in-image.inline-float-right img { max-height: 285px; }


/** BOXOUTS **/

.article-boxout {
    background-color: var(--boxout-color);
    border: var(--boxout-border);
    border-top: var(--boxout-border-top);
    margin: 1.5rem 1.5rem;
    box-sizing: border-box;
    width: calc(100% - 3rem);
    padding: 1.125rem 1.5rem 1.5rem;
    overflow: hidden;
}

.article-boxout .article-full-headline {
    font-family: var(--font-family-condensed);
    font-size: var(--font-standard);
    font-weight: var(--font-weight-xx-bold);
    color: var(--accent);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0;
    margin: 0 0 0.5rem;
}

/* A handwritten SIGNATURE graphic (editor's letter sign-off — TEG 3-1 "Clare"): a modest inline
   block after the letter text, never floated beside copy. Keyed off the image description. */
.article-in-image.signature-img { float: none; clear: both; margin: 0.4rem 0 1rem; }
.article-in-image.signature-img img.article-in-image { max-height: 64px; width: auto; margin: 0; }

/* A SUBHEAD that IS a kicker label in print (phase-3c: sans face + ≤10pt — TEG 9-1 "In flower
   now", 8pt pink caps Gotham): render as the small caps sans label, not the serif subhead face.
   Class only appears with the 3c attrs ⇒ no-op elsewhere. Beats a per-title serif override via
   the two-class selector. */
.article-subhead.subhead-kicker,
.article-boxout .article-subhead.subhead-kicker {
    font-family: var(--font-family-condensed);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

/* Kicker label above a boxout heading (phase-3c `eyebrow` attr — TEG 9-1 "NEW GARDEN"): a small
   caps sans line in its TRUE print colour (inline style; defaults to main text colour). Emitted
   only when 3c captured a printed label ⇒ no-op elsewhere. */
.boxout-eyebrow {
    font-family: var(--font-family-condensed);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    margin: 0.9rem 0 0.1rem;
    padding: 0;
}
.boxout-eyebrow + .article-subhead { margin-top: 0; }
.article-boxout .article-full-subhead {
    font-family: var(--font-family-condensed);
    font-size: var(--font-large);
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .article-full-lead {
    font-family: var(--font-family-main);
    font-size: var(--font-standard);
    font-weight: var(--font-weight-standard);
    color: var(--second-color);
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .article-full-byline {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-bold);
    color: var(--main-color);
    letter-spacing: 0.04em;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .article-full-body {
    font-family: var(--font-family-main);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    color: var(--main-color);
    line-height: 1.55;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .article-pull-quote {
    font-family: var(--pull-quote-font);
    font-size: var(--font-medium);
    font-weight: var(--pull-quote-weight);
    font-style: var(--pull-quote-style);
    color: var(--pull-quote-color);
    line-height: 1.2;
    padding: 0;
    margin: 0 0 0.5rem;
    border: none;
}
.article-boxout .article-pull-quote-credit {
    font-family: var(--font-family-condensed);
    font-size: var(--font-small);
    font-weight: var(--font-weight-bold);
    color: var(--forth-color);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--font-family-main);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    margin: 0.4rem 0 0.8rem;
}
.article-boxout th {
    font-weight: var(--font-weight-bold);
    text-align: left;
    padding: 0.1rem 0.5rem 0.3rem 0;
    border-bottom: 1px solid var(--main-color);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: var(--font-smallest);
}
.article-boxout td {
    padding: 0.15rem 0.5rem 0.15rem 0;
    vertical-align: top;
}
.article-boxout .article-subhead {
    font-family: var(--font-family-condensed);
    font-size: var(--font-medium);
    font-weight: var(--font-weight-x-bold);
    color: var(--main-color);
    line-height: 1.2;
    text-transform: none;   /* captured (printed) case — see .article-subhead above */
    letter-spacing: 0.04em;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .article-body {
    font-family: var(--font-family-main);
    font-size: var(--font-small);
    font-weight: var(--font-weight-standard);
    color: var(--main-color);
    line-height: 1.55;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .articleImageCredit {
    font-family: var(--font-family-condensed);
    font-size: var(--font-smallest);
    color: var(--forth-color);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0;
    margin: 0 0 0.5rem;
}
.article-boxout .contributor-entry { margin: 10px 0; }


/** READER OVERRIDE **/

.listenholder { text-align: left !important; padding: 0 var(--side-pad); margin-bottom: 20px; }
.article-pull-quote .ld_bold { font-weight: var(--font-weight-xx-bold); }


/** RETINA / HIGH-DPI ADJUSTMENTS **/

@media only screen and (-webkit-device-pixel-ratio: 3) {
    :root { --side-pad: 1.5rem; }
    .flexy { margin-top: 20px; }
    .article-standfirst { padding: 5px 0 6px; }
    .article-full-byline { margin-bottom: 1.5rem; }
}

/* Feature card with secondary image but no real hero: contained within grey panel */
.toc-feature-img.toc-img-contained {
    background: #e8e8e8;
}
.toc-feature-img.toc-img-contained img {
    object-fit: contain !important;
    object-position: center top !important;
}

/* Mobile: hide thumbnails on standard/compact, indent text to align with feature cards */
@media (max-width: 639px), (min-resolution: 2.5dppx) {
    .toc-standard .toc-thumb,
    .toc-compact .toc-thumb { display: none; }
    .toc-standard { padding-left: 1.5rem; padding-top: 0.9rem; padding-bottom: 0.9rem; }
    .toc-compact { padding-left: 1.5rem; padding-top: 0.75rem; padding-bottom: 0.75rem; }
}
/* (The old scrim duplicate-and-hide rules were removed 2026-06-05 — the hero is now a single
   responsive DOM block, .article-hero--scrim, that needs no per-breakpoint hiding.) */

@media (max-width: 520px), (min-resolution: 2.5dppx) {
    .article-hero-portrait-float { flex-direction: column; }
    .portrait-float-img { flex: 0 0 auto; max-width: 68%; margin: 0 auto; }
    .article-in-image.portrait-float { float: none; width: 100%; max-width: 100%; margin: 16px 0; }
    .article-in-image.portrait-float img { display: block; width: 100%; height: auto; max-height: 60vh;
        object-fit: contain; }  /* contain so a landscape-phone short viewport clamps max-height without stretching */
    /* A byline headshot stays a SMALL left float on mobile too (don't blow it up to full width like a
       normal portrait-float); left edge aligns with the body text; natural (square) shape, not circle. */
    .article-in-image.contributor-byline-float { float: left; width: auto; max-width: 72px; margin: 2px 12px 6px var(--side-pad); }
    .article-in-image.contributor-byline-float img { display: block; width: auto; max-width: 72px; max-height: 72px; height: auto; border-radius: 4px; object-fit: contain; }
    .header-headshot { width: 18vw; height: 18vw; min-width: 56px; min-height: 56px; }
    .article-in-image.contained { float: none; width: 100%; margin: 16px 0; }
    .article-in-image.inline-float-right { float: none; width: 100%; max-width: 100%; margin: 16px 0; }
    .article-in-image.page-centered { float: none; width: 100%; max-width: 100%; margin: 16px 0; }
    .article-in-image.solo { max-width: 100%; }
    .article-boxout .article-in-image.portrait-float,
    .article-boxout .article-in-image.contained,
    .article-boxout .article-in-image.inline-float-right {
        float: none; max-width: 55%; margin: 8px auto 10px; display: block;
    }
    .article-boxout .article-in-image.portrait-float img {
        display: block; margin: 0 auto; width: auto; max-width: 100%; max-height: 180px; height: auto;
    }
    .article-boxout .article-in-image.contained img {
        display: block; margin: 0 auto; width: auto; max-width: 100%; max-height: 180px; height: auto;
    }
    .article-boxout .article-in-image.inline-float-right img {
        display: block; margin: 0 auto; width: 100%; max-width: 100%; max-height: 180px; height: auto;
        object-fit: contain;  /* preserve ratio when the max-height clamps (landscape phone) */
    }
}


/** THEMES — light is the DEFAULT (no class needed).
 *
 *  The reader detects the OS/user colour scheme and sets a class on the body/container in code:
 *  `.darktheme` or `.sepiatheme`. It never sets a `.lighttheme` class — light is just the base CSS
 *  above. So dark and sepia are class-scoped OVERRIDES (this also lets the user override the OS
 *  setting from inside the reader). We do NOT use `@media (prefers-color-scheme)` — the reader owns
 *  the decision. Theme colours are redefined as CSS variables ON the theme class so they cascade to
 *  every descendant; the per-article inline `:root{--accent…}` still feeds `var(--accent-dark)`.
 *  Set the background on the theme class itself (not `body`) so it works whether the reader puts the
 *  class on <body> or on a wrapper element above it. **/

.darktheme {
    --main-color:           var(--main-color-dark);
    --second-color:         var(--second-color-dark);
    --third-color:          var(--third-color-dark);
    --forth-color:          var(--forth-color-dark);
    --boxout-color:         var(--boxout-color-dark);
    --boxout-border-color:  var(--boxout-border-color-dark);
    --accent:               var(--accent-dark);
    background-color: #0f0f0f;
}
.darktheme a { color: #ffffff; }

.sepiatheme {
    --main-color:    #5b4636;   /* warm dark brown on paper */
    --second-color:  #6b5645;
    --third-color:   #5b4636;
    --forth-color:   #8a7560;
    --boxout-color:  #efe3c8;   /* slightly deeper paper for boxout fills */
    background-color: #f4ecd8;  /* sepia paper */
}
.sepiatheme a { color: var(--accent); }


/** MAGAZINE CONTENTS / SECTION PAGES (EPUB reader nav — section_NN.xml) **/

.masthead { padding: 14px 0 10px; border-bottom: 2px solid var(--accent); margin-bottom: 12px; }
.masthead .sectionName { font-family: var(--font-family-main-display); font-weight: 800;
                         font-size: 1.6rem; text-transform: uppercase; letter-spacing: 0.02em;
                         color: var(--accent-on-light, var(--main-color)); }
.masthead .masthead-date { font-family: var(--font-family-main); font-size: 0.8rem;
                           color: var(--second-color); margin-top: 2px; }

.sectionArticleBlockOdd { display: flex; align-items: flex-start; gap: 12px; padding: 4px 0; }
.sectionArticleThumbBlock { flex: 0 0 100px; }
.sectionArticleImage { width: 100px; height: 100px; object-fit: cover; display: block;
                       border-radius: 3px; background: #eee; }
.sectionArticleTextBlock { flex: 1 1 auto; min-width: 0; }
.sectionArticleLink { text-decoration: none; }
.sectionArticleHeadline { font-family: var(--font-family-main-display); font-weight: 700;
                          font-size: 1.05rem; line-height: 1.15; color: var(--main-color); }
.sectionArticleByline { font-family: var(--font-family-main); font-size: 0.78rem;
                        color: var(--second-color); margin-top: 2px; }
.sectionArticleBody { font-family: var(--font-family-main); font-size: 0.82rem;
                      color: var(--third-color); margin-top: 4px; line-height: 1.35; }
.article-spacer { height: 1px; background: rgba(0,0,0,0.08); margin: 8px 0; }

/* ── Comfortable reading measure on wide screens (tablet / landscape / a misreporting wide webview) ──
   Cap the TEXT column and centre it (≈ BBC Sport's ~80% measure) so body copy doesn't sprawl
   edge-to-edge on a tablet/desktop. Media (hero / images / carousels / feature cards) is deliberately
   NOT listed here, so full-bleed stays full-bleed.
   DPR-GATED (max-resolution: 2dppx) — the in-app phone webview MISREPORTS a wide layout viewport
   (innerWidth≈996) at DPR=3 then zooms the page to fit the device, so an unconditional cap treated the
   PHONE as a wide screen and narrowed the reading column to ~680/996 → far too thin after the zoom.
   Gating to <2.5dppx applies the cap only on genuine desktop/tablet (DPR≤2.49; iPad is 2dppx, and a
   Windows monitor at ~225% scaling is 2.0–2.49) and leaves high-DPR phones (DPR≥2.5 — the misreporting
   webview AND real phone browsers) full-width. The upper bound is 2.49dppx (was 2dppx) to match the
   hero DPR boundary so a Windows-scaled desktop doesn't fall in the old gap. 730px matches the web
   reader's text-column width (the reader caps its article column at 1000px with ~730px of text). */
@media (max-resolution: 2.49dppx) {
    .connect-mobile-edition .article-full-headline,
    .connect-mobile-edition .article-full-lead,
    .connect-mobile-edition .article-standfirst,
    .connect-mobile-edition .article-full-byline,
    .connect-mobile-edition .article-full-body,
    .connect-mobile-edition .article-subhead,
    .connect-mobile-edition .article-pull-quote,
    .connect-mobile-edition .article-pull-quote-credit,
    .connect-mobile-edition .article-boxout {
        max-width: 730px;
        margin-right: auto;
        /* LEFT-align the capped column (don't centre). Centring each element independently put them in
           DIFFERENT containers — the inline-block standfirst pill (margin:auto→0 → far left), the
           headshot-row headline (centres within its flex column) and the body (centres in the wrapper) —
           giving 3 different left edges. Left-aligning means every element sits at side-pad from its
           container's left, and the headshot row starts at the wrapper's left, so they all line up.
           Trade-off: a right-hand gap on very wide screens (a left-aligned measure, not centred). */
    }
}


/* ==== PUZZLE WIDGETS (external-CSS pilot): class-scoped copies of the per-widget
   inline <style> rules. Pilot articles ship NO inline widget styles and rely on these;
   non-pilot articles still carry their #uid inline copies, which win ties (same values,
   higher specificity) - so these are additive and safe everywhere. Per-instance grid
   columns (crossword cols, pathfinder cols) are set by script.js at init. ==== */
/* ==== krisskross-widget ==== */
.krisskross-widget{max-width:520px;margin:1em auto;font-family:var(--font-family-main,sans-serif);text-align:center;}.krisskross-widget .kk-grid{border-collapse:collapse;margin:0 auto 10px;}.krisskross-widget .kk-cell{border:1.5px solid #888;width:1.9em;height:1.9em;padding:0;background:#fff;position:relative;}.krisskross-widget .kk-len-n{position:absolute;top:-0.05em;left:1px;font-size:0.45em;color:#888;line-height:1;font-weight:700;}.krisskross-widget .kk-empty{width:1.9em;height:1.9em;}.krisskross-widget .kk-in{width:100%;height:100%;border:none;background:transparent;text-align:center;font-weight:700;text-transform:uppercase;outline:none;color:#1d4ed8;}.krisskross-widget .kk-in.kk-right{color:#16a34a;}.krisskross-widget .kk-in.kk-wrong{color:#dc2626;}.krisskross-widget .kk-group{font-size:0.85em;margin:3px 0;text-align:left;}.krisskross-widget .kk-len{font-weight:800;color:var(--accent-on-light,#1a1a1a);margin-right:6px;}.krisskross-widget .kk-w{margin-right:9px;letter-spacing:0.4px;}.krisskross-widget .kk-w.kk-done{text-decoration:line-through;color:#9ca3af;}.krisskross-widget .kk-check{margin-top:6px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.krisskross-widget .kk-msg{margin-left:8px;font-size:0.9em;font-weight:700;}.krisskross-widget .kk-note{font-size:0.85em;color:#6b7280;}

/* ==== bricktrick-widget ==== */
.bricktrick-widget{max-width:460px;margin:1em auto;font-family:var(--font-family-main,sans-serif);text-align:center;}.bricktrick-widget .bt-row{display:flex;align-items:center;justify-content:center;gap:6px;margin:3px 0;}.bricktrick-widget .bt-n{font-weight:800;color:var(--accent-on-light,#1a1a1a);min-width:1.2em;}.bricktrick-widget .bt-cells{display:inline-flex;gap:2px;}.bricktrick-widget .bt-c{width:1.7em;height:1.9em;text-transform:uppercase;font-weight:700;text-align:center;border:1.5px solid #b78a5a;border-radius:3px;background:#faf3ea;outline:none;color:#1d4ed8;padding:0;}.bricktrick-widget .bt-c.bt-ok{border-color:#16a34a;color:#16a34a;background:#f0fdf4;}.bricktrick-widget .bt-c.bt-bad{border-color:#dc2626;color:#dc2626;background:#fef2f2;}.bricktrick-widget .bt-clue{font-size:0.85em;text-align:left;margin:2px 0;}.bricktrick-widget .bt-clues{margin-top:8px;column-count:2;column-gap:18px;}.bricktrick-widget .bt-check{margin-top:8px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.bricktrick-widget .bt-msg{margin-left:8px;font-size:0.9em;font-weight:700;}

/* ==== missinglink-widget ==== */
.missinglink-widget{max-width:480px;margin:1em auto;font-family:var(--font-family-main,sans-serif);}.missinglink-widget .mlk-row{display:flex;align-items:center;justify-content:center;gap:9px;margin:5px 0;}.missinglink-widget .mlk-w{font-weight:800;min-width:7.5em;}.missinglink-widget .mlk-row .mlk-w:first-child{text-align:right;}.missinglink-widget .mlk-cells{display:inline-flex;gap:2px;}.missinglink-widget .mlk-c{width:1.7em;height:1.9em;text-transform:uppercase;font-weight:700;text-align:center;border:1.5px solid #bbb;border-radius:3px;outline:none;color:#1d4ed8;padding:0;}.missinglink-widget .mlk-c.mlk-shaded{background:#fbdce4;border-color:#e8a2b8;}.missinglink-widget .mlk-c.mlk-right{border-color:#16a34a;color:#16a34a;background:#f0fdf4;}.missinglink-widget .mlk-c.mlk-shaded.mlk-right{background:#d9f3e1;}.missinglink-widget .mlk-c.mlk-wrong{border-color:#dc2626;color:#dc2626;background:#fef2f2;}.missinglink-widget .mlk-check{margin-top:8px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.missinglink-widget .mlk-msg{margin-left:8px;font-size:0.9em;font-weight:700;}.missinglink-widget .mlk-foot{text-align:center;}

/* ==== crossword-widget ==== */
.crossword-widget{max-width:100%;margin:1em auto;}.crossword-widget .cw-grid{display:grid;gap:0;border:2px solid #333;width:100%;max-width:560px;}.crossword-widget .cw-cell{position:relative;background:#fff;border:1px solid #999;}.crossword-widget .cw-cell::before{content:'';display:block;padding-bottom:100%;}.crossword-widget .cw-black{background:#222;border-color:#222;}.crossword-widget .cw-word{background:#d4eaff;}.crossword-widget .cw-active{background:#6aaeee;}.crossword-widget .cw-num{position:absolute;top:1px;left:2px;font-size:0.55em;line-height:1;color:#333;pointer-events:none;z-index:1;}.crossword-widget .cw-input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;border:none;background:transparent;text-align:center;text-transform:uppercase;font-size:1.3em;font-weight:700;padding:0;cursor:pointer;caret-color:transparent;outline:none;}.crossword-widget .cw-clues{display:flex;gap:1.5em;margin-top:1em;font-size:0.85em;}.crossword-widget .cw-clues-col{flex:1;min-width:0;}.crossword-widget .cw-clues-heading{font-size:0.95em;font-weight:700;margin:0 0 0.4em;text-transform:uppercase;letter-spacing:0.05em;}.crossword-widget .cw-clues-list{list-style:none;margin:0;padding:0;max-height:320px;overflow-y:auto;border:1px solid #ddd;border-radius:4px;}.crossword-widget .cw-clue{padding:0.3em 0.5em;cursor:pointer;border-bottom:1px solid #eee;line-height:1.3;}.crossword-widget .cw-clue:last-child{border-bottom:none;}.crossword-widget .cw-clue:hover{background:#f5f5f5;}.crossword-widget .cw-clue-active{background:#d4eaff;}.crossword-widget .cw-cn{font-weight:700;min-width:1.8em;display:inline-block;}

/* ==== sudoku-widget ==== */
.sudoku-widget{max-width:380px;margin:1em auto;}.sudoku-widget .su-grid{display:grid;grid-template-columns:repeat(9,2.2em);width:fit-content;margin:0 auto;border:3px solid #333;}.sudoku-widget .su-cell{position:relative;aspect-ratio:1/1;background:#fff;border:1px solid #bbb;display:flex;align-items:center;justify-content:center;font-size:1.1em;font-weight:700;}.sudoku-widget .su-box-tl{border-top:3px solid #333;border-left:3px solid #333;}.sudoku-widget .su-box-t{border-top:3px solid #333;}.sudoku-widget .su-box-l{border-left:3px solid #333;}.sudoku-widget .su-given{color:#222;background:#f0f0f0;}.sudoku-widget .su-cell.su-active{background:#d4eaff;}.sudoku-widget .su-cell.su-related{background:#eef5ff;}.sudoku-widget .su-input{width:100%;height:100%;border:none;background:transparent;text-align:center;font-size:1em;font-weight:700;padding:0;caret-color:transparent;outline:none;}.sudoku-widget .su-input.su-right{color:#16a34a;}.sudoku-widget .su-input.su-wrong{color:#dc2626;}.sudoku-widget .su-check{margin-top:6px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.sudoku-widget .su-msg{margin-left:8px;font-size:0.9em;font-weight:700;}

/* ==== codeword-widget ==== */
.codeword-widget{max-width:560px;margin:1em auto;font-family:var(--font-family-main,sans-serif);text-align:center;}.codeword-widget table{border-collapse:collapse;margin:0 auto;}.codeword-widget .cwd-cell{border:1px solid #777;width:1.85em;height:1.85em;position:relative;padding:0;background:#fff;}.codeword-widget .cwd-n{position:absolute;top:0;left:1px;font-size:0.5em;color:#555;line-height:1;}.codeword-widget .cwd-black-given{background:#1a1a1a;}.codeword-widget .cwd-cell.cwd-black{background:#1a1a1a;}.codeword-widget .cwd-cell.cwd-black .cwd-in{color:transparent;}.codeword-widget .cwd-cell.cwd-black .cwd-n{color:#888;}.codeword-widget .cwd-gl{font-weight:800;font-size:0.95em;display:block;margin-top:0.35em;}.codeword-widget .cwd-in{width:100%;height:100%;border:none;background:transparent;text-align:center;font-weight:700;text-transform:uppercase;outline:none;color:#1d4ed8;padding-top:0.4em;}.codeword-widget .cwd-in.cwd-right{color:#16a34a;}.codeword-widget .cwd-in.cwd-wrong{color:#dc2626;}.codeword-widget .cwd-hint{font-size:0.75em;color:#6b7280;margin:6px 0;}.codeword-widget .cwd-track{display:flex;flex-wrap:wrap;gap:3px;justify-content:center;margin:8px 0;}.codeword-widget .cwd-tr{display:inline-flex;flex-direction:column;align-items:center;border:1px solid #ccc;border-radius:3px;min-width:1.5em;padding:1px 2px;}.codeword-widget .cwd-tr b{font-size:0.55em;color:#666;font-weight:700;}.codeword-widget .cwd-tr-in{width:1.3em;height:1.1em;border:none;background:transparent;text-align:center;font-weight:800;font-size:0.8em;text-transform:uppercase;outline:none;color:#1d4ed8;padding:0;}.codeword-widget .cwd-tr.cwd-got{border-color:#16a34a;background:#f0fdf4;}.codeword-widget .cwd-check{margin-top:6px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.codeword-widget .cwd-msg{margin-left:8px;font-size:0.9em;font-weight:700;}

/* ==== setsquare-widget ==== */
.setsquare-widget table{border-collapse:collapse;margin:0 auto;}.setsquare-widget td{text-align:center;font-weight:700;padding:2px;}.setsquare-widget .ss-cell{border:1.5px solid #999;width:2.3em;height:2.3em;font-size:1.05em;background:#fff;}.setsquare-widget .ss-given{background:#f2f2f2;}.setsquare-widget .ss-op{width:1.6em;color:#444;}.setsquare-widget .ss-t{color:var(--accent-on-light,#1a1a1a);}.setsquare-widget .ss-in{width:100%;height:100%;border:none;background:transparent;text-align:center;font-size:1em;font-weight:700;outline:none;color:#1d4ed8;}.setsquare-widget .ss-in.ss-right{color:#16a34a;}.setsquare-widget .ss-in.ss-wrong{color:#dc2626;}.setsquare-widget .ss-check{margin-top:8px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.setsquare-widget .ss-msg{margin-left:8px;font-size:0.9em;font-weight:700;}

/* ==== pathfinder-widget ==== */
.pathfinder-widget{max-width:420px;margin:1em auto;font-family:var(--font-family-main,sans-serif);text-align:center;}.pathfinder-widget .pf-wrap{position:relative;display:inline-block;}.pathfinder-widget .pf-grid{display:grid;width:fit-content;margin:0 auto;border:2px solid #333;background:#fff;position:relative;font-size:14px;}.pathfinder-widget .pf-c{width:2em;height:2em;line-height:2em;font-weight:700;border:1px solid #ddd;cursor:pointer;user-select:none;position:relative;z-index:2;color:#1a1a1a;}.pathfinder-widget .pf-c.pf-on{background:rgba(37,99,235,0.18);color:#1d4ed8;}.pathfinder-widget .pf-c.pf-start{background:#fbcfe8;}.pathfinder-widget .pf-c.pf-start.pf-on{background:#f9a8d4;}.pathfinder-widget .pf-c.pf-no{background:#fecaca !important;transition:background 0.1s;}.pathfinder-widget svg.pf-trail{position:absolute;inset:0;z-index:1;pointer-events:none;}.pathfinder-widget .pf-words{list-style:none;padding:0;margin:10px 0 0;column-count:2;column-gap:18px;}.pathfinder-widget .pf-w{font-size:0.85em;text-align:left;margin:2px 0;}.pathfinder-widget .pf-w.pf-done{text-decoration:line-through;color:#16a34a;}.pathfinder-widget .pf-w.pf-done::after{content:' \2713';}.pathfinder-widget .pf-reset{margin-top:8px;font-size:0.85em;padding:3px 10px;background:#1e3a5f;color:#93c5fd;border:1px solid #2a4a7f;border-radius:4px;cursor:pointer;}.pathfinder-widget .pf-msg{margin-left:8px;font-size:0.9em;font-weight:700;}


/** ContinentalModeller-overrides.css — title overrides for base.css **/

/** Continental Modeller (CM) — title overrides for base.css (fonts only).
 *
 * CM's print type, READ FROM THE PDF (not eyeballed — pdf pages 14-60 span probe):
 *   body 8pt (~45k chars)      FrutigerLTStd-Light          → Frutiger Light (humanist sans)
 *   sub-heads/captions 8pt     FrutigerLTStd-BoldCn         → Frutiger Bold Condensed
 *   display up to 42pt         FrutigerLTStd-UltraBlack     → Frutiger UltraBlack
 *   italic accents             FrutigerLTStd-LightItalic
 * A single-family humanist-sans design (PECO house style — sister title Railway Modeller is the
 * serif one). Frutiger is a licensed commercial face, so everything maps to the closest FREE
 * Google family with the same weight span: Fira Sans (300/400/700/900 + italic) and
 * Fira Sans Condensed (the BoldCn sub-heads/captions). If PECO supply web-licensed Frutiger woff2
 * we would swap in the real ones.
 *
 * Fonts only — layout/colour stay on base.css. Isolated to the "cm"/"continental" title.
 */

:root {
    /* Running body → Fira Sans (Light in print; weight set on the body class below). */
    --font-family-main:         "Fira Sans", "Helvetica Neue", Arial, sans-serif;
    /* Sans furniture (eyebrow, sub-heads, bylines, captions) → Fira Sans Condensed (≈ BoldCn). */
    --font-family-secondary:    "Fira Sans Condensed", "Fira Sans", Arial, sans-serif;
    --font-family-condensed:    "Fira Sans Condensed", "Fira Sans", Arial, sans-serif;
    --standfirst-font:          "Fira Sans", "Helvetica Neue", Arial, sans-serif;
    /* Display (headline / hero headline / dropcap) → Fira Sans at UltraBlack weight. */
    --font-family-main-display: "Fira Sans", "Helvetica Neue", Arial, sans-serif;
    --headline-font-serif:      "Fira Sans", "Helvetica Neue", Arial, sans-serif;
    --headline-font-sans:       "Fira Sans", "Helvetica Neue", Arial, sans-serif;
    --headline-weight:          900;   /* FrutigerLTStd-UltraBlack display headlines */
    --pull-quote-font:          "Fira Sans", "Helvetica Neue", Arial, sans-serif;
}

/* Body copy is LIGHT in print (FrutigerLTStd-Light). */
.article-full-body { font-weight: 300; }
.article-full-body .ld_bold { font-weight: 700; }

/* FONTS — inlined from Google Fonts (the reader doesn't follow @import; the @font-face woff2 src
   on fonts.gstatic.com is fetched directly). Fira Sans 300/300i/400/700/900 + Fira Sans Condensed
   400/700. */
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf1VFn2lg.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf8VFn2lg.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf0VFn2lg.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf7VFn2lg.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf3VFn2lg.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf2VFn2lg.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9f4kDNxMZdWfMOD5VvkrBiQyf4VFk.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreSxf6TF0.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreQhf6TF0.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreShf6TF0.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreRRf6TF0.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreSRf6TF0.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreSBf6TF0.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnPKreRhf6.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5VvmojLeTY.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5Vvk4jLeTY.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5Vvm4jLeTY.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5VvlIjLeTY.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5VvmIjLeTY.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5VvmYjLeTY.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9E4kDNxMZdWfMOD5Vvl4jL.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eSxf6TF0.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eQhf6TF0.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eShf6TF0.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eRRf6TF0.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eSRf6TF0.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eSBf6TF0.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnLK3eRhf6.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eSxf6TF0.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eQhf6TF0.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eShf6TF0.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eRRf6TF0.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eSRf6TF0.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eSBf6TF0.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasans/v18/va9B4kDNxMZdWfMOD5VnFK_eRhf6.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfvtrftV.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfLtrftV.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfrtrftV.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfXtrftV.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfntrftV.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfjtrftV.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfbtrQ.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMl0ciZb.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMB0ciZb.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMh0ciZb.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMd0ciZb.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMt0ciZb.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMp0ciZb.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fira Sans Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firasanscondensed/v11/wEOsEADFm8hSaQTFG18FErVhsC9x-tarWU3IuMR0cg.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}



/* ==== EXTERNALIZED PER-ARTICLE STYLES (generated by phase 4 — do not edit) ==== */
div[article="article_14-1.xml"],body.art-article_14-1{--accent:#2e7d32 !important;--accent-dark:#2e7d32 !important;--fft-accent:#2e7d32 !important;--t3-accent:#2e7d32 !important;--tof-accent:#2e7d32 !important;--standfirst-fg:#fff !important;--standfirst-bg:#2e7d32 !important;--accent-on-light:#2e7d32 !important;--boxout-border-color:#2e7d32 !important;--boxout-border-color-dark:#2e7d32 !important;--pull-quote-color:#2e7d32 !important;--pull-quote-border-color:#2e7d32 !important;--toc-section-span-bg:#2e7d32 !important;}div[article="article_14-1.xml"] p.dropcap::first-letter,body.art-article_14-1 p.dropcap::first-letter{color:#231f20!important;}div[article="article_14-1.xml"] .article-boxout,body.art-article_14-1 .article-boxout{border-top:3px solid #2e7d32!important;}div[article="article_14-1.xml"] p.article-pull-quote,body.art-article_14-1 p.article-pull-quote{border-top-color:#2e7d32!important;border-bottom-color:#2e7d32!important;}
div[article="article_24-1.xml"],body.art-article_24-1{--accent:#cc0000 !important;--accent-dark:#cc0000 !important;--fft-accent:#cc0000 !important;--t3-accent:#cc0000 !important;--tof-accent:#cc0000 !important;--standfirst-fg:#fff !important;--standfirst-bg:#cc0000 !important;--accent-on-light:#cc0000 !important;--boxout-border-color:#cc0000 !important;--boxout-border-color-dark:#cc0000 !important;--pull-quote-color:#cc0000 !important;--pull-quote-border-color:#cc0000 !important;--toc-section-span-bg:#cc0000 !important;}div[article="article_24-1.xml"] p.dropcap::first-letter,body.art-article_24-1 p.dropcap::first-letter{color:#231f20!important;}div[article="article_24-1.xml"] .article-boxout,body.art-article_24-1 .article-boxout{border-top:3px solid #cc0000!important;}div[article="article_24-1.xml"] p.article-pull-quote,body.art-article_24-1 p.article-pull-quote{border-top-color:#cc0000!important;border-bottom-color:#cc0000!important;}
div[article="article_3-1.xml"],body.art-article_3-1{--accent:#1565c0 !important;--accent-dark:#1565c0 !important;--fft-accent:#1565c0 !important;--t3-accent:#1565c0 !important;--tof-accent:#1565c0 !important;--standfirst-fg:#fff !important;--standfirst-bg:#1565c0 !important;--accent-on-light:#1565c0 !important;--boxout-border-color:#1565c0 !important;--boxout-border-color-dark:#1565c0 !important;--pull-quote-color:#1565c0 !important;--pull-quote-border-color:#1565c0 !important;--toc-section-span-bg:#1565c0 !important;}div[article="article_3-1.xml"] p.dropcap::first-letter,body.art-article_3-1 p.dropcap::first-letter{color:#1565c0!important;}div[article="article_3-1.xml"] .article-boxout,body.art-article_3-1 .article-boxout{border-top:3px solid #1565c0!important;}div[article="article_3-1.xml"] p.article-pull-quote,body.art-article_3-1 p.article-pull-quote{border-top-color:#1565c0!important;border-bottom-color:#1565c0!important;}
div[article="article_36-1.xml"],body.art-article_36-1{--accent:#e65100 !important;--accent-dark:#e65100 !important;--fft-accent:#e65100 !important;--t3-accent:#e65100 !important;--tof-accent:#e65100 !important;--standfirst-fg:#fff !important;--standfirst-bg:#e65100 !important;--accent-on-light:#1a1a1a !important;--boxout-border-color:#e65100 !important;--boxout-border-color-dark:#e65100 !important;--pull-quote-color:#1a1a1a !important;--pull-quote-border-color:#e65100 !important;--toc-section-span-bg:#e65100 !important;}div[article="article_36-1.xml"] p.dropcap::first-letter,body.art-article_36-1 p.dropcap::first-letter{color:#231f20!important;}div[article="article_36-1.xml"] .article-boxout,body.art-article_36-1 .article-boxout{border-top:3px solid #e65100!important;}div[article="article_36-1.xml"] p.article-pull-quote,body.art-article_36-1 p.article-pull-quote{border-top-color:#e65100!important;border-bottom-color:#e65100!important;}
div[article="article_48-1.xml"],body.art-article_48-1{--accent:#2e7d32 !important;--accent-dark:#2e7d32 !important;--fft-accent:#2e7d32 !important;--t3-accent:#2e7d32 !important;--tof-accent:#2e7d32 !important;--standfirst-fg:#fff !important;--standfirst-bg:#2e7d32 !important;--accent-on-light:#2e7d32 !important;--boxout-border-color:#2e7d32 !important;--boxout-border-color-dark:#2e7d32 !important;--pull-quote-color:#2e7d32 !important;--pull-quote-border-color:#2e7d32 !important;--toc-section-span-bg:#2e7d32 !important;}div[article="article_48-1.xml"] p.dropcap::first-letter,body.art-article_48-1 p.dropcap::first-letter{color:#231f20!important;}div[article="article_48-1.xml"] .article-boxout,body.art-article_48-1 .article-boxout{border-top:3px solid #2e7d32!important;}div[article="article_48-1.xml"] p.article-pull-quote,body.art-article_48-1 p.article-pull-quote{border-top-color:#2e7d32!important;border-bottom-color:#2e7d32!important;}
div[article="article_56-1.xml"],body.art-article_56-1{--accent:#cc0000 !important;--accent-dark:#cc0000 !important;--fft-accent:#cc0000 !important;--t3-accent:#cc0000 !important;--tof-accent:#cc0000 !important;--standfirst-fg:#fff !important;--standfirst-bg:#cc0000 !important;--accent-on-light:#cc0000 !important;--boxout-border-color:#cc0000 !important;--boxout-border-color-dark:#cc0000 !important;--pull-quote-color:#cc0000 !important;--pull-quote-border-color:#cc0000 !important;--toc-section-span-bg:#cc0000 !important;}div[article="article_56-1.xml"] p.dropcap::first-letter,body.art-article_56-1 p.dropcap::first-letter{color:#231f20!important;}div[article="article_56-1.xml"] .article-boxout,body.art-article_56-1 .article-boxout{border-top:3px solid #cc0000!important;}div[article="article_56-1.xml"] p.article-pull-quote,body.art-article_56-1 p.article-pull-quote{border-top-color:#cc0000!important;border-bottom-color:#cc0000!important;}
div[article="article_64-1.xml"],body.art-article_64-1{--accent:#e65100 !important;--accent-dark:#e65100 !important;--fft-accent:#e65100 !important;--t3-accent:#e65100 !important;--tof-accent:#e65100 !important;--standfirst-fg:#fff !important;--standfirst-bg:#e65100 !important;--accent-on-light:#1a1a1a !important;--boxout-border-color:#e65100 !important;--boxout-border-color-dark:#e65100 !important;--pull-quote-color:#1a1a1a !important;--pull-quote-border-color:#e65100 !important;--toc-section-span-bg:#e65100 !important;}div[article="article_64-1.xml"] p.dropcap::first-letter,body.art-article_64-1 p.dropcap::first-letter{color:#231f20!important;}div[article="article_64-1.xml"] .article-boxout,body.art-article_64-1 .article-boxout{border-top:3px solid #e65100!important;}div[article="article_64-1.xml"] p.article-pull-quote,body.art-article_64-1 p.article-pull-quote{border-top-color:#e65100!important;border-bottom-color:#e65100!important;}
div[article="article_74-1.xml"],body.art-article_74-1{--accent:#1565c0 !important;--accent-dark:#1565c0 !important;--fft-accent:#1565c0 !important;--t3-accent:#1565c0 !important;--tof-accent:#1565c0 !important;--standfirst-fg:#fff !important;--standfirst-bg:#1565c0 !important;--accent-on-light:#1565c0 !important;--boxout-border-color:#1565c0 !important;--boxout-border-color-dark:#1565c0 !important;--pull-quote-color:#1565c0 !important;--pull-quote-border-color:#1565c0 !important;--toc-section-span-bg:#1565c0 !important;}div[article="article_74-1.xml"] p.dropcap::first-letter,body.art-article_74-1 p.dropcap::first-letter{color:#1565c0!important;}div[article="article_74-1.xml"] .article-boxout,body.art-article_74-1 .article-boxout{border-top:3px solid #1565c0!important;}div[article="article_74-1.xml"] p.article-pull-quote,body.art-article_74-1 p.article-pull-quote{border-top-color:#1565c0!important;border-bottom-color:#1565c0!important;}
div[article="article_80-1.xml"],body.art-article_80-1{--accent:#1565c0 !important;--accent-dark:#1565c0 !important;--fft-accent:#1565c0 !important;--t3-accent:#1565c0 !important;--tof-accent:#1565c0 !important;--standfirst-fg:#fff !important;--standfirst-bg:#1565c0 !important;--accent-on-light:#1565c0 !important;--boxout-border-color:#1565c0 !important;--boxout-border-color-dark:#1565c0 !important;--pull-quote-color:#1565c0 !important;--pull-quote-border-color:#1565c0 !important;--toc-section-span-bg:#1565c0 !important;}div[article="article_80-1.xml"] p.dropcap::first-letter,body.art-article_80-1 p.dropcap::first-letter{color:#1565c0!important;}div[article="article_80-1.xml"] .article-boxout,body.art-article_80-1 .article-boxout{border-top:3px solid #1565c0!important;}div[article="article_80-1.xml"] p.article-pull-quote,body.art-article_80-1 p.article-pull-quote{border-top-color:#1565c0!important;border-bottom-color:#1565c0!important;}
div[article="article_84-1.xml"],body.art-article_84-1{--accent:#1565c0 !important;--accent-dark:#1565c0 !important;--fft-accent:#1565c0 !important;--t3-accent:#1565c0 !important;--tof-accent:#1565c0 !important;--standfirst-fg:#fff !important;--standfirst-bg:#1565c0 !important;--accent-on-light:#1565c0 !important;--boxout-border-color:#1565c0 !important;--boxout-border-color-dark:#1565c0 !important;--pull-quote-color:#1565c0 !important;--pull-quote-border-color:#1565c0 !important;--toc-section-span-bg:#1565c0 !important;}div[article="article_84-1.xml"] p.dropcap::first-letter,body.art-article_84-1 p.dropcap::first-letter{color:#1565c0!important;}div[article="article_84-1.xml"] .article-boxout,body.art-article_84-1 .article-boxout{border-top:3px solid #1565c0!important;}div[article="article_84-1.xml"] p.article-pull-quote,body.art-article_84-1 p.article-pull-quote{border-top-color:#1565c0!important;border-bottom-color:#1565c0!important;}
div[article="article_86-1.xml"],body.art-article_86-1{--accent:#1565c0 !important;--accent-dark:#1565c0 !important;--fft-accent:#1565c0 !important;--t3-accent:#1565c0 !important;--tof-accent:#1565c0 !important;--standfirst-fg:#fff !important;--standfirst-bg:#1565c0 !important;--accent-on-light:#1565c0 !important;--boxout-border-color:#1565c0 !important;--boxout-border-color-dark:#1565c0 !important;--pull-quote-color:#1565c0 !important;--pull-quote-border-color:#1565c0 !important;--toc-section-span-bg:#1565c0 !important;}div[article="article_86-1.xml"] p.dropcap::first-letter,body.art-article_86-1 p.dropcap::first-letter{color:#1565c0!important;}div[article="article_86-1.xml"] .article-boxout,body.art-article_86-1 .article-boxout{border-top:3px solid #1565c0!important;}div[article="article_86-1.xml"] p.article-pull-quote,body.art-article_86-1 p.article-pull-quote{border-top-color:#1565c0!important;border-bottom-color:#1565c0!important;}
div[article="article_88-1.xml"],body.art-article_88-1{--accent:#cc0000 !important;--accent-dark:#cc0000 !important;--fft-accent:#cc0000 !important;--t3-accent:#cc0000 !important;--tof-accent:#cc0000 !important;--standfirst-fg:#fff !important;--standfirst-bg:#cc0000 !important;--accent-on-light:#cc0000 !important;--boxout-border-color:#cc0000 !important;--boxout-border-color-dark:#cc0000 !important;--pull-quote-color:#cc0000 !important;--pull-quote-border-color:#cc0000 !important;--toc-section-span-bg:#cc0000 !important;}div[article="article_88-1.xml"] p.dropcap::first-letter,body.art-article_88-1 p.dropcap::first-letter{color:#cc0000!important;}div[article="article_88-1.xml"] .article-boxout,body.art-article_88-1 .article-boxout{border-top:3px solid #cc0000!important;}div[article="article_88-1.xml"] p.article-pull-quote,body.art-article_88-1 p.article-pull-quote{border-top-color:#cc0000!important;border-bottom-color:#cc0000!important;}
div[article="article_89-1.xml"],body.art-article_89-1{--accent:#1565c0 !important;--accent-dark:#1565c0 !important;--fft-accent:#1565c0 !important;--t3-accent:#1565c0 !important;--tof-accent:#1565c0 !important;--standfirst-fg:#fff !important;--standfirst-bg:#1565c0 !important;--accent-on-light:#1565c0 !important;--boxout-border-color:#1565c0 !important;--boxout-border-color-dark:#1565c0 !important;--pull-quote-color:#1565c0 !important;--pull-quote-border-color:#1565c0 !important;--toc-section-span-bg:#1565c0 !important;}div[article="article_89-1.xml"] p.dropcap::first-letter,body.art-article_89-1 p.dropcap::first-letter{color:#1565c0!important;}div[article="article_89-1.xml"] .article-boxout,body.art-article_89-1 .article-boxout{border-top:3px solid #1565c0!important;}div[article="article_89-1.xml"] p.article-pull-quote,body.art-article_89-1 p.article-pull-quote{border-top-color:#1565c0!important;border-bottom-color:#1565c0!important;}
/* -- inline-style utility classes -- */
.s-03c48993{color:#c95a23 !important;}
.s-1360ef87{color:#8c909b !important;}
.s-15d1fcf8{color:#a72c31 !important;}
.s-24aaf653{object-position:50% 65% !important;}
.s-2b901bed{color:#0081a1 !important;}
.s-335304f8{object-position:50% 45% !important;}
.s-3a7cdf8d{object-position:center 40.0% !important;}
.s-3e7215e7{object-position:center 60.0% !important;}
.s-405fb4ab{color:#0072bc !important;}
.s-45d553dc{--sa:#e65100 !important;--sa-on-bg:#ffffff !important;--sa-text:#1a1a1a !important;}
.s-45fe4cbb{object-position:50% 35% !important;}
.s-4bd87007{object-position:50% 55% !important;}
.s-4f291bae{color:#007f49 !important;}
.s-5ac3c58e{color:#427c4b !important;}
.s-6f2c29fb{color:#dd5943 !important;}
.s-70fe4286{object-position:50% 50% !important;}
.s-73e94852{--sa:#2e7d32 !important;--sa-on-bg:#ffffff !important;--sa-text:#2e7d32 !important;}
.s-75e0825d{object-position:50% 60% !important;}
.s-75e7faab{--panel-bg:#ffffff !important;--panel-fg:#111111 !important;}
.s-7e214262{object-position:50% 40% !important;}
.s-cdd45d3c{object-position:center 65.0% !important;}
.s-d07ba922{object-position:center 50.0% !important;}
.s-d16c79e8{color:#0081a1 !important;font-size:1.5em !important;}
.s-e0db4727{object-position:center 45.0% !important;}
.s-e926ad16{--sa:#cc0000 !important;--sa-on-bg:#ffffff !important;--sa-text:#cc0000 !important;}
.s-f23880f1{color:#bd1b20 !important;}
.s-f7fe089f{--sa:#1565c0 !important;--sa-on-bg:#ffffff !important;--sa-text:#1565c0 !important;}
