/* ====================================================================
   ARTICLE CANVAS  v2.0.0  (23 October 2026)
   One reading system for every page with writing on it: the Grounded
   Canvas design from claude-notes/article-redesign-handoff.md, tuned by
   Deyne on 23 October in the design switcher (claude-test-facility/
   design-switcher/skins/canvas.css was the mock-up; this file is built
   from it with his settings baked in as the defaults). How it is wired:
   claude-notes/claude_article-canvas-plan.md and the 23 October handover.

   Loads on every front-end page, after every other theme stylesheet,
   with js/article-article-canvas.js. Every rule is scoped to .ss-canvas, which
   functions.php puts on html and body; reading pages also carry
   .ss-canvas-read (the wash, the still nebula, the compact header).
   The per-template stylesheets are not edited: the sections below
   re-point the selectors they already use. This file is the single
   owner of the reading system, the way retro-tv.css owns the TV.

   THE DIALS. Each setting is a data-cv-* attribute on html, printed by
   functions.php from ss_canvas_defaults(). To retune the site, change
   a value there (and the matching token below where one exists). On the
   local site the tune bar (in article-article-canvas.js, only when html carries
   data-cv-tune) turns the same dials live; Copy settings on the bar
   gives the values to paste back.

   Sections
     1. Tokens and the dials
     2. The nebula on reading pages, the wash, the header, the footer,
        comments, the three squares
     3. The prose well, pictures, outlines, the last round
     4. Shared components: cards, stat tiles, kickers, callouts
     5. News story
     6. Biography
     7. Series guide
     8. Episode pages (panel text) and lessons
     9. Science puzzle
    10. Plain pages
    11. Hubs, lists and search
    12. Space pages
    13. Phones (900px and under)
    14. Reduced motion and print
   ==================================================================== */

/* ====================================================================
   1. TOKENS, AND THE DIALS THE TUNE BAR TURNS
   The tune bar (js/canvas-tune.js, localhost only) writes data-cv-*
   attributes on html; the rules after the block read them. Without the
   bar the defaults stand.
   ==================================================================== */
