/*
 * FinanceProspector — Homepage Hero
 * Component: FP-C-002 — Homepage Hero
 * Version:   v2.9 (Phase 2 — Responsive production: tablet + mobile)
 * Reference: Approved Hero reference (production)
 * --------------------------------------------------------
 * PHASE 2 — RESPONSIVE PRODUCTION
 *
 * BREAKPOINTS:
 *   Desktop (≥ 1024px): 2-column grid. Unchanged from Phase 1.
 *   Tablet  (640–1023px): Stacked 1-column. Max-width 800px centered.
 *   Mobile  (< 640px):   Stacked 1-column. Full-width with 20px margins.
 *
 * TYPOGRAPHY SCALE (Typography System v2.0):
 *   Headline:   56px desktop / 44px tablet / 36px mobile
 *   Card title: 28px desktop / 24px tablet / 22px mobile
 *   Hero body:  18px desktop / 16px tablet / 16px mobile
 *   Card desc:  16px desktop / 16px tablet / 15px mobile
 *
 * SPACING SCALE (Responsive Spacing Matrix):
 *   Section top:    96px desktop / 64px tablet / 48px mobile
 *   Section bottom: 80px desktop / 56px tablet / 40px mobile
 *   Column gap:     64px desktop / 48px tablet (stacked) / 32px mobile
 *   Card padding:   32px desktop / 24px tablet / 20px mobile
 *   Side margins:   32px desktop / 24px tablet / 20px mobile
 *
 * RATINGS TABLE (mobile):
 *   Qualifier column hidden on mobile to prevent horizontal overflow.
 *   Label column: white-space: normal; font-size: 12px; wraps to 2 lines.
 *   Table-layout: fixed; explicit column proportions.
 *
 * Desktop typography (Typography System v2.0 exact values):
 *
 *   Hero Headline (Display XL):  56px / 700 / 1.10 / -0.03em
 *   Card Title (Heading M):      28px / 600 / 1.25 / -0.01em
 *   Hero Body (Body L):          18px / 400 / 1.60
 *   Card Desc (Body M):          16px / 400 / 1.65
 *   Rating label (Body S):       14px / 600 / 1.55
 *   Rating score:                14px / 700
 *   Qualifier (Caption):         13px / 600 / 1.50
 *
 * Desktop spacing (Responsive Spacing Matrix):
 *   Section padding: 128px
 *   Column gap:       64px
 *   Card padding:     32px
 *   Side margins:     32px
 */

/* ── GeneratePress Integration ────────────────────────────
 * Front-page-specific overrides for GeneratePress defaults.
 * Scoped to .home — the body class WordPress assigns when
 * is_front_page() is true (static front page setting).
 * ───────────────────────────────────────────────────────── */

/*
 * Remove the gap between the site header and the Hero section.
 * GeneratePress adds a bottom margin to .site-header by default.
 * The Hero's own top padding (128px) provides all needed breathing room.
 *
 * Note: .entry-title and .entry-header suppression was previously
 * handled here via CSS. These rules are superseded by front-page.php,
 * which calls only get_header() + get_footer() and therefore never
 * renders the content loop, entry-header, or entry-title at all.
 */
.home .site-header {
    margin-bottom: 0;
}


/* ── GenerateBlocks Resets (retained; now dead selectors) ─ */
/*
 * These selectors targeted GB-specific classes (.gb-container etc.)
 * and are now unused after migrating the Hero pattern to core blocks
 * (core/group, core/heading, core/paragraph) in v1.2.
 * Retained for reference. Safe to remove in a future cleanup pass.
 */
.fp-hero.gb-container {
    max-width: none;
    width: 100%;
    padding: 0;
    margin: 0;
}

.fp-hero__container.gb-container {
    display: grid;
    flex-direction: unset;
}

.fp-hero__left.gb-container,
.fp-hero__right.gb-container {
    display: block;
    flex-direction: unset;
}

.fp-editorial-card.gb-container {
    display: block;
    flex-direction: unset;
}

.fp-hero .gb-headline,
.fp-hero .gb-text {
    margin: 0;
    padding: 0;
}

/* ── Section Shell ────────────────────────────────────── */
.fp-hero {
    display: block;                       /* override inherited flex-child behaviour from GP's #page wrapper */
    background-color: var(--fp-color-white);
    padding-top:    var(--fp-space-xxxl);  /* 96px  — reduced from 128px */
    /* Bottom half of the standard section gap: 128 - 32 top on the next
       section = 96px. See --fp-section-gap-desktop in base.css. */
    padding-left:  0;
    padding-right: 0;
    width: 100%;
    box-sizing: border-box;
    /* ⚠ Governed major-section gap (v3.54.2): the bottom half, 48px from 640 up
       and 32px below. padding-TOP above is the approved header → hero distance
       (96 / 64 / 48) and is UNTOUCHED — a different boundary with its own value.
       See explore-by-category.css for why this is a padding and not a margin. */
    padding-bottom: calc(var(--fp-section-gap) - var(--fp-space-l));
}

/* ── Inner Grid Container ─────────────────────────────── */
.fp-hero__container {
    display: grid;
    grid-template-columns: 49fr 51fr;      /* staging test: right col wider per reference */
    gap: var(--fp-space-xxl);              /* 64px column gap */
    align-items: center;
    width: 100%;                           /* fill the section shell */
    max-width: 1500px;                     /* Hero-only override; --fp-container-max-width (1200px) unchanged */
    margin: 0 auto;
    padding: 0 var(--fp-margin-desktop);   /* 32px side margins */
    box-sizing: border-box;                /* padding does not add to declared width */
}

/* ── Left Column ──────────────────────────────────────── */
.fp-hero__left {
    min-width: 0;     /* grid items default to min-width:auto; override so the column can shrink */
    /* max-width removed: at 1500px container / 49fr the column is ~672px;
       keeping 620px here would prevent "Choose with Confidence." from
       fitting on one line (needs ~664px). Grid proportions now control width. */
}

/* ── Hero Headline — Display XL (56px / 700 / 1.10) ──── */
.fp-hero__headline {
    font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont,
                 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 56px;
    font-weight: 700;
    line-height: 1.10;
    letter-spacing: -0.03em;
    color: var(--fp-color-navy);
    margin: 0 0 var(--fp-space-m);   /* 24px */
}

/* Second headline line — green, forced to its own line */
.fp-hero__headline-green {
    display: block;
    color: var(--fp-color-hero-heading);   /* v3.57.140 (owner, 2026-10-26): Dark Green #338E39. Was --fp-color-green #42B649 */
}

/* ── Hero Body — Body L (18px / 400 / 1.60) ──────────── */
.fp-hero__body {
    font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont,
                 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 18px;
    font-weight: 400;
    line-height: 1.60;
    color: var(--fp-color-gray-500);
    margin: 0 0 var(--fp-space-l);   /* 32px */
    max-width: 520px;
}

/* ── Trust Statement ──────────────────────────────────── */
.fp-hero__trust {
    display: flex;
    align-items: center;
    gap: 12px;
}

.fp-hero__trust-icon {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: block;
}

.fp-hero__trust-text {
    font-size: var(--fp-font-body-m);   /* 16px */
    font-weight: var(--fp-weight-body);
    line-height: 1.50;
    color: var(--fp-color-gray-500);   /* v3.57.142 - owner-approved homepage colour (2026-10-27) */
    margin: 0;
}

/* "trusted" — green emphasis */
.fp-hero__trust-highlight {
    color: var(--fp-color-green);
    font-weight: var(--fp-weight-medium);
}

/* ── Right Column ─────────────────────────────────────── */
.fp-hero__right {
    min-width: 0;     /* same as left: allow the column to shrink; prevents table overflow from blowing out the column */
    width: 100%;
}

