/* ─────────────────────────────────────────────────────────────────────────
   fpai-site.css — chrome for the standalone First-Party AI™ site ONLY.

   The page body itself is customernode.com/about/first-party-ai, ported
   verbatim, styled by dist/css/fpai-v3.css (a copy of the real stylesheet).
   This file supplies ONLY what landing_base.css would have provided there:
   a page reset, a minimal header/footer, and the theme surface.

   Keep this small. Anything that belongs to the FPAI page's own look belongs
   in fpai-v3.css so it stays in sync with the real page. See README.md.
   ───────────────────────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

/* The FPAI page is DARK by design — fpai-v3.css paints a near-black canvas and
   light text, regardless of theme. But style-variables.css resolves to the LIGHT
   token set (--inv-bg-color: #202F39), so anything here using that token renders
   dark-on-dark and disappears. Declare our own ink instead of flipping the
   tokens — the ported page depends on them and must not be disturbed. */
body.fpai-standalone {
    --fpai-ink: #f1f5f9;
    --fpai-canvas: #050509;
}

html, body {
    margin: 0;
    padding: 0;
    background: var(--fpai-canvas, #050509);
    color: var(--fpai-ink, #f1f5f9);
    font-family: var(--font-main, 'Satoshi', system-ui, sans-serif);
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
}

img { max-width: 100%; }
a { color: inherit; }

/* ── Hero CTA — deliberately larger here than on customernode.com ──────────
   Two reasons it earns the extra weight on this site specifically:

   1. It is this page's ONLY job. There is no nav and no other conversion path;
      the whole site exists to route to CustomerNode™.
   2. TRADEMARK: the CTA is what creates the "direct association between the
      mark and the identified services" that TMEP § 1301.04 requires of a
      specimen (the Exhibit H argument for Serial No. 99073401). If a
      substitute specimen is ever needed, this button is the thing being
      photographed — it should be unmissable in the screenshot.

   Override lives HERE, not in fpai-v3.css: that file is a verbatim copy of the
   real stylesheet and must stay re-syncable from customerNode_root. ── */
.fpai-hero .fpai-btn-primary {
    padding: 1.15rem 2.9rem;
    font-size: 1.05rem;
    gap: 0.7rem;
    letter-spacing: 0.01em;
}
.fpai-hero .fpai-btn-primary svg {
    width: 24px;
    height: 24px;
}


/* ── Section seam ─────────────────────────────────────────────────────────
   Each section paints its glow with `inset: 0`, so the radial gradient is
   clipped to the section box and stops dead at the boundary — a tonal step
   straight across the page where two lit sections meet.

   Fixed by fading the bg layers out at the top and bottom, so the sections
   blend. NO divider line here: the hero's lit hairline marks the one edge
   that earns it. Repeating it at every seam turns a signature into wallpaper,
   and the Problem→Solution transition should be felt, not announced. ── */
.fpai-crisis-bg,
.fpai-introduce-bg {
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
}

/* .fpai-section-subtitle has `margin: 0 auto`, which centres the BOX but leaves
   the text left-aligned. The h2 has a --centered modifier; the subtitle has no
   equivalent, so it silently mismatches the centred heading above it. */
.fpai-crisis .fpai-section-subtitle,
.fpai-introduce .fpai-section-subtitle {
    text-align: center;
}

/* ── The shared model (Problem) ────────────────────────────────────────────
   The inverse of the Solution's orbit, and deliberately quieter.

   Solution: one sealed machine at the top, radiating DOWN to the five people.
   Problem:  the five people at the top, converging DOWN into a model that is
             not theirs — and that four other companies are feeding too.

   The direction of the relationship flips. That is the argument as composition,
   so it needs no sentence. It must NOT compete with the orbit for intensity:
   the problem is dead (grey, static, no glow), the solution is alive. Balance
   by presence, not by volume. ── */
.fpai-shared {
    max-width: 640px;
    margin: clamp(2.5rem, 5vw, 3.75rem) auto 0;
}
.fpai-shared-row {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
}
.fpai-shared-co {
    flex: 1 1 0;
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
    padding: 0.5rem 0.35rem;
    border-radius: 8px;
    background: color-mix(in srgb, var(--fpai-ink) 3%, transparent);
    border: 1px solid color-mix(in srgb, var(--fpai-ink) 7%, transparent);
    color: color-mix(in srgb, var(--fpai-ink) 30%, transparent);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* You are in here too — the only one lit, and it changes nothing. */
.fpai-shared-co--you {
    color: color-mix(in srgb, var(--fpai-ink) 68%, transparent);
    border-color: color-mix(in srgb, var(--fpai-ink) 16%, transparent);
    background: color-mix(in srgb, var(--fpai-ink) 5%, transparent);
}
.fpai-shared-wires {
    display: block;
    width: 100%;
    height: 72px;
}
.fpai-shared-wires path {
    fill: none;
    stroke: color-mix(in srgb, var(--fpai-ink) 13%, transparent);
    stroke-width: 1;
}
.fpai-shared-model {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    padding: 0.9rem 1.25rem;
    max-width: 260px;
    margin: 0 auto;
    border-radius: 12px;
    background: color-mix(in srgb, var(--fpai-ink) 4%, transparent);
    border: 1px solid color-mix(in srgb, var(--fpai-ink) 9%, transparent);
    text-align: center;
}
.fpai-shared-model-label {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: 0.92rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: color-mix(in srgb, var(--fpai-ink) 62%, transparent);
}
.fpai-shared-model-sub {
    font-size: 0.72rem;
    color: color-mix(in srgb, var(--fpai-ink) 34%, transparent);
}
@media (max-width: 640px) {
    .fpai-shared-co { font-size: 0.5rem; letter-spacing: 0.04em; }
    .fpai-shared-wires { height: 52px; }
}

/* ══ ROLE GRID — the before/after ═══════════════════════════════════════════
   THE STRUCTURE IS THE ARGUMENT. Two grids, the same five people, in the same
   order. Third-party AI is what they say now; First-Party AI™ is what they say
   instead. The reader maps role-to-role without being told, so the contrast
   defines the mark — no sentence has to.

   This is load-bearing twice: it's the product position, and it's the trademark
   position (Serial 99073401 §B — the mark reads differently to an executive,
   a seller, IT, legal, and an operator). Do NOT reduce this to one grid, and do
   NOT let the two fall out of sync — the mirror IS the point.

   Built from fpai-v3.css's OWN tokens (--fpai-card-bg/-border/-gradient/-glow)
   rather than reusing .fpai-agent-card, which is opacity:0 until a
   .fpai-layer--active parent animates it. Same language, no hidden contract. ══ */
.fpai-role-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    margin-top: clamp(2.25rem, 4vw, 3.25rem);
}
.fpai-role {
    flex: 1 1 176px;
    max-width: 208px;
    padding: 1.6rem 1.1rem 1.25rem;
    border-radius: 16px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
/* A FACE, not a pictogram. A universal "user" glyph is the icon for an ACCOUNT
   — it reads cold because it's a placeholder for a person, not a person. These
   are the brand's own illustrated portraits (customerNode_root static/img/
   personN.png, previously unused anywhere).

   The before/after is carried by the SAME FIVE FACES: drained of colour under
   third-party AI, in full colour under First-Party AI™. Do not swap one grid's
   cast without the other — the mirror is the argument.

   CASTING IS RANDOM, ON PURPOSE. The face-to-role assignment was drawn from a
   seeded shuffle of the brand's portrait set. It carries no meaning and is not
   curated. An earlier pass hand-picked "role-appropriate" faces and produced
   exactly the default you'd expect — the white man as the executive, in the
   first slot. Every judgment about which face suits which role is a stereotype
   with extra steps.

   The one hand-correction: the shuffle put the woman in glasses on IT, which
   is the exact stereotype the randomisation exists to avoid — swapped with the
   seller. Correcting a roll that lands ON a stereotype is not the same as
   casting FOR one.

   So: if a future edit feels like a face doesn't "look like" an executive /
   a lawyer / an engineer — that instinct is the bug, not the casting. Re-roll
   the whole set or leave it alone; do not re-cast individual roles. */
.fpai-role-glyph {
    position: relative;
    width: 56px; height: 56px;
    margin-bottom: 1.1rem;
}
.fpai-role-face {
    width: 56px; height: 56px;
    border-radius: 50%;
    object-fit: cover;
    object-position: 50% 22%;   /* portraits are 67x101 — bias to the face */
    display: block;
    transition: filter 0.45s ease, opacity 0.45s ease;
}
.fpai-role-badge {
    position: absolute;
    right: -4px; bottom: -2px;
    width: 22px; height: 22px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 0 0 2.5px var(--fpai-canvas, #050509);
}
.fpai-role-badge svg { width: 10px; height: 10px; }
.fpai-role-line {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: 1.02rem; font-weight: 600; letter-spacing: -0.015em;
    line-height: 1.3; margin: 0 0 0.5rem;
}
.fpai-role-sub {
    font-size: 0.78rem; line-height: 1.5; margin: 0 0 1.1rem;
    flex: 1;
}
.fpai-role-who {
    font-family: var(--brand-font, 'Space Grotesk', sans-serif);
    font-size: 0.6rem; font-weight: 600;
    letter-spacing: 0.16em; text-transform: uppercase;
}

/* ── BEFORE: third-party. Flat, unlit, colourless — the emotional floor.
      No glow, no gradient, no lift on hover. Nothing here is yours. ── */
.fpai-role--cold {
    background: color-mix(in srgb, var(--fpai-ink) 2.5%, transparent);
    border: 1px solid color-mix(in srgb, var(--fpai-ink) 7%, transparent);
}
.fpai-role--cold .fpai-role-face {
    filter: grayscale(1) brightness(0.62) contrast(0.9);
    opacity: 0.55;
}
.fpai-role--cold .fpai-role-badge {
    background: color-mix(in srgb, var(--fpai-ink) 10%, var(--fpai-canvas, #050509));
    color: color-mix(in srgb, var(--fpai-ink) 34%, transparent);
}
.fpai-role--cold .fpai-role-line { color: color-mix(in srgb, var(--fpai-ink) 62%, transparent); }
.fpai-role--cold .fpai-role-sub  { color: color-mix(in srgb, var(--fpai-ink) 38%, transparent); }
.fpai-role--cold .fpai-role-who  { color: color-mix(in srgb, var(--fpai-ink) 28%, transparent); }

/* ── AFTER: first-party. The brand arrives — glass, gradient glyph, lit edge,
      and it lifts. Same card, same grid slot: only the answer changed. ── */
.fpai-role--lit {
    background: var(--fpai-card-bg, color-mix(in srgb, #f1f5f9 4%, #06060e));
    border: 1px solid color-mix(in srgb, var(--indigo, #4f46e5) 26%, transparent);
    box-shadow: 0 18px 40px -24px var(--fpai-glow, rgba(99,102,241,0.2)),
                inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent);
}
.fpai-role--lit:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--indigo, #4f46e5) 44%, transparent);
    box-shadow: 0 26px 54px -22px var(--fpai-glow-strong, rgba(99,102,241,0.4)),
                inset 0 1px 0 color-mix(in srgb, #fff 12%, transparent);
}
.fpai-role--lit .fpai-role-face {
    filter: none;
    opacity: 1;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--indigo, #4f46e5) 55%, transparent),
                0 10px 24px -8px var(--fpai-glow-strong, rgba(99,102,241,0.4));
}
.fpai-role--lit .fpai-role-badge {
    background: var(--fpai-gradient-soft, linear-gradient(135deg, #4f46e5, #6366f1));
    color: #fff;
}
.fpai-role--lit .fpai-role-line { color: var(--fpai-ink); }
.fpai-role--lit .fpai-role-sub  { color: color-mix(in srgb, var(--fpai-ink) 62%, transparent); }
.fpai-role--lit .fpai-role-who  { color: color-mix(in srgb, var(--indigo, #4f46e5) 92%, var(--fpai-ink)); }

@media (max-width: 640px) {
    .fpai-role { flex: 1 1 100%; max-width: 340px; }
}

/* ── The "What is First-Party AI™?" block (the definitional SEO section).
      Plain type — the answer is the asset, not the styling. ── */
/* The FAQ was ID-scoped (`#first-party-ai-definition h2/h3/p/a`) when it was a raw
   stack of headings and paragraphs. Those selectors are gone: an ID (1,0,1)
   outranks every class rule below, so the block silently won every fight and the
   card layout could not set its own spacing. It also carried two self-cancelling
   declarations -- `margin-top: 2.75rem` immediately overridden by a `margin`
   shorthand, and `margin-left/right: auto` overridden the same way, which killed
   the centring it was asking for. Dead intent from a layout that no longer
   exists. Everything it did is now done by the .fpai-faq-* classes. */
.fpai-faq { text-align: center; }
.fpai-faq .fpai-section-inner--narrow { max-width: 720px; }

/* ── Footer: links home + the trademark notice. No year (it would rot). ── */

/* ── Safety net: the ported markup uses .reveal, which fpai-v3.css sets to
      opacity:0 until fpai-v3.js adds .is-visible. If that JS ever fails
      to load here, the entire page would be invisible — a blank #1 result.
      Anything still unrevealed after load gets forced visible. ── */
html.reveal-failsafe .reveal,
html.reveal-failsafe .reveal-card {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
}


/* ══ PATENT ARTICLE CARD ═══════════════════════════════════════════════════
   Ported verbatim from customerNode_root/customerNode_site/static/css/public/
   index_v6.css (.article-card*), where the same card sits in the Defensibility
   section of the home page. Same component, same look, one design.

   The href is a CONTRACT: it must equal
   brand/linkedin-series/published/06-patent-portfolio-announcement/link.txt.
   Guarded by customerNode_root → core/testing/backend/public/
   test_patent_article_url_contract.py, which fails if the two drift. See
   README.md § Outbound contracts. ══ */
.article-card {
    display: flex;
    text-align: left;
    text-decoration: none !important;
    border-radius: 20px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--inv-bg-color) 9%, transparent);
    background: color-mix(in srgb, var(--purple) 2%, var(--main-bg-color));
    box-shadow: 0 4px 24px color-mix(in srgb, var(--inv-bg-color) 4%, transparent);
    transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}

.article-card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--purple) 28%, transparent);
    box-shadow: 0 18px 50px color-mix(in srgb, var(--purple) 12%, transparent);
}

.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: 1.75rem 2rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.55rem;
}

.article-card-meta {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--inv-bg-color);
    opacity: 0.5;
}

.article-card-meta svg {
    width: 14px;
    height: 14px;
    color: #0a66c2;
    opacity: 0.9;
    flex: none;
}

.article-card-title {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--inv-bg-color);
    margin: 0;
}

.article-card-teaser {
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--inv-bg-color);
    opacity: 0.6;
    margin: 0;
}

.article-card-readmore {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.4rem;
    font-size: 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);
}


.article-card--featured .article-card-meta svg {
    color: #6366f1;
}
@media (max-width: 640px) {
    .article-card { flex-direction: column; }
    .article-card-media { flex: none; width: 100%; aspect-ratio: 1200 / 628; }
    .article-card-body { padding: 1.5rem 1.5rem 1.75rem; }
    .article-card-title { font-size: 1.3rem; }
}

/* The card lives on a dark canvas here; index_v6.css themes it from the page
   tokens, which resolve LIGHT. Re-ink it the way the rest of this site is. */
.fpai-defensible .article-card {
    --inv-bg-color: #f1f5f9;
    max-width: 720px;
    margin: clamp(2.5rem, 5vw, 3.5rem) auto 0;
    background: color-mix(in srgb, var(--fpai-ink) 3%, transparent);
    border-color: color-mix(in srgb, var(--fpai-ink) 9%, transparent);
    text-align: left;
}
.fpai-defensible .article-card:hover {
    border-color: color-mix(in srgb, var(--indigo, #4f46e5) 34%, transparent);
    box-shadow: 0 18px 44px -26px var(--fpai-glow-strong, rgba(99,102,241,0.4));
}
/* The meta glyph is the LinkedIn mark, so it wears LinkedIn blue -- matching
   card 2 on the customernode index (that card is --hub, so it never takes the
   `--featured` indigo repaint). Lightened from the brand #0a66c2, which goes
   muddy against this near-black canvas. */
.fpai-defensible .article-card-meta svg { color: #4d9fe8; }
.fpai-defensible .article-card-readmore { color: #a78bfa; }

/* -- FAQ / "What is First-Party AI(TM)?" ------------------------------
   The single highest-leverage block on the page, and it shipped as raw
   <h2>/<h3>/<p> with no classes -- default browser link styling and all.

   Its reader is a MACHINE and a skeptic, not someone who just felt something:
     - the <h2> is the exact head term this domain ranks #1 for,
     - it is the FAQPage JSON-LD source,
     - it is the text a model quotes when asked "what is First-Party AI",
       which is the fix for the wedge-slot misclassification.

   So it is designed to look intentional without looking sold: quiet chrome, a
   prominent lead answer (that one IS the definition), two supporting answers,
   a ghost exit. THE COPY IS FROZEN -- Google requires FAQPage structured data
   to match visible text, so this is a restyle only. */
/* The lead answer is the definition -- the sentence that gets quoted. It gets
   size and measure the two supporting answers do not. */
.fpai-faq .fpai-faq-lead {
    max-width: 46ch;
    margin: 0 auto;
    text-align: center;
    font-family: var(--font-main);
    font-size: 1.12rem;
    line-height: 1.6;
    color: color-mix(in srgb, var(--fpai-ink) 62%, transparent);
}
.fpai-faq .fpai-faq-lead strong {
    font-family: var(--brand-font);
    font-weight: 600;
    color: var(--fpai-ink);
}


.fpai-faq .fpai-faq-foot {
    margin-top: 2.25rem;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
}

@media (max-width: 720px) {
    .fpai-faq .fpai-faq-lead { font-size: 1rem; }
}

/* -- Hero: full-screen on mobile -------------------------------------
   fpai-v3.css sets `min-height: auto` on .fpai-hero below 768px, plus 120px /
   80px of vertical padding. That is correct on customernode.com, where this
   hero is one section inside a longer page sitting under a fixed nav. Here it
   is the landing hero of a STANDALONE page and the topnav was removed -- so the
   120px cleared nothing and the hero stopped ~300px short of the fold on a
   390x844 phone.

   Fixed here rather than in fpai-v3.css: that file is a verbatim, re-syncable
   copy of the customernode styles. Every deviation for this site lives in this
   file, which loads after it.

   svh, NOT vh: iOS Safari resolves 100vh against the viewport with the URL bar
   RETRACTED, so a 100vh hero is taller than the screen on load and the scroll
   cue lands underneath the browser chrome. 100svh is the small viewport -- it
   always fits. vh first as the fallback for browsers without svh. NOT dvh:
   that reflows as the chrome hides on scroll, which visibly jitters the hero.

   The scroll cue is position:absolute / bottom:2.5rem, so it pins to the hero's
   bottom edge and is unaffected by dropping the padding. */
@media (max-width: 768px) {
    .fpai-hero {
        min-height: 100vh;
        min-height: 100svh;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
    }
}

/* Landscape phones: a full-height hero is only ~390px tall, which the title +
   sub + CTA cannot fit. Let it grow with its content instead of clipping. */
@media (max-width: 900px) and (orientation: landscape) and (max-height: 500px) {
    .fpai-hero {
        min-height: auto;
        padding-top: 5rem !important;
        padding-bottom: 4rem !important;
    }
}

/* -- Site footer -----------------------------------------------------
   The CONTENT here is the original four links + the trademark line, and it
   stays that way on purpose. customernode.com's `footer-v2` was ported in
   briefly and reverted: it dragged 12 customernode.com URLs onto a site that
   nothing in this repo can test and that we do not watch. Four links is the
   whole outbound surface, and each one is a route that will outlive us.

   What IS borrowed from footer-v2 is the treatment only -- the gradient top
   hairline, the ambient glow, the wipe-underline hover, the fine-print tone.
   Same visual language as the main site, none of its maintenance.

   No year: this is a static file with no template engine, and a hardcoded year
   rots the moment we forget this repo (which we did, for three years). A
   yearless copyright is valid and ages forever.

   Reveal rides fpai-v3.js's existing `.reveal` + `data-reveal-container`, so
   the `html.reveal-failsafe` net already covers it. */
footer.fpai-site-footer {
    --fsf-purple: #7873F5;
    --fsf-blue: #60a5fa;
    --fsf-ink: #f1f5f9;
    --fsf-text: #94a3b8;
    --fsf-faint: color-mix(in srgb, #475569 90%, #000);
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background:
        radial-gradient(115% 130% at 50% -15%, rgba(120, 115, 245, 0.11) 0%, rgba(120, 115, 245, 0.03) 32%, rgba(0, 0, 0, 0) 62%),
        linear-gradient(180deg, #05050b 0%, #000000 58%);
    padding: 3.75rem 0 2.25rem;
}

/* Gradient hairline + soft glow across the very top edge -- the signature
   detail carried over from the main site's footer. */
footer.fpai-site-footer::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background: linear-gradient(90deg,
        rgba(120, 115, 245, 0) 0%,
        rgba(120, 115, 245, 0.55) 24%,
        rgba(96, 165, 250, 0.6) 52%,
        rgba(212, 144, 255, 0.5) 78%,
        rgba(120, 115, 245, 0) 100%);
    box-shadow: 0 0 14px rgba(120, 115, 245, 0.35);
    z-index: 2;
}

footer.fpai-site-footer .fpai-site-footer-inner {
    position: relative;
    z-index: 1;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

footer.fpai-site-footer .fpai-site-footer-nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem 2.1rem;
}

footer.fpai-site-footer .fpai-site-footer-nav li {
    position: relative;
    display: flex;
    align-items: center;
}

/* Hairline dot between links -- replaces the old literal "·" characters, so
   the separators disappear cleanly when the row wraps on mobile. */
footer.fpai-site-footer .fpai-site-footer-nav li + li::before {
    content: "";
    position: absolute;
    left: -1.05rem;
    top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 3px;
    border-radius: 50%;
    background: var(--fsf-faint);
}

footer.fpai-site-footer .fpai-site-footer-nav a {
    position: relative;
    display: inline-block;
    color: var(--fsf-text);
    text-decoration: none !important;
    font-family: var(--font-main);
    font-size: 0.88rem;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: 0.01em;
    transition: color 0.22s ease;
}

/* Gradient underline wipes in from the left on hover. */
footer.fpai-site-footer .fpai-site-footer-nav a::after {
    content: "";
    position: absolute;
    left: 0; bottom: -4px;
    width: 100%;
    height: 1px;
    background: linear-gradient(90deg, var(--fsf-purple), var(--fsf-blue));
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
footer.fpai-site-footer .fpai-site-footer-nav a:hover { color: var(--fsf-ink); }
footer.fpai-site-footer .fpai-site-footer-nav a:hover::after { transform: scaleX(1); }

footer.fpai-site-footer .fpai-site-footer-divider {
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1) 18%, rgba(255, 255, 255, 0.1) 82%, transparent);
    margin: 2.25rem 0 1.5rem;
}

/* Scoped so it beats any generic `p` rule; this is legal fine print and must
   never render as body text. */
footer.fpai-site-footer .fpai-site-legal {
    margin: 0;
    text-align: center;
    font-family: var(--font-main);
    font-size: 0.68rem;
    line-height: 1.6;
    letter-spacing: 0.01em;
    color: var(--fsf-faint);
}

footer.fpai-site-footer a:focus-visible {
    outline: 2px solid rgba(120, 115, 245, 0.7);
    outline-offset: 3px;
    border-radius: 4px;
}

@media (max-width: 640px) {
    footer.fpai-site-footer { padding: 3rem 0 2rem; }
    footer.fpai-site-footer .fpai-site-footer-nav ul { gap: 0.9rem 1.6rem; }
    footer.fpai-site-footer .fpai-site-footer-nav li + li::before { left: -0.85rem; }
    footer.fpai-site-footer .fpai-site-footer-divider { margin: 1.9rem 0 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
    footer.fpai-site-footer .fpai-site-footer-nav a,
    footer.fpai-site-footer .fpai-site-footer-nav a::after {
        transition: color 0.2s ease;
        transform: none !important;
    }
}