html.ss-canvas {
    --cv-prose-w: 900px;      /* the reading column (Prose dial) */
    --cv-wide-w: var(--content-w, 1520px);   /* hero, strips, figures, end matter: the site's content width (Frame dial) */
    --cv-quote-w: calc(var(--cv-prose-w) + 200px);  /* pull quotes, between the two */
    --cv-canvas-w: var(--site-w, 1600px);    /* the channel: the header's width (Frame dial) */
    --cv-size: 20px;          /* Body dial */
    --cv-lh: 1.75;
    --cv-radius: 14px;
    --cv-display: 'Space Grotesk', sans-serif;
    --cv-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --cv-mono: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
    --cv-star-dim: 1;         /* the nebula's opacity on reading pages (Nebula dial: still, bright) */
    --cv-numbers: block;      /* "Section 01" kickers: block or none */

    /* THE COLOURS (Deyne, 23 October, evening): the site's own recipe
       for every orange and brown, the handoff's Electric Cyan, Signal
       Green and light type on top. The rating keeps the site's honey.
       The tune bar's Colours dial swaps to the full handoff palette
       (data-cv-palette="studio") or to the site's tokens ("site"). */
    --cv-ink: #E5E7EB;                             /* paragraphs */
    --cv-bright: #F3F4F6;                          /* Starlight: headings, lead, bold */
    --cv-muted: rgba(243, 244, 246, 0.62);
    --cv-faint: rgba(243, 244, 246, 0.4);
    --cv-line: rgba(243, 244, 246, 0.1);
    --cv-accent: var(--supernova-orange, #CD5A24);  /* the site's orange */
    --cv-accent-soft: rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.06);
    --cv-label: #00BCFF;                           /* Electric Cyan: card tags, stat labels */
    --cv-kicker: #00BCFF;                          /* "Section 01" above a heading */
    --cv-class: #38EF7D;                           /* Signal Green: the classroom box */
    --cv-honey: var(--rating-honey, #f2b830);      /* the rating, untouched */
    --cv-surface: var(--glass-bg);                 /* the site's glass, the card material */
    /* The same glass mirrored for the two rating cards on the right
       (Deyne, 23 October, night): the site's glass runs dark at the top
       left to light at the bottom right, so this runs dark at the top
       RIGHT to light at the bottom left, and the two light ends meet in
       the middle of the row. The stroke goes to the outer, right edge. */
    --cv-surface-r: linear-gradient(225deg, var(--glass-top) 0%, var(--glass-bottom) 100%);
    --cv-surface-border: rgba(255, 255, 255, 0.08);
    --cv-channel-rgb: var(--deep-space-rgb, 26, 12, 8);  /* only the flat washes read this */
}
/* The handoff's cyan and light type re-point the site's shared tokens on
   the html element, so chips, card titles and links that read them
   follow. The site's oranges and browns are left alone on purpose. */
html.ss-canvas:not([data-cv-palette="site"]) {
    --nebula-turquoise: #00BCFF;
    --nebula-turquoise-hover: #33C9FF;
    --nebula-turquoise-rgb: 0, 188, 255;
    --starlight: #F3F4F6;
    --starlight-muted: #E5E7EB;
}
/* THE STUDIO PALETTE: the full handoff, Flame Orange and Espresso too. */
html.ss-canvas[data-cv-palette="studio"] {
    --cv-accent: #FF6B35;
    --cv-accent-soft: rgba(255, 107, 53, 0.06);
    --cv-surface: #1E1310;
    --cv-surface-r: #1E1310;
    --cv-surface-border: rgba(243, 244, 246, 0.1);
    --cv-channel-rgb: 11, 10, 18;
    --supernova-orange: #FF6B35;
    --supernova-orange-hover: #E55A26;
    --supernova-orange-light: #FF8A5E;
    --supernova-orange-rgb: 255, 107, 53;
}
/* THE SITE PALETTE: the theme's own tokens from the top of style.css,
   for comparison, and the fallback if the studio palette is turned down. */
html.ss-canvas[data-cv-palette="site"] {
    --cv-ink: var(--starlight-muted, #E2E8F0);
    --cv-bright: var(--starlight, #F7FAFC);
    --cv-muted: rgba(247, 250, 252, 0.66);
    --cv-faint: rgba(247, 250, 252, 0.45);
    --cv-line: rgba(247, 250, 252, 0.1);
    --cv-accent: var(--supernova-orange, #CD5A24);
    --cv-accent-soft: rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.06);
    --cv-label: var(--nebula-turquoise, #4A9FD4);
    --cv-kicker: var(--supernova-orange, #CD5A24);
    --cv-class: var(--highlight-yellow, #fadb67);
    --cv-surface: var(--glass-bg);
    --cv-surface-r: linear-gradient(225deg, var(--glass-top) 0%, var(--glass-bottom) 100%);
    --cv-surface-border: rgba(255, 255, 255, 0.08);
    --cv-channel-rgb: var(--deep-space-rgb, 26, 12, 8);
}
/* SWITCHER: the frame, prose and body dials. */
html.ss-canvas[data-cv-frame="handoff"] { --cv-canvas-w: 1280px; --cv-wide-w: 1140px; }
html.ss-canvas[data-cv-prose="720"] { --cv-prose-w: 720px; }
html.ss-canvas[data-cv-prose="800"] { --cv-prose-w: 800px; }
html.ss-canvas[data-cv-prose="900"] { --cv-prose-w: 900px; }
html.ss-canvas[data-cv-prose="960"] { --cv-prose-w: 960px; }
html.ss-canvas[data-cv-size="18"] { --cv-size: 18px; }
html.ss-canvas[data-cv-size="19"] { --cv-size: 19px; }
html.ss-canvas[data-cv-size="20"] { --cv-size: 20px; }
html.ss-canvas[data-cv-size="22"] { --cv-size: 22px; }
html.ss-canvas[data-cv-size="24"] { --cv-size: 24px; }  /* classroom TV */
html.ss-canvas[data-cv-ink="bright"] { --cv-ink: var(--starlight, #F7FAFC); }
html.ss-canvas[data-cv-labels="inter"] { --cv-mono: var(--cv-body); }
html.ss-canvas[data-cv-stars="bright"] { --cv-star-dim: 1; }
html.ss-canvas[data-cv-numbers="off"] { --cv-numbers: none; }
/* SWITCHER: the big numeral (Deyne liked Bento's chapter numbers): the
   number alone above the heading, Space Grotesk, in the kicker colour,
   about a third of the size Bento used. The small "Section 01" kicker
   stays on the dial. */
/* The numerals in Space Beo Grotesk, the heavy cut Deyne had made for the
   Space Timers (the theme's own copy in space-timers/, digits only).
   Numbers only; every other heading stays Space Grotesk. */
@font-face { font-family: "Space Beo Grotesk"; font-weight: 900; font-display: swap; src: url("../space-timers/SpaceBeoGrotesk-900.woff2") format("woff2"); }
html.ss-canvas[data-cv-numbers="big"] :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2::before {
    content: counter(cv-sec, decimal-leading-zero);
    font-family: "Space Beo Grotesk", var(--cv-display);
    font-weight: 900;
    font-size: 2.1rem;
    line-height: 1;
    letter-spacing: 0;
    text-transform: none;
    color: var(--cv-kicker);
    opacity: 0.92;
    margin-bottom: 0.35rem;
}

/* Things that exist only for the canvas (the compact rating card, the
   squares, the source tile, the class card, the wash div) vanish when the
   class is off, so As now on the local bar is the old page exactly. */
body:not(.ss-canvas) .ss-canvas-only { display: none !important; }
body:not(.ss-canvas) .cv-wash,
body:not(.ss-canvas) .cv-comments-toggle { display: none !important; }


/* ====================================================================
   2. THE NEBULA ON READING PAGES, AND THE CHANNEL
   The baked nebula (html.ss-baked::before) and the field stars
   (.ss-field, .ss-tw) come from ss-cosmos.css. On a reading page they
   hold still and dim; the tune bar's Stars dial puts the drift back.
   The channel is a gradient, not a box: solid in the middle, fading to
   nothing at the sides so the nebula shows round the edges.
   ==================================================================== */
html.ss-canvas.ss-canvas-read:not([data-cv-stars="moving"]).ss-baked::before,
html.ss-canvas.ss-canvas-read:not([data-cv-stars="moving"]) .ss-field,
html.ss-canvas.ss-canvas-read:not([data-cv-stars="moving"]) .ss-tw {
    animation: none !important;
}
html.ss-canvas.ss-canvas-read .ss-tw { opacity: 0; }
html.ss-canvas.ss-canvas-read.ss-baked::before,
html.ss-canvas.ss-canvas-read .ss-field.is-on {
    opacity: var(--cv-star-dim);
}

/* THE WASH (Deyne, 23 October, evening). One fixed layer behind the
   whole page, made by article-canvas.js (div.cv-wash), in place of the old box
   channel on the article. Colour and fade are two layers: the background
   is the colour (Wash dial), the mask is the fade across the screen
   (Fade dial), opacity is the strength (Strength dial). It sits behind
   the translucent header and footer too, so the article pours out of the
   header instead of starting under it. Reading containers are lifted
   above it (z-index 1); the sticky header already is. */
.ss-canvas .cv-wash {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    /* The header's own recipe: lunar rock at the header's solidity at
       the top, deep space at the header's darker end below (ss-cosmos.css:
       --chrome-solid 0.86 and 0.86 minus 0.28). */
    background: linear-gradient(180deg,
        rgb(61 35 24 / var(--cv-wash-top, 0.86)) 0%,
        rgb(26 12 8 / var(--cv-wash-bottom, 0.58)) 100%);
    -webkit-mask-image: var(--cv-fade);
    mask-image: var(--cv-fade);
    opacity: 1;
}
.ss-canvas.ss-canvas-read .cv-wash { display: block; }
/* The glow: the warm radial Cinema had behind the opening, in the
   site's orange. Off unless the Glow dial says so. */
.ss-canvas .cv-wash::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 60% 40% at 50% 12%, rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.22), transparent 70%);
    opacity: 0;
}
html[data-cv-glow="on"] .cv-wash::before { opacity: 1; }
/* The fade, from two sliders (article-canvas.js writes the numbers on html):
   --cv-reach, how far the solid part runs out from the centre as a
   percentage of the screen (10 narrow, 50 the whole screen), and
   --cv-edge, how much tint is left at the screen's edge (0 none, 1 all).
   Cinema was reach 28, edge 0.15; Tight was 15 and 0. The Fade buttons
   only move the sliders. */
html.ss-canvas {
    --cv-reach: 30;           /* Deyne, 23 October */
    --cv-edge: 0.10;
    --cv-wash-top: 0.969;     /* Strength 89 on the bar: between the header's own 0.86 / 0.58 and solid */
    --cv-wash-bottom: 0.908;
    --cv-fade: linear-gradient(90deg,
        rgb(0 0 0 / var(--cv-edge)) 0%,
        #000 calc(50% - var(--cv-reach) * 1%),
        #000 calc(50% + var(--cv-reach) * 1%),
        rgb(0 0 0 / var(--cv-edge)) 100%);
}
/* The strength, from a slider: article-canvas.js sets --cv-wash-top and
   --cv-wash-bottom on html. 0 is off, the middle is the header's own
   solidity (0.86 and 0.58), the top is solid (1 and 1). */
html.ss-canvas[data-cv-strength="0"] .cv-wash { display: none; }
/* The Wash dial: the header's browns (default), the site's deep space
   flat, or the handoff's Deep Space flat, for comparison. */
html.ss-canvas[data-cv-wash="site"] .cv-wash { background: rgb(26 12 8 / var(--cv-wash-top, 0.86)); }
html.ss-canvas[data-cv-wash="handoff"] .cv-wash { background: rgb(11 10 18 / var(--cv-wash-top, 0.86)); }
/* Lifted above the wash: every page's main element (the page and the
   footer live inside it) and, belt and braces, the known wrappers. The
   header is sticky and positioned already. */
.ss-canvas main.site-main,
.ss-canvas-read .news-article-container,
.ss-canvas-read .bio-page-container,
.ss-canvas-read .ss-guide-page,
.ss-canvas-read .rf-page,
.ss-canvas-read .sspz-page,
.ss-canvas-read .rf-about,
.ss-canvas-read .rf-contact,
.ss-canvas-read .rf-editorial,
.ss-canvas-read .hwr-page,
.ss-canvas-read .rf-footer,
.ss-canvas-read .main-content-new {
    position: relative;
    z-index: 1;
}


/* SWITCHER: the Header dial. The site's chrome is a warm brown gradient
   (ss-cosmos.css); "Studio tone" draws it in the handoff's Espresso and
   Deep Space so the whole page sits in one tone. */
html.ss-canvas[data-cv-chrome="studio"] .site-header-new {
    background: linear-gradient(145deg, rgb(30 19 16 / var(--chrome-solid, 0.86)), rgb(11 10 18 / calc(var(--chrome-solid, 0.86) - 0.28)));
}
html.ss-canvas[data-cv-chrome="studio"] .rf-footer {
    background: linear-gradient(180deg, rgb(30 19 16 / calc(var(--chrome-solid, 0.86) - 0.50)), rgb(11 10 18 / calc(var(--chrome-solid, 0.86) - 0.28)));
}


/* SWITCHER: Header size and Header on scroll (Deyne, 23 October, night).
   Size, on reading pages and wide screens only: Compact (the default) is
   80px with the logo at 64px from the moment the page loads, and it never
   changes size; Full is the site's 112px header. On scroll: Stays does
   nothing; Hides slides the header away on the way down and back on the
   way up at the same size, a transform only, so nothing ever jumps;
   Shrinks (Full size only) is the comparison: the header leaves the
   page flow (fixed, with the page padded by its full height) so the page
   does not move when it shrinks, the bar animates 112px to 68px and the
   logo is SCALED, not resized, because an image sized "auto" under a cap
   cannot animate its height. article-canvas.js sets cv-head-slim and
   cv-head-hidden on html by scroll direction; off inside an open lesson
   and for reduced motion. */
html.ss-canvas .site-header-new { transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1); }   /* coming back: slower, eased */
html.ss-canvas.cv-head-hidden .site-header-new { transition: transform 0.3s ease-in; }                 /* going away: quicker */
html.ss-canvas .header-container-new { transition: height 0.3s ease; }
html.ss-canvas .site-logo-new { transform-origin: left center; transition: transform 0.3s ease; }
html.ss-canvas[data-cv-headerscroll="hides"].cv-head-hidden .site-header-new { transform: translateY(-101%); }
@media (min-width: 901px) {
    /* Compact: one size, always. */
    html.ss-canvas.ss-canvas-read[data-cv-headersize="compact"] .header-container-new { height: 5rem; }
    html.ss-canvas.ss-canvas-read[data-cv-headersize="compact"] .logo-area .site-logo-new { height: 4rem; max-height: 4rem; }
    /* Full with Shrinks: out of the flow, so the page holds still. */
    html.ss-canvas.ss-canvas-read[data-cv-headersize="full"][data-cv-headerscroll="shrinks"] .site-header-new { position: fixed; top: 0; left: 0; right: 0; }
    html.ss-canvas.ss-canvas-read[data-cv-headersize="full"][data-cv-headerscroll="shrinks"] body { padding-top: 7rem; }
    html.ss-canvas.ss-canvas-read[data-cv-headersize="full"][data-cv-headerscroll="shrinks"].cv-head-slim .header-container-new { height: 4.25rem; }
    html.ss-canvas.ss-canvas-read[data-cv-headersize="full"][data-cv-headerscroll="shrinks"].cv-head-slim .site-logo-new { transform: scale(0.6); }
}
@media (prefers-reduced-motion: reduce) {
    html.ss-canvas .site-header-new,
    html.ss-canvas .header-container-new,
    html.ss-canvas .site-logo-new { transition: none; }
}

/* SWITCHER: the Footer dial. Band: the footer's own gradient and orange
   line, as now. On the wash: no band, the footer sits on the same wash as
   the article with a hairline above it. Soft edge: the band fades in
   from the wash instead of starting on a line. */
html.ss-canvas.ss-canvas-read[data-cv-footer="wash"] .rf-footer {
    background: none;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}
html.ss-canvas.ss-canvas-read[data-cv-footer="soft"] .rf-footer {
    border-top: 0;
    padding-top: 2.5rem;
    background: linear-gradient(180deg, rgb(61 35 24 / 0) 0, rgb(61 35 24 / 0.45) 160px, rgb(26 12 8 / 0.7) 100%);
}

/* SWITCHER: Comments. article-canvas.js moves the comments and the form into
   .cv-comments-body and puts a toggle row in front: "Join the discussion"
   with the count. Folded: the row alone until it is pressed; a page that
   already has comments shows them and folds only the form. */
.ss-canvas .cv-comments-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    max-width: var(--cv-prose-w);
    margin: 3rem auto 0;
    padding: 1.1rem 1.4rem;
    box-sizing: border-box;
    background: var(--cv-surface);
    border: 1px solid var(--cv-surface-border);
    border-radius: var(--cv-radius);
    color: var(--cv-bright);
    font: 600 1rem/1.3 var(--cv-body);
    text-align: left;
    cursor: pointer;
    transition: border-color 0.2s ease;
}
.ss-canvas .cv-comments-toggle:hover { border-color: var(--cv-accent); }
.ss-canvas .cv-comments-toggle small {
    font-family: var(--cv-mono);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cv-label);
}
.ss-canvas .cv-comments-toggle::after {
    content: "+";
    font-family: var(--cv-display);
    font-size: 1.4rem;
    line-height: 1;
    color: var(--cv-accent);
    margin-left: 0.5rem;
}
.ss-canvas .cv-comments-open > .cv-comments-toggle::after { content: "\2212"; }  /* a minus sign */
html:not([data-cv-comments="folded"]) .ss-canvas .cv-comments-toggle { display: none; }
html[data-cv-comments="folded"] .ss-canvas .cv-comments-body { display: none; }
html[data-cv-comments="folded"] .ss-canvas .cv-comments-open > .cv-comments-body { display: block; }
html[data-cv-comments="folded"] .ss-canvas .cv-comments-has > .cv-comments-body { display: block; }
html[data-cv-comments="folded"] .ss-canvas .cv-comments-has:not(.cv-comments-open) .comment-respond { display: none; }
.ss-canvas .comments-wrapper { max-width: var(--cv-wide-w); margin-left: auto; margin-right: auto; }

/* SWITCHER: the three blocks top right of the title: Share, Copy link,
   YouTube, drawn like the footer's social squares, icon only, the name
   on hover. Copy link turns the site's green (#38A169, the share pop-up's
   own) for a moment. On phones they sit in a row under the byline. */
.ss-canvas .news-article > .news-header { position: relative; }
.ss-canvas .cv-tools {
    position: absolute;
    right: 2rem;              /* in from the frame edge, not on it */
    top: 3rem;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
/* The footer's social squares, exactly (style.css .rf-footer-social a):
   2.25rem, a 4px corner, a faint line, no fill, the icon at half white;
   turquoise on hover. */
.ss-canvas .cv-tool {
    width: 2.25rem;
    height: 2.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    box-sizing: border-box;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 4px;
    color: rgba(255, 255, 255, 0.5);
    text-decoration: none;
    cursor: pointer;
    transition: all 0.2s;
}
.ss-canvas .cv-tool svg { width: 1rem; height: 1rem; fill: currentColor; display: block; }
.ss-canvas .cv-tool:hover,
.ss-canvas .cv-tool:focus-visible {
    border-color: var(--nebula-turquoise);
    color: var(--nebula-turquoise);
    background: rgba(205, 90, 36, 0.1);
}
/* Each square its own colour, like the footer's: Share the site's link
   blue, Copy link the copied green, YouTube its red. */
.ss-canvas .cv-tool--share:hover,
.ss-canvas .cv-tool--share:focus-visible { border-color: var(--nebula-turquoise); color: var(--nebula-turquoise); background: rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.1); }
.ss-canvas .cv-tool--copy:hover,
.ss-canvas .cv-tool--copy:focus-visible { border-color: #38A169; color: #38A169; background: rgba(56, 161, 105, 0.1); }
.ss-canvas .cv-tool--youtube:hover,
.ss-canvas .cv-tool--youtube:focus-visible { border-color: #ff0000; color: #ff0000; background: rgba(255, 0, 0, 0.1); }
.ss-canvas .cv-tool.is-copied,
.ss-canvas .cv-tool.is-copied:hover { background: #38A169; border-color: #38A169; color: #fff; }
html[data-cv-topright="none"] .cv-tools { display: none; }
@media (max-width: 900px) {
    .ss-canvas .cv-tools { position: static; flex-direction: row; margin: 1rem 0 0.25rem; }
}


/* ====================================================================
   3. THE PROSE WELL
   One set of rules for every reading surface. The list in :is() names
   the wrappers each template already has; a new template joins by
   carrying .cv-prose. Specificity: .ss-canvas plus the deepest entry
   (.rf-page .entry-content) beats every per-template rule without
   !important, except on phones where mobile.css forces sizes (section
   13 answers in kind).
   ==================================================================== */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) {
    font-family: var(--cv-body);
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
    counter-reset: cv-sec;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) p {
    font-family: var(--cv-body);
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
    margin: 0 0 1.3em;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) :is(ul, ol) {
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
    margin: 0 0 1.3em 1.4em;
    padding: 0;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) li {
    font-size: inherit;
    line-height: inherit;
    color: inherit;
    margin-bottom: 0.45em;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) :is(strong, b) {
    color: var(--cv-bright);
    font-weight: 700;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) a:not(.news-source-btn):not(.bio-hub-btn):not([class*="btn"]) {
    color: var(--cv-accent);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) a:not([class*="btn"]):hover {
    color: var(--supernova-orange-light, #D4742E);
}

/* The lead paragraph: bigger, in Starlight, opened by a drop cap in
   Space Grotesk and orange, about three lines tall. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > p:first-of-type {
    font-size: calc(var(--cv-size) * 1.28);
    line-height: 1.6;
    color: var(--cv-bright);
    font-weight: 400;
    background: none;
    border: 0;
    padding: 0;
    border-radius: 0;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > p:first-of-type::first-letter {
    font-family: var(--cv-display);
    font-weight: 700;
    font-size: 3.05em;
    line-height: 0.78;
    color: var(--cv-accent);
    float: left;
    padding: 0.04em 0.14em 0 0;
}
/* A lead written entirely in bold (some biographies) keeps the lead's
   own weight; the bright colour already marks it out. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > p:first-of-type :is(strong, b) {
    font-weight: 400;
}

/* Headings: Space Grotesk 700, Starlight, no underline bar, a small
   numbered kicker above each h2. Orange leaves the headings and keeps
   its accent jobs. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) :is(h2, h3, h4) {
    font-family: var(--cv-display) !important;
    font-weight: 700 !important;
    color: var(--cv-bright) !important;
    text-transform: none !important;
    letter-spacing: 0 !important;
    text-shadow: none;
    background: none;
    border: 0;
    padding: 0;
    text-wrap: balance;
    display: block;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2 {
    font-size: calc(var(--cv-size) * 1.55);
    line-height: 1.2;
    margin: 3rem 0 1.1rem;
    counter-increment: cv-sec;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2::before {
    content: "Section " counter(cv-sec, decimal-leading-zero);
    display: var(--cv-numbers);
    font-family: var(--cv-mono);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--cv-kicker);
    margin-bottom: 0.5rem;
    position: static;
    width: auto;
    height: auto;
    background: none;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2::after {
    content: none !important;
    display: none !important;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h3 {
    font-size: calc(var(--cv-size) * 1.2) !important;
    line-height: 1.3;
    margin: 2rem 0 0.75rem !important;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h4 {
    font-size: calc(var(--cv-size) * 1.05);
    margin: 1.6rem 0 0.5rem;
}

/* Pull quotes: between the two widths, an orange rule, italic, the
   attribution in the small label face. The breakout is a negative
   margin from the 720px column, floored so it never leaves the screen. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) blockquote {
    box-sizing: border-box;
    width: auto;
    margin: 2.6rem max(calc(50% - var(--cv-quote-w) / 2), calc(50% - 50vw + 1rem));
    padding: 1.6rem 2rem;
    border: 0;
    border-left: 3px solid var(--cv-accent);
    border-radius: 0 12px 12px 0;
    background: var(--cv-accent-soft);
    font-size: calc(var(--cv-size) * 1.15);
    line-height: 1.55;
    font-style: italic;
    color: var(--cv-bright);
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) blockquote p {
    font-size: inherit;
    line-height: inherit;
    color: inherit;
    margin: 0 0 0.8rem;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) blockquote p:last-child { margin-bottom: 0; }
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) blockquote cite {
    display: block;
    margin-top: 0.8rem;
    font-family: var(--cv-mono);
    font-style: normal;
    font-size: 0.66rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--cv-faint);
}

/* Pictures: the text stays at 720px, the pictures may go out to the
   wide track. style.css section 8 keeps the height cap (70vh times the
   picture's shape), so a tall picture never towers; only the width
   limit is raised here. Hand-written figures round a [caption] are
   display: contents (section 8), so the breakout goes on .wp-caption. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) {
    --article-pic-w: var(--cv-wide-w);
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .wp-caption,
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > figure:not(:has(> .wp-caption)),
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > p > img:only-child {
    margin-left: max(calc(50% - var(--cv-wide-w) / 2), calc(50% - 50vw + 1rem));
    margin-right: max(calc(50% - var(--cv-wide-w) / 2), calc(50% - 50vw + 1rem));
    margin-top: 2.6rem;
    margin-bottom: 2.6rem;
    max-width: none;
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .wp-caption img,
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > figure img {
    border-radius: var(--cv-radius);
    border: 1px solid var(--cv-line);
}
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) :is(.wp-caption-text, figcaption) {
    font-family: var(--cv-body);
    font-size: 0.8rem;
    font-style: italic;
    line-height: 1.5;
    color: var(--cv-faint);
    text-align: center;
    margin: 0.6rem auto 0;
    max-width: 70ch;
}

/* Tables and code keep their own look but read at the body size. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) table {
    font-size: calc(var(--cv-size) * 0.88);
}


/* SWITCHER: the Pictures dial. article-canvas.js tags every picture box in the
   prose (a .wp-caption, a bare figure, a lone picture in a paragraph)
   with cv-pic, its order (cv-pic--odd, cv-pic--even) and its shape
   (cv-pic--landscape, cv-pic--portrait, cv-pic--square, from the
   picture's own width and height). Centred is the default above.
   Offset: pictures run a little wider than the text and overhang it,
   left then right, with the caption set against the near edge. Wide by
   shape: landscape pictures go out to the frame, portrait and square
   ones sit at the text width. Both drop the hairline border. */
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) { display: flow-root; }  /* holds the floats */
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic {
    /* Offset means the picture sits to one side, hanging out past the
       column, and the words run down beside it: a float, the first to
       the left, the next to the right. The box shrink-wraps the picture,
       so the width goes on the picture itself (the theme fixes the box's
       width with !important). About 55% of the column plus the overhang. */
    --cv-over: min(260px, 13vw);
    --cv-pic: calc(var(--cv-prose-w) * 0.55 + var(--cv-over));
    /* The box is exactly as wide as the picture will be: the same sum the
       picture uses below, from the ratio the script copies onto the box
       (--ss-ar). A tall or square picture is held to the height cap and
       so comes out narrower than --cv-pic; without this the box, its frame
       and its caption stayed at the full --cv-pic (Deyne, 24 October, on
       live). With no ratio yet (or a picture that fails to load) the box
       keeps the full width, so a caption can never collapse. */
    width: min(var(--cv-pic), 100%, calc(var(--article-pic-h, 70vh) * var(--ss-ar, 99)));
    max-width: none;
    clear: both;
    margin: 0.35em 0 1.25rem;
}
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--odd { float: left; margin-left: calc(-1 * var(--cv-over)); margin-right: 2rem; }
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--even { float: right; margin-right: calc(-1 * var(--cv-over)); margin-left: 2rem; }
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic img {
    width: min(var(--cv-pic), calc(var(--article-pic-h, 70vh) * var(--ss-ar, 99)));
    max-width: none;
    margin: 0;
    border: 0;
    border-radius: 10px;
}
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic :is(.wp-caption-text, figcaption) {
    /* The floated box shrink-wraps the picture. A caption with its own
       width would push the box wider than the picture, so it is given no
       width of its own and then told to fill the box: exactly the
       picture's width, wrapping underneath it. */
    display: block;
    width: 0;
    min-width: 100%;
    max-width: none;
    box-sizing: border-box;
    text-align: left;
    margin: 0.5rem 0 0;
}
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--even :is(.wp-caption-text, figcaption) { text-align: right; }
/* Headings, quotes and the boxes start below a picture, never beside it. */
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) :is(h2, h3, h4, blockquote, .cv-callout, .sg-concepts, .sg-facts, table, .ep-concepts) { clear: both; }
html[data-cv-pictures="wide"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic img { border: 0; border-radius: 10px; }
html[data-cv-pictures="wide"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--landscape {
    --article-pic-w: var(--cv-canvas-w);
    --article-pic-h: 84vh;
    margin-left: max(calc(50% - var(--cv-canvas-w) / 2), calc(50% - 50vw + 1rem));
    margin-right: max(calc(50% - var(--cv-canvas-w) / 2), calc(50% - 50vw + 1rem));
}
html[data-cv-pictures="wide"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) :is(.cv-pic--portrait, .cv-pic--square) {
    --article-pic-w: var(--cv-prose-w);
    --article-pic-h: 62vh;
    margin-left: 0;
    margin-right: 0;
    max-width: 100%;
}
@media (max-width: 900px) {
    html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { --cv-over: 0px; float: none; margin: 2rem auto; }
    html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--odd,
    html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--even { margin-left: auto; margin-right: auto; }
    html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic img { width: min(100%, calc(var(--article-pic-h, 70vh) * var(--ss-ar, 99))); margin: 0 auto; }
    html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic :is(.wp-caption-text, figcaption) { text-align: center; margin-left: auto; margin-right: auto; }
}

/* SWITCHER: the Outline dial for the offset pictures (Deyne, 23 October,
   night: the faint frame at the top of the page, round the picture and
   the words beside it, to break the page up). Drawn as a pseudo-element
   on the floated picture box, so it runs from the picture's outer edge
   to the far edge of the column and is as tall as the picture and its
   caption; a long paragraph runs on below it. Hairline: the line only.
   Tint: a soft fill and no line. Picture: a hairline round the picture
   and caption alone. */
html[data-cv-pictures="offset"]:not([data-cv-outline="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { position: relative; }
html[data-cv-pictures="offset"]:not([data-cv-outline="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic::after {
    content: "";
    position: absolute;
    top: -14px;
    bottom: -14px;
    width: calc(var(--cv-prose-w) + var(--cv-over) + 28px);
    border-radius: 16px;
    pointer-events: none;
    z-index: -1;
}
html[data-cv-pictures="offset"]:not([data-cv-outline="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--odd::after { left: -14px; }
html[data-cv-pictures="offset"]:not([data-cv-outline="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--even::after { right: -14px; }
html[data-cv-pictures="offset"][data-cv-outline="hairline"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic::after { border: 1px solid rgba(255, 255, 255, 0.09); }
html[data-cv-pictures="offset"][data-cv-outline="tint"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic::after { background: rgba(255, 255, 255, 0.025); border: 1px solid rgba(255, 255, 255, 0.04); }
html[data-cv-pictures="offset"][data-cv-outline="picture"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic::after { width: auto; left: -10px; right: -10px; top: -10px; bottom: -10px; border-radius: 14px; border: 1px solid rgba(255, 255, 255, 0.09); }
/* The float sits over the frame line, so the frame is drawn behind the
   text with a negative z-index and the picture box makes its own stack. */
html[data-cv-pictures="offset"]:not([data-cv-outline="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { isolation: isolate; }

/* Outline look 4, "Sections" (Deyne, 23 October, night: boxes round the
   text to break up the long scroll). article-canvas.js wraps each heading and
   what follows it in div.cv-sec and marks which side its first picture
   hangs over. The box is a hairline round the section, pushed out on
   that side to take the overhanging picture in; a section with no
   picture hugs the column. */
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec { --cv-over: 0px; }
html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec { --cv-over: min(260px, 13vw); }
html[data-cv-outline="sections"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec {
    display: flow-root;
    margin: 2.25rem -1.5rem;
    padding: 0.25rem 1.5rem 0.5rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 16px;
}
html[data-cv-outline="sections"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec--left { margin-left: calc(-1 * var(--cv-over) - 1.5rem); padding-left: calc(var(--cv-over) + 1.5rem); }
html[data-cv-outline="sections"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec--right { margin-right: calc(-1 * var(--cv-over) - 1.5rem); padding-right: calc(var(--cv-over) + 1.5rem); }
html[data-cv-outline="sections"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec > h2 { margin-top: 1.4rem; }
html[data-cv-outline="sections"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec > :last-child { margin-bottom: 0.6rem; }
@media (max-width: 900px) {
    html[data-cv-outline="sections"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec { margin-left: 0; margin-right: 0; padding-left: 1rem; padding-right: 1rem; }
}

/* SWITCHER: the last round (Deyne, 23 October, late). */

/* Shapes: in Offset, a landscape picture stops floating. "Column" runs it
   the full width of the text; "Wide" takes it out to the frame, as Wide
   by shape does, with the text carrying on underneath. Square and
   upright pictures keep floating with the text beside them. */
html[data-cv-pictures="offset"]:not([data-cv-shapes="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--landscape {
    float: none;
    clear: both;
    width: auto;
    margin: 2.6rem 0;
}
html[data-cv-pictures="offset"]:not([data-cv-shapes="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--landscape img {
    width: min(100%, calc(var(--article-pic-h, 70vh) * var(--ss-ar, 99)));
    margin: 0 auto;
}
html[data-cv-pictures="offset"]:not([data-cv-shapes="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--landscape :is(.wp-caption-text, figcaption) {
    width: auto;
    min-width: 0;
    max-width: 70ch;
    margin: 0.6rem auto 0;
    text-align: center;
}
html[data-cv-pictures="offset"][data-cv-shapes="wide"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--landscape {
    --article-pic-h: 84vh;
    margin-left: max(calc(50% - var(--cv-canvas-w) / 2), calc(50% - 50vw + 1rem));
    margin-right: max(calc(50% - var(--cv-canvas-w) / 2), calc(50% - 50vw + 1rem));
}
/* A wide landscape picture takes no frame in any look: it breaking the
   run of framed pictures is the point (Deyne, 23 October, late). */
html[data-cv-pictures="offset"]:not([data-cv-shapes="off"]) .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic--landscape::after { display: none; }

/* Pic high: a floated picture no taller than a share of the screen, so
   the words beside it and the picture finish nearer together. */
html[data-cv-pichigh="70"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { --article-pic-h: 70vh; }
html[data-cv-pichigh="60"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { --article-pic-h: 60vh; }
html[data-cv-pichigh="50"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { --article-pic-h: 50vh; }
html[data-cv-pichigh="none"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic { --article-pic-h: 999vh; }

/* Rule: a hairline across the column above each numbered heading, the
   same line as the top of the page, a beat at every section. */
html[data-cv-secrule="on"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2 {
    border-top: 1px solid rgba(255, 255, 255, 0.09);
    padding-top: 1.5rem;
}
html[data-cv-secrule="on"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-sec:first-of-type > h2 { border-top: 0; padding-top: 0; }

/* Contents: the numbered sections in one line under the byline, each a
   link; article-canvas.js builds it from the headings. */
.ss-canvas .cv-contents {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.6rem;
    margin: 1.5rem 0 0;
    padding: 0;
    max-width: 820px;
}
.ss-canvas .cv-contents a {
    font-family: var(--cv-body);
    font-size: 0.86rem;
    line-height: 1.4;
    color: var(--cv-muted);
    text-decoration: none;
    transition: color 0.2s ease;
}
.ss-canvas .cv-contents a:hover,
.ss-canvas .cv-contents a:focus-visible { color: var(--cv-bright); }
.ss-canvas .cv-contents a b {
    font-family: "Space Beo Grotesk", var(--cv-display);
    font-weight: 900;
    font-size: 0.95rem;
    color: var(--cv-kicker);
    margin-right: 0.45em;
}
html[data-cv-contents="off"] .cv-contents { display: none; }
.ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2 { scroll-margin-top: 6.5rem; }   /* under the compact header */
/* A contents link glides to its section rather than jumping (Deyne, 23
   October, late); off for anyone who has asked for reduced motion. */
html.ss-canvas:not(.ss-canvas-episode) { scroll-behavior: smooth; }   /* not on episode pages: the lesson chrome does its own scrolling */
@media (prefers-reduced-motion: reduce) { html.ss-canvas { scroll-behavior: auto; } }

/* Tidy: no lone word on a paragraph's last line (Chrome and Edge; Safari
   ignores it and loses nothing). */
html[data-cv-tidy="on"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) p { text-wrap: pretty; }

@media (max-width: 900px) {
    .ss-canvas .cv-contents { gap: 0.4rem 1rem; }
    .ss-canvas .cv-contents a { font-size: 0.82rem; }
}


/* ====================================================================
   4. SHARED COMPONENTS
   Cards (the old sidebar cards, now in the strip and the end matter),
   stat tiles (the dossier numbers), card tags, the classroom box.
   ==================================================================== */
/* A card: the site's own glass material, no blur (nothing to blur but
   the channel), a soft corner. */
.ss-canvas .news-sidebar-card,
.ss-canvas .cv-card {
    background: var(--cv-surface);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 1px solid var(--cv-surface-border);
    border-radius: var(--cv-radius);
    padding: 1.4rem 1.5rem;
    min-width: 0;
    box-sizing: border-box;
}
/* The card tag: the small label face, uppercase, spaced, a rule under. */
.ss-canvas .news-sidebar-title,
.ss-canvas .cv-card-tag {
    font-family: var(--cv-mono);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    margin: 0 0 1rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--cv-line);
}
/* Key findings read at 0.92rem, not 0.78. */
.ss-canvas .news-findings-list li {
    font-family: var(--cv-body);
    font-size: 0.95rem;
    line-height: 1.55;
    color: rgba(247, 250, 252, 0.82);
    padding: 0.5rem 0 0.5rem 1.4rem;
}
.ss-canvas .news-findings-list li::before { font-size: 0.9rem; }
/* Hover on a finding (Deyne, 24 October): news.css grows the row by a
   scale() and nudges the arrow, which inside the capped, scrolling list
   paints outside the box and brings up scrollbars. Here the row stays
   put: the arrow goes yellow and the words go bright, nothing else. */
.ss-canvas .news-findings-list li:hover {
    transform: none;
    background: none;
    color: var(--cv-bright);
}
.ss-canvas .news-findings-list li:hover::before { transform: none; color: var(--highlight-yellow, #fadb67); }
.ss-canvas .news-findings-list li:hover::after { opacity: 0; }
.ss-canvas .news-findings-list { overflow-x: hidden; }

/* Stat tiles: the dossier strip becomes a row of tiles, each with the
   figure in Space Grotesk and the label in the small face. Used by the
   news dossier and the biography dossier. */
.ss-canvas :is(.news-dossier, .bio-dossier) {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 1rem;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    margin: 1.25rem 0 0;
}
.ss-canvas :is(.news-dossier-stat, .bio-dossier-stat) {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.35rem;
    text-align: left;
    background: var(--cv-surface);
    border: 1px solid var(--cv-surface-border);
    border-left: 3px solid var(--cv-label);
    border-right: 1px solid var(--cv-surface-border);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    min-width: 0;
    box-sizing: border-box;
}
.ss-canvas :is(.news-dossier-stat, .bio-dossier-stat)::before,
.ss-canvas :is(.news-dossier-stat, .bio-dossier-stat)::after {
    content: none !important;
    display: none !important;
}
.ss-canvas .news-dossier-stat.news-dossier-stat-rating {
    border-left-color: var(--cv-honey);
    align-items: center;
    text-align: center;
}
.ss-canvas :is(.news-dossier-num, .bio-dossier-num) {
    font-family: var(--cv-display);
    font-weight: 700;
    font-size: 1.45rem;
    line-height: 1.1;
    color: var(--cv-bright);
    font-variant-numeric: tabular-nums;
    order: 2;
}
.ss-canvas :is(.news-dossier-label, .bio-dossier-label) {
    font-family: var(--cv-mono);
    font-weight: 600;
    font-size: 0.56rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cv-label);
    order: 1;
}
.ss-canvas .news-dossier-stat-rating .news-dossier-label { order: 3; color: var(--cv-honey); }

/* The classroom box: one job for the highlight colour on articles. */
.ss-canvas .cv-card.cv-card--class { border-left: 3px solid var(--cv-class); }
.ss-canvas .cv-card--class .cv-card-tag { color: var(--cv-class); }

/* A wide callout inside the prose (an analogy, a definition): the card
   material with an orange hairline, out at the wide track. Articles opt
   in with class="cv-callout" on a div or aside. */
.ss-canvas .cv-callout {
    box-sizing: border-box;
    margin: 2.6rem max(calc(50% - var(--cv-wide-w) / 2), calc(50% - 50vw + 1rem));
    padding: 1.9rem 2.2rem;
    background: var(--cv-surface);
    border: 1px solid rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.35);
    border-radius: 16px;
}
.ss-canvas .cv-callout h3 {
    font-family: var(--cv-display);
    font-weight: 700;
    font-size: 1.2rem;
    color: var(--cv-bright);
    margin: 0 0 0.7rem;
}
.ss-canvas .cv-callout p {
    font-size: calc(var(--cv-size) * 0.92);
    line-height: 1.7;
    color: rgba(247, 250, 252, 0.8);
    margin: 0;
}


/* ====================================================================
   5. NEWS STORY  (single-news.php, news.css)
   The two-column shell goes. .news-layout, .news-body and .news-sidebar
   lose their boxes (display: contents), so the hero, the article and
   every card are direct children of .news-article, and a grid with
   explicit rows places them:
     1 hero (title block, then the picture)    2 hero caption
     3 Key Findings | compact rating            4 stat tiles
     5 the prose well                           6 share
     7 Primary Source | Revisiting              8 the full rating card
     9 Other Sources                           10 back link
   ==================================================================== */
.ss-canvas .news-article-container {
    max-width: var(--cv-canvas-w);
    margin: 0 auto;
    padding: 0 clamp(16px, 3vw, 48px) 3rem;
    box-sizing: border-box;
}
.ss-canvas .news-breadcrumb {
    max-width: var(--cv-wide-w);
    margin: 1.5rem auto 1rem;
    font-family: var(--cv-body);
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cv-faint);
}
.ss-canvas .news-article {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    column-gap: 1.25rem;
    row-gap: 0;
    align-items: start;
    max-width: var(--cv-wide-w);
    margin: 0 auto;
}
.ss-canvas .news-layout,
.ss-canvas .news-body,
.ss-canvas .news-sidebar {
    display: contents;
}
.ss-canvas .news-body::before,
.ss-canvas .news-body .entry-content::before { content: none !important; display: none !important; }
.ss-canvas .news-article > *,
.ss-canvas .news-article .news-body > *,
.ss-canvas .news-article .news-sidebar > * {
    grid-column: 1 / -1;
    min-width: 0;
    box-sizing: border-box;
}
/* Rows. The compact rating card is new markup in single-news.php; the
   unrated card (news-rating-card-none) takes its cell instead. */
.ss-canvas .news-article > .news-hero-image,
.ss-canvas .news-article > .news-header          { grid-row: 1; }
.ss-canvas .news-article > .news-hero-caption    { grid-row: 2; }
.ss-canvas .news-article .news-sidebar-findings  { grid-row: 3; grid-column: 1; margin-top: 2.75rem; }
.ss-canvas .news-article .cv-rating              { grid-row: 3; grid-column: 2; margin-top: 2.75rem; }
.ss-canvas .news-article .news-dossier           { grid-row: 4; }
.ss-canvas .news-article .news-content           { grid-row: 5; }
.ss-canvas .news-article .news-share             { grid-row: 6; }
.ss-canvas .news-article .news-source-card       { grid-row: 7; grid-column: 1; margin-top: 3.25rem; }
.ss-canvas .news-article .cv-class               { grid-row: 7; grid-column: 2; margin-top: 3.25rem; }
/* The end matter in two columns instead of a stack: the full rating card
   on the left over two rows, Revisiting and Other Sources on the right. */
.ss-canvas .news-article .news-rating-card       { grid-row: 8 / span 2; grid-column: 1; margin-top: 1.25rem; }
.ss-canvas .news-article .news-feedback-card     { grid-row: 8; grid-column: 2; margin-top: 1.25rem; align-self: start; }
.ss-canvas .news-article .news-sources-card      { grid-row: 9; grid-column: 2; margin-top: 0; align-self: start; }
.ss-canvas .news-article:not(:has(.cv-class)) .news-feedback-card { grid-row: 7; margin-top: 3.25rem; }
.ss-canvas .news-article:not(:has(.cv-class)) .news-sources-card  { grid-row: 8; margin-top: 1.25rem; }
.ss-canvas .news-article .news-rating-card-none  { grid-row: 3; grid-column: 2; margin-top: 2.75rem; }
.ss-canvas .news-article .news-back-btn          { grid-row: 10; grid-column: 1 / -1; justify-self: center; margin-top: 2rem; }
/* Key Findings never taller than the rating card beside it (Deyne, 23
   October, late): article-canvas.js caps the card at the rating card's
   height when it would be taller (a grid row cannot do it alone: a
   percentage min-height on the item beats any max-height), and the list
   scrolls inside, with a thin scrollbar in the card's orange. On a story
   with no rating card the findings take both columns. */
.ss-canvas .news-article:has(.cv-rating) .news-sidebar-findings {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
}
.ss-canvas .news-article:has(.cv-rating) .news-sidebar-findings .news-findings-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.6rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.55) transparent;
}
.ss-canvas .news-findings-list::-webkit-scrollbar { width: 6px; }
.ss-canvas .news-findings-list::-webkit-scrollbar-track { background: transparent; }
.ss-canvas .news-findings-list::-webkit-scrollbar-thumb { background: rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.55); border-radius: 3px; }
.ss-canvas .news-article:not(:has(.cv-rating)):not(:has(.news-rating-card-none)) .news-sidebar-findings { grid-column: 1 / -1; }
/* An unrated story has no full rating card for the left column, so Other
   Sources takes both columns, its list in two. */
.ss-canvas .news-article:not(:has(.news-rating-card:not(.news-rating-card-none))) .news-sources-card { grid-column: 1 / -1; margin-top: 1.25rem; }   /* a gap under the pair */
.ss-canvas .news-article:not(:has(.news-rating-card:not(.news-rating-card-none))) .news-sources-list { columns: 2; column-gap: 2.5rem; }
.ss-canvas .news-article:not(:has(.news-rating-card:not(.news-rating-card-none))) .news-sources-item { break-inside: avoid; }

/* The two pairs stand the same height. */
.ss-canvas .news-article .news-sidebar-findings,
.ss-canvas .news-article .cv-rating,
.ss-canvas .news-article .news-rating-card-none,
.ss-canvas .news-article .news-source-card,
.ss-canvas .news-article .cv-class { align-self: stretch; }
/* ---- The hero, the prose well and the compact rating card. KEEP THIS
   BLOCK HERE: it was cut twice by edits that spanned the markers below. ---- */
/* The hero: the title block first, the picture under it, no scrim.
   The figure holds the img then .news-hero-inner; column-reverse puts
   the words on top. */
.ss-canvas .news-hero-overlay,
.ss-canvas .news-hero-image {
    display: flex;
    flex-direction: column;
    margin: 0;
    border-radius: 0;
    isolation: auto;
    /* The figure reserved a 16:9 box with its overflow hidden; now it
       holds the words as well as the picture, so it grows to fit (the
       picture keeps its own 16:9 below). A plain column with the words
       ordered first, not column-reverse: that packs from the bottom and
       on phones the title spilled out of the top and was clipped. */
    aspect-ratio: auto !important;
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;   /* mobile.css pins the phone hero's height with !important */
    border: 1px solid var(--cv-line);
    border-radius: 0 !important;
}
.ss-canvas .news-hero-inner { order: -1; }
.ss-canvas .news-hero-overlay::after { display: none; }
.ss-canvas .news-hero-overlay img,
.ss-canvas .news-hero-image img {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
    /* Square, the only square picture on the page: the hero is the frame
       of the page, not one of the pictures (Deyne, 23 October, late).
       Its border is the figure's own hairline, so it meets the frame on
       one line. */
    border-radius: 0;
    border: 0;
    margin-top: 2.25rem;
}
.ss-canvas .news-hero-inner,
.ss-canvas .news-header {
    position: static;
    padding: 2.5rem 0 0;
    max-width: 820px;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    text-align: left;
}
.ss-canvas .news-category-tag {
    font-family: var(--cv-mono);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--cv-kicker);
    margin: 0 0 0.9rem;
}
.ss-canvas .news-title {
    font-family: var(--cv-display);
    font-weight: 700;
    font-size: clamp(2.1rem, 4.6vw, 3.3rem);
    line-height: 1.08;
    color: var(--cv-bright);
    margin: 0 0 1rem;
    text-shadow: none;
    text-wrap: balance;
}
.ss-canvas .news-hero-hook,
.ss-canvas .news-hook {
    font-family: var(--cv-body);
    font-size: clamp(1.05rem, 2vw, 1.3rem);
    line-height: 1.55;
    color: var(--cv-muted);
    margin: 0 0 1.4rem;
    max-width: 46ch;
    text-shadow: none;
    border: 0;
    background: none;
    padding: 0;
    font-style: normal;
}
.ss-canvas .news-byline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.7rem;
    font-family: var(--cv-body);
    font-size: 0.78rem;
    color: var(--cv-faint);
    margin: 0;
}
.ss-canvas .news-byline .news-reading-time {
    font-weight: 700;
    font-size: 0.64rem;
    letter-spacing: 0.06em;
    padding: 0.25rem 0.6rem;
    border-radius: 5px;
    color: var(--cv-label);
    background: rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.12);
}
.ss-canvas .news-hero-caption {
    font-family: var(--cv-body);
    font-size: 0.78rem;
    font-style: italic;
    line-height: 1.5;
    color: var(--cv-faint);
    text-align: center;
    max-width: 70ch;
    margin: 0.6rem auto 0;
}

/* The prose well. */
.ss-canvas .news-article .news-content {
    width: 100%;
    max-width: var(--cv-prose-w);
    justify-self: center;
    margin: 3.25rem auto 0;
    background: none;
    border: 0;
    padding: 0;
    box-shadow: none;
    overflow: visible;
}
.ss-canvas .news-article .news-share {
    width: 100%;
    max-width: var(--cv-prose-w);
    justify-self: center;
    margin: 2rem auto 0;
}

/* The compact rating card (new markup): the badge beside Method and
   Certainty, the six cells two across, the date and the link. Uses the
   rating system's own badge, bars and colours. */
.ss-canvas .cv-rating { border-left: 3px solid var(--cv-honey); }
.ss-canvas .cv-rating-top {
    display: flex;
    align-items: center;
    gap: 1.4rem;
    margin-bottom: 1rem;
}
.ss-canvas .cv-rating-badge { width: 104px; height: 104px; flex: none; display: block; }   /* bigger than the tile's 62px, so the two read as different things */
.ss-canvas .cv-rating-fields { display: grid; gap: 0.5rem; min-width: 0; }
.ss-canvas .cv-rfield b {
    display: block;
    font-family: var(--cv-mono);
    font-weight: 600;
    font-size: 0.56rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cv-label);
}
.ss-canvas .cv-rfield span {
    font-family: var(--cv-body);
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--cv-bright);
}
.ss-canvas .cv-rating .news-rating-key {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem 0.9rem;
    margin: 1.1rem 0 0;
    padding: 1rem 0 0;
    border-top: 1px solid var(--cv-line);
    list-style: none;
}
.ss-canvas .cv-rating .news-rating-key-row { margin: 0; }
.ss-canvas .cv-rating-foot {
    font-family: var(--cv-body);
    font-size: 0.72rem;
    line-height: 1.6;
    color: var(--cv-faint);
    margin: 1rem 0 0;
}
.ss-canvas .cv-rating-foot a { color: var(--cv-label); text-decoration: underline; text-underline-offset: 2px; }

/* The Mirror dial (Deyne, 23 October, night). "Right": the card on the
   OUTER right edge of each bento row, site wide (not every right-hand
   card: a row of four tiles mirrors its fourth only, so the row is not
   symmetrical), takes the site's glass turned the other way (so the light
   ends of the row meet in the middle) and carries its flash on the right,
   outer edge; the text inside is not touched.
   "Rating": the compact rating card and the fourth tile only. "None".
   article-canvas.js reads each card's own flash colour and width off its left
   border once, stores them on the card, and adds cv-mirror; this rule
   does the rest. Tripled class to outrank the card rules above. */
.ss-canvas .cv-mirror.cv-mirror.cv-mirror {
    background: var(--cv-surface-r);
    border-left: 1px solid var(--cv-surface-border);
    border-right: var(--cv-flash-w, 1px) solid var(--cv-flash, var(--cv-surface-border));
}
.ss-canvas .news-article .news-sidebar-findings { border-left: 3px solid var(--cv-accent); }   /* the flash news.css gave it, which the card rule above had taken */
.ss-canvas .news-article .cv-rating { border-left: 3px solid var(--cv-honey); }

/* The fourth tile as the Primary Source (Deyne, 23 October, night): the
   rating is already in the card above it, so the tile carries the study
   button instead, in the share button's turquoise. single-news.php
   prints both tiles; the Tile 4 dial shows one or the other. */
html:not([data-cv-tile4="source"]) .cv-tile-source { display: none !important; }
.ss-canvas .news-dossier-stat.cv-tile-source { gap: 0.55rem; border-left-color: var(--cv-label); }   /* blue, like its button (Deyne, second thoughts) */
.ss-canvas .cv-tile-source .news-dossier-label { color: var(--cv-label); order: 1; }
.ss-canvas .cv-tile-btn {
    order: 2;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 1.3rem;
    border-radius: 8px;
    background: rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.12);
    color: var(--nebula-turquoise);
    border: 1px solid rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.35);
    font-family: var(--cv-body);
    font-size: 0.8rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.2s ease, transform 0.2s ease;
}
.ss-canvas .cv-tile-btn:hover,
.ss-canvas .cv-tile-btn:focus-visible {
    background: rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.22);
    color: var(--nebula-turquoise);
    transform: translateY(-1px);
}
.ss-canvas .cv-tile-host {
    order: 3;
    font-family: var(--cv-mono);
    font-size: 0.56rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--cv-faint);
}

/* The classroom card's list (restored 23 October, night: it had gone
   with a cut and the browser's own blue links and bullets showed). */
html[data-cv-classbox="off"] .cv-class           { display: none !important; }
.ss-canvas .cv-class-list { list-style: none; margin: 0; padding: 0; }
.ss-canvas .cv-class-list li {
    font-family: var(--cv-body);
    font-size: 0.95rem;
    line-height: 1.6;
    color: rgba(247, 250, 252, 0.82);
    padding: 0.5rem 0;
    border-bottom: 1px solid rgba(247, 250, 252, 0.05);
}
.ss-canvas .cv-class-list li:last-child { border-bottom: 0; }
.ss-canvas .cv-class-list .cv-class-k {
    display: inline-block;
    min-width: 3.6em;
    margin-right: 0.4em;
    font-family: var(--cv-mono);
    font-size: 0.6rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cv-class);
}
.ss-canvas .cv-class-list a { color: var(--cv-accent); text-decoration: underline; text-underline-offset: 2px; }
.ss-canvas .cv-class-list a:hover { color: var(--supernova-orange-light, #D4742E); }

/* The full rating card fills its column; its badge and grades read
   better left-aligned there than centred in a wide box. */
.ss-canvas .news-article .news-rating-card:not(.news-rating-card-none) { width: 100%; max-width: none; }
.ss-canvas .news-article .news-rating-card:not(.news-rating-card-none) .news-rating-badge-wrap { justify-content: flex-start; }
.ss-canvas .news-article .news-sources-card { width: 100%; max-width: none; }

/* The breadcrumbs go (Deyne, 23 October, late night): the logo goes home,
   the nav names every section, the story's kicker is now the link to its
   section. Search's path under a result comes from the SEO plugin's
   structured data, not from this row, so nothing is lost there. */
.ss-canvas :is(.news-breadcrumb, .hub-breadcrumb, .bn-breadcrumb, .archive-rf-breadcrumb, .breadcrumb-nav) { display: none !important; }
.news-category-tag a { color: inherit; text-decoration: none; }
.news-category-tag a:hover,
.news-category-tag a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }

/* The unrated story's card and tile (Deyne, 23 October, late night):
   every story keeps the same shape, and an unrated one says why. The
   old sidebar "No Rating" card is hidden on the canvas. */
.ss-canvas .news-article .news-rating-card-none { display: none !important; }
.ss-canvas .cv-rating--none .cv-rating-badge { opacity: 0.7; }
.ss-canvas .cv-rating-why {
    font-family: var(--cv-body);
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--cv-muted);
    margin: 1.1rem 0 0;
    padding-top: 1rem;
    border-top: 1px solid var(--cv-line);
}
.ss-canvas .cv-tile-unrated .news-rating-dossier-badge { opacity: 0.7; }
html[data-cv-tile4="source"] .ss-canvas .news-dossier-stat-rating:not(.cv-tile-source):not(.cv-tile-unrated) { display: none !important; }

/* The Share button under the article keeps its blue on hover (news.css
   turns it yellow); the Other Sources list grows to its content instead
   of scrolling inside its card (Deyne, 23 October, night). */
.ss-canvas .news-share-btn:hover,
.ss-canvas .news-share-btn:focus-visible {
    background: rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.22);
    border-color: rgba(var(--nebula-turquoise-rgb, 74, 159, 212), 0.5);
    color: var(--nebula-turquoise);
}
.ss-canvas .news-sources-list { max-height: none; overflow: visible; }
/* The two orange buttons (Read the original study, Contact us) drawn
   like the Share button: a faint orange fill, orange text and a hairline
   at rest; the whole thing faint yellow on hover (Deyne, 23 October,
   late). */
.ss-canvas .news-source-btn,
.ss-canvas .news-feedback-btn {
    background: rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.12);
    border: 1px solid rgba(var(--supernova-orange-rgb, 205, 90, 36), 0.35);
    color: var(--supernova-orange);
    box-shadow: none;
}
.ss-canvas .news-source-btn:hover,
.ss-canvas .news-source-btn:focus-visible,
.ss-canvas .news-feedback-btn:hover,
.ss-canvas .news-feedback-btn:focus-visible {
    background: rgba(var(--highlight-yellow-rgb, 250, 219, 103), 0.14);
    border-color: rgba(var(--highlight-yellow-rgb, 250, 219, 103), 0.45);
    color: var(--highlight-yellow);
    transform: translateY(-1px);
}

/* The strips under the article (watch, puzzles, read) and the comments
   sit inside the channel at the wide track. */
.ss-canvas .news-article-container > .news-strip,
.ss-canvas .news-article-container > .comments-wrapper {
    max-width: var(--cv-wide-w);
    margin-left: auto;
    margin-right: auto;
}


/* ====================================================================
   6. BIOGRAPHY  (page-biography.php, biography.css)
   The biography article carries .news-article too, so the grid above
   applies. Its own children get their rows here: Fact File and the
   Educator Hub card in the strip, the three dossier stats as tiles,
   the timeline at prose width, More Educators in the end matter.
   ==================================================================== */
.ss-canvas .bio-page-container {
    max-width: var(--cv-canvas-w);
    margin: 0 auto;
    padding: 0 clamp(16px, 3vw, 48px) 3rem;
    box-sizing: border-box;
}
.ss-canvas .bio-article .bio-factfile-card        { grid-row: 3; grid-column: 1; margin-top: 2.75rem; }
.ss-canvas .bio-article .bio-hub-card             { grid-row: 3; grid-column: 2; margin-top: 2.75rem; }
.ss-canvas .bio-article .bio-dossier              { grid-row: 4; }
.ss-canvas .bio-article .bio-content              { grid-row: 5; }
.ss-canvas .bio-article .bio-timeline-section     { grid-row: 6; }
.ss-canvas .bio-article .bio-share                { grid-row: 7; }
.ss-canvas .bio-article .bio-sidebar > .news-sidebar-card:not(.bio-factfile-card):not(.bio-hub-card) {
    grid-row: 8;
    width: 100%;
    max-width: var(--cv-prose-w);
    justify-self: center;
    margin-top: 3.25rem;
}
.ss-canvas .bio-article .bio-content,
.ss-canvas .bio-article .bio-timeline-section,
.ss-canvas .bio-article .bio-share {
    width: 100%;
    max-width: var(--cv-prose-w);
    justify-self: center;
    background: none;
    border: 0;
    padding: 0;
    box-shadow: none;
    overflow: visible;
}
.ss-canvas .bio-article .bio-content { margin-top: 3.25rem; }
.ss-canvas .bio-article .bio-timeline-section { margin-top: 2.5rem; }
/* biography.css sets the heading rule with !important; answered in kind. */
.ss-canvas .bio-content h2,
.ss-canvas .bio-sec-title {
    display: block !important;
    font-family: var(--cv-display) !important;
    font-size: calc(var(--cv-size) * 1.55) !important;
    font-weight: 700 !important;
    color: var(--cv-bright) !important;
    text-transform: none !important;
    letter-spacing: 0 !important;
    margin: 3rem 0 1.1rem !important;
}
.ss-canvas .bio-content h2::after,
.ss-canvas .bio-sec-title::after {
    content: none !important;
    display: none !important;
}
.ss-canvas .bio-sec-title { margin-top: 0 !important; }
.ss-canvas .bio-timeline-event,
.ss-canvas .bio-timeline-year {
    font-size: calc(var(--cv-size) * 0.92);
    line-height: 1.6;
}
.ss-canvas .bio-timeline-event { color: var(--cv-ink); }


/* ====================================================================
   7. SERIES GUIDE  (page-series-guide.php, series-guide.css)
   One column: the rail's cards go under the article, two across. The
   prose moves to the well; the episode card grid, the OU band and the
   strips stay at the wide track, the one place a multi-card grid is
   right.
   ==================================================================== */
.ss-canvas .ss-guide-page {
    max-width: var(--cv-canvas-w);
    padding-left: clamp(16px, 3vw, 48px);
    padding-right: clamp(16px, 3vw, 48px);
    box-sizing: border-box;
}
.ss-canvas .sg-article { max-width: var(--cv-wide-w); margin-left: auto; margin-right: auto; }
.ss-canvas .sg-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
}
.ss-canvas .sg-railcol {
    position: static;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
    align-items: start;
}
.ss-canvas .sg-card {
    background: var(--cv-surface);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border-radius: var(--cv-radius);
}
.ss-canvas .ss-guide-page .sg-content {
    max-width: var(--cv-prose-w);
    margin: 2rem auto 0;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    padding: 0;
    box-shadow: none;
}
.ss-canvas .sg-content .sg-lead {
    font-size: calc(var(--cv-size) * 1.28);
    line-height: 1.6;
    color: var(--cv-bright);
}
/* The concept cards and fact boxes inside the guide text go out to the
   wide track, like a callout. */
.ss-canvas .sg-content :is(.sg-concepts, .sg-facts) {
    margin-left: max(calc(50% - var(--cv-wide-w) / 2), calc(50% - 50vw + 1rem));
    margin-right: max(calc(50% - var(--cv-wide-w) / 2), calc(50% - 50vw + 1rem));
}
.ss-canvas .sg-content .sg-concept-desc,
.ss-canvas .sg-content .sg-facts li {
    font-size: calc(var(--cv-size) * 0.88);
    line-height: 1.6;
}
.ss-canvas .sg-standfirst { font-size: clamp(1.05rem, 2vw, 1.3rem); line-height: 1.55; }


/* ====================================================================
   8. EPISODE PAGES (panel text) AND LESSONS
   The TV, the VCR and the lesson machinery are untouched. The text in
   the info panel reads in the well; the lead loses its orange box; the
   h2 drops the capitals and the yellow bar. Lesson paragraphs and lists
   take the body size and the 720px measure inside their section cards.
   ==================================================================== */
.ss-canvas .bn-panel-content { counter-reset: cv-sec; }
/* The panels lose their glass box: the words sit on the wash, as an
   article's do (Deyne, 23 October, late night). The TV, the VCR and
   the lesson's controls keep theirs. */
.ss-canvas .bn-panel {
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    box-shadow: none;
    overflow: visible;
}
.ss-canvas .bn-panel::before { display: none; }
/* The lesson: the header card and the 5E section cards without their
   glass fill and shadow; each section keeps its phase colour on the left
   and a hairline. The progress bar (a sticky control) and the mission
   control footer keep their panels. */
.ss-canvas .ss-lesson-header {
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    box-shadow: none;
}
.ss-canvas .ss-section,
.ss-canvas .ss-section:hover {
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: none;
}
/* Three classes here: the shared paragraph rule above sets the margin
   shorthand with the same weight, so the panel's auto margins need one
   class more to win. */
.ss-canvas .bn-panels-zone .bn-panel-content > :is(p, h2, h3, h4, ul, ol, blockquote) {
    max-width: var(--cv-prose-w);
    margin-left: auto;
    margin-right: auto;
}
.ss-canvas .bn-panels-zone .bn-panel-content > p { margin-bottom: 1.3em; }
.ss-canvas .bn-panel-content > p:first-of-type,
.ss-canvas .bn-panel-content p.ep-lead {
    border-left: 0;
    background: none;
    padding: 0;
    border-radius: 0;
    font-weight: 400;
    font-size: calc(var(--cv-size) * 1.28);
    color: var(--cv-bright);
    margin-bottom: 1.75rem;
}
.ss-canvas .bn-panels-zone .bn-panel-content h2 {
    font-size: calc(var(--cv-size) * 1.55);
    text-transform: none;
    text-shadow: none;
    padding-bottom: 0;
    margin: 3rem auto 1.1rem;
}
.ss-canvas .bn-panel-content h3 {
    font-family: var(--cv-display);
    font-size: calc(var(--cv-size) * 1.2);
    text-transform: none;
    letter-spacing: 0;
    color: var(--cv-bright);
}
.ss-canvas .bn-panel-content .ep-concepts { max-width: none; }
.ss-canvas .bn-episodes-grid-header p {
    font-size: calc(var(--cv-size) * 0.92);
    line-height: 1.6;
}

/* Lessons: the reading text only. Quiz options, buttons, labels and
   the simulations keep their own sizes. */
.ss-canvas .ss-lesson .ss-section > p,
.ss-canvas .ss-lesson .ss-section > ul > li,
.ss-canvas .ss-lesson .ss-section > ol > li,
.ss-canvas .ss-lesson .ss-reveal__body p,
.ss-canvas .ss-lesson .ss-predict__reveal p {
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
}
.ss-canvas .ss-lesson .ss-section > p,
.ss-canvas .ss-lesson .ss-section > ul,
.ss-canvas .ss-lesson .ss-section > ol {
    max-width: var(--cv-prose-w);
}
.ss-canvas .ss-lesson .ss-section > h2 {
    font-size: calc(var(--cv-size) * 1.4);
    color: var(--cv-bright);
}


/* ====================================================================
   9. SCIENCE PUZZLE  (single-science-puzzles.php)
   The setup and the answer read at the body size in the well; the
   options, buttons and diagrams keep their own look.
   ==================================================================== */
.ss-canvas .sspz-setup p,
.ss-canvas .sspz-answer p {
    font-family: var(--cv-body);
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
}
.ss-canvas .sspz-setup,
.ss-canvas .sspz-answer {
    max-width: var(--cv-prose-w);
    margin-left: auto;
    margin-right: auto;
}
.ss-canvas .sspz-answer h2 {
    font-family: var(--cv-display);
    font-size: calc(var(--cv-size) * 1.3);
    color: var(--cv-bright);
}


/* ====================================================================
   10. PLAIN PAGES  (page.php; About, Editorial, How we rate, Contact)
   page.php: the panel glass goes, the text reads in the well. The four
   custom pages keep their dossier heads and bento cards; their text
   takes the system's size, ink and faces.
   ==================================================================== */
.ss-canvas .rf-page {
    max-width: var(--cv-canvas-w);
    padding-left: clamp(16px, 3vw, 48px);
    padding-right: clamp(16px, 3vw, 48px);
    box-sizing: border-box;
}
.ss-canvas .rf-page .entry-content {
    max-width: var(--cv-prose-w);
    margin: 2rem auto;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    padding: 0;
    box-shadow: none;
    overflow: visible;
}
.ss-canvas .rf-page .entry-content::before { content: none !important; display: none !important; }
.ss-canvas .rf-page .entry-content h1 {
    font-family: var(--cv-display);
    font-size: clamp(2.1rem, 4.6vw, 3.3rem);
    line-height: 1.08;
    color: var(--cv-bright);
}
.ss-canvas .rf-page .entry-content h1::after { display: none; }

/* The custom plain pages: card prose a step under the body size so the
   bento cards keep their shape; open paragraphs at the full size. */
.ss-canvas :is(.rf-about, .rf-contact, .hwr-page, .rf-ed-page, .rf-editorial) p {
    font-family: var(--cv-body);
    font-size: calc(var(--cv-size) - 2px);
    line-height: 1.7;
    color: var(--cv-ink);
}
.ss-canvas :is(.rf-about, .rf-contact, .hwr-page) > p,
.ss-canvas .hwr-subtitle,
.ss-canvas .rf-about-intro p,
.ss-canvas .rf-ed-intro p {
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    max-width: var(--cv-prose-w);
}
.ss-canvas :is(.rf-about, .rf-contact, .hwr-page, .rf-ed-page, .rf-editorial) :is(h2, h3) {
    font-family: var(--cv-display);
    font-weight: 700;
    color: var(--cv-bright);
}
.ss-canvas :is(.rf-about, .rf-contact, .hwr-page, .rf-ed-page, .rf-editorial) li {
    font-size: calc(var(--cv-size) - 2px);
    line-height: 1.6;
    color: var(--cv-ink);
}


/* ====================================================================
   11. HUBS, LISTS AND SEARCH
   Paragraph text only: the educator's About, the catalogue intro, the
   category, topic and puzzle intros, search excerpts. Cards keep their
   own sizes.
   ==================================================================== */
.ss-canvas .hub-bio-content {
    max-width: var(--cv-prose-w);
    margin-left: auto;
    margin-right: auto;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    padding: 0;
}
.ss-canvas .hub-bio-content h2 { border-bottom: 0; padding-bottom: 0; }
.ss-canvas :is(.cat-intro, .categories-hero p, .category-hero p, .topics-hero p, .hub-intro, .hub-about p, .sspz-archive-intro, .archive-intro p) {
    font-family: var(--cv-body);
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
    max-width: var(--cv-prose-w);
}
.ss-canvas :is(.hub-sidebar-text, .hub-sidebar-card p) {
    font-size: 1rem;
    line-height: 1.6;
    color: var(--cv-ink);
}
.ss-canvas :is(.ss-card-excerpt, .archive-rf-excerpt, .cat-card-desc) {
    font-size: max(1rem, 0.95em);
    line-height: 1.6;
}


/* ====================================================================
   12. SPACE PAGES  (Moon, Voyager, eclipse: ss-sim.css)
   The section prose only. The timeline cards keep the sizes set on
   18 October.
   ==================================================================== */
.ss-canvas .ss-sim-prose {
    font-family: var(--cv-body);
    font-size: var(--cv-size);
    line-height: var(--cv-lh);
    color: var(--cv-ink);
    max-width: var(--cv-prose-w);
}
.ss-canvas .ss-sim-sec-title {
    font-family: var(--cv-display);
    font-weight: 700;
    color: var(--cv-bright);
}
.ss-canvas .ss-sim-sec-kicker {
    font-family: var(--cv-mono);
    letter-spacing: 0.18em;
    text-transform: uppercase;
}


/* ====================================================================
   13. PHONES  (900px and under)
   One column, 17.5px body, the strip and the end matter stack, the
   wide things go full width. mobile.css forces sizes with !important
   below 768px, so the same is used here where it has to be.
   ==================================================================== */
@media (max-width: 900px) {
    html.ss-canvas { --cv-size: 18px; }
    html.ss-canvas[data-cv-size="18"], html.ss-canvas[data-cv-size="19"] { --cv-size: 17.5px; }
    html.ss-canvas[data-cv-size="20"] { --cv-size: 18px; }
    html.ss-canvas[data-cv-size="22"] { --cv-size: 18.5px; }
    html.ss-canvas[data-cv-size="24"] { --cv-size: 20px; }

    .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) p {
        font-size: var(--cv-size) !important;
        line-height: var(--cv-lh) !important;
    }
    .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) > p:first-of-type {
        font-size: calc(var(--cv-size) * 1.22) !important;
        line-height: 1.55 !important;
        padding: 0 !important;
    }
    .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h2 {
        font-size: calc(var(--cv-size) * 1.45) !important;
    }
    .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) h3 {
        font-size: calc(var(--cv-size) * 1.18) !important;
    }

    /* The news and biography grid becomes a column; order keeps the
       reading order of the desktop grid. */
    .ss-canvas .news-article {
        display: flex;
        flex-direction: column;
    }
    .ss-canvas .news-article > * { width: 100%; max-width: none; }
    .ss-canvas .news-article > .news-hero-image,
    .ss-canvas .news-article > .news-header          { order: 1; }
    .ss-canvas .news-article > .news-hero-caption    { order: 2; }
    .ss-canvas .news-article .news-sidebar-findings,
    .ss-canvas .news-article .bio-factfile-card      { order: 3; margin-top: 2rem; }
    .ss-canvas .news-article .cv-rating,
    .ss-canvas .news-article .news-rating-card-none,
    .ss-canvas .news-article .bio-hub-card           { order: 4; margin-top: 1rem; }
    .ss-canvas .news-article .news-dossier,
    .ss-canvas .news-article .bio-dossier            { order: 5; }
    .ss-canvas .news-article .news-content,
    .ss-canvas .news-article .bio-content            { order: 6; margin-top: 2.5rem; }
    .ss-canvas .news-article .bio-timeline-section   { order: 7; }
    .ss-canvas .news-article .news-share,
    .ss-canvas .news-article .bio-share              { order: 8; }
    .ss-canvas .news-article .news-source-card       { order: 9; margin-top: 2.5rem; }
    .ss-canvas .news-article .cv-class               { order: 10; margin-top: 1rem; }
    .ss-canvas .news-article .news-feedback-card     { order: 11; margin-top: 1rem; }
    .ss-canvas .news-article:has(.cv-rating) .news-sidebar-findings { max-height: none !important; }
    .ss-canvas .news-article .news-sources-list { columns: 1; }
    /* One column: nothing mirrors, every flash back on the left. */
    .ss-canvas .cv-mirror.cv-mirror.cv-mirror {
        background: var(--cv-surface);
        border-left: var(--cv-flash-w, 1px) solid var(--cv-flash, var(--cv-surface-border));
        border-right: 1px solid var(--cv-surface-border);
    }
    html[data-cv-pictures="offset"] .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) .cv-pic::after { display: none; }
    .ss-canvas .news-article .news-rating-card:not(.news-rating-card-none) { margin-top: 1rem; }
    .ss-canvas .news-article .news-rating-card:not(.news-rating-card-none) { order: 11; }
    .ss-canvas .news-article .news-sources-card      { order: 12; }
    .ss-canvas .bio-article .bio-sidebar > .news-sidebar-card:not(.bio-factfile-card):not(.bio-hub-card) { order: 13; margin-top: 2.5rem; }
    .ss-canvas .news-article .news-back-btn          { order: 14; align-self: center; }

    /* mobile.css pulls these out to the screen edge; the canvas keeps
       one gutter. */
    .ss-canvas .news-hero-overlay,
    .ss-canvas .news-dossier,
    .ss-canvas .bio-dossier,
    .ss-canvas .news-sidebar,
    .ss-canvas .sg-railcol,
    .ss-canvas .sg-ou-band {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
    .ss-canvas .news-hero-overlay img,
    .ss-canvas .news-hero-image img { margin-top: 1.25rem; }
    .ss-canvas .news-hero-inner,
    .ss-canvas .news-header { padding: 1.25rem 0 0; }
    .ss-canvas .news-title { font-size: 1.85rem; }
    .ss-canvas :is(.news-dossier, .bio-dossier) { grid-template-columns: 1fr 1fr; }
    .ss-canvas .news-dossier-stat:last-child { display: flex; }
    .ss-canvas .news-sidebar-card,
    .ss-canvas .cv-card { padding: 1.1rem 1.15rem; }
    .ss-canvas .sg-railcol { grid-template-columns: 1fr; }
    .ss-canvas .news-article-container,
    .ss-canvas .bio-page-container,
    .ss-canvas .ss-guide-page,
    .ss-canvas .rf-page { padding-left: 16px; padding-right: 16px; }
    .ss-canvas .cv-callout { padding: 1.25rem 1.1rem; }
    .ss-canvas :is(.news-content, .bio-content, .sg-content, .rf-page .entry-content, .bn-panel-content, .hub-bio-content, .cv-prose) blockquote {
        padding: 1.1rem 1.2rem;
        font-size: calc(var(--cv-size) * 1.08);
    }
}
@media (max-width: 480px) {
    .ss-canvas :is(.news-dossier, .bio-dossier) { grid-template-columns: 1fr 1fr; gap: 0.6rem; }
    .ss-canvas :is(.news-dossier-stat, .bio-dossier-stat) { padding: 0.8rem 0.9rem; }
    .ss-canvas :is(.news-dossier-num, .bio-dossier-num) { font-size: 1.25rem; }
}


/* ====================================================================
   14. REDUCED MOTION AND PRINT
   The nebula already stops for reduced motion (ss-cosmos.css); the
   canvas adds no animation of its own. In print the channel goes.
   ==================================================================== */
@media (prefers-reduced-motion: reduce) {
    .ss-canvas .news-body::before,
    .ss-canvas .entry-content::before { animation: none !important; }
}
@media print {
    .ss-canvas .cv-wash { display: none; }
}