/* ── Editorial Framework Card ─────────────────────────── */
.fp-editorial-card {
    width: 100%;                           /* fill the right grid column */
    box-sizing: border-box;                /* padding and border included in width */
    background-color: var(--fp-color-white);
    border: 1px solid var(--fp-color-gray-200);
    border-radius: var(--fp-radius-card);   /* 12px */
    padding: var(--fp-space-l);             /* 32px */
    box-shadow: var(--fp-shadow-1);
}

/* ── Card Title — Heading M (28px / 600 / 1.25) ─────── */
.fp-editorial-card__title {
    font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont,
                 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 28px;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.01em;
    color: var(--fp-color-navy);
    text-align: center;              /* Heading centred within the card. Set on
                                        the base rule only: the 640-1023 and
                                        <640 title rules change font-size and
                                        margin alone, so the alignment inherits
                                        to every breakpoint from here. */
    margin: 0 0 var(--fp-space-s);   /* 16px */
}

/* ── Card Description — Body M (16px / 400 / 1.65) ───── */
.fp-editorial-card__desc {
    font-size: 16px;
    font-weight: 400;
    line-height: 1.65;
    color: var(--fp-color-gray-500);
    margin: 0 0 var(--fp-space-m);   /* 24px */
}

/* ── Ratings Table ────────────────────────────────────── */
.fp-ratings {
    width: 100%;
    border-collapse: collapse;
    border: 0;
    margin: 0;
}

/* Remove all table grid lines while preserving spacing and alignment. */
.fp-editorial-card .fp-ratings,
.fp-editorial-card .fp-ratings th,
.fp-editorial-card .fp-ratings td {
    border: 0;
}

/* Visually hidden table headers — accessible to screen readers */
.fp-ratings thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.fp-rating-row td {
    padding: 12px 0;   /* Final desktop polish: 12px vertical */
    border: 0;
    vertical-align: middle;
}

/* Rating label — Body S (14px / 600 / 1.55) */
.fp-rating-row__label {
    font-size: 14px;
    font-weight: 600;
    line-height: 1.55;
    color: var(--fp-color-navy);
    padding-right: var(--fp-space-s);   /* 16px gap to score */
}

/*
 * Score-to-star gap — specificity correction.
 *
 * `.fp-rating-row td { padding: 12px 0; }` above has specificity (0,1,1)
 * and therefore outranks the (0,1,0) `.fp-rating-row__score` rule below,
 * so its `padding-right: 8px` never applied and the computed value was 0.
 * That is why the ratings rendered as "4.7*" with no separation.
 *
 * This rule targets the same <td> at specificity (0,2,1) so the intended
 * 8px gap takes effect. Only `padding-right` is declared — the 12px
 * vertical padding continues to come from the `td` rule above, so row
 * heights and vertical rhythm are untouched. No other property is set.
 */
.fp-rating-row td.fp-rating-row__score {
    padding-right: var(--fp-space-xs);   /* 8px — numeric score to first star */
}

/* Numeric score — 14px / 700 */
.fp-rating-row__score {
    font-size: 14px;
    font-weight: 700;
    color: var(--fp-color-navy);
    text-align: right;
    padding-right: var(--fp-space-xs);   /* 8px */
    white-space: nowrap;
}

/*
 * FinanceProspector row — pale-green surface. This tint plus the green stars
 * are what differentiate the proprietary score; the number itself uses the
 * same navy typography as the community rows.
 */
.fp-rating-row--editorial td {
    /* Pale Green #D5EFD7 — Illustration Palette v1.1 shading/soft-fill value,
       replacing the uncontrolled derived tint rgba(66,182,73,0.08) (#F0F9F0).
       Real-page verified: row stays continuous, zero layout change. */
    background-color: #D5EFD7;
}

/*
 * FinanceProspector Editorial Score — proprietary 10-point scale.
 * The numeric value is navy and uses the SAME size and weight as the G2,
 * Capterra and Trustpilot numbers, so the proprietary score is not visually
 * ranked above the community ratings. The green now lives only in the stars.
 * The /10 denominator matches the number exactly in size and weight.
 */
/* Denominator on every row — /10 for the editorial score, /5 for the
   community ratings. Inherits size, weight and colour from the score cell so
   the complete numeric expression is one consistent treatment. */
.fp-rating-row__denominator {
    font-size: inherit;
    font-weight: inherit;
    color: inherit;
}

/* FINANCEPROSPECTOR EDITORIAL SCORE — CANONICAL COLOUR RULE.
   ⚠ SCOPED TO THE EDITORIAL ROW ONLY. .fp-rating-row__score is shared by all
   four rows of this table; the other three are G2, Capterra and Trustpilot
   community ratings and MUST stay navy. Recolouring the bare selector would
   turn third-party ratings green. The denominator inherits, so /10 follows.
   Supersedes the previous navy-score decision. */
.fp-rating-row--editorial .fp-rating-row__score {
    color: var(--fp-color-green);   /* v3.57.140 (owner, 2026-10-26): FinanceProspector score colour Core Green #42B649. Was --fp-color-score-text #15803D */
}

/* Stars column */
.fp-rating-row__stars {
    padding: 12px var(--fp-space-xs);   /* Final desktop polish: 12px 8px */
    white-space: nowrap;
    line-height: 1;
}

/*
 * Stars: the governed FP Star v1.0 rating row lives in base.css (.fp-stars).
 * Accessibility: role="img" + aria-label on the outer span; both star layers
 * are aria-hidden, so screen readers announce only the label. (Until v3.55.7
 * this card used Unicode glyphs drawn by the OS fallback font.)
 */

/* Qualifier — Caption (13px / 600 / 1.50) */
.fp-rating-row__qualifier {
    font-size: 13px;
    font-weight: 600;
    line-height: 1.50;
    text-align: left;                    /* Bring qualifier closer to the stars */
    padding-left: 12px;                 /* Preserve a clear visual gap */
    white-space: nowrap;
}

.fp-rating-row__qualifier--green { color: var(--fp-color-green); }
.fp-rating-row__qualifier--navy  { color: var(--fp-color-navy);  }

/* ── Methodology Link ─────────────────────────────────── */
/*
 * Rendered in template-parts/homepage-hero.php.
 * To update the URL, edit the href in the PHP template.
 * Provisional URL: /editorial-methodology/
 * Update to the live slug before launch.
 */
.fp-editorial-card__methodology {
    margin: 10px 0 0;   /* Final desktop polish: 10px top */
    text-align: right;
}

.fp-editorial-card__methodology a {
    font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont,
                 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 14px;
    font-weight: 500;
    color: var(--fp-color-blue);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    transition: var(--fp-button-transition);
}

/* Shared homepage CTA arrow gap — see --fp-cta-arrow-gap in base.css.
   Replaces gap:4px, which never applied because the arrow was part of the
   link's single text node rather than a separate element. Arrow spacing
   only; Hero layout, typography and colours are unchanged. */
.fp-editorial-card__methodology a .fp-cta-arrow {
    margin-left: var(--fp-cta-arrow-gap);
}

/* The colour is declared explicitly on hover: GeneratePress applies its own
   a:hover colour, which turned this link dark grey on Staging. Bible ch. 54.9
   requires the Text CTA to stay within the blue interaction system. */
.fp-editorial-card__methodology a:hover {
    color: var(--fp-color-blue);
    text-decoration: underline;
}

/* Text CTA states — Bible ch. 54.9. Colour-only; no geometry change.
   :visited must be declared explicitly or the browser default purple
   shows through. */
.fp-editorial-card__methodology a:active {
    color: var(--fp-color-blue-pressed);
}

.fp-editorial-card__methodology a:visited {
    color: var(--fp-color-blue);
}

.fp-editorial-card__methodology a:focus-visible {
    outline: 2px solid var(--fp-color-blue);
    outline-offset: 3px;
    border-radius: 2px;
}

