/* InventNode site theme — LIGHT.
 *
 * Loaded AFTER fpai-site.css and fpai-v3.css, and overrides them. The shared
 * fpai-*.css files stay byte-identical to the firstpartyai repo on purpose so
 * the three sites remain diffable against one design system; every
 * site-specific colour lives here.
 *
 * Palette matches the favicon: light #f4f5fb field, indigo gradient mark.
 * Structure is untouched — same hero, same orbs, same footer.
 *
 * TWO THINGS TO KNOW BEFORE EDITING (both cost time to rediscover):
 *
 * 1. The page background is NOT body's background. It is the fixed wash on
 *    `body:has(.fpai-hero)` in fpai-v3.css, which sets background-color,
 *    -image, -attachment and -repeat with !important, and forces .fpai-hero
 *    and .fpai-section to `background: transparent !important` so the wash
 *    shows through. Overriding `.fpai-hero { background }` does nothing.
 *
 * 2. --fpai-canvas / --fpai-ink are declared on `body.fpai-standalone`, not on
 *    :root. A custom property set on body shadows one set on :root for body and
 *    every descendant, so declaring them in :root here silently does nothing.
 */

body.fpai-standalone {
    --fpai-canvas: #f4f5fb;
    --fpai-ink: #1b1c2b;
    --fpai-gradient: linear-gradient(160deg, #4f46e5 0%, #6366f1 40%, #8b5cf6 100%);
    --fpai-glow: rgba(99, 102, 241, 0.16);
    --fpai-glow-strong: rgba(99, 102, 241, 0.3);
    color: #1b1c2b;
}

html { background: #f4f5fb; }

/* ── The page wash ────────────────────────────────────────────────── */
body:has(.fpai-hero) {
    background-color: #f4f5fb !important;
    background-image:
        radial-gradient(58% 46% at 12% 6%, rgba(99, 102, 241, 0.14) 0%, transparent 55%),
        radial-gradient(52% 42% at 88% 16%, rgba(139, 92, 246, 0.11) 0%, transparent 55%),
        radial-gradient(56% 48% at 84% 74%, rgba(99, 102, 241, 0.11) 0%, transparent 55%),
        radial-gradient(52% 48% at 14% 92%, rgba(79, 70, 229, 0.10) 0%, transparent 55%),
        linear-gradient(180deg, #ffffff 0%, #f7f8fc 45%, #eef0f6 100%) !important;
    background-attachment: fixed !important;
    background-repeat: no-repeat !important;
}

/* ── Type ─────────────────────────────────────────────────────────── */
/* fpai forces hero text white because its field is near-black. Ours is not. */
.fpai-hero .fpai-hero-title,
.fpai-hero .fpai-hero-sub,
.fpai-hero .fpai-btn-ghost,
.fpai-hero .fpai-hero-scroll-cue {
    color: #1b1c2b !important;
}

/* fpai lifts the gradient ramp to light violet so it pops on black. On a light
   field that same ramp is barely legible, so bring it back down. */
.fpai-gradient-text,
.fpai-section-title--centered,
.fpai-kicker-term,
.fpai-thesis-headline em,
.fpai-stat-value {
    background-image: linear-gradient(130deg, #4338ca 0%, #4f46e5 44%, #7c3aed 100%) !important;
}

/* ── Orbs ─────────────────────────────────────────────────────────── */
.fpai-hero-mesh::before {
    background: radial-gradient(circle, rgba(79, 70, 229, 0.16) 0%, rgba(79, 70, 229, 0) 70%);
}
.fpai-hero-mesh::after {
    background: radial-gradient(circle, rgba(99, 102, 241, 0.13) 0%, rgba(99, 102, 241, 0) 70%);
}
.fpai-hero-orb-3 {
    background: radial-gradient(circle, rgba(139, 92, 246, 0.14) 0%, rgba(139, 92, 246, 0) 70%);
}

/* ── Footer ───────────────────────────────────────────────────────── */
footer.fpai-site-footer {
    --fsf-purple: #6366f1;
    --fsf-blue: #4f46e5;
    --fsf-ink: #1b1c2b;
    --fsf-text: #5a5c72;
    --fsf-faint: #c7c5e2;
    background:
        radial-gradient(115% 130% at 50% -15%, rgba(99, 102, 241, 0.12) 0%, rgba(99, 102, 241, 0.04) 32%, rgba(0, 0, 0, 0) 62%),
        linear-gradient(180deg, #eef0f6 0%, #e4e7f1 58%) !important;
}
footer.fpai-site-footer .fpai-site-footer-nav a { color: #3c3a63; }
footer.fpai-site-footer .fpai-site-footer-nav a:hover { color: #4f46e5; }
/* #5a5c72, not a lighter grey: the legal line is small text on #e4e7f1, so it
   needs 4.5:1. #6c6e85 measured 4.04:1 and failed; this is 5.30:1. */
footer.fpai-site-footer .fpai-site-legal { color: #5a5c72; }
footer.fpai-site-footer .fpai-site-footer-divider {
    background: linear-gradient(90deg, transparent, #c7c5e2, transparent);
}

/* ══════════════════════════════════════════════════════════════════
   PAGE COMPONENTS
   Only what the shared CSS doesn't already provide. The three-step
   grid, buttons, eyebrow and section titles are all reused as-is.
   ══════════════════════════════════════════════════════════════════ */

/* ── The flow: arrows between the three steps ─────────────────────
   Drawn as ::after on the card rather than as markup, so the arrows
   are decorative and screen readers read three plain steps. They
   disappear when the grid wraps to one column. */
.inv-flow { position: relative; }
.inv-flow .fpai-pillar-title {
    font-family: var(--brand-font, 'Space Grotesk', system-ui, sans-serif);
    font-weight: 600;
    font-size: 1.35rem;
    letter-spacing: -0.01em;
    color: #4f46e5;
    margin: 0 0 0.5rem;
}
.inv-flow .fpai-pillar-desc {
    color: #4a4c62;
    font-size: 1rem;
    line-height: 1.55;
    margin: 0;
}
@media (max-width: 820px) {
    /* Stacked: point the chevron down, between the cards. */
    .inv-flow .fpai-pillar-card + .fpai-pillar-card::after {
        left: 50%;
        top: -1.45rem;
        width: 1.5rem;
        height: 0.95rem;
        transform: translateX(-50%);
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 12' fill='none' stroke='%23a5b4fc' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 2l8 8 8-8'/%3E%3C/svg%3E");
    }
}


/* ── Closing CTA ──────────────────────────────────────────────────── */
.inv-cta { text-align: center; }
.inv-cta-sub { color: #4a4c62; font-size: 1.05rem; margin: 0 0 2rem; }

/* ══════════════════════════════════════════════════════════════════
   LAYOUT CORRECTIONS
   ══════════════════════════════════════════════════════════════════ */

/* `.fpai-section-inner--narrow` is DEAD on this page. fpai-v3.css defines it at
   line 365 (max-width: var(--fpai-max-w-narrow) = 820px), then line 3707
   redefines `.fpai-section-inner { max-width: 960px }` at EQUAL specificity and
   later in the file, so the modifier always loses. Re-assert it with a
   body-scoped selector (higher specificity, no !important needed). Without
   this the article card is 960px wide with its text pinned far left. */
body .fpai-section-inner--narrow { max-width: 700px; }

/* fpai's rhythm is built for a long page with big sections between the gaps.
   This page has three short blocks, so the inherited padding leaves ~250px of
   dead space between each. Tighten the scale rather than the content. */
body.fpai-standalone { --fpai-section-py: clamp(3.25rem, 5.5vw, 4.75rem); }

/* No forced wrap: 34ch was breaking a line that fits on one. Let it use the
   width it has and only wrap when it genuinely runs out. */
.fpai-hero-sub { max-width: 62ch; margin-left: auto; margin-right: auto; }

/* Section headers are centred, so centre the cards they head. Left-aligned
   copy under a centred title is the misalignment that reads as unfinished. */

/* Consecutive sections stack bottom padding onto the next section's top
   padding, which was leaving 220px and 192px voids at the seams. Drop the
   bottom padding on the middle sections; the next section's top padding is the
   separator. */
#process, #background { padding-bottom: 0; }


/* ── Trademark mark ───────────────────────────────────────────────────
   Only the hero ™ was styled (fpai owns .fpai-tm). Every other ™ on the
   page was a bare full-size character sitting on the baseline. */
.inv-tm {
    font-size: 0.58em;
    vertical-align: super;
    line-height: 0;
    letter-spacing: 0;
}

/* ── Step-card icons ──────────────────────────────────────────────────
   Reuses the shared .fpai-pillar-icon shell; its gradient/border are keyed to
   --purple/--blurple which resolve dark here, so restate them for the light
   field. Centred to match the centred card copy. */
.inv-flow .fpai-pillar-icon {
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 1.1rem;
    background: linear-gradient(135deg, rgba(99, 102, 241, 0.14), rgba(139, 92, 246, 0.08));
    border: 1px solid rgba(99, 102, 241, 0.22);
    color: #4f46e5;
}

/* ── Card hover ───────────────────────────────────────────────────────
   fpai's hover reveals a 3px accent bar via ::before and lifts the card. The
   bar is pinned to the card's top edge, and this card has an 18px radius with
   overflow:visible (needed for the chevron), so the bar's square ends poked
   past the rounded corners. Inset and round it to follow the corner. */


/* fpai's `.fpai-pillar-icon svg { fill: currentColor }` beats the fill="none"
   presentation attribute on the markup (CSS always wins over presentation
   attributes), so stroke-drawn icons render as solid blobs. Restate it. */
.inv-flow .fpai-pillar-icon svg {
    fill: none;
    stroke: currentColor;
    width: 21px;
    height: 21px;
}


/* ── ™, actually ──────────────────────────────────────────────────────
   fpai sets `-webkit-text-fill-color: rgba(255,255,255,.4)` on
   `.fpai-hero .fpai-tm` for its near-black hero. That property OVERRIDES
   `color` when painting text, so setting `color` alone does nothing and
   getComputedStyle().color still reports the value you set. That is a lying
   measurement: it says indigo while the glyph paints white. Set the fill. */
.fpai-hero .fpai-tm,
.fpai-hero-title .fpai-tm,
.inv-tm {
    -webkit-text-fill-color: #6366f1;
    color: #6366f1;
    opacity: 1;
}

/* HERO HEIGHT: DO NOT OVERRIDE.
   fpai's `.fpai-hero { min-height: 100vh }` is intentional and this site keeps
   it. I shortened it three times (72vh, 58vh, then content-sized) and each one
   was wrong: the full-viewport hero is the shared design, and the scroll cue
   depends on there being a screenful to scroll past. If the hero feels empty,
   the answer is more in the hero, not less hero. */

/* Scroll cue. fpai renders it white at opacity .3 against a near-black hero,
   which reads clearly. Inheriting that opacity with dark ink on a pale field
   gives rgb(180,179,195) — technically present, visually gone. Same failure as
   the ™. Give it the brand indigo and enough weight to actually be seen. */
.fpai-hero .fpai-hero-scroll-cue {
    color: #4f46e5 !important;
    opacity: 0.55;
}

/* ══════════════════════════════════════════════════════════════════════
   GLASS CARD SYSTEM
   Applies to the three step cards and the featured article card.

   Layering, outermost first:
     .inv-sheen   pointer-tracked specular highlight (own element, because
                  ::before is the gradient ring and ::after is the chevron)
     ::before     1px gradient hairline, drawn as a masked ring
     ::after      the flow chevron (step cards only, 2nd and 3rd)
   ══════════════════════════════════════════════════════════════════════ */

.inv-flow .fpai-pillar-card {
    --mx: 50%;
    --my: 0%;
    position: relative;
    isolation: isolate;
    overflow: visible;
    border: 0;
    border-radius: 22px;
    /* Frosted, not flat white: translucent so the page wash reads through. */
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.88) 0%, rgba(255, 255, 255, 0.60) 100%);
    -webkit-backdrop-filter: blur(26px) saturate(180%);
    backdrop-filter: blur(26px) saturate(180%);
    box-shadow:
        0 1px 1px rgba(28, 27, 58, 0.04),
        0 8px 20px -10px rgba(79, 70, 229, 0.20),
        0 26px 52px -20px rgba(79, 70, 229, 0.16),
        inset 0 1px 0 rgba(255, 255, 255, 0.95);   /* specular top edge */
    transition:
        transform 620ms cubic-bezier(0.16, 1, 0.3, 1),
        box-shadow 620ms cubic-bezier(0.16, 1, 0.3, 1);
    will-change: transform;
}

/* Gradient hairline. A masked ring, so the border itself carries a gradient
   rather than a flat colour. Brighter top-left, cooler bottom-right. */
.inv-flow .fpai-pillar-card::before {
    content: "";
    position: absolute;
    inset: 0;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: auto;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(140deg,
        rgba(255, 255, 255, 0.95) 0%,
        rgba(199, 210, 254, 0.75) 34%,
        rgba(165, 180, 252, 0.45) 62%,
        rgba(139, 92, 246, 0.30) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0.85;
    transition: opacity 620ms cubic-bezier(0.16, 1, 0.3, 1);
    pointer-events: none;
    z-index: 0;
}

/* Pointer-tracked specular highlight. Sits above the surface, below content. */
.inv-sheen {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    opacity: 0;
    z-index: 0;
    transition: opacity 520ms cubic-bezier(0.16, 1, 0.3, 1);
    background:
        radial-gradient(340px circle at var(--mx) var(--my),
            rgba(255, 255, 255, 0.85) 0%,
            rgba(199, 210, 254, 0.35) 32%,
            rgba(255, 255, 255, 0) 68%);
}

.inv-flow .fpai-pillar-card > *:not(.inv-sheen) { position: relative; z-index: 1; }

/* ── Hover ────────────────────────────────────────────────────────────── */
.inv-flow .fpai-pillar-card:hover {
    transform: translateY(-6px) scale(1.012);
    box-shadow:
        0 1px 1px rgba(28, 27, 58, 0.05),
        0 14px 28px -12px rgba(79, 70, 229, 0.28),
        0 44px 80px -28px rgba(79, 70, 229, 0.30),
        inset 0 1px 0 rgba(255, 255, 255, 1);
}
.inv-flow .fpai-pillar-card:hover::before { opacity: 1; }
.inv-flow .fpai-pillar-card:hover .inv-sheen { opacity: 1; }

/* Icon reacts rather than sitting inert. */
.inv-flow .fpai-pillar-icon {
    transition: transform 620ms cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 620ms cubic-bezier(0.16, 1, 0.3, 1);
}
.inv-flow .fpai-pillar-card:hover .fpai-pillar-icon {
    transform: translateY(-2px) scale(1.06);
    box-shadow: 0 10px 22px -10px rgba(79, 70, 229, 0.55);
}

/* ── Reveal: spring in, staggered ─────────────────────────────────────── */
.inv-flow .fpai-pillar-card {
    opacity: 0;
    transform: translateY(26px) scale(0.975);
    transition:
        opacity 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--inv-delay, 0ms),
        transform 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--inv-delay, 0ms),
        box-shadow 620ms cubic-bezier(0.16, 1, 0.3, 1);
}
.inv-flow.is-visible .fpai-pillar-card {
    opacity: 1;
    transform: translateY(0) scale(1);
}
.inv-flow .fpai-pillar-card:nth-child(1) { --inv-delay: 0ms; }
.inv-flow .fpai-pillar-card:nth-child(2) { --inv-delay: 110ms; }
.inv-flow .fpai-pillar-card:nth-child(3) { --inv-delay: 220ms; }
/* Hover must not fight the entrance transform once revealed. */
.inv-flow.is-visible .fpai-pillar-card:hover {
    transform: translateY(-6px) scale(1.012);
}

@media (prefers-reduced-motion: reduce) {
    .inv-flow .fpai-pillar-card,
    .inv-flow .fpai-pillar-icon { transition: none; }
    .inv-flow .fpai-pillar-card { opacity: 1; transform: none; }
    .inv-sheen { display: none; }
}

/* ── Flow chevron ─────────────────────────────────────────────────────
   ::after, because ::before is the gradient hairline. A background-image,
   because CSS borders do not paint on this pseudo-element (and because the
   card's own ::before is spoken for). */
.inv-flow .fpai-pillar-card + .fpai-pillar-card::after {
    content: "";
    position: absolute;
    left: -1.45rem;
    top: 50%;
    width: 0.95rem;
    height: 1.5rem;
    transform: translateY(-50%);
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20' fill='none' stroke='%23a5b4fc' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 2l8 8-8 8'/%3E%3C/svg%3E");
    opacity: 1;
    z-index: 2;
}
@media (max-width: 820px) {
    .inv-flow .fpai-pillar-card + .fpai-pillar-card::after {
        left: 50%;
        top: -1.45rem;
        width: 1.5rem;
        height: 0.95rem;
        transform: translateX(-50%);
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 12' fill='none' stroke='%23a5b4fc' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 2l8 8 8-8'/%3E%3C/svg%3E");
    }
}

/* Centred copy under centred section headers. (This was lost when the flat
   card styles were stripped for the glass pass.) */
.inv-flow .fpai-pillar-card { text-align: center; padding: 2.15rem 1.75rem 2.35rem; }
.inv-flow .fpai-pillar-desc { max-width: 24ch; margin-left: auto; margin-right: auto; }

/* Sheen: pure white specular. The indigo mid-stop was tinting the whole
   surface, so the hovered card read duller than its neighbours instead of
   brighter, which is the opposite of what a lift should do. */
.inv-sheen {
    background:
        radial-gradient(300px circle at var(--mx) var(--my),
            rgba(255, 255, 255, 0.95) 0%,
            rgba(255, 255, 255, 0.45) 30%,
            rgba(255, 255, 255, 0) 65%);
}
/* Hover brightens the glass itself, not just the highlight. */
.inv-flow .fpai-pillar-card:hover {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.97) 0%, rgba(255, 255, 255, 0.80) 100%);
}

/* ── Claim counts ─────────────────────────────────────────────────────
   Reuses fpai's .fpai-stats-grid / .fpai-stat-card. Their surfaces are keyed
   to --inv-bg-color, which resolves light-on-dark, so restate for this field.
   Dividers between cards, matching the customernode.com treatment. */
.inv-stats { margin: 0 auto 3.25rem; gap: 0; }
.inv-stats .fpai-stat-card {
    background: transparent;
    padding: 0.5rem 2.75rem;
    position: relative;
}
.inv-stats .fpai-stat-card + .fpai-stat-card::before {
    content: "";
    position: absolute;
    left: 0;
    top: 12%;
    bottom: 12%;
    width: 1px;
    background: linear-gradient(180deg, transparent, #c7c5e2 35%, #c7c5e2 65%, transparent);
}
.inv-stats .fpai-stat-value {
    background: linear-gradient(130deg, #4338ca 0%, #4f46e5 44%, #7c3aed 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    font-variant-numeric: tabular-nums;
}
.inv-stats .fpai-stat-label {
    color: #6c6e85;
    font-size: 0.82rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}
@media (max-width: 620px) {
    .inv-stats .fpai-stat-card { padding: 0.5rem 1.4rem; }
}

/* ── Closing CTA: the nucleus stage ───────────────────────────────────
   Needs real air above it so the claim counts land before this begins. */
.inv-final {
    padding-top: clamp(7rem, 15vh, 12rem) !important;
    padding-bottom: clamp(4rem, 9vh, 7rem) !important;
}
.inv-final .fpai-final-cta-bg {
    background: radial-gradient(ellipse 62% 52% at 50% 46%, rgba(99, 102, 241, 0.16), transparent 70%);
}
.inv-final .inv-cta-sub {
    color: #4a4c62;
    font-size: 1.06rem;
    max-width: 54ch;
    margin: 0.9rem auto 0;
}
/* The stage label sits on a light field here, not fpai's near-black. */

/* In letter-spaced uppercase (eyebrow, card meta) the parent tracking applies
   either side of the ™ span, so it reads "CUSTOMERNODE ™ IS ...". Pull it back
   onto the word. */
.fpai-eyebrow .inv-tm,
.article-card-meta .inv-tm {
    margin-left: -0.16em;
    margin-right: 0.05em;
}

/* Sub sized so its rendered width matches the wordmark's.
   Measured: the sub needs ~0.179x the title's font-size for the two text
   widths to line up. The title is clamp(3.25rem, 9vw, 6.5rem), so:
     upper  6.5rem  * 0.176 = 1.146rem   (title capped above ~1156px)
     middle 9vw     * 0.179 = 1.615vw
   The lower bound is a readability floor, not a width match: at the title's
   own 3.25rem floor the matched size would be ~9px. */
.fpai-hero-sub {
    font-size: clamp(1rem, 1.615vw, 1.146rem) !important;
    line-height: 1.5;
}

/* ══════════════════════════════════════════════════════════════════════
   VERTICAL RHYTHM — one place, explicit values.

   These were previously scattered and got silently deleted by a regex
   sweep during the glass pass, which dropped `title -> cards` to 8px.
   Keep them together and keep the selectors specific enough to win.

   Intended scale:   eyebrow -> title 16   title -> content 44
                     block -> block 64     section -> section 96 (section padding)
   ══════════════════════════════════════════════════════════════════════ */

#process .fpai-eyebrow,
#background .fpai-eyebrow {
    margin-bottom: 16px !important;
}

#process .fpai-section-title,
#process .fpai-section-title--centered {
    margin-bottom: 44px !important;
}

#contact .fpai-section-title,
#contact .fpai-section-title--centered {
    margin-bottom: 16px !important;
}

.inv-stats {
    margin: 0 auto 64px !important;
}

/* The nucleus stage carries its own generous canvas, so it does not need the
   full block gap above it. */
.inv-final .fpai-cta-stage {
    margin-top: 8px;
}

/* ══════════════════════════════════════════════════════════════════════
   ARTICLE CARD — ported verbatim from customernode.com
   (customerNode_site/static/css/public/index_v6.css, .article-card block)

   WHY EXPLICIT PIXELS INSTEAD OF THE ORIGINAL rem VALUES:
   customernode.com renders at a 20px root font-size; this site is at 16px.
   The source rules are identical in rem, but 1.5rem is 30px there and 24px
   here, which is why this card looked shrunken. Every value below is the
   canonical rem figure x 20px, so it renders at the same visual size.
   Container is 700px to match .defend-inner.

   Do NOT fold this card back into the glass system above. It is meant to be
   the same component as the one on customernode.com, not a variation.
   ══════════════════════════════════════════════════════════════════════ */

.inv-bg-inner { max-width: 700px; }

.article-card {
    display: flex;
    text-align: left;
    text-decoration: none !important;
    border-radius: 20px;
    overflow: hidden;
    border: 1px solid rgba(32, 47, 57, 0.09);
    background: #fbfbff;
    box-shadow: 0 4px 24px rgba(32, 47, 57, 0.04);
    transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}
.article-card:hover {
    transform: translateY(-4px);
    border-color: rgba(120, 115, 245, 0.28);
    box-shadow: 0 18px 50px rgba(120, 115, 245, 0.12);
}
.article-card-media {
    flex: 0 0 44%;
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, #eef0f6, #e3e6f3);
}
.article-card-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 0.4s ease;
}
.article-card:hover .article-card-media img { transform: scale(1.04); }

.article-card-body {
    flex: 1;
    min-width: 0;
    padding: 35px 40px;          /* 1.75rem 2rem at 20px root */
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 11px;                   /* 0.55rem */
}
.article-card-meta {
    display: inline-flex;
    align-items: center;
    gap: 9px;                    /* 0.45rem */
    font-size: 14.4px;           /* 0.72rem */
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #1b1c2b;
    opacity: 0.5;
}
.article-card-meta svg { width: 17.5px; height: 17.5px; opacity: 0.9; flex: none; }
.article-card--featured .article-card-meta svg { color: #6366f1; }

.article-card-title {
    font-size: 30px;             /* 1.5rem */
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: #1b1c2b;
    margin: 0;
}
.article-card-teaser {
    font-size: 18.4px;           /* 0.92rem */
    line-height: 1.5;
    color: #1b1c2b;
    opacity: 0.6;
    margin: 0;
}
.article-card-readmore {
    display: inline-flex;
    align-items: center;
    gap: 8px;                    /* 0.4rem */
    margin-top: 8px;
    font-size: 16.4px;           /* 0.82rem */
    font-weight: 600;
    color: #818cf8;
}
.article-card-readmore svg { transition: transform 0.25s ease; }
.article-card:hover .article-card-readmore svg { transform: translateX(3px); }

@media (max-width: 640px) {
    .article-card { flex-direction: column; }
    .article-card-media { flex: none; width: 100%; aspect-ratio: 1200 / 628; }
}

/* The meta line is 700-weight uppercase with 0.04em tracking; the ™ still
   picked up a gap either side. Tighter pull than the eyebrow needs. */
.article-card-meta .inv-tm {
    margin-left: -0.3em;
    margin-right: 0.12em;
    font-size: 0.5em;
}

/* ══════════════════════════════════════════════════════════════════════
   GLASS, PROPERLY

   1. The section clipped the cards' shadows (.fpai-section is overflow:hidden
      upstream). #process has no orbs of its own, so it can open up.
   2. Frosted glass only reads if there is something behind it to refract.
      The page wash here is near-uniform, so a translucent panel over it just
      looks white. An aurora sits behind the row and the cards blur it.
   ══════════════════════════════════════════════════════════════════════ */

#process { overflow: visible; }
#process .fpai-section-inner { overflow: visible; }

/* Aurora behind the card row. Decorative, sits under the cards. */
.inv-flow::before {
    content: "";
    position: absolute;
    inset: -14% -8%;
    z-index: 0;
    pointer-events: none;
    filter: blur(46px) saturate(150%);
    opacity: 0.95;
    background:
        radial-gradient(38% 60% at 14% 42%, rgba(99, 102, 241, 0.42), transparent 70%),
        radial-gradient(34% 58% at 48% 76%, rgba(139, 92, 246, 0.34), transparent 72%),
        radial-gradient(36% 62% at 84% 34%, rgba(78, 172, 241, 0.36), transparent 70%),
        radial-gradient(30% 48% at 66% 12%, rgba(199, 210, 254, 0.55), transparent 74%);
}

/* Now the cards can actually be glass: far more translucent, heavier blur,
   and a real edge. */
.inv-flow .fpai-pillar-card {
    z-index: 1;
    border-radius: 26px;
    background:
        linear-gradient(155deg,
            rgba(255, 255, 255, 0.62) 0%,
            rgba(255, 255, 255, 0.34) 46%,
            rgba(255, 255, 255, 0.46) 100%);
    -webkit-backdrop-filter: blur(34px) saturate(190%) brightness(1.06);
    backdrop-filter: blur(34px) saturate(190%) brightness(1.06);
    box-shadow:
        /* specular top edge */
        inset 0 1.5px 0 rgba(255, 255, 255, 0.98),
        /* light catching the left edge */
        inset 1.5px 0 0 rgba(255, 255, 255, 0.55),
        /* thickness: shadow pooling inside the bottom */
        inset 0 -22px 34px -26px rgba(49, 46, 129, 0.34),
        /* contact shadow */
        0 2px 4px rgba(49, 46, 129, 0.06),
        /* key */
        0 16px 30px -14px rgba(79, 70, 229, 0.26),
        /* ambient */
        0 40px 70px -30px rgba(79, 70, 229, 0.28);
}

/* Brighter, more defined rim: a true specular arc top-left fading to nothing. */
.inv-flow .fpai-pillar-card::before {
    background: linear-gradient(145deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, 0.75) 18%,
        rgba(199, 210, 254, 0.50) 42%,
        rgba(165, 180, 252, 0.22) 66%,
        rgba(255, 255, 255, 0.45) 100%);
    opacity: 0.95;
}

.inv-flow .fpai-pillar-card:hover {
    background:
        linear-gradient(155deg,
            rgba(255, 255, 255, 0.76) 0%,
            rgba(255, 255, 255, 0.48) 46%,
            rgba(255, 255, 255, 0.58) 100%);
    box-shadow:
        inset 0 1.5px 0 rgba(255, 255, 255, 1),
        inset 1.5px 0 0 rgba(255, 255, 255, 0.7),
        inset 0 -24px 38px -26px rgba(49, 46, 129, 0.30),
        0 2px 4px rgba(49, 46, 129, 0.07),
        0 24px 44px -16px rgba(79, 70, 229, 0.34),
        0 64px 96px -36px rgba(79, 70, 229, 0.38);
}

/* Icon reads as a smaller pane of the same glass. */
.inv-flow .fpai-pillar-icon {
    border-radius: 16px;
    background: linear-gradient(150deg, rgba(255, 255, 255, 0.9), rgba(224, 231, 255, 0.55));
    border: 1px solid rgba(255, 255, 255, 0.85);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 1),
        0 6px 14px -8px rgba(79, 70, 229, 0.45);
}

/* Aurora, tightened. Inset -14%/-8% let it spill past the row and read as
   haze; the colour should live UNDER the glass, not around it. Hues now run
   in flow order: indigo (Discover) -> violet (Draft) -> cyan (Guard). */
.inv-flow::before {
    inset: -3% -1.5%;
    filter: blur(38px) saturate(160%);
    opacity: 1;
    background:
        radial-gradient(30% 66% at 17% 50%, rgba(79, 70, 229, 0.50), transparent 72%),
        radial-gradient(30% 66% at 50% 54%, rgba(139, 92, 246, 0.46), transparent 72%),
        radial-gradient(30% 66% at 83% 48%, rgba(78, 172, 241, 0.46), transparent 72%),
        radial-gradient(60% 40% at 50% 6%, rgba(224, 231, 255, 0.6), transparent 76%);
}

/* Copy has to stay readable over the tinted glass. */
.inv-flow .fpai-pillar-desc { color: #3f4157; }
.inv-flow .fpai-pillar-title { color: #3730a3; }

/* ── Nucleus CTA label ────────────────────────────────────────────────
   The source .cta-core is inline-flex with gap:0.6rem, i.e. built for a
   label plus an arrow; my markup only supplied the label. Its ::before is a
   coloured indigo/cyan bloom, which I had overridden with white and so lost
   the colour the source had. Both restored. */
.inv-final .cta-core {
    font-family: var(--brand-font, 'Space Grotesk', system-ui, sans-serif);
    font-weight: 600;
    font-size: 1.35rem;
    letter-spacing: -0.01em;
    color: #4f46e5;
}
.inv-final .cta-core::before {
    background: radial-gradient(ellipse at center,
        rgba(99, 102, 241, 0.26) 0%,
        rgba(78, 172, 241, 0.12) 46%,
        transparent 72%);
}
.inv-final .cta-core-label {
    background: linear-gradient(130deg, #4338ca 0%, #4f46e5 44%, #7c3aed 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.inv-final .cta-core-arrow {
    color: #4f46e5;
    transition: transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
    flex: none;
}
.inv-final .fpai-cta-stage:hover .cta-core-arrow { transform: translateX(4px); }

/* More air between the process cards and the patent-pending proof.
   The 96px section gap reads much tighter than it measures, because the
   cards' glow and 40/70px ambient shadows occupy most of it. */
#background { padding-top: 180px !important; }

/* ══════════════════════════════════════════════════════════════════════
   AURORA v2 — one light source, not three colours

   The first pass gave each card its own hue (indigo / violet / cyan). Three
   pastels in a row reads as decoration and it went candy. This is a single
   raking light across the whole row, held inside the indigo family with one
   cool accent, so the three panes read as one sheet of glass under one lamp.
   Deeper and more saturated, but lower opacity: tonal rather than pastel.
   ══════════════════════════════════════════════════════════════════════ */
.inv-flow::before {
    inset: -4% -2%;
    filter: blur(30px) saturate(125%);
    opacity: 1;
    background:
        /* the lamp: raking light from upper-left, indigo core */
        radial-gradient(64% 92% at 12% 6%, rgba(67, 56, 202, 0.34) 0%, rgba(67, 56, 202, 0.10) 42%, transparent 74%),
        /* cool falloff into the lower-right, the only other hue */
        radial-gradient(70% 96% at 96% 92%, rgba(30, 64, 128, 0.24) 0%, transparent 72%),
        /* mid-field density so the centre pane is not empty */
        radial-gradient(48% 70% at 54% 52%, rgba(79, 70, 229, 0.20) 0%, transparent 76%),
        /* neutral ground keeps it from turning purple overall */
        linear-gradient(148deg, rgba(226, 232, 245, 0.85) 0%, rgba(203, 213, 235, 0.55) 55%, rgba(224, 231, 255, 0.5) 100%);
}

/* Cooler, less milky glass. brightness(1.06) was washing the tone out. */
.inv-flow .fpai-pillar-card {
    background:
        linear-gradient(158deg,
            rgba(255, 255, 255, 0.58) 0%,
            rgba(248, 250, 255, 0.30) 48%,
            rgba(255, 255, 255, 0.40) 100%);
    -webkit-backdrop-filter: blur(30px) saturate(150%);
    backdrop-filter: blur(30px) saturate(150%);
    box-shadow:
        inset 0 1.5px 0 rgba(255, 255, 255, 0.96),
        inset 1.5px 0 0 rgba(255, 255, 255, 0.45),
        inset 0 -26px 38px -28px rgba(30, 41, 89, 0.40),
        0 2px 4px rgba(30, 41, 89, 0.07),
        0 16px 30px -14px rgba(49, 46, 129, 0.22),
        0 40px 70px -34px rgba(49, 46, 129, 0.26);
}
.inv-flow .fpai-pillar-card:hover {
    background:
        linear-gradient(158deg,
            rgba(255, 255, 255, 0.72) 0%,
            rgba(248, 250, 255, 0.44) 48%,
            rgba(255, 255, 255, 0.52) 100%);
    box-shadow:
        inset 0 1.5px 0 rgba(255, 255, 255, 1),
        inset 1.5px 0 0 rgba(255, 255, 255, 0.6),
        inset 0 -28px 42px -28px rgba(30, 41, 89, 0.36),
        0 2px 4px rgba(30, 41, 89, 0.08),
        0 24px 44px -16px rgba(49, 46, 129, 0.30),
        0 64px 96px -40px rgba(49, 46, 129, 0.34);
}

/* Rim: cooler and tighter, less rainbow. */
.inv-flow .fpai-pillar-card::before {
    background: linear-gradient(148deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, 0.62) 22%,
        rgba(199, 210, 254, 0.38) 52%,
        rgba(129, 140, 248, 0.20) 78%,
        rgba(255, 255, 255, 0.35) 100%);
    opacity: 0.9;
}

/* It is the LinkedIn logo now, so use LinkedIn's blue rather than the
   --featured indigo override (which existed for a generic document icon). */
.article-card--featured .article-card-meta svg { color: #0a66c2; opacity: 1; }

/* ══════════════════════════════════════════════════════════════════════
   AURORA v3 — invert the relationship

   v2 put the colour behind the cards only, so the panes were DARKER than
   the page and read as dark tiles floating in white. Apple's glass is the
   other way round: the field carries the colour, and the panel is the
   lightest thing in the frame, catching the light.

   So the tint now spans the whole section, and the cards become luminous
   on top of it.
   ══════════════════════════════════════════════════════════════════════ */

#process { position: relative; isolation: isolate; }
#process::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    /* ONE clean descent plus a single soft light pool. The previous field
       stacked three radials in different hues (indigo, steel, indigo) at low
       alpha, and low-alpha hues layered over each other average out to grey:
       that is where the mud came from. */
    background:
        radial-gradient(120% 80% at 50% -10%, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0) 60%),
        linear-gradient(180deg, #f4f6fc 0%, #e9edf8 46%, #dfe5f4 100%);
}

/* The row-level aurora is no longer needed: the field does that job now.
   Keep a faint pool under the row so the panes still have something with
   structure to refract, but nothing that darkens them. */
.inv-flow::before {
    inset: -6% -3%;
    filter: blur(44px) saturate(120%);
    opacity: 0.75;
    background:
        radial-gradient(58% 84% at 20% 30%, rgba(255, 255, 255, 0.85) 0%, transparent 70%),
        radial-gradient(54% 80% at 78% 72%, rgba(224, 231, 255, 0.75) 0%, transparent 72%);
}

/* Panels: the brightest thing in the frame. */
.inv-flow .fpai-pillar-card {
    background:
        linear-gradient(158deg,
            rgba(255, 255, 255, 0.92) 0%,
            rgba(255, 255, 255, 0.74) 46%,
            rgba(255, 255, 255, 0.84) 100%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    backdrop-filter: blur(24px) saturate(140%);
    box-shadow:
        inset 0 1.5px 0 rgba(255, 255, 255, 1),
        inset 1.5px 0 0 rgba(255, 255, 255, 0.7),
        inset 0 -24px 36px -30px rgba(30, 41, 89, 0.28),
        0 2px 4px rgba(30, 41, 89, 0.06),
        0 18px 34px -16px rgba(49, 46, 129, 0.20),
        0 44px 80px -38px rgba(49, 46, 129, 0.24);
}
.inv-flow .fpai-pillar-card:hover {
    background:
        linear-gradient(158deg,
            rgba(255, 255, 255, 0.99) 0%,
            rgba(255, 255, 255, 0.88) 46%,
            rgba(255, 255, 255, 0.94) 100%);
}

/* The field is painted on the section box, so it ends in a hard horizontal
   seam at the section boundary. Feather both edges into the page. */
#process::after {
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 12%, #000 86%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 12%, #000 86%, transparent 100%);
}

/* ══════════════════════════════════════════════════════════════════════
   LIQUID GLASS — actual refraction

   Researched rather than guessed. Apple's Liquid Glass is not blur: the
   material REFRACTS what is behind it, bending light at the curved edge
   (lensing) with specular highlights on the bezel. Blur alone reads as
   frosted plastic, which is what these cards were.

   Technique (kube.io / ekino writeups, w3c/svgwg#1142): an SVG
   feDisplacementMap driven by a displacement map whose R channel encodes X
   offset and G encodes Y, neutral at 128. dist/images/glass-displace.png is
   generated with the refraction confined to a 34px bezel using a squircle
   falloff, so the centre is undistorted and the rim bends the background
   outward, exactly like the edge of a real lens.

   Chromium-only: only Chrome supports an SVG filter in backdrop-filter. The
   @supports block below is additive, so every other browser keeps the plain
   blur version and loses nothing but the lensing.
   ══════════════════════════════════════════════════════════════════════ */

@supports (backdrop-filter: url(#invGlassLens)) {
    .inv-flow .fpai-pillar-card {
        -webkit-backdrop-filter: url(#invGlassLens) blur(3px) saturate(160%) brightness(1.02);
        backdrop-filter: url(#invGlassLens) blur(3px) saturate(160%) brightness(1.02);
        /* The lens does the work now, so the fill drops back and lets the
           refracted background carry the surface. */
        background:
            linear-gradient(158deg,
                rgba(255, 255, 255, 0.50) 0%,
                rgba(255, 255, 255, 0.26) 46%,
                rgba(255, 255, 255, 0.38) 100%);
    }
    .inv-flow .fpai-pillar-card:hover {
        background:
            linear-gradient(158deg,
                rgba(255, 255, 255, 0.62) 0%,
                rgba(255, 255, 255, 0.36) 46%,
                rgba(255, 255, 255, 0.48) 100%);
    }
}

/* Specular bezel. Real glass catches a bright line where the curve turns,
   strongest at the top-left, with a weaker return on the lower-right. This
   is a second ring inside the refractive edge, not the border itself. */
.inv-flow .fpai-pillar-card {
    box-shadow:
        inset 0 1.5px 0.5px rgba(255, 255, 255, 1),
        inset 1.5px 0 0.5px rgba(255, 255, 255, 0.8),
        inset -1px -1px 0.5px rgba(255, 255, 255, 0.55),
        inset 0 -20px 30px -28px rgba(30, 41, 89, 0.30),
        0 2px 4px rgba(30, 41, 89, 0.06),
        0 18px 34px -16px rgba(49, 46, 129, 0.20),
        0 44px 80px -38px rgba(49, 46, 129, 0.24);
}

/* ── Stat block rhythm ────────────────────────────────────────────────
   fpai hardcodes `.fpai-stat-label { height: 68px }` (and 44px on the
   value) because its labels run to two lines. Ours are single words, so
   that reserved 68px became an invisible slab under every number: the
   block measured 140px tall for ~70px of content, which is what made the
   rhythm read wrong. Height goes auto and the gap becomes deliberate. */
.inv-stats .fpai-stat-value {
    height: auto;
    margin-bottom: 10px;
    justify-content: center;
}
.inv-stats .fpai-stat-label {
    height: auto;
    max-width: none;
    display: block;
    line-height: 1.3;
}
.inv-stats .fpai-stat-card { padding: 0 44px; }
/* With the block now its true height, rebalance either side of it. */
#background .fpai-eyebrow { margin-bottom: 26px !important; }
.inv-stats { margin: 0 auto 72px !important; }

/* ── Proof section title ──────────────────────────────────────────────
   'CustomerNode™ is patent pending' is a longer line than the process
   title, so cap it a little smaller and keep it on one line at desktop. */
#background .fpai-section-title {
    font-size: clamp(1.7rem, 3.4vw, 2.6rem);
    margin-bottom: 40px !important;
}
#background .fpai-section-title .inv-tm { font-size: 0.5em; }

/* ── Closing section ──────────────────────────────────────────────────
   It now carries the same eyebrow -> title -> content shape as the other
   two, and needs real separation from the proof block above. */
.inv-final {
    padding-top: clamp(9rem, 19vh, 15rem) !important;
    padding-bottom: clamp(4.5rem, 10vh, 8rem) !important;
}
#contact .fpai-eyebrow { margin-bottom: 16px !important; }
#contact .fpai-section-title { margin-bottom: 18px !important; }
.inv-final .inv-cta-sub {
    max-width: 46ch;
    margin: 0 auto;
    line-height: 1.6;
}
.inv-final .fpai-cta-stage { margin-top: 26px; }

/* ── CTA label polish ─────────────────────────────────────────────────
   Problems, zoomed in at 3x:
     - straight typewriter apostrophe instead of a real one (now U+2019)
     - the label ran a 130deg gradient, which across a short bold string at
       21px reads as uneven colour rather than as a gradient
     - the arrow was solid indigo while the text ended violet, so they did
       not agree, and its 2.4 stroke was lighter than the letterforms
     - label was only 42% of the 460px stage, so it floated
   Solid deep indigo for both, larger, with the arrow weighted to match. */
.inv-final .cta-core-label {
    background: none;
    -webkit-background-clip: initial;
    background-clip: initial;
    -webkit-text-fill-color: #4338ca;
    color: #4338ca;
    font-size: 1.12rem;
    letter-spacing: -0.012em;
}
.inv-final .cta-core { gap: 0.62rem; font-size: 1.12rem; }
.inv-final .cta-core-arrow { color: #4338ca; }

/* ══════════════════════════════════════════════════════════════════════
   REVEAL CHOREOGRAPHY

   The cards previously entered as one flat block: fade + rise + slight
   scale, all parts moving together. Premium motion is layered — the
   surface arrives, then what is on it settles, and the material catches
   light as it lands.

   1. Cards tilt up in 3D (rotateX) out of a blur, on a spring with a
      little overshoot, staggered 130ms.
   2. Icon, title and copy each arrive behind their own card, so the card
      reads as a surface carrying content rather than a picture of one.
   3. A specular sweep runs across the glass once, as the card lands.
      --mx is registered with @property so it can actually be animated.
   ══════════════════════════════════════════════════════════════════════ */

@property --mx {
    syntax: '<percentage>';
    initial-value: 50%;
    inherits: false;
}

.inv-flow { perspective: 1400px; perspective-origin: 50% 30%; }

.inv-flow .fpai-pillar-card {
    opacity: 0;
    transform: translateY(42px) rotateX(10deg) scale(0.955);
    transform-origin: 50% 100%;
    filter: blur(7px);
    transition:
        opacity 780ms cubic-bezier(0.22, 1, 0.36, 1) var(--inv-delay, 0ms),
        transform 1050ms cubic-bezier(0.22, 1.14, 0.36, 1) var(--inv-delay, 0ms),
        filter 700ms cubic-bezier(0.22, 1, 0.36, 1) var(--inv-delay, 0ms),
        box-shadow 620ms cubic-bezier(0.16, 1, 0.3, 1),
        background 620ms cubic-bezier(0.16, 1, 0.3, 1);
}
.inv-flow.is-visible .fpai-pillar-card {
    opacity: 1;
    transform: translateY(0) rotateX(0) scale(1);
    filter: blur(0);
}
.inv-flow .fpai-pillar-card:nth-child(1) { --inv-delay: 0ms; }
.inv-flow .fpai-pillar-card:nth-child(2) { --inv-delay: 130ms; }
.inv-flow .fpai-pillar-card:nth-child(3) { --inv-delay: 260ms; }

/* Contents settle after their own card. */
.inv-flow .fpai-pillar-icon,
.inv-flow .fpai-pillar-title,
.inv-flow .fpai-pillar-desc {
    opacity: 0;
    transform: translateY(14px);
    transition:
        opacity 620ms cubic-bezier(0.22, 1, 0.36, 1) calc(var(--inv-delay, 0ms) + var(--inv-inner, 0ms)),
        transform 720ms cubic-bezier(0.22, 1.1, 0.36, 1) calc(var(--inv-delay, 0ms) + var(--inv-inner, 0ms));
}
.inv-flow .fpai-pillar-icon  { --inv-inner: 190ms; transform: translateY(14px) scale(0.86); }
.inv-flow .fpai-pillar-title { --inv-inner: 270ms; }
.inv-flow .fpai-pillar-desc  { --inv-inner: 340ms; }
.inv-flow.is-visible .fpai-pillar-icon,
.inv-flow.is-visible .fpai-pillar-title,
.inv-flow.is-visible .fpai-pillar-desc { opacity: 1; transform: translateY(0) scale(1); }

/* Light sweeps across the glass once, as the card lands. */
@keyframes inv-sweep {
    0%   { opacity: 0;    --mx: -25%; }
    22%  { opacity: 0.95; }
    100% { opacity: 0;    --mx: 125%; }
}
.inv-flow.is-visible .fpai-pillar-card .inv-sheen {
    animation: inv-sweep 1500ms cubic-bezier(0.22, 1, 0.36, 1) var(--inv-delay, 0ms) 1 both;
}
/* Hover still owns the sheen afterwards. */
.inv-flow .fpai-pillar-card:hover .inv-sheen { animation: none; opacity: 1; }

/* Stats and the article card get the same family of entrance. */
.inv-stats .fpai-stat-card {
    opacity: 0;
    transform: translateY(24px) scale(0.97);
    transition:
        opacity 700ms cubic-bezier(0.22, 1, 0.36, 1) var(--s-delay, 0ms),
        transform 900ms cubic-bezier(0.22, 1.12, 0.36, 1) var(--s-delay, 0ms);
}
.inv-stats.is-visible .fpai-stat-card { opacity: 1; transform: translateY(0) scale(1); }
.inv-stats .fpai-stat-card:nth-child(1) { --s-delay: 0ms; }
.inv-stats .fpai-stat-card:nth-child(2) { --s-delay: 120ms; }
.inv-stats .fpai-stat-card:nth-child(3) { --s-delay: 240ms; }

.article-card.reveal {
    opacity: 0;
    transform: translateY(34px) rotateX(6deg) scale(0.975);
    transform-origin: 50% 100%;
    filter: blur(5px);
    transition:
        opacity 760ms cubic-bezier(0.22, 1, 0.36, 1),
        transform 1000ms cubic-bezier(0.22, 1.12, 0.36, 1),
        filter 680ms cubic-bezier(0.22, 1, 0.36, 1),
        box-shadow 300ms ease, border-color 300ms ease;
}
.article-card.reveal.is-visible { opacity: 1; transform: none; filter: blur(0); }

@media (prefers-reduced-motion: reduce) {
    .inv-flow .fpai-pillar-card,
    .inv-flow .fpai-pillar-icon,
    .inv-flow .fpai-pillar-title,
    .inv-flow .fpai-pillar-desc,
    .inv-stats .fpai-stat-card,
    .article-card.reveal {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        transition: none !important;
    }
    .inv-flow.is-visible .fpai-pillar-card .inv-sheen { animation: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   CTA CAPSULE

   The label was bare text floating at the centre of the medallion, while
   every other surface on the page is glass. That is why it read as
   unintegrated: it is a button, and it was the only control not made of
   the site's material.

   It becomes a liquid-glass capsule built from the same system as the
   cards — the same lens filter, the same specular rim, the same lift on
   hover — so the CTA belongs to the page rather than sitting on top of it.
   ══════════════════════════════════════════════════════════════════════ */

.inv-final .cta-core {
    padding: 0.75rem 1.4rem;
    border-radius: 999px;
    isolation: isolate;
    background:
        linear-gradient(158deg,
            rgba(255, 255, 255, 0.78) 0%,
            rgba(255, 255, 255, 0.52) 48%,
            rgba(255, 255, 255, 0.66) 100%);
    -webkit-backdrop-filter: blur(22px) saturate(165%);
    backdrop-filter: blur(22px) saturate(165%);
    box-shadow:
        inset 0 1.5px 0.5px rgba(255, 255, 255, 1),
        inset 1.5px 0 0.5px rgba(255, 255, 255, 0.75),
        inset 0 -14px 22px -20px rgba(30, 41, 89, 0.32),
        0 2px 4px rgba(30, 41, 89, 0.07),
        0 14px 28px -12px rgba(49, 46, 129, 0.24),
        0 34px 60px -30px rgba(49, 46, 129, 0.30);
    transition:
        transform 620ms cubic-bezier(0.16, 1, 0.3, 1),
        box-shadow 620ms cubic-bezier(0.16, 1, 0.3, 1),
        background 620ms cubic-bezier(0.16, 1, 0.3, 1);
}
@supports (backdrop-filter: url(#invGlassLens)) {
    .inv-final .cta-core {
        -webkit-backdrop-filter: url(#invGlassLens) blur(2px) saturate(165%);
        backdrop-filter: url(#invGlassLens) blur(2px) saturate(165%);
    }
}

/* Gradient hairline, same masked-ring technique as the cards. */
.inv-final .cta-core::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(148deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, 0.6) 22%,
        rgba(199, 210, 254, 0.42) 54%,
        rgba(129, 140, 248, 0.24) 80%,
        rgba(255, 255, 255, 0.4) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    z-index: -1;
}
/* The existing ::before bloom now pools behind the capsule. */
.inv-final .cta-core::before { z-index: -2; }

.inv-final .fpai-cta-stage:hover .cta-core {
    transform: translateY(-3px);
    background:
        linear-gradient(158deg,
            rgba(255, 255, 255, 0.94) 0%,
            rgba(255, 255, 255, 0.70) 48%,
            rgba(255, 255, 255, 0.82) 100%);
    box-shadow:
        inset 0 1.5px 0.5px rgba(255, 255, 255, 1),
        inset 1.5px 0 0.5px rgba(255, 255, 255, 0.9),
        inset 0 -16px 26px -20px rgba(30, 41, 89, 0.28),
        0 2px 4px rgba(30, 41, 89, 0.08),
        0 20px 38px -14px rgba(49, 46, 129, 0.30),
        0 52px 84px -34px rgba(49, 46, 129, 0.36);
}
