/*
 * AltcoinGordon design tokens — the literal, machine-readable version
 * of the "Verification-First Journalism" / "Ink and Paper" design
 * system exported from Google Stitch (see the uploaded DESIGN.md,
 * Aug 2026 redesign). Loaded before style.css (see functions.php) so
 * every component rule in style.css can reference these custom
 * properties instead of a hardcoded value.
 *
 * REBRAND NOTE (Aug 2026): this file replaces the earlier blue-accent
 * "brand-system.md" palette. To avoid a sitewide find/replace across
 * every template's CSS in one pass, the original --ag-* token NAMES
 * are kept (navy-900, accent-600, etc.) but their VALUES now point at
 * the new Ink & Paper palette below, and new tokens are added for
 * concepts the old system didn't have (paper surface, gold accent,
 * trust navy, data-gray). Homepage components (header, hero, footer,
 * sidebar widgets) are being rebuilt to use the new semantic names
 * directly; article/archive/search/404 templates still reference the
 * old names and inherit the new colors automatically until they get
 * their own rebuild pass (see task #172/#173).
 */
:root {
    /* ---- New Ink & Paper semantic tokens (use these in new code) ----
       Colors below are the LITERAL values from the actual Stitch
       export's tailwind.config (pasted verbatim by the user from the
       live project — see the raw homepage code.html) — this is the
       single most authoritative source, verified byte-for-byte against
       DESIGN.md too. A separately-typed "Implementation Guide" the
       user sent earlier had different hex values (#C5A059 gold,
       #1b5e20/#b71c1c status) that do NOT match the actual exported
       project and have been reverted here in favor of the real thing. */
    --ag-paper: #f8fafc;
    --ag-paper-dark: #0f172a;  /* dark-mode surface token — reserved, no dark-mode toggle built yet */
    --ag-paper-white: #ffffff;
    --ag-media-placeholder: #f1f5f9;  /* image container fallback bg, distinct from --ag-paper */
    --ag-ring-hole: #0f172a;          /* Intelligence Card trust-ring center, deliberately near-black */
    --ag-ink: #0f172a;
    --ag-gold: #2563eb;
    --ag-gold-tint: rgba(37, 99, 235, 0.12);
    --ag-trust-navy: #1e293b;
    --ag-primary: #0f172a;      /* the export's "primary" token — true black, distinct from --ag-ink */
    --ag-secondary: #60a5fa;    /* the export's "secondary" token — footer link brown, verified against raw HTML's text-secondary class */
    --ag-primary-fixed-variant: #475569;
    --ag-success-green: #15803d;
    --ag-error-red: #b91c1c;
    --ag-data-gray: #475569;
    --ag-outline: #64748b;
    --ag-outline-variant: #cbd5e1;
    --ag-outline-variant-30: rgba(203, 213, 225, 0.3);
    --ag-surface: #f8fafc;
    --ag-surface-dim: #cbd5e1;
    --ag-surface-bright: #f8fafc;
    --ag-surface-container-lowest: #ffffff;
    --ag-surface-container-low: #f1f5f9;
    --ag-surface-container: #f1f5f9;
    --ag-surface-container-high: #e2e8f0;
    --ag-surface-container-highest: #e2e8f0;
    --ag-on-surface-variant: #334155;
    --ag-hairline-on-ink: rgba(15, 23, 42, 0.1);

    /* ---- Legacy names, remapped to the new palette (back-compat for
       article/archive/search/404 templates not yet rebuilt) ---- */
    --ag-navy-900: #0f172a;   /* was #0f172a — now = ink */
    --ag-navy-800: #1e293b;   /* was #1e293b — now = primary black (ticker/footer-strip surfaces) */
    --ag-slate-700: #334155;
    --ag-slate-600: #475569;
    /* #747878 -> #6a6e6e (Aug 2026 a11y pass): at 10px this token
       renders .badge-strip__count on --ag-slate-100 (#f4f4f2) at only
       4.05:1, under the 4.5:1 WCAG AA minimum for normal text. All 11
       usages of this token are muted small text on light surfaces --
       none are borders or on dark -- so darkening it slightly raises
       contrast everywhere it appears and lowers it nowhere. Now
       4.69:1 on #f4f4f2, 4.90:1 on #f9f9f7. */
    --ag-slate-450: #7c8ba1;
    --ag-slate-500: #64748b;
    --ag-slate-400: #94a3b8;
    --ag-slate-300: #cbd5e1;
    --ag-slate-200: #e2e8f0;
    --ag-slate-100: #f1f5f9;
    --ag-slate-50: #f8fafc;
    --ag-white: #ffffff;

    /* Accent — Sophisticated Gold, #B08D57 (verified against the raw
       exported tailwind.config's "accent-gold" value). */
    --ag-accent-700: #1d4ed8;
    --ag-accent-600: #2563eb;
    --ag-accent-500: #3b82f6;
    --ag-accent-400: #60a5fa;
    --ag-accent-tint-50: #eff6ff;

    /* Semantic: success (market up) — #058A5F, verified against the
       raw exported tailwind.config's "success-green" value. */
    --ag-success-700: #15803d;
    --ag-success-600: #16a34a;
    --ag-success-500: #22c55e;
    --ag-success-tint-50: #f0fdf4;

    /* Semantic: warning */
    --ag-warning-700: #b45309;
    --ag-warning-600: #d97706;
    --ag-warning-tint-50: #fffbeb;

    /* Semantic: error (market down) — #D93025, verified against the
       raw exported tailwind.config's "error-red" value. */
    --ag-error-700: #b91c1c;
    --ag-error-600: #dc2626;
    --ag-error-500: #ef4444;
    --ag-error-tint-50: #fef2f2;

    /* Category accents — kept distinct from the gold verification
       accent so a category badge never gets confused with a
       "verified" signal. */
    --ag-cat-news: #2563eb;
    --ag-cat-macro: #6d28d9;
    --ag-cat-exchange: #0d9488;
    --ag-cat-regulatory: var(--ag-warning-600);
    --ag-cat-default: #0284c7;
    /* Added Aug 2026 for the Guides/DeFi/AI/Press Releases desks --
       these WP categories existed with no matching accent, so every
       badge on them silently fell back to --ag-cat-default instead of
       a desk-appropriate color. Kept visually distinct from the four
       above: emerald (learning/growth), violet (DeFi's common crypto-
       brand color), cyan (techy, distinct from exchange's teal), and a
       deliberately muted slate for Press Releases so company-submitted
       content still reads as visually different from staff reporting. */
    --ag-cat-guides: #10b981;
    --ag-cat-defi: #8b5cf6;
    --ag-cat-ai: #22d3ee;
    --ag-cat-press-releases: #64748b;
    /* Added Aug 2026 for the Research & Intelligence and Reviews
       desks — infrastructure created ahead of content (see
       home.php's docblock) so these have a correct color from the
       first post published into them, rather than falling back to
       --ag-cat-default. Amber for Research (distinct from every
       existing accent, reads as "analysis/reports"), rose for
       Reviews (distinct warm tone for comparison/verdict content). */
    --ag-cat-research: #d97706;
    --ag-cat-reviews: #e11d48;

    /* Category badge TINT colors (Aug 2026 design-system audit fix) —
       the light-text-on-tinted-background treatment .ag-badge--* uses
       in style.css. These lived only as hardcoded hex/rgba directly in
       style.css until now; extracted here so every color value in the
       badge system has one source of truth, matching the border tokens
       (--ag-cat-* above) they pair with. Byte-identical values — a pure
       extraction, not a recolor, so this changes zero pixels on the
       live site. */
    --ag-cat-news-text: #93c5fd;           --ag-cat-news-bg: rgba(59,130,246,0.18);
    --ag-cat-macro-text: #c7d2fe;          --ag-cat-macro-bg: rgba(129,140,248,0.18);
    --ag-cat-exchange-text: #99f6e4;       --ag-cat-exchange-bg: rgba(45,212,191,0.18);
    --ag-cat-regulatory-text: #fde68a;     --ag-cat-regulatory-bg: rgba(217,119,6,0.18);
    --ag-cat-guides-text: #6ee7b7;         --ag-cat-guides-bg: rgba(16,185,129,0.18);
    --ag-cat-defi-text: #c4b5fd;           --ag-cat-defi-bg: rgba(139,92,246,0.18);
    --ag-cat-ai-text: #67e8f9;             --ag-cat-ai-bg: rgba(34,211,238,0.18);
    --ag-cat-press-releases-text: #cbd5e1; --ag-cat-press-releases-bg: rgba(100,116,139,0.18);
    --ag-cat-research-text: #fcd34d;       --ag-cat-research-bg: rgba(217,119,6,0.18);
    --ag-cat-reviews-text: #fda4af;        --ag-cat-reviews-bg: rgba(225,29,72,0.18);
    --ag-cat-default-text: #bae6fd;        --ag-cat-default-bg: rgba(56,189,248,0.18);

    /* Trust badge colors — Aug 2026 editorial trust badge expansion
       (see inc/trust-badges.php for the full registry). Deliberately a
       separate namespace from --ag-cat-* above: category color says
       "which desk," badge color says "how this was verified," and the
       two must never be visually confusable. Each of the 11 Intelligence
       Card badge variants (.ic-badge--* in style.css) is a two-stop
       vertical gradient; -start is the top stop, the bare/-end name is
       the bottom stop. Values are a pure extraction from what was
       previously hardcoded hex directly in style.css (Aug 2026
       design-system audit fix) — zero pixels changed on the live site.
       Six of the eleven -end values were already defined pre-audit but
       never actually wired into style.css; that gap is now closed. */
    --ag-badge-verified-start: #826b43; /* was #c9a668 — 2.30:1 for white badge text, now 5.08:1 (Aug 2026 a11y fix) */   --ag-badge-verified-end: #a3814a;
    --ag-badge-factcheck-start: #14b87f;  --ag-badge-factcheck-end: #0a8f61;
    --ag-badge-official-start: #16507d;   --ag-badge-official-end: #0a3455;
    --ag-badge-onchain-start: #5b4fe0;    --ag-badge-onchain: #4338ca;
    --ag-badge-data-start: #0d87c9;       --ag-badge-data: #0369a1;
    --ag-badge-live-start: #ef4444;       --ag-badge-live: #dc2626;
    --ag-badge-expert-start: #4c41c9;     --ag-badge-expert: #3730a3;
    --ag-badge-fresh-start: #197c93; /* was #22a6c4 — 2.87:1 for white badge text, now 4.83:1 (Aug 2026 a11y fix) */      --ag-badge-fresh: #0e7490;
    --ag-badge-evergreen-start: #10b981;  --ag-badge-evergreen: #059669;
    --ag-badge-analysis-start: #64748b;   --ag-badge-analysis-end: #475569;
    --ag-badge-default-start: #6b7280;    --ag-badge-default-end: #4b5563;

    /* Typography — verified against the raw exported code.html's
       tailwind.config fontFamily block: it's a DUAL-font system, not
       all-serif. display-lg/headline-lg/headline-lg-mobile/headline-md
       use Source Serif 4; body-lg/body-md/label-caps/data-mono all use
       Inter. (An earlier, separately-typed "Implementation Guide" said
       "use Source Serif 4 for all text" — that doesn't match the
       actual exported project and has been reverted.) */
    /* "AG Serif Fallback" is Georgia with size-adjust/ascent-override applied
       so it occupies the same space Source Serif 4 will (see assets/fonts.css,
       generated by scripts/fetch-fonts.py). It is inserted, not substituted:
       the rest of the stack is unchanged, and if Georgia is not installed the
       face does not match and Iowan Old Style / Charter / Times take over
       exactly as before. */
    --ag-font-serif: "Source Serif 4", "AG Serif Fallback", Georgia, "Iowan Old Style", Charter, "Times New Roman", serif;
    --ag-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --ag-font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

    --ag-text-display: clamp(2.25rem, 4vw, 3.5rem);
    --ag-text-h1: 2rem;
    --ag-text-h2: 1.5rem;
    --ag-text-h3: 1.125rem;
    --ag-text-h4: 1rem;
    --ag-text-body: 1.0625rem;
    --ag-text-ui: 0.9375rem;
    --ag-text-small: 0.8125rem;
    --ag-text-caption: 0.75rem;
    --ag-text-data: 0.9375rem;
    --ag-text-quote: 1.25rem;

    /* Stitch scale, used directly by new homepage components */
    --ag-text-display-lg: 56px;
    --ag-text-headline-lg: 40px;
    --ag-text-headline-lg-mobile: 32px;
    --ag-text-headline-md: 28px;
    --ag-text-body-lg: 18px;
    --ag-text-body-md: 16px;
    --ag-text-label-caps: 12px;
    --ag-text-data-mono: 14px;

    /* Spacing (8pt scale, 4px half-step) */
    --ag-space-1: 4px;
    --ag-space-2: 8px;
    --ag-space-3: 12px;
    --ag-space-4: 16px;
    --ag-space-5: 24px;
    --ag-space-6: 32px;

    /* Distance from the bottom of the site header to the first thing on any
       page. ONE value, applied globally -- see the #content rule in
       style.css. Every template used to supply its own and they had drifted
       to 55, 60, 62 and 21px; the 21 was a page shipped the same day, which
       is how this kept happening. A new template now inherits the right
       spacing without knowing this rule exists. */
    --ag-page-top: 32px;
    --ag-space-7: 48px;
    --ag-space-8: 64px;
    --ag-space-9: 96px;

    /* Containers + margins — verified against the raw exported
       code.html's tailwind.config spacing block exactly:
       margin-desktop 64px, margin-mobile 16px, gutter 24px, plus
       footer-only stack-lg/section-gap. */
    --ag-container-wide: 1280px;
    --ag-container-narrow: 68ch;
    --ag-margin-desktop: 64px;
    --ag-margin-mobile: 16px;
    --ag-gutter: 24px;
    --ag-gutter-lg: 48px;
    --ag-stack-lg: 32px;
    --ag-section-gap: 64px;

    /* Radius — the exported tailwind.config's borderRadius block:
       DEFAULT 2px, lg 4px, xl 8px, full 12px. -lg is what most
       card/module rounded-* classes in the export actually use. */
    --ag-radius-sm: 4px;
    --ag-radius-md: 8px;
    --ag-radius-lg: 16px;
    /* WCAG 2.1 AA minimum interactive target size — intentionally
       its own constant, not a --ag-space-* step, so it never drifts
       if the spacing scale changes. */
    --ag-touch-target: 44px;
    --ag-radius-full: 999px;

    /* Elevation — flat by default. */
    --ag-shadow-popover: 0 8px 24px rgba(26, 26, 26, 0.12);
    --ag-shadow-hover: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);

    /* Borders */
    /* brand-system.md / mockups define the hairline as `1px solid var(--s200)`
       (#e2e8f0), solid — not a 30%-alpha slate-300. The alpha value made every
       card, nav and row border read markedly fainter than spec across the
       homepage, archive and claim pages. Audited 6 Aug 2026. */
    --ag-border-hairline: 1px solid var(--ag-slate-200);
    --ag-border-strong: 1px solid var(--ag-outline-variant);

    /* Motion — verified against the raw exported code.html's own
       inline <style>: `animation: slideUpFade 0.8s
       cubic-bezier(0.16,1,0.3,1) forwards`, translateY(30px) start. */
    --ag-transition-fast: 120ms ease;
    --ag-transition-base: 200ms ease;
    --ag-transition-entrance: 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --ag-transition-fast: 0ms;
        --ag-transition-base: 0ms;
        --ag-transition-entrance: 0ms;
    }
}

/* =====================================================================
   VERIFICATION LAYER TOKENS
   Source: docs/design/redesign-2026-08/design-system-spec.html v1.1 §02
   Added: 6 Aug 2026, redesign-2026-08.

   Appended as a second :root block on purpose — later declarations win
   for duplicate properties, so this adds the verification vocabulary and
   re-points exactly one existing token without editing the block above.

   WHY THESE ARE NOT ALIASES ONTO --ag-accent-*
   -------------------------------------------
   design-system-spec.html §02 specifies --ag-stance-contradicts as
   var(--ag-accent-600), because both it and brand-system.md were written
   against the navy/blue ramp where accent-600 is #2563eb. This theme was
   re-skinned to ink/gold on 5 Aug — between those two documents — so
   accent-600 is now #B08D57. Aliasing literally would have two effects,
   both disqualifying:

     1. "disputed" would render in the amber family. Settled decision #2
        says disputed is accent blue, never red or amber — and gold is
        already this palette's "verified" signal, so aliasing would
        invert the meaning rather than merely shift the hue.
     2. The disputed pip would sit at 2.40:1 against an unfilled pip,
        under the 3:1 WCAG 1.4.11 floor. Spec §03 calls that ratio
        "required, not cosmetic" because the pips carry the information.

   So the verification layer carries its own blue, scoped to itself. The
   gold brand accent is unchanged on every other surface.

   Ratios below were computed with the WCAG relative-luminance formula
   against THIS file's live ramp, not against the spec's:
     #2563eb pip  vs --ag-slate-200 (#e2e3e1)   4.01:1  (1.4.11 needs 3.0)
     #2563eb text on --ag-slate-50  (#f9f9f7)   4.90:1  (AA needs 4.5)
     #1d4ed8 text on --ag-verify-tint-50        6.16:1  (AA needs 4.5)
   ===================================================================== */
:root {

    /* The verification accent. Scoped — do not use outside .ag-* blocks. */
    --ag-verify-accent:     #2563eb;
    --ag-verify-accent-700: #1d4ed8;
    --ag-verify-tint-50:    #eff6ff;

    /* Chip borders. Literal values from IMPLEMENTATION-BRIEF.md §6's
       status-to-colour table, tokenised here so that component CSS stays
       hex-free per brief §7. */
    --ag-verify-border:           #bfdbfe;
    --ag-status-verified-border:  #bbf7d0;
    --ag-status-false-border:     #fecaca;

    /* Stance rules (spec §02). Supports is ink, not a colour — support is
       the baseline, not an event. Echo is deliberately the faintest:
       syndication does not corroborate. */
    --ag-stance-supports:    var(--ag-navy-900);
    --ag-stance-contradicts: var(--ag-verify-accent);
    --ag-stance-partial:     var(--ag-slate-400);
    --ag-stance-echo:        var(--ag-slate-300);

    /* Corroboration pips (brief §6). --ag-slate-400 appears here as a
       non-text marker only, which is permitted; it must never be used as
       text on a light surface (2.45:1). */
    --ag-pip-off:         var(--ag-slate-200);
    --ag-pip-on:          var(--ag-navy-900);
    --ag-pip-on-disputed: var(--ag-verify-accent);
    --ag-pip-on-verified: var(--ag-success-700);

    /* Re-pointed, not new. --ag-cat-news was #2563eb, which is now the
       verification accent. A News badge and a disputed claim chip
       co-occur on every archive row, and the row is exactly where
       corroboration has to stay scannable. Moved to the blue that the
       category system already carried as its default. */
    --ag-cat-news: #0284c7;
}

/* Companion to the --ag-cat-news re-point above. .ag-badge--news
   (style.css:131) pairs three tokens — text, background tint and border.
   Moving only the border would leave one badge wearing three different
   blues, so the tint pair moves with it, from the blue-500 family to the
   sky family that #0284c7 belongs to. Checked, not assumed: #7dd3fc on
   the new tint reads 7.95:1 against the dark badge surface, marginally
   better than the 7.68:1 the old pair gave. */
:root {
    --ag-cat-news-text: #7dd3fc;
    --ag-cat-news-bg:   rgba(14, 165, 233, 0.18);
}


/* ---------------------------------------------------------------------
   Nav height. Needed by anything that pins under the nav - the archive
   band header and the claim status bar (brief 5.5). Tracks
   .site-nav-row__inner, which is 80px and drops to 64px at 600px.
   If that height changes, change it here too or things pin at the wrong
   offset and hide under the nav.
   --------------------------------------------------------------------- */
/* Measured on the rendered page, not inferred: the header is 121px
   wide-screen and 81px on mobile. The 40px difference is the price
   ticker, which is hidden below Tailwind md (768px) - so the
   breakpoint here is 767px, not 600px. */
:root { --ag-nav-h: 121px; }

@media (max-width: 767px) {
    :root { --ag-nav-h: 81px; }
}
/*
 Theme Name:   GeneratePress Child — AltcoinGordon
 Theme URI:    https://altcoingordon.com
 Description:  Full custom editorial design for AltcoinGordon.com,
               implementing the design system documented in
               docs/design/brand-system.md. Every color/spacing/type
               value below is a var(--ag-*) token from
               assets/design-tokens.css, not a hardcoded value — see
               that file for the single source of truth.
 Author:       AltcoinGordon
 Author URI:   https://altcoingordon.com
 Template:     generatepress
 Version:      3.0.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Text Domain:  generatepress-child
*/

/* ---------------------------------------------------------------------
   Reset + base
   --------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* Mobile audit (Aug 2026): the page allowed a couple px of horizontal
   scroll — traced to the FAQ accordion chevron (a 9x9 box rotated 45deg
   via transform, whose rotated diagonal paints ~2px past its own layout
   box; Chrome counts that "ink overflow" toward scrollWidth). Fixed at
   the source below (.faq-item h3), but html/body get this belt-and-
   suspenders rule too since any future rotated/transformed element can
   reintroduce the same class of bug — this never clips vertical scroll
   or the sticky sidebar, only a stray sideways scrollbar. */