/* ════════════════════════════════════════════════════════
 * PHASE 2 — RESPONSIVE (v2.9)
 * ════════════════════════════════════════════════════════ */


/* ── Tablet: 640px–1023px ─────────────────────────────────
 * Grid collapses from 2-column to 1-column (stacked).
 * Left column content (headline, body, trust) comes first.
 * Right column (editorial card) follows below.
 * Container max-width: 800px, centred — comfortable read width.
 * Card inner at 640px: 592 − 48 = 544px.
 * Card inner at 800px+: 800 − 48 (margin) − 48 (padding) = 704px.
 */
@media (min-width: 640px) and (max-width: 1023px) {

    .fp-hero {
        padding-top:    var(--fp-space-xxl);   /* 64px — reduced from 96px */
        /* 96 gap - 32 top on the next section = 64px. */
    }

    .fp-hero__container {
        grid-template-columns: 1fr;            /* stacked */
        gap: var(--fp-space-xl);               /* 48px between left and right stacks */
        max-width: 800px;                      /* centred; prevents over-wide card */
        padding: 0 var(--fp-margin-tablet);    /* 24px side margins */
    }

    /* ── Headline: Display XL → 44px (tablet) */
    .fp-hero__headline {
        font-size: 44px;
    }

    /* ── Hero body: Body L → Body M at tablet */
    .fp-hero__body {
        font-size: var(--fp-font-body-m);      /* 16px */
        max-width: none;                       /* fills stacked column */
        margin-bottom: var(--fp-space-m);      /* 24px */
    }

    /* ── Editorial card: pad reduced */
    .fp-editorial-card {
        padding: var(--fp-space-m);            /* 24px — from 32px */
    }

    /* ── Card title: Heading M → 24px (tablet) */
    .fp-editorial-card__title {
        font-size: 24px;
    }

    /* ── Card desc: stays Body M (16px) */
    .fp-editorial-card__desc {
        font-size: var(--fp-font-body-m);      /* 16px */
    }
}


/* ── Mobile: < 640px ──────────────────────────────────────
 * Stacked layout. Full content width (viewport − 40px margins).
 * Content width at 390px: 350px. Card inner: 350 − 40 = 310px.
 * All typography reduced for compact screen.
 * Ratings table: qualifier column hidden, label wraps to 2 lines.
 */
@media (max-width: 639px) {

    .fp-hero {
        padding-top:    var(--fp-space-xl);   /* 48px */
        /* 72 gap - 24 top on the next section = 48px. */
    }

    .fp-hero__container {
        grid-template-columns: 1fr;           /* stacked */
        gap: var(--fp-space-l);              /* 32px between left and right stacks */
        padding: 0 var(--fp-margin-mobile);  /* 20px side margins */
        max-width: none;                     /* full viewport width */
    }

    /* ── Headline: 36px — Display M for mobile */
    .fp-hero__headline {
        font-size: 36px;
        margin-bottom: var(--fp-space-s);    /* 16px — tighter on mobile */
    }

    /* ── Hero body: 16px, no max-width, tighter bottom margin */
    .fp-hero__body {
        font-size: var(--fp-font-body-m);    /* 16px */
        max-width: none;
        margin-bottom: var(--fp-space-m);    /* 24px */
    }

    /* ── Trust statement: slightly tighter */
    .fp-hero__trust {
        gap: 10px;
    }

    .fp-hero__trust-icon {
        width: 26px;
        height: 26px;
    }

    /* ── Editorial card: compact padding */
    .fp-editorial-card {
        padding: var(--fp-space-m) 20px;    /* 24px top/bottom, 20px sides */
    }

    /* ── Card title: 22px — Heading S for mobile */
    .fp-editorial-card__title {
        font-size: 22px;
        margin-bottom: var(--fp-space-xs);   /* 8px */
    }

    /* ── Card desc: 15px — slightly reduced */
    .fp-editorial-card__desc {
        font-size: 15px;
        margin-bottom: var(--fp-space-s);    /* 16px */
    }

    /*
     * ── Ratings table — mobile layout ──────────────────────
     * Problem: "FinanceProspector Editorial Score" at 14px with
     *   white-space: nowrap overflows a 302px card interior.
     * Solution: fixed table layout with explicit column proportions.
     *   Label:    55% (≈166px) — wraps to 2 lines at 12px font.
     *   Score:    15% (≈45px)  — "4.7" fits at 14px.
     *   Stars:    30% (≈91px)  — 5 stars at 15px + 1px spacing fits.
     *   Qualifier: hidden — redundant with score + stars on mobile.
     */
    /* Auto layout on mobile. Under table-layout:fixed the browser derives
       column widths from the first row — the visually hidden <thead> — so
       the cell widths were ignored and the columns fell back to equal
       thirds, which could not hold ten star positions. Auto layout sizes
       each column to its content: the stars cell is nowrap and takes exactly
       the width it needs, and the label column absorbs the remainder. */
    /*
     * Below 640px the ratings render as blocks rather than a table. A <tr>
     * kept inside table layout is confined to one column's width, so neither
     * the two-level editorial row nor its full-width tint can work there.
     * Semantics are unaffected — the table roles are preserved in markup and
     * the visually hidden <thead> still provides column headers.
     */
    .fp-ratings,
    .fp-ratings tbody {
        display: block;
        width: 100%;
    }

    /* Grid, not flex-wrap. Flex-wrap made the line breaks EMERGENT: at
       375px the editorial row ran out of room and collapsed to THREE
       levels (label / score / stars+qualifier), and the community rows
       had no shared axes — their scores sat 51px apart at 639px. Grid
       placement declares the structure instead of letting it fall out of
       available width. */
    .fp-rating-row {
        display: grid;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
    }

    .fp-rating-row td {
        display: block;
    }

    /* Community rows: one line, three explicit columns shared by all three
       rows, so their labels, scores and star groups sit on common axes.
       8px gaps, not 12: at 12px the label track drops to 164px against the
       166px "Trustpilot Community Rating" needs at 375px and it would wrap. */
    .fp-rating-row:not(.fp-rating-row--editorial) {
        grid-template-columns: minmax(0, 1fr) auto auto;
        column-gap: 8px;
    }

    .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__label {
        min-width: 0;
    }

    /* ── Narrow phones (< 392px): community rows go two-level ──
     * The longest community label, "Trustpilot Community Rating", needs
     * about 181px in Inter. At 375px the card interior is 293px, which
     * after the score, stars and two 8px gaps leaves the label only 163px —
     * 17px short, so Capterra and Trustpilot wrapped and the three rows
     * ended at uneven 39 / 57 / 57px heights.
     * Reducing the gap cannot recover it: even at a visually unacceptable
     * 2px the label is still 5px short. The width simply is not there.
     *
     * So the community rows take the same deliberate two-level shape the
     * editorial row uses:
     *     line 1   Trustpilot Community Rating
     *     line 2   4.6/5   * * * * *
     * The label gets the full interior — far more than the 181px it needs —
     * and the score and stars sit on shared axes beneath it.
     *
     * The bare threshold is 392px — the track reaches 181px exactly there —
     * but that leaves under 3px of margin, and the projection carries a few
     * pixels of uncertainty. The breakpoint is set at 400px, where the
     * track is 188px against the 181px required: a 7px margin. 399.98px is
     * used so it cannot overlap the 400px-and-above rules on fractional
     * viewports.
     * ──────────────────────────────────────────────────── */
    @media (max-width: 399.98px) {

        /* The row carries the vertical padding; the CELLS are zeroed.
           `.fp-rating-row td { padding: 10px 0 }` applies to every cell, so
           on two levels it was counted twice — 20px of padding on line 1
           plus 20px on line 2 gave 78px rows instead of 61px. */
        .fp-rating-row:not(.fp-rating-row--editorial) {
            grid-template-columns: auto 1fr;
            row-gap: 4px;
            padding: 10px 0;
        }

        .fp-rating-row:not(.fp-rating-row--editorial) td {
            padding: 0;
        }

        .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__label {
            grid-column: 1 / -1;
            grid-row: 1;
        }

        .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__score {
            grid-column: 1;
            grid-row: 2;
        }

        /* Vertical padding zeroed: the stars carry `padding: 10px 4px` in
           the single-line treatment, which on a second level added 20px to
           every community row — 78px instead of 61px. The row's own 10px
           padding already provides the vertical rhythm. */
        .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__stars {
            grid-column: 2;
            grid-row: 2;
            justify-self: start;
            padding: 0 4px 0 0;
        }
    }

    /* Community qualifiers stay hidden on mobile, as before. Needs this
       specificity because `.fp-rating-row td { display: block }` above
       outranks the single-class `.fp-rating-row__qualifier` rule. */
    .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__qualifier {
        display: none;
    }

    .fp-rating-row__label {
        white-space: normal;                 /* allow multi-line wrap */
        font-size: 12px;
    }

    .fp-rating-row__score {
        padding-right: 4px;
        font-size: 13px;
    }

    .fp-rating-row__stars {
        padding: 10px 4px;
        font-size: 13px;                    /* scale stars slightly */
    }

    .fp-rating-row__qualifier {
        display: none;                       /* hidden on mobile — see comment above */
    }

    .fp-rating-row td {
        padding: 10px 0;
    }

    /*
     * MOBILE-ONLY two-level FinanceProspector row (below 640px).
     *
     * Ten readable star positions need ~144px, which is more than a phone
     * column allocation can give alongside the long label and the score.
     * Rather than shrinking the stars or squeezing the shared table columns,
     * the editorial row alone becomes a two-level block:
     *
     *   FinanceProspector Editorial Score        9.0/10
     *   ★★★★★★★★★☆                          Excellent
     *
     * The ten stars stay on ONE continuous line — this is not a two-line
     * star treatment. The community rows keep the standard single-level
     * table layout, and desktop/tablet are untouched.
     */
    .fp-rating-row--editorial {
        /* A 2 x 2 grid: label | score on line 1, stars | qualifier on line 2.
           Grid is safe here because .fp-ratings and tbody are display:block
           in this range, so the rows are block-level and no table column
           algorithm is involved. */
        /* Three columns on row 2: stars take the remainder, then the score
           and the qualifier sit together at the right. Row 1's label spans
           all three. */
        /* Row 2: score | stars | qualifier. The qualifier takes the
           remainder so it sits at the right; score and stars are
           content-sized at the left. Row 1's label spans all three. */
        /* Two columns: score, then stars taking the remainder. Was three
           while the qualifier was visible; with it hidden the third track
           would be dead space. */
        grid-template-columns: auto minmax(0, 1fr);
        column-gap: 12px;
        row-gap: 6px;
        padding: 10px 0;   /* horizontal padding removed: 12px of it indented
                              this row's label, breaking the label axis
                              shared with the three community rows. The tint
                              now spans the full card interior, matching how
                              the other ranges treat it. */
        margin-bottom: 4px;
        border-radius: 6px;
        background-color: var(--fp-color-green-tint);
    }

    /* Cells become flex items; the tint moves to the row so the row-gap does
       not show the card surface through it. */
    .fp-rating-row--editorial td {
        display: block;
        padding: 0;
        background-color: transparent;
    }

    /* Explicit grid placement replaces the order + ::after break hack the
       flex version needed. The ten stars stay on ONE continuous line. */
    .fp-rating-row--editorial .fp-rating-row__label {
        grid-column: 1 / -1;   /* full width: the score no longer shares row 1 */
        grid-row: 1;
        min-width: 0;
    }

    /* Score moves to ROW 2 and sits with the qualifier on the right of the
       star row, so mobile reads:
           row 1   FinanceProspector Editorial Score
           row 2   [stars]            9.0/10  Excellent
       Previously the score sat alone on row 1's right, which left the label
       and score sharing a line and the stars and qualifier sharing another —
       an awkward split of one rating across two levels. */
    .fp-rating-row--editorial .fp-rating-row__score {
        grid-column: 1;
        grid-row: 2;
        justify-self: start;
        align-self: center;
        text-align: left;
        padding-right: var(--fp-space-xs);   /* 8px to the first star */
    }

    /* Order matches the community rows below: numeric score first, then
       stars, then the qualifier. Previously the stars led and the score sat
       to their right, which gave the editorial row a different reading
       order from the three community rows and made it look like special
       treatment rather than the same pattern. */
    .fp-rating-row--editorial .fp-rating-row__stars {
        grid-column: 2;
        grid-row: 2;
        justify-self: start;
        padding: 0;
    }

    /* Hidden on mobile, matching the community rows in this same block. The
       row reads: label / score + stars. Removing it also gives the score and
       stars the full width instead of competing with a third track. */
    .fp-rating-row--editorial .fp-rating-row__qualifier {
        display: none;
    }

    /* Methodology link — right-aligned at every breakpoint */
    /* Right-aligned at every breakpoint so the CTA stays anchored to the
       bottom-right of the card. Previously left-aligned below 640px, which
       was the only breakpoint where it did not match the approved
       placement. */
    .fp-editorial-card__methodology {
        text-align: right;
    }
}

