/* ============================================================================
   PRODUCTS — incontrol (products.html) · page-specific styles
   ----------------------------------------------------------------------------
   Shared core (tokens, navbar, buttons, footer, reveal, reduced-motion) lives
   in css/styles.css — this file styles the .pr-* sections of the Products page,
   built 1:1 from the Figma exports. 1440 design, fluid 1280–1600 per the site
   standard. Namespace: .pr-*.
   ============================================================================ */

/* ============================================================
   PR §1 · HERO — pill + H1 + lead + two CTAs (section.page-hero.svg)
   design: full-width warm gradient band, a centred ~820 content column,
   left-aligned text; section ~560px tall under the 74px navbar.
   ============================================================ */
.pr-hero {
  background: linear-gradient(180deg, #FFF5F0 0%, var(--bg) 100%);
  padding: 96px 0 80px;
}
.pr-hero__inner {
  /* centred ~785 content column (the design's h1 needs 785 for its 2-line wrap);
     shrinks with the gutter on narrower screens */
  width: min(785px, calc(100% - 2 * var(--gutter)));
  margin-inline: auto;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 15px;
}
.pr-hero__h1 {
  margin: 0; max-width: 785px;
  font-size: 56px; font-weight: 400; line-height: 59px;
  letter-spacing: -1.568px; color: var(--text-strong);
}
.pr-hero__lead {
  margin: 8px 0 0; max-width: 706px;
  font-size: 19px; font-weight: 400; line-height: 29px;
  letter-spacing: -0.32px; color: var(--text);
}
.pr-hero__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 17px; }
.pr-btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 22px; border-radius: 999px;
  font-size: 15px; font-weight: 500; line-height: 1;
  letter-spacing: -0.32px; text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.pr-btn--primary { background: var(--brand); color: #fff; }   /* #FF5F16 by marketing's decision (2026-10-13); the AA shade --brand-strong before it */
.pr-btn--primary:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(0, 0, 0, .2); }
.pr-btn--primary svg { transition: transform .2s ease; }
.pr-btn--primary:hover svg { transform: translateX(3px); }
.pr-btn--ghost { border: 1px solid rgba(10, 23, 51, 0.15); color: var(--text-strong); }
.pr-btn--ghost:hover { border-color: var(--text-strong); }

/* ============================================================
   PR §2 · MONITOR — browser window wrapping the LIVE incontrol
   dashboard (the site's own .dash--screen rebuild, not a raster)
   ============================================================ */
.pr-monitor { background: var(--bg); padding: 8px 0 120px; }
.pr-window {
  width: min(1100px, calc(100% - 2 * var(--gutter)));   /* design: 170px side margins at 1440 */
  margin-inline: auto;
  box-sizing: border-box;
  background: #0B0B0B;
  border-radius: 20px;
  box-shadow: 0 40px 80px rgba(10, 23, 51, 0.18);
  padding: 18px;
}
.pr-window__bar { display: flex; gap: 6px; height: 10px; margin-bottom: 14px; }   /* 18 + 10 + 14 = 42 (design screen top) */
.pr-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--c); flex: none; }
.pr-window__screen {
  position: relative;             /* .dash--screen fills this via inset:0 */
  aspect-ratio: 1064 / 574;
  border-radius: 10px;
  overflow: hidden;
  background: var(--card);
}
/* Progressive screen blur (2026-10-14, marketing correction 26 = the deck's slide 29 «Add blur»; the user:
   «add the same blur … as we have in the hero page»): the landing monitor's technique and ramp — main.js
   overlays five blurred .monitor__blurclone copies of the dashboard in this screen too, and the layer rules
   live in styles.css. Keep these three values equal to .monitor__screen's (styles.css, "TUNE THE SCREEN BLUR"). */
.pr-window__screen { --blur-top: 37%; --blur-bottom: 96%; --blur-max: 12; }

/* ---- .dash--window: products-page tweaks vs the landing monitor ---- */
.dash--window .sbar__actions { margin-right: 0; }   /* landing clipped the tabs at screen-x 690; here show them all */
.dash--window .sside__foot { margin-top: auto; }    /* push Settings/Log out to the sidebar bottom */
.dash--window .snav--danger,
.dash--window .snav--danger .snav__ico { color: #e5484d; }   /* Log out = red */

/* ---- the big "Gross Fees by Scheme in EUR" chart card, 1:1 with
   "incontrol dashboard (2).svg" (correction 24, 2026-10-14). Values measured
   from the export's 2987×1913 screenshot at the screen's 1064 scale; the
   card keeps ITS size (the row height belongs to the other cards) — the
   title + pill keep the design's insets from the top, the month labels the
   design's distance from the bottom, the plot fills the room in between.
   Scoped to .dash--window: the landing monitor shares these classes. ---- */
.dash--window .chart {
  --cw-ink: #0e1624; --cw-label: #565656; --cw-grid: #f1f1f1;
  --cw-pill-line: #f1f1f1; --cw-pill-ink: #7d7d7d;
  --cw-orange: #ff860d; --cw-blue: #006cff;
  --cw-oarea: rgba(255, 134, 13, .4); --cw-oarea-0: rgba(255, 134, 13, 0);
  --cw-barea: #dfe0e5; --cw-barea-0: var(--card);   /* the blue series' fill is opaque: it hides the orange area below it */
  position: relative; display: block; padding: 0; gap: 0;
}
:root[data-theme="dark"] .dash--window .chart {
  --cw-ink: var(--ink); --cw-label: var(--muted); --cw-grid: var(--grid);
  --cw-pill-line: var(--line); --cw-pill-ink: var(--muted);
  --cw-orange: var(--line-orange); --cw-blue: var(--line-blue);
  --cw-oarea: rgba(255, 120, 66, .4); --cw-oarea-0: rgba(255, 120, 66, 0);
  --cw-barea: #1e2a45;
}
.dash--window .chart .chart__head { display: block; }
.dash--window .chart .cap {
  position: absolute; left: 16.6px; top: 23.2px;
  font-size: 13px; font-weight: 600; line-height: 20px; letter-spacing: 0; color: var(--cw-ink); white-space: nowrap;
}
.dash--window .chart .search {
  position: absolute; right: 18px; top: 17.5px; width: 88.3px; height: 29.6px; box-sizing: border-box;
  padding: 0 0 0 9.9px; gap: 6.6px; background: var(--card); border: 1px solid var(--cw-pill-line);
  color: var(--cw-pill-ink); font-size: 10px; line-height: 1;
}
.dash--window .chart .search .ico { width: 12px; height: 12px; color: var(--cw-pill-ink); }
.dash--window .chart .chart__plot { display: block; }
.dash--window .chart .yaxis {
  position: absolute; left: 16.6px; top: 70.2px; bottom: 25.5px; padding: 0;
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start;
  font-size: 7.5px; line-height: 10px; color: var(--cw-label); text-align: left;
}
.dash--window .chart svg.plot {
  position: absolute; left: 49.2px; top: 70px;
  width: calc(100% - 72.4px); height: calc(100% - 99.5px); overflow: visible;   /* an inline svg sizes like a replaced element: no left+right stretch */
}
.dash--window .chart .plot line,
.dash--window .chart .plot polyline { vector-effect: non-scaling-stroke; }
.dash--window .chart .plot__line { stroke-width: 1; stroke-dasharray: 1.25 1.6; stroke-linejoin: round; }
.dash--window .chart .xaxis {
  position: absolute; left: 49.2px; right: 23.2px; bottom: 18.7px; height: 10px; padding: 0;
  display: block; font-size: 7.5px; line-height: 10px; color: var(--cw-label);
}
.dash--window .chart .xaxis span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }

/* ============================================================
   PR §3 · MODULES — "One platform, two specialized engines".
   A tabbed card (Fee Manager / Interchange Hub) swapping copy + a
   product-mockup widget. Built 1:1 from section#modules.svg.
   ============================================================ */
.pr-mod { background: var(--bg); padding: 100px 0 120px; }

.pr-eyebrow {
  display: block;
  font-size: 13px; font-weight: 500; line-height: 17px;
  letter-spacing: 0.78px; text-transform: uppercase;
  color: var(--brand);   /* #FF5F16 by marketing's decision (2026-10-13); the AA shade #c03e0b before it */
}

/* ---- section head (centred) ---- */
.pr-mod__head {
  width: min(640px, calc(100% - 2 * var(--gutter)));
  margin-inline: auto;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 16px;
}
.pr-mod__head .pr-eyebrow { text-align: center; }
.pr-mod__h2 {
  margin: 0; max-width: 520px;
  font-size: 40px; font-weight: 400; line-height: 46px;
  letter-spacing: -1px; color: var(--text-strong);
}
.pr-mod__lead {
  margin: 0; max-width: 600px;
  font-size: 18px; font-weight: 400; line-height: 28px;
  letter-spacing: -0.32px; color: var(--text);
}

/* ---- the card ---- */
.pr-mod__card {
  box-sizing: border-box;
  width: min(1200px, calc(100% - 2 * var(--gutter)));
  margin: 64px auto 0;
  display: flex; gap: 60px;
  padding: 41px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(10, 23, 51, 0.04), 0 8px 24px rgba(10, 23, 51, 0.06);
  border-radius: 24px;
}

/* ---- tabs (left rail) ---- */
.pr-mod__tabs { flex: 1 1 260px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }   /* 09-19: flex-shrink 1 (was 0 0 260) — the tabs column's slack (pill 193 wide) absorbs the card's 22px shrink at the 1280 floor, so the PANEL keeps its design width at every viewport */
.pr-mtab {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 14px 18px; border: 0; border-radius: 12px;
  background: transparent; cursor: pointer; font-family: inherit;
  font-size: 15px; font-weight: 500; line-height: 20px; letter-spacing: -0.32px;
  color: var(--text-strong);
  transition: background-color .2s ease, color .2s ease;
}
.pr-mtab.is-active { background: rgba(255, 95, 22, 0.08); color: var(--brand); font-weight: 600; }   /* #FF5F16 by marketing's decision (2026-10-13) */
.pr-mtab:not(.is-active):hover { background: rgba(10, 23, 51, 0.04); }
.pr-mtab__arrow { flex: none; color: currentColor; }
.pr-mtab:not(.is-active) .pr-mtab__arrow { display: none; }

/* ---- panels (only the active one is shown) ---- */
.pr-mod__panels { flex: 0 0 796px; min-width: 0; min-height: 429px; }   /* min-height = design inner (511 - 2*41) so the card doesn't jump between states; 09-19: fixed 796 = design card inner 1116 - tabs 260 - gap 60 (was 1 1 auto, which shrank to 776 at 1280 and re-wrapped the panel copy) */
.pr-mpanel { display: flex; align-items: flex-start; gap: 40px; animation: pr-panel-in .3s ease; }
#pr-panel-fee.pr-mpanel { gap: 20px; }   /* 09-19 wrap-match: the Fee Manager lead (user crop) breaks "...scheme fees. / ...identify savings / opportunities..." only with a copy box in [399, 421) — Chrome measures line 2 at 398.2 vs the design's 389 column; copy = 796 - gap - widget 367 = 409 (11px margin each side). The widget is pinned right, so the lead-to-widget distance is unchanged; the IX panel keeps the shared 40. */
.pr-mpanel[hidden] { display: none; }
@keyframes pr-panel-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.pr-mpanel__copy { flex: 1 1 auto; min-width: 0; max-width: 440px; }
.pr-mpanel__h3 {
  margin: 18px 0 0;
  font-size: 32px; font-weight: 500; line-height: 38px;
  letter-spacing: -0.64px; color: var(--text-strong);
}
.pr-mpanel__lead {
  margin: 16px 0 0; max-width: 420px;
  font-size: 18px; font-weight: 400; line-height: 28px;
  letter-spacing: -0.32px; color: var(--text);
}