html, body { overflow-x: hidden; }
body {
    margin: 0;
    font-family: var(--ag-font-sans);
    font-size: var(--ag-text-ui);
    color: var(--ag-ink);
    background: var(--ag-paper);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
/* Aug 2026 a11y fix: was --ag-accent-600 (2.9-3.1:1 on paper/white,
   fails 4.5:1) as the DEFAULT link color for all inline body-copy
   links — a:hover already correctly used --ag-accent-700 below, this
   just makes the resting state match. */
a { color: var(--ag-accent-700); text-decoration: none; }
a:hover, a:focus { color: var(--ag-accent-700); }
/* No blanket `color` here on purpose: every heading in the rebuilt
   templates (header/footer/home) already carries its own explicit
   Tailwind text-color class, exactly matching the real Stitch export.
   The one exception is "The Daily Verify" newsletter heading, which the
   export also leaves uncolored so it inherits white (text-on-primary)
   from its black card — a hardcoded navy color here was silently
   winning that inheritance and rendering it near-invisible on black.
   See docs/design or the Aug 2026 bugfix note in home.php. */
h1, h2, h3, h4, h5, h6 { margin: 0; font-family: var(--ag-font-serif); font-weight: 700; }
p { margin: 0 0 1.2em; }
ul { margin: 0; padding: 0; list-style: none; }
button { font-family: inherit; cursor: pointer; background: none; border: none; }
:focus-visible { outline: 2px solid var(--ag-accent-600); outline-offset: 2px; }

/* Root-cause fix (Aug 2026): the GeneratePress PARENT theme's own
   main.css sets `.site-content { display: flex; }` unconditionally —
   it expects that flex row to contain exactly one child, its own
   `#primary.content-area` wrapper (plus an optional `.sidebar`), which
   its template-parts create. Our header.php intentionally opens
   `#content.site-content` directly with no such wrapper (this child
   theme owns 100% of its own templates — see the file header comment
   above), so every top-level section our templates output (hero,
   trending, story grid, newsletter band, etc.) became its OWN flex
   item instead of stacking — each one squeezed to a fraction of the
   row width. This is almost certainly the actual, long-standing cause
   behind "the site looks broken on every device": it's real, present
   in the raw HTML/CSS, and has nothing to do with browser caching.
   Restoring normal block stacking here, scoped to our own theme's
   stylesheet (loaded after the parent's, so it wins the cascade). */
#content.site-content { display: block; }

/*
 * GLOBAL PAGE TOP SPACING -- read this before building a new template.
 *
 * Every page gets the same breathing room under the header from here, so a
 * template does not have to remember to add it. This exists because
 * remembering did not work: measured across the live site, the gap between
 * the header and the first heading was 55px on /verification/, /about/ and
 * /corrections/, 60px on /news/, 62px on the homepage, and 21px on a page
 * shipped that morning. Six pages, five answers, no rule -- just each
 * template solving the same problem again and one of them getting it wrong.
 *
 * If a template needs to sit flush against the header -- a full-bleed band,
 * a hero with its own dark background -- it opts out by declaring itself,
 * rather than by every other page opting in:
 *
 *     add_filter( 'body_class', ... 'ag-flush' ... )   // see functions.php
 *
 * A template should NOT add its own padding-top to the first element on the
 * page. If one does, it is additive with this and the page ends up with
 * twice the spacing of every other page, which is the failure this rule
 * replaced.
 * Selector note: `#content`, NOT `#content.site-content`. This install
 * renders the wrapper with an id and no class at all, so the
 * `#content.site-content` rule a few lines above has never matched anything
 * -- it is dead, and it is why the first version of this rule silently did
 * nothing too. Verified against the live DOM rather than assumed.
 */
#content { padding-top: var(--ag-page-top); }

body.ag-flush #content { padding-top: 0; }

/* GenerateBlocks' Query/Looper blocks always add their own wrapping
   tag around whatever they loop (confirmed against the installed
   plugin's includes/blocks/class-{query,looper}.php) — there's no way
   to make one of those blocks directly BE a target element like
   `.hero-lead` when it also needs child blocks nested inside it. This
   class removes such a wrapper from the box model entirely
   (`display: contents`) so its own children participate directly in
   whatever grid/flex layout the *real* parent element defines, without
   an extra unstyled `<div>` breaking that layout — see
   inc/blocks-patterns.php's altcoingordon_homepage_hero_section_blocks(). */
.gb-transparent { display: contents; }

/* px-margin-desktop / px-margin-mobile in the raw export */
.ag-container { max-width: var(--ag-container-wide); margin: 0 auto; padding: 0 var(--ag-margin-desktop); }
.ag-container-narrow { max-width: var(--ag-container-narrow); margin: 0 auto; padding: 0 var(--ag-margin-desktop); }
@media (max-width: 900px) {
    .ag-container, .ag-container-narrow { padding: 0 var(--ag-margin-mobile); }
}
.ag-visually-hidden {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}
.skip-link {
    position: absolute; left: -999px; top: 0; background: var(--ag-navy-900); color: var(--ag-white);
    padding: var(--ag-space-3) var(--ag-space-4); z-index: 1000; border-radius: 0 0 6px 0;
}
.skip-link:focus { left: 0; }

/* ---------------------------------------------------------------------
   Category + status badges (shared component)
   --------------------------------------------------------------------- */
.ag-badge {
    display: inline-block;
    font-family: var(--ag-font-sans);
    font-size: var(--ag-text-caption);
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    padding: 3px var(--ag-space-3);
    border-radius: var(--ag-radius-sm);
    /* Defensive: badges positioned absolute over a clipped thumbnail
       (hero-lead__badge and similar) were getting visibly cut off by
       the parent's overflow:hidden for longer category names (e.g.
       WordPress's default "Uncategorized" on stray posts). Real
       categories are short (News/Macro/Exchange/Regulatory), but this
       keeps any future long name from clipping mid-word. */
    max-width: calc(100% - 24px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ag-badge--news       { color: var(--ag-cat-news-text); background: var(--ag-cat-news-bg);  border: 1px solid var(--ag-cat-news); }
.ag-badge--macro      { color: var(--ag-cat-macro-text); background: var(--ag-cat-macro-bg); border: 1px solid var(--ag-cat-macro); }
.ag-badge--exchange   { color: var(--ag-cat-exchange-text); background: var(--ag-cat-exchange-bg);  border: 1px solid var(--ag-cat-exchange); }
.ag-badge--regulatory { color: var(--ag-cat-regulatory-text); background: var(--ag-cat-regulatory-bg);  border: 1px solid var(--ag-cat-regulatory); }
/* Added Aug 2026 -- same light-text-on-tinted-background pattern as
   the four rules above, just extended to the Guides/DeFi/AI/Press
   Releases desks (see altcoingordon_badge_class() in functions.php,
   which previously only recognized news/macro/exchange/regulatory and
   fell everything else back to .ag-badge--default). Colors moved to
   --ag-cat-*-text/-bg tokens in design-tokens.css (Aug 2026
   design-system audit fix) — same values, just no longer hardcoded
   here. */
.ag-badge--guides         { color: var(--ag-cat-guides-text); background: var(--ag-cat-guides-bg);  border: 1px solid var(--ag-cat-guides); }
.ag-badge--defi           { color: var(--ag-cat-defi-text); background: var(--ag-cat-defi-bg);  border: 1px solid var(--ag-cat-defi); }
.ag-badge--ai             { color: var(--ag-cat-ai-text); background: var(--ag-cat-ai-bg);  border: 1px solid var(--ag-cat-ai); }
.ag-badge--press-releases { color: var(--ag-cat-press-releases-text); background: var(--ag-cat-press-releases-bg); border: 1px solid var(--ag-cat-press-releases); }
.ag-badge--research       { color: var(--ag-cat-research-text); background: var(--ag-cat-research-bg);   border: 1px solid var(--ag-cat-research); }
.ag-badge--reviews        { color: var(--ag-cat-reviews-text); background: var(--ag-cat-reviews-bg);   border: 1px solid var(--ag-cat-reviews); }
.ag-badge--default    { color: var(--ag-cat-default-text); background: var(--ag-cat-default-bg); border: 1px solid var(--ag-cat-default); }
.ag-badge--format {
    color: var(--ag-slate-600);
    background: var(--ag-slate-100);
    border: 1px solid var(--ag-slate-300);
    text-transform: none;
    letter-spacing: 0;
}

/* ---------------------------------------------------------------------
   Button (Aug 2026 design-system audit fix) — a canonical component,
   added net-new here rather than retrofitted onto the five buttons
   already live across the site (.header-subscribe-btn, .newsletter-box
   button, .footer-newsletter-form button, .not-found__link, and the
   Tailwind-utility CTA button in home.php). Those five keep working
   exactly as they render today — rewriting them in place risked visible
   regressions on a live site for a cosmetic-only win. This class is the
   one new button implementations (and any of the five, next time one
   gets touched) should reach for instead of hand-rolling another
   variant. Two variants (primary/secondary), hover/active states
   already used elsewhere in this file, and a real :disabled state —
   the audit's other finding was that no button or form control in the
   stylesheet defined one. */
.ag-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font-family: var(--ag-font-sans); font-size: var(--ag-text-label-caps); font-weight: 600;
    letter-spacing: 0.05em; text-transform: uppercase; padding: 12px var(--ag-space-5);
    border-radius: var(--ag-radius-sm); border: 1px solid transparent; cursor: pointer;
    transition: background-color var(--ag-transition-fast), color var(--ag-transition-fast), transform 0.2s ease, opacity var(--ag-transition-fast);
}
.ag-btn:active { transform: scale(0.97); }
.ag-btn--primary { background: var(--ag-primary); color: var(--ag-white); }
.ag-btn--primary:hover { background: var(--ag-ink); color: var(--ag-white); }
.ag-btn--secondary { background: transparent; color: var(--ag-ink); border-color: var(--ag-outline-variant); }
.ag-btn--secondary:hover { border-color: var(--ag-accent-600); color: var(--ag-accent-600); }
.ag-btn:disabled, .ag-btn[aria-disabled="true"] {
    cursor: not-allowed; opacity: 0.5; transform: none; pointer-events: none;
}

/* Defensive :disabled states for the five existing hand-rolled buttons
   above — none had one (the audit's finding). Purely additive: none of
   these currently ever render with a `disabled` attribute, so this
   changes nothing about how the site looks today, only how it will
   look the first time a form-submission-in-progress state gets added. */
.header-subscribe-btn:disabled,
.newsletter-box button:disabled,
.footer-newsletter-form button:disabled,
.not-found__link[aria-disabled="true"],
.ag-search-form button:disabled,
.header-search-form button:disabled {
    cursor: not-allowed; opacity: 0.5; pointer-events: none;
}

/* ---------------------------------------------------------------------
   Header: two-row (ticker + nav), sticky
   --------------------------------------------------------------------- */
.site-header { position: sticky; top: 0; z-index: 100; }

/* Row 1: live "Market Pulse" price ticker — black strip, Inter tabular
   nums, per-asset trend icon, inline Fear & Greed chip, "Verified
   Stories" pill. See header.php / footer.php (a decorative bottom
   repeat) for the shared [data-ticker-coin] markup contract. */
.price-ticker {
    background: var(--ag-navy-800);
    padding: 0;
    overflow-x: auto;
    scrollbar-width: none;
}
.price-ticker::-webkit-scrollbar { display: none; }
.price-ticker__inner {
    display: flex; align-items: center; gap: var(--ag-space-5); white-space: nowrap;
    height: 40px; padding: 0 var(--ag-space-8);
}
.price-ticker--footer .price-ticker__inner { padding: 0 var(--ag-space-5); gap: var(--ag-space-6); justify-content: flex-start; }
/* Verified against the raw export's own <style> block: a 30s linear
   scrolling marquee, not a static row — footer.php duplicates the row
   list once inside .ticker-move for a seamless loop. */
.ticker-wrap { overflow: hidden; white-space: nowrap; box-sizing: border-box; background: var(--ag-ink); }
.ticker-move { display: inline-flex; animation: ag-ticker 30s linear infinite; }
@keyframes ag-ticker { 0% { transform: translate3d(0,0,0); } 100% { transform: translate3d(-50%,0,0); } }
@media (prefers-reduced-motion: reduce) { .ticker-move { animation: none; } }
.price-ticker__label { display: flex; align-items: baseline; gap: var(--ag-space-2); margin-right: var(--ag-space-2); }
.price-ticker__label-title { font-size: var(--ag-text-label-caps); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ag-white); }
.price-ticker__label-sub { font-size: var(--ag-text-caption); color: var(--ag-data-gray); }
.price-ticker__row {
    display: flex; align-items: center; gap: 4px; font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums; color: var(--ag-white); padding: 4px 8px; border-radius: var(--ag-radius-sm);
    transition: background-color var(--ag-transition-fast);
}
.price-ticker__row:hover { background: rgba(255,255,255,0.08); }
.price-ticker__row svg { flex-shrink: 0; color: var(--ag-success-green); }
.price-ticker__row.is-down svg { color: var(--ag-error-red); }
.price-ticker__symbol { font-size: var(--ag-text-caption); font-weight: 600; color: var(--ag-white); }
.price-ticker__price { font-size: var(--ag-text-data-mono); color: var(--ag-white); }
.price-ticker__change { font-size: var(--ag-text-caption); color: var(--ag-data-gray); }
.price-ticker__row.is-up .price-ticker__change { color: var(--ag-success-green); }
.price-ticker__row.is-down .price-ticker__change { color: var(--ag-error-red); }
.price-ticker__fng, .price-ticker__verified {
    display: flex; align-items: center; gap: 6px; font-size: var(--ag-text-caption); color: var(--ag-white);
}
.price-ticker__fng svg { color: var(--ag-gold); }
/* Verified: raw export's "Verified Stories" pill is text-on-primary
   (plain white) throughout — only the Fear & Greed icon is gold. */
.price-ticker__verified { margin-left: auto; color: var(--ag-white); flex-shrink: 0; }
.price-ticker__verified svg { flex-shrink: 0; }

/* Row 2: wordmark + nav */
.site-nav-row {
    background: rgba(249,249,247,0.92);
    border-bottom: var(--ag-border-hairline);
    backdrop-filter: saturate(180%) blur(6px);
}
/* Verified against the raw export's actual <nav> markup: logo + link
   list share ONE flex container on the left (space-x-8 = 32px gap
   between them), search/subscribe/menu grouped on the right, pushed
   there with margin-left:auto — NOT a 3-column centered-nav grid (that
   was wrong, based on the separately-typed "Implementation Guide"
   rather than the real export). */
.site-nav-row__inner { display: flex; align-items: center; height: 80px; gap: var(--ag-space-6); }
.site-nav-row__inner .header-actions { margin-left: auto; }
.site-branding { display: flex; align-items: center; margin: 0; }
.site-branding a { display: flex; align-items: center; color: var(--ag-primary); }
.site-branding img, .site-branding svg { height: 44px; width: auto; }
/* font-display-lg text-headline-lg text-primary uppercase tracking-tighter
   in the raw export: Source Serif 4, 40px/700, true black, -0.05em. */
.site-branding__wordmark {
    font-family: var(--ag-font-serif); font-weight: 700; font-size: var(--ag-text-headline-lg); letter-spacing: -0.05em;
    text-transform: uppercase; color: var(--ag-primary);
}

.primary-navigation { display: flex; align-items: center; height: 100%; }
.primary-navigation ul { display: flex; gap: var(--ag-space-5); height: 100%; align-items: flex-end; }
.primary-navigation li { display: flex; align-items: flex-end; }
.primary-navigation a {
    font-family: var(--ag-font-sans); font-size: var(--ag-text-label-caps); font-weight: 600; color: var(--ag-on-surface-variant);
    text-transform: uppercase; letter-spacing: 0.05em; padding-bottom: 6px; border-bottom: 2px solid transparent;
    transition: color var(--ag-transition-fast);
}
/* Verified: raw export's nav-link hover is a plain color change to
   accent-gold — no underline/border animation on hover. */
.primary-navigation a:hover { color: var(--ag-gold); }
/* Raw export's "current" item (News): border-b-2 border-primary pb-1
   (4px padding + 2px border = 6px, matching others' plain 6px padding),
   text-primary at 80% opacity. */
.primary-navigation .current-menu-item > a,
.primary-navigation .current-menu-ancestor > a { color: var(--ag-primary); opacity: 0.8; border-bottom-color: var(--ag-primary); padding-bottom: 4px; }

.header-actions { display: flex; align-items: center; gap: var(--ag-space-4); }
.header-search-toggle, .menu-toggle {
    color: var(--ag-ink); display: flex; align-items: center; justify-content: center;
    padding: 6px; min-width: var(--ag-touch-target); min-height: var(--ag-touch-target); transition: color var(--ag-transition-fast);
}
.header-search-toggle:hover, .menu-toggle:hover { color: var(--ag-gold); }
.menu-toggle { display: none; }

/* Verified: raw export's Subscribe pill is bg-primary hover:bg-ink —
   both are near-black, i.e. essentially NO hover color change, only
   the btn-scale press animation. The gold hover here was wrong. */
.header-subscribe-btn {
    display: inline-flex; align-items: center; background: var(--ag-primary); color: var(--ag-white);
    font-family: var(--ag-font-sans); font-size: var(--ag-text-label-caps); font-weight: 600;
    letter-spacing: 0.05em; text-transform: uppercase; padding: 12px var(--ag-space-5);
    border-radius: var(--ag-radius-sm); transition: background-color var(--ag-transition-fast), transform 0.2s ease;
}
.header-subscribe-btn:hover { background: var(--ag-ink); color: var(--ag-white); }
.header-subscribe-btn:active { transform: scale(0.97); }

.header-search-form { display: none; padding: var(--ag-space-3) 0; border-top: var(--ag-border-hairline); background: var(--ag-paper-white); }
.header-search-form.is-open { display: block; }
.header-search-form form { display: flex; gap: var(--ag-space-2); }
.header-search-form input[type="search"] {
    flex: 1; padding: 10px var(--ag-space-4); border: var(--ag-border-strong);
    border-radius: var(--ag-radius-md); font-size: var(--ag-text-ui); font-family: var(--ag-font-sans);
}
.header-search-form button {
    background: var(--ag-ink); color: var(--ag-white); border-radius: var(--ag-radius-md);
    padding: 0 var(--ag-space-5); font-weight: 600; font-size: var(--ag-text-small);
}

/* Standalone search form (404.php, search.php) — same visual treatment
   as the header's version without requiring its collapsible wrapper. */
.ag-search-form { display: flex; gap: var(--ag-space-2); max-width: 480px; margin: 0 auto; }
.ag-search-form input[type="search"] {
    flex: 1; padding: 12px var(--ag-space-4); border: var(--ag-border-strong);
    border-radius: var(--ag-radius-md); font-size: var(--ag-text-ui); font-family: var(--ag-font-sans);
}
/* Aug 2026 a11y fix: default bg was --ag-accent-600 with white text
   (3.09:1, fails 4.5:1) — hover already darkened to --ag-accent-700
   (passes), so the resting state is what needed to change. Hover now
   signals via opacity instead of a color step the token scale doesn't
   have one darker than. */
.ag-search-form button {
    background: var(--ag-accent-700); color: var(--ag-white); border-radius: var(--ag-radius-md);
    padding: 0 var(--ag-space-5); font-weight: 600; font-size: var(--ag-text-small);
}
.ag-search-form button:hover { opacity: 0.85; }

.mobile-nav { display: none; background: var(--ag-paper-white); border-bottom: var(--ag-border-hairline); padding: var(--ag-space-4) 0; }
.mobile-nav.is-open { display: block; }
.mobile-nav ul { display: flex; flex-direction: column; gap: 4px; }
.mobile-nav a {
    display: block; padding: 12px 0; font-size: var(--ag-text-ui); font-weight: 600;
    color: var(--ag-ink); border-bottom: var(--ag-border-hairline); min-height: var(--ag-touch-target);
}
.mobile-nav__subscribe {
    display: block; margin-top: var(--ag-space-3); text-align: center; background: var(--ag-ink); color: var(--ag-white) !important;
    padding: 12px; border-radius: var(--ag-radius-sm); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
    font-size: var(--ag-text-label-caps); border-bottom: none !important;
}

/* ---------------------------------------------------------------------
   Homepage — rebuilt Aug 2026 against the Stitch "Ink and Paper"
   export: ambient WebGL shader canvas behind everything, 12-col grid
   (8-col main + 4-col sidebar), scroll-entrance animations.
   --------------------------------------------------------------------- */
#bg-canvas { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: -1; pointer-events: none; }

.homepage-grid { display: grid; grid-template-columns: 2fr 1fr; gap: var(--ag-space-6); padding: var(--ag-space-6) 0 var(--ag-space-8); align-items: start; }
.homepage-main { display: flex; flex-direction: column; gap: var(--ag-space-7); min-width: 0; }
.homepage-sidebar {
    display: flex; flex-direction: column; gap: var(--ag-space-6);
    padding-left: var(--ag-space-6); border-left: var(--ag-border-hairline);
}
.hr-subtle { border: none; border-top: var(--ag-hairline-on-ink); margin: 0; }

/* Entrance animations + hover-lift, matching the Stitch export's
   scroll-triggered CSS. Respects prefers-reduced-motion via the
   `--ag-transition-entrance: 0ms` override in design-tokens.css, but
   that alone doesn't stop the animation's opacity:0 starting state, so
   the reduced-motion block below turns the whole animation off. */
/* Verified against the raw export's own slideUpFade keyframe: 30px, not 20px */
@keyframes ag-slide-up-fade { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
@keyframes ag-pulse-glow { 0% { box-shadow: 0 0 0 0 rgba(176,141,87,0.4); } 70% { box-shadow: 0 0 0 6px rgba(176,141,87,0); } 100% { box-shadow: 0 0 0 0 rgba(176,141,87,0); } }
@media (prefers-reduced-motion: no-preference) {
    .animate-entrance { animation: ag-slide-up-fade var(--ag-transition-entrance) forwards; opacity: 0; }
    .animate-entrance-delay-1 { animation: ag-slide-up-fade var(--ag-transition-entrance) 0.15s forwards; opacity: 0; }
    .animate-entrance-delay-2 { animation: ag-slide-up-fade var(--ag-transition-entrance) 0.3s forwards; opacity: 0; }
    .hover-lift { transition: transform 0.3s cubic-bezier(0.16,1,0.3,1), box-shadow 0.3s cubic-bezier(0.16,1,0.3,1); }
    .hover-lift:hover { transform: translateY(-4px); box-shadow: var(--ag-shadow-hover); }
    .interactive-badge:hover { animation: ag-pulse-glow 1.5s infinite; }
}
@media (prefers-reduced-motion: reduce) {
    .animate-entrance, .animate-entrance-delay-1, .animate-entrance-delay-2 { opacity: 1; animation: none; }
}
/* JS-driven variant: assets/entrance-animations.js adds .is-in-view via
   IntersectionObserver instead of relying purely on load-time
   animation, so below-the-fold sections (Latest Reports, Deep Dives)
   animate in on scroll rather than firing invisibly at page load. */
[data-animate-on-scroll] { opacity: 0; transform: translateY(30px); }
[data-animate-on-scroll].is-in-view {
    animation: ag-slide-up-fade var(--ag-transition-entrance) forwards;
}
@media (prefers-reduced-motion: reduce) {
    [data-animate-on-scroll] { opacity: 1; transform: none; animation: none; }
}

/* Hero article — verified against raw export: h-[400px] md:h-[500px].
   The article itself has no wrapper divs to hang a `gap` on (our
   GenerateBlocks markup is flat: media, badge-row, h1, p, meta as
   direct siblings), so the raw export's two nested gaps — gap-6 (32px)
   between media and the text block, gap-4 (16px) uniformly between
   badge-row/h1/p/meta within it — are reproduced as margin-top on each
   sibling instead. */
.hero-lead__media {
    position: relative; border-radius: var(--ag-radius-lg); overflow: hidden;
    height: 400px; background: var(--ag-surface-container-high);
}
@media (min-width: 900px) {
    .hero-lead__media { height: 500px; }
}
.hero-lead__media img {
    width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); opacity: 0.9;
    transition: filter 0.7s ease, opacity 0.7s ease;
}
.hero-lead__media:hover img { filter: grayscale(0); opacity: 1; }
.hero-lead__badge-row { display: flex; align-items: center; gap: var(--ag-space-3); margin-top: var(--ag-space-6); }
.hero-lead__date { font-family: var(--ag-font-mono); font-size: var(--ag-text-caption); color: var(--ag-data-gray); }
/* Mobile: font-headline-lg-mobile/text-headline-lg-mobile (32px). Desktop
   (md:): font-headline-lg/text-headline-lg (40px) — verified against raw
   export, which our previous single-size version missed. */
.hero-lead__headline { font-family: var(--ag-font-serif); font-weight: 700; font-size: var(--ag-text-headline-lg-mobile); line-height: 1.2; color: var(--ag-ink); margin-top: var(--ag-space-4); }
.hero-lead__dek, .hero-lead__meta { margin-top: var(--ag-space-4); }
@media (min-width: 900px) {
    .hero-lead__headline { font-size: var(--ag-text-headline-lg); }
}
.hero-lead__headline a { color: inherit; }
/* The raw export's <h1> isn't even a link and has no hover treatment;
   our version must link to the article, but shouldn't invent a gold
   hover color that isn't in the source design. */
.hero-lead__headline a:hover { color: inherit; }
.hero-lead__dek { font-family: var(--ag-font-sans); font-size: var(--ag-text-body-lg); line-height: 1.65; color: var(--ag-on-surface-variant); margin-top: var(--ag-space-3); max-width: 60ch; }
.hero-lead__meta { display: flex; align-items: center; gap: var(--ag-space-2); margin-top: var(--ag-space-4); font-size: var(--ag-text-label-caps); color: var(--ag-ink); text-transform: uppercase; }
/* Aug 2026 design-critique fix: was person-style initials ("AE") on a
   byline that's always the same "AltcoinGordon Editorial" desk, never
   an individual — read as an unfinished placeholder rather than a
   deliberate mark. A gold verified-icon in the same tinted-circle
   treatment as the trust badge icons (.badge-hero__icon /
   .badge-strip__icon) reads as "our editorial desk," which is what
   it actually is. */
.byline-avatar {
    width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--ag-gold) 12%, var(--ag-surface-container-lowest));
    color: var(--ag-gold);
}

/* Latest Verified Reports */
.section-heading {
    font-family: var(--ag-font-serif); font-size: var(--ag-text-headline-md); font-weight: 600; color: var(--ag-ink);
}
.latest-reports__head { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: var(--ag-space-5); }
.latest-reports__view-all { font-family: var(--ag-font-sans); font-size: var(--ag-text-label-caps); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ag-accent-700); }
.latest-reports__view-all:hover { text-decoration: underline; }
/* gap-x-gutter(24px) gap-y-8(32px); article: p-3(12px) rounded-lg(4px)
   border-transparent hover:border-outline-variant/30 — verified against
   raw export exactly. */
.latest-reports__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--ag-space-6) var(--ag-gutter); }
.report-card {
    display: flex; flex-direction: column; gap: var(--ag-space-2); border-radius: var(--ag-radius-lg);
    padding: var(--ag-space-3); border: 1px solid transparent; transition: border-color var(--ag-transition-fast);
}
.report-card:hover { border-color: var(--ag-outline-variant-30); }
.report-card__media { width: 100%; height: 192px; border-radius: var(--ag-radius-sm); overflow: hidden; background: var(--ag-surface-container); }
.report-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; }
.report-card:hover .report-card__media img { transform: scale(1.05); }
.report-card__meta { display: flex; align-items: center; gap: 6px; font-family: var(--ag-font-mono); font-size: 11px; color: var(--ag-data-gray); text-transform: uppercase; margin-top: var(--ag-space-1); }
.report-card__meta svg { color: var(--ag-success-green); flex-shrink: 0; }
.report-card__headline { font-family: var(--ag-font-serif); font-size: 20px; line-height: 1.4; font-weight: 600; color: var(--ag-ink); }
.report-card__headline a { color: inherit; }
/* The raw export's headline hover class (text-primary-fixed-variant)
   isn't a real defined color in its own tailwind config, so it's a
   visual no-op in the live sample — no gold hover here either. */
.report-card__headline a:hover { color: inherit; }

/* Deep Dives & Analysis — verified against raw export: gap-6(32px)
   article, p-4(16px), rounded-lg(4px), border-transparent hover
   outline-variant/30, hover-lift (translateY -4px + shadow), media
   h-40 (160px), md:w-1/3 (~33%). */
.deep-dives { display: flex; flex-direction: column; gap: var(--ag-space-6); }
.deep-dive-card {
    display: flex; gap: var(--ag-space-6); border-radius: var(--ag-radius-lg); padding: var(--ag-space-4);
    background: rgba(249,249,247,0.5); border: 1px solid transparent;
    transition: border-color var(--ag-transition-fast), transform 0.3s cubic-bezier(0.16,1,0.3,1), box-shadow 0.3s cubic-bezier(0.16,1,0.3,1);
}
.deep-dive-card:hover { border-color: var(--ag-outline-variant-30); transform: translateY(-4px); box-shadow: var(--ag-shadow-hover); }
.deep-dive-card__media { flex: 0 0 33%; height: 160px; border-radius: var(--ag-radius-sm); overflow: hidden; background: var(--ag-surface-container); }
.deep-dive-card__media img { width: 100%; height: 100%; object-fit: cover; }
.deep-dive-card__body { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.deep-dive-card__meta { font-family: var(--ag-font-mono); font-size: 11px; color: var(--ag-accent-700); text-transform: uppercase; letter-spacing: 0.03em; }
.deep-dive-card__headline { font-family: var(--ag-font-serif); font-size: var(--ag-text-h2); font-weight: 600; color: var(--ag-ink); margin-top: 6px; }
.deep-dive-card__headline a { color: inherit; }
/* Same non-functional hover class in the source as report-card — no
   gold hover color on the headline text. */
.deep-dive-card__headline a:hover { color: inherit; }
.deep-dive-card__dek { font-size: var(--ag-text-small); color: var(--ag-on-surface-variant); margin-top: 6px; }

/* Sidebar widgets — shared chrome */
.sidebar-widget {
    background: rgba(249,249,247,0.8); border: var(--ag-border-hairline); border-radius: var(--ag-radius-sm);
    padding: var(--ag-space-5);
}
.sidebar-widget__title {
    font-family: var(--ag-font-sans); font-size: var(--ag-text-label-caps); font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--ag-ink); border-bottom: var(--ag-border-hairline); padding-bottom: var(--ag-space-3);
    margin-bottom: var(--ag-space-4); display: flex; align-items: center; gap: var(--ag-space-2);
}
.sidebar-widget__title svg { color: var(--ag-gold); flex-shrink: 0; }

/* Market Pulse (sidebar price list) */
.market-pulse-widget__list { display: flex; flex-direction: column; }
.market-pulse-widget__row { display: flex; justify-content: space-between; align-items: center; padding: var(--ag-space-2) 0; border-bottom: 1px solid var(--ag-outline-variant-30); }
.market-pulse-widget__row:last-child { border-bottom: none; }
.market-pulse-widget__symbol { font-family: var(--ag-font-mono); font-weight: 600; color: var(--ag-ink); }
.market-pulse-widget__name { font-family: var(--ag-font-mono); font-size: 11px; color: var(--ag-data-gray); }
.market-pulse-widget__figures { text-align: right; }
.market-pulse-widget .price-ticker__price { color: var(--ag-ink); font-size: var(--ag-text-data-mono); }
.market-pulse-widget .price-ticker__change { font-size: 12px; }
.market-pulse-widget .price-ticker__change { color: var(--ag-data-gray); }
.market-pulse-widget__row.is-up .price-ticker__change { color: var(--ag-success-green); }
.market-pulse-widget__row.is-down .price-ticker__change { color: var(--ag-error-red); }

/* Trending Verified (sidebar) */
.sidebar-trending__list { display: flex; flex-direction: column; gap: var(--ag-space-4); }
.sidebar-trending__item { display: flex; gap: var(--ag-space-4); align-items: flex-start; }
.sidebar-trending__rank { font-family: var(--ag-font-serif); font-size: var(--ag-text-headline-md); color: var(--ag-outline-variant); line-height: 1; transition: color var(--ag-transition-fast); }
.sidebar-trending__item:hover .sidebar-trending__rank { color: var(--ag-gold); }
.sidebar-trending__body { display: flex; flex-direction: column; gap: 2px; }
.sidebar-trending__headline { font-family: var(--ag-font-sans); font-size: 15px; line-height: 1.3; font-weight: 500; color: var(--ag-ink); }
.sidebar-trending__item:hover .sidebar-trending__headline { text-decoration: underline; }
.sidebar-trending__cat { font-family: var(--ag-font-mono); font-size: 10px; color: var(--ag-data-gray); text-transform: uppercase; }

/* Verification Standard callout */
.verification-standard-callout { background: var(--ag-surface-container-highest); }
.verification-standard-callout > svg { color: var(--ag-trust-navy); }
.verification-standard-callout h3 { font-family: var(--ag-font-serif); font-size: 20px; color: var(--ag-ink); margin-top: var(--ag-space-3); }
.verification-standard-callout p { font-size: var(--ag-text-small); color: var(--ag-on-surface-variant); margin: var(--ag-space-2) 0 0; }
.verification-standard-callout a { font-family: var(--ag-font-sans); font-size: 11px; color: var(--ag-ink); text-transform: uppercase; text-decoration: underline; }
.verification-standard-callout a:hover { color: var(--ag-gold); }

/* Newsletter box (sidebar "Daily Verify") */
.newsletter-box { background: var(--ag-ink); color: var(--ag-white); }
.newsletter-box h3 { font-family: var(--ag-font-serif); font-size: 22px; }
.newsletter-box p { font-size: var(--ag-text-small); color: var(--ag-outline-variant); margin: var(--ag-space-2) 0 0; }
.newsletter-box form { display: flex; flex-direction: column; gap: var(--ag-space-2); margin-top: var(--ag-space-4); }
.newsletter-box input[type="email"] {
    background: transparent; border: none; border-bottom: 1px solid rgba(255,255,255,0.3); color: var(--ag-white);
    font-family: var(--ag-font-mono); font-size: var(--ag-text-small); padding: var(--ag-space-2) 0;
}
.newsletter-box input[type="email"]::placeholder { color: var(--ag-outline-variant); }
/* Aug 2026 a11y fix: was "outline: none" + a border-color-only cue,
   opting this one input out of the site's otherwise-consistent global
   :focus-visible outline (see near the top of this file) for
   something much harder to see. Keeps the gold border-bottom as a
   secondary cue but restores the real outline as the primary one. */
.newsletter-box input[type="email"]:focus { outline: 2px solid var(--ag-accent-600); outline-offset: 2px; border-bottom-color: var(--ag-gold); }
.newsletter-box button {
    margin-top: var(--ag-space-3); background: var(--ag-white); color: var(--ag-ink); font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em; font-size: var(--ag-text-label-caps); padding: var(--ag-space-3);
    border-radius: var(--ag-radius-sm); transition: background-color var(--ag-transition-fast), color var(--ag-transition-fast);
}
.newsletter-box button:hover { background: var(--ag-gold); color: var(--ag-white); }

/* Legacy Fear & Greed gauge widget markup — kept for potential reuse
   elsewhere; the homepage sidebar itself no longer renders it as of
   the Aug 2026 redesign (its data now surfaces inline in the header
   ticker's "Fear & Greed: NN" chip instead — see header.php). */
.fear-greed { border: var(--ag-border-hairline); border-radius: var(--ag-radius-md); padding: var(--ag-space-4); }
.fear-greed__header { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--ag-space-3); }
.fear-greed__title { font-family: var(--ag-font-sans); font-size: var(--ag-text-small); font-weight: 700; color: var(--ag-slate-600); text-transform: uppercase; letter-spacing: 0.3px; }
.fear-greed__source { font-size: 11px; color: var(--ag-slate-400); }
.fear-greed__gauge { position: relative; height: 8px; border-radius: var(--ag-radius-full); background: linear-gradient(90deg, var(--ag-error-500), var(--ag-warning-600), var(--ag-slate-300), var(--ag-success-600), var(--ag-success-500)); }
.fear-greed__needle { position: absolute; top: -4px; width: 2px; height: 16px; background: var(--ag-navy-900); transform: translateX(-1px); transition: left var(--ag-transition-base); }
.fear-greed__readout { display: flex; align-items: baseline; gap: var(--ag-space-2); margin-top: var(--ag-space-3); }
.fear-greed__value { font-family: var(--ag-font-mono); font-size: 28px; font-weight: 500; color: var(--ag-navy-900); }
.fear-greed__label { font-size: var(--ag-text-small); color: var(--ag-slate-500); }

/* Market Snapshot (Aug 2026 homepage rebuild) — the full-width
   dashboard band that replaced the old 3-coin sidebar widget. Reuses
   the same [data-ticker-coin]/.price-ticker__price/.price-ticker__change
   hooks price-ticker.js already updates (so this needs zero new JS for
   prices), plus the pre-existing-but-previously-unused .fear-greed
   gauge widget (see the "Legacy" comment above — it's not legacy
   anymore) and a new, equally keyless CoinGecko /global fetch for BTC
   dominance (assets/btc-dominance.js). */
.market-snapshot { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--ag-space-3); }
.market-snapshot__card {
    background: var(--ag-surface-container-low); border: var(--ag-border-hairline); border-radius: var(--ag-radius-lg);
    padding: var(--ag-space-4); display: flex; flex-direction: column; gap: 4px;
}
.market-snapshot__card .price-ticker__price { color: var(--ag-ink); font-size: 18px; font-weight: 600; }
.market-snapshot__card .price-ticker__change { font-size: var(--ag-text-small); }
.market-snapshot__label { font-family: var(--ag-font-mono); font-size: 11px; color: var(--ag-slate-500); text-transform: uppercase; letter-spacing: 0.4px; }
.market-snapshot__card.is-up .price-ticker__change { color: var(--ag-success-green); }
.market-snapshot__card.is-down .price-ticker__change { color: var(--ag-error-red); }
.market-snapshot__stat { font-family: var(--ag-font-mono); font-size: 18px; font-weight: 600; color: var(--ag-ink); }
.market-snapshot .fear-greed { border: none; padding: 0; }
.market-snapshot .fear-greed__value { font-size: 18px; }

@media (max-width: 900px) {
    .market-snapshot { grid-template-columns: repeat(2, 1fr); }
}

/* ---------------------------------------------------------------------
   Archive / search listing
   --------------------------------------------------------------------- */
/* padding-top/bottom only, not the `padding` shorthand — .archive-header
   shares its element with .ag-container (which supplies the left/right
   inset, 16px on mobile). A 3-value shorthand's implicit "0" for
   left/right silently wins the cascade over .ag-container's own
   padding since this rule is declared later, zeroing that inset and
   pushing the "DESK" label + title flush against the screen edge on
   mobile (same bug class as the .article-layout fix elsewhere in this
   file — see that comment for the full story). */
/* padding-top removed: supplied globally by the #content rule above.
   Leaving it here made every page using this component doubly spaced. */
.archive-header { padding-bottom: var(--ag-space-2); }
/*
 * THE page title. One spec, every page and every archive.
 *
 * Measured before this existed: /about/, /verification/, /corrections/,
 * /contact/ and /terms/ rendered 52px weight 400 through
 * .archive-header__title, while /news/ and every category archive rendered
 * 36px weight 700 through .ag-archive__title, and /wire/ had invented a
 * third at 46px weight 700. Nobody chose that; three templates each solved
 * the same problem and none of them knew about the others.
 *
 * .ag-archive__title is listed here rather than deleted because archive.php
 * wraps its title in topic-hub logic that is not worth unpicking for a font
 * size. It is an alias, not a second opinion -- do not give it its own type
 * rules anywhere else.
 *
 * New templates should not use either class directly. Call ag_page_header()
 * (inc/page-header.php) and inherit this.
 */
.archive-header__title,
.ag-archive__title {
    font-size: var(--ag-text-display);
    font-family: var(--ag-font-serif);
}
.archive-header__desc { color: var(--ag-slate-500); margin-top: 6px; }
.listing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--ag-space-5); padding: var(--ag-space-5) 0 var(--ag-space-7); }
.pagination { display: flex; justify-content: center; gap: var(--ag-space-2); padding: var(--ag-space-5) 0 var(--ag-space-8); }
.pagination a, .pagination span {
    display: inline-flex; align-items: center; justify-content: center; min-width: var(--ag-touch-target); height: var(--ag-touch-target);
    border-radius: var(--ag-radius-md); font-size: var(--ag-text-small); border: var(--ag-border-hairline); color: var(--ag-navy-900);
}
.pagination .current { background: var(--ag-navy-900); color: var(--ag-white); border-color: var(--ag-navy-900); }
.pagination a:hover { border-color: var(--ag-accent-600); color: var(--ag-accent-600); }

/* ---------------------------------------------------------------------
   Single article
   --------------------------------------------------------------------- */
.reading-progress {
    position: fixed; top: 0; left: 0; height: 3px; width: 0; background: var(--ag-accent-600);
    z-index: 200; transition: width 0.1s linear;
}
@media (prefers-reduced-motion: reduce) { .reading-progress { transition: none; } }

/* Article layout (Aug 2026): wider two-column reading page — content
   + a right-rail "Trending Verified" sidebar — modeled on how sites
   like Cointelegraph lay out a single article, replacing the earlier
   single centered 68ch column that left huge empty gutters on desktop.
   ag-container (1280px) sets the overall width; the 68ch cap moves
   down onto the actual text — reverted Aug 2026: user feedback was
   that capping body copy while the hero image ran full main-column
   width left a large dead gap between the text column and the
   sidebar. Body copy now matches the hero's width (full main-column
   width) instead of a separate, narrower measure. */
/* padding-top/bottom only (not the shorthand) — the shorthand's "0"
   for left/right was silently zeroing out .ag-container's own
   horizontal inset (64px desktop / 16px mobile, same class is on this
   element), since this rule comes later in the cascade and wins on
   equal specificity. Invisible on desktop (the 1280px max-width +
   auto margins still centered everything with room to spare) but on
   phones, where the container is already 100% width, it left the
   headline and body text flush against the screen edges. */
.article-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--ag-gutter-lg); align-items: start; padding-top: var(--ag-space-6); padding-bottom: var(--ag-space-8); }
.article-main { min-width: 0; } /* prevents the grid track from blowing out to the hero image's intrinsic width */
.article-header, .entry-content { max-width: none; }

.article-sidebar { position: sticky; top: var(--ag-space-6); display: flex; flex-direction: column; gap: var(--ag-space-7); min-width: 0; }
.sidebar-widget__title {
    display: flex; align-items: center; gap: var(--ag-space-2); font-family: var(--ag-font-sans);
    font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ag-ink);
    padding-bottom: var(--ag-space-3); border-bottom: var(--ag-border-strong); margin: 0 0 var(--ag-space-4);
}
.sidebar-widget__title-icon { color: var(--ag-gold); flex-shrink: 0; }
.trending-list { display: flex; flex-direction: column; gap: var(--ag-space-4); list-style: none; margin: 0; padding: 0; }
.trending-list__link { display: flex; gap: var(--ag-space-3); align-items: flex-start; }
/* --ag-slate-500, not --ag-outline-variant (Aug 2026 a11y pass):
   outline-variant (#c4c7c7) gave 1.61:1 against the #f9f9f7 page
   background -- these rank numerals were very nearly invisible. Note
   this uses a DARKER value than home.php's equivalent numerals
   (--ag-slate-450): at 20px this is normal-size text needing the full
   4.5:1, whereas home.php renders the same idea at 28px, which counts
   as large text and only needs 3:1. Same component, two sizes, two
   correct answers. Now 4.90:1. */