/* ── Provider Review illustration (FP-C-002) ───────────────
 * Added to the left hero column only. Placement and proportions are
 * DERIVED from the approved reference screenshot, anchored on the
 * Editorial Framework card, which appears in both:
 *
 *   reference card width 327px  ->  real card width 669px  =  x2.0459
 *     illustration 132 x 169 in-frame   -> 270px wide rendered
 *     gap illustration-right -> card-left = 30px -> 61px
 *     illustration top = 84px below the card top
 *     copy-right -> card-left = 166px -> 340px, so the copy block
 *       ends about 367px from the column's left edge
 *
 * The copy block is constrained to reproduce that composition. Only the
 * WIDTH changes: wording, font size, weight, colour, line-height and
 * order are untouched. The illustration is absolutely positioned so it
 * never enters the flow and cannot shift the headline, body or trust
 * line, and the Editorial Framework card is unaffected.
 * ──────────────────────────────────────────────────────── */

/* The illustration's positioning context is .fp-hero__lower, NOT the whole
 * column. Anchoring it to the column let it reach into the headline band:
 * the headline renders on two lines in Inter and three in the build
 * harness's wider substitute font, so the column's internal geometry
 * shifts with the font and a bottom-anchored illustration rose into the
 * headline. On Staging that opaque artwork painted over "Choose with
 * Confidence." — it was occlusion, not clipping.
 * Anchoring to the lower block makes headline clearance structural. */
.fp-hero__left {
    position: relative;
}

.fp-hero__lower {
    position: relative;
}

.fp-hero__illustration {
    display: none;   /* desktop two-column composition only */
}

/* Shared: the image always fills its wrapper and keeps its aspect ratio. */
.fp-hero__illustration-img {
    display: block;
    width: 100%;
    height: auto;
}