/* checklist */
.pr-checks { list-style: none; margin: 22px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.pr-checks li {
  display: flex; align-items: flex-start; gap: 12px;
  font-size: 15px; font-weight: 400; line-height: 20px; letter-spacing: -0.32px;
  color: var(--text-strong);
}
.pr-check {
  flex: none; width: 20px; height: 20px; margin-top: 1px;
  display: grid; place-items: center;
  background: rgba(77, 178, 92, 0.12); border-radius: 10px; color: #4db25c;
}
.pr-check .icon { width: 10px; height: 10px; }

/* Learn more CTA (navy → auto-inverts in dark, same as .cta-demo). It's a
   <button> (opens the module popup), so reset button chrome. */
.pr-mod__cta {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 30px; padding: 14px 22px;
  border: 0; cursor: pointer; font-family: inherit;
  background: var(--text-strong); color: var(--bg);
  border-radius: 999px; text-decoration: none;
  font-size: 15px; font-weight: 500; line-height: 1; letter-spacing: -0.32px;
  transition: transform .2s ease, box-shadow .2s ease;
}
.pr-mod__cta:hover { transform: translateY(-2px); box-shadow: 0 10px 24px var(--shadow); }
.pr-mod__cta .icon { transition: transform .2s ease; }
.pr-mod__cta:hover .icon { transform: translateX(3px); }

/* ---- widgets (product mockups; aria-hidden decoration) ---- */
.pr-mwidget {
  flex: none; align-self: flex-start; box-sizing: border-box; margin-top: 66px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(10, 23, 51, 0.04), 0 8px 24px rgba(10, 23, 51, 0.06);
  border-radius: 24px;
}

/* Fee Manager widget */
.pr-mwidget--fee { width: 367px; padding: 26px 29px; }
.pr-mw__label { margin: 0; font-size: 13px; font-weight: 400; line-height: 17px; letter-spacing: -0.32px; color: var(--text); }
.pr-mw__figure {
  margin: 3px 0 0; display: flex; align-items: baseline; gap: 8px;
  font-size: 28px; font-weight: 600; line-height: 36px; letter-spacing: -0.56px; color: var(--text-strong);
}
.pr-mw__delta { color: #2f9e44; font-weight: 500; }
.pr-mw__chip {
  margin-left: auto; align-self: center; padding: 4px 10px;
  background: rgba(255, 95, 22, 0.1); border-radius: 99px;
  font-size: 12px; font-weight: 600; line-height: 16px; letter-spacing: -0.32px;
  color: var(--brand); white-space: nowrap;   /* #FF5F16 by marketing's decision (2026-10-13) */
}
.pr-mw__bars { margin-top: 22px; display: flex; flex-direction: column; gap: 10px; }
.pr-mw__bar { display: grid; grid-template-columns: 118px 1fr auto; align-items: center; gap: 12px; }
.pr-mw__blabel { font-size: 13px; font-weight: 400; line-height: 17px; letter-spacing: -0.32px; color: var(--text-strong); white-space: nowrap; }
.pr-mw__track { height: 8px; border-radius: 4px; background: #f4f4f4; overflow: hidden; }
.pr-mw__fill { display: block; height: 100%; border-radius: 4px; background: #ff5f16; }
.pr-mw__bval { font-size: 12px; font-weight: 400; line-height: 16px; letter-spacing: -0.32px; color: var(--text); text-align: right; white-space: nowrap; }

/* Interchange Hub widget */
.pr-mwidget--ix { width: 333px; padding: 21px; }
.pr-mw__eyebrow { margin: 0; font-size: 10px; font-weight: 600; line-height: 15px; letter-spacing: 1px; text-transform: uppercase; color: var(--text); }
.pr-mw__title { margin: 2px 0 0; font-size: 14px; font-weight: 600; line-height: 20px; color: var(--text-strong); }
.pr-mw__rows { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.pr-mw__row { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border: 1px solid #f3f4f6; border-radius: 14px; }
.pr-mw__dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--d); }
.pr-mw__rlabel { font-size: 11px; font-weight: 500; line-height: 14px; color: var(--text); }
.pr-mw__rval { margin-left: auto; font-size: 20px; font-weight: 700; line-height: 28px; letter-spacing: -0.5px; color: var(--text-strong); }

/* ============================================================
   PR §4 · CAPABILITIES — "Built for scheme cost governance".
   3×2 grid of 6 feature cards. Built 1:1 from section.section.svg.
   ============================================================ */
.pr-caps { background: #fff; padding: 100px 0; }   /* design section is pure #FFFFFF (cards read via their border) */
.pr-caps__head {
  width: min(640px, calc(100% - 2 * var(--gutter)));
  margin: 0 auto 64px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 16px;
}
.pr-caps__head .pr-eyebrow { text-align: center; }
.pr-caps__h2 {
  margin: 0; max-width: 600px;
  font-size: 40px; font-weight: 400; line-height: 46px;
  letter-spacing: -1px; color: var(--text-strong);
}

.pr-caps__grid {
  width: min(1200px, calc(100% - 2 * var(--gutter)));
  margin-inline: auto;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;
}
.pr-cap-card {
  box-sizing: border-box;
  padding: 32px 32px 52px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 24px;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.pr-cap-card:hover { transform: translateY(-4px); box-shadow: 0 10px 28px rgba(10, 23, 51, 0.08); border-color: rgba(10, 23, 51, 0.12); }
.pr-cap-card__icon { display: block; width: 44px; height: 44px; }
.pr-cap-card__title {
  margin: 20px 0 0;
  font-size: 22px; font-weight: 500; line-height: 29px;
  letter-spacing: -0.44px; color: var(--text-strong);
}
.pr-cap-card__desc {
  margin: 8px 0 0;
  font-size: 15px; font-weight: 400; line-height: 23px;
  letter-spacing: -0.32px; color: var(--text);
}

/* ============================================================
   PR §5 · HOW IT WORKS — navy band, header row + 4-step "cube" strip.
   Built 1:1 from section.section (1).svg. The band is always navy in both
   themes (like the footer). Interaction: exactly one cube is enlarged at a
   time — first by default, hover transfers the enlarge (CSS-only).
   ============================================================ */
.pr-hiw { background: #0A1733; padding: 100px 0; }

.pr-hiw__head {
  width: min(1200px, calc(100% - 2 * var(--gutter)));
  margin: 0 auto 64px;
  display: flex; justify-content: space-between; align-items: flex-start; gap: 60px;
}
.pr-hiw__intro { max-width: 570px; }
.pr-eyebrow--onnavy { color: var(--brand); }   /* the same brand orange as .pr-eyebrow since 2026-10-13 (the hook stays for the navy band) */
.pr-hiw__h2 { margin: 16px 0 0; font-size: 40px; font-weight: 400; line-height: 46px; letter-spacing: -1px; color: #fff; }
.pr-hiw__lead { max-width: 563px; margin: 40px 0 0; font-size: 18px; font-weight: 400; line-height: 28px; letter-spacing: -0.32px; color: rgba(255, 255, 255, 0.7); }

/* the step strip: four rounded cards (24 px, correction 37 — the user's picture) that TOUCH, each keeping its own 1-px border
   (the two borders meet at the junctions and the band shows between the corners, as drawn) */
.pr-hiw__strip {
  width: min(1200px, calc(100% - 2 * var(--gutter)));
  margin-inline: auto;
  display: flex; align-items: flex-start;   /* cubes top-align; the featured one grows downward */
  min-height: 242px;                         /* reserve the featured height so cubes resize INSIDE the strip — the container never changes size, so the page below never shifts */
}
.pr-hiw-card {
  flex: 1 1 0; min-width: 0; box-sizing: border-box;
  height: 216px; padding: 32px 28px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 24px;
  background: transparent;
  transition: height .35s ease, background-color .35s ease, border-color .35s ease;
}

/* FEATURED cube = bigger. Default is the first; hovering any cube transfers it. */
.pr-hiw-card:first-child,
.pr-hiw__strip .pr-hiw-card:hover {
  height: 242px;
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.22);
  position: relative; z-index: 1;            /* the brighter border sits above the neighbours' */
}
/* while the strip is hovered, the first cube is only featured if it's the hovered one */
.pr-hiw__strip:hover .pr-hiw-card:first-child:not(:hover) {
  height: 216px;
  background: transparent;
  border-color: rgba(255, 255, 255, 0.12);
  z-index: 0;
}

.pr-hiw-card__num { display: block; font-size: 14px; font-weight: 600; line-height: 18px; letter-spacing: 0.56px; color: var(--brand); }
.pr-hiw-card__title { margin: 5px 0 0; font-size: 22px; font-weight: 500; line-height: 29px; letter-spacing: -0.44px; color: #fff; }
.pr-hiw-card__desc { margin: 11px 0 0; font-size: 14px; font-weight: 400; line-height: 22px; letter-spacing: -0.32px; color: rgba(255, 255, 255, 0.7); }

/* ============================================================
   PR §8 · FAQ — centred accordion. Built 1:1 from section.section (3).svg.
   ============================================================ */
.pr-faq { background: #fff; padding: 100px 0; }
.pr-faq__inner {
  width: min(840px, calc(100% - 2 * var(--gutter)));
  margin-inline: auto;
  display: flex; flex-direction: column; align-items: center; gap: 64px;
}
.pr-faq__h2 { margin: 0; font-size: 40px; font-weight: 400; line-height: 46px; letter-spacing: -1px; color: var(--text-strong); text-align: center; }

.pr-faq__list { width: 100%; max-width: 760px; }
.pr-faq__item { border-top: 1px solid var(--border); }
.pr-faq__item:last-child { border-bottom: 1px solid var(--border); }
.pr-faq__qh { margin: 0; }
.pr-faq__q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 24px 0; border: 0; background: transparent; cursor: pointer; font-family: inherit; text-align: left;
}
.pr-faq__qt { font-size: 18px; font-weight: 500; line-height: 23px; color: var(--text-strong); }

/* + / − icon (drawn; the vertical bar collapses when open) */
.pr-faq__ico { position: relative; flex: none; width: 14px; height: 14px; }
.pr-faq__ico::before,
.pr-faq__ico::after { content: ""; position: absolute; background: var(--brand); border-radius: 2px; }
.pr-faq__ico::before { left: 0; right: 0; top: 50%; height: 1.6px; transform: translateY(-50%); }
.pr-faq__ico::after { top: 0; bottom: 0; left: 50%; width: 1.6px; transform: translateX(-50%); transition: transform .25s ease, opacity .25s ease; }
.pr-faq__item.is-open .pr-faq__ico::after { transform: translateX(-50%) scaleY(0); opacity: 0; }

/* answer — animates open via grid-template-rows 0fr→1fr */
.pr-faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .3s ease; }
.pr-faq__item.is-open .pr-faq__a { grid-template-rows: 1fr; }
.pr-faq__a-inner { overflow: hidden; }
.pr-faq__a-inner p {
  margin: 0; padding: 0 0 24px; max-width: 700px;
  font-size: 16px; font-weight: 400; line-height: 26px; letter-spacing: -0.32px; color: var(--text);
}

/* ============================================================
   MODULE POPUP · Stripe-style card over a tinted, blurred backdrop + motion.
   Reframed from a full-screen takeover (was: 1:1 Fee manager - popup.svg)
   into a centered card over a tinted, blurred backdrop. All values are the
   user's final lab tuning (bento-dialog-lab.html). The orange + blue glow
   spots behind the card were dropped on 2026-10-14 (marketing corrections 17).
   Keyed on .pr-modal, so every popup (products + both solutions pages)
   shares the card/motion.
   ============================================================ */

/* overlay: fixed, NON-scrolling (the scroll happens in .pr-modal__scroll) + backdrop tint.
   ⚠️ .pr-modal has backdrop-filter → it is the containing block for any position:fixed
   child; keep the scrolling on .pr-modal__scroll, never on the overlay itself. */
.pr-modal {
  position: fixed; inset: 0; z-index: 1000; overflow: hidden;
  background-color: rgb(229 237 245 / 0.50);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  transition-property: opacity, background-color, backdrop-filter;
}
.pr-modal[hidden] { display: none; }
.pr-modal[data-status="initial"] { opacity: 0; }
.pr-modal[data-status="open"]    { opacity: 1; transition-duration: .25s; }
.pr-modal[data-status="close"]   { opacity: 0; transition-duration: .3s; }

/* scroll container — centers the card, scrolls */
.pr-modal__scroll {
  position: absolute; inset: 0; z-index: 2;
  display: flex; justify-content: center; align-items: flex-start;
  overflow-y: auto; padding: 5vh var(--gutter);
}

/* the CARD (surface, radius, shadow, slide motion) */
.pr-modal__card {
  position: relative; z-index: 2;
  width: 100%; max-width: 1200px; margin: 0 auto;
  background: var(--surface); border-radius: 22px;
  box-shadow: 0 40px 80px -20px rgba(20, 30, 60, .35);
  overflow: hidden; transform-origin: top;
  transition-property: transform; will-change: transform;
}
.pr-modal[data-status="initial"] .pr-modal__card { transform: translateY(200px); }
.pr-modal[data-status="open"]    .pr-modal__card { transform: translateY(0); transition-duration: .8s; transition-timing-function: cubic-bezier(.22, 1, .36, 1); }
.pr-modal[data-status="close"]   .pr-modal__card { transform: translateY(100px); transition-duration: .35s; }

/* close button — was position:fixed for the full-screen takeover; now absolute in the card
   corner. Same pale-orange circle + rotate-on-hover, only the positioning changed. */
.pr-modal__close {
  position: absolute; top: 20px; right: 20px; z-index: 5;
  width: 48px; height: 48px; border: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: #FBEBE4; color: #FF6900;
  transition: background-color .2s ease, transform .2s ease;
}
.pr-modal__close:hover { transform: rotate(90deg); }

/* content wrapper (was full-screen; now card padding). The 4 blocks are its only children. */
.pr-modal__inner { padding: 44px 48px 56px; }
@media (max-width: 640px) { .pr-modal__inner { padding: 34px 24px 40px; } }

/* content reveal — staggers the 4 blocks (no class needed; they're the direct children) */
.pr-modal__inner > * {
  opacity: 0; transform: translate3d(0, 20px, 0);
  animation: pr-modal-reveal .75s cubic-bezier(.2, 0, 0, 1) forwards;
}
.pr-modal__inner > *:nth-child(2) { animation-delay: .09s; }
.pr-modal__inner > *:nth-child(3) { animation-delay: .18s; }
.pr-modal__inner > *:nth-child(4) { animation-delay: .27s; }
@keyframes pr-modal-reveal { to { opacity: 1; transform: translateZ(0); } }

/* header */
.pr-fmp__head { display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 1fr); gap: 80px; align-items: start; }
.pr-fmp__intro { max-width: 560px; }
.pr-fmp__h2 { margin: 16px 0 0; font-size: 40px; font-weight: 400; line-height: 46px; letter-spacing: -1px; color: var(--text-strong); }
.pr-fmp__lead { margin: 16px 0 0; font-size: 18px; font-weight: 400; line-height: 28px; letter-spacing: -0.32px; color: var(--text); }
.pr-fmp__intro .pr-btn { margin-top: 24px; }

.pr-fmp__checks { list-style: none; margin: 112px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }   /* offset down to align with the lead, per the design */
.pr-fmp__checks li { display: flex; align-items: flex-start; gap: 12px; font-size: 15px; font-weight: 400; line-height: 20px; letter-spacing: -0.32px; color: var(--text-strong); }
.pr-fmp__check { flex: none; width: 22px; height: 22px; margin-top: 1px; display: grid; place-items: center; background: rgba(255, 95, 22, 0.1); border-radius: 11px; color: var(--brand); }
.pr-fmp__check .icon { width: 11px; height: 11px; }
/* Interchange Hub popup head (2026-10-14, the user's green crop): the lead breaks «…in view. / …with transaction- /
   level…» and each check holds ONE line. Lead window (18px, nowrap probe): must fit «Track costs, … with transaction-»
   526.6, must not fit «Keep … in view. Track» 559.2 → the intro column 540 (the lead takes the column's width; the
   h2 466 fits). Check 1 needs 455.2 (22 icon + 12 gap + 421.2 text): at a 1280 viewport the content box is 1081.6,
   1066.6 with the scroller's 15px scrollbar → gap 60 leaves 466.6 for the checks (11px spare). The checks start at
   600 instead of 640. Spanish: text-wrap pretty keeps a check from ending on one word (at 1280 with the scrollbar
   «…según ingresos y | costos» → «…según ingresos | y costos»). */
#pr-modal-ix .pr-fmp__head { grid-template-columns: minmax(0, 540px) minmax(0, 1fr); gap: 60px; }
#pr-modal-ix .pr-fmp__checks li { text-wrap: pretty; }
/* Fee Manager popup head (2026-10-15, the user's Fee Manager SVG): the lead breaks «…understand cost drivers, /
   validate … across Visa / and Mastercard billing.» (3 lines), the h2 «…scheme fees and / savings opportunities»
   and each check holds ONE line. Lead window (18px, nowrap probe): must fit «Review … cost drivers,» 545.3 and
   «validate … across Visa» 527.7, must not fit «… across Visa and» 561.8 → the intro column 550 (the h2 needs
   [532, 674)). The widest check needs 475.7 (22 icon + 12 gap + 441.7 «Spot scheme updates … custom alerts»): at a
   1280 viewport the content box is 1066.6 with the scroller's 15px scrollbar → gap 36 leaves 480.6 (4.9 spare). */
#pr-modal-fee .pr-fmp__head { grid-template-columns: minmax(0, 550px) minmax(0, 1fr); gap: 36px; }
#pr-modal-fee .pr-fmp__checks { margin-top: 141px; }   /* the design aligns check 1 with the lead's first line; the shared 112 assumes a 1-line h2 (this one has 2) */

/* dashboard product mockups (supplied SVGs) */
.pr-fmp__mocks { margin-top: 72px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; align-items: start; }
.pr-fmp__mocks img { width: 100%; height: auto; display: block; border-radius: 24px; }
/* ── the Agreement Negotiation mockups ANIMATE THEIR INSIDES on open (user, 2026-09-07: "the inside, not a hover
   effect"). products.js (the loader moved there from solutions.js on 2026-09-19) swaps the two <img data-inline-svg> for the SVG documents (lazily; the <img> is the fallback)
   whose groups carry classes baked into the asset files: po-agreement = .pa-sheet--back / --mid / --front (the two
   faded sheets + the front document; they live inside the frame's clip, so the rise is cropped at the frame edge) +
   .pa-pill (the "$183M agreed incentives" pill — nested in the front sheet's clip, so it settles in place instead of
   sliding in from outside); po-schememix = .pm-card--1/2/3 (the card stack) + .pm-pill (the "Best scheme mix
   identified" pill, wrapped in a new <g>) + .pm-badge (its green check). Timeline, from the popup opening (the row
   itself reveals at .09s): the LEFT mockup first — sheets rise .45 / .57 / .69, its pill settles 1.15 — then the
   RIGHT — cards deal .95 / 1.07 / 1.19, its pill settles 1.65, the check pops 2.0; then the picture rests. The two
   run in SEQUENCE on purpose: in parallel (cards at .55/.67/.79) six shadowed groups moved at once and the entrance
   measured 34–35 fps; sequenced it holds 53–59 (same run, warm opens) (an idle float was tried and dropped: a permanent repaint loop of two
   path-heavy SVGs for a 4px bob). The modal is display:none while closed, so this replays on every open. Reduced
   motion = the finished picture, no motion.
   PERF (measured in the pane, 1536): SVG filters are the whole cost — with every filter off the entrance holds 60 fps,
   with them ~45. So (1) each inline svg gets its own compositor layer (will-change) and (2) products.js strips the
   OUTER frame's drop-shadow filter (static, yet re-filtered on every repaint of the moving groups) and this CSS
   drop-shadow — the same two shadows (0/.71/1.43 @.04 + 0/5.71/17.14 @.06 in asset units, ×1.076 rendered) — is
   applied to the svg root instead, where it is composited. The inner shadows (sheets, cards, pills) stay in the SVG:
   they belong to the parts that move. */
.pr-fmp__mocks--anim .pr-mock-svg { width: 100%; height: auto; display: block; border-radius: 24px; will-change: transform;
  filter: drop-shadow(0 .8px 1.5px rgba(10, 23, 51, .04)) drop-shadow(0 6px 18px rgba(10, 23, 51, .06)); }
:root[data-theme="dark"] .pr-fmp__mocks--anim .pr-mock-svg { filter: drop-shadow(0 .8px 1.5px rgba(0, 0, 0, .2)) drop-shadow(0 6px 18px rgba(0, 0, 0, .3)) brightness(0.92); }
.pr-fmp__mocks--anim .pr-mock-svg--own-shadow { filter: none; }
:root[data-theme="dark"] .pr-fmp__mocks--anim .pr-mock-svg--own-shadow { filter: brightness(0.92); }
@keyframes pr-mock-rise   { from { opacity: 0; transform: translateY(44px); } to { opacity: 1; transform: translateY(0); } }
@keyframes pr-mock-deal   { from { opacity: 0; transform: translateY(26px) scale(.985); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes pr-mock-settle { from { opacity: 0; transform: translateY(12px) scale(.94); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes pr-mock-pop    { 0% { opacity: 0; transform: scale(.3); } 65% { opacity: 1; transform: scale(1.14); } 100% { opacity: 1; transform: scale(1); } }

/* ── Fee Manager popup: the three dashboard mockups ANIMATE THEIR INSIDES on open (2026-09-19, products.html #pr-modal-fee).
   Same recipe as the five solutions popups: the <img data-inline-svg>s inside .pr-fmp__mocks--anim are swapped for the SVG
   documents by products.js (lazily, when the trigger nears the viewport), the classes are baked into the asset files
   (harmless as <img>), and these keyframes run once per open (the modal is display:none while closed, so they restart).
   Entrance only, no idle loops (path-heavy SVGs would repaint forever). Reduced motion = the finished picture (REDUCED MOTION block).
   fill-mode BACKWARDS (not both): the first keyframe hides each part through its delay, and once an animation ends the element
   drops back to its plain attribute styling (every end keyframe equals it) instead of keeping a finished compositor effect,
   which pixel-snaps the layer and left glyphs up to half a pixel off the static render (measured 0.9 % of pixels > 24/255; now 0).
   Choreography, left to right with overlaps, resting by ~3.5 s:
     Performance Score  .4 - 2.0   title / sub / axis fade in; the gauge arc DRAWS (pathLength=1, stroke-dashoffset 1 to 0);
                                   the tip dot and the "B" grade pop when it lands; "78 score" fades; the label fades and "EUR 890K" settles
     Announcements     1.0 - 3.5   title / sub fade in; row 1 then row 2 slide in from the right, their tag pills settle, the headlines
                                   fade; the "4 Updates" pill settles; the bell RINGS (rotates about its top, two swings)
     Unit Cost         1.6 - 3.1   title fades in; the blue underline glides from under "Variable" to under "Fixed" while the two
                                   labels swap ink; the table rows populate top to bottom */
.pr-fmp__mocks--anim :is(.ps-title, .ps-sub, .ps-axis, .ps-tip, .ps-grade, .ps-score, .ps-label, .ps-value, .an-title, .an-sub, .an-row, .an-pill, .an-text, .an-upd, .an-bell, .uc-title, .uc-row, .uc-underline) { transform-box: fill-box; transform-origin: 50% 50%; }
.pr-fmp__mocks--anim .an-bell { transform-origin: 50% 0; }
@keyframes pr-mock-in  { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes ps-draw     { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes an-slide    { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: translateX(0); } }
@keyframes an-ring     { 0% { transform: rotate(0); } 20% { transform: rotate(14deg); } 45% { transform: rotate(-11deg); } 70% { transform: rotate(6deg); } 85% { transform: rotate(-3deg); } 100% { transform: rotate(0); } }
@keyframes uc-tabslide { from { transform: translateX(82px); } to { transform: translateX(0); } }
@keyframes uc-ink-on   { from { fill: #6A7282; } to { fill: #101828; } }
@keyframes uc-ink-off  { from { fill: #101828; } to { fill: #6A7282; } }
/* Performance Score */
.pr-fmp__mocks--anim .ps-title { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) .4s backwards; }
.pr-fmp__mocks--anim .ps-sub   { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) .5s backwards; }
.pr-fmp__mocks--anim .ps-axis  { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) .6s backwards; }
.pr-fmp__mocks--anim .ps-arc   { stroke-dasharray: 1; animation: ps-draw 1.1s cubic-bezier(.4, 0, .2, 1) .6s backwards; }
.pr-fmp__mocks--anim .ps-tip   { animation: pr-mock-pop .45s cubic-bezier(.22, 1, .36, 1) 1.6s backwards; }
.pr-fmp__mocks--anim .ps-grade { animation: pr-mock-pop .5s cubic-bezier(.22, 1, .36, 1) 1.65s backwards; }
.pr-fmp__mocks--anim .ps-score { animation: pr-mock-in .35s cubic-bezier(.22, 1, .36, 1) 1.85s backwards; }
.pr-fmp__mocks--anim .ps-label { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 1.5s backwards; }
.pr-fmp__mocks--anim .ps-value { animation: pr-mock-settle .55s cubic-bezier(.22, 1, .36, 1) 1.65s backwards; }
/* Upcoming Announcements */
.pr-fmp__mocks--anim .an-title  { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 1s backwards; }
.pr-fmp__mocks--anim .an-sub    { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 1.1s backwards; }
.pr-fmp__mocks--anim .an-row--1 { animation: an-slide .55s cubic-bezier(.22, 1, .36, 1) 1.25s backwards; }
.pr-fmp__mocks--anim .an-row--2 { animation: an-slide .55s cubic-bezier(.22, 1, .36, 1) 1.65s backwards; }
.pr-fmp__mocks--anim .an-pill   { animation: pr-mock-settle .45s cubic-bezier(.22, 1, .36, 1) 1.35s backwards; }
.pr-fmp__mocks--anim .an-row--2 .an-pill { animation-delay: 1.75s; }
.pr-fmp__mocks--anim .an-text   { animation: pr-mock-in .35s cubic-bezier(.22, 1, .36, 1) 1.55s backwards; }
.pr-fmp__mocks--anim .an-row--2 .an-text { animation-delay: 1.95s; }
.pr-fmp__mocks--anim .an-upd    { animation: pr-mock-settle .5s cubic-bezier(.22, 1, .36, 1) 2.2s backwards; }
.pr-fmp__mocks--anim .an-bell   { animation: an-ring .9s ease-in-out 2.6s backwards; }
/* Unit Cost by Product */
.pr-fmp__mocks--anim .uc-title      { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 1.6s backwards; }
.pr-fmp__mocks--anim .uc-underline  { animation: uc-tabslide .45s cubic-bezier(.22, 1, .36, 1) 1.9s backwards; }
.pr-fmp__mocks--anim .uc-tab--fixed { animation: uc-ink-on .45s ease 1.9s backwards; }
.pr-fmp__mocks--anim .uc-tab--var   { animation: uc-ink-off .45s ease 1.9s backwards; }
.pr-fmp__mocks--anim .uc-row--0 { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 2.35s backwards; }
.pr-fmp__mocks--anim .uc-row--1 { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 2.47s backwards; }
.pr-fmp__mocks--anim .uc-row--2 { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 2.59s backwards; }
.pr-fmp__mocks--anim .uc-row--3 { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 2.71s backwards; }

/* ── Interchange Hub popup: the three dashboard mockups ANIMATE THEIR INSIDES on open (2026-10-15, products.html #pr-modal-ix).
   Same recipe as the Fee Manager popup above (classes baked into ix-merchant / ix-dashboard / ix-mcc.svg, products.js inlines them
   lazily, fill-mode BACKWARDS so the finished frame equals the static render, reduced motion = the finished picture). Own ih*-
   class and keyframe names on purpose: products.css also loads on the two solutions pages, where solutions.css defines the
   similar ixd- / ixm- classes and keyframes for the two solutions Interchange popups (issuer + acquirer) — nothing here may match those.
   Choreography, left to right with overlaps, resting by ~3.5 s:
     Merchant Profitability  .4 - 1.9   title / sub fade in; the table rows populate top to bottom (row number + merchant name),
                                        each row's merchant ID and MCC slide in from the right .2 s behind it
     Interchange Dashboard   .9 - 2.8   the two orange filter pills PULSE in turn as if just applied, the two KPI cards refresh
                                        (deal), the four "By Jurisdiction" bars GROW from the baseline, their value / share labels fade in
     Profitability by MCC   1.6 - 3.5   title / sub fade in, the gridlines + zero line + y labels fade in, the three bars GROW from
                                        the zero line, their percent labels pop, then the category labels fade in */
.pr-fmp__mocks--anim :is(.ihm-title, .ihm-sub, .ihm-cell, .ihm-val, .ihd-pill, .ihd-kpi, .ihd-bar, .ihd-lbl, .ihc-title, .ihc-sub, .ihc-axis, .ihc-bar, .ihc-pct, .ihc-cat) { transform-box: fill-box; transform-origin: 50% 50%; }
.pr-fmp__mocks--anim :is(.ihd-bar, .ihc-bar) { transform-origin: 50% 100%; }
@keyframes ih-slide { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: translateX(0); } }
@keyframes ih-pulse { 0% { transform: scale(1); } 40% { transform: scale(1.06); } 100% { transform: scale(1); } }
@keyframes ih-grow  { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes ih-fade  { from { opacity: 0; } to { opacity: 1; } }
/* Merchant Profitability */
.pr-fmp__mocks--anim .ihm-title { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) .4s backwards; }
.pr-fmp__mocks--anim .ihm-sub   { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) .5s backwards; }
.pr-fmp__mocks--anim .ihm-cell  { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihm-val   { animation: ih-slide .45s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihm-r1 { animation-delay: .60s; }
.pr-fmp__mocks--anim .ihm-r2 { animation-delay: .70s; }
.pr-fmp__mocks--anim .ihm-r3 { animation-delay: .80s; }
.pr-fmp__mocks--anim .ihm-r4 { animation-delay: .90s; }
.pr-fmp__mocks--anim .ihm-r5 { animation-delay: 1.00s; }
.pr-fmp__mocks--anim .ihm-r6 { animation-delay: 1.10s; }
.pr-fmp__mocks--anim .ihm-r7 { animation-delay: 1.20s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r1 { animation-delay: .80s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r2 { animation-delay: .90s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r3 { animation-delay: 1.00s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r4 { animation-delay: 1.10s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r5 { animation-delay: 1.20s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r6 { animation-delay: 1.30s; }
.pr-fmp__mocks--anim .ihm-val.ihm-r7 { animation-delay: 1.40s; }
/* Interchange Dashboard */
.pr-fmp__mocks--anim .ihd-pill    { animation: ih-pulse .45s ease-out backwards; }
.pr-fmp__mocks--anim .ihd-pill--1 { animation-delay: .9s; }
.pr-fmp__mocks--anim .ihd-pill--2 { animation-delay: 1.1s; }
.pr-fmp__mocks--anim .ihd-kpi     { animation: pr-mock-deal .6s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihd-kpi--1  { animation-delay: 1.3s; }
.pr-fmp__mocks--anim .ihd-kpi--2  { animation-delay: 1.45s; }
.pr-fmp__mocks--anim .ihd-bar     { animation: ih-grow .7s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihd-bar--1  { animation-delay: 1.65s; }
.pr-fmp__mocks--anim .ihd-bar--2  { animation-delay: 1.77s; }
.pr-fmp__mocks--anim .ihd-bar--3  { animation-delay: 1.89s; }
.pr-fmp__mocks--anim .ihd-bar--4  { animation-delay: 2.01s; }
.pr-fmp__mocks--anim .ihd-lbl     { animation: ih-fade .3s ease-out backwards; }
.pr-fmp__mocks--anim .ihd-lbl--1  { animation-delay: 2.05s; }
.pr-fmp__mocks--anim .ihd-lbl--2  { animation-delay: 2.17s; }
.pr-fmp__mocks--anim .ihd-lbl--3  { animation-delay: 2.29s; }
.pr-fmp__mocks--anim .ihd-lbl--4  { animation-delay: 2.41s; }
/* Profitability by MCC */
.pr-fmp__mocks--anim .ihc-title  { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 1.6s backwards; }
.pr-fmp__mocks--anim .ihc-sub    { animation: pr-mock-in .4s cubic-bezier(.22, 1, .36, 1) 1.7s backwards; }
.pr-fmp__mocks--anim .ihc-axis   { animation: ih-fade .4s ease-out 1.85s backwards; }
.pr-fmp__mocks--anim .ihc-bar    { animation: ih-grow .7s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihc-bar--1 { animation-delay: 2.1s; }
.pr-fmp__mocks--anim .ihc-bar--2 { animation-delay: 2.25s; }
.pr-fmp__mocks--anim .ihc-bar--3 { animation-delay: 2.4s; }
.pr-fmp__mocks--anim .ihc-pct    { animation: pr-mock-pop .45s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihc-pct--1 { animation-delay: 2.6s; }
.pr-fmp__mocks--anim .ihc-pct--2 { animation-delay: 2.75s; }
.pr-fmp__mocks--anim .ihc-pct--3 { animation-delay: 2.9s; }
.pr-fmp__mocks--anim .ihc-cat    { animation: pr-mock-in .35s cubic-bezier(.22, 1, .36, 1) backwards; }
.pr-fmp__mocks--anim .ihc-cat--1 { animation-delay: 2.95s; }
.pr-fmp__mocks--anim .ihc-cat--2 { animation-delay: 3.03s; }
.pr-fmp__mocks--anim .ihc-cat--3 { animation-delay: 3.11s; }

/* capability cards row (reuses .pr-cap-card) */
.pr-fmp__caps { margin-top: 40px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
/* the reframed popup card is narrower than the Figma full-screen layout, so trim the
   cap-card side padding HERE (popups only — not §4) to keep the "Savings you can measure"
   desc on 2 lines like the design instead of wrapping to 3. */
.pr-fmp__caps .pr-cap-card { padding-inline: 20px; }

/* bottom CTA */
.pr-fmp__cta { margin-top: 96px; display: flex; flex-direction: column; align-items: center; text-align: center; }
.pr-fmp__cta-h2 { margin: 0; font-size: 40px; font-weight: 400; line-height: 46px; letter-spacing: -1px; color: var(--text-strong); }
.pr-fmp__cta-lead { margin: 20px 0 0; max-width: 600px; font-size: 18px; font-weight: 400; line-height: 28px; letter-spacing: -0.32px; color: var(--text); }
.pr-fmp__cta .pr-btn { margin-top: 28px; }

/* ── the two PRODUCTS popups' cards + closing block = the Fee Manager design (2026-10-15, the user's Fee Manager SVG
   «frame.svg», 1440×1653; the Interchange Hub popup is the same template, the user's crop). Scoped to the two ids so
   the solutions popups (which share .pr-fmp__caps / .pr-cap-card / .pr-fmp__cta) and the products page's own §4
   capability cards do not change. Type fitted with fontTools on the Geist files against the outlined glyphs:
   titles «T» 15.62 px tall = 22px Geist 500, ink widths of the three titles → −0.43px (−0.439/−0.416/−0.429);
   descs «T» 10.65 = 15px Geist 400, six line widths → −0.31px, line pitch 23; closing h2 «T» 28.4 = 40px Geist 400,
   ink width 628.66 → −0.99px; lead «T» 12.78 = 18px Geist 400, ink width 591.90 → −0.31px.
   Spacing (design, on the frame's stroke centres): mockup frame bottom → card top 87.5 — the row's box bottom sits
   32 asset units (32 × colW / 430 at the tallest, 430-wide mockup) under its drawn frame, colW = (W − 48) / 3, so the
   margin is 87.5 − 32 / 1290 × (W − 48) = 88.69px − 2.4806% of the content width W (61.3 at 1536, 62.2 at 1280).
   The text margins use Chrome's line boxes (it rounds the font's ascent / descent to whole pixels: the title's
   baseline sits 22 into its 29px box, the desc's 17 into 23, the h2's 37 into 46, the lead's 20 into 28): icon
   bottom → title cap top 26.38 (cap top 6.38 into the box → margin 20); title cap top → desc cap top 38.37 (22.62 +
   9.4 + 6.35); card 234.4 tall (min-height: a longer Spanish desc grows it); cards bottom → closing h2 ink top 131.06
   (ink top 7.96 into the box → margin 123.1); h2 ink bottom («g» −162 units, 2.52 above the box bottom) → lead ink
   top 29.72 (2.52 + 20 + 7.2); lead ink bottom (−156 units, 5.19 above the box bottom) → button top 31.19 (5.19 + 26). The popup card is the design's #FBFBFB page with WHITE cards (the solutions popups did the
   same in solutions.css v=52); dark keeps the surface card and lifts the inner cards a touch. */
:is(#pr-modal-fee, #pr-modal-ix) .pr-modal__card { background: #FBFBFB; }
/* Interchange Hub card 3 ("Price with confidence"): its desc breaks like the user's crop ("…to evaluate pricing / and profitability
   scenarios before you act.") — the first line needs 318 px. Only this card changes: it takes 374 of the row's 1060 px (cards 1-2: 343 each,
   still wide enough for "Monitor monthly performance, trends, and" = 274 px) and its desc runs 13 px into its own right padding; the icon,
   title, desc start, padding, type and height stay identical to cards 1-2. From 1340 px windows (the popup card at its full 1200 width);
   narrower windows keep three equal cards (card 3 wraps to 3 lines there). English only: the Spanish card 3 is 3 lines at any of these
   widths, so the Spanish popup keeps its three equal cards. Correction 35 (the 1296-px popup of correction 34 was too wide). */
@media (min-width: 1340px) {
  :lang(en) #pr-modal-ix .pr-fmp__caps { grid-template-columns: minmax(0, 343fr) minmax(0, 343fr) minmax(0, 374fr); }
  :lang(en) #pr-modal-ix .pr-cap-card:nth-child(3) .pr-cap-card__desc { margin-right: -13px; }
}
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__caps { margin-top: calc(88.69px - 2.4806%); gap: 22px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__caps .pr-cap-card { min-height: 234.4px; padding: 32px; background: #fff; border-color: #EDEDED; border-radius: 24px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__caps .pr-cap-card:hover { border-color: rgba(10, 23, 51, 0.12); }
:is(#pr-modal-fee, #pr-modal-ix) .pr-cap-card__title { margin-top: 20px; letter-spacing: -0.43px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-cap-card__desc { margin-top: 9.4px; letter-spacing: -0.31px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__cta { margin-top: 123.1px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__cta-h2 { letter-spacing: -0.99px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__cta-lead { margin-top: 20px; max-width: 720px; letter-spacing: -0.31px; }
:is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__cta .pr-btn { margin-top: 26px; }

/* ============================================================
   DARK THEME
   ============================================================ */
:root[data-theme="dark"] .pr-hero {
  background: linear-gradient(180deg, rgba(255, 95, 22, 0.06) 0%, var(--bg) 100%);
}
:root[data-theme="dark"] .pr-btn--ghost { border-color: rgba(255, 255, 255, 0.2); }

/* §3 modules */
:root[data-theme="dark"] .pr-mtab.is-active { background: rgba(255, 95, 22, 0.12); }
:root[data-theme="dark"] .pr-mtab:not(.is-active):hover { background: rgba(255, 255, 255, 0.05); }
:root[data-theme="dark"] .pr-mw__chip { background: rgba(255, 95, 22, 0.14); }
:root[data-theme="dark"] .pr-mw__track { background: rgba(255, 255, 255, 0.08); }
:root[data-theme="dark"] .pr-mw__row { border-color: var(--border); }
:root[data-theme="dark"] .pr-mw__delta { color: #3fb95e; }

/* §4 capabilities */
:root[data-theme="dark"] .pr-caps { background: var(--bg); }
:root[data-theme="dark"] .pr-cap-card:hover { box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35); border-color: rgba(255, 255, 255, 0.14); }

/* §8 faq */
:root[data-theme="dark"] .pr-faq { background: var(--bg); }

/* module popup */
/* dark backdrop: the light pale-blue tint reads as a washed film over the dark page —
   swap it for a subtle dark dim + a real blur so the page behind frosts instead of washes. */
:root[data-theme="dark"] .pr-modal {
  background-color: rgba(8, 13, 26, 0.4);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
:root[data-theme="dark"] .pr-modal__close { background: rgba(255, 95, 22, 0.18); }
/* the two products popups (2026-10-15): the light #FBFBFB page + white cards → dark keeps the surface card and lifts
   the cap cards a touch (the solutions popups' dark rule) */
:root[data-theme="dark"] :is(#pr-modal-fee, #pr-modal-ix) .pr-modal__card { background: var(--surface); }
:root[data-theme="dark"] :is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__caps .pr-cap-card { background: rgba(255, 255, 255, 0.04); border-color: var(--border); }
:root[data-theme="dark"] :is(#pr-modal-fee, #pr-modal-ix) .pr-fmp__caps .pr-cap-card:hover { border-color: rgba(255, 255, 255, 0.14); }
/* the dashboard mockup SVGs are light product screenshots; soften them slightly on the dark backdrop */
:root[data-theme="dark"] .pr-fmp__mocks img { filter: brightness(0.92); }

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .pr-btn, .pr-btn svg { transition: none; }
  .pr-btn--primary:hover { transform: none; }
  .pr-mtab, .pr-mod__cta, .pr-mod__cta .icon { transition: none; }
  .pr-mod__cta:hover { transform: none; }
  .pr-mpanel { animation: none; }
  .pr-cap-card { transition: none; }
  .pr-cap-card:hover { transform: none; }
  .pr-hiw-card { transition: none; }
  .pr-faq__a, .pr-faq__ico::after { transition: none; }
  .pr-modal__close { transition: none; }
  .pr-modal__close:hover { transform: none; }
  .pr-modal, .pr-modal__card { transition: none; }
  .pr-modal[data-status="initial"] .pr-modal__card { transform: none; }
  .pr-modal__inner > * { animation: none; opacity: 1; transform: none; }
    .pr-fmp__mocks--anim :is(.ps-title, .ps-sub, .ps-axis, .ps-arc, .ps-tip, .ps-grade, .ps-score, .ps-label, .ps-value, .an-title, .an-sub, .an-row, .an-pill, .an-text, .an-upd, .an-bell, .uc-title, .uc-tab, .uc-underline, .uc-row) { animation: none; }
    .pr-fmp__mocks--anim :is(.ihm-title, .ihm-sub, .ihm-cell, .ihm-val, .ihd-pill, .ihd-kpi, .ihd-bar, .ihd-lbl, .ihc-title, .ihc-sub, .ihc-axis, .ihc-bar, .ihc-pct, .ihc-cat) { animation: none; }
    .pr-fmp__mocks--anim .ps-arc { stroke-dasharray: none; }
}