.trending-list__rank { font-family: var(--ag-font-serif); font-size: 20px; line-height: 1.3; color: var(--ag-slate-500); flex-shrink: 0; transition: color var(--ag-transition-fast); }
.trending-list__link:hover .trending-list__rank { color: var(--ag-gold); }
.trending-list__headline { display: block; font-family: var(--ag-font-sans); font-size: 15px; line-height: 1.35; font-weight: 600; color: var(--ag-ink); }
.trending-list__link:hover .trending-list__headline { text-decoration: underline; }
.trending-list__meta { display: block; font-family: var(--ag-font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ag-data-gray); margin-top: 3px; }

/* Default: object-fit: contain, for the older flat, text-heavy
   branded SVG (light bg, wordmark, category chip, verified badge
   near the edges — see altcoingordon_parse_svg_dimensions() in
   functions.php). Cropping that graphic cuts off real content, so
   contain guarantees the whole thing stays visible; the bg color
   matches the SVG's own canvas fill so there's no visible seam.

   .article-hero--photo overrides to cover: real Unsplash photos (Aug
   2026, see altcoingordon_thumbnail_is_photo()) are a normal 1200x630
   editorial image, not edge-critical — contain left blank bars down
   both sides since the image is narrower than the hero once scaled
   to fit its height. Cover fills the frame properly instead. */
.article-hero { position: relative; background: var(--ag-media-placeholder); overflow: hidden; }
.article-hero img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* Aug 2026 Intelligence Card redesign: the hero now renders via
   altcoingordon_ic_media( $id, 'hero' ) — a .ic-media element whose
   own aspect-ratio (see .ic-hero__media) governs height, so the old
   fixed 380px/220px wrapper height is dropped in favor of that. The
   rules above stay only for any old cached markup / feed reader that
   still renders a bare <img> here directly. */
.article-hero .ic-media { width: 100%; }
/* object-position: bottom, not center — the hero's aspect ratio is
   still wider than the photo's native 1200x630 even constrained to
   the main column, so cover crops some vertical content regardless.
   Anchoring to the bottom keeps the wordmark/category chip/
   photographer-credit strip (all composited near the photo's bottom
   edge — see photo_watermark.py) fully visible; the top-right
   "verified" corner badge is the one element that can get cropped on
   wide screens, an acceptable trade since it's a secondary trust
   signal, not the Unsplash-required attribution. */
.article-hero--photo img { object-fit: cover; object-position: center bottom; }

@media (max-width: 782px) {
	.article-hero { height: auto; }
}

.article-header { padding: var(--ag-space-6) 0 0; }
.article-header__title { font-size: var(--ag-text-h1); line-height: 1.25; font-family: var(--ag-font-serif); letter-spacing: -0.02em; }
.article-header__meta {
    display: flex; align-items: center; gap: var(--ag-space-3); flex-wrap: wrap; margin: var(--ag-space-5) 0;
    padding: var(--ag-space-4) 0; border-top: var(--ag-border-hairline); border-bottom: var(--ag-border-hairline);
    font-size: var(--ag-text-small); color: var(--ag-slate-500);
}
.article-header__meta .share-links { margin-left: auto; display: flex; gap: var(--ag-space-3); }
/* Aug 2026 a11y fix: had zero padding, so the clickable area was
   exactly the icon's own ~16-24px box. Full 44px would blow out this
   tight inline row (icons sit shoulder-to-shoulder with reading-time
   text), so this is a partial improvement, not full 2.5.5 compliance
   — that criterion is AAA, not required for this site's AA target. */
.article-header__meta .share-links a { color: var(--ag-slate-500); display: inline-flex; padding: 8px; margin: -8px; border-radius: var(--ag-radius-sm); }
.article-header__meta .share-links a:hover { color: var(--ag-accent-600); }
.article-header__meta a.author-link { color: var(--ag-navy-900); font-weight: 600; }
/* display: contents — the wrapper generates no box of its own, so its
   two children (.reading-time, .share-links) act as direct flex items
   of .article-header__meta, same as before this element existed. Only
   the mobile override below turns it into a real flex row. */
.meta-secondary { display: contents; }

/* ---------------------------------------------------------------------
   Article Trust Panel — Aug 2026 editorial trust badge expansion.
   Sits between the byline meta bar and the article body (see
   single.php); badge markup itself is rendered by
   altcoingordon_render_trust_badges() in inc/trust-badges.php so the
   icon/color/tooltip lookup lives in exactly one place. Deliberately
   plain, readable HTML (no JS rendering) — badges show icon + text
   label, never icon-only, per requirement #3 ("recognizable at small
   sizes") and the SEO/accessibility requirement in #6. */
.trust-panel {
    display: flex; flex-direction: column; gap: var(--ag-space-3);
    margin: 0 0 var(--ag-space-5); padding: var(--ag-space-4);
    background: var(--ag-surface-container-low); border: var(--ag-border-hairline); border-radius: var(--ag-radius-lg);
}
.trust-panel__badges { display: flex; flex-wrap: wrap; gap: var(--ag-space-2); }
.trust-badge {
    display: inline-flex; align-items: center; gap: 5px;
    background: color-mix(in srgb, var(--ag-badge-color) 12%, var(--ag-surface-container-lowest));
    border: 1px solid color-mix(in srgb, var(--ag-badge-color) 45%, transparent);
    color: var(--ag-badge-color); font-family: var(--ag-font-sans); font-weight: 700;
    font-size: var(--ag-text-caption); letter-spacing: 0.2px; text-transform: uppercase;
    padding: 5px 10px 5px 8px; border-radius: var(--ag-radius-full); line-height: 1; cursor: default;
}
.trust-badge__icon { font-size: 15px !important; line-height: 1; }
.trust-panel__meta {
    display: flex; flex-wrap: wrap; gap: var(--ag-space-4);
    font-family: var(--ag-font-sans); font-size: var(--ag-text-caption); color: var(--ag-slate-500);
    padding-top: var(--ag-space-3); border-top: var(--ag-border-hairline);
}
.trust-panel__meta-item { display: inline-flex; align-items: center; gap: 5px; }
.trust-panel__meta-item .material-symbols-outlined { font-size: 15px !important; color: var(--ag-outline); }
.trust-panel__meta-item strong { color: var(--ag-slate-700); font-weight: 700; }

.entry-content { font-family: var(--ag-font-serif); font-size: var(--ag-text-body); line-height: 1.75; color: var(--ag-slate-700); }
.entry-content .article-dek {
    font-size: var(--ag-text-quote); font-style: italic; color: var(--ag-slate-600);
    border-left: 3px solid var(--ag-accent-600); padding-left: var(--ag-space-4); margin: 0 0 1.4em;
}
.entry-content p { margin: 0 0 1.2em; }
.entry-content h2 {
    font-family: var(--ag-font-sans); font-size: var(--ag-text-small); font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.4px; color: var(--ag-accent-700); border-left: 3px solid var(--ag-accent-600);
    padding-left: var(--ag-space-3); margin: 2em 0 1em;
}
.entry-content h3 { font-family: var(--ag-font-sans); font-size: var(--ag-text-h3); font-weight: 700; color: var(--ag-navy-900); margin-top: 0; }

.faq-item { border-bottom: var(--ag-border-hairline); padding: var(--ag-space-4) 0; }
/* padding-right: the ::after chevron below is a 9x9 box rotated 45deg;
   the rotated diagonal (~12.7px) paints past the unrotated 9px box on
   the right, which browsers count toward scrollWidth — this reserves
   room for that so it never pushes the page into horizontal scroll. */
.faq-item h3 { display: flex; align-items: center; justify-content: space-between; font-size: var(--ag-text-h3); margin: 0; padding-right: 4px; }
.faq-item h3::after {
    content: ""; width: 9px; height: 9px; border-right: 2px solid var(--ag-slate-500); border-bottom: 2px solid var(--ag-slate-500);
    transform: rotate(45deg); transition: transform var(--ag-transition-fast); flex-shrink: 0; margin-left: var(--ag-space-3);
}
.faq-item.is-open h3::after { transform: rotate(-135deg); }
.faq-item p { font-size: var(--ag-text-ui); color: var(--ag-slate-700); margin-top: var(--ag-space-3); }

.related-articles { padding: var(--ag-space-7) 0 var(--ag-space-7); border-top: var(--ag-border-hairline); margin-top: var(--ag-space-7); }
.related-articles .section-heading { margin-bottom: var(--ag-space-5); }
/* Desktop-only: 3 equal columns inside the narrower article-main track
   (squeezed by the 320px sidebar) leaves each Intelligence Card too
   narrow for its badges — same root cause as the homepage Deep Dives
   fix. 2 columns gives real width back; below 900px .article-layout
   already drops the sidebar and .story-grid already goes to 2 columns
   on its own, so this rule only needs to fire above that point. */
@media (min-width: 901px) {
    .related-articles .story-grid { grid-template-columns: repeat(2, 1fr); }
}

/* story-grid/story-card: the related-articles markup in single.php
   referenced these classes from the start, but no rules for them were
   ever written — with zero CSS the cards fell back to plain block
   stacking (one full-width row per article). Mirrors .report-card's
   established visual language (rounded media, hover zoom, mono meta
   row) so this matches the rest of the site rather than inventing a
   new card style. No image-overlay badge (that was tried, then
   dropped — see the single.php comment above story-card__meta below):
   category is redundant with the chip both image providers already
   bake into the picture, so instead the meta row reuses the same
   "Fact-Checked" verified marker as .report-card__meta. */
.story-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--ag-space-6) var(--ag-gutter); }
/* Compact companion card — related-articles rail and other tight
   spots where the full Intelligence Card treatment (blur/grade/
   gradient overlay) is too heavy. Plain thumbnail + a single
   Fact-Checked marker, not the full badge/trust instrumentation. */
.story-card { display: flex; flex-direction: column; gap: var(--ag-space-2); }
/* aspect-ratio (1200/630, the real canvas size both image providers
   render at — see altcoingordon-card image size + photo_watermark.py),
   not a fixed height: a fixed 160px box didn't match the image's own
   1.905:1 aspect ratio, so object-fit:cover had to crop a slice off
   top and bottom to fill it — on the branded placeholder SVGs that
   risked cropping into the wordmark/verified-badge/photographer-credit
   elements deliberately positioned near the edges. Matching the box to
   the image's real aspect ratio (same fix applied to the homepage
   cards) means object-fit:contain now shows the whole graphic with no
   crop, at any card width. */
.story-card__media { width: 100%; aspect-ratio: 1200 / 630; border-radius: var(--ag-radius-sm); overflow: hidden; background: var(--ag-surface-container); }
.story-card__media img { width: 100%; height: 100%; object-fit: contain; transition: transform 0.5s ease; }
.story-card:hover .story-card__media img { transform: scale(1.05); }
.story-card__meta { display: flex; align-items: center; gap: 6px; font-family: var(--ag-font-mono); font-size: 11px; color: var(--ag-data-gray); text-transform: uppercase; margin-top: var(--ag-space-1); }
.story-card__meta-icon { color: var(--ag-success-green); flex-shrink: 0; font-size: 14px !important; }
.story-card__headline { font-family: var(--ag-font-serif); font-size: 18px; line-height: 1.4; font-weight: 600; color: var(--ag-ink); }
.story-card__headline a { color: inherit; }
.story-card__headline a:hover { color: inherit; }

/* ===================================================================
   AltcoinGordon Intelligence Cards (Aug 2026 featured-image redesign)
   — replaces the plain <img> featured image sitewide with a processed
   photo background (blur/grade/gradient/vignette) plus a live-rendered
   overlay: category, verification badges, reading time, last-updated,
   and Trust/Confidence/Sources instrumentation. Design approved via
   /outputs/intelligence-card-mockup-v2.html after 8 rounds of
   feedback — ported here verbatim, same values, real site tokens.
   Rendered by altcoingordon_ic_media() in inc/intelligence-card.php;
   see that file for the PHP side of this component. One component,
   used identically in every template — home.php, archive.php,
   search.php, 404.php, single.php (grid + hero variants), and every
   place .story-card used to render its own media block.

   Variants (altcoingordon_ic_media( $post_id, $variant )):
     'grid' (default) — used in card grids/rails. 1200:630 media.
     'hero' — .ic-hero__media modifier, larger 1200:500 (720 on
       mobile) media + bumped type scale, for the single lead story.

   States: hover (image scales via .ic-article:hover .ic-media__bg,
   no separate class needed — CSS-only, no JS).

   Badge color family: each of the 11 .ic-badge--* variants below maps
   1:1 to a --ag-badge-{name}-start/-end token pair in
   design-tokens.css — see the "Trust badge colors" block there. The
   same 10 verification badges also render via .trust-badge (a
   differently-styled pill, used in the article-page trust panel and
   the /verification/ hub) and .badge-strip__icon (the homepage
   verification strip) — those two both key off a single
   --ag-badge-color custom property set inline per-instance from
   altcoingordon_trust_badge_registry(), so all three renderings stay
   in sync with one source of truth even though they look different
   by design (chip vs. icon-circle vs. photo-overlay badge).
   =================================================================== */
.ic-article { display: flex; flex-direction: column; gap: var(--ag-space-2); }
.ic-media {
	position: relative; aspect-ratio: 1200 / 630; border-radius: var(--ag-radius-lg); overflow: hidden;
	display: flex; flex-direction: column; justify-content: space-between; cursor: pointer;
	box-shadow: 0 1px 3px rgba(0,0,0,0.1); background: var(--ag-surface-container-low, var(--ag-media-placeholder));
}
/* blur(2px)/brightness(0.97) is the approved floor for this treatment —
   lightened twice from an original blur(9px)/brightness(0.92) on user
   feedback ("make it lighter, more of the photo recognizable"). Any
   lighter and it stops reading as a processed background at all. Text
   legibility is the gradient's job now, not the photo filter's. */
.ic-media__bg {
	position: absolute; inset: -6%; background-size: cover; background-position: center;
	filter: blur(2px) saturate(0.97) brightness(0.97) contrast(1);
	transform: scale(1.06); transition: transform 5s cubic-bezier(0.16,1,0.3,1);
}
.ic-article:hover .ic-media__bg { transform: scale(1.14); }
/* Three dark zones: a cap at the top (behind the category chip), a
   clear window through the middle so the photo stays genuinely
   visible, and the original dark base at the bottom (behind the
   metarow/trust row text). Badges don't need the cap — they're solid
   fills, legible against any photo already. */
.ic-media__gradient { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(8,9,10,0.5) 0%, rgba(8,9,10,0.22) 13%, rgba(8,9,10,0.03) 26%, rgba(8,9,10,0.06) 52%, rgba(6,7,8,0.82) 100%); }
.ic-media__vignette { position: absolute; inset: 0; background: radial-gradient(120% 90% at 50% 40%, rgba(0,0,0,0) 55%, rgba(0,0,0,0.2) 100%); }
.ic-media__noise { position: absolute; inset: 0; opacity: 0.05; mix-blend-mode: overlay; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.ic-media__sr-img { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* Category and badges are always two separate rows, never sharing one
   line — fixed, not conditional, so a 1-badge card and a 5-badge card
   use the identical top zone; the badge row just wraps. */
.ic-media__top { position: absolute; top: 0; left: 0; right: 0; z-index: 2; display: flex; flex-direction: column; align-items: flex-start; gap: var(--ag-space-2); padding: var(--ag-space-3); }
/* Solid dark chip, not translucent — reads clearly no matter what's
   behind it in the photo. */
/* Intentionally not color-coded like .ag-badge--{category} elsewhere
   on the site: this chip sits on top of an arbitrary photo, so a
   fixed dark-glass treatment is the only one guaranteed to stay
   legible regardless of the image underneath. Two-tier system by
   design, not an inconsistency — .ag-badge--* still owns per-category
   color everywhere it's on a plain background. */
.ic-category {
	font-family: var(--ag-font-mono); font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	padding: 4px 9px; border-radius: var(--ag-radius-sm); color: var(--ag-white); background: rgba(10,12,14,0.72);
	border: 1px solid rgba(255,255,255,0.16); backdrop-filter: blur(3px);
	box-shadow: 0 2px 6px rgba(0,0,0,0.25);
}
.ic-badges { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-start; }
.ic-badge {
	display: flex; align-items: center; gap: 5px; padding: 5px 10px 5px 7px; border-radius: var(--ag-radius-full);
	font-family: var(--ag-font-sans); font-size: 10.5px; font-weight: 800; letter-spacing: 0.02em; text-transform: uppercase;
	color: var(--ag-white); box-shadow: 0 2px 6px rgba(0,0,0,0.35), inset 0 0 0 1px rgba(255,255,255,0.25);
}
.ic-badge .material-symbols-outlined { font-size: 14px; }
/* All 11 variants pull both gradient stops from --ag-badge-*-start/-end
   (design-tokens.css) — no hardcoded color values here by design, so a
   future rebrand only ever touches the token file. */
.ic-badge--verified { background: linear-gradient(180deg, var(--ag-badge-verified-start), var(--ag-badge-verified-end)); }
.ic-badge--factcheck { background: linear-gradient(180deg, var(--ag-badge-factcheck-start), var(--ag-badge-factcheck-end)); }
.ic-badge--official { background: linear-gradient(180deg, var(--ag-badge-official-start), var(--ag-badge-official-end)); }
.ic-badge--onchain { background: linear-gradient(180deg, var(--ag-badge-onchain-start), var(--ag-badge-onchain)); }
.ic-badge--data { background: linear-gradient(180deg, var(--ag-badge-data-start), var(--ag-badge-data)); }
.ic-badge--expert { background: linear-gradient(180deg, var(--ag-badge-expert-start), var(--ag-badge-expert)); }
.ic-badge--live { background: linear-gradient(180deg, var(--ag-badge-live-start), var(--ag-badge-live)); }
.ic-badge--fresh { background: linear-gradient(180deg, var(--ag-badge-fresh-start), var(--ag-badge-fresh)); }
.ic-badge--evergreen { background: linear-gradient(180deg, var(--ag-badge-evergreen-start), var(--ag-badge-evergreen)); }
.ic-badge--analysis { background: linear-gradient(180deg, var(--ag-badge-analysis-start), var(--ag-badge-analysis-end)); }
.ic-badge--default { background: linear-gradient(180deg, var(--ag-badge-default-start), var(--ag-badge-default-end)); }

/* Bottom overlay — the only place metadata lives. Row A = reading
   time / updated (quiet). Row B = Trust / Confidence / Sources —
   always the same slots in the same order; a slot that doesn't apply
   (Press Releases skip the fact-check pipeline) is simply omitted,
   never a different layout. */
.ic-media__bottom { position: absolute; bottom: 0; left: 0; right: 0; z-index: 2; padding: var(--ag-space-3); display: flex; flex-direction: column; gap: var(--ag-space-2); }
.ic-metarow { display: flex; align-items: center; gap: 8px; font-family: var(--ag-font-mono); font-size: 11px; color: rgba(255,255,255,0.68); text-transform: uppercase; letter-spacing: 0.02em; }
.ic-metarow .material-symbols-outlined { font-size: 13px; vertical-align: -2px; margin-right: 3px; color: rgba(255,255,255,0.5); }
.ic-metarow .dot { opacity: 0.45; }

.ic-trustrow { display: flex; align-items: center; gap: 14px; padding-top: 8px; border-top: 1px solid rgba(255,255,255,0.14); flex-wrap: wrap; }
.ic-metric { display: flex; align-items: center; gap: 7px; }
.ic-metric__label { font-family: var(--ag-font-mono); font-size: 9.5px; font-weight: 600; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.04em; }
.ic-metric__value { font-family: var(--ag-font-mono); font-size: 12.5px; font-weight: 700; color: var(--ag-white); }

.ic-ring { position: relative; width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; }
.ic-ring__fill { position: absolute; inset: 0; border-radius: 50%; }
.ic-ring__hole { position: absolute; inset: 3px; border-radius: 50%; background: var(--ag-ring-hole); display: flex; align-items: center; justify-content: center; font-family: var(--ag-font-mono); font-size: 8.5px; font-weight: 800; color: var(--ag-white); }

.ic-bar { width: 46px; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.18); overflow: hidden; }
.ic-bar__fill { height: 100%; border-radius: 2px; }
.ic-metric__value--empty { color: rgba(255,255,255,0.38); font-weight: 600; }

/* Headline lives OUTSIDE the media box, styled identically to the
   site's pre-existing story-card headline — nothing new here on
   purpose, per "Title stays as it is now." */
.ic-article__headline { font-family: var(--ag-font-serif); font-size: 18px; line-height: 1.4; font-weight: 600; color: var(--ag-ink); margin: 0; }
.ic-article__headline a { color: inherit; text-decoration: none; }
.ic-article__headline a:hover { color: inherit; }

.ic-hero__media { aspect-ratio: 1200/500; }
.ic-hero__media .ic-media__top { padding: var(--ag-space-5); }
.ic-hero__media .ic-media__bottom { padding: var(--ag-space-5); }
.ic-hero__media .ic-badge { font-size: 11.5px; padding: 6px 12px 6px 8px; }
.ic-hero__media .ic-metric__value { font-size: 14px; }
.ic-hero .ic-article__headline { font-size: 30px; line-height: 1.22; }

@media (max-width: 782px) {
	.ic-hero__media { aspect-ratio: 1200/720; }
	.ic-hero .ic-article__headline { font-size: 22px; line-height: 1.28; }
}


/* ---------------------------------------------------------------------
   404
   --------------------------------------------------------------------- */
/* padding-top/bottom only, not the `padding` shorthand — 404.php's markup
   is the one place .not-found is combined with .ag-container on the same
   element (archive.php/search.php's empty states use .not-found alone,
   already inside a container). Same bug class as .archive-header and
   .article-layout elsewhere in this file: a 2-value shorthand's implicit
   "0" for left/right wins the cascade over .ag-container's own padding
   since this rule is declared later, zeroing that inset on mobile. */
.not-found { padding-top: var(--ag-space-9); padding-bottom: var(--ag-space-9); text-align: center; }
.not-found__code { font-family: var(--ag-font-serif); font-size: 72px; color: var(--ag-accent-600); }
.not-found__title { font-size: var(--ag-text-h2); margin-top: var(--ag-space-2); }
.not-found__desc { color: var(--ag-slate-500); margin-top: var(--ag-space-3); }
/* Aug 2026 a11y fix: same default-vs-hover contrast issue as
   .ag-search-form button above — see that comment. */
.not-found__link {
    display: inline-block; margin-top: var(--ag-space-5); background: var(--ag-accent-700); color: var(--ag-white);
    padding: 10px var(--ag-space-5); border-radius: var(--ag-radius-md); font-weight: 600; font-size: var(--ag-text-ui);
}
.not-found__link:hover { opacity: 0.85; }

/* ---------------------------------------------------------------------
   Static pages (About, Editorial Standards, Verification Policy,
   Contact, Advertise, Privacy Policy, Terms of Service) — Aug 2026.
   page.php reuses .archive-header for the hero (same proven, bug-fixed
   padding rule — see that comment above) and .entry-content for the
   body copy (same serif-prose treatment single.php uses for article
   bodies). These rules only add: list styling entry-content never
   needed before now (article bodies don't use <ul>/<ol>), link color
   (article bodies rarely link out), and the pillar/contact card grids
   used across About/Editorial Standards/Verification Policy/Contact/
   Advertise for their multi-column sections. */
.entry-content ul, .entry-content ol { margin: 0 0 1.3em; padding-left: 1.3em; }
.entry-content ul { list-style: disc; }
.entry-content ol { list-style: decimal; }
.entry-content li { margin-bottom: 0.55em; }
.entry-content li::marker { color: var(--ag-accent-600); }
.entry-content li p { margin-bottom: 0.3em; }
.entry-content strong { color: var(--ag-ink); font-weight: 700; }
.entry-content a { color: var(--ag-accent-700); text-decoration: underline; text-underline-offset: 2px; }
.entry-content a:hover { color: var(--ag-accent-600); }
.entry-content h2:first-child { margin-top: 0; }
/* Badge landing pages (user-reported bug, fixed here): page.php's static
   pages put their dek inside .archive-header, so .entry-content's real
   first child is always a <p>/<blockquote> and this zero never applies
   to them. page-verification-badge.php is different — "What This Badge
   Means" is the literal first element in .entry-content, so the rule
   above zeroed its top margin and left only the header's 8px bottom
   padding between the "N articles carry this badge" stat and this
   heading. Adjacent-sibling selector (badge-hero is immediately followed
   by page-content-wrap in the markup) out-specifies the rule above and
   restores real spacing, without touching any other page that reuses
   .entry-content h2:first-child. */
.badge-hero + .page-content-wrap .entry-content h2:first-child { margin-top: var(--ag-space-6); }

.page-content-wrap { padding-bottom: var(--ag-space-9); }
.page-content-wrap .entry-content { max-width: 100%; }

.pillar-grid {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--ag-gutter);
    margin: var(--ag-space-2) 0 var(--ag-space-7);
}
.pillar-grid--4 { grid-template-columns: repeat(4, 1fr); }
/* Card chrome shared across three previously-independent declarations
   (Aug 2026 design-system audit fix) — .pillar-card, .contact-card and
   .badge-glossary__card were byte-for-byte identical rule sets under
   three different names. Grouped into one declaration so there's a
   single place to change the shared "surface-container-low box with a
   hairline border" treatment; each class name is untouched everywhere
   else (templates, static-page HTML) so this is a zero-markup-change,
   zero-visual-change consolidation. */
.pillar-card, .contact-card, .badge-glossary__card {
    background: var(--ag-surface-container-low); border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-lg); padding: var(--ag-space-5);
}
.pillar-card__num { font-family: var(--ag-font-serif); font-size: 32px; line-height: 1; color: var(--ag-accent-600); }
.pillar-card__title {
    font-family: var(--ag-font-sans); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
    font-size: var(--ag-text-ui); color: var(--ag-ink); margin: var(--ag-space-3) 0 var(--ag-space-2);
}
.pillar-card__desc { color: var(--ag-slate-600); font-size: var(--ag-text-small); line-height: 1.65; margin: 0; }

.contact-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--ag-gutter); margin: var(--ag-space-2) 0 var(--ag-space-7); }
.contact-card__icon { color: var(--ag-accent-600); margin-bottom: var(--ag-space-3); display: inline-flex; }
.contact-card__title { font-family: var(--ag-font-sans); font-weight: 700; font-size: var(--ag-text-ui); color: var(--ag-ink); margin: 0 0 var(--ag-space-2); }
.contact-card__desc { color: var(--ag-slate-600); font-size: var(--ag-text-small); line-height: 1.6; margin: 0 0 var(--ag-space-3); }
.contact-card__email { font-family: var(--ag-font-mono); font-size: var(--ag-text-ui); color: var(--ag-accent-700); text-decoration: none; font-weight: 600; }
.contact-card__email:hover { color: var(--ag-accent-600); text-decoration: underline; }

/* Disclosure chip — a "not staff-verified" label (sponsored/company-
   submitted content). Deliberately neutral gray, never gold/accent
   colors: those read as a positive trust signal on .trust-badge and
   .ic-badge, and this chip means the opposite. Renamed from
   .trust-chip (Aug 2026 design-system audit fix) — the old name
   invited exactly that confusion. */
.disclosure-chip {
    display: inline-flex; align-items: center; gap: 6px; background: var(--ag-surface-container-high);
    border: 1px solid var(--ag-outline-variant); color: var(--ag-slate-600); font-family: var(--ag-font-sans);
    font-size: var(--ag-text-caption); font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px;
    padding: 4px 10px; border-radius: var(--ag-radius-md);
}

/* Badge glossary — the full 10-badge reference table on the
   Verification & Editorial Standards page (/corrections/). Each card
   reuses .trust-badge for the chip itself so the glossary always
   matches what actually renders in the live Trust Panel, then adds
   the "when we use it" criteria copy beneath. */
.badge-glossary { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--ag-space-4); margin: var(--ag-space-2) 0 var(--ag-space-7); }
.badge-glossary__card .trust-badge { margin-bottom: var(--ag-space-3); }
.badge-glossary__card p { color: var(--ag-slate-600); font-size: var(--ag-text-small); line-height: 1.65; margin: 0; }

/* Verification Center (Aug 2026) — badge landing page hero + the hub
   page's 9-card grid. badge-hero extends .archive-header (same proven
   padding-bug-fixed container rule) with an icon circle above the
   eyebrow and a live article-count stat below the dek.
   padding-top override (user-reported bug, fixed here): .archive-header's
   32px top padding was sized for a plain text eyebrow sitting right under
   the sticky nav — badge-hero adds a 56px icon circle above that eyebrow,
   so the same 32px read as the icon nearly touching the nav bar. Bumped
   to 64px here (badge-hero is declared after .archive-header, so equal
   specificity lets this win the cascade) so the icon gets real breathing
   room on both mobile and desktop. */
.badge-hero { display: flex; flex-direction: column; align-items: flex-start; padding-top: var(--ag-space-6); }
/* .badge-hero__icon and .badge-strip__icon (below, near .badge-strip)
   are the same "verification badge icon circle" component at two
   sizes — previously two verbatim copies of this color-mix formula.
   Consolidated here (Aug 2026 design-system audit fix); each keeps its
   own size/margin via its own selector. */
.badge-hero__icon, .badge-strip__icon {
    border-radius: var(--ag-radius-full); display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--ag-badge-color) 12%, var(--ag-surface-container-lowest));
    border: 1px solid color-mix(in srgb, var(--ag-badge-color) 45%, transparent); color: var(--ag-badge-color);
}
.badge-hero__icon { width: 56px; height: 56px; margin-bottom: var(--ag-space-3); }
.badge-hero__icon .material-symbols-outlined { font-size: 28px; }
.badge-hero__eyebrow-link { color: inherit; }
.badge-hero__eyebrow-link:hover { text-decoration: underline; }
.badge-hero__stat {
    display: inline-block; margin-top: var(--ag-space-3); font-family: var(--ag-font-mono); font-size: var(--ag-text-caption);
    color: var(--ag-slate-500); text-transform: uppercase; letter-spacing: 0.3px;
}

.verification-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--ag-space-4); margin: var(--ag-space-2) 0 var(--ag-space-7); }
.verification-grid__card {
    display: flex; flex-direction: column; align-items: flex-start; gap: var(--ag-space-3);
    background: var(--ag-surface-container-low); border: var(--ag-border-hairline); border-radius: var(--ag-radius-lg);
    padding: var(--ag-space-5); transition: border-color var(--ag-transition-fast), transform var(--ag-transition-fast);
}
.entry-content .verification-grid__card { text-decoration: none; }
.verification-grid__card:hover { border-color: var(--ag-accent-600); transform: translateY(-2px); }
.verification-grid__card p { color: var(--ag-slate-600); font-size: var(--ag-text-small); line-height: 1.6; margin: 0; }
.verification-grid__count { font-family: var(--ag-font-mono); font-size: var(--ag-text-caption); color: var(--ag-slate-500); text-transform: uppercase; letter-spacing: 0.3px; }

.badge-links { display: flex; flex-wrap: wrap; gap: var(--ag-space-5); margin: var(--ag-space-2) 0 var(--ag-space-6); }
.badge-links a { font-family: var(--ag-font-sans); font-weight: 700; font-size: var(--ag-text-small); text-transform: uppercase; letter-spacing: 0.3px; color: var(--ag-accent-700); }
.badge-links a:hover { text-decoration: underline; }

/* Homepage Verification Standards strip (Aug 2026) — a condensed,
   square-tile echo of the Verification Center's .verification-grid
   cards: same icon-chip + label + live article count idea, just
   smaller so 8 fit in one row under the header. No fixed aspect-ratio
   (dropped once the count line was added — a hard 1:1 square clipped
   three lines of content) but padding/sizing keep the tiles reading
   as compact squares. Shows 8 of the 9 verification badges — Evergreen
   Guide (last in registry order) is left out, since it describes a
   content type more than a verification method, and 8 keeps the grid
   even. See home.php. */
.badge-strip { display: grid; grid-template-columns: repeat(8, 1fr); gap: var(--ag-space-3); }
.badge-strip__item {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
    text-align: center;
    background: var(--ag-surface-container-low); border: var(--ag-border-hairline); border-radius: var(--ag-radius-lg);
    padding: var(--ag-space-4) var(--ag-space-2); transition: border-color var(--ag-transition-fast), transform var(--ag-transition-fast);
}
.badge-strip__item:hover { border-color: var(--ag-accent-600); transform: translateY(-2px); }
/* Shared icon-circle chrome (background/border/color/shape) now lives
   on the grouped .badge-hero__icon, .badge-strip__icon selector near
   .badge-hero above — this just sets this size's dimensions. */