/* ── Desktop rating rows (>= 1024px) — CARD-WIDTH DRIVEN ──
 * The layout responds to the CARD's usable width, not the viewport. The
 * Editorial Framework card is what actually determines whether a
 * four-column row fits: it is squeezed by the two-column hero, so its
 * interior is only 391px at a 1024px viewport against 603px at 1440px.
 *
 * The previous implementation keyed off the viewport and activated the
 * four-column grid at 1024px, where the fixed tracks reserved 336px of a
 * 391px interior and left the label track at 55px for a label needing
 * 229px. Labels shredded across three lines and cells overlapped.
 *
 * THRESHOLD: 590px usable card width, from measurements taken on Staging
 * with the production Inter font, not from the build harness (which
 * substitutes a font about 24% wider and cannot be trusted for glyph
 * metrics):
 *     "FinanceProspector Editorial Score"  229.43px  (measured)
 *     score + ten stars + "Excellent"      241px
 *     three 16px gaps                       48px
 *     intentional breathing room            60px
 *     -------------------------------------------
 *     raw threshold                        578.43px  -> rounded up to 590
 * Rounded UP deliberately: the compact layout should engage slightly early
 * rather than the four-column grid engaging in a card that is marginally
 * too narrow. That failure mode is what this replaces.
 *
 * Track widths are fixed, never `auto`. Each <tr> is its own grid
 * container, so an `auto` track sizes to THAT ROW's content — the
 * editorial score track measured 49.4px against the community rows' 39.7px
 * and the 1fr label track absorbed the difference, shifting every
 * community column by 9.75px. Fixed tracks give all four rows identical
 * geometry, which is what makes the alignment axes immutable.
 *
 * The pale-green highlight is BACKGROUND ONLY on the editorial row: no
 * padding, no track override, no influence on text position. Carrying it
 * with padding previously indented that row's label by 12px.
 * ──────────────────────────────────────────────────────── */

@media (min-width: 1024px) {

    .fp-editorial-card {
        container-type: inline-size;
    }

    .fp-ratings,
    .fp-ratings tbody {
        display: block;
        width: 100%;
    }

    .fp-rating-row {
        display: grid;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
    }

    /* `td` qualifier required throughout: `.fp-rating-row td` is (0,1,1)
       and silently overrides a bare class at (0,1,0). */
    .fp-rating-row td {
        display: block;
        box-sizing: border-box;
        min-width: 0;
        padding: 12px 0;
        background-color: transparent;
    }

    .fp-rating-row--editorial {
        background-color: var(--fp-color-green-tint);
        border-radius: 6px;
    }

    /* ── COMPACT: card narrower than 590px ──────────────
     * The label takes its own full-width line, so it never competes with
     * the fixed tracks. The rating cluster sits beneath it and still keeps
     * one shared axis per element across all four rows. */
    .fp-rating-row {
        grid-template-columns: 52px 152px minmax(0, 1fr);
        column-gap: 16px;
        row-gap: 2px;
    }

    /* ── Editorial tint hugs its content ──────────────────
     * The compact grid gives the third track minmax(0, 1fr) and the row
     * width: 100%, so the qualifier track absorbed all surplus card width
     * and the pale-green row background stretched with it. Measured on
     * Staging, with "Excellent" always ending at 293.5px:
     *     1199  tint 480.2  trailing 186.7
     *     1280  tint 521.5  trailing 228.0
     *     1300  tint 531.7  trailing 238.2
     *     1360  tint 562.3  trailing 268.8
     * The trailing space GROWS with the card, so this is a compact-mode
     * structural issue, not a 1280-1300 one. Viewport-band patches were
     * rejected: they would have fixed three widths and left 1199 and 1360
     * identical.
     *
     * Only the EDITORIAL row is changed, because only it carries a
     * background. Tracks 1 and 2 stay fixed at 52px and 152px, so the
     * score and star axes do not move; the qualifier track simply stops
     * claiming surplus, and the row stops spanning the card.
     * The community rows are untouched — they have no background, so their
     * width is not visible, and leaving them full-width keeps the shared
     * score and star axes intact.
     *
     * The wide 4-track execution at >=590px card width is unaffected: this
     * rule lives in the compact branch only.
     * ────────────────────────────────────────────────────── */
    .fp-rating-row--editorial {
        grid-template-columns: 52px 152px max-content;
        width: fit-content;
        padding-right: var(--fp-space-m);   /* ~24px after "Excellent" */
    }

    .fp-rating-row td.fp-rating-row__label {
        grid-column: 1 / -1;
        grid-row: 1;
        justify-self: start;
        padding: 12px 0 0;
    }

    .fp-rating-row td.fp-rating-row__score {
        grid-column: 1;
        grid-row: 2;
        justify-self: start;
        padding: 0 0 12px;
    }

    .fp-rating-row td.fp-rating-row__stars {
        grid-column: 2;
        grid-row: 2;
        justify-self: start;
        padding: 0 0 12px;
    }

    .fp-rating-row td.fp-rating-row__qualifier {
        grid-column: 3;
        grid-row: 2;
        justify-self: start;
        text-align: left;
        padding: 0 0 12px;
    }

    /* ── WIDE: card at or above 590px ───────────────────
     * One shared four-column grid. The 1fr label track absorbs all slack,
     * so the label-to-score gap is a consequence of the track system
     * rather than a value tuned on any single element. At the 590px
     * threshold the label track is 282px against the measured 229.43px
     * label — about 52px of breathing room, widening to 65px at 1440. */
    @container (min-width: 590px) {

        .fp-rating-row {
            /* The qualifier track is max-content, not a fixed width:
               "Excellent" is identical in all four rows, so max-content
               resolves the same for each and the axis still holds — while
               sizing correctly in whatever font renders. Score and stars
               MUST stay fixed because their content differs per row. */
            grid-template-columns: minmax(0, 1fr) 52px 152px max-content;
            row-gap: 0;
        }

        .fp-rating-row td.fp-rating-row__label {
            grid-column: 1;
            grid-row: 1;
            padding: 12px 0;
        }

        .fp-rating-row td.fp-rating-row__score     { grid-column: 2; grid-row: 1; padding: 12px 0; }
        .fp-rating-row td.fp-rating-row__stars     { grid-column: 3; grid-row: 1; padding: 12px 0; }
        .fp-rating-row td.fp-rating-row__qualifier { grid-column: 4; grid-row: 1; padding: 12px 0; }
    
    /* ── Restore wide-mode geometry ───────────────────────
     * v3.11.58 added width: fit-content and padding-right to
     * .fp-rating-row--editorial as a BASE rule, described in that changelog
     * as compact-scoped. It was not. This block overrides
     * grid-template-columns but never reset width or padding, so
     * fit-content leaked into wide mode: it collapsed the flexible label
     * track from 293.594px to 229.43px and dragged the whole editorial row
     * 64.164px left of the community rows, breaking the shared score, star
     * and qualifier axes that the four-row wide layout depends on.
     * Measured on Staging: tint 603.1 -> 563, editorial score at 245.4
     * against the community rows' 309.6.
     * These two declarations restore the approved wide execution. Any
     * future wide-mode tint treatment must NOT use row width — see the
     * pseudo-element approach under discussion.
     * ────────────────────────────────────────────────────── */
    .fp-rating-row--editorial {
        width: 100%;
        padding-right: 0;
    }
}
}


/* ── Rating rows 640-767 — EXPLICIT SHARED GRID ───────────
 * This band previously used table-layout: auto, which sized each row's
 * columns from that row's own content. The consequences were structural,
 * not cosmetic:
 *   - the numeric scores never formed a column: the score axis measured a
 *     9.7px spread at every width, exactly the width difference between
 *     "9.0/10" and "4.6/5", because auto layout right-aligned each score
 *     inside a per-row cell;
 *   - the stars sat 8px from the score at every width;
 *   - the label -> score gap swung from 3px to 95px across the band with
 *     nothing anchoring it.
 * A 32px label padding was previously used to force separation. It is
 * REMOVED here rather than stacked on the grid: the grid produces the gap
 * structurally (57px at 670 against the 34px the padding gave), and the
 * padding was also what wrapped the label and grew the hero 22px at 640.
 *
 * Tracks match the system already proven at 768-1023 and >=1024: fixed
 * widths for the three elements whose content differs per row, so all four
 * rows share identical geometry, and max-content for the qualifier, which
 * is safe because "Excellent" is identical in every row.
 *
 * Gaps are 12px, not 16px. At 16px with a 56px score track the label has
 * -1px of slack at 640px in Inter and would wrap, reintroducing the 22px
 * height regression. 12px leaves +15px there while still tripling the
 * score -> stars gap from 8px to 21px.
 * ──────────────────────────────────────────────────────── */