.badge-strip__icon { width: 38px; height: 38px; }
.badge-strip__icon .material-symbols-outlined { font-size: 19px !important; line-height: 1; }
.badge-strip__label {
    font-family: var(--ag-font-sans); font-weight: 700; font-size: 11px; letter-spacing: 0.2px; text-transform: uppercase;
    color: var(--ag-slate-700); line-height: 1.25;
}
.badge-strip__count {
    font-family: var(--ag-font-mono); font-size: 10px; color: var(--ag-slate-500); text-transform: uppercase; letter-spacing: 0.2px;
}

@media (max-width: 900px) {
    .pillar-grid, .pillar-grid--4, .contact-grid, .badge-glossary, .verification-grid { grid-template-columns: 1fr; }
    .badge-strip { grid-template-columns: repeat(4, 1fr); }
}
@media (max-width: 560px) {
    .badge-strip { grid-template-columns: repeat(2, 1fr); }
}

/* ---------------------------------------------------------------------
   Footer — rebuilt Aug 2026: light "sitemap" footer (was dark navy),
   plus a decorative bottom repeat of the live ticker. See footer.php.
   --------------------------------------------------------------------- */
/* Verified: raw export's <footer> is bg-surface-container-lowest
   (#ffffff, pure white) — not the paper tone, which is used elsewhere. */
.site-footer { background: var(--ag-surface-container-lowest); color: var(--ag-on-surface-variant); margin-top: var(--ag-space-7); border-top: var(--ag-border-hairline); }
.site-footer .ag-container { padding-top: var(--ag-space-7); padding-bottom: var(--ag-space-6); }
.footer-grid { display: grid; grid-template-columns: 1.3fr repeat(3, 1fr); gap: var(--ag-space-6); }
.footer-brand__wordmark { font-family: var(--ag-font-serif); font-weight: 700; font-size: 22px; color: var(--ag-ink); text-transform: uppercase; }
.footer-brand p { color: var(--ag-on-surface-variant); font-size: var(--ag-text-small); margin-top: var(--ag-space-3); line-height: 1.6; max-width: 42ch; }
.footer-brand__badge { display: flex; align-items: center; gap: var(--ag-space-2); margin-top: var(--ag-space-4); font-family: var(--ag-font-sans); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ag-ink); }
.footer-brand__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ag-gold); flex-shrink: 0; }
.footer-col__title {
    font-family: var(--ag-font-sans); font-size: var(--ag-text-caption); font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--ag-ink); margin-bottom: var(--ag-space-4);
}
.footer-col ul { display: flex; flex-direction: column; gap: var(--ag-space-3); }
/* Verified: raw export's footer links are text-secondary (#775928
   brown) with hover:text-on-surface + underline — not gold. Gold is
   reserved for the small "Editorial Standards" verified icon only. */
.footer-col a { color: var(--ag-secondary); font-size: var(--ag-text-body-md); display: inline-flex; align-items: center; gap: 4px; transition: color var(--ag-transition-fast); }
.footer-col a:hover { text-decoration: underline; color: var(--ag-on-surface-variant); }
.footer-col--newsletter__copy { font-size: var(--ag-text-small); color: var(--ag-on-surface-variant); margin-bottom: var(--ag-space-3); max-width: 32ch; }
.footer-newsletter-form { display: flex; flex-direction: column; gap: var(--ag-space-2); }
.footer-newsletter-form input[type="email"] {
    border: var(--ag-border-strong); border-radius: var(--ag-radius-sm); background: var(--ag-surface-container-low);
    padding: 10px var(--ag-space-3); font-family: var(--ag-font-sans); font-size: var(--ag-text-small); color: var(--ag-ink);
}
.footer-newsletter-form input[type="email"]::placeholder { color: var(--ag-outline); }
.footer-newsletter-form button {
    background: var(--ag-ink); color: var(--ag-white); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
    font-size: var(--ag-text-label-caps); padding: 12px; border-radius: var(--ag-radius-sm); transition: background-color var(--ag-transition-fast);
}
.footer-newsletter-form button:hover { background: var(--ag-gold); }
.footer-bottom {
    border-top: var(--ag-border-hairline); margin-top: var(--ag-space-6); padding-top: var(--ag-space-5);
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--ag-space-3);
    font-size: var(--ag-text-caption); color: var(--ag-outline);
}
.footer-bottom__links { display: flex; gap: var(--ag-space-5); align-items: center; }
.footer-bottom__links a { color: var(--ag-outline); display: inline-flex; align-items: center; gap: 4px; }
.footer-bottom__links a:hover { color: var(--ag-ink); }

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
    .primary-navigation { display: none; }
    .menu-toggle { display: flex; }
    .header-subscribe-btn { display: none; }
    .homepage-grid { grid-template-columns: 1fr; }
    .homepage-sidebar { border-left: none; padding-left: 0; border-top: var(--ag-border-hairline); padding-top: var(--ag-space-6); }
    .latest-reports__grid, .listing-grid, .story-grid { grid-template-columns: repeat(2, 1fr); }
    .deep-dive-card { flex-direction: column; }
    .deep-dive-card__media { flex-basis: auto; height: 160px; }
    .footer-grid { grid-template-columns: 1fr 1fr; }
    .footer-col--newsletter { grid-column: 1 / -1; }
    .article-header__title { font-size: 26px; }
    .entry-content { font-size: 16px; }
    /* Sidebar drops below the article and stops being sticky —
       there's no room for a 320px rail once the two columns can no
       longer sit side by side comfortably. */
    .article-layout { grid-template-columns: 1fr; }
    .article-sidebar { position: static; }
    .article-header, .entry-content { max-width: none; }
}

@media (max-width: 600px) {
    /* Homepage card images were three different sizes on mobile —
       same aspect ratio everywhere (fixed earlier), but the hero image
       sits directly in the full-width column with no card chrome,
       while the "Latest Verified Reports" and "Deep Dives" cards wrap
       image+text in a padded/bordered card box (p-3 / p-4 + a 1px
       border), so their images were 26px / 34px narrower than the
       hero's — and, since width still drives height via the aspect
       ratio, visibly smaller too. Bleeding the image out to the card's
       own outer edge (negative margin equal to that padding+border,
       width increased by the same amount) makes every section's image
       the same width as the hero, so they now read as one consistent
       size across the whole homepage. Text below the image keeps its
       normal inset — only the photo bleeds. */
    .home-card-media--p3 { margin: -13px -13px 0 !important; width: calc(100% + 26px) !important; }
    .home-card-media--p4 { margin: -17px -17px 0 !important; width: calc(100% + 34px) !important; }

    .latest-reports__grid, .listing-grid, .story-grid { grid-template-columns: 1fr; }
    .footer-grid { grid-template-columns: 1fr; gap: var(--ag-space-5); }
    .hero-lead__media { height: 260px; }
    .hero-lead__headline { font-size: 26px; }
    /* .article-hero fixed height removed — Aug 2026, see .ic-hero__media */
    .article-header__title { font-size: 22px; }
    .price-ticker__label-sub, .price-ticker__fng { display: none; }
    .site-nav-row__inner { height: 64px; }
    .site-branding img, .site-branding svg { height: 34px; }
    .site-branding__wordmark { font-size: 19px; }

    /* Byline meta bar (avatar/name/date/read-time/share icons) doesn't
       fit on one line at phone widths. Row 1: avatar/name/date. Row 2:
       "X min read" + share icons together on ONE shared line, read-time
       left / icons right. A lone flex-basis:100% on .reading-time
       forces IT alone onto a full-width line, which then pushes
       .share-links to a third line of its own instead of sharing the
       second one — so the pair is grouped in single.php under
       .meta-secondary (display:contents above 600px, invisible to
       layout) and it's THAT wrapper, not .reading-time, that gets
       forced onto its own row here; internally it lays its two
       children out with justify-content: space-between. */
    .article-header__meta { row-gap: var(--ag-space-3); }
    .article-header__meta .meta-secondary {
        display: flex; align-items: center; justify-content: space-between; flex-basis: 100%;
        padding-top: var(--ag-space-3); border-top: var(--ag-border-hairline);
    }
    .article-header__meta .meta-secondary .share-links { margin-left: 0; }
}
/*
 * Literal, near-verbatim copy of the <style> block inside the real
 * Stitch export's code.html (uploaded Aug 2026 as
 * stitch_altcoin_gordon_editorial_identity.zip). These are the classes
 * Tailwind's CDN build doesn't generate on its own — animation
 * keyframes, the ticker marquee, and the soft "flat" 10%-opacity
 * border helpers — so they're kept as a small hand-written stylesheet
 * loaded after the Tailwind CDN script (see functions.php). Only two
 * additions beyond the original, both marked below: JS-hook classes for
 * the live price ticker's up/down coloring, and show/hide rules for the
 * search form + mobile nav drawer toggles (assets/nav.js).
 */
body {
    color: #0f172a;
}
.border-t-subtle { border-top: 1px solid rgba(26, 26, 26, 0.1); }
.border-b-subtle { border-bottom: 1px solid rgba(26, 26, 26, 0.1); }
.border-l-subtle { border-left: 1px solid rgba(26, 26, 26, 0.1); }
.border-r-subtle { border-right: 1px solid rgba(26, 26, 26, 0.1); }
.flat-border { border: 1px solid rgba(26, 26, 26, 0.1); }

/* Animation Keyframes */
@keyframes slideUpFade {
    from { opacity: 0; transform: translateY(30px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes pulseGlow {
    0% { box-shadow: 0 0 0 0 rgba(176, 141, 87, 0.4); }
    70% { box-shadow: 0 0 0 6px rgba(176, 141, 87, 0); }
    100% { box-shadow: 0 0 0 0 rgba(176, 141, 87, 0); }
}

.ticker-wrap { overflow: hidden; white-space: nowrap; box-sizing: border-box; }
.ticker-move { display: inline-block; animation: ticker 30s linear infinite; }
@keyframes ticker {
    0% { transform: translate3d(0, 0, 0); }
    100% { transform: translate3d(-50%, 0, 0); }
}

@media (prefers-reduced-motion: no-preference) {
    .animate-entrance { animation: slideUpFade 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards; opacity: 0; }
    .animate-entrance-delay-1 { animation: slideUpFade 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.2s forwards; opacity: 0; }
    .animate-entrance-delay-2 { animation: slideUpFade 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.4s forwards; opacity: 0; }
    .animate-entrance-delay-3 { animation: slideUpFade 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.6s forwards; opacity: 0; }
    .hover-lift { transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
    .hover-lift:hover { transform: translateY(-4px); box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1); }
    .interactive-badge:hover { animation: pulseGlow 1.5s infinite; }
    .btn-scale { transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease; }
    .btn-scale:active { transform: scale(0.97); }
}
@media (prefers-reduced-motion: reduce) {
    .animate-entrance, .animate-entrance-delay-1, .animate-entrance-delay-2, .animate-entrance-delay-3 { opacity: 1; }
    .hover-lift { transition: none; }
    .btn-scale { transition: background-color 0.2s ease, color 0.2s ease; }
}

/* --- Additions beyond the literal export (functional, not visual) --- */

/* Live ticker up/down coloring — assets/price-ticker.js adds is-up/
   is-down to the [data-ticker-coin] row itself (header ticker, footer
   marquee, AND the sidebar Market Pulse widget all use this same
   contract, and only the header row also carries the price-ticker__row
   class) so these rules key off the shared [data-ticker-coin] attribute
   selector, not a class name only one of the three markups actually
   has — that mismatch was why the sidebar widget's change% and the
   footer marquee never picked up the green/red coloring at all. */
/* Aug 2026 a11y pass: one colour pair cannot serve both ticker chromes.
   The same #058A5F sat on the black header bar, the #1a1a1a footer
   marquee AND the light Market Pulse card, and measured 3.98:1 on the
   marquee and 4.11:1 on the card -- failing 4.5:1 AA at 12px in BOTH
   directions, too dark for the dark chrome and too light for the light
   one. (#D93025 was worse on dark at 3.65:1.) So the value is now a
   custom property, set per chrome:

     dark  (header #000, marquee #1a1a1a)  up #0FA06E 5.20:1  down #EF5350 4.99:1
     light (Market Pulse / Market Snapshot) up #05774F 5.25:1  down #C62828 5.29:1

   Ratios are against the marquee's #1a1a1a and the card's #f9f9f7
   respectively -- the darker/lighter of each pair -- so the header bar
   and any lighter card surface clear these numbers comfortably.

   Dark is the default because the two light contexts are the ones with
   real class names to hook (.market-pulse-widget, .market-snapshot__card);
   the header and footer tickers carry only utility classes. */
[data-ticker-coin] { --ag-tk-up: #22c55e; --ag-tk-down: #f87171; }
.market-pulse-widget [data-ticker-coin],
.market-snapshot__card { --ag-tk-up: #15803d; --ag-tk-down: #b91c1c; }

[data-ticker-coin].is-up .price-ticker__change { color: var(--ag-tk-up); }
[data-ticker-coin].is-down .price-ticker__change { color: var(--ag-tk-down); }
[data-ticker-coin].is-up .price-ticker__trend-icon { color: var(--ag-tk-up); }
[data-ticker-coin].is-down .price-ticker__trend-icon { color: var(--ag-tk-down); }

/* Header search form + mobile nav drawer — hidden until toggled open by
   assets/nav.js (simple class-toggle, no framework). */
#header-search-form:not(.is-open),
#mobile-nav:not(.is-open) {
    display: none;
}

/* Newsletter input fields — GeneratePress's own compiled stylesheet
   (main.min.css, enqueued as the "generate-style" handle) is printed
   dead last in <head>, AFTER this file, and it styles
   input[type="email"] etc. with an attribute selector. An attribute
   selector (specificity 0,1,1) beats a plain Tailwind utility class
   like .bg-transparent (0,1,0) regardless of source order, so GP's
   default light input box was winning over the export's intended
   look on every email field site-wide — most visibly on "The Daily
   Verify" black card, where the field should stay transparent (so
   black shows through, white text) but was rendering as a plain
   white/light box instead. ID selectors (specificity 1,0,0) beat GP's
   rule outright, so these are keyed off each form's own field ID
   rather than a class. Colors match the literal export's design
   tokens for each field's surrounding component. */
#email {
    background-color: transparent;
    border-color: rgba(255, 255, 255, 0.3);
    color: #ffffff;
}
#email::placeholder {
    color: #cbd5e1;
}
#email:focus {
    border-color: #2563eb;
}
#email-subscribe {
    background-color: #f8fafc;
    border-color: #cbd5e1;
    color: #0f172a;
}
#email-subscribe::placeholder {
    color: #334155;
}
#email-subscribe:focus {
    border-color: #2563eb;
}
/* =====================================================================
   VERIFICATION LAYER COMPONENTS
   Source: docs/design/redesign-2026-08/design-system-spec.html v1.1 SS05
   Added:  6 Aug 2026, redesign-2026-08.

   CASCADE POSITION -- LOAD-BEARING
   --------------------------------
   This file is concatenated by tailwind-build/build.sh at position 4 of
   5, immediately BEFORE assets/tailwind-compiled.css. Tailwind must stay
   last: Preflight sets a { color: inherit } and is meant to win ties
   against style.css, which is what keeps homepage headlines from
   inheriting the link colour. Reordering that once turned every headline
   on the site gold. Nothing here needs to outrank Tailwind -- every rule
   below is class-scoped (0,1,0) and so already beats Preflight element
   selectors (0,0,1) on specificity regardless of print order.

   NO HARDCODED HEX (brief SS7)
   ----------------------------
   Every colour reads a token from design-tokens.css so a palette change
   stays a one-file change. The verification blue lives in --ag-verify-*
   rather than --ag-accent-*; see the long note in design-tokens.css for
   why aliasing onto the live gold accent was not an option.

   TWO DELIBERATE DIVERGENCES FROM THE SPEC PIXELS
   -----------------------------------------------
   1. Radii. The spec was authored against --ag-radius-md: 8px; the live
      token in this theme is 4px (and radius-lg is 4px, not 16px). Using
      the live tokens keeps verification surfaces consistent with every
      other card on the site, which is what "the palette does not grow"
      is protecting. The verification layer should not be the one place
      on the site with rounder corners.
   2. Mono. The spec sets IBM Plex Mono for trust chips and timestamps.
      The --ag-font-mono token in this theme resolves to Inter first, so
      those read proportional. Rather than re-point a shared token that
      the ticker also uses, each numeric run here carries
      font-variant-numeric: tabular-nums, which is the property actually
      doing the alignment work. Raised as a separate ticket, not fixed
      here.

   NO MOTION (spec SS06). No shimmer, no spinner, no skeleton pulse.
   Motion on a verification surface implies activity that is not
   happening. Loading states are static --ag-pip-off blocks, which keeps
   prefers-reduced-motion trivially satisfied.
   ===================================================================== */


/* ---------------------------------------------------------------------
   Shared: focus rings and tap targets (spec SS08).
   2px --ag-verify-accent at 2px offset on every interactive element
   this layer introduces. 44px minimum tap targets.
   --------------------------------------------------------------------- */
.ag-corrob a:focus-visible,
.ag-stance a:focus-visible,
.ag-pub a:focus-visible,
.ag-arow a:focus-visible,
.ag-dupe > summary:focus-visible,
.ag-feeds > summary:focus-visible {
    outline: 2px solid var(--ag-verify-accent);
    outline-offset: 2px;
    border-radius: var(--ag-radius-sm);
}


/* ---------------------------------------------------------------------
   .ag-status -- claim status chip. Five modifiers, spec SS04.
   The colour assignment is the load-bearing decision in this system:
   disputed is information, not error. --ag-warning-* has NO role here.
   Reaching for amber on a claim surface means the component is wrong.
   --------------------------------------------------------------------- */
.ag-status {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px 6px 11px;
    border: 1px solid;
    border-radius: var(--ag-radius-full);
    font-family: var(--ag-font-sans);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

/* The icon carries shape as well as colour, so status is never
   colour-alone even before the text label is counted (WCAG 1.4.1). */
.ag-status svg { width: 15px; height: 15px; flex: none; }

.ag-status--unproven {
    background: var(--ag-slate-100);
    color: var(--ag-slate-700);
    border-color: var(--ag-slate-300);
}

.ag-status--developing {
    background: var(--ag-white);
    color: var(--ag-navy-800);
    border-color: var(--ag-slate-400);
}

/* Accent blue, never amber. Settled decision #2. */
.ag-status--disputed {
    background: var(--ag-verify-tint-50);
    color: var(--ag-verify-accent-700);
    border-color: var(--ag-verify-border);
}

.ag-status--verified {
    background: var(--ag-success-tint-50);
    color: var(--ag-success-700);
    border-color: var(--ag-status-verified-border);
}

/* Red is reserved for this state alone -- actively disproven. */
.ag-status--false {
    background: var(--ag-error-tint-50);
    color: var(--ag-error-700);
    border-color: var(--ag-status-false-border);
}

/* The one-sentence gloss that sits beside the chip. */
.ag-status-gloss {
    font-size: 13.5px;
    color: var(--ag-slate-600);
    max-width: 52ch;
}


/* ---------------------------------------------------------------------
   .ag-corrob -- the corroboration meter. The hero component.
   Counts INDEPENDENT PUBLISHERS against MIN_CORROBORATING_SOURCES.
   Never renders a percentage: confidence sits between 0.26 and 0.30 on
   355 of 361 claims, so a percentage bar communicates nothing and reads
   as broken.
   --------------------------------------------------------------------- */
.ag-corrob {
    background: var(--ag-white);
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    padding: 16px 18px;
    max-width: 420px;
}

.ag-corrob__label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
    margin-bottom: 4px;
}

/* Serif, sized as a heading -- the count is the headline of this
   component, not a caption. Spec SS05.1. */
.ag-corrob__count {
    font-family: var(--ag-font-serif);
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.3;
    margin-bottom: 10px;
    font-variant-numeric: tabular-nums;
}

.ag-corrob__count small {
    font-family: var(--ag-font-sans);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--ag-slate-500);
    letter-spacing: 0;
}

.ag-corrob__pips { display: flex; gap: 5px; }

.ag-corrob__note {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--ag-slate-500);
}

.ag-corrob__note b { color: var(--ag-slate-700); font-weight: 600; }


/* ---------------------------------------------------------------------
   .ag-pip -- one corroboration slot.
   Pip count equals the threshold; publishers beyond it append extra
   pips. Filled-vs-unfilled must clear 3:1 (WCAG 1.4.11) because the
   pips carry information -- that ratio is required, not cosmetic.
   Verified against the live ramp: navy 13.52:1, disputed 4.01:1,
   verified 5.09:1, each against --ag-pip-off.
   Never the sole signal: every pip group ships with a visible text
   count and a matching aria-label on the group.
   --------------------------------------------------------------------- */
.ag-pip {
    height: 8px;
    flex: 1;
    min-width: 16px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-pip-off);
}

.ag-pip--on { background: var(--ag-pip-on); }
.ag-pip--on.ag-pip--disputed { background: var(--ag-pip-on-disputed); }
.ag-pip--on.ag-pip--verified { background: var(--ag-pip-on-verified); }


/* ---------------------------------------------------------------------
   .ag-stance -- the repeating unit: a stance label, then which
   publishers hold it. Four stances.
   Echo renders but is excluded from every count and from band
   placement. Syndication is not corroboration, and the row says so in
   words, not only in colour.
   --------------------------------------------------------------------- */
.ag-stance {
    border-top: 2px solid var(--ag-stance-supports);
    max-width: 560px;
}

.ag-stance--contradicts { border-top-color: var(--ag-stance-contradicts); }
.ag-stance--partial     { border-top-color: var(--ag-stance-partial); }
.ag-stance--echo        { border-top-color: var(--ag-stance-echo); }

.ag-stance__hd {
    display: flex;
    gap: 12px;
    align-items: baseline;
    flex-wrap: wrap;
    padding: 10px 0 12px;
}

.ag-stance__name {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.ag-stance--supports .ag-stance__name { color: var(--ag-navy-900); }

/* accent-700, not the 600 the rule uses: the rule is a non-text marker,
   the label is text and needs the darker shade to clear AA. */
.ag-stance--contradicts .ag-stance__name { color: var(--ag-verify-accent-700); }

/* slate-600, NOT the slate-400 the rule uses. Slate 400 fails AA as
   text at 2.45:1; slate-500 is the floor. Spec SS01 correction. */
.ag-stance--partial .ag-stance__name,
.ag-stance--echo .ag-stance__name { color: var(--ag-slate-600); }

.ag-stance__who { font-size: 13px; color: var(--ag-slate-600); }
.ag-stance__who b { color: var(--ag-navy-900); font-weight: 600; }


/* ---------------------------------------------------------------------
   .ag-pub -- publisher card. ONE CARD PER PUBLISHER, never per feed.
   Rows sharing a publisher root collapse into a single card with a
   details disclosure listing the feeds. A real details element, so it
   is keyboard-operable for free.
   --------------------------------------------------------------------- */
.ag-pub {
    background: var(--ag-white);
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    padding: 14px 16px;
    margin-bottom: 9px;
}

.ag-pub__top {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 9px;
}

.ag-pub__name { font-weight: 600; font-size: 14.5px; }
.ag-pub__name a { color: var(--ag-navy-900); }

.ag-pub__trust {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    color: var(--ag-slate-500);
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-sm);
    padding: 2px 6px;
}

.ag-pub__time {
    margin-left: auto;
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    color: var(--ag-slate-500);
}

.ag-pub__foot { margin-top: 12px; }

/* The counted-once disclosure. This is the component that stops the
   product overstating its own evidence. */
.ag-feeds > summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    cursor: pointer;
    list-style: none;
    font-size: 12.5px;
    color: var(--ag-slate-500);
}

.ag-feeds > summary::-webkit-details-marker { display: none; }
.ag-feeds > summary::before { content: "\25B8"; font-size: 10px; }
.ag-feeds[open] > summary::before { content: "\25BE"; }

.ag-feeds ul {
    margin: 8px 0 0;
    padding: 0 0 0 18px;
    font-family: var(--ag-font-mono);
    font-size: 12.5px;
    color: var(--ag-slate-500);
}

.ag-feeds__note {
    margin: 8px 0 0;
    font-size: 12.5px;
    color: var(--ag-slate-500);
}


/* ---------------------------------------------------------------------
   .ag-excerpt -- evidence quotation. A real blockquote.
   --------------------------------------------------------------------- */
.ag-excerpt {
    margin: 0;
    padding-left: 13px;
    border-left: 2px solid var(--ag-slate-200);
    font-family: var(--ag-font-serif);
    font-size: 15.5px;
    line-height: 1.6;
    color: var(--ag-slate-700);
}


/* ---------------------------------------------------------------------
   .ag-tl -- status timeline. A real ol, one li per history row.
   A TERMINAL PENDING NODE IS MANDATORY. Every claim in the database
   currently has exactly one history entry; without the pending node the
   timeline renders as a single orphaned dot and reads as a bug.
   --------------------------------------------------------------------- */
.ag-tl {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
    max-width: 560px;
}

.ag-tl::before {
    content: "";
    position: absolute;
    left: 6px;
    top: 9px;
    bottom: 22px;
    width: 1px;
    background: var(--ag-slate-200);
}

.ag-tl li { position: relative; padding: 0 0 20px 28px; }

.ag-tl__dot {
    position: absolute;
    left: 0;
    top: 4px;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--ag-white);
    border: 2px solid var(--ag-navy-900);
}

/* Dashed slate-400 marks the open/pending node. Slate 400 is allowed
   here: it is a non-text marker, not text. */
.ag-tl__dot--open {
    border-color: var(--ag-slate-400);
    border-style: dashed;
}

.ag-tl__dot--disputed { border-color: var(--ag-verify-accent); }
.ag-tl__dot--verified { border-color: var(--ag-success-700); }
.ag-tl__dot--false    { border-color: var(--ag-error-700); }

.ag-tl__when {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    color: var(--ag-slate-500);
}

.ag-tl__what { font-size: 14px; font-weight: 600; margin: 2px 0; }
.ag-tl__why  { font-size: 13px; color: var(--ag-slate-600); }

.ag-tl li.is-pending .ag-tl__what {
    color: var(--ag-slate-600);
    font-weight: 500;
}


/* ---------------------------------------------------------------------
   .ag-band -- archive band header. Two bands, always in this order:
   Corroborated (2+ independent publishers), then Single source.
   Bands make the flatness editorial rather than making the ranking look
   like it gave up, and they drain in the right direction as diversity
   improves. Sticky, so the band a row belongs to stays on screen.
   --------------------------------------------------------------------- */
.ag-band {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
    padding-bottom: 9px;
    border-bottom: 1px solid var(--ag-slate-300);
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--ag-slate-50);
}

.ag-band__name {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-navy-900);
}

.ag-band--pending .ag-band__name { color: var(--ag-slate-600); }
.ag-band__gloss { font-size: 12.5px; color: var(--ag-slate-600); }

.ag-band__n {
    margin-left: auto;
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    color: var(--ag-slate-500);
}


/* ---------------------------------------------------------------------
   .ag-arow -- archive row, two densities.
   THE CORROBORATION CELL KEEPS ITS WIDTH IN BOTH. It is the ordering
   key and must stay scannable at 70 rows; dense only drops the dek and
   tightens leading.
   --------------------------------------------------------------------- */
.ag-arow {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr) auto;
    gap: 18px;
    align-items: start;
    padding: 14px 0;
    border-bottom: var(--ag-border-hairline);
}

.ag-arow--dense {
    padding: 9px 0;
    gap: 14px;
    /* 84px, not a proportional shrink: the cell still holds three pips
       plus a short label at both densities. */
    grid-template-columns: 84px minmax(0, 1fr) auto;
}

.ag-arow__cor { padding-top: 3px; }

.ag-arow__pips { display: flex; gap: 3px; margin-bottom: 5px; }

.ag-arow__pips span {
    width: 14px;
    height: 6px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-pip-off);
}

.ag-arow__pips span.on { background: var(--ag-pip-on); }
.ag-arow__pips span.on.disputed { background: var(--ag-pip-on-disputed); }
.ag-arow__pips span.on.verified { background: var(--ag-pip-on-verified); }

/* slate-500, not the slate-400 the earlier mockups used. This is the
   not-scored label, one of the four places spec SS01 corrects. */
.ag-arow__n {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11px;
    color: var(--ag-slate-500);
    white-space: nowrap;
}

.ag-arow__hl {
    font-family: var(--ag-font-serif);
    font-size: 18px;
    line-height: 1.32;
    font-weight: 600;
    letter-spacing: -.01em;
    margin: 0 0 5px;
}

.ag-arow--dense .ag-arow__hl { font-size: 15.5px; margin: 0 0 3px; }

.ag-arow__meta { font-size: 12px; color: var(--ag-slate-500); }

.ag-arow__when {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    color: var(--ag-slate-500);
    white-space: nowrap;
    padding-top: 4px;
}


/* ---------------------------------------------------------------------
   .ag-dupe -- near-duplicate disclosure.
   Corroboration ranking PROMOTES duplicates, because a story that gets
   rewritten accumulates sources. Collapse first, rank second.
   --------------------------------------------------------------------- */
.ag-dupe > summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    cursor: pointer;
    list-style: none;
    font-size: 12px;
    color: var(--ag-verify-accent-700);
    background: var(--ag-verify-tint-50);
    border: 1px solid var(--ag-verify-border);
    border-radius: var(--ag-radius-full);
    padding: 4px 11px;
}

.ag-dupe > summary::-webkit-details-marker { display: none; }

.ag-dupe ol {
    margin: 9px 0 0;
    padding-left: 18px;
    font-size: 12.5px;
    color: var(--ag-slate-600);
}


/* ---------------------------------------------------------------------
   .ag-empty -- empty states (spec SS06).
   The failure mode to avoid is not ugliness. It is a page that looks
   like the pipeline is down when it is working exactly as designed.
   --------------------------------------------------------------------- */
.ag-empty {
    background: var(--ag-white);
    border: 1px dashed var(--ag-slate-300);
    border-radius: var(--ag-radius-md);
    padding: 20px;
    text-align: center;
    font-size: 13.5px;
    color: var(--ag-slate-600);
}

.ag-empty b {
    display: block;
    color: var(--ag-navy-900);
    font-size: 14.5px;
    margin-bottom: 4px;
}


/* ---------------------------------------------------------------------
   Loading states. Static blocks only -- no shimmer, no pulse, no
   spinner. Motion here would imply activity that is not happening.
   --------------------------------------------------------------------- */
.ag-skeleton {
    background: var(--ag-pip-off);
    border-radius: var(--ag-radius-sm);
}

.ag-pub--skeleton { min-height: 84px; background: var(--ag-white); }
.ag-pub--skeleton .ag-skeleton { height: 12px; margin-bottom: 8px; }


/* ---------------------------------------------------------------------
   MOBILE -- the one hard rule (spec SS07 rule 4, brief SS5.5).
   Corroboration is the ONLY verification element that never shrinks,
   never folds and never drops below the fold. Trust score, confidence,
   reasoning and entities may compress or fold away. Pips and the
   publisher count hold their desktop size at every breakpoint.
   --------------------------------------------------------------------- */
@media (max-width: 700px) {

    /* Archive rows put the corroboration cell INLINE ABOVE the
       headline, so pips lead the reading order rather than being pushed
       below the fold by a wrapped headline. */
    .ag-arow,
    .ag-arow--dense {
        grid-template-columns: 1fr;
        gap: 6px;
    }

    .ag-arow__cor {
        padding-top: 0;
        display: flex;
        align-items: center;
        gap: 10px;
    }

    .ag-arow__pips { margin-bottom: 0; }

    /* Explicitly NOT shrunk. Same 14x6 pip and same 11px label as
       desktop -- this is the rule, not an oversight. */
    .ag-arow__pips span { width: 14px; height: 6px; }
    .ag-arow__n { font-size: 11px; }

    /* The timestamp already appears in .ag-arow__meta on mobile. */
    .ag-arow__when { display: none; }

    /* Meter holds full size and goes full width. */
    .ag-corrob { max-width: none; }
    .ag-corrob__pips { gap: 5px; }
    .ag-pip { height: 8px; }

    /* These MAY compress -- and do. */
    .ag-pub__trust { font-size: 10.5px; }
    .ag-excerpt { font-size: 15px; }

    .ag-band { gap: 8px; }
    .ag-band__gloss { width: 100%; }
}