@media (min-width: 640px) and (max-width: 767px) {

    .fp-ratings,
    .fp-ratings tbody {
        display: block;
        width: 100%;
    }

    .fp-rating-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 52px 152px max-content;
        column-gap: 12px;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
    }

    /* `td` qualifier required: `.fp-rating-row td` is (0,1,1) and silently
       overrides a bare class at (0,1,0). */
    .fp-rating-row td {
        display: block;
        box-sizing: border-box;
        min-width: 0;
        padding: 12px 0;
        background-color: transparent;
    }

    .fp-rating-row td.fp-rating-row__label     { justify-self: start; padding-right: 0; }
    .fp-rating-row td.fp-rating-row__score     { justify-self: start; padding-right: 0; }
    .fp-rating-row td.fp-rating-row__stars     { justify-self: start; padding-left: 0; }
    .fp-rating-row td.fp-rating-row__qualifier { justify-self: start; text-align: left; padding-right: 0; }

    /* Tint on the ROW: as grid items the cells shrink to their content, so
       a per-cell background fragments the band. No horizontal padding, or
       it indents this row's label and breaks the label axis. */
    .fp-rating-row--editorial {
        background-color: var(--fp-color-green-tint);
        border-radius: 6px;
    }
}

/* ── Tablet rating rows: explicit grid tracks (768-1023px) ─
 * The four elements — label, numeric score, star group and qualifier — are
 * positioned INDEPENDENTLY, not distributed by table auto-layout.
 *
 * Automatic distribution was the root of the long spacing cycle: every
 * adjustment to one column forced the other three to redistribute, so
 * fixing one gap always broke another. The row is therefore a CSS grid
 * with four explicit tracks, and each element controls its own placement
 * within its track via justify-self. Changing one track no longer moves
 * anything else.
 *
 * Tracks at 834px (702px interior):
 *     label  46.128% ->   0-324   element start-aligned (was 41%, +36px
     *                                 total: two successive +18px steps)
 *     score    7.1%  -> 288-338   element END-aligned, so all four numbers
 *                                 share the 338 right edge
 *     stars   27.5%  -> 338-531   start-aligned, 24px lead
 *     qual    24.4%  -> 531-702   start-aligned, so "Excellent" travels
 *                                 with the cluster rather than pinning to
 *                                 the card edge
 * The rating cluster reads as one group — 24px and 25px internal gaps —
 * with the leftover space falling after it as margin.
 *
 * ALIGNMENT CONTRACT — MANDATORY, VERIFY BEFORE CHANGING ANY TRACK.
 * Independent positioning does NOT mean independent alignment. The tracks
 * exist to control the SPACING BETWEEN columns; the columns themselves
 * must stay in exact vertical alignment on every row:
 *     - all labels share one left edge
 *     - all numeric scores share one right edge (justify-self: end)
 *     - all star groups share one left x
 *     - all "Excellent" labels share one left x
 *     - within a row, all four elements are centred on the row's centre
 *     - the four rows keep an identical height and pitch
 * This holds because the SAME grid template is applied to all four rows —
 * the editorial row overrides only its background, never its tracks. Any
 * future per-row track override would break the contract.
 * Verified programmatically at 834px, not by eye: every horizontal axis
 * measures a 0.000px spread, row heights 0.000px, row pitch 0.001px.
 * ──────────────────────────────────────────────────────── */

@media (min-width: 768px) and (max-width: 1023px) {

    .fp-ratings,
    .fp-ratings tbody {
        display: block;
        width: 100%;
    }

    .fp-rating-row {
        display: grid;
        /* Rating cluster translated +36px from the original 41% track,
           applied as two successive +18px steps. Each step is 2.564% of the
           702px interior at 834px. ONLY the first and last tracks change:
           the label track absorbs the shift and the qualifier track
           releases it, so the score and stars tracks keep their widths and
           the cluster's internal spacing is carried across untouched.
           This is a pure horizontal translation, not a redistribution. */
        grid-template-columns: 46.128% 7.1% 27.5% 19.272%;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
    }

    /* Every rule is qualified with `td`: `.fp-rating-row td` has
       specificity (0,1,1) and silently overrides an unqualified class at
       (0,1,0), which has caught padding rules here repeatedly. */
    .fp-rating-row td {
        display: block;
        box-sizing: border-box;
        padding: 12px 0;
    }

    .fp-rating-row td.fp-rating-row__label {
        justify-self: start;
        min-width: 0;
        padding-right: 0;
    }

    /* LEFT-aligned, not right. All four values must begin on the same
       vertical axis: "9.0/10" is six characters against the community
       rows' five, so right-alignment matched their right edges and left
       "9.0/10" starting ~10px further left than "4.6/5". */
    .fp-rating-row td.fp-rating-row__score {
        justify-self: start;
        text-align: left;
        padding-right: 0;
    }

    .fp-rating-row td.fp-rating-row__stars {
        justify-self: start;
        padding-left: 24px;
    }

    .fp-rating-row td.fp-rating-row__qualifier {
        justify-self: start;
        text-align: left;
        padding-right: 0;
    }

    /* The tint moves from the cells to the ROW. As grid items the cells
       shrink to their content, so a per-cell background no longer spans
       the row and the pale-green band broke into four separate blocks. */
    .fp-rating-row--editorial {
        background-color: var(--fp-color-green-tint);
        border-radius: 6px;
    }

    .fp-rating-row--editorial td {
        background-color: transparent;
    }
}


/* ── Tablet: illustration beside the copy (768-1023px) ─────
 * APPROVED.
 * The stacked tablet layout has no whitespace beside the copy: the body
 * runs the full column at every width. To keep the desktop concept the
 * copy is capped and the illustration occupies the freed column.
 *
 * BELOW 768px the illustration is hidden and the copy returns to full
 * width. At 640px the copy column narrows to ~373px, which pushes the
 * trust statement onto two lines and separates its checkmark from the
 * text — the point at which the illustration costs more than it adds.
 * The base rule (.fp-hero__illustration { display: none }) covers this;
 * no mobile-specific override is needed.
 * ──────────────────────────────────────────────────────── */

@media (min-width: 768px) and (max-width: 1023px) {

    /* Copy capped at 63% of the column so the illustration has a usable
       column beside it. Derived, not assumed: preserving the two-line
       headline would have required a 582px copy block, leaving only ~146px
       for the artwork. 63% lets the headline take its natural three-line
       break and frees ~248px — close to the 232px desktop master.
       The cap applies ONLY in this range; below 768px the copy returns to
       full width. */
    .fp-hero__headline,
    .fp-hero__body,
    .fp-hero__trust {
        max-width: 63%;
    }

    .fp-hero__illustration {
        display: block;
        position: absolute;
        right: 0;
        bottom: 0;
        width: 33%;
        pointer-events: none;
    }
}