/* No transitions are introduced by this layer, but the guard stays so a
   later addition cannot quietly reintroduce motion here. */
@media (prefers-reduced-motion: reduce) {
    .ag-corrob,
    .ag-pip,
    .ag-status,
    .ag-tl__dot,
    .ag-dupe > summary,
    .ag-feeds > summary { transition: none !important; animation: none !important; }
}


/* ---------------------------------------------------------------------
   CLAIM PAGE LAYOUT -- /claim/<slug>/
   Source: claim-page-mockup.html, reconciled to the spec (which wins):
   BEM ag- names throughout, and the threshold parenthetical uses
   slate-500 rather than the slate-400 the mockup had, since that is one
   of the four contrast failures spec SS01 corrects by name.
   --------------------------------------------------------------------- */
.ag-claim {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 48px;
    align-items: start;
    padding: 0 0 64px;
}

.ag-claim__crumbs {
    font-size: 12px;
    color: var(--ag-slate-500);
    padding: 20px 0 0;
    letter-spacing: .02em;
}

.ag-claim__crumbs a { color: var(--ag-slate-600); }

.ag-claim__eyebrow {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
    margin: 20px 0 14px;
}

.ag-claim__eyebrow .dot {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--ag-slate-300);
}

/* The H1 IS the claim statement. Serif, 34px desktop / 25px mobile. */
.ag-claim__statement {
    font-family: var(--ag-font-serif);
    font-size: 34px;
    line-height: 1.22;
    letter-spacing: -.02em;
    font-weight: 700;
    margin: 0 0 18px;
}

.ag-claim__statusline {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.ag-claim__meter { margin: 26px 0 0; }

.ag-claim__section { margin-top: 44px; }

.ag-claim__h2 {
    font-family: var(--ag-font-serif);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.01em;
    margin: 0 0 6px;
}

.ag-claim__sub {
    font-size: 13.5px;
    color: var(--ag-slate-600);
    margin: 0 0 20px;
    max-width: 62ch;
}

/* Why this status. Accent-tinted only when the claim is disputed --
   disputed is information, so it gets emphasis, not alarm. */
.ag-reason {
    border-left: 3px solid var(--ag-slate-300);
    background: var(--ag-white);
    border-radius: 0 var(--ag-radius-md) var(--ag-radius-md) 0;
    padding: 16px 20px;
    margin-top: 26px;
}

.ag-reason--disputed {
    border-left-color: var(--ag-verify-accent);
    background: var(--ag-verify-tint-50);
}

.ag-reason__lbl {
    display: block;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
    margin-bottom: 6px;
}

.ag-reason--disputed .ag-reason__lbl { color: var(--ag-verify-accent-700); }

.ag-reason p {
    margin: 0;
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.6;
    color: var(--ag-slate-700);
}

.ag-reason--disputed p { color: var(--ag-navy-800); }

/* Sidebar */
.ag-side {
    position: sticky;
    top: 56px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.ag-card {
    background: var(--ag-white);
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    padding: 18px;
}

.ag-card h2,
.ag-card h3 {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
    margin: 0 0 14px;
}

.ag-kv {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px dashed var(--ag-slate-200);
    font-size: 13.5px;
}

.ag-kv:last-child { border-bottom: 0; }
.ag-kv dt { color: var(--ag-slate-600); }

.ag-kv dd {
    margin: 0;
    font-weight: 600;
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 13px;
}

.ag-ent { display: flex; flex-wrap: wrap; gap: 7px; }

.ag-ent span,
.ag-ent a {
    font-size: 12.5px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-full);
    padding: 4px 11px;
    color: var(--ag-slate-700);
    background: var(--ag-slate-50);
}

.ag-method { font-size: 13px; color: var(--ag-slate-600); line-height: 1.6; }

/* The threshold parenthetical. slate-500, NOT slate-400 -- this is
   named in spec SS01 as one of the four contrast failures to fix. */
.ag-claim__threshold-note { color: var(--ag-slate-500); }

@media (max-width: 980px) {
    .ag-claim { grid-template-columns: 1fr; gap: 32px; }
    .ag-side { position: static; }
}

@media (max-width: 640px) {
    .ag-claim__statement { font-size: 25px; }
}


/* ---------------------------------------------------------------------
   .ag-vstrip -- article verification strip.
   Sits BETWEEN the byline and the body: the first thing after who wrote
   this is what it claims and who else confirms it.
   Mockup called this .vstrip/.vclaim/.vpips; renamed to the ag- BEM
   convention that brief SS7 mandates.
   --------------------------------------------------------------------- */
.ag-vstrip {
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    background: var(--ag-white);
    padding: 14px 18px 16px;
    margin: 22px 0 28px;
}

.ag-vstrip__hd {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
    padding-bottom: 10px;
    border-bottom: var(--ag-border-hairline);
    margin-bottom: 12px;
}

.ag-vstrip__l {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-navy-900);
}

.ag-vstrip__count { font-size: 12.5px; color: var(--ag-slate-600); }

.ag-vstrip__n {
    margin-left: auto;
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    color: var(--ag-slate-500);
}

.ag-vclaim {
    display: grid;
    grid-template-columns: 58px minmax(0, 1fr) auto;
    gap: 14px;
    align-items: start;
    padding: 9px 0;
}

.ag-vclaim + .ag-vclaim { border-top: 1px dashed var(--ag-slate-200); }

.ag-vclaim__pips { display: flex; gap: 3px; padding-top: 5px; }

.ag-vclaim__pips span {
    width: 14px;
    height: 6px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-pip-off);
}

.ag-vclaim__pips span.on { background: var(--ag-pip-on); }
.ag-vclaim__pips span.on.disputed { background: var(--ag-pip-on-disputed); }
.ag-vclaim__pips span.on.verified { background: var(--ag-pip-on-verified); }

.ag-vclaim__st {
    margin: 0 0 3px;
    font-family: var(--ag-font-serif);
    font-size: 15.5px;
    line-height: 1.4;
}

.ag-vclaim__st a { color: var(--ag-navy-900); }
.ag-vclaim__meta { font-size: 12px; color: var(--ag-slate-500); }

.ag-vstrip__ft {
    margin-top: 12px;
    padding-top: 10px;
    border-top: var(--ag-border-hairline);
    font-size: 12px;
    color: var(--ag-slate-500);
}

/* Tracked paragraphs get a margin rule, not an inline highlight -- it
   must not interrupt reading. Accent when that claim is disputed. */
.ag-article-body .tracked { position: relative; }

.ag-article-body .tracked::before {
    content: "";
    position: absolute;
    left: -18px;
    top: .35em;
    bottom: .35em;
    width: 2px;
    background: var(--ag-slate-300);
}

.ag-article-body .tracked--disputed::before { background: var(--ag-verify-accent); }

@media (max-width: 700px) {
    /* Corroboration never shrinks. The badge folds instead. */
    .ag-vclaim { grid-template-columns: 58px minmax(0, 1fr); }
    .ag-vclaim .ag-status { grid-column: 1 / -1; justify-self: start; }
    .ag-article-body .tracked::before { left: -10px; }
}

/* ── Editorial provenance card ──────────────────────────────────────
   Who compiled this story, who owns it, and whether a human has
   checked it yet. Sits between the byline and the verification strip:
   who produced it, then what it claims.

   Built as a card rather than a sentence because it is reference
   information, not prose -- a reader scanning for "has anyone actually
   looked at this" should find it in one glance, and the same layout
   has to read correctly whether the answer is yes or no. */

/* Accent tokens, not literals. NOTE for whoever edits this next:
   --ag-gold is a legacy NAME holding the site's blue (#2563eb) --
   the palette moved to blue and the token did not get renamed. Use
   --ag-accent-600 so this card follows the brand if it ever changes
   again. (The generated article images are still drawn in the old
   gold; that mismatch is real and worth resolving separately.) */
.ag-prov {
    border: var(--ag-border-hairline);
    border-left: 3px solid var(--ag-accent-600, #2563eb);
    border-radius: var(--ag-radius-md);
    background: var(--ag-slate-50, #f8fafc);
    padding: 16px 18px;
    margin: 20px 0 4px;
}

.ag-prov__head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.ag-prov__av {
    flex: none;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--ag-accent-600, #2563eb);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ag-prov__who {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1 1 auto;
}

.ag-prov__name {
    font-weight: 650;
    font-size: 15px;
    color: var(--ag-ink, #1a1a1a);
    text-decoration: none;
}

.ag-prov__name:hover { text-decoration: underline; }

.ag-prov__role {
    font-size: 12.5px;
    color: var(--ag-slate-600, #52514e);
}

/* Status pill. Colour alone never carries the state -- the word is the
   label, the dot is reinforcement, per the site's a11y convention. */
.ag-prov__state {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    padding: 5px 11px;
    border-radius: var(--ag-radius-full, 20px);
    white-space: nowrap;
}

.ag-prov__state::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
}

.ag-prov__state--done {
    background: rgba(12, 163, 12, .10);
    color: #0a7a0a;
}
.ag-prov__state--done::before { background: #0ca30c; }

/* Amber, deliberately NOT the brand accent. "Awaiting review" is a
   state, and a state that borrowed the accent colour would read as
   decoration rather than as information. */
.ag-prov__state--pending {
    background: rgba(180, 83, 9, .10);
    color: #b45309;
}
.ag-prov__state--pending::before { background: #d97706; }

.ag-prov__kv {
    margin: 14px 0 0;
    padding: 12px 0 0;
    border-top: 1px dashed var(--ag-slate-200, #e1e0d9);
    display: grid;
    gap: 0;
}

.ag-prov__kv > div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    padding: 6px 0;
    font-size: 13px;
}

/* Explicit 400: a bare <dt> inherits the browser's bold, which had the
   label rendering heavier (700) than the value beside it (600) --
   backwards, and out of step with the sidebar cards where the label is
   the quiet half of the pair. */
.ag-prov__kv dt {
    color: var(--ag-slate-600, #475569);
    font-weight: 400;
    flex: none;
}

.ag-prov__kv dd {
    margin: 0;
    text-align: right;
    color: var(--ag-ink, #1a1a1a);
    font-weight: 600;
}

.ag-prov__cov {
    font-weight: 500 !important;
    color: var(--ag-slate-600, #52514e) !important;
}

.ag-prov__more {
    display: inline-block;
    margin-top: 12px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ag-accent-700, #1d4ed8);
    text-decoration: none;
}

.ag-prov__more:hover { text-decoration: underline; }

/* ── Mobile ────────────────────────────────────────────────────────
   The desktop layout put the status pill on the same row as the name
   and let it wrap, which on a narrow screen dropped it under the
   avatar at a ragged indent. Below 560px the card becomes two clean
   blocks instead: identity, then a full-width status row, then the
   key/values as stacked label-over-value pairs. Nothing wraps
   awkwardly because nothing shares a row that cannot fit one. */
@media (max-width: 560px) {
    .ag-prov {
        padding: 14px 14px 16px;
        margin: 18px 0 4px;
    }

    .ag-prov__head {
        gap: 10px;
        row-gap: 12px;
    }

    .ag-prov__av {
        width: 34px;
        height: 34px;
        font-size: 12px;
    }

    .ag-prov__name { font-size: 14.5px; }
    .ag-prov__role { font-size: 12px; }

    /* Own row, full width, left-aligned with the text column rather
       than floating under the avatar. */
    .ag-prov__state {
        order: 3;
        width: 100%;
        margin: 0;
        justify-content: center;
        padding: 7px 12px;
    }

    .ag-prov__kv {
        margin-top: 12px;
        padding-top: 10px;
    }

    .ag-prov__kv > div {
        flex-direction: column;
        align-items: flex-start;
        gap: 1px;
        padding: 7px 0;
        border-bottom: 1px dashed var(--ag-slate-200, #e2e8f0);
    }

    .ag-prov__kv > div:last-child { border-bottom: 0; padding-bottom: 0; }

    .ag-prov__kv dt {
        font-size: 11px;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--ag-slate-500, #64748b);
    }

    .ag-prov__kv dd {
        text-align: left;
        font-size: 13.5px;
        line-height: 1.45;
    }

    .ag-prov__more {
        margin-top: 14px;
        font-size: 13px;
    }
}

/* Source list in the article rail. Was inheriting the article body's
   15px, which sat a size larger than everything else in that column --
   the sidebar cards run at 13-13.5px. */
.ag-srcs {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ag-srcs li {
    padding: 6px 0;
    border-bottom: 1px dashed var(--ag-slate-200, #e2e8f0);
}

.ag-srcs li:last-child { border-bottom: 0; padding-bottom: 0; }

.ag-srcs a {
    font-family: var(--ag-font-sans);
    font-size: 13.5px;
    font-weight: 500;
    color: var(--ag-ink, #0f172a);
    text-decoration: none;
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
}

.ag-srcs a::after {
    content: "\2197";           /* outbound, so a reader knows it leaves the site */
    font-size: 11px;
    color: var(--ag-slate-500, #64748b);
}

.ag-srcs a:hover {
    color: var(--ag-accent-700, #1d4ed8);
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ── Topic hub brief ───────────────────────────────────────────────
   Sits above the story list on a topic archive. The archive itself is
   a newspaper-style run of hairline rows, so this is set as section
   front matter rather than a boxed widget: a rule, a label, a serif
   standfirst, then body. Boxing it would have made the page's most
   durable content look like an advertisement inside its own list.

   Type follows the site: Source Serif 4 at 700 for headings (they were
   rendering at 400 and read as unfinished), Inter for body. */

/* Full block width, so the rules line up with the story rows and the
   corroborated bands below rather than stopping two-thirds across.
   At 1160px a single column of 16px text is a ~140-character measure,
   which is unreadable -- so the body sets in two columns and the
   standfirst spans them, which is what a broadsheet does with exactly
   this problem. Columns only above 1000px; below that the measure is
   comfortable on its own. */
.ag-hub {
    position: relative;
    margin: 10px 0 6px;
    padding-top: 22px;
    border-top: 2px solid var(--ag-ink, #0f172a);
}

@media (min-width: 1000px) {
    .ag-hub {
        columns: 2;
        column-gap: 52px;
    }

    /* The lead and the navigation belong to the whole brief, not to a
       column. */
    .ag-hub__label,
    .ag-hub > p:first-of-type,
    .ag-hub__rel {
        column-span: all;
    }

    /* Nothing should straddle a column break -- a heading stranded at
       the foot of column one is the classic way this layout fails. */
    .ag-hub h2,
    .ag-hub h3,
    .ag-hub li {
        break-inside: avoid;
    }

    .ag-hub h2 { break-after: avoid; }

    /* First heading in a column should not inherit the big top margin
       that separates sections mid-flow. */
    .ag-hub h2:first-of-type { margin-top: 0; }
}

.ag-hub__label {
    display: block;
    margin-bottom: 14px;
    font-family: var(--ag-font-sans);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-slate-500, #64748b);
}

/* Standfirst: serif, to answer the serif H1 above it, and a size step
   up from body so the topic definition reads first. */
.ag-hub > p:first-of-type {
    font-family: var(--ag-font-serif);
    font-size: 20.5px;
    line-height: 1.5;
    color: var(--ag-ink, #0f172a);
    /* Full block width, matching the rules and the story rows. It had a
       78ch cap for measure, which left the lead visibly short of the
       block edge and made the whole brief read as narrower than it is.
       A standfirst is three or four lines, not a page of body copy, so
       the long measure costs little and the alignment is worth more. */
    max-width: none;
    margin: 0 0 24px;
}

.ag-hub p {
    font-size: 16px;
    line-height: 1.7;
    color: var(--ag-slate-700, #334155);
    margin: 0 0 14px;
}

.ag-hub h2 {
    font-family: var(--ag-font-serif);
    font-size: 21px;
    font-weight: 700;
    line-height: 1.28;
    letter-spacing: -.012em;
    color: var(--ag-ink, #0f172a);
    margin: 30px 0 12px;
}

.ag-hub h3 {
    font-family: var(--ag-font-sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-slate-500, #64748b);
    margin: 22px 0 8px;
}

/* Marker in the accent, hung outside the measure so the text edge
   stays flush with the paragraphs above it. */
.ag-hub ul {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
}

.ag-hub li {
    position: relative;
    padding-left: 20px;
    margin-bottom: 10px;
    font-size: 15.5px;
    line-height: 1.62;
    color: var(--ag-slate-700, #334155);
}

.ag-hub li::before {
    content: "";
    position: absolute;
    left: 2px;
    top: .62em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ag-accent-600, #2563eb);
}

.ag-hub li strong,
.ag-hub p strong {
    color: var(--ag-ink, #0f172a);
    font-weight: 650;
}

.ag-hub a {
    color: var(--ag-ink, #0f172a);
    text-decoration: underline;
    text-decoration-color: var(--ag-accent-600, #2563eb);
    text-decoration-thickness: 1.5px;
    text-underline-offset: 2.5px;
}

.ag-hub a:hover { color: var(--ag-accent-700, #1d4ed8); }

/* Related hubs. Labelled, so the chips read as navigation rather than
   as tags on the page itself, and bounded by rules top and bottom so
   the brief closes cleanly before the story list starts. */
.ag-hub__rel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 26px 0 0;
    padding: 16px 0 22px;
    border-top: var(--ag-border-hairline);
    border-bottom: 2px solid var(--ag-ink, #0f172a);
}

.ag-hub__rel::before {
    content: "Related";
    font-family: var(--ag-font-sans);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-slate-500, #64748b);
    margin-right: 4px;
}

.ag-hub__rel a {
    font-family: var(--ag-font-sans);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-full, 999px);
    padding: 6px 14px;
    color: var(--ag-slate-700, #334155);
    background: #fff;
    transition: border-color .12s ease, color .12s ease;
}

.ag-hub__rel a:hover {
    border-color: var(--ag-accent-600, #2563eb);
    color: var(--ag-accent-700, #1d4ed8);
}

@media (max-width: 560px) {
    .ag-hub { padding-top: 18px; }
    .ag-hub > p:first-of-type { font-size: 18px; }
    .ag-hub p { font-size: 15.5px; }
    .ag-hub h2 { font-size: 19px; margin-top: 24px; }
    .ag-hub li { font-size: 15px; }
    .ag-hub__rel { gap: 7px; padding-bottom: 18px; }
    .ag-hub__rel a { font-size: 12.5px; padding: 5px 12px; }
}

/* ── Contextual internal links ─────────────────────────────────────
   Links added to body copy by ag-internal-links.php, pointing at the
   topic hubs. Styled deliberately quieter than an outbound citation:
   these are navigation the reader did not ask for, so they should be
   findable without interrupting the sentence. Ink text with an accent
   underline, rather than a coloured word in the middle of a
   paragraph. */

.ag-ilink {
    color: var(--ag-ink, #0f172a);
    text-decoration: underline;
    text-decoration-color: var(--ag-accent-600, #2563eb);
    text-decoration-thickness: 1.5px;
    text-underline-offset: 2.5px;
    transition: color .12s ease;
}

.ag-ilink:hover {
    color: var(--ag-accent-700, #1d4ed8);
    text-decoration-thickness: 2px;
}


/* ---------------------------------------------------------------------
   .ag-update -- appended when new publishers add reporting.

   Lives inside post content, written by app/tasks/article_update.py, so
   it has to look deliberate next to body prose without depending on
   anything around it. Left rule and slate fill are the same devices the
   market-impact block and the verification strip already use, so an
   update reads as part of the page rather than an insertion into it.

   Not styled as an alert. An update is the product working -- a story
   gaining corroboration is the thing this site exists to show -- so it
   should read as editorial, not as an erratum.
   --------------------------------------------------------------------- */
.ag-update {
    margin: 30px 0;
    padding: 18px 22px;
    background: var(--ag-slate-50);
    border: var(--ag-border-hairline);
    border-left: 3px solid var(--ag-accent-600);
    border-radius: 0 var(--ag-radius-md) var(--ag-radius-md) 0;
}

.ag-update__meta {
    margin: 0 0 8px;
    font-family: var(--ag-font-sans);
    font-size: 12.5px;
    color: var(--ag-slate-600);
}

.ag-update__meta strong {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-accent-700);
    margin-right: 6px;
}

.ag-update__meta time {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
}

.ag-update p:last-child {
    margin: 0;
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.65;
    color: var(--ag-navy-800);
}

/* More than one update stacks; collapse the gap so a long-running story
   reads as a sequence rather than a pile of separate boxes. */
.ag-update + .ag-update { margin-top: -12px; }

/* ---------------------------------------------------------------------
   .ag-coverage — the corroboration trail at the foot of an article.
                                                            (2026-08-07)

   Sibling to .ag-update, and deliberately quieter than it. An update is
   news -- something changed since you last looked -- so it carries an
   accent rule. This is the standing evidence for the count in the strip
   at the top of the page: it should read as part of the record, not as
   an announcement. Slate field, hairline border, no accent.

   Numbered list because the order is the same order the strip names the
   publishers in, and a reader comparing the two should not have to work
   at it.
   --------------------------------------------------------------------- */
.ag-coverage {
    margin: 44px 0 8px;
    padding: 22px 24px 20px;
    background: var(--ag-slate-50);
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
}

.ag-coverage__h {
    margin: 0 0 6px;
    font-family: var(--ag-font-sans);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}

.ag-coverage__lede {
    margin: 0 0 16px;
    font-family: var(--ag-font-sans);
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--ag-slate-600);
}

.ag-coverage__list {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: agcov;
}

.ag-coverage__item {
    counter-increment: agcov;
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr);
    gap: 4px 12px;
    padding: 13px 0;
    border-top: var(--ag-border-hairline);
}

.ag-coverage__item::before {
    content: counter(agcov, decimal-leading-zero);
    grid-row: 1 / span 2;
    font-family: var(--ag-font-mono);
    font-size: 11.5px;
    line-height: 1.7;
    color: var(--ag-slate-400);
}

.ag-coverage__pub {
    font-family: var(--ag-font-sans);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}

.ag-coverage__link {
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.45;
    color: var(--ag-navy-900);
    text-decoration: none;
    border-bottom: 1px solid var(--ag-slate-300);
    /* Sits on the grid's second row, beside the counter, not under it. */
    justify-self: start;
}

.ag-coverage__link:hover,
.ag-coverage__link:focus {
    color: var(--ag-accent-700);
    border-bottom-color: var(--ag-accent-600);
}

.ag-coverage__ft {
    margin: 16px 0 0;
    padding-top: 14px;
    border-top: var(--ag-border-hairline);
    font-family: var(--ag-font-sans);
    font-size: 12px;
    line-height: 1.6;
    color: var(--ag-slate-500);
}

@media (max-width: 600px) {
    .ag-coverage { padding: 18px 16px 16px; margin-top: 34px; }
    .ag-coverage__item { grid-template-columns: 22px minmax(0, 1fr); gap: 3px 9px; }
    .ag-coverage__link { font-size: 15px; }
}

/* ---------------------------------------------------------------------
   .ag-coverage__when — the timeline half of the coverage block.

   Each row carries the outlet's own publication time as a gap against
   ours. Two states, and they are styled differently on purpose:

     --after   an outlet that followed us. Accent, tabular figures. This
               is the claim worth making and it should be legible at a
               glance down the column.
     --before  an outlet that had it first. These are the sources the
               article was written from. Muted, but PRESENT — dropping
               them would turn a verifiable record into a marketing claim
               on the one page whose job is that the reader need not take
               our word for anything.
   --------------------------------------------------------------------- */
.ag-coverage__when {
    grid-column: 2;
    margin-top: 5px;
    font-family: var(--ag-font-mono);
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
    letter-spacing: .01em;
}

.ag-coverage__when--after {
    color: var(--ag-accent-700);
}

.ag-coverage__when--after::before {
    content: "\2193\00a0";  /* downward arrow: they came after us */
    opacity: .75;
}

.ag-coverage__when--before {
    color: var(--ag-slate-400);
}

.ag-coverage__when--before::before {
    content: "\2191\00a0";  /* upward arrow: they were there first */
    opacity: .75;
}

@media (max-width: 600px) {
    .ag-coverage__when { font-size: 11px; }
}

/* ---------------------------------------------------------------------
   Official and Price badges.                                (2026-08-07)

   These are not points on the corroboration scale -- they say the scale
   does not apply -- so they must not be mistaken at a glance for the
   states that ARE on it. Unproven, Developing and Verified run slate ->
   white -> green; these two sit outside that ramp entirely.

   Official borrows the accent used for primary sources elsewhere on the
   site. It reads as authoritative, which is the claim: the issuing body
   published this itself. It is deliberately NOT green -- green is
   "independently confirmed", and confirmation is precisely what an
   official filing does not need and has not had.

   Price is neutral by design. Analysis is not a truth claim, so its
   badge should carry no verdict colour at all; anything warmer would
   read as endorsement of somebody's price target.
   --------------------------------------------------------------------- */
.ag-status--official {
    background: var(--ag-accent-tint-50);
    color: var(--ag-accent-700);
    border-color: #bfdbfe;
}

.ag-status--price {
    background: var(--ag-slate-50);
    color: var(--ag-slate-600);
    border-color: var(--ag-slate-300);
}

/* The sourcing strip on an exempt article: same furniture as the
   verification strip, without the meter it has no data for. */
.ag-vstrip--exempt .ag-vstrip__n {
    font-family: var(--ag-font-sans);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-accent-700);
}

.ag-vstrip--exempt .ag-vstrip__ft {
    border-top: 0;
}

/* Newsroom funnel card. The refusal list is deliberately quieter than the
   figures above it: it is context for the headline numbers, not a second
   set of headline numbers competing with them.

   The sub-heading uses PADDING above, not margin. Margin collapses against
   the list that ends immediately before it, so a margin-top here silently
   did nothing and the label sat against that list's closing divider --
   reading as a caption on the last row rather than the title of the list
   below it. Padding cannot collapse. The tight space beneath is the other
   half of the same point: a heading must sit nearer what it introduces
   than what it follows. */
.ag-kv__note{margin:0 0 .6rem;font-size:.78rem;line-height:1.45;opacity:.72}
.ag-kv__sub{margin:0 0 .15rem;padding-top:1.6rem;font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;opacity:.6;font-weight:600}
.ag-kv__sub + .ag-kv{margin-top:0}
.ag-kv--muted{opacity:.78}
.ag-kv--muted dd{font-variant-numeric:tabular-nums}
.ag-kv__foot{margin:.8rem 0 0;padding-top:.6rem;border-top:1px solid rgba(128,128,128,.22);font-size:.75rem;line-height:1.5;opacity:.68}

/* The "New" badge: a pending state, so it must not read as a verdict.
   Slate like Unproven rather than green like Verified -- nothing has been
   confirmed -- but with the accent border to mark it as live and moving,
   where Unproven is where a story has come to rest. */
.ag-status--new {
    background: var(--ag-slate-100);
    color: var(--ag-slate-700);
    border-color: var(--ag-blue-300, #93c5fd);
}

/* Off-scale rows: a rule where the meter would be, not a zero.
   Sized to the pip row so the first grid column keeps its width and the
   archive keeps its vertical rhythm. */
.ag-arow__na{display:block;width:26px;height:2px;border-radius:1px;
  background:var(--ag-hairline,#e2e8f0);margin:7px 0}

/* Off-scale article row: rule in place of the meter. */
.ag-vclaim__pips--na{display:flex;align-items:center}
/* ============================================================
   homepage-extra.css — RECOVERED SOURCE

   These rules previously existed ONLY inside assets/bundle.css,
   which is a BUILD ARTIFACT regenerated by tailwind-build/build.sh.
   Running the build wiped them. Recovered here 6 Aug 2026 from
   backups/theme-snapshot-1618 so they survive every future build.

   Contents: the .aghome__* / .ag-rail__* homepage layer, plus the
   Tailwind utilities the purge pass does not currently emit.
   All colours use var(--ag-*) tokens, so the palette applies.
   ============================================================ */

.absolute{position:absolute}
.inset-0{inset:0}
.left-0{left:0}
.top-0{top:0}
.top-full{top:100%}
.-z-10{z-index:-10}
.z-50{z-index:50}
.mb-3{margin-bottom:.75rem}
.mb-6{margin-bottom:1.5rem}
.ml-auto{margin-left:auto}
.mr-4{margin-right:1rem}
.mt-3{margin-top:.75rem}
.mt-4{margin-top:1rem}
.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}
.h-10{height:2.5rem}
.h-20{height:5rem}
.h-8{height:2rem}
.h-9{height:2.25rem}
.h-full{height:100%}
.w-8{width:2rem}
.min-w-\[240px\]{min-width:240px}
.max-w-2xl{max-width:42rem}
.max-w-3xl{max-width:48rem}
.flex-shrink-0,.shrink-0{flex-shrink:0}
.flex-grow{flex-grow:1}
.items-start{align-items:flex-start}
.items-end{align-items:flex-end}
.gap-1{gap:.25rem}
.gap-12{gap:3rem}
.gap-gutter{gap:24px}
.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)))}
.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))}
.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*var(--tw-space-x-reverse));margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)))}
.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1.5rem*var(--tw-space-x-reverse));margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)))}
.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem*var(--tw-space-x-reverse));margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)))}
.space-x-gutter>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(24px*var(--tw-space-x-reverse));margin-left:calc(24px*(1 - var(--tw-space-x-reverse)))}
.overflow-x-auto{overflow-x:auto}
.truncate,.whitespace-nowrap{white-space:nowrap}
.rounded{border-radius:.125rem}
.rounded-sm{border-radius:.125rem}
.border-b-2{border-bottom-width:2px}
.border-outline-variant\/50{border-color:hsla(180,3%,77%,.5)}
.border-primary{--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity,1))}
.bg-on-primary{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}
.bg-paper{--tw-bg-opacity:1;background-color:rgb(249 249 247/var(--tw-bg-opacity,1))}
.bg-paper\/90{background-color:hsla(60,14%,97%,.9)}
.bg-surface-container-highest\/80{background-color:hsla(90,3%,89%,.8)}
.bg-surface\/80{background-color:hsla(60,14%,97%,.8)}
.bg-transparent{background-color:transparent}
.p-2{padding:.5rem}
.p-4{padding:1rem}
.p-6{padding:1.5rem}
.px-2{padding-left:.5rem;padding-right:.5rem}
.px-6{padding-left:1.5rem;padding-right:1.5rem}
.px-margin-desktop{padding-left:64px;padding-right:64px}
.px-margin-mobile{padding-left:16px;padding-right:16px}
.py-1{padding-top:.25rem;padding-bottom:.25rem}
.py-3{padding-top:.75rem;padding-bottom:.75rem}
.py-4{padding-top:1rem;padding-bottom:1rem}
.py-8{padding-top:2rem;padding-bottom:2rem}
.pb-1{padding-bottom:.25rem}
.pb-2{padding-bottom:.5rem}
.pb-\[6px\]{padding-bottom:6px}
.pl-4{padding-left:1rem}
.text-right{text-align:right}
.font-body-lg,.font-body-md,.font-data-mono{font-family:Inter}
.font-display-lg,.font-headline-lg-mobile,.font-headline-md{font-family:"Source Serif 4"}
.text-body-lg{font-size:18px;line-height:30px;font-weight:400}
.text-headline-lg-mobile{font-size:32px;line-height:40px;font-weight:700}
.text-headline-md{font-size:28px;line-height:36px;font-weight:600}
.text-size-10{font-size:10px}
.text-size-11{font-size:11px}
.text-size-12{font-size:12px}
.text-size-15{font-size:15px}
.text-size-22{font-size:22px}
.text-xs{font-size:.75rem;line-height:1rem}
.font-medium{font-weight:500}
.leading-tight{line-height:1.25}
.text-data-gray{--tw-text-opacity:1;color:rgb(102 102 102/var(--tw-text-opacity,1))}
.text-outline{--tw-text-opacity:1;color:rgb(116 120 120/var(--tw-text-opacity,1))}
.text-primary{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}
.text-slate-450{--tw-text-opacity:1;color:rgb(132 136 136/var(--tw-text-opacity,1))}
.text-trust-navy{--tw-text-opacity:1;color:rgb(0 43 73/var(--tw-text-opacity,1))}
.underline{text-decoration-line:underline}
.placeholder-outline-variant::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(196 199 199/var(--tw-placeholder-opacity,1))}
.placeholder-outline-variant::placeholder{--tw-placeholder-opacity:1;color:rgb(196 199 199/var(--tw-placeholder-opacity,1))}
.opacity-0{opacity:0}
.opacity-80{opacity:.8}
.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}
.backdrop-blur-md{--tw-backdrop-blur:blur(12px)}
.backdrop-blur-md,.backdrop-blur-sm{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}
.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}
.duration-150,.transition-opacity{transition-duration:.15s}
.duration-200{transition-duration:.2s}
.hover\:border-accent-gold\/30:hover{border-color:rgba(176,141,87,.3)}
.hover\:bg-accent-gold:hover{--tw-bg-opacity:1;background-color:rgb(176 141 87/var(--tw-bg-opacity,1))}
.hover\:bg-ink:hover{--tw-bg-opacity:1;background-color:rgb(26 26 26/var(--tw-bg-opacity,1))}
.hover\:bg-primary-container:hover{--tw-bg-opacity:1;background-color:rgb(28 27 27/var(--tw-bg-opacity,1))}
.hover\:bg-surface-container-low:hover{--tw-bg-opacity:1;background-color:rgb(244 244 242/var(--tw-bg-opacity,1))}
.hover\:text-accent-gold:hover{--tw-text-opacity:1;color:rgb(176 141 87/var(--tw-text-opacity,1))}
.hover\:text-on-primary:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}
.focus\:border-accent-gold:focus{--tw-border-opacity:1;border-color:rgb(176 141 87/var(--tw-border-opacity,1))}
.focus\:ring-accent-gold:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(176 141 87/var(--tw-ring-opacity,1))}
.group:focus-within .group-focus-within\:visible{visibility:visible}
.group:focus-within .group-focus-within\:opacity-100{opacity:1}
.group:hover .group-hover\:visible{visibility:visible}
.group:hover .group-hover\:text-accent-gold{--tw-text-opacity:1;color:rgb(176 141 87/var(--tw-text-opacity,1))}
.group:hover .group-hover\:underline{text-decoration-line:underline}
.group:hover .group-hover\:opacity-100{opacity:1}
.ag-rail__item {
    display: grid;
    grid-template-columns: 24px minmax(0, 1fr);
    gap: 12px;
    padding: 12px 0;
    min-height: 44px;
    border-bottom: var(--ag-border-hairline);
    text-decoration: none;
}
.ag-rail__item:last-child { border-bottom: 0; }
.ag-rail__i {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 12.5px;
    color: var(--ag-slate-400);
    padding-top: 2px;
}
.ag-rail__body { display: block; min-width: 0; }
.ag-rail__hl {
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.34;
    font-weight: 600;
    color: var(--ag-navy-900);
    margin: 0 0 6px;
}
.ag-rail__item:hover .ag-rail__hl,
.ag-rail__item:focus-visible .ag-rail__hl { text-decoration: underline; }
.ag-rail__meta {
    font-family: var(--ag-font-sans);
    font-size: 11.5px;
    color: var(--ag-slate-500);
    display: flex;
    align-items: center;
    gap: 8px;
}
.ag-rail__pips { display: flex; gap: 3px; flex: 0 0 auto; }
.ag-rail__pips span {
    width: 15px;
    height: 6px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-pip-off);
}
.ag-rail__pips span.on { background: var(--ag-pip-on); }
.hover\:text-accent-gold:hover { color: rgb(37 99 235 / var(--tw-text-opacity, 1)); }
.hover\:bg-accent-gold:hover { background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1)); }
.hover\:border-accent-gold\/30:hover { border-color: rgba(37, 99, 235, .3); }
.focus\:border-accent-gold:focus { border-color: rgb(37 99 235 / var(--tw-border-opacity, 1)); }
.focus\:ring-accent-gold:focus { --tw-ring-color: rgb(37 99 235 / var(--tw-ring-opacity, 1)); }
.group:hover .group-hover\:text-accent-gold { color: rgb(37 99 235 / var(--tw-text-opacity, 1)); }
.aghome__hero {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) 340px;
    gap: 48px;
    align-items: start;
    padding: 30px 0 36px;
    border-bottom: 2px solid var(--ag-navy-900);
}
/* Without this the 340px rail never collapses, so the 1.6fr lead column
   resolves to 0px below ~700px and the headline renders one word per line
   on top of the rail. This is the mockup's own breakpoint. */