@media (min-width: 1024px) {

    /* Constrain the BODY and TRUST line only, so the illustration has the
       open space the reference shows. The headline is left unconstrained:
       its natural break already clears the illustration horizontally, and
       narrowing it would fragment "Find. Compare." across lines.
       Width only — wording, size, weight, colour and line-height are
       untouched. */
    /* Proportional, not fixed: 430px is 66.87% of the 643px column at
       1440px, so this reproduces the master exactly there while scaling
       with the column below it. A fixed 430px cap became 97.9% of the
       column at 1024px, which pushed the body text under the illustration. */
    .fp-hero__body,
    .fp-hero__trust {
        max-width: 66.87%;
    }

    /* Absolutely positioned: never enters the flow, so the headline, body,
       trust line, card and hero height are all unaffected. Placed in the
       open whitespace beside the lower copy — see the note above the block
       for how left/top were derived. */
    /*
     * Responsive across the whole two-column desktop range.
     *
     * The previous hard-coded pixel values were measured at 1440px and did
     * not scale: at 1280px the illustration overflowed the column by 78px
     * and sat on top of the Editorial Framework card.
     *
     * RIGHT EDGE is pinned at 0.08% inside the column, so the illustration
     * can never escape into the card gutter at any width, whatever its
     * size. Anchoring on the right also means the width can change without
     * a second value having to track it.
     *
     * WIDTH is a CONTINUOUS function of the viewport — no step at any
     * breakpoint. The column itself is linear in the viewport
     * (col = 0.49 x (vw - 128)), so:
     *
     *   <= 1200px    33% of the column. This is the widest the artwork can
     *                be below 1200 without clipping a headline descender —
     *                the headline runs to 4 or 5 lines here and occupies
     *                more of the column.
     *   1200-1440    calc(24.48vw - 120.5px). Interpolates between 173.3px
     *                at 1200 and exactly 232px at 1440. Continuous at both
     *                ends: 33% of the column at 1200 IS 173.3px.
     *   >= 1440px    232px — the frozen master, reproduced exactly.
     *
     * Anchored to the column's BOTTOM, not its top: the headline grows from
     * 3 to 5 lines across this range and the column extends downward, so a
     * bottom anchor keeps the illustration beside the lower copy — the
     * approved relationship — rather than drifting.
     *
     * Verified by rendering each width with and without the illustration
     * and diffing for text pixels the artwork paints over: zero everywhere
     * from 1024 to 1440, including either side of every breakpoint.
     */
    /* VISUAL TEST — 190px.
     * Sized down rather than forced into the space. The left column caps at
     * 672px, so the open area beside the copy caps at 241px and never grows;
     * at 232px the artwork filled almost all of it and could not be centred.
     * 190px leaves real margin on both sides at every desktop width.
     *
     * Horizontal: centred in the open space. The copy is capped at 66.87% of
     * the column, so the open area is the remaining 33.13% — the artwork is
     * placed at its centre, which tracks the column at any width.
     *
     * Vertical: centred on the body/trust block via top: 50% and a -50%
     * translate, CLAMPED by max() so the top can never rise above the
     * headline. Headline clearance stays structural, not a tuned offset. */
    .fp-hero__illustration {
        display: block;
        position: absolute;
        /* max() clamp: centred wherever the space allows, flush to the
           column edge where it does not. Below ~1300px the centred
           position pushed the artwork past the column boundary — measured
           157 illustration pixels in the gutter at 1280 and 890 at 1240.
           Flush-right containment is preferable to a gutter bleed, and a
           clamp avoids introducing another breakpoint. */
        right: max(1px, calc(16.565% - 95px));   /* 1px, not 0: at 0 the
                       right edge lands exactly on the column boundary and
                       antialiasing spills a sub-pixel sliver into the
                       gutter — measured 36 stray pixels at 1260px. */
        top: max(-20px, calc(50% - 95px));    /* 95px = half of 190/1.0 —
                       the replacement asset has a SQUARE 1:1 viewBox, not
                       the previous 0.8056 portrait, so the half-height
                       constant in the existing centring rule changes with
                       it. The rule itself is unchanged. */
        /* 240px — approved 2026-08-23. Raised from 190px: the artwork already
           fills ~90% of its canvas, so display size was the readability lever.
           Verified on a real-page render at 1440 — zero hero/section movement. */
        width: 240px;
        /* +40px rightward, approved 2026-08-23 after the pale backdrop was
           removed from the artwork. Pixel-diffed at 1440: hero copy, Editorial
           Framework card and hero height all unchanged — transform only. */
        transform: translateX(40px);
        pointer-events: none;
    }


}

/* ── Compact methodology alignment ────────────────────────
 * In compact mode the ratings block ends well short of the card: the
 * content stops at ~293.5px and the pale-green tint at ~317.5px, while the
 * title, description and this methodology row all run the full ~480px card
 * width. The right-aligned link therefore finished 163px past the tint and
 * pointed straight at the void the ratings leave, which is what made the
 * card read as oversized.
 *
 * Capping this row to the tint width gives the ratings and the CTA a shared
 * right edge, so they read as one left-weighted content group. text-align:
 * right is retained, so the link's ink ends flush AT that edge.
 *
 * REJECTED ALTERNATIVES: capping the card itself (previewed on Staging —
 * it opened an excessive gap between the hero columns and produced a
 * 499 -> 605px jump at the compact/wide boundary); spreading the ratings to
 * full width (would drag the tint back to full width, undoing v3.11.58);
 * centring the ratings (a new alignment language inside a left-aligned
 * card).
 *
 * BOTH NUMBERS ARE MEASURED, NOT DESIGNED — REVALIDATE IF ANYTHING MOVES:
 *   1414.98  derived from the 590px card-content container threshold.
 *            Measured on Staging: 1414 is the last 3-track width
 *            (contentBox 589.9), 1415 the first 4-track one (590.38).
 *            The card is its own query container, so this CANNOT be a
 *            container query — sizing a container from its own query is a
 *            cycle and the declaration is discarded. It must stay a media
 *            query, which couples it to the hero geometry.
 *   317px    the compact tint width on Staging: score + stars +
 *            "Excellent" + 24px trailing.
 * Revalidate both if the hero ratio, container max-width, card padding or
 * border, rating content, or the qualifier text changes.
 * ──────────────────────────────────────────────────────── */
@media (min-width: 1024px) and (max-width: 1414.98px) {
    .fp-editorial-card__methodology {
        max-width: 317px;
    }
}

/* ── Narrow-desktop illustration containment (1024–1249.98) ───────────
 * FIX: the ≥1024 rule sizes the artwork at a FIXED 190px while the open
 * area beside the copy is a PROPORTION — "the copy is capped at 66.87%
 * of the column, so the open area is the remaining 33.13%" (see the
 * ≥1024 block above). That model only holds while 33.13% of the column
 * is at least 190px, i.e. a column of ~575px, reached at ~1303px.
 * Below that the artwork is wider than the space it is centred in, so
 * the max() clamp holds it flush to the column edge — containment is
 * preserved, but the surplus width lands on the copy.
 *
 * Measured on Staging (painted ink vs painted glyphs, not boxes —
 * box tests are inadequate here, per FP-C-002):
 *   1024  31.1px of copy covered   1100  18.4px
 *   1199  10.8px                   1200  10.3px
 *   1220  clear                    1250+ clear
 * At 1024 the word "the" in the body sentence was fully occluded.
 *
 * Restores the artwork to the open area the ≥1024 rule already assumes,
 * which is also the approved ≤1200px behaviour recorded for FP-C-002
 * ("33% of the left column"). min() so it can never exceed the approved
 * 190px. Upper bound 1249.98 keeps 1250+ byte-identical.
 *
 * Deliberately NOT done: moving the artwork into the card gutter (the
 * 1px clamp exists precisely to prevent gutter bleed) and narrowing the
 * copy cap (reflows the body and lifts the headline 14.4px).
 * ──────────────────────────────────────────────────────────────────── */
@media (min-width: 1024px) and (max-width: 1249.98px) {
    .fp-hero__illustration {
        width: min(190px, 33%);
    }
}

/* v3.57.121 - owner (HOMEPAGE-HERO-METHODOLOGY-AMENDMENT.md + REFERENCE-CLARIFICATION.md): the "Read Editorial Methodology" link takes
   the font size of the Buying Guides methodology text (.fp-collection__hero--buying-guides .fp-collection__hero-col--method
   .fp-collection__intro = var(--fp-font-body-m), 16px at every width). Weight, colour, arrow, alignment and focus are unchanged. */
.fp-editorial-card__methodology a { font-size: var(--fp-font-body-m); }

/* v3.57.125 - owner: in this heading "FinanceProspector" matches the header logo - Finance #173F73 (the logo's .st0, the same
   value as --fp-color-navy), Prospector #42B649 (.st1) - with no space between the two spans; the other words keep the
   heading's navy. r2: Finance was Core Blue #2563EB in r1 (Work QA bbb241b). FLAG: #42B649 on white is 2.62:1, below the 3:1
   large-text minimum; kept as the owner's logo match, not a contrast pass. */
.fp-editorial-card__title .fp-brand-name__finance { color: var(--fp-color-navy); }
.fp-editorial-card__title .fp-brand-name__prospector { color: var(--fp-color-green); }
/* v3.57.140 (owner, 2026-10-26): the score-row label "FinanceProspector Editorial Score" uses the same brand-name pattern -
   "Finance" Core Navy, "Prospector" Core Green, "Editorial Score" stays the label's navy. Colour only; the spans add no
   spacing, so the label reads and wraps exactly as before. */
.fp-rating-row__label .fp-brand-name__finance { color: var(--fp-color-navy); }
.fp-rating-row__label .fp-brand-name__prospector { color: var(--fp-color-green); }

/* v3.57.134 r3 - QUALIFIER TRACK WITH A SHORTER LABEL (owner amendment 2026-10-24: Capterra "Great").
 * The wide container grid and the 640-767 grid size the qualifier column per row (max-content), which held only while
 * every row said "Excellent". The hidden spacer below gives every community qualifier cell the width of "Excellent",
 * so the label, score, star and qualifier axes are shared again. It is zero-height, invisible and not exposed to
 * assistive technology; the visible qualifier text and its alignment are unchanged. */
@container (min-width: 590px) {
    .fp-rating-row:not(.fp-rating-row--editorial) td.fp-rating-row__qualifier::after {
        content: "Excellent";
        display: block;
        height: 0;
        overflow: hidden;
        visibility: hidden;
    }
}
@media (min-width: 640px) and (max-width: 767px) {
    .fp-rating-row:not(.fp-rating-row--editorial) td.fp-rating-row__qualifier::after {
        content: "Excellent";
        display: block;
        height: 0;
        overflow: hidden;
        visibility: hidden;
    }
}

/* v3.57.134 r4 - ONE STAR AXIS FOR ALL FOUR ROWS ON PHONES (< 640px; owner, 2026-10-24).
 * Before: each row sized its own score column. The editorial row used a 12px gap plus 8px score padding around
 * "9.0/10", the community rows an 8px gap plus 4px padding around "4.6/5" etc., so the green stars began ~18px right of
 * the navy ones; and from 400px the community rows went single-line with their stars at the far right.
 * Now every row takes the same two-level shape the narrow phones already used - label on line 1, score + stars on
 * line 2 - with one shared spacing (8px gap + 4px score padding) and a left-aligned score column that is at least as wide as the
 * widest score, "9.0/10", via a hidden zero-height spacer (not exposed to assistive technology). Every star group
 * therefore starts at the same x in every row. Values, fills, accessible names, the ten editorial stars, the tint, the
 * hidden phone qualifiers and every width from 640px up are unchanged. */
@media (max-width: 639.98px) {
    .fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) {
        grid-template-columns: auto minmax(0, 1fr);
        column-gap: 8px;
        row-gap: 4px;
        padding: 10px 0;
    }
    .fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) td {
        padding: 0;
    }
    .fp-ratings .fp-rating-row--editorial {
        grid-template-columns: auto minmax(0, 1fr);
        column-gap: 8px;
    }
    .fp-ratings .fp-rating-row td.fp-rating-row__label {
        grid-column: 1 / -1;
        grid-row: 1;
    }
    .fp-ratings .fp-rating-row td.fp-rating-row__score {
        grid-column: 1;
        grid-row: 2;
        justify-self: start;
        text-align: left;
        padding: 0 4px 0 0;
    }
    .fp-ratings .fp-rating-row td.fp-rating-row__score::after {
        content: "9.0/10";
        display: block;
        height: 0;
        overflow: hidden;
        visibility: hidden;
    }
    .fp-ratings .fp-rating-row td.fp-rating-row__stars {
        grid-column: 2;
        grid-row: 2;
        justify-self: start;
        padding: 0;
    }
}

/* v3.57.140 r4 - HOMEPAGE CARD DARK-GRAY TRIAL (owner, 2026-10-27; qa/work-reviews/2026-10-26-v3.57.140-r3/README.md).
 * Scoped to the homepage Editorial Framework card (.fp-ratings) only, for Jacqueline's review:
 *   - "Editorial Score" in the editorial label, and each community row's whole label ("G2 Community Rating" etc.);
 *   - each community score and its /5 (the denominator inherits);
 *   - the FILLED part of each community star row (.fp-stars--navy fill); the pale-navy empty base, the exact
 *     fractional fills and the role="img" labels are unchanged;
 *   - the community "Excellent"/"Great" qualifiers (shown at 640px and up; hidden on phones as before).
 * "Finance" stays navy and "Prospector" green; the FinanceProspector score, stars and "Excellent" stay Core Green.
 * Community ratings elsewhere on the site are unchanged. Dark Gray #4B5563: 7.56:1 on white, 7.02:1 on the #F0F9F0 tint;
 * filled vs empty star 5.10:1. No size, weight or layout change. */
.fp-ratings .fp-rating-row--editorial .fp-rating-row__label,
.fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__label,
.fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__score,
.fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) .fp-rating-row__qualifier {
    color: var(--fp-color-gray-500);   /* r8 (owner, 2026-10-27): Option 1, Medium Gray #6B7280 (r4-r7 trial: #4B5563) */
}
.fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) .fp-stars--navy .fp-stars__fill {
    background-color: var(--fp-color-gray-600);
}

/* v3.57.140 r6/r7 - HOMEPAGE CARD LIGHTER WEIGHT (r6 400 -> r7 500) + LIGHTER COMMUNITY STARS (owner, 2026-10-27; proposal for review).
 * Every text item in the card's rating rows is regular 400: the FinanceProspector Editorial Score and community labels
 * (were 600), the scores and their denominators (were 700) and Excellent/Great (were 600). Size, colour and line-height
 * are unchanged. Stars have no weight; the proposal lightens the COMMUNITY star fill one step, Dark Gray #4B5563 ->
 * Medium Gray #6B7280 (v1.1 text gray), still 3.26:1 against the unchanged #CCD5E0 empty star so fractional fills stay
 * readable. FinanceProspector stars stay Core Green (a lighter green #6FC875 would fall to 1.68:1 against their empty
 * stars - shown as an option on the review board, not applied). Fills, star geometry and aria-labels are unchanged. */
.fp-ratings .fp-rating-row td.fp-rating-row__label,
.fp-ratings .fp-rating-row td.fp-rating-row__score,
.fp-ratings .fp-rating-row td.fp-rating-row__qualifier {
    font-weight: 700;   /* r8 (owner, 2026-10-27): Option 1, bold 700 (r6 tried 400, r7 500) */
}
.fp-ratings .fp-rating-row:not(.fp-rating-row--editorial) .fp-stars--navy .fp-stars__fill {
    background-color: var(--fp-color-gray-500);
}
/* v3.57.145 (P21, owner instruction 2026-10-28): homepage "Read Editorial Methodology" keeps Core Blue on focus (hover already did); its pressed #1E40AF is restated after. GeneratePress's inline `a:hover, a:focus, a:active { color: var(--contrast) }`
   (#222222, (0,1,1), loaded after this file) won these states. Colour only - size, weight, underline, focus ring and destination unchanged. */
.fp-editorial-card__methodology a:focus,
.fp-editorial-card__methodology a:focus-visible { color: var(--fp-color-blue); }
.fp-editorial-card__methodology a:focus:active { color: var(--fp-color-blue-pressed); }