@media (max-width: 960px) {
    /* minmax(0,...) not the mockup's bare 1fr: a bare 1fr track keeps a
       min-content floor, and real headlines/URLs push that floor past the
       viewport (measured 415px inside a 350px container). min-width:0 on the
       children lets them shrink for the same reason. */
    .aghome__hero { grid-template-columns: minmax(0, 1fr); gap: 30px; }
    .aghome__lead,
    .aghome__side { min-width: 0; }
}
.aghome__lead-im { display: block; margin-bottom: 20px; }
.aghome__lead-im img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: var(--ag-radius-md);
}
.aghome__kicker {
    font-family: var(--ag-font-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
    margin-bottom: 8px;
}
.aghome__hl {
    font-family: var(--ag-font-serif);
    font-size: 40px;
    line-height: 1.12;
    font-weight: 700;
    letter-spacing: -.02em;
    margin: 0 0 12px;
}
.aghome__hl a { color: var(--ag-navy-900); text-decoration: none; }
.aghome__hl a:hover { text-decoration: underline; }
.aghome__dek {
    font-size: 17px;
    line-height: 1.55;
    color: var(--ag-slate-600);
    margin: 0 0 14px;
    max-width: 60ch;
}
.aghome__meta,
.aghome__m {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 11.5px;
    color: var(--ag-slate-500);
}
.aghome__mono {
    font-family: var(--ag-font-mono);
    font-variant-numeric: tabular-nums;
}
.aghome__pips { display: flex; gap: 3px; flex: 0 0 auto; }
.aghome__pips span {
    width: 14px;
    height: 6px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-pip-off);
}
.aghome__pips span.on { background: var(--ag-pip-on); }
.aghome__side-h {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    margin: 0 0 4px;
    color: var(--ag-navy-900);
}
.aghome__grid { padding: 34px 0 0; }
.aghome__cards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 26px;
    margin-top: 22px;
}
/* Mockup collapses the card grid to a single column here. Without it the
   grid stayed 3-up at 390px, rendering 99px-wide cards. */
@media (max-width: 900px) {
    .aghome__cards { grid-template-columns: 1fr; }
}
/* The sidebar column was never styled at all — it defaulted to display:block,
   so the rail and the two cards had no vertical rhythm between them. */
.aghome__side { display: flex; flex-direction: column; gap: 22px; }
.aghome__card-im { display: block; margin-bottom: 10px; }
.aghome__card-im img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: var(--ag-radius-md);
}
.aghome__chip {
    display: inline-block;
    font-family: var(--ag-font-mono);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-accent-700);
    margin-bottom: 6px;
}
.aghome__card-hl {
    font-family: var(--ag-font-serif);
    font-size: 17px;
    line-height: 1.32;
    font-weight: 600;
    margin: 0 0 8px;
}
.aghome__card-hl a { color: var(--ag-navy-900); text-decoration: none; }
.aghome__card-hl a:hover { text-decoration: underline; }
.aghome__card-im img {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
.nav { background: #fff; border-bottom: hairline }
Live was: black ticker bar, and a bg-paper/90 + backdrop-blur nav.

   Restyled, NOT rebuilt: the ticker keeps its live prices, and the nav
   keeps search, subscribe and the dropdowns. The mockup header has no
   nav links at all, so matching its markup literally would delete
   working features.

   Scoped to the page header so the Tailwind utilities are not changed
   anywhere else on the site.
   --------------------------------------------------------------------- */
:root {
    /* The mockups' navy. Kept as its own token rather than moving
       --ag-navy-900, which the whole verification layer reads. */
    --ag-chrome-navy: #0f172a;
    --ag-chrome-dim: #cbd5e1;
}
body > header {
    background-color: var(--ag-white);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border-bottom: var(--ag-border-hairline);
}
body > header > .bg-primary .text-on-primary,
body > header > .bg-primary .font-label-caps {
    color: var(--ag-chrome-dim);
}
body > header > .bg-primary .text-outline {
    color: var(--ag-slate-500);
}
.ag-ticker__wrap {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
}
.ag-ticker__item { display: inline-flex; gap: 6px; align-items: baseline; }
.ag-ticker .up { color: var(--ag-success-500); }
.ag-ticker .dn { color: var(--ag-error-500); }
.ag-nav {
    background: var(--ag-white);
    border-bottom: var(--ag-border-hairline);
    position: sticky;
    top: 0;
    z-index: 40;
}
.ag-nav__wrap {
    max-width: 1200px;
    margin: 0 auto;
    padding: 13px 20px;
    display: flex;
    align-items: center;
    gap: 26px;
}
.ag-brand {
    font-family: var(--ag-font-serif);
    font-weight: 700;
    font-size: 21px;
    letter-spacing: -.02em;
    color: var(--ag-navy-900);
    text-decoration: none;
    flex: 0 0 auto;
}
.ag-brand__wm span { color: var(--ag-accent-600); }
.ag-nav__list {
    display: flex;
    gap: 19px;
    flex-wrap: nowrap;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 14px;
    flex-wrap: wrap;
}
.ag-nav__list a {
    color: var(--ag-slate-700);
    text-decoration: none;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}
/* Both states were just "turn accent blue", which is neither of the two
   things the mockups do. Hover underlines and keeps the slate colour; the
   current desk goes navy + 600 and carries a 2px accent rule beneath it
   (box-shadow, so it sits tight under the text rather than at the bottom
   of the 44px tap target a border-bottom would use). */
.ag-nav__list a:hover { color: var(--ag-slate-700); text-decoration: underline; }
.ag-nav__list a[aria-current="page"] {
    color: var(--ag-navy-900);
    font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--ag-accent-600);
}
.ag-nav__list a[aria-current="page"]:hover { color: var(--ag-navy-900); }
/* ------------------------------------------------------------------
   Ticker chrome — restored 6 Aug 2026.

   The .ag-ticker strip had no background rule in any source file, so it
   rendered on the page background (white). That is not just off-design:
   stitch-base.css sets the DARK-chrome market colours on it
   (--ag-tk-up #22c55e / --ag-tk-down #f87171), which are tuned for a
   navy surface. On white they measure 1.86:1 and 2.55:1 — well under
   AA. Painting the strip navy-900, as the approved mockup specifies,
   is what makes those values legal: 7.83:1 and 6.45:1.
   ------------------------------------------------------------------ */
.ag-ticker {
    background: var(--ag-navy-900);
    color: var(--ag-slate-300);
    /* handover §5.5: the mono token was fixed but .ag-ticker never consumed
       it, so all 40 tabular figures rendered in proportional Inter. */
    font-family: var(--ag-font-mono);
    font-size: 12.5px;
    line-height: 1.5;
    padding: 8px 0;
    font-variant-numeric: tabular-nums;
}
.ag-ticker a { color: var(--ag-slate-300); }
.ag-ticker__item { color: var(--ag-slate-300); }

/* ------------------------------------------------------------------
   Card grid integrity — 6 Aug 2026.
   Cards without a featured image were 74px tall inside a grid row sized
   to 313px neighbours, tearing large holes through both bands. Cards now
   stretch to the row and every one carries a 16:9 image box; the
   thumbnail-less variant is a flat navy field rather than a gap.
   ------------------------------------------------------------------ */
.aghome__cards { align-items: stretch; }
.aghome__card { height: 100%; }
.aghome__card-im { display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--ag-slate-200); }
.aghome__card-im img { width: 100%; height: 100%; object-fit: cover; display: block; }
.aghome__card-im--empty {
    background:
      radial-gradient(120% 90% at 22% 12%, var(--ag-navy-800) 0%, var(--ag-navy-900) 62%),
      var(--ag-navy-900);
}

/* ==================================================================
   Homepage blocks added 6 Aug 2026 to match the approved mockup:
   promise bar, Fear & Greed card, newsroom stats, claims strip,
   sections grid, and the how-it-works band. Tokens only.
   ================================================================== */

/* --- promise bar --- */
.ag-promise { background: var(--ag-navy-900); color: var(--ag-slate-300); }
.ag-promise__wrap { display: flex; align-items: center; gap: 14px; padding-top: 11px; padding-bottom: 11px; flex-wrap: wrap; font-size: 13.5px; }
.ag-promise__pips { display: flex; gap: 3px; flex: none; }
.ag-promise__pips span { width: 16px; height: 6px; border-radius: var(--ag-radius-full); background: var(--ag-slate-700); }
.ag-promise__pips span.on { background: var(--ag-white); }
.ag-promise__pips span.on:last-child { background: var(--ag-accent-400); }
.ag-promise__txt b { color: var(--ag-white); font-weight: 600; }
.ag-promise__link { color: var(--ag-accent-400); margin-left: auto; white-space: nowrap; font-size: 13px; }

/* --- sidebar cards --- */
.ag-card { background: var(--ag-white); border: 1px solid var(--ag-slate-200); border-radius: var(--ag-radius-md); padding: 17px; }
.ag-fng__num { font-family: var(--ag-font-serif); font-size: 32px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; }
.ag-fng__num small { font-family: var(--ag-font-sans); font-size: 13.5px; font-weight: 500; color: var(--ag-slate-600); letter-spacing: 0; }
.ag-fng__gauge { height: 8px; border-radius: var(--ag-radius-full); margin: 14px 0 7px; position: relative;
  background: linear-gradient(90deg, var(--ag-error-700), var(--ag-warning-600), var(--ag-slate-500), var(--ag-success-500), var(--ag-success-700)); }
.ag-fng__gauge i { position: absolute; left: 50%; top: -5px; width: 3px; height: 18px; background: var(--ag-navy-900); border-radius: 2px; }
.ag-fng__scale { display: flex; justify-content: space-between; font-family: var(--ag-font-mono); font-size: 10.5px; color: var(--ag-slate-500); }
.ag-kv { margin: 0; }
.ag-kv > div { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px dashed var(--ag-slate-200); font-size: 13.5px; }
.ag-kv > div:last-child { border-bottom: 0; }
.ag-kv dt { color: var(--ag-slate-600); margin: 0; }
.ag-kv dd { margin: 0; font-family: var(--ag-font-mono); font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; }

/* --- claims strip --- */
.ag-claims { padding-top: 52px; }
.ag-claims__h { font-family: var(--ag-font-serif); font-size: 26px; font-weight: 700; letter-spacing: -0.015em; margin: 0 0 5px; }
.ag-claims__lede { color: var(--ag-slate-600); margin: 0 0 22px; max-width: 72ch; }
.ag-claims__list { background: var(--ag-white); border: 1px solid var(--ag-slate-200); border-radius: var(--ag-radius-md); overflow: hidden; }
.ag-claims__row { display: grid; grid-template-columns: 74px minmax(0,1fr) auto; gap: 18px; padding: 15px 18px; border-bottom: 1px solid var(--ag-slate-200); align-items: center; }
.ag-claims__row:last-child { border-bottom: 0; }
.ag-claims__row:hover { background: var(--ag-slate-50); }
.ag-claims__row p { margin: 0; font-size: 15px; line-height: 1.45; }
.ag-claims__row p a { color: var(--ag-navy-900); border-bottom: 1px solid var(--ag-slate-300); }
.ag-claims__sub { font-size: 12px; color: var(--ag-slate-500); margin-top: 4px; }
.ag-claims__status { font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; border-radius: var(--ag-radius-sm); padding: 3px 9px; border: 1px solid var(--ag-slate-300); background: var(--ag-slate-100); color: var(--ag-slate-700); }
.ag-claims__status--disputed { background: var(--ag-accent-tint-50); color: var(--ag-accent-700); border-color: var(--ag-verify-border); }
.ag-claims__status--verified { background: var(--ag-success-tint-50); color: var(--ag-success-700); border-color: var(--ag-status-verified-border); }
.ag-claims__status--false { background: var(--ag-error-tint-50); color: var(--ag-error-700); border-color: var(--ag-status-false-border); }
.ag-claims__status--developing { background: var(--ag-white); color: var(--ag-navy-800); border-color: var(--ag-slate-400); }
.ag-claims__more, .ag-cats { margin-top: 18px; }
.ag-claims__more { text-align: center; }

/* --- sections grid --- */
.ag-cats { padding-top: 52px; margin-top: 0; }
.ag-cats__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 18px; }
.ag-cats__item { border: 1px solid var(--ag-slate-200); background: var(--ag-white); border-radius: var(--ag-radius-md); padding: 15px 17px; display: flex; align-items: baseline; gap: 10px; }
.ag-cats__item b { font-family: var(--ag-font-serif); font-size: 16.5px; font-weight: 700; }
.ag-cats__item b a { color: var(--ag-navy-900); }
.ag-cats__item span { margin-left: auto; font-family: var(--ag-font-mono); font-size: 11.5px; color: var(--ag-slate-500); }

/* --- how it works --- */
.ag-how { background: var(--ag-navy-900); color: var(--ag-slate-300); margin-top: 56px; padding: 48px 0 52px; }
.ag-how__h { font-family: var(--ag-font-serif); font-size: 28px; font-weight: 700; color: var(--ag-white); letter-spacing: -0.02em; margin: 0 0 8px; }
.ag-how__lede { max-width: 70ch; margin: 0 0 34px; color: var(--ag-slate-400); font-size: 15.5px; line-height: 1.65; }
.ag-how__steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; }
.ag-how__step { border-top: 2px solid var(--ag-slate-700); padding-top: 15px; }
/* Step 04's rest border was accent-500 (the mockup marks the last step as
   the payoff). Dropped 6 Aug 2026: with all eight panels sharing a blue
   hover, a permanently blue step read as stuck-on rather than emphasised.
   It now sits slate-700 like 01-03 and goes accent-400 on hover with them. */
.ag-how__step .n { font-family: var(--ag-font-mono); font-size: 11.5px; color: var(--ag-slate-500); margin-bottom: 9px; }
.ag-how__step h3 { font-size: 15px; font-weight: 600; color: var(--ag-white); margin: 0 0 7px; }
.ag-how__step p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ag-slate-400); }
.ag-how__stances { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; margin-top: 40px; border: 1px solid var(--ag-navy-800); border-radius: var(--ag-radius-md); overflow: hidden; }
.ag-how__st { padding: 16px 18px; background: #0b1220; border-right: 1px solid var(--ag-navy-800); }
.ag-how__st:last-child { border-right: 0; }
.ag-how__st .lbl { font-size: 10.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; margin-bottom: 7px; }
.ag-how__st p { margin: 0; font-size: 12.5px; color: var(--ag-slate-400); line-height: 1.55; }
.ag-how__st .bar { height: 3px; border-radius: 2px; margin-bottom: 11px; width: 34px; }
/* ------------------------------------------------------------------
   Stance legend: neutral at rest, accent blue on hover/focus. The same
   colour on all four panels, so the row reads as one consistent control
   rather than four differently-behaving ones.

   Colour is decoration here, never the message: each panel's sentence is
   always visible, so nothing is hover-gated and touch users lose no
   information.

   Rest labels are slate-400 rather than the spec's slate-500 for Echo:
   slate-500 on the #0b1220 panel measures ~3.8:1, under AA for 10.5px
   text. slate-400 measures ~6:1. Accessibility is at 100 and stays there.

   The claim page still renders .ag-stance--contradicts in STATIC accent
   per design-system-spec.html and handover Section 2 decision 2. This
   legend and that page differ on purpose — change both or neither.
   ------------------------------------------------------------------ */
.ag-how__st { transition: background 140ms ease; }
.ag-how__st .lbl { color: var(--ag-slate-400); transition: color 140ms ease; }
.ag-how__st .bar { background: var(--ag-slate-700); transition: background 140ms ease; }
.ag-how__st:hover,
.ag-how__st:focus-within { background: var(--ag-navy-800); }

/* One hover colour for every panel — accent blue. */
.ag-how__st:hover .lbl,
.ag-how__st:focus-within .lbl { color: var(--ag-accent-400); }
.ag-how__st:hover .bar,
.ag-how__st:focus-within .bar { background: var(--ag-accent-600); }

.ag-how__statuses { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 26px; }
.ag-how__stat { display: inline-flex; align-items: center; gap: 8px; border-radius: var(--ag-radius-full); padding: 6px 14px; font-size: 12.5px; font-weight: 600; border: 1px solid; }
.ag-how__stat--unproven { background: #111c31; color: var(--ag-slate-300); border-color: var(--ag-slate-700); }
.ag-how__stat--developing { background: transparent; color: var(--ag-slate-200); border-color: var(--ag-slate-600); }
.ag-how__stat--disputed { background: rgba(37,99,235,0.16); color: var(--ag-accent-400); border-color: var(--ag-accent-700); }
.ag-how__stat--verified { background: rgba(34,197,94,0.14); color: #4ade80; border-color: var(--ag-success-700); }
.ag-how__stat--false { background: rgba(239,68,68,0.14); color: #fca5a5; border-color: var(--ag-error-700); }
.ag-how__note { margin-top: 22px; font-size: 13px; color: var(--ag-slate-500); max-width: 76ch; line-height: 1.6; }
.ag-how__note b { color: var(--ag-slate-200); font-weight: 600; }

@media (max-width: 900px) {
  .ag-how__steps, .ag-cats__grid { grid-template-columns: 1fr 1fr; }
  .ag-how__stances { grid-template-columns: 1fr 1fr; }
  .ag-claims__row { grid-template-columns: 1fr; gap: 8px; }
}
@media (max-width: 560px) {
  .ag-how__steps, .ag-cats__grid, .ag-how__stances { grid-template-columns: 1fr; }
}

/* ==================================================================
   MOCKUP FIDELITY PASS — 6 Aug 2026.
   Measured the live page against the approved mockup rather than
   checking that elements merely existed. Each rule below closes a
   specific measured gap; the measurement is in the comment.
   ================================================================== */

/* S1. Container mismatch. Header/ticker/nav sat on max-width 1200 /
   padding 20 (content x=264) while the promise bar, main and the how
   band sat on 1280 / 64 (content x=224). Every body section was inset
   40px from the header, down the whole page. One container now. */
.ag-container { max-width: 1200px; padding-left: 20px; padding-right: 20px; }
.ag-promise__wrap { padding-left: 20px; padding-right: 20px; }

/* T1-T7. Ticker. It was Inter 15px with no vertical padding, no
   direction arrows, and Fear & Greed sitting inline instead of pushed
   to the right rail. The ticker is the most financial terminal
   element on the page and it was rendering as body sans. */
.ag-ticker { padding: 8px 0; }
.ag-ticker__wrap {
    font-family: var(--ag-font-mono);
    font-size: 12.5px;
    gap: 26px;
    align-items: center;
    font-variant-numeric: tabular-nums;
}
.ag-ticker__item { gap: 5px; }
.ag-ticker__item:last-child { margin-left: auto; }
.ag-ticker [data-ticker-change].up::before { content: "\25B2\00A0"; }
.ag-ticker [data-ticker-change].dn::before { content: "\25BC\00A0"; }

/* B1. Band labels rendered as Inter 15px/400 - indistinguishable from
   body copy. In the mockup a band is a small tracked uppercase rule,
   which is what makes Corroborated / Single source read as structure
   rather than as a sentence. */
.ag-band { display: flex; align-items: baseline; gap: 13px; flex-wrap: wrap; }
.ag-band__name { font-family: var(--ag-font-sans); font-size: 11px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ag-navy-900); }
.ag-band--pending .ag-band__name { color: var(--ag-slate-600); }
.ag-band__gloss { font-family: var(--ag-font-sans); font-size: 12.5px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--ag-slate-600); }
.ag-band__n { margin-left: auto; font-family: var(--ag-font-mono); font-size: 11.5px; color: var(--ag-slate-500); font-variant-numeric: tabular-nums; }

/* C1. Cards had no card treatment at all: transparent background, zero
   border, zero radius. They were bare text columns on the page. */
.aghome__card {
    background: var(--ag-white);
    border: 1px solid var(--ag-slate-200);
    border-radius: var(--ag-radius-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.aghome__card-bd { padding: 15px 17px 17px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.aghome__card-hl { font-size: 17.5px; line-height: 1.33; margin: 0; }
.aghome__m { margin-top: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 11.5px; color: var(--ag-slate-500); }
.aghome__m .aghome__mono, .aghome__card .aghome__mono { font-family: var(--ag-font-mono); font-variant-numeric: tabular-nums; }

/* C2. Category chip was mono 10px in accent blue with no chip at all.
   The mockup draws a bordered slate chip in the UI sans. */
.aghome__chip {
    font-family: var(--ag-font-sans);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ag-slate-600);
    border: 1px solid var(--ag-slate-200);
    border-radius: var(--ag-radius-sm);
    padding: 3px 8px;
    align-self: flex-start;
    background: transparent;
}

/* H1/H3. Hero. Headline was 40px against the mockup 42px, and the
   kicker rendered as mono slate rather than the tracked accent-blue
   eyebrow that tells you which desk the lead came from. */
.aghome__hl { font-size: 42px; line-height: 1.13; letter-spacing: -0.028em; }
.aghome__kicker {
    font-family: var(--ag-font-sans);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ag-accent-700);
}
.aghome__meta { font-size: 12.5px; color: var(--ag-slate-500); gap: 11px; }

/* R1. Rail/sidebar headings were Source Serif 11.5px - a serif set at
   caption size reads as a mistake. The mockup uses the tracked sans
   label, same device as the band. */
.aghome__side-h {
    font-family: var(--ag-font-sans);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--ag-navy-900);
    margin: 0 0 3px;
}
.ag-rail__sub { font-size: 12.5px; color: var(--ag-slate-600); margin: 0 0 12px; line-height: 1.5; }

/* Promise bar: the link wrapped to a second line at 1200px because the
   row was free to wrap. Text takes the free space, link holds the rail. */
.ag-promise__wrap { flex-wrap: nowrap; }
.ag-promise__txt { flex: 1 1 auto; min-width: 0; }
.ag-promise__link { flex: 0 0 auto; }
@media (max-width: 860px) {
  .ag-promise__wrap { flex-wrap: wrap; }
  .ag-promise__link { margin-left: 0; }
}


/* ------------------------------------------------------------------
   Fidelity pass, 6 Aug 2026 — measured against homepage-mockup.html.
   ------------------------------------------------------------------ */

/* The theme's global heading rule sets line-height 1.2; the mockup lets
   these inherit the body's 1.5. Applied only to the headings measured. */
.aghome__side-h,
.ag-claims__h,
.ag-how__h { line-height: 1.5; }

/* Band: the homepage band is a transparent rule-under-label, not the
   filled strip verification.css defines for the archive. Scoped to the
   homepage so the archive keeps its own treatment. */
.aghome .ag-band,
main.aghome .ag-band {
    background: transparent;
    margin: 40px 0 0;
    padding-bottom: 9px;
    border-bottom: 1px solid var(--ag-slate-300);
}

/* Responsive breakpoints carried by the mockup but missing from the theme. */
@media (max-width: 900px) {
    .ag-cats__grid { grid-template-columns: 1fr 1fr; }
    .ag-how__steps { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
    .ag-how__stances { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
    .ag-cats__grid { grid-template-columns: 1fr; }
    .ag-how__steps { grid-template-columns: 1fr; }
}


/* ------------------------------------------------------------------
   Header lockup, nav tools and mobile drawer — 6 Aug 2026.
   ------------------------------------------------------------------ */

/* Wordmark + seal. The wordmark is wrapped in .ag-brand__wm so that
   flex + gap separates the seal from the wordmark, not "Altcoin" from
   "Gordon" — the bare text node would otherwise become its own flex item. */
.ag-brand { display: flex; align-items: center; gap: 10px; }
.ag-brand__seal { display: block; flex: none; width: 26px; height: 26px; border-radius: 6px; }
.ag-brand__wm { white-space: nowrap; }

.ag-nav__tools { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.ag-icon {
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: var(--ag-radius-sm);
    color: var(--ag-slate-600);
    background: none; border: 0; padding: 0; cursor: pointer;
    text-decoration: none;
}
.ag-icon:hover { background: var(--ag-slate-100); }
.ag-icon svg { width: 18px; height: 18px; }
.ag-nav__toggle { display: none; }

@media (max-width: 860px) {
    .ag-nav__list { display: none; }
    .ag-nav__toggle { display: grid; }
}

/* ------------------------------------------------------------------
   RESTORED 6 Aug 2026. These four blocks were removed by accident when
   the old drawer CSS was spliced out — the slice ran from the drawer
   comment to the newsletter block and took everything in between.
   ------------------------------------------------------------------ */

/* .ag-kv means two different things. On the claim page it IS the row, and
   verification.css styles it flex/space-between. On the homepage it is the
   <dl> CONTAINER with .ag-kv > div rows, so that rule laid all four stats
   side by side and overflowed the Newsroom card. */
.aghome .ag-kv,
.aghome dl.ag-kv { display: block; }

/* Inline nav search (desktop base; the mobile row is defined further down) */
.ag-search { width: 0; overflow: hidden; transition: width 160ms ease; }
.ag-search.is-open { width: 220px; }
.ag-search__field {
    width: 100%;
    min-height: 44px;
    padding: 8px 12px;
    border: 1px solid var(--ag-slate-300);
    border-radius: var(--ag-radius-sm);
    background: var(--ag-white);
    color: var(--ag-navy-900);
    font: inherit;
    font-size: 14px;
}
.ag-search__field::-webkit-search-cancel-button { cursor: pointer; }

/* "All stories today" and "Browse all N claims" — mockup .more */
.aghome__more { margin-top: 24px; text-align: center; }
.ag-claims__more { margin-top: 24px; text-align: center; }
.aghome__more a,
.ag-claims__more a {
    display: inline-block;
    padding: 11px 22px;
    min-height: 44px;
    line-height: 22px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-sm);
    background: var(--ag-white);
    color: var(--ag-slate-700);
    font-size: 13.5px;
    text-decoration: none;
}
.aghome__more a:hover,
.ag-claims__more a:hover { border-color: var(--ag-slate-300); color: var(--ag-navy-900); }

/* Claims status pill — deliberate deviation from the mockup's 74px track,
   which is 10px too narrow for UNPROVEN and 19px too narrow for DEVELOPING,
   so the text overflowed its own right padding. ag_audit.py will report
   `width want 74px got 100px` and `textAlign want start got center`; both
   are intended. */
.ag-claims__row { grid-template-columns: 100px minmax(0, 1fr) auto; }
.ag-claims__status {
    justify-self: center;
    width: -moz-max-content;
    width: max-content;
    text-align: center;
    white-space: nowrap;
}

/* Promise bar rotator. Slides are stacked in one grid cell and toggled with
   visibility, not [hidden]: removing them from flow made the bar jump
   63px -> 42px -> 63px as it rotated, because the middle slide fits one
   line where the others wrap. */
.ag-promise__slides { flex: 1 1 auto; min-width: 0; display: grid; }
.ag-promise__slide { grid-area: 1 / 1; display: flex; align-items: center; gap: 14px; }
.ag-promise__slide.is-off { visibility: hidden; pointer-events: none; }

.ag-promise__pip {
    position: relative;
    width: 16px;
    height: 6px;
    padding: 0;
    border: 0;
    border-radius: var(--ag-radius-full);
    background: var(--ag-slate-700);
    cursor: pointer;
    transition: background 160ms ease;
}
/* 16x6 is far below a usable tap target; expand the hit area without
   changing the layout the pips sit in. */
.ag-promise__pip::after { content: ""; position: absolute; inset: -14px -5px; }
.ag-promise__pip.is-on { background: var(--ag-accent-400); }
.ag-promise__pip:hover { background: var(--ag-slate-400); }
.ag-promise__pip.is-on:hover { background: var(--ag-accent-400); }
.ag-promise__pip:focus-visible { outline: 2px solid var(--ag-accent-400); outline-offset: 3px; }

@media (max-width: 640px) {
    .ag-promise__slide { flex-wrap: wrap; gap: 8px; }
    .ag-promise__link { margin-left: 0; }
}

/* How-it-works steps: same accent-blue hover as the stance panels. */
.ag-how__step { transition: border-color 140ms ease; }
.ag-how__step .n { transition: color 140ms ease; }
.ag-how__step:hover,
.ag-how__step:focus-within { border-top-color: var(--ag-accent-400); }
.ag-how__step:hover .n,
.ag-how__step:focus-within .n { color: var(--ag-accent-400); }

/* ------------------------------------------------------------------
   Newsletter band (mockup .news) — full-bleed white, between the how
   band and the footer. The mockup's inline email form is deliberately
   not built: see the note in home.php. The right column keeps the
   mockup's 380px track so a form can drop straight in later.
   ------------------------------------------------------------------ */
.ag-news {
    margin-top: 56px;
    background: var(--ag-white);
    border-top: var(--ag-border-hairline);
    border-bottom: var(--ag-border-hairline);
    padding: 38px 0;
}
.ag-news__wrap { display: grid; grid-template-columns: 1fr 380px; gap: 40px; align-items: center; }
.ag-news__h {
    font-family: var(--ag-font-serif);
    font-size: 23px;
    font-weight: 700;
    letter-spacing: -.015em;
    margin: 0 0 6px;
}
.ag-news__p { margin: 0; color: var(--ag-slate-600); font-size: 14.5px; max-width: 60ch; }
/* Mockup .form: field + button on one row. */
.ag-news__form { display: flex; gap: 9px; }
.ag-news__field {
    flex: 1;
    min-width: 0;
    min-height: 44px;
    padding: 12px 14px;
    border: 1px solid var(--ag-slate-300);
    border-radius: var(--ag-radius-sm);
    background: var(--ag-white);
    color: var(--ag-navy-900);
    font: inherit;
    font-size: 14px;
}
.ag-news__btn {
    flex: 0 0 auto;
    min-height: 44px;
    padding: 12px 20px;
    border: 0;
    border-radius: var(--ag-radius-sm);
    background: var(--ag-accent-600);
    color: var(--ag-white);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 140ms ease;
}
.ag-news__btn:hover:not(:disabled) { background: var(--ag-accent-700); }

/* Inactive until a handler exists. Kept on-palette rather than greyed to
   death, but unmistakably not clickable. */
.ag-news__field:disabled {
    background: var(--ag-slate-50);
    color: var(--ag-slate-500);
    cursor: not-allowed;
}
.ag-news__btn:disabled { opacity: .5; cursor: not-allowed; }
.ag-news__hint {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--ag-slate-500);
}

@media (max-width: 820px) {
    .ag-news__wrap { grid-template-columns: 1fr; gap: 20px; }
}

/* ------------------------------------------------------------------
   Footer — rebuilt 1:1 to homepage-mockup.html. The previous markup
   still used gold-era Tailwind utilities, so the navy/accent repaint
   never reached it. Lives here rather than in style.css because this
   file is bundled last and therefore wins over the old rules.
   ------------------------------------------------------------------ */
.ag-footer {
    background: var(--ag-navy-900);
    color: var(--ag-slate-400);
    padding: 40px 0 46px;
    font-size: 13.5px;
}
.ag-footer__cols { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 34px; }
.ag-footer h4 {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ag-slate-300);
    margin: 0 0 12px;
}
.ag-footer a { color: var(--ag-slate-400); display: block; padding: 5px 0; text-decoration: none; }
.ag-footer a:hover { color: var(--ag-white); }

/* Column headings are sans in the mockup. The theme has a global serif rule
   for h1-h6 which .ag-footer h4 did not override, so they were rendering in
   Source Serif 4. */
.ag-footer h4 { font-family: var(--ag-font-sans); }

/* Selector has to out-specify `.ag-footer a` (0,1,1) — as a plain
   `.ag-footer__brand` (0,1,0) it lost, so the brand was picking up the
   generic link rule's slate-400 colour, display:block and 5px padding
   instead of its own white / inline / unpadded treatment.

   flex + gap:10px is what the mockup does: `.brand` is a flex container, so
   the "Altcoin" text node and the <span>Gordon</span> become separate flex
   items with a real 10px space between them. Deliberate here, unlike in the
   header where the same rule would have split a wordmark that has a seal
   sitting beside it. */
.ag-footer a.ag-footer__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    width: -moz-fit-content;
    width: fit-content;
    margin-bottom: 12px;
    padding: 0;
    font-family: var(--ag-font-serif);
    font-weight: 700;
    font-size: 20px;
    letter-spacing: -.02em;
    line-height: 1.5;
    color: var(--ag-white);
    text-decoration: none;
}
.ag-footer a.ag-footer__brand:hover { color: var(--ag-white); }
.ag-footer__brand span { color: var(--ag-accent-400); }
.ag-footer__about { margin: 0; color: var(--ag-slate-400); line-height: 1.65; max-width: 38ch; }

/* Pages that do not exist yet: shown, but not clickable and visibly quieter
   than the live links so the difference is legible. */
.ag-footer__soon { display: block; padding: 5px 0; color: var(--ag-slate-600); cursor: default; }

.ag-footer__legal {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 18px;
    margin-top: 32px;
    padding-top: 20px;
    border-top: 1px solid var(--ag-navy-800);
    font-size: 12.5px;
    color: var(--ag-slate-500);
}
.ag-footer__legal a { display: inline; padding: 0; }
.ag-footer__disclaimer { margin-left: auto; }

@media (max-width: 820px) {
    .ag-footer__cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
    .ag-footer__disclaimer { margin-left: 0; }
}

/* ------------------------------------------------------------------
   Price ticker — static row on desktop, marquee below 820px.
   ------------------------------------------------------------------
   The strip was flex-wrap:wrap, so at 390px its six items broke onto
   three stacked rows and the header ate a third of the screen.

   Structure: .ag-ticker__wrap is now only the centring box; the flex
   row moved to .ag-ticker__track so there is something to animate.
   Each half is a .ag-ticker__set using display:contents, so the items
   still lay out as direct children of the track.

   The loop uses margin-right on items rather than gap on the track.
   With gap, translateX(-50%) lands half an inter-set gap out and the
   seam visibly stutters each cycle; with margin every item measures
   the same, so half the track is exactly one set.

   Nothing is dropped — every coin and the Fear & Greed chip are still
   present — where hiding the strip on mobile would have cost the
   information outright.
   ------------------------------------------------------------------ */
.ag-ticker__wrap { display: block; }
.ag-ticker__track { display: flex; flex-wrap: wrap; align-items: center; gap: 26px; }
.ag-ticker__set { display: contents; }
.ag-ticker__set--dupe { display: none; }

@keyframes ag-ticker-slide {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}

@media (max-width: 820px) {
    .ag-ticker { font-size: 11.5px; padding: 7px 0; }
    .ag-ticker__wrap { overflow: hidden; padding: 0 14px; }
    .ag-ticker__track {
        flex-wrap: nowrap;
        gap: 0;
        width: -moz-max-content;
        width: max-content;
        animation: ag-ticker-slide 34s linear infinite;
    }
    .ag-ticker__item { flex: 0 0 auto; margin-right: 14px; }
    .ag-ticker__set--dupe { display: contents; }
    /* let a reader stop it to actually read a price */
    .ag-ticker:hover .ag-ticker__track,
    .ag-ticker:focus-within .ag-ticker__track { animation-play-state: paused; }
}

/* Motion is decoration; without it the strip stays a single line the
   reader can swipe through at their own pace. */
@media (prefers-reduced-motion: reduce) {
    .ag-ticker__track { animation: none; }
    .ag-ticker__wrap { overflow-x: auto; scrollbar-width: none; }
    .ag-ticker__wrap::-webkit-scrollbar { display: none; }
}


/* ==================================================================
   Mobile search + drawer — 6 Aug 2026.
   ================================================================== */

/* Search. The open field used to wrap the nav onto a second line, which
   pushed the bar to 142px tall and left the input sitting right of the
   icons. It now drops out of flow entirely and becomes a full-width row
   under the nav, so the bar keeps its height and the field gets the whole
   viewport instead of ~150px. */
@media (max-width: 820px) {
    .ag-nav__wrap { position: relative; flex-wrap: nowrap; }
    .ag-search {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        width: auto;
        padding: 10px 16px 12px;
        background: var(--ag-white);
        border-bottom: var(--ag-border-hairline);
        box-shadow: 0 10px 20px -12px rgba(15, 23, 42, .35);
        overflow: hidden;
        max-height: 0;
        padding-top: 0;
        padding-bottom: 0;
        transition: max-height 180ms ease, padding 180ms ease;
    }
    .ag-search.is-open { max-height: 80px; padding-top: 10px; padding-bottom: 12px; }
    .ag-search__field { width: 100%; }
}

/* ---------------- drawer ---------------- */
.ag-drawer { position: fixed; inset: 0; z-index: 60; background: rgba(15, 23, 42, .5); }
.ag-drawer[hidden] { display: none; }
@supports (backdrop-filter: blur(2px)) {
    .ag-drawer { backdrop-filter: blur(2px); }
}

.ag-drawer__panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    width: min(88vw, 330px);
    background: var(--ag-white);
    box-shadow: -12px 0 40px -16px rgba(15, 23, 42, .55);
    /* slide in, rather than appear — most of what made the plain panel
       feel unfinished was that it simply blinked into existence */
    transform: translateX(100%);
    transition: transform 220ms cubic-bezier(.16, 1, .3, 1);
}
.ag-drawer.is-open .ag-drawer__panel { transform: none; }

.ag-drawer__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 12px 14px 16px;
    background: var(--ag-navy-900);
}
.ag-drawer__brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ag-drawer__seal { display: block; flex: none; width: 24px; height: 24px; border-radius: 6px; }
.ag-drawer__wm {
    font-family: var(--ag-font-serif);
    font-weight: 700;
    font-size: 17px;
    letter-spacing: -.02em;
    color: var(--ag-white);
}
.ag-drawer__wm span { color: var(--ag-accent-400); }

.ag-drawer__close {
    margin-left: auto;
    flex: none;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--ag-radius-sm);
    background: transparent;
    color: var(--ag-slate-400);
    cursor: pointer;
}
.ag-drawer__close svg { width: 18px; height: 18px; }
.ag-drawer__close:hover { color: var(--ag-white); background: var(--ag-navy-800); }
.ag-drawer__close:focus-visible { outline: 2px solid var(--ag-accent-400); outline-offset: -2px; }

.ag-drawer__nav { flex: 1 1 auto; overflow-y: auto; padding: 6px 0 10px; }
.ag-drawer__label {
    margin: 16px 0 2px;
    padding: 0 16px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-drawer__nav a {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 48px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--ag-slate-100);
    color: var(--ag-navy-900);
    font-size: 15px;
    text-decoration: none;
}
.ag-drawer__nav a:last-child { border-bottom: 0; }
.ag-drawer__nav a:hover { background: var(--ag-slate-50); }
/* current desk gets an accent spine rather than just coloured text */
.ag-drawer__nav a[aria-current="page"] { color: var(--ag-accent-700); font-weight: 600; }
.ag-drawer__nav a[aria-current="page"]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    bottom: 8px;
    width: 3px;
    border-radius: 0 2px 2px 0;
    background: var(--ag-accent-600);
}

.ag-drawer__foot {
    flex: none;
    padding: 16px;
    border-top: var(--ag-border-hairline);
    background: var(--ag-slate-50);
}
.ag-drawer__foot p {
    margin: 0 0 10px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--ag-slate-600);
}
.ag-drawer__foot a {
    font-size: 13px;
    font-weight: 600;
    color: var(--ag-accent-700);
    text-decoration: none;
}
.ag-drawer__foot a:hover { text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
    .ag-drawer__panel { transition: none; }
    .ag-search { transition: none; }
}


/* ==================================================================
   Category / archive — 1:1 with category-archive-mockup.html.
   ================================================================== */
.ag-archive { padding-bottom: 72px; }

/* padding-top was 20px. The gap under the site header is owned by the
   global #content rule now, and keeping this made /news/ sit 92px down
   against a 55px standard. */
.ag-crumbs { padding: 0; font-size: 12px; color: var(--ag-slate-500); }
.ag-crumbs a { color: var(--ag-slate-600); text-decoration: none; }
.ag-crumbs a:hover { text-decoration: underline; }
.ag-crumbs span { margin: 0 4px; }

/* padding-top was 22px. The gap under the site header belongs to the global
   #content rule; keeping this put /news/ 17px lower than every other page.
   The navy rule stays -- it is the archive's own device, not spacing. */
.ag-archive__head { padding: 0 0 20px; border-bottom: 2px solid var(--ag-navy-900); }
/* Type comes from the shared .archive-header__title spec in style.css --
   font-family, size and weight deliberately absent here. This block used to
   set 36px/700 and was the reason /news/ and every category archive looked
   like a different site from /about/. Layout only. */
.ag-archive__title {
    margin: 0 0 8px;
    line-height: 1.2;
    letter-spacing: -.02em;
    color: var(--ag-navy-900);
}
.ag-archive__desc { margin: 0 0 18px; max-width: 60ch; font-size: 15px; color: var(--ag-slate-600); }
.ag-archive__controls { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.ag-archive__sortgrp { display: flex; align-items: center; gap: 10px; }
.ag-archive__sortlbl {
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
/* Links, not buttons: sorting is a real URL so it survives no-JS and is
   crawlable. aria-current replaces the mockup's aria-pressed, which is not
   valid on a link. */
.ag-seg {
    display: flex;
    overflow: hidden;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-full);
    background: var(--ag-white);
}
.ag-seg a {
    padding: 6px 15px;
    font-size: 13px;
    color: var(--ag-slate-600);
    text-decoration: none;
}
.ag-seg a:hover { background: var(--ag-slate-50); text-decoration: none; }
.ag-seg a[aria-current] { background: var(--ag-navy-900); color: var(--ag-white); font-weight: 600; }
.ag-archive__count {
    margin-left: auto;
    font-family: var(--ag-font-mono);
    font-size: 12.5px;
    color: var(--ag-slate-500);
    font-variant-numeric: tabular-nums;
}

/* Band. verification.css styles .ag-band as a filled strip; on the archive
   the mockup draws it as a rule-under-label, like the homepage but with its
   own 34px rhythm and a 12px name. Scoped so neither other page shifts. */
.ag-archive .ag-band-sec { margin-top: 34px; }
.ag-archive .ag-band {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0;
    padding: 0 0 10px;
    background: transparent;
    border-bottom: 1px solid var(--ag-slate-300);
}
.ag-archive .ag-band__name { font-size: 12px; letter-spacing: .06em; color: var(--ag-navy-900); }
.ag-archive .ag-band--pending .ag-band__name { color: var(--ag-slate-500); }
.ag-archive .ag-band__gloss { font-size: 13px; color: var(--ag-slate-600); }
.ag-archive .ag-band__n { margin-left: auto; font-family: var(--ag-font-mono); font-size: 12px; color: var(--ag-slate-500); }

/* Row — the archive's repeating unit. */
.ag-archive .ag-arow {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr) auto;
    gap: 20px;
    align-items: start;
    padding: 16px 0;
    border-bottom: var(--ag-border-hairline);
}
.ag-archive .ag-arow:hover { background: var(--ag-white); }
.ag-archive .ag-arow--dense { padding: 10px 0; gap: 16px; grid-template-columns: 84px minmax(0, 1fr) auto; }

.ag-archive .ag-arow__cor { padding-top: 3px; }
.ag-archive .ag-arow__pips { display: flex; gap: 3px; margin-bottom: 5px; }
.ag-archive .ag-arow__pips span {
    width: 14px;
    height: 6px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-slate-200);
}
.ag-archive .ag-arow__pips span.on { background: var(--ag-navy-900); }
.ag-archive .ag-arow__n {
    font-family: var(--ag-font-mono);
    font-size: 11px;
    letter-spacing: .01em;
    color: var(--ag-slate-500);
    white-space: nowrap;
}

.ag-archive .ag-arow__hl {
    margin: 0 0 6px;
    font-family: var(--ag-font-serif);
    font-size: 19px;
    line-height: 1.32;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--ag-navy-900);
}
.ag-archive .ag-arow__hl a { color: inherit; text-decoration: none; }
.ag-archive .ag-arow__hl a:hover { text-decoration: underline; }
.ag-archive .ag-arow--dense .ag-arow__hl { font-size: 15.5px; line-height: 1.35; margin: 0 0 3px; }

.ag-archive .ag-arow__sub {
    margin: 0 0 8px;
    max-width: 74ch;
    font-size: 13.5px;
    color: var(--ag-slate-600);
}
.ag-archive .ag-arow__meta {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--ag-slate-500);
}
.ag-archive .ag-arow--dense .ag-arow__meta { font-size: 11.5px; gap: 8px; }
.ag-archive .ag-arow__dot { width: 3px; height: 3px; border-radius: 50%; background: var(--ag-slate-300); }
.ag-archive .ag-arow__chip {
    padding: 2px 7px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-sm);
    background: var(--ag-white);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ag-slate-600);
}
.ag-archive .ag-arow__when {
    padding-top: 4px;
    font-family: var(--ag-font-mono);
    font-size: 12px;
    color: var(--ag-slate-500);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.ag-archive .ag-arow--dense .ag-arow__when { font-size: 11.5px; padding-top: 2px; }

/* Duplicate collapse */
.ag-archive .ag-dupe { margin-top: 8px; }
.ag-archive .ag-dupe summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 11px;
    border: 1px solid #bfdbfe;
    border-radius: var(--ag-radius-full);
    background: var(--ag-accent-tint-50);
    color: var(--ag-accent-700);
    font-size: 12px;
    list-style: none;
    cursor: pointer;
}
.ag-archive .ag-dupe summary::-webkit-details-marker { display: none; }
.ag-archive .ag-dupe ol { margin: 10px 0 0; padding: 0 0 0 18px; font-size: 13px; line-height: 1.7; color: var(--ag-slate-600); }

.ag-archive .ag-empty {
    margin-top: 14px;
    padding: 22px;
    border: 1px dashed var(--ag-slate-300);
    border-radius: var(--ag-radius-md);
    background: var(--ag-white);
    text-align: center;
    font-size: 13.5px;
    color: var(--ag-slate-600);
}
.ag-archive .ag-empty b { display: block; margin-bottom: 4px; font-size: 14.5px; color: var(--ag-navy-900); }

.ag-pager { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 40px; }
.ag-pager a,
.ag-pager span {
    padding: 7px 13px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-sm);
    background: var(--ag-white);
    font-size: 13.5px;
    color: var(--ag-slate-600);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}
.ag-pager .current {
    background: var(--ag-navy-900);
    border-color: var(--ag-navy-900);
    color: var(--ag-white);
    font-weight: 600;
}

@media (max-width: 720px) {
    .ag-archive .ag-arow { grid-template-columns: 1fr; gap: 8px; }
    .ag-archive .ag-arow__when { padding-top: 0; }
    .ag-archive .ag-arow__cor { display: flex; align-items: center; gap: 9px; }
    .ag-archive .ag-arow__pips { margin-bottom: 0; }
    /* removed: the shared .archive-header__title spec clamps its own size,
       and this override made /news/ 28px on mobile while every other page
       was 36px. One spec, one size. */
}

/* ==================================================================
   Single article — 1:1 with article-home-mockup.html #view-article,
   with one deliberate change: see the measure note below.
   ================================================================== */
.ag-article { padding-bottom: 72px; }

.ag-art-grid {
    display: grid;
    /* Mockup is `minmax(0,1fr) 300px` with a 56px gutter and .art-col capped
       at 68ch. That left a wide strip of dead space between the end of the
       text and the rail. Gutter is 40px here and the measure is 84ch, so the
       column actually fills. Drop the max-width entirely for edge-to-edge —
       lines then run ~100 characters, past comfortable reading length. */
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 40px;
    align-items: start;
    padding-top: 8px;
}
.ag-art-col { max-width: 84ch; }

.ag-art__cat {
    display: inline-block;
    margin: 18px 0 10px;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-accent-700);
    text-decoration: none;
}
.ag-art__cat:hover { text-decoration: underline; }

.ag-art__title {
    margin: 0 0 14px;
    font-family: var(--ag-font-serif);
    font-size: 38px;
    line-height: 1.18;
    font-weight: 700;
    letter-spacing: -.025em;
    color: var(--ag-navy-900);
}
.ag-art__dek {
    margin: 0 0 20px;
    font-family: var(--ag-font-serif);
    font-size: 20px;
    line-height: 1.5;
    font-style: italic;
    color: var(--ag-slate-600);
}

/* Lead image on single posts. Added Aug 2026 -- the template had never
   rendered one, so every article page shipped with three <img> tags, all
   logos. Ratio is locked to the plate's own 40:21 so the reserved box
   matches what loads and nothing shifts underneath the reader. */
.ag-art__lead{margin:1.75rem 0 2rem;}
.ag-art__lead img{display:block;width:100%;height:auto;aspect-ratio:40/21;object-fit:cover;border-radius:.5rem;background:#edebe5;}
.ag-art__leadcap{margin-top:.6rem;font-size:.8125rem;line-height:1.45;color:var(--ag-muted,#6b7280);letter-spacing:.01em;}
@media (max-width:640px){.ag-art__lead{margin:1.25rem -1rem 1.5rem;}.ag-art__lead img{border-radius:0;}.ag-art__leadcap{padding:0 1rem;}}

.ag-byline {
    display: flex;
    align-items: center;
    gap: 11px;
    flex-wrap: wrap;
    padding: 13px 0;
    border-top: var(--ag-border-hairline);
    border-bottom: var(--ag-border-hairline);
    font-size: 13px;
    color: var(--ag-slate-600);
}
.ag-byline__av {
    display: grid;
    place-items: center;
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--ag-navy-900);
    color: var(--ag-white);
    font-size: 11.5px;
    font-weight: 700;
}
.ag-byline__author { color: var(--ag-slate-600); text-decoration: none; }
.ag-byline__author:hover { text-decoration: underline; }
.ag-byline__sep { width: 3px; height: 3px; border-radius: 50%; background: var(--ag-slate-300); }
.ag-byline__meth { margin-left: auto; font-size: 12.5px; }

/* Body. Serif measure, with the margin rule that marks a tracked claim. */
.ag-art__body {
    position: relative;
    font-family: var(--ag-font-serif);
    font-size: 17px;
    line-height: 1.75;
    color: var(--ag-navy-800);
}
.ag-art__body p { margin: 0 0 1.2em; }
.ag-art__body .tracked { position: relative; }
.ag-art__body .tracked::before {
    content: "";
    position: absolute;
    left: -22px;
    top: .45em;
    bottom: .45em;
    width: 2px;
    border-radius: 2px;
    background: var(--ag-slate-300);
}
.ag-art__body .tracked.d::before { background: var(--ag-accent-600); }

.ag-art__body .mi,
.ag-art__body .market-impact {
    margin: 30px 0;
    padding: 18px 22px;
    border: var(--ag-border-hairline);
    border-left: 3px solid var(--ag-navy-900);
    border-radius: 0 var(--ag-radius-md) var(--ag-radius-md) 0;
    background: var(--ag-white);
}
.ag-art__body .mi .l,
.ag-art__body .market-impact .l {
    display: block;
    margin-bottom: 7px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-art__body .mi p,
.ag-art__body .market-impact p {
    margin: 0;
    font-family: var(--ag-font-serif);
    font-size: 16.5px;
    line-height: 1.65;
    color: var(--ag-slate-700);
}

/* Rail */
.ag-art__side { position: sticky; top: 110px; display: flex; flex-direction: column; gap: 22px; }
.ag-art__side .ag-card {
    padding: 18px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    background: var(--ag-white);
}
.ag-art__side .ag-card h3 {
    margin: 0 0 13px;
    font-family: var(--ag-font-sans);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-card__kv {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px dashed var(--ag-slate-200);
    font-size: 13.5px;
}
.ag-card__kv:last-child { border-bottom: 0; }
.ag-card__kv b { font-family: var(--ag-font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.ag-card__meth { margin: 0; font-size: 13px; line-height: 1.6; color: var(--ag-slate-600); }
.ag-card--rel a {
    display: block;
    margin-bottom: 5px;
    font-family: var(--ag-font-serif);
    font-size: 15.5px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ag-navy-900);
    text-decoration: none;
}
.ag-card--rel a:hover { text-decoration: underline; }
.ag-card__m { display: block; margin-bottom: 14px; font-size: 12px; color: var(--ag-slate-500); }

@media (max-width: 1000px) {
    .ag-art-grid { grid-template-columns: 1fr; gap: 34px; }
    .ag-art-col { max-width: none; }
    .ag-art__side { position: static; }
}
@media (max-width: 640px) {
    .ag-art__title { font-size: 28px; }
    .ag-art__dek { font-size: 17px; }
    /* the margin rule would sit off-screen at this width */
    .ag-art__body .tracked::before { display: none; }
}

/* ------------------------------------------------------------------
   style.css sets `html, body { overflow-x: hidden }`. That quietly makes
   both elements scroll containers, which disables position:sticky for
   every descendant — measured: the article rail scrolled away (top 154 ->
   -1346) where the mockup's pins at 110.

   `clip` clips on the same axis WITHOUT creating a scroll container, so
   sticky survives. Behind @supports so anything without clip keeps the
   old hidden behaviour rather than losing the clipping entirely.
   ------------------------------------------------------------------ */
@supports (overflow-x: clip) {
    html,
    body { overflow-x: clip; }
}

/* ------------------------------------------------------------------
   Editorial links are not blue in the mockups.
   ------------------------------------------------------------------
   style.css sets `a { color: var(--ag-accent-700) }` globally, so every
   in-body and in-claim link rendered accent blue. The mockups override
   that everywhere editorial text appears — .vst a, .hl a, .crow p a,
   .num h3 a — with color:inherit plus a slate underline, so a link reads
   as part of the sentence rather than a UI control. Accent is kept for
   hover and for genuine CTAs.
   ------------------------------------------------------------------ */
.ag-art__body a,
.ag-vclaim__st a,
.ag-vstrip .ag-vclaim a {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid var(--ag-slate-300);
}
.ag-art__body a:hover,
.ag-vclaim__st a:hover,
.ag-vstrip .ag-vclaim a:hover {
    color: var(--ag-accent-700);
    border-bottom-color: var(--ag-accent-600);
}

/* ------------------------------------------------------------------
   Article CTA links: blue, as the mockup draws them.
   ------------------------------------------------------------------
   Tailwind Preflight prints last and carries `a { color: inherit }` —
   deliberate, per the handover, so headlines inherit ink instead of
   turning link-coloured. The side effect is that any anchor without its
   own colour rule inherits its parent instead: "How we verify →" picked
   up the byline's slate-600 and "Read the methodology →" the card's, when
   the mockup renders both accent.
   ------------------------------------------------------------------ */
.ag-byline__meth a,
.ag-card__meth a { color: var(--ag-accent-600); }
.ag-byline__meth a:hover,
.ag-card__meth a:hover { color: var(--ag-accent-700); text-decoration: underline; }

/* ==================================================================
   Claim page — 1:1 with claim-page-mockup.html.
   ================================================================== */
/* .ag-page had no max-width and no padding at all, so the statement ran
   the full 1440px and sat flush against the viewport edge. */
.ag-page { max-width: 1200px; margin: 0 auto; padding: 0 20px; }

.ag-claim__crumbs { padding: 20px 0 0; font-size: 12px; letter-spacing: .02em; color: var(--ag-slate-500); }
.ag-claim__crumbs a { color: var(--ag-slate-600); text-decoration: none; }
.ag-claim__crumbs a:hover { text-decoration: underline; }

.ag-claim {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 48px;
    padding: 0 0 64px;
    align-items: start;
}
.ag-claim__head { padding: 20px 0 0; }
.ag-claim__eyebrow {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-claim__eyebrow .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--ag-slate-300); }

.ag-claim__statement {
    margin: 0 0 18px;
    font-family: var(--ag-font-serif);
    font-size: 34px;
    line-height: 1.22;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--ag-navy-900);
}
.ag-claim__statusline { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 6px; }
.ag-status-gloss { font-size: 13.5px; color: var(--ag-slate-600); max-width: 52ch; }

/* Corroboration meter. Was capped at 420px and padded 16/18. */
.ag-claim__meter .ag-corrob,
.ag-corrob {
    max-width: none;
    margin: 26px 0 0;
    padding: 20px 22px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    background: var(--ag-white);
}
.ag-corrob__label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
/* Was rendering Source Serif 700 18px — a heading, where the mockup makes
   it tabular metadata. This is the corroboration figure, the one number
   the whole page exists to report. */
.ag-corrob__count {
    font-family: var(--ag-font-mono);
    font-size: 13px;
    font-weight: 400;
    color: var(--ag-slate-600);
    font-variant-numeric: tabular-nums;
    letter-spacing: normal;
}
.ag-corrob__pips { display: flex; align-items: center; gap: 6px; }
.ag-corrob__pips .ag-pip,
.ag-claim__meter .ag-pip {
    position: relative;
    flex: 1;
    width: auto;
    height: 8px;
    border-radius: var(--ag-radius-full);
    background: var(--ag-slate-200);
}
/* The filled state needs the same specificity as the base rule above:
   `.ag-corrob__pips .ag-pip` (0,2,0) beats a bare `.ag-pip--on` (0,1,0),
   so every pip rendered empty — on the one component whose entire job is
   showing how much corroboration exists. */
.ag-corrob__pips .ag-pip--on,
.ag-claim__meter .ag-pip--on { background: var(--ag-navy-900); }
.ag-corrob__pips .ag-pip--on.ag-pip--disputed,
.ag-claim__meter .ag-pip--on.ag-pip--disputed { background: var(--ag-accent-600); }
.ag-corrob__pips .ag-pip--on.ag-pip--verified,
.ag-claim__meter .ag-pip--on.ag-pip--verified { background: var(--ag-success-700); }
/* Threshold marker: the hairline showing where verification begins. */
.ag-corrob__pips .ag-pip--threshold::after,
.ag-claim__meter .ag-pip--threshold::after {
    content: "";
    position: absolute;
    right: -4px;
    top: -5px;
    bottom: -5px;
    width: 1px;
    background: var(--ag-slate-400);
}
/* The FOOT is the flex row — note left, threshold right. Flexing the note
   itself pushed its own <b> away from the rest of the sentence, so
   "Cointelegraph" and "is the only independent publisher…" sat at opposite
   ends of the box. */
.ag-corrob__foot {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 12px;
    font-size: 12.5px;
    color: var(--ag-slate-500);
}
.ag-corrob__note { margin: 0; }
.ag-corrob__foot b { color: var(--ag-slate-700); font-weight: 600; }
.ag-claim__threshold-note { color: var(--ag-slate-400); }

/* Mobile status bar (IMPLEMENTATION-BRIEF 5.5). It has no desktop
   counterpart in the mockup and was rendering on every viewport, printing
   "Unproven · 1 of 3 publishers" a second time under the reasoning box. */
.ag-claim__pin { display: none; }
@media (max-width: 700px) {
    .ag-claim__pin {
        position: sticky;
        top: 0;
        z-index: 25;
        display: flex;
        align-items: center;
        gap: 10px;
        margin: 16px 0 0;
        padding: 9px 14px;
        border: var(--ag-border-hairline);
        border-radius: var(--ag-radius-full);
        background: rgba(255, 255, 255, .96);
        font-size: 12.5px;
        color: var(--ag-slate-600);
    }
    .ag-claim__pin-pips { display: flex; gap: 3px; flex: none; }
    .ag-claim__pin-pips span { width: 12px; height: 5px; border-radius: var(--ag-radius-full); background: var(--ag-slate-200); }
    .ag-claim__pin-pips span.on { background: var(--ag-navy-900); }
}

.ag-reason {
    margin-top: 26px;
    padding: 16px 20px;
    border-left: 3px solid var(--ag-slate-300);
    border-radius: 0 var(--ag-radius-md) var(--ag-radius-md) 0;
    background: var(--ag-white);
}
.ag-reason--disputed { border-left-color: var(--ag-accent-600); background: var(--ag-accent-tint-50); }
.ag-reason__lbl {
    display: block;
    margin-bottom: 6px;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-reason p { margin: 0; font-family: var(--ag-font-serif); font-size: 16px; line-height: 1.6; color: var(--ag-slate-700); }
.ag-reason--disputed .ag-reason__lbl { color: var(--ag-accent-700); }

.ag-claim__section { margin-top: 44px; }
.ag-claim__h2 {
    margin: 0 0 6px;
    font-family: var(--ag-font-serif);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--ag-navy-900);
}
.ag-claim__sub { margin: 0 0 20px; max-width: 62ch; font-size: 13.5px; color: var(--ag-slate-600); }

/* Stance group — the repeating unit. Its 2px rule was rendering slate-300
   where the spec makes it navy; that rule is what marks the unit. */
.ag-stance { max-width: none; margin-bottom: 28px; border-top: 2px solid var(--ag-navy-900); }
.ag-stance--contradicts { border-top-color: var(--ag-accent-600); }
.ag-stance--partial { border-top-color: var(--ag-slate-400); }
.ag-stance--echo { border-top-color: var(--ag-slate-300); }
.ag-stance__hd { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding: 12px 0 14px; }
.ag-stance__name { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.ag-stance--supports .ag-stance__name { color: var(--ag-navy-900); }
.ag-stance--contradicts .ag-stance__name { color: var(--ag-accent-700); }
.ag-stance--partial .ag-stance__name,
.ag-stance--echo .ag-stance__name { color: var(--ag-slate-600); }
.ag-stance__who { font-size: 13.5px; color: var(--ag-slate-600); }
.ag-stance__who b { color: var(--ag-navy-900); font-weight: 600; }

.ag-pub {
    margin-bottom: 10px;
    padding: 16px 18px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-md);
    background: var(--ag-white);
}
.ag-pub__top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.ag-pub__name { font-size: 15px; font-weight: 600; }
.ag-pub__name a { color: var(--ag-navy-900); text-decoration: none; }
.ag-pub__name a:hover { text-decoration: underline; }
.ag-pub__trust {
    padding: 2px 7px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-sm);
    font-family: var(--ag-font-mono);
    font-size: 11.5px;
    color: var(--ag-slate-500);
    font-variant-numeric: tabular-nums;
}
.ag-pub__time { margin-left: auto; font-size: 12px; color: var(--ag-slate-500); font-variant-numeric: tabular-nums; }
.ag-excerpt {
    margin: 0;
    padding: 0 0 0 14px;
    border-left: 2px solid var(--ag-slate-200);
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.6;
    color: var(--ag-slate-700);
}
.ag-pub__foot { margin-top: 12px; font-size: 12.5px; }
.ag-feeds summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    list-style: none;
    cursor: pointer;
    font-size: 12.5px;
    color: var(--ag-slate-500);
}
.ag-feeds summary::-webkit-details-marker { display: none; }
.ag-feeds ul { margin: 8px 0 0; padding: 0 0 0 18px; font-family: var(--ag-font-mono); font-size: 12.5px; color: var(--ag-slate-500); }

/* Timeline */
.ag-tl { max-width: none; position: relative; list-style: none; margin: 0; padding: 0; }
.ag-tl::before { content: ""; position: absolute; left: 6px; top: 10px; bottom: 26px; width: 1px; background: var(--ag-slate-200); }
.ag-tl li { position: relative; padding: 0 0 22px 30px; }
.ag-tl__dot { position: absolute; left: 0; top: 4px; width: 13px; height: 13px; border-radius: 50%; background: var(--ag-white); border: 2px solid var(--ag-navy-900); }
.ag-tl__dot--open { border-color: var(--ag-slate-300); border-style: dashed; }
.ag-tl__dot--disputed { border-color: var(--ag-accent-600); }
.ag-tl__dot--verified { border-color: var(--ag-success-700); }
.ag-tl__when { font-family: var(--ag-font-mono); font-size: 12px; color: var(--ag-slate-500); font-variant-numeric: tabular-nums; }
.ag-tl__what { margin: 3px 0; font-size: 14px; font-weight: 600; }
.ag-tl__why { font-size: 13.5px; color: var(--ag-slate-600); }
.ag-tl__pending .ag-tl__what { color: var(--ag-slate-500); font-weight: 500; }

/* Rail */
.ag-side { position: sticky; top: 56px; display: flex; flex-direction: column; gap: 24px; }
.ag-side .ag-card { padding: 18px; border: var(--ag-border-hairline); border-radius: var(--ag-radius-md); background: var(--ag-white); }
.ag-side .ag-card h2 {
    margin: 0 0 14px;
    font-family: var(--ag-font-sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-side .ag-kv { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; border-bottom: 1px dashed var(--ag-slate-200); font-size: 13.5px; }
.ag-side .ag-kv:last-child { border-bottom: 0; }
.ag-side .ag-kv dt { color: var(--ag-slate-600); }
.ag-side .ag-kv dd { margin: 0; font-family: var(--ag-font-mono); font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.ag-ent { display: flex; flex-wrap: wrap; gap: 7px; }
.ag-ent span,
.ag-ent a {
    padding: 4px 11px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-full);
    background: var(--ag-slate-50);
    font-size: 12.5px;
    color: var(--ag-slate-700);
    text-decoration: none;
}
.ag-ent a:hover { border-color: var(--ag-slate-400); }
.ag-related {
    display: block;
    margin-bottom: 6px;
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.35;
    font-weight: 600;
    color: var(--ag-navy-900);
    text-decoration: none;
}
.ag-related:hover { text-decoration: underline; }
.ag-related-meta { font-size: 12px; color: var(--ag-slate-500); }
.ag-method { font-size: 13px; line-height: 1.6; color: var(--ag-slate-600); }
.ag-method a { color: var(--ag-accent-600); font-weight: 500; }
.ag-method a:hover { color: var(--ag-accent-700); text-decoration: underline; }

@media (max-width: 980px) {
    .ag-claim { grid-template-columns: 1fr; gap: 32px; }
    .ag-side { position: static; }
}
@media (max-width: 640px) {
    .ag-claim__statement { font-size: 26px; }
}

/* Overflow marker on the archive meter: the mockup draws threshold-many
   pips and appends "+N" for anything beyond the bar. */
.ag-archive .ag-arow__more {
    font-family: var(--ag-font-mono);
    font-size: 10px;
    color: var(--ag-slate-500);
    align-self: center;
}

/* ==================================================================
   Article verification strip — measured against the mockup's .vstrip.
   ==================================================================
   Nine differences, all of them padding/scale drift: the strip carried
   its own padding instead of letting the head/row/foot own it, the head
   and foot had lost their slate-50 fill, rows had no dividers, and the
   in-strip status badge was rendering as the full-size pill chip from
   the claim page rather than the mockup's compact square badge.
   ================================================================== */
.ag-vstrip { padding: 0; overflow: hidden; }
.ag-vstrip__hd {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: var(--ag-border-hairline);
    background: var(--ag-slate-50);
}
.ag-vstrip__l {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ag-slate-500);
}
.ag-vstrip__count { font-size: 12.5px; color: var(--ag-slate-600); }
.ag-vstrip__n {
    margin-left: auto;
    font-family: var(--ag-font-mono);
    font-size: 12.5px;
    color: var(--ag-slate-600);
}
.ag-vclaim {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) auto;
    gap: 16px;
    align-items: start;
    padding: 14px 18px;
    border-bottom: var(--ag-border-hairline);
}
.ag-vclaim:last-of-type { border-bottom: 0; }
.ag-vclaim:hover { background: var(--ag-slate-50); }
.ag-vclaim__pips { display: flex; gap: 3px; padding-top: 5px; }
.ag-vclaim__pips span { width: 16px; height: 6px; border-radius: var(--ag-radius-full); background: var(--ag-slate-200); }
.ag-vclaim__pips span.on { background: var(--ag-navy-900); }
.ag-vclaim__st {
    margin: 0 0 5px;
    font-size: 15px;
    line-height: 1.5;
    color: var(--ag-navy-800);
}
.ag-vclaim__meta { font-size: 12px; color: var(--ag-slate-500); }
.ag-vstrip__ft {
    padding: 12px 18px;
    border-top: var(--ag-border-hairline);
    background: var(--ag-slate-50);
    font-size: 12.5px;
    color: var(--ag-slate-600);
}

/* In the strip the mockup uses a compact square badge, not the claim
   page's full-size pill. Same state colours, smaller frame. */
.ag-vstrip .ag-status {
    align-self: start;
    margin-top: 2px;
    padding: 3px 8px;
    border-radius: var(--ag-radius-sm);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .03em;
    text-transform: uppercase;
    white-space: nowrap;
}
.ag-vstrip .ag-status__glyph { display: none; }


/* ---------------------------------------------------------------------
   Homepage verification badges (Aug 2026).

   The card meta row already carried a pip meter and a count. The badge
   names the state that count adds up to, and the publisher list names
   who is behind it -- a reader deciding what to trust should not have to
   click through to find out.

   Compact square frame, the same one the article strip uses. The claim
   page's full pill chip is too heavy for an 11.5px meta row, and the
   glyph is dropped because the badge already carries a text label, so
   the state is never communicated by colour alone (WCAG 1.4.1).
   --------------------------------------------------------------------- */
.aghome__m .ag-status,
.aghome__meta .ag-status {
    padding: 2px 7px;
    border-radius: var(--ag-radius-sm);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    line-height: 1.6;
    gap: 0;
}

.aghome__meta .ag-status { font-size: 10.5px; }

.aghome__m .ag-status__glyph,
.aghome__meta .ag-status__glyph { display: none; }

/* Names truncate rather than wrap the meta row onto a third line. */
.aghome__pubs {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* On a card the meta row does not fit on one line once a badge and a
   publisher list are in it, so it breaks on purpose rather than wherever
   the text happens to run out: meter, badge and count on the first line,
   who and when on the second. Left to flex-wrap it broke mid-run and
   stranded a separator at the end of the line above. */
.aghome__m .aghome__pubs { flex-basis: 100%; margin-top: 1px; }


/* ---------------------------------------------------------------------
   Brand mark v4 — the seal.                              (2026-08-07)

   Two variants, and the surface decides which one applies, not taste:

     logo-icon.svg          carries its navy field. White surfaces only —
                            the header, and anything on Slate 100 or lighter.
     logo-icon-onnavy.svg   drops the field. The only correct mark on a navy
                            surface, where a navy field is invisible and the
                            bars end up floating inside a square nobody can
                            see. That was the drawer's problem.

   Dropping the field also costs the mark its optical mass, so the fieldless
   variant is drawn at 7/6 the size: 24 -> 28. That ratio is not arbitrary —
   it puts the bar block (12.5 of the mark's 26 units) exactly on the cap
   height of the 20px wordmark it stands beside.

   border-radius is reset to 0 on the drawer seal: it was rounding a
   rectangle that is now fully transparent, which did nothing except invite
   someone to wonder later why it was there.
   --------------------------------------------------------------------- */
.ag-drawer__seal { width: 28px; height: 28px; border-radius: 0; }

.ag-footer .ag-footer__seal {
    display: block;
    flex: none;
    width: 28px;
    height: 28px;
}

/* ---------------------------------------------------------------------
   Lead image — below the story, and cropped to the generator.  (2026-08-07)

   Two separate faults lived here.

   1. Position. The mockup drew the picture first, above the kicker. On a
      page whose entire promise is corroboration that puts artwork ahead of
      the headline, the publisher count and the verification badge — the
      reader meets the decoration before the evidence. Both card grids
      already went text-only for exactly that reason. The markup now emits
      the picture last, so this rule sets margin-top, not margin-bottom.

   2. Height. The live rule was `height: auto`, so a featured image
      rendered at its full natural height — several hundred pixels in the
      lead column — and shoved everything after it down the page. The box
      is given 1200/630, the exact canvas every featured image is
      generated on: placeholder_image_provider.py (BASE_W, BASE_H), the
      Unsplash path, which upscales onto that canvas, and
      photo_watermark.py (CANVAS_SIZE). Those cards carry a headline, a
      category chip and the wordmark, laid out to be read whole; crop them
      to 16/9 and the wordmark is sliced in half. Match the generator and
      nothing is cut.

   Appended rather than edited in place: these are the same declarations
   the design pass wrote, and a later rule wins on equal specificity
   without removing a line of anyone's work.
   --------------------------------------------------------------------- */
.aghome__lead-im {
    display: block;
    aspect-ratio: 1200 / 630;
    margin-top: 26px;
    margin-bottom: 0;
    overflow: hidden;
    border-radius: var(--ag-radius-md);
    background: var(--ag-slate-200);
}

.aghome__lead-im img {
    width: 100%;
    height: 100%;
    /* contain, not cover: the source already IS the box's ratio, so this
       only guards the case where a future provider hands over something
       else — it letterboxes rather than beheading the picture. */
    object-fit: contain;
    display: block;
    /* The clip belongs to the box now. Leaving the radius on both
       double-rounds the corner against overflow: hidden. */
    border-radius: 0;
}

@media (max-width: 600px) {
    .aghome__lead-im { margin-top: 20px; }
}

/* The corroborated band as row two of the hero's left column.
   Measured before the change: the lead ended at y=853, the sidebar ran to
   y=1585, so 732px of the left column was white. align-items:start is right
   for these two columns -- neither should stretch -- so the fix is to give
   the short column something to carry rather than pad the tall one.
   Behind the mockup's own 960px breakpoint: below that the hero is a single
   column and this section falls back into plain document order. */
@media (min-width: 961px) {
    .aghome__hero > .aghome__side { grid-row: 1 / span 2; }
    .aghome__hero > .aghome__grid--in-hero { grid-column: 1; grid-row: 2; min-width: 0; }
    /* The band is now 772px wide rather than the full 1160px, so the card
       grid has to be told to stop asking for three tracks. */
    .aghome__grid--in-hero .aghome__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The continuation of the corroborated band, below the hero and full width.
   Three across like every other full-width band, so it reads as the same
   band continuing rather than a new one starting. The top padding replaces
   the band header it deliberately does not repeat. */
.aghome__grid--corrob-below { padding-top: 26px; }
.aghome__more--solo { padding: 18px 0 26px; }

/* Lift the corroborated cards level with the Newsroom card beside them.
   Measured: the section carried 34px of top padding and the band label a
   further 40px of margin, so the first story card began at y=1026 while the
   Newsroom card next to it began at y=977 -- the left column read as
   starting lower than the right.
   The 34px is redundant here: this section sits in the hero grid, whose own
   48px gap already separates it from the lead. Dropping that and tightening
   the label margin to 25px removes exactly the 49px of drift.
   The band selector is doubled (.aghome__grid.aghome__grid--in-hero) because
   a single class lost to the existing .ag-band rule on specificity and the
   margin silently stayed at 40px -- 15px of the drift survived the first fix.
   Scoped to --in-hero so the full-width bands below keep their own rhythm. */
@media (min-width: 961px) {
    .aghome__grid--in-hero { padding-top: 0; }
    .aghome__grid.aghome__grid--in-hero .ag-band { margin-top: 25px; }
}

/* Newsroom card and story cards share a grid row, so they align by
   construction rather than by arithmetic.

   The previous approach subtracted padding until the two tops matched. That
   held at exactly one viewport width: the lead headline wraps to a different
   height as the column narrows, so every other width put them back out of
   step -- flush at 1440px, 15px adrift at 1300px.

   Three rows: lead and sidebar, then the band label, then the story cards
   beside the Newsroom card. display:contents dissolves the section wrapper
   so its label and card grid become grid items in their own right; without
   it they are trapped in one cell and cannot occupy separate rows. */
@media (min-width: 961px) {
    .aghome__hero > .aghome__lead { grid-column: 1; grid-row: 1; }
    .aghome__hero > .aghome__side { grid-column: 2; grid-row: 1; }
    .aghome__hero > .aghome__grid--in-hero { display: contents; }
    .aghome__hero .aghome__grid--in-hero > .ag-band { grid-column: 1; grid-row: 2; margin-top: 0; }
    .aghome__hero .aghome__grid--in-hero > .aghome__cards { grid-column: 1; grid-row: 3; margin-top: 0; min-width: 0; }
    .aghome__hero .aghome__grid--in-hero > .ag-empty { grid-column: 1; grid-row: 3; }
    .aghome__hero > .ag-card--newsroom { grid-column: 2; grid-row: 3; }
    /* Row 2 is the label only, so the gap above the cards comes from the
       grid, not from a margin that would push one column and not the other. */
    .aghome__hero { row-gap: 22px; column-gap: 48px; }
}

/* Card badges wear the verification page's pill, at the meta row's scale.

   They were a 10px uppercase square chip with the glyph hidden. The comment
   above explained the reasoning -- a full 13px pill is heavy in an 11.5px
   row -- and that reasoning is sound, so this keeps the constraint and
   changes the shape: pill radius, sentence case, glyph restored, colour and
   spacing from the same component, sized for the row rather than the page.

   Restoring the glyph does not cost the WCAG 1.4.1 argument, which held
   that the badge must not rely on colour alone. The text label was what
   satisfied it and the label is still there; the glyph is now a second,
   redundant carrier of the same state. */
.aghome__m .ag-status,
.aghome__meta .ag-status {
    padding: 3px 10px 3px 8px;
    border-radius: var(--ag-radius-full);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.45;
    gap: 5px;
}

.aghome__meta .ag-status { font-size: 11.5px; }

.aghome__m .ag-status__glyph,
.aghome__meta .ag-status__glyph { display: block; width: 13px; height: 13px; flex: none; }

/* The legend in the how-band is the real chip now, so it needs the row
   spacing the hand-rolled spans used to carry themselves. */
.ag-how__statuses { display: flex; flex-wrap: wrap; gap: 10px; }

/* The status badge in an archive row, at the meta row's scale -- same
   treatment the homepage cards get, for the same reason: the full page
   pill is heavy in a dense list. */
.ag-arow__status { display: inline-flex; }
.ag-arow__meta .ag-status {
    padding: 2px 9px 2px 7px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.45;
    gap: 5px;
}
.ag-arow__meta .ag-status__glyph { width: 12px; height: 12px; flex: none; }

/* The article strip badge, matching the verification page.

   It was the last square uppercase chip with its glyph hidden -- the same
   treatment the homepage cards and archive rows had before, and the same
   fix: pill radius, sentence case, glyph restored, colour and spacing from
   the component itself. The strip is a full-width block rather than a dense
   meta row, so it can carry 12px comfortably, closer to the 13px the
   verification page uses than the 11px the card rows take.

   With this the badge is drawn one way everywhere it appears -- homepage
   cards, archive rows, article strip, the how-band legend and the
   verification page -- so a reader learns the vocabulary once. */
.ag-vstrip .ag-status {
    align-self: start;
    margin-top: 2px;
    padding: 4px 12px 4px 9px;
    border-radius: var(--ag-radius-full);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
    gap: 6px;
}
.ag-vstrip .ag-status__glyph { display: block; width: 14px; height: 14px; flex: none; }

/* Load more, for the corroborated band.

   Deliberately identical to .aghome__more a -- the square control the
   design already uses for this slot. Only the behaviour changed, from
   leaving the page to opening the rest in place, so the control should not
   change with it. It cannot simply join that rule's selector list because
   this is a <button> and that rule is written for <a>, so the values are
   mirrored here and must be kept in step.

   The hover is the design's own (border darkens, text goes to navy) with a
   faint background added, so the state is unmistakable on a control a
   reader is expected to press several times. Text darkens rather than
   lightens: it stays readable through the whole interaction. */
.ag-more__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 22px;
    min-height: 44px;
    line-height: 22px;
    border: var(--ag-border-hairline);
    border-radius: var(--ag-radius-sm);
    background: var(--ag-white);
    color: var(--ag-slate-700);
    font-family: var(--ag-font-sans);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}
.ag-more__btn:hover {
    border-color: var(--ag-slate-300);
    color: var(--ag-navy-900);
    background: var(--ag-slate-50);
}
.ag-more__btn:active { background: var(--ag-slate-100); }
.ag-more__btn:focus-visible { outline: 2px solid var(--ag-blue-600, #2563eb); outline-offset: 2px; }
.ag-more__count { font-variant-numeric: tabular-nums; opacity: .65; font-weight: 500; }
@media (prefers-reduced-motion: reduce) {
    .ag-more__btn { transition: none !important; }
}

/* [hidden] has to be spelled out here.
   The browser's own [hidden] rule is display:none at the lowest possible
   specificity, so any author rule that sets display beats it. Both controls
   sets one -- .ag-more__btn is inline-flex -- so hiding it in JavaScript
   set the attribute and changed nothing on screen. The attribute selector
   outranks it. Found by looking at a screenshot: a property check read
   hidden=true and reported success while the control was plainly still
   there. */
.ag-more__btn[hidden] { display: none; }

/* Collapse the load-more tail at parse time, not after paint.

   ag-more.js is deferred, so hiding the tail in script happened AFTER the
   browser had painted all 58 cards -- the page then lost most of a screen
   of height in one frame. On a throttled phone that was 0.083 CLS of a
   0.177 total, the single largest shift on the page, caused by the feature
   meant to improve it.

   .ag-js is set by an inline script in <head>, so this applies before
   anything paints and the collapsed state is what gets painted first.
   :not([data-ag-more-ready]) hands control to the script the moment it
   initialises; both states are identical, so the handover is invisible.

   There are two blocks with a Load more now -- corroborated opens at 9,
   Latest articles at 15 -- so the selector is keyed on data-ag-more-initial
   rather than matching every [data-ag-more]. A single shared threshold
   would hide cards one block had promised to show, after first paint,
   which is the exact shift this rule exists to prevent.

   Each nth-child threshold MUST equal its data-ag-more-initial + 1 in
   home.php. Change one, change the other, same commit. */
.ag-js [data-ag-more][data-ag-more-initial="9"]:not([data-ag-more-ready]) [data-ag-more-list] > *:nth-child(n+10) {
    display: none;
}

.ag-js [data-ag-more][data-ag-more-initial="15"]:not([data-ag-more-ready]) [data-ag-more-list] > *:nth-child(n+16) {
    display: none;
}

/* Reserve the ticker's width before the prices arrive.

   Each item renders as a dash, then becomes $64,878.00 +0.88% when the
   fetch lands, and every item on the row moves. That was 0.060 CLS at
   2.5s. A min-width holds the space, and tabular figures stop the number
   itself resizing as digits change. */
.ag-ticker__item { min-width: 148px; }
.ag-ticker__item [data-ticker-price],
.ag-ticker__item [data-ticker-change] { font-variant-numeric: tabular-nums; }

/* ===================================================================
   THE WIRE — /wire/

   A departures board. The visual job is that a row reads as a PERSISTENT
   object which changes, not as an item in a stream: fixed columns, aligned
   numbers, no card chrome. Cards imply arrival; rows imply standing.

   The publisher count is the hero and is set in the mono face at a size
   nothing else on the page uses, because it is the one number a reader is
   here to watch move.
   =================================================================== */

.ag-wire {
    /* No width, no padding. Both belong to the shared wrappers this template
       now uses -- .ag-container for width, .page-content-wrap for the bottom
       gap, the global #content rule for the top. This block previously set
       max-width: 1000px and its own padding, which is why the page looked
       like it belonged to a different site while every font matched. */
}




/* The connection indicator. A board that has quietly lost its stream looks
   identical to a quiet night, so this is load-bearing rather than
   decorative -- it is the only way a reader can tell the difference. */
.ag-wire__status {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--ag-font-mono);
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ag-data-gray);
    margin: var(--ag-space-4) 0 0;
}

.ag-wire__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--ag-outline);
    flex: none;
}

.ag-wire__status[data-state="live"] .ag-wire__dot {
    background: #16a34a;
    animation: ag-wire-pulse 2.4s ease-in-out infinite;
}

.ag-wire__status[data-state="reconnecting"] .ag-wire__dot,
.ag-wire__status[data-state="polling"] .ag-wire__dot { background: #d97706; }
.ag-wire__status[data-state="down"] .ag-wire__dot { background: #dc2626; }

@keyframes ag-wire-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.35; }
}

.ag-wire__board {
    margin-top: var(--ag-space-6);
    border-top: 1px solid var(--ag-outline-variant);
}

.ag-wire__row {
    display: grid;
    grid-template-columns: 1fr 130px 120px 92px;
    gap: var(--ag-space-4);
    align-items: baseline;
    padding: 14px 0;
    border-bottom: 1px solid var(--ag-outline-variant);
}

.ag-wire__row--head {
    font-family: var(--ag-font-sans);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ag-data-gray);
    padding: 10px 0;
}

.ag-wire__headline {
    font-family: var(--ag-font-serif);
    font-size: 17px;
    line-height: 1.35;
    color: var(--ag-ink);
    display: block;
}

a.ag-wire__headline:hover { color: var(--ag-accent-700); }

.ag-wire__outlets {
    display: block;
    font-family: var(--ag-font-mono);
    font-size: 11px;
    color: var(--ag-data-gray);
    margin-top: 5px;
}

/* The number the page exists for. */
.ag-wire__pubs {
    font-family: var(--ag-font-mono);
    font-size: 12px;
    color: var(--ag-data-gray);
    white-space: nowrap;
}

.ag-wire__pubs b {
    font-size: 22px;
    font-weight: 500;
    color: var(--ag-ink);
    margin-right: 4px;
}

/* "+3", for two minutes after a row changes. Long enough that a reader who
   glances back still sees why the row is highlighted; short enough that the
   board is not permanently covered in badges. */
.ag-wire__delta {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    background: #dcfce7;
    color: #15803d;
    font-size: 11px;
    font-weight: 600;
}

.ag-wire__chip {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px;
    border-radius: 999px;
    border: 1px solid var(--ag-outline-variant);
    font-family: var(--ag-font-sans);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

.ag-wire__chip--new        { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }
.ag-wire__chip--developing { background: #fefce8; border-color: #fde68a; color: #a16207; }
.ag-wire__chip--verified   { background: #f0fdf4; border-color: #bbf7d0; color: #15803d; }
.ag-wire__chip--unproven   { background: var(--ag-surface); color: var(--ag-on-surface-variant); }
.ag-wire__chip--disputed   { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }

/* The ageing clock. Tabular figures so a row does not jiggle sideways every
   time a minute rolls over -- the number changes, the layout must not. */
.ag-wire__age {
    font-family: var(--ag-font-mono);
    font-size: 13px;
    color: var(--ag-data-gray);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* The row changed. A brief wash rather than a flash: the reader may be
   looking somewhere else on the board, and a two-second highlight is still
   there when their eye arrives. */
.ag-wire__row.is-changed {
    animation: ag-wire-flash 2.2s ease-out 1;
}

@keyframes ag-wire-flash {
    0%   { background: #dcfce7; }
    100% { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .ag-wire__row.is-changed { animation: none; background: #f0fdf4; }
    .ag-wire__status[data-state="live"] .ag-wire__dot { animation: none; }
}

.ag-wire__empty,
.ag-wire__foot {
    font-family: var(--ag-font-sans);
    font-size: 13px;
    line-height: 1.6;
    color: var(--ag-on-surface-variant);
    padding: var(--ag-space-6) 0;
}

.ag-wire__foot { border-top: 1px solid var(--ag-outline-variant); margin-top: var(--ag-space-2); }

/* Below 720 the four columns stop being a table and become a stacked block.
   The count and the clock stay on one line together, because the whole
   proposition of the page is those two numbers side by side. */
@media (max-width: 720px) {
    .ag-wire__row {
        grid-template-columns: 1fr auto;
        gap: 6px 12px;
        padding: 16px 0;
    }
    .ag-wire__row--head { display: none; }
    .ag-wire__story { grid-column: 1 / -1; }
    .ag-wire__pubs { grid-column: 1; }
    .ag-wire__status-cell { grid-column: 1; }
    .ag-wire__age { grid-column: 2; grid-row: 2 / 4; align-self: center; }
    .ag-wire__headline { font-size: 16px; }
}

/* A row that has just arrived. Deliberately quieter than .is-changed: an
   arrival is announced by being new at the top of the board, where a count
   that moved has to catch the eye somewhere down the page. */
.ag-wire__row.is-added {
    animation: ag-wire-arrive 2.6s ease-out 1;
}

@keyframes ag-wire-arrive {
    0%   { background: #eff6ff; opacity: 0.35; }
    100% { background: transparent; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .ag-wire__row.is-added { animation: none; }
}

/* The Wire's nav entry. A small live dot, because the item points at
   something that is happening rather than something that was published --
   the same signal the page itself uses for its connection state. */
.ag-nav__livedot {
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 6px;
    border-radius: 50%;
    background: #16a34a;
    vertical-align: middle;
}

.ag-nav__live { white-space: nowrap; }

.ag-drawer__live { display: block; }

@media (prefers-reduced-motion: no-preference) {
    .ag-nav__livedot { animation: ag-wire-pulse 2.4s ease-in-out infinite; }
}

/* ===================================================================
   DISPUTE REPORTS — the body of a Disputed / False article.

   Deliberately not article typography. A reader arriving at a page badged
   Disputed is not here to read; they are here to compare. So the two
   accounts sit as parallel blocks with the outlet's name attached to its
   own words, and the eye can run down the left edge and see where the
   reports part company without reading a sentence of ours.

   Written by backend/app/services/dispute_report/service.py: render_html().
   =================================================================== */

.ag-dispute__standfirst {
    font-family: var(--ag-font-sans);
    font-size: 18px;
    line-height: 1.55;
    color: var(--ag-on-surface-variant);
    margin: 0 0 var(--ag-space-6);
}

.ag-dispute h2 {
    font-family: var(--ag-font-sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ag-data-gray);
    margin: var(--ag-space-6) 0 var(--ag-space-3);
    padding-bottom: 6px;
    border-bottom: 1px solid var(--ag-outline-variant);
}

.ag-dispute__agreed ul,
.ag-dispute__confirmed ul { margin: 0; padding-left: 20px; }

.ag-dispute__agreed li,
.ag-dispute__confirmed li {
    font-family: var(--ag-font-sans);
    font-size: 16px;
    line-height: 1.6;
    margin-bottom: 8px;
    color: var(--ag-ink);
}

.ag-dispute__point { margin: var(--ag-space-5) 0 var(--ag-space-6); }

.ag-dispute__point h3 {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-family: var(--ag-font-serif);
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ag-ink);
    margin: 0 0 var(--ag-space-3);
}

.ag-dispute__n {
    flex: none;
    font-family: var(--ag-font-mono);
    font-size: 12px;
    color: var(--ag-accent-700);
}

/* Each side's own words. The left rule is what makes two of these read as a
   comparison rather than as a pull-quote. */
.ag-dispute__pos {
    margin: 0 0 12px;
    padding: 12px 16px;
    border-left: 3px solid var(--ag-outline-variant);
    background: var(--ag-surface);
    border-radius: 0 var(--ag-radius-md) var(--ag-radius-md) 0;
}

.ag-dispute__pos p {
    font-family: var(--ag-font-serif);
    font-size: 16px;
    line-height: 1.55;
    color: var(--ag-ink);
    margin: 0 0 6px;
}

.ag-dispute__pos cite {
    display: block;
    font-family: var(--ag-font-mono);
    font-size: 11px;
    font-style: normal;
    color: var(--ag-data-gray);
}

.ag-dispute__pos cite a { color: var(--ag-accent-700); text-decoration: none; }
.ag-dispute__pos cite a:hover { text-decoration: underline; }
.ag-dispute__pos cite time { margin-left: 8px; }

/* The most useful line on the page: what would actually settle it. */
.ag-dispute__resolve {
    font-family: var(--ag-font-sans);
    font-size: 14px;
    line-height: 1.55;
    color: var(--ag-on-surface-variant);
    margin: 10px 0 0;
    padding: 10px 14px;
    border: 1px dashed var(--ag-outline-variant);
    border-radius: var(--ag-radius-md);
}

.ag-dispute__resolve b { color: var(--ag-ink); }

.ag-dispute__guidance p {
    font-family: var(--ag-font-sans);
    font-size: 16px;
    line-height: 1.65;
    color: var(--ag-ink);
    margin: 0;
}

@media (max-width: 720px) {
    .ag-dispute__standfirst { font-size: 16px; }
    .ag-dispute__point h3 { font-size: 18px; }
    .ag-dispute__pos { padding: 10px 12px; }
}
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],input:where(:not([type])),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-width:1px;border-radius:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5rem;--tw-shadow:0 0 #0000}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,input:where(:not([type])):focus,select:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-color:#2563eb}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-top:0;padding-bottom:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size="1"])){background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;flex-shrink:0;height:1rem;width:1rem;color:#2563eb;background-color:#fff;border-color:#6b7280;border-width:1px;--tw-shadow:0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0'/%3E%3C/svg%3E")}@media (forced-colors:active) {[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}@media (forced-colors:active) {[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=radio]:checked:focus,[type=radio]:checked:hover{border-color:transparent;background-color:currentColor}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media (forced-colors:active) {[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{border-color:transparent;background-color:currentColor}[type=file]{background:unset;border-color:inherit;border-width:0;border-radius:0;padding:0;font-size:unset;line-height:inherit}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.block{display:block}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.min-h-screen{min-height:100vh}.grow{flex-grow:1}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.gap-3{gap:.75rem}.gap-x-gutter{-moz-column-gap:24px;column-gap:24px}.gap-y-8{row-gap:2rem}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-transparent{border-color:transparent}.bg-surface\/50{background-color:rgba(248,250,252,.5)}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-3{padding:.75rem}.font-body-md{font-family:Inter}.font-headline-md{font-family:"Source Serif 4"}.font-label-caps{font-family:Inter}.text-label-caps{font-size:12px;line-height:16px;letter-spacing:.05em;font-weight:600}.text-size-20{font-size:20px}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.leading-\[28px\]{line-height:28px}.tracking-wider{letter-spacing:.05em}.text-\[Npx\]{color:Npx}.text-\[var\(--ag-accent-700\)\]{color:var(--ag-accent-700)}.text-ink{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.hover\:border-outline-variant\/30:hover{border-color:rgba(203,213,225,.3)}@media (min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}