/* Experimental 3 (env test) — ported from design-hub page-content-x3.tsx.
   Tactical dossier: mono labels + coordinates, dark/bright rhythm, flowy
   gradient hovers, mouse-reactive aurora hero, pinned-hero curtain. */

.p-x3 {
  background: var(--color-black);
  color: var(--color-white);
}

.p-x3 .x3-mono {
  font-family: var(--font-sans);
}

.p-x3 .x3-label {
  font-size: var(--fs-kicker);
  letter-spacing: var(--track-wide);
  color: rgba(255, 255, 255, 0.5);
}
.p-x3 .x3-label--light {
  color: var(--color-kicker-on-white);
}
/* on-ink kicker wanting blue: Blue 200, never the saturated 500
   (blue-on-dark contrast rule, 2026-08-01) */
.p-x3 .x3-label--blue {
  color: var(--color-blue-200);
}
/* keeps a phrase on one line so a wrap lands BEFORE it (hero kicker:
   "…Magic Quadrant™ / for Identity Verification") */
.p-x3 .x3-nobreak { white-space: nowrap; }

/* ---------- curtain: hero pins, sections slide over ---------- */
.p-x3 .x3-pin {
  position: sticky;
  top: 0;
  z-index: 0;
  height: 100vh;
  overflow: hidden;
}
.p-x3 .x3-over {
  position: relative;
  z-index: 10;
}

/* ---------- hero ---------- */
.p-x3 .x3-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 100vh;
  overflow: hidden;
  background: var(--color-black);
}
.p-x3 .x3-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.38;
  filter: grayscale(1);
}
/* campaign hero still (e.g. /agentic-fraud/): the image IS the statement,
   so it keeps its color and reads stronger than the ambient video */
.p-x3 .x3-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% center;
  opacity: 0.62;
}
/* phones: the title sits over the image's brightest region, so the still
   steps back a notch to keep the display type crisp */
@media (max-width: 639px) {
  .p-x3 .x3-hero__img { opacity: 0.45; }
}
/* campaign body copy runs wider so the two-sentence message holds two lines
   (doubled class outranks the base .p-x3 .x3-hero__sub cap further down) */
.p-x3.p-x3--agentic .x3-hero__sub { max-width: 780px; }
.p-x3 .x3-hero__aurora {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.p-x3 .x3-blob {
  position: absolute;
  will-change: transform;
}
.p-x3 .x3-blob > span {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 9999px;
  animation: x3-breathe 16s ease-in-out infinite;
}
.p-x3 .x3-blob--1 {
  left: -8%;
  top: -12%;
  width: 95vmin;
  height: 95vmin;
  opacity: 0.65;
}
.p-x3 .x3-blob--1 > span {
  filter: blur(80px);
  background: radial-gradient(
    circle,
    color-mix(in oklab, var(--color-x3-blue-deep) 80%, transparent) 0%,
    color-mix(in oklab, var(--color-x3-blue-deep) 25%, transparent) 45%,
    transparent 68%
  );
}
.p-x3 .x3-blob--2 {
  right: -8%;
  top: 2%;
  width: 85vmin;
  height: 85vmin;
  opacity: 0.55;
}
.p-x3 .x3-blob--2 > span {
  filter: blur(90px);
  animation-duration: 13s;
  animation-delay: 2s;
  background: radial-gradient(
    circle,
    color-mix(in oklab, var(--color-x3-blue-bright) 65%, transparent) 0%,
    color-mix(in oklab, var(--color-blue) 20%, transparent) 48%,
    transparent 68%
  );
}
.p-x3 .x3-blob--3 {
  bottom: -20%;
  left: 18%;
  width: 95vmin;
  height: 95vmin;
  opacity: 0.55;
}
.p-x3 .x3-blob--3 > span {
  filter: blur(95px);
  animation-duration: 19s;
  animation-delay: 5s;
  background: radial-gradient(
    circle,
    color-mix(in oklab, var(--color-x3-indigo) 75%, transparent) 0%,
    color-mix(in oklab, var(--color-x3-blue-deep) 30%, transparent) 45%,
    transparent 68%
  );
}
@keyframes x3-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}
.p-x3 .x3-hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    color-mix(in oklab, var(--color-black) 32%, transparent) 0%,
    transparent 32%,
    transparent 52%,
    color-mix(in oklab, var(--color-black) 62%, transparent) 100%
  );
}
.p-x3 .x3-hero__inner {
  position: relative;
  z-index: 1;
  margin-top: auto;
  margin-inline: auto;
  width: 100%;
  max-width: var(--container-large);
  padding: 112px 20px 56px;
}
@media (min-width: 1024px) {
  .p-x3 .x3-hero__inner { padding-inline: 32px; }
}
.p-x3 .x3-hero__title {
  margin-top: 24px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 11vw;
  line-height: 0.98;
}
@media (min-width: 640px) { .p-x3 .x3-hero__title { font-size: 8.5vw; } }
@media (min-width: 1024px) {
  .p-x3 .x3-hero__title { font-size: clamp(52px, 6.4vw, 92px); }
}
.p-x3 .x3-rotate {
  position: relative;
  display: block;
  height: 0.95em;
  color: rgba(255, 255, 255, 0.9);
}
.p-x3 .x3-rotate__line {
  position: absolute;
  inset-inline: 0;
  top: 0;
  opacity: 0;
  transform: translateY(40%);
  transition:
    opacity 0.6s var(--ease-out-expo),
    transform 0.6s var(--ease-out-expo);
}
.p-x3 .x3-rotate__line.is-active {
  opacity: 1;
  transform: none;
}
.p-x3 .x3-rotate__line.is-leaving {
  opacity: 0;
  transform: translateY(-40%);
}
.p-x3 .x3-hero__row {
  display: flex;
  flex-direction: column;
  gap: 40px;
  /* tightened (Sofia, 2026-08-10: "move this a little up") — the sub
     cluster rides closer to the title */
  margin-top: 32px;
}
.p-x3 .x3-hero__row--rule {
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  padding-top: 26px;
}
/* phones + tablets: no rotation (the two variants run 3 vs 2 lines, and
   the swap leaves a hole) — the title is static on its first line, flowing
   at its natural height, so the lockup is always exactly three tight lines */
@media (max-width: 1023px) {
  .p-x3 .x3-rotate { height: auto; }
  .p-x3 .x3-rotate__line {
    position: static;
    transition: none;
  }
  .p-x3 .x3-rotate__line:first-child { opacity: 1; transform: none; }
  .p-x3 .x3-rotate__line + .x3-rotate__line { display: none; }
}
/* phones: the desktop-scale gaps come in a notch */
@media (max-width: 639px) {
  .p-x3 .x3-hero__row { gap: 28px; margin-top: 32px; }
  .p-x3 .x3-hero__row--rule { padding-top: 24px; }
}
/* phones + tablets: the copy block anchors to the BOTTOM like desktop
   (Sofia 2026-08-06: the centered version read weird — one bottom-anchored
   layout everywhere; the scrim's dark foot carries the legibility) */
@media (max-width: 1023px) {
  .p-x3 .x3-hero__inner {
    margin-top: auto;
    /* 44px → 84px foot (Sofia 2026-08-19, iPhone shot): the open banner's
       54px shift + the next section's -20px curtain were covering the
       sub's tail; the copy group now clears both */
    padding-block: 96px 84px;
  }
}
@media (min-width: 1024px) {
  .p-x3 .x3-hero__row {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
    gap: 64px;
  }
}
.p-x3 .x3-hero__sub {
  /* fits the two-line positioning statement at 1280 (layout rule: hero sub
     ≤2 lines); the single Get-started action leaves the row the room */
  max-width: 860px;
  font-size: var(--fs-body);
  line-height: var(--leading-body);
  color: rgba(255, 255, 255, 0.75);
}
/* a step up from body (Sofia, 2026-08-10: "make the highlighted text a
   bit bigger") */
@media (min-width: 640px) { .p-x3 .x3-hero__sub { font-size: var(--fs-xl); } }
/* the positioning statement stays a clean 2-line block at every width:
   text-wrap:balance evens the two lines (it naturally breaks after "users,")
   and never orphans "other side." to a third line. Replaces the old hard
   <br>, whose shrink-to-content box was exactly L2's width — one hair of
   render variance pushed the last words down (Nacim 2026-08-18, on web). */
.p-x3 .x3-hero__sub { text-wrap: balance; }
.p-x3 .x3-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.p-x3 .x3-btn-white {
  height: 44px;
  padding-inline: 24px;
  border-radius: var(--radius-lg);
  background: var(--color-white);
  color: var(--color-black);
}
.p-x3 .x3-btn-white:hover { background: rgba(255, 255, 255, 0.9); }
.p-x3 .x3-btn-ghost {
  height: 44px;
  padding-inline: 24px;
  border-radius: var(--radius-lg);
  border-color: rgba(255, 255, 255, 0.25);
}
.p-x3 .x3-btn-black {
  height: 44px;
  padding-inline: 24px;
  border-radius: var(--radius-lg);
  background: var(--color-black);
  color: var(--color-white);
}
.p-x3 .x3-btn-black:hover { background: rgba(0, 0, 0, 0.85); }

.p-x3 .x3-statement__inner,
.p-x3 .x3-expertise__inner,
.p-x3 .x3-quote__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 1024px) {
  .p-x3 .x3-statement__inner,
.p-x3 .x3-expertise__inner,
.p-x3 .x3-quote__inner { padding-inline: 32px; }
}

/* ---------- statement (bright, full screen, scroll-filled text) ---------- */
.p-x3 .x3-statement {
  border-top: 1px solid var(--color-border-light);
  background: var(--color-background);
  color: var(--color-foreground);
  display: flex;
  flex-direction: column;
  /* the 100vh floor retired (Sofia, 2026-08-04): the leftover height
     pooled under the logo wall and pushed the stat band far down — the
     section now sizes to its content and the stats ride right under
     the wall as one chapter */
  /* curtain edge: the statement is the first section riding over the pinned
     hero, so its top corners round off against the dark video behind it */
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
}
@media (min-width: 768px) {
  .p-x3 .x3-statement {
    border-top-left-radius: 32px;
    border-top-right-radius: 32px;
  }
}

/* ---------- chapter seams (page-flow pass, 2026-07-21) ----------
   The statement's rounded curtain edge over the hero is the page-wide motif:
   every change of ground (bright ⇄ dark) opens on the same rounded edge,
   sliding over the closing chapter. Tone-adjacent neighbors (cases→expertise,
   products→certs, quote→cta) stay flush — they read as one chapter.
   Chapters (products moved before platform, Sofia 2026-08-04): hero ·
   statement+industries · use cases · why · trust stack · products ·
   platform · certs · quotes+cta. certs now opens the dark chapter over
   the bright platform section; products opens black over the stack's
   blue ground. */
.p-x3 .x3-stackc,
.p-x3 .x3-cases,
.p-x3 .x3-products,
.p-x3 .x3-certs,
.p-x3 .x3-quote {
  position: relative;
  margin-top: -20px;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
}
@media (min-width: 768px) {
  .p-x3 .x3-stackc,
  .p-x3 .x3-cases,
  .p-x3 .x3-products,
  .p-x3 .x3-certs,
  .p-x3 .x3-quote {
    margin-top: -32px;
    border-top-left-radius: 32px;
    border-top-right-radius: 32px;
  }
}
/* the chapter being covered gives the overlap back as bottom padding, so
   its closing content keeps its intended breathing room */
.p-x3 .x3-statement,
.p-x3 .x3-stackc,
.p-x3 .x3-expertise,
.p-x3 .x3-certs { padding-bottom: 20px; }
@media (min-width: 768px) {
  .p-x3 .x3-statement,
  .p-x3 .x3-stackc,
  .p-x3 .x3-expertise,
  .p-x3 .x3-certs { padding-bottom: 32px; }
}
.p-x3 .x3-statement__inner {
  width: 100%;
  /* top tightened (Sofia, 2026-08-04) so the 3-row logo wall fits the
     fold; bottom collapsed the same evening so the stat band reads as
     part of this chapter, right under the wall (the section's own 20/32
     seam give-back + the statbar's 8px top supply the remaining air) */
  padding-block: 72px 8px;
  transform: scale(0.94);
  transform-origin: 50% 0;
  transition: transform 0.9s var(--ease-out-expo);
}
@media (min-width: 768px) { .p-x3 .x3-statement__inner { padding-block: 96px 8px; } }
.p-x3 .x3-statement__inner.is-settled { transform: none; }
.p-x3 .x3-statement__text {
  margin-top: 8px;
  /* copy is hand-broken into two lines via .x3-statement__line rows;
     the cap only guards against overflow on narrow desktop widths */
  max-width: 980px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 30px;
  line-height: 1.12;
  letter-spacing: var(--track-tight);
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.28em;
  row-gap: 0.04em;
}
/* each hand-broken line is a full-width row inside the flex container */
.p-x3 .x3-statement__line {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.28em;
  row-gap: 0.04em;
}
/* word-by-word scroll fill: dim words turn black in reading order.
   Resting grey is grey-400, not lighter — WCAG 1.4.3 needs 3:1 for the
   unfilled state (a11y audit 2026-08-05; grey-200 measured 1.58:1) */
.p-x3 .x3-w {
  color: var(--color-grey-400);
  transition: color 0.3s ease;
}
.p-x3 .x3-w.is-filled { color: var(--color-black); }
@media (min-width: 640px) { .p-x3 .x3-statement__text { font-size: 40px; } }
@media (min-width: 768px) { .p-x3 .x3-statement__text { font-size: 50px; } }

/* ---------- why incode / differentiators (bright, expanding card row) ---------- */
.p-x3 .x3-expertise {
  border-top: 1px solid var(--color-border-light);
  background: var(--color-grey-100);
  color: var(--color-foreground);
}
/* same vertical rhythm as the other content sections (was 48/56 — the one
   outlier on the page) */
.p-x3 .x3-expertise__inner { padding-block: var(--space-section-sm); }
@media (min-width: 768px) { .p-x3 .x3-expertise__inner { padding-block: var(--space-section); } }
/* Expanding card row (developios-style): four tall white cards; the
   hovered card (first card when idle) grows and reveals its body and an
   aurora icon tile; a small mono .0N index sits in every card's top-right
   corner. */
.p-x3 .x3-ucs {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin-top: 48px;
}
@media (min-width: 640px) { .p-x3 .x3-ucs { grid-template-columns: repeat(2, 1fr); } }
.p-x3 .x3-uc {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  overflow: hidden;
  border-radius: 24px;
  background: var(--color-white);
  padding: 28px 24px 24px;
}
.p-x3 .x3-uc__title {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: var(--fs-3xl);
  line-height: 1.15;
  color: var(--color-black);
  max-width: 9em;
}
.p-x3 .x3-uc__reveal { margin-top: 12px; }
.p-x3 .x3-uc__line {
  font-size: var(--fs-sm);
  line-height: var(--leading-body);
  color: var(--color-grey-on-white);
  max-width: 46ch;
}
.p-x3 .x3-uc__media {
  width: 100%;
  margin-top: 24px;
  border-radius: 16px;
  overflow: hidden;
}
/* media slot as an aurora tile (same token blues as the hero blobs) with a
   big white glyph */
.p-x3 .x3-uc__media--tile {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 10;
  background:
    radial-gradient(120% 95% at 12% 0%, color-mix(in oklab, var(--color-x3-blue-deep) 80%, transparent), transparent 62%),
    radial-gradient(110% 100% at 92% 100%, color-mix(in oklab, var(--color-x3-indigo) 65%, transparent), transparent 65%),
    color-mix(in oklab, var(--color-black) 86%, var(--color-x3-blue-deep));
}
.p-x3 .x3-uc__tile-icon {
  width: 64px;
  height: 64px;
  -webkit-mask-size: contain;
  mask-size: contain;
  color: var(--color-white);
  opacity: 0.92;
}
/* media slot as a bright product-canvas zoom: PlatformScene.astro renders
   the scene (dot grid + white cards) absolutely inside; the slot only
   frames it. Same layout behavior as --tile (aspect on grid, flex-fill
   inside the desktop accordion). */
.p-x3 .x3-uc__media--canvas {
  position: relative;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--color-border-light);
  background: var(--color-white);
}
.p-x3 .x3-uc__num {
  position: absolute;
  top: 30px;
  right: 24px;
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wider);
  line-height: 1;
  color: var(--color-grey-500);
}
/* Phones/tablets (and any no-hover input): the cards are a stack of CLOSED
   layers — each sheet overlaps the one above it, only num + title showing.
   Tapping a layer opens it (body + aurora tile ease in); tapping again
   closes the deck. x3.js toggles is-open. */
@media (max-width: 1023px), (hover: none) {
  .p-x3 .x3-ucs {
    display: block;
    margin-top: 40px;
  }
  .p-x3 .x3-uc {
    cursor: pointer;
    border: 1px solid var(--color-border-light);
    /* flat sheets, no shadow — the stacked-deck overlap read as broken
       on phones (Nacim, 2026-08-10, screenshot) */
    -webkit-tap-highlight-color: transparent;
  }
  .p-x3 .x3-uc + .x3-uc { margin-top: 12px; }
  /* 'Platform integrations' holds one line — the base 9em cap forced the
     wrap; the closed sheets have the full row for the title (Nacim,
     2026-08-10) */
  .p-x3 .x3-uc__title { max-width: none; }
  /* + affordance, rotating to × when the layer is open */
  .p-x3 .x3-uc::after {
    content: "+";
    position: absolute;
    top: 24px;
    right: 22px;
    font-size: var(--fs-2xl);
    line-height: 1;
    color: var(--color-grey-300);
    transition: transform 0.3s var(--ease-out-expo), color 0.2s ease;
  }
  .p-x3 .x3-uc.is-open::after {
    transform: rotate(45deg);
    color: var(--color-blue);
  }
  .p-x3 .x3-uc__num { right: 48px; }
  /* closed at rest: body + tile take no space, then ease open */
  .p-x3 .x3-uc__reveal {
    max-height: 0;
    margin-top: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-height 0.55s var(--ease-out-expo), opacity 0.3s ease, margin-top 0.55s var(--ease-out-expo);
  }
  .p-x3 .x3-uc.is-open .x3-uc__reveal {
    max-height: 160px;
    margin-top: 12px;
    opacity: 1;
  }
  .p-x3 .x3-uc__media {
    max-height: 0;
    margin-top: 0;
    opacity: 0;
    transition: max-height 0.55s var(--ease-out-expo), opacity 0.35s ease 0.1s, margin-top 0.55s var(--ease-out-expo);
  }
  .p-x3 .x3-uc.is-open .x3-uc__media {
    max-height: 300px;
    margin-top: 20px;
    opacity: 1;
  }
}

/* Desktop with a real pointer: flex accordion. The open card is driven by
   JS (`is-open` from x3.js), not :hover — hover-only state collapses every
   card while the pointer crosses the gaps, which reads as a jitter. JS
   keeps the last-hovered card open across gaps and reverts to the first
   card when the pointer leaves the row. */
@media (min-width: 1024px) and (hover: hover) {
  .p-x3 .x3-ucs {
    display: flex;
    gap: 16px;
  }
  .p-x3 .x3-uc {
    flex: 1 1 0;
    height: clamp(380px, 54vh, 520px);
    padding: 24px 22px 22px;
    transition: flex-grow 0.7s var(--ease-out-expo);
  }
  .p-x3 .x3-uc.is-open { flex-grow: 2.4; }
  /* + affordance in the bottom-right corner: cues that the card reveals
     on hover; fades out once the card is open (mobile's rule doesn't
     apply here, so the closed cards need their own cue) */
  .p-x3 .x3-uc::after {
    content: "+";
    position: absolute;
    bottom: 22px;
    right: 22px;
    z-index: 1;
    font-size: 24px;
    line-height: 1;
    color: var(--color-grey-300);
    transition: opacity 0.3s ease;
  }
  .p-x3 .x3-uc.is-open::after { opacity: 0; }
  /* Constant wrap width + a reserved two-line slot: the title never
     re-wraps while the card animates, and the body below starts at the
     same y in every card. */
  .p-x3 .x3-uc__title {
    font-size: 24px;
    width: 155px;
    max-width: none;
    min-height: 2.3em;
  }
  /* Fixed width so the copy keeps its wrap while the card animates. */
  .p-x3 .x3-uc__reveal {
    width: 380px;
    max-width: none;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  /* In-flow, not absolute: fills whatever space is left below the tags,
     so the copy can never slide under the illustration. */
  .p-x3 .x3-uc__media {
    width: 100%;
    margin: 20px 0 0;
    flex: 1 1 0;
    min-height: 0;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  /* the tile fills whatever height the flex column leaves it */
  .p-x3 .x3-uc__media--tile,
  .p-x3 .x3-uc__media--canvas { aspect-ratio: auto; }
  .p-x3 .x3-uc.is-open .x3-uc__reveal,
  .p-x3 .x3-uc.is-open .x3-uc__media {
    opacity: 1;
    transition: opacity 0.5s ease 0.25s;
  }
  /* index number moves out of the title zone (narrow closed cards can't
     hold a long title AND a top-right number) down to the bottom corner;
     it sits on the open card's bright canvas scene, so it eases to the
     product-chrome grey in sync with the scene's fade-in. */
  .p-x3 .x3-uc__num {
    top: auto;
    bottom: 38px;
    right: 38px;
    z-index: 1;
    transition: color 0.3s ease;
  }
  .p-x3 .x3-uc.is-open .x3-uc__num {
    color: var(--color-grey-400);
    transition: color 0.45s ease 0.25s;
  }
}

/* flowy gradient hover (dark + light variants) */
.p-x3 .x3-flow,
.p-x3 .x3-flow-light {
  position: relative;
  overflow: hidden;
}
.p-x3 .x3-flow > *,
.p-x3 .x3-flow-light > * {
  position: relative;
  z-index: 1;
}
.p-x3 .x3-flow::before,
.p-x3 .x3-flow-light::before {
  content: "";
  position: absolute;
  inset: -45%;
  z-index: 0;
  opacity: 0;
  transition: opacity 0.45s ease;
  will-change: transform, opacity;
}
.p-x3 .x3-flow::before {
  background:
    radial-gradient(42% 60% at 18% 30%, color-mix(in oklab, var(--color-x3-blue-deep) 60%, transparent), transparent 62%),
    radial-gradient(36% 55% at 78% 18%, color-mix(in oklab, var(--color-blue) 45%, transparent), transparent 60%),
    radial-gradient(52% 72% at 62% 85%, color-mix(in oklab, var(--color-x3-indigo) 50%, transparent), transparent 65%),
    radial-gradient(28% 42% at 38% 68%, color-mix(in oklab, var(--color-blue-200) 16%, transparent), transparent 60%);
  filter: blur(28px) saturate(130%);
}
.p-x3 .x3-flow-light::before {
  background:
    radial-gradient(42% 60% at 18% 30%, color-mix(in oklab, var(--color-blue) 22%, transparent), transparent 62%),
    radial-gradient(36% 55% at 78% 18%, color-mix(in oklab, var(--color-blue-200) 50%, transparent), transparent 60%),
    radial-gradient(52% 72% at 62% 85%, color-mix(in oklab, var(--color-x3-blue-deep) 16%, transparent), transparent 65%),
    radial-gradient(28% 42% at 38% 68%, color-mix(in oklab, var(--color-blue-100) 60%, transparent), transparent 60%);
  filter: blur(24px) saturate(120%);
}
.p-x3 .x3-flow:hover::before,
.p-x3 .x3-flow-light:hover::before {
  opacity: 1;
  animation: x3-flow-drift 7s ease-in-out infinite;
}
@keyframes x3-flow-drift {
  0%, 100% { transform: translate(0%, 0%) rotate(0deg) scale(1); }
  33% { transform: translate(6%, -5%) rotate(7deg) scale(1.1); }
  66% { transform: translate(-5%, 4%) rotate(-5deg) scale(1.05); }
}

/* ---------- quote (dark) ---------- */
.p-x3 .x3-quote {
  border-top: 1px solid var(--color-border-light);
  background: var(--color-background);
  color: var(--color-foreground);
}
.p-x3 .x3-quote__inner {
  padding-block: var(--space-section-md);
  text-align: center;
}
@media (min-width: 768px) { .p-x3 .x3-quote__inner { padding-block: 112px; } }
/* testimonial wall (Sofia, 2026-07-23, wiz.io reference): two card rows
   drifting in opposite directions, shorter than the reference — quotes
   line-clamp so every card holds the same compact height. The tracks ride
   the base.css marquee (-50% over a duplicated group); pausing on hover
   lets a card be read; prefers-reduced-motion pauses via .animate-marquee. */
.p-x3 .x3-quote__rows {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 40px;
}
.p-x3 .x3-quote__row {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}
.p-x3 .x3-quote__track {
  display: flex;
  width: max-content;
  will-change: transform;
  /* scaled with the 2026-08-10 set (18 cards per row, was ~5): same
     px/s drift, longer loop */
  animation-duration: 190s;
}
.p-x3 .x3-quote__row--reverse .x3-quote__track {
  animation-direction: reverse;
  animation-duration: 210s; /* slightly slower so the rows never sync up */
}
.p-x3 .x3-quote__row:hover .x3-quote__track { animation-play-state: paused; }
.p-x3 .x3-quote__group { display: flex; }
.p-x3 .x3-qcard {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  flex-shrink: 0;
  width: 320px;
  /* gap as margin (not flex gap) so the -50% loop point stays seamless */
  margin-right: 16px;
  border: 1px solid var(--color-border-light);
  border-radius: 16px;
  background: var(--color-white); /* pure white lifts the cards off the F9F9F9 section ground */
  padding: 24px;
  text-align: left;
}
@media (min-width: 768px) { .p-x3 .x3-qcard { width: 420px; padding: 26px 28px; } }
.p-x3 .x3-qcard__logo {
  height: var(--logo-h, 22px);
  width: auto;
  object-fit: contain;
}
/* G2 reviews: mark + stars + a quiet verified caption where the
   client logo would sit (Sofia, 2026-08-10) */
.p-x3 .x3-qcard__g2 {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 22px;
}
.p-x3 .x3-qcard__g2-logo { height: 22px; width: auto; }
.p-x3 .x3-qcard__g2-stars { height: 14px; width: auto; }
.p-x3 .x3-qcard__g2-cap {
  font-size: var(--fs-xs);
  color: var(--color-grey-on-white);
}
/* anonymous clients: their descriptor sits where the logo would */
.p-x3 .x3-qcard__client {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wider);
  line-height: 22px;
  color: var(--color-grey-500);
}
.p-x3 .x3-qcard__text {
  margin-top: 16px;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--color-black);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  /* 6 lines: the 2026-08-10 testimonial set runs longer than the
     original wall's copy */
  -webkit-line-clamp: 6;
  overflow: hidden;
}
.p-x3 .x3-qcard__attr {
  margin-top: auto;
  padding-top: 18px;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  color: var(--color-grey-on-white);
}
.p-x3 .x3-quote__actions {
  display: flex;
  justify-content: center;
  margin-top: 32px;
}
/* phones (Sofia, 2026-08-07): the drifting marquee doesn't work on
   touch — the wall flattens into ONE regular swipe carousel: every
   quote in a single scroll-snap track, duplicates gone, no animation
   (rows/tracks/groups stop generating boxes via display: contents) */
@media (max-width: 767px) {
  .p-x3 .x3-quote__rows {
    flex-direction: row;
    gap: 0;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    margin-inline: calc(-1 * var(--space-inline));
    padding-inline: var(--space-inline);
    scroll-padding-inline: var(--space-inline);
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .p-x3 .x3-quote__row,
  .p-x3 .x3-quote__track,
  .p-x3 .x3-quote__group { display: contents; }
  .p-x3 .x3-quote__group[aria-hidden="true"] { display: none; }
  .p-x3 .x3-qcard {
    width: 80vw;
    max-width: 340px;
    scroll-snap-align: center;
  }
}

/* phones: the quote band and the CTA close ranks — desktop's air reads as
   a void at one column */
@media (max-width: 639px) {
  .p-x3 .x3-quote__inner { padding-block: 64px 40px; }
}
.p-x3 .x3-btn-outline {
  height: 44px;
  padding-inline: 24px;
  border-radius: var(--radius-lg);
}

/* ---------- trusted-by tile marquee (before the CTA) ----------
   fourmula.ai reference (Sofia, 2026-07-30): the label sits left, one
   rounded near-white tile per client logo drifts by on the base.css
   marquee (2-copy loop), edge fade via mask, pause on hover. */
.p-x3 .x3-trusted {
  border-top: 1px solid var(--color-border-light);
  background: var(--color-background);
  color: var(--color-foreground);
}
.p-x3 .x3-trusted__inner {
  margin-inline: auto;
  width: 100%;
  max-width: var(--container-large);
  padding: 64px 20px;
  display: grid;
  gap: 28px;
  align-items: center;
}
@media (min-width: 1024px) {
  .p-x3 .x3-trusted__inner {
    grid-template-columns: 200px minmax(0, 1fr);
    padding: 88px 32px;
    gap: 40px;
  }
}
.p-x3 .x3-trusted__label {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tight);
  font-size: var(--fs-xl);
  color: var(--color-black);
}
.p-x3 .x3-trusted__row {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}
.p-x3 .x3-trusted__track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation-duration: 55s;
}
.p-x3 .x3-trusted__row:hover .x3-trusted__track { animation-play-state: paused; }
.p-x3 .x3-trusted__group { display: flex; }
.p-x3 .x3-trusted__tile {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 236px;
  height: 168px;
  /* gap as margin (not flex gap) so the -50% loop point stays seamless */
  margin-right: 16px;
  border: 1px solid var(--color-border-light);
  border-radius: 24px;
  /* the ref's soft tile: a whisper of a diagonal grade off the ground */
  background: linear-gradient(135deg, var(--color-grey-50), var(--color-white) 70%);
}
/* the ref's quiet greyscale logos; color returns on hover (the same
   behavior as the partner grid) */
.p-x3 .x3-trusted__tile img {
  filter: grayscale(1);
  opacity: 0.72;
  transition: filter 0.25s ease, opacity 0.25s ease;
}
.p-x3 .x3-trusted__tile:hover img {
  filter: none;
  opacity: 1;
}
@media (max-width: 639px) {
  .p-x3 .x3-trusted__inner { padding: 48px 20px 56px; }
  .p-x3 .x3-trusted__tile { width: 180px; height: 128px; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .p-x3 .x3-blob > span,
  .p-x3 .x3-flow::before,
  .p-x3 .x3-flow-light::before {
    animation: none !important;
    transition: none !important;
  }
  .p-x3 .x3-flow::before,
  .p-x3 .x3-flow-light::before { opacity: 0 !important; }
  /* the gradient reveal never fires here, so the insights just show */
  .p-x3 .x3-stack-row__insight {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .p-x3 .x3-statement__inner { transform: none; }
  .p-x3 .x3-rotate__line { transition: none; }
  .p-x3 .x3-ind__seg.is-on {
    transition: none;
    background: var(--color-x3-blue-deep);
  }
}


/* ---------- industries stat carousel (inside the statement section) ---------- */
.p-x3 .x3-indcar {
  /* tightened (Sofia, 2026-08-04) so the 3-row logo wall fits the fold;
     the divider hairline above the tabs retired (Sofia, 2026-08-06),
     then the title→tabs air trimmed a step (28 → 18, same day) */
  margin-top: 16px;
  padding-top: 18px;
}
@media (min-width: 768px) { .p-x3 .x3-indcar { margin-top: 20px; } }
.p-x3 .x3-indcar__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.p-x3 .x3-indcar__tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  border: 1px solid var(--color-border-light);
  border-radius: 999px;
  background: var(--color-grey-50);
  cursor: pointer;
  /* a step past --fs-xs (Sofia, 2026-08-10: tab labels "too small") */
  font-size: 13px;
  line-height: 1;
  letter-spacing: 0;
  color: var(--color-grey-500);
  transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
}
/* icon inherits the tab's text color (grey → black on hover, white when active);
   sized to the label's cap height so it reads as part of the word */
.p-x3 .x3-indcar__tab-icon {
  width: 16px;
  height: 16px;
}
.p-x3 .x3-indcar__tab:hover {
  border-color: var(--color-grey-300);
  color: var(--color-black);
}
.p-x3 .x3-indcar__tab.is-active {
  border-color: var(--color-black);
  background: var(--color-black);
  color: var(--color-grey-50);
}
.p-x3 .x3-indcar__panes {
  position: relative;
  margin-top: 28px;
}
/* inactive panes stack absolutely; the active one stays in flow so the
   container takes its natural height */
.p-x3 .x3-indcar__pane {
  position: absolute;
  inset: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 24px;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.45s ease, transform 0.45s ease;
  pointer-events: none;
}
.p-x3 .x3-indcar__pane.is-active {
  position: relative;
  inset: auto;
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
/* fixed 50/50 split: the detail column starts at the same x on every tab,
   so switching industries never shifts the layout */
@media (min-width: 1024px) {
  .p-x3 .x3-indcar__pane {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: stretch;
    gap: 48px;
  }
}
/* stat column (Sofia, 2026-07-30): the industry tagline sits at the TOP,
   right under the tab pills; the big number + meter + claim push to the
   column's bottom so their baseline lines up with the logo tiles' bottom
   edge in the right column (both columns stretch to the pane height) */
.p-x3 .x3-ind__stat {
  display: flex;
  flex-direction: column;
}
.p-x3 .x3-ind__stat .x3-indcar__desc {
  margin-top: 0;
}
/* the tagline always holds ONE line (Sofia, 2026-07-30) — nowrap on the
   two-column layout, with a fluid size step-down so the longest line
   ("Secure customer activation…", 76ch) still fits the half-pane column
   at 1024 */
@media (min-width: 1024px) {
  .p-x3 .x3-ind__stat .x3-indcar__desc {
    white-space: nowrap;
    font-size: clamp(12px, 1vw, 14px);
  }
}
.p-x3 .x3-ind__value {
  display: flex;
  align-items: baseline;
  gap: 2px;
  margin-top: 24px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 48px;
  line-height: 1;
  color: var(--color-black);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 768px) { .p-x3 .x3-ind__value { font-size: 56px; } }
@media (min-width: 1024px) { .p-x3 .x3-ind__value { margin-top: auto; } }
.p-x3 .x3-ind__den {
  margin-left: 10px;
  font-size: var(--fs-3xl);
  letter-spacing: var(--track-tight);
  color: var(--color-grey-500);
}
.p-x3 .x3-ind__meter {
  display: flex;
  gap: 3px;
  margin-top: 14px;
  max-width: 320px;
}
.p-x3 .x3-ind__seg {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--color-border-light);
}
.p-x3 .x3-ind__seg.is-on {
  transition: background-color 0.45s ease;
  transition-delay: calc(0.35s + var(--seg) * 0.08s);
}
.p-x3 .x3-indcar__pane.is-active .x3-ind__seg.is-on {
  background: var(--color-x3-blue-deep);
}
.p-x3 .x3-indcar__claim {
  margin-top: 14px;
  font-size: var(--fs-sm);
  line-height: var(--leading-snug);
  color: var(--color-grey-on-white);
}
/* right column: customer logos on top, description below.
   On desktop it hangs off a hairline; both are anchored to the bottom of
   the column — desc baselines with the claim under the meter, logos ride
   just above it. */
.p-x3 .x3-ind__detail { min-width: 0; }
@media (min-width: 1024px) {
  .p-x3 .x3-ind__detail {
    display: flex;
    flex-direction: column;
    border-left: 1px solid var(--color-border-light);
    padding-left: 48px;
    padding-top: 6px;
  }
  .p-x3 .x3-ind__detail .x3-indcar__logos { margin-top: auto; }
}
.p-x3 .x3-indcar__desc {
  margin-top: 20px;
  font-size: var(--fs-sm);
  line-height: var(--leading-snug);
  color: var(--color-grey-on-white);
}
/* one rounded tile per client logo (Sofia, 2026-07-30 reference):
   white cards lifting off the grey-50 statement ground, logo centered */
.p-x3 .x3-indcar__logos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.p-x3 .x3-logo-tile {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 84px;
  padding: 20px 24px;
  border-radius: 16px;
  background: var(--color-white);
  border: 1px solid var(--color-border-light);
}
/* --logo-h is the per-logo optical height set in the INDUSTRIES data:
   a uniform pixel height makes wide wordmarks (Revolut, FanDuel) read huge
   next to compact marks (Citi, Nu), so each logo carries its own height
   tuned to equalize perceived size across every industry row */
.p-x3 .x3-indcar__logos img {
  height: var(--logo-h, 22px);
  width: auto;
}
/* One persistent logo wall (Sofia, 2026-08-04): no panes, no stat column.
   "All" lights every tile; an industry tab lights only its own logos and
   the rest dim in place — the wall itself never moves. */
.p-x3 .x3-indcar__wall {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-top: 28px;
}
@media (min-width: 768px) {
  .p-x3 .x3-indcar__wall {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .p-x3 .x3-indcar__wall {
    grid-template-columns: repeat(8, minmax(0, 1fr));
  }
}
/* narrower tiles than the retired 2×2 industry grids: trim the horizontal
   padding and cap the logo width so wide wordmarks scale down, not clip */
.p-x3 .x3-indcar__wall .x3-logo-tile {
  padding: 20px 14px;
  transition: border-color 0.45s ease;
}
.p-x3 .x3-indcar__wall img {
  height: var(--logo-h, 22px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
  transition: filter 0.45s ease, opacity 0.45s ease;
}
.p-x3 .x3-indcar__wall .x3-logo-tile.is-dim {
  border-color: var(--color-grey-50);
}
.p-x3 .x3-indcar__wall .x3-logo-tile.is-dim img {
  filter: grayscale(1);
  opacity: 0.22;
}
/* mobile wall (Nacim, 2026-08-10, round 3): no industry tabs — the wall
   becomes an AUTO-DRIFTING two-row marquee ('estaría bien que los logos
   se movieran en carrousel automáticamente' — supersedes the manual
   sideways scroller). The tile run is duplicated in the markup
   (.x3-logo-tile--dup, aria-hidden), so a translate of one copy loops
   seamlessly; the shift is -50% minus half the 10px column gap because
   the copy period includes the gap between the two copies. The dup tiles
   render ONLY here — desktop keeps the 32-tile grid. */
.p-x3 .x3-logo-tile--dup { display: none; }
@keyframes x3-wall-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(calc(-50% - 5px)); }
}
@media (max-width: 767px) {
  .p-x3 .x3-indcar__tabs { display: none; }
  .p-x3 .x3-indcar__wallwrap {
    overflow: hidden;
    margin-inline: -20px;
    -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
    mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  }
  .p-x3 .x3-logo-tile--dup { display: flex; }
  .p-x3 .x3-indcar__wall {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-template-rows: repeat(2, auto);
    grid-auto-columns: 148px;
    gap: 10px;
    width: max-content;
    margin-top: 8px;
    padding-block: 8px 12px;
    animation: x3-wall-marquee 60s linear infinite;
    will-change: transform;
  }
  .p-x3 .x3-indcar__wall .x3-logo-tile {
    padding: 18px 10px;
  }
}
/* reduced motion: the marquee parks — fall back to the manual sideways
   scroller so every logo stays reachable */
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .p-x3 .x3-indcar__wall { animation: none; }
  .p-x3 .x3-indcar__wallwrap {
    overflow-x: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* ---------- stat banner (open ledger under the logo wall) ----------
   The dark aurora plate retired (Sofia, 2026-08-04: too rigid) — the
   stats sit directly on the bright ground as top-aligned columns: every
   figure starts on the same top edge as the 7.1B+, and each caption
   tucks right under its own figure (the shared caption row was tried
   and dropped — it stranded the taglines mid-air below the small
   figures). Numbers on bright take the canonical blue→black fill
   (base.css .stat-grad); count-up unchanged (site.js data-counter). */
.p-x3 .x3-statbar {
  background: var(--color-background);
}
.p-x3 .x3-statbar__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  /* breathing room both sides (Sofia, 2026-08-04: "too tight"); top
     trimmed a notch toward the wall (Sofia, 2026-08-10: "reduce the
     space between the logo cards and the stats, just a bit") */
  padding: 28px var(--space-inline) 96px;
}
@media (min-width: 1024px) {
  .p-x3 .x3-statbar__inner {
    padding-block: 36px 112px;
    padding-inline: 24px;
  }
}
.p-x3 .x3-statbar__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* stacked pairs top-align (caps wrap to different depths on phones) */
  align-items: start;
  gap: 36px 32px;
  color: var(--color-black);
}
/* phones (Sofia, 2026-08-07): the 7.1B leads ALONE on its own full
   row, big; the four secondary pairs follow as two 2-up rows */
@media (max-width: 1023px) {
  .p-x3 .x3-statbar__lead { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
  .p-x3 .x3-statbar__row {
    grid-template-columns: 1.15fr repeat(4, 1fr);
    /* the four pairs center on the lead number's height so the band reads
       as ONE aligned line (Sofia, 2026-08-04: "align this horizontally") */
    align-items: center;
    gap: 0 32px;
  }
  /* hairline dividers structure the row like the nav menus */
  .p-x3 .x3-statbar__item {
    border-left: 1px solid var(--color-border-light);
    padding-left: 32px;
  }
}
/* hover: the pair lifts and its figure takes the brand blue — the band
   answers the pointer instead of sitting flat (Sofia: "too plain").
   The lift rides on the CHILDREN, never the hovered box itself: moving
   the hit area out from under an edge-parked pointer flickers hover
   on/off (Sofia, 2026-08-07: "weird bounce/vibration") */
.p-x3 .x3-statbar__fig,
.p-x3 .x3-statbar__cap {
  transition: color 0.25s ease, transform 0.3s var(--ease-out-expo);
}
.p-x3 .x3-statbar__item:hover .x3-statbar__fig,
.p-x3 .x3-statbar__item:hover .x3-statbar__cap { transform: translateY(-4px); }
.p-x3 .x3-statbar__item:hover .x3-statbar__fig { color: var(--color-blue); }
.p-x3 .x3-statbar__item:hover .x3-statbar__cap { color: var(--color-foreground); }
.p-x3 .x3-statbar__num {
  font-family: var(--font-display);
  font-weight: 500;
  /* full-row lead on phones carries the same 72px as desktop
     (Sofia, 2026-08-07: "on its own, big") */
  font-size: 72px;
  line-height: 1;
  letter-spacing: var(--track-tight);
}
.p-x3 .x3-statbar__fig {
  /* sized to hold "8 of the top 10" on ONE line inside its column */
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: var(--track-tight);
  white-space: nowrap;
  color: var(--color-black);
}
@media (min-width: 768px) { .p-x3 .x3-statbar__fig { font-size: 22px; } }
.p-x3 .x3-statbar__cap {
  margin-top: 8px;
  font-size: var(--fs-sm);
  color: var(--color-grey-on-white);
}

/* ---------- why incode: section title ---------- */
.p-x3 .x3-expertise__title {
  margin-top: 16px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  color: var(--color-black);
  font-size: 26px;
  line-height: 1.05;
}
@media (min-width: 640px) { .p-x3 .x3-expertise__title { font-size: 32px; } }
@media (min-width: 768px) { .p-x3 .x3-expertise__title { font-size: 36px; } }
/* one-sentence sub under the title (Sofia, 2026-08-04); no width cap so
   it holds a single line on desktop */
.p-x3 .x3-expertise__intro {
  margin-top: 14px;
  font-size: var(--fs-body);
  line-height: var(--leading-body);
  color: var(--color-grey-on-white);
}
/* ---------- "Show all" title-row link (platform / products) ----------
   the action rides the section title's baseline as a quiet underlined
   mono link instead of a detached button row below the content */
.p-x3 .x3-titlerow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 24px;
}
.p-x3 .x3-showall {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* padding-block lifts the 21px link over the 24px a11y tap floor; the
     negative margin keeps the titlerow baseline seat unchanged */
  padding-block: 6px;
  margin-block: -6px;
  font-size: var(--fs-sm);
  letter-spacing: var(--track-widest);
  color: rgba(255, 255, 255, 0.6);
  transition: color 0.2s ease;
}
.p-x3 .x3-showall__label {
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-color: color-mix(in oklab, currentColor 45%, transparent);
  transition: text-decoration-color 0.2s ease;
}
.p-x3 .x3-showall:hover { color: var(--color-white); }
.p-x3 .x3-showall:hover .x3-showall__label { text-decoration-color: currentColor; }
.p-x3 .x3-showall--light { color: var(--color-grey-on-white); }
.p-x3 .x3-showall--light:hover { color: var(--color-black); }

/* ---------- platform stack (dark pillar cards) ---------- */
.p-x3 .x3-stack {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--color-black);
  color: var(--color-white);
}
.p-x3 .x3-stack__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-stack__inner { padding-block: var(--space-section); } }
@media (min-width: 1024px) { .p-x3 .x3-stack__inner { padding-inline: 24px; } }
.p-x3 .x3-stack__title {
  margin-top: 24px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 26px;
  line-height: 1.05;
}
@media (min-width: 640px) { .p-x3 .x3-stack__title { font-size: 32px; } }
@media (min-width: 768px) { .p-x3 .x3-stack__title { font-size: 36px; } }
.p-x3 .x3-stack__intro {
  margin-top: 16px;
  font-size: var(--fs-body);
  line-height: var(--leading-body);
  color: rgba(255, 255, 255, 0.7);
}
.p-x3 .x3-stack__rows { margin-top: 32px; }
.p-x3 .x3-stack-row {
  display: grid;
  gap: 10px;
  align-items: center;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  padding: 26px 20px;
  cursor: default;
}
.p-x3 .x3-stack-row:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.12); }
@media (min-width: 768px) {
  .p-x3 .x3-stack-row {
    grid-template-columns: 1fr auto 24px;
    gap: 32px;
    padding: 30px 28px;
  }
}
.p-x3 .x3-stack-row__main {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.p-x3 .x3-stack-row__name {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: var(--fs-2xl);
  line-height: 1.15;
  color: var(--color-white);
}
@media (min-width: 768px) { .p-x3 .x3-stack-row__name { font-size: 24px; } }
.p-x3 .x3-stack-row__line {
  font-size: var(--fs-sm);
  line-height: var(--leading-snug);
  color: rgba(255, 255, 255, 0.65);
}
/* insight claim: hidden at rest, fades in with the row's flow gradient
   (same 0.45s ease as .x3-flow::before) so they read as one reveal */
.p-x3 .x3-stack-row__insight {
  max-width: 380px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tight);
  font-size: var(--fs-2xl);
  line-height: 1.25;
  text-align: right;
  text-wrap: balance;
  color: var(--color-white);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
@media (min-width: 768px) { .p-x3 .x3-stack-row__insight { font-size: var(--fs-3xl); } }
.p-x3 .x3-stack-row:hover .x3-stack-row__insight {
  opacity: 1;
  transform: none;
}
/* no pointer to hover with (touch): the insight is simply visible */
@media (hover: none) {
  .p-x3 .x3-stack-row__insight {
    opacity: 1;
    transform: none;
    text-align: left;
  }
}
.p-x3 .x3-stack-row__arrow {
  display: none;
  color: rgba(255, 255, 255, 0.3);
  opacity: 0;
  transition: opacity 0.3s ease, transform 0.3s ease, color 0.3s ease;
}
@media (min-width: 768px) { .p-x3 .x3-stack-row__arrow { display: block; } }
.p-x3 .x3-stack-row:hover .x3-stack-row__arrow {
  opacity: 1;
  transform: translateX(4px);
  color: var(--color-blue-200);
}

/* ---------- trust stack, alternate (one question at a time) ----------
   Exploration 2026-07-21: question list left (mono index, meter sweep on
   the active row), single answer pane right. Same carousel contract as
   x3-indcar: auto-rotate 4s, click pins. Old three-row version keeps its
   styles above (still live on /agentic-fraud/). */
.p-x3 .x3-stackb {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--color-black);
  color: var(--color-white);
}
.p-x3 .x3-stackb__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-stackb__inner { padding-block: var(--space-section); } }
@media (min-width: 1024px) { .p-x3 .x3-stackb__inner { padding-inline: 24px; } }
/* one framed card ties questions and answer together (Sofia, 2026-07-21):
   shared border + faint wash, full-height division between the columns */
.p-x3 .x3-stackb__grid {
  display: grid;
  grid-template-columns: 1fr;
  margin-top: 48px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 24px;
  background:
    radial-gradient(70% 60% at 100% 0%, color-mix(in oklab, var(--color-x3-blue-deep) 16%, transparent), transparent 65%),
    rgba(255, 255, 255, 0.02);
  overflow: hidden;
}
@media (min-width: 900px) {
  .p-x3 .x3-stackb__grid {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    align-items: stretch;
  }
}
.p-x3 .x3-stackb__tabs {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 24px 24px 28px;
}
/* the three questions own the column's full height (Sofia, 2026-07-21):
   rows grow evenly edge to edge, hairlines only BETWEEN rows — no dead
   band above the first question or below the last */
@media (min-width: 900px) {
  .p-x3 .x3-stackb__tabs { padding: 0 40px 0 36px; }
  .p-x3 .x3-stackb__tab {
    flex: 1;
    display: flex;
    align-items: center;
    padding: 16px 0;
  }
  .p-x3 .x3-stackb__tabs .x3-stackb__tab:first-child { border-top: 0; }
  .p-x3 .x3-stackb__tabs .x3-stackb__tab:last-child { border-bottom: 0; }
}
/* question-only rows (Sofia, 2026-07-21): no number, no name, no meter —
   the pillar name lives as the answer's kicker instead, and rows respond
   to hover as well as click (x3.js) */
.p-x3 .x3-stackb__tab {
  position: relative;
  display: block;
  padding: 26px 0;
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  background: none;
  text-align: left;
  cursor: pointer;
}
.p-x3 .x3-stackb__tab:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.12); }
.p-x3 .x3-stackb__tab-q {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tight);
  font-size: 19px;
  line-height: 1.2;
  color: rgba(255, 255, 255, 0.45);
  transition: color 0.3s ease;
}
@media (min-width: 768px) { .p-x3 .x3-stackb__tab-q { font-size: var(--fs-3xl); } }
.p-x3 .x3-stackb__tab:hover .x3-stackb__tab-q { color: rgba(255, 255, 255, 0.75); }
.p-x3 .x3-stackb__tab.is-active .x3-stackb__tab-q { color: var(--color-white); }
/* panes: overlay idiom shared with x3-indcar so switching never reflows */
/* grid-stack idiom: every pane occupies the same cell, so the TALLEST pane
   sets the card height for all three questions — the card never resizes on
   switch (Sofia, 2026-07-21) */
.p-x3 .x3-stackb__panes {
  position: relative;
  display: grid;
  align-content: center;
  padding: 28px 24px 32px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
@media (min-width: 900px) {
  .p-x3 .x3-stackb__panes {
    padding: 44px 48px;
    border-top: 0;
    border-left: 1px solid rgba(255, 255, 255, 0.1);
  }
}
/* ---- the stack as layers: three glowing discs stacked vertically ----
   (Sofia's reference: translucent blue ellipses overlapping downward.)
   The stack lives behind the answer, bleeding off the card's right edge
   (the grid's overflow:hidden crops it). The active question lights its
   layer: pane 0 → top disc, 1 → middle, 2 → bottom. Pure CSS :has(). */
.p-x3 .x3-stackb__layers { display: none; }
@media (min-width: 1100px) {
  .p-x3 .x3-stackb__layers {
    display: block;
    position: absolute;
    top: 50%;
    right: -56px;
    width: 320px;
    height: 360px;
    transform: translateY(-50%);
    pointer-events: none;
  }
  /* keep the answer copy clear of the stack zone */
  .p-x3 .x3-stackb__pane { padding-right: 240px; }
}
.p-x3 .x3-disc {
  opacity: 0.34;
  transition: opacity 0.55s ease;
  /* the container is pointer-events:none; each disc opts back in so its
     layer title can reveal on hover */
  pointer-events: auto;
}
.p-x3 .x3-disc:hover { opacity: 1; }
.p-x3 .x3-disc__label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-widest);
  fill: var(--color-white);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.p-x3 .x3-disc:hover .x3-disc__label { opacity: 1; }
.p-x3 .x3-disc .x3-disc__glow {
  opacity: 0.14;
  transition: opacity 0.55s ease;
}
.p-x3 .x3-stackb__grid:has(.x3-stackb__pane[data-stackb-pane="0"].is-active) .x3-disc--1,
.p-x3 .x3-stackb__grid:has(.x3-stackb__pane[data-stackb-pane="1"].is-active) .x3-disc--2,
.p-x3 .x3-stackb__grid:has(.x3-stackb__pane[data-stackb-pane="2"].is-active) .x3-disc--3 {
  opacity: 1;
}
.p-x3 .x3-stackb__grid:has(.x3-stackb__pane[data-stackb-pane="0"].is-active) .x3-disc--1 .x3-disc__glow,
.p-x3 .x3-stackb__grid:has(.x3-stackb__pane[data-stackb-pane="1"].is-active) .x3-disc--2 .x3-disc__glow,
.p-x3 .x3-stackb__grid:has(.x3-stackb__pane[data-stackb-pane="2"].is-active) .x3-disc--3 .x3-disc__glow {
  opacity: 0.6;
}
.p-x3 .x3-stackb__pane {
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(12px);
  /* exit stays instant; only the ENTERING pane animates (rule below) */
  transition: none;
  pointer-events: none;
}
.p-x3 .x3-stackb__pane.is-active {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.p-x3 .x3-stackb__pane-name {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-widest);
  color: var(--color-blue-200);
}
.p-x3 .x3-stackb__pane-line {
  margin-top: 12px;
  max-width: 620px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 26px;
  line-height: 1.15;
  color: var(--color-white);
  text-wrap: pretty;
}
@media (min-width: 768px) { .p-x3 .x3-stackb__pane-line { font-size: 33px; } }
/* the problems each pillar solves, as a quiet bullet list under the solution */
.p-x3 .x3-stackb__pane-points {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 22px;
  list-style: none;
  padding: 0;
}
.p-x3 .x3-stackb__pane-points li {
  position: relative;
  padding-left: 18px;
  font-size: var(--fs-sm);
  line-height: var(--leading-snug);
  color: rgba(255, 255, 255, 0.7);
}
.p-x3 .x3-stackb__pane-points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 9999px;
  background: var(--color-blue);
}

/* ---------- trust stack, blueprint plate (specia1ne.com reference) ----------
   Flat Incode-blue ground, two-column rows split by horizontal hairlines
   (spine + numbered chips removed, Sofia 2026-07-24). The active row turns
   white, grows a step, and reveals its solution line (right column) +
   arrow (far right). Carousel contract unchanged: 4s auto-rotate, manual
   click pins. */
.p-x3 .x3-stackc {
  /* ink ground with the hero's aurora hues bleeding in from the corners */
  background:
    radial-gradient(90% 70% at 12% 0%, color-mix(in oklab, var(--color-x3-blue-deep) 38%, transparent), transparent 62%),
    radial-gradient(70% 55% at 95% 100%, color-mix(in oklab, var(--color-x3-indigo) 30%, transparent), transparent 65%),
    var(--color-black);
  color: var(--color-white);
}
.p-x3 .x3-stackc__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-stackc__inner { padding-block: var(--space-section); } }
@media (min-width: 1024px) { .p-x3 .x3-stackc__inner { padding-inline: 24px; } }
/* single-column head: the head-right highlighted intro retired
   (Sofia, 2026-08-04) */
.p-x3 .x3-stackc__head {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
.p-x3 .x3-stackc__label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  color: rgba(255, 255, 255, 0.65);
}
.p-x3 .x3-stackc__title {
  margin-top: 24px;
  max-width: 24ch;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 30px;
  line-height: 1.02;
  color: var(--color-white);
}
@media (min-width: 640px) { .p-x3 .x3-stackc__title { font-size: 40px; } }
@media (min-width: 1280px) { .p-x3 .x3-stackc__title { font-size: 50px; } }
/* column heads: mono labels over each column — desktop only,
   on mobile the answer sits right under its question so no cue is needed */
.p-x3 .x3-stackc__colhead { display: none; }
@media (min-width: 900px) {
  .p-x3 .x3-stackc__colhead {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 28px;
    margin-top: 56px;
  }
}
.p-x3 .x3-stackc__colhead-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-widest);
  color: rgba(255, 255, 255, 0.6);
}
/* row list: horizontal hairlines between rows */
.p-x3 .x3-stackc__rows {
  position: relative;
  margin-top: 56px;
  border-top: 1px solid rgba(255, 255, 255, 0.32);
}
@media (min-width: 900px) {
  .p-x3 .x3-stackc__colhead + .x3-stackc__rows { margin-top: 14px; }
}
.p-x3 .x3-stackc__row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  width: 100%;
  padding: 26px 0;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.32);
  background: none;
  text-align: left;
  color: inherit;
  cursor: pointer;
}
@media (min-width: 900px) {
  .p-x3 .x3-stackc__row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 28px;
    align-items: center;
    padding: 34px 0;
  }
}
/* left cell: the question with its layer name as subtitle underneath */
.p-x3 .x3-stackc__left {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  min-width: 0;
}
.p-x3 .x3-stackc__q {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: var(--fs-2xl);
  line-height: 1.05;
  color: rgba(255, 255, 255, 0.55);
  text-align: left;
  transition: color 0.45s ease, font-size 0.45s ease;
}
@media (min-width: 900px) { .p-x3 .x3-stackc__q { font-size: var(--fs-3xl); } }
@media (min-width: 1100px) { .p-x3 .x3-stackc__q { white-space: nowrap; } }
@media (min-width: 1280px) { .p-x3 .x3-stackc__q { font-size: 24px; } }
.p-x3 .x3-stackc__row:hover .x3-stackc__q { color: rgba(255, 255, 255, 0.8); }
.p-x3 .x3-stackc__row.is-active .x3-stackc__q { color: var(--color-white); }
@media (min-width: 900px) {
  .p-x3 .x3-stackc__row.is-active .x3-stackc__q { font-size: 25px; }
}
@media (min-width: 1280px) {
  .p-x3 .x3-stackc__row.is-active .x3-stackc__q { font-size: 29px; }
}
/* phones (single column): the hidden answer stops reserving space —
   inactive rows collapse to just question + layer name instead of
   leaving a void */
@media (max-width: 899px) {
  .p-x3 .x3-stackc__row .x3-stackc__right { display: none; }
  .p-x3 .x3-stackc__row.is-active .x3-stackc__right { display: flex; }
}
.p-x3 .x3-stackc__name {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-widest);
  color: rgba(255, 255, 255, 0.7);
}
.p-x3 .x3-stackc__row.is-active .x3-stackc__name { color: var(--color-white); }
/* right cell: the answer line, revealed with the active row */
.p-x3 .x3-stackc__right {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding-right: 40px;
}
.p-x3 .x3-stackc__line {
  max-width: 44ch;
  font-size: var(--fs-body);
  line-height: var(--leading-snug);
  color: rgba(255, 255, 255, 0.85);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.p-x3 .x3-stackc__row.is-active .x3-stackc__line {
  opacity: 1;
  transform: none;
}
/* the open-card affordance: a 48px ring on EVERY row (Sofia, 2026-08-04:
   "a lot more evident that a card popup appears"), filling to a solid
   white disc on the active row and nudging ↗ on hover — the drill-in
   reads as a button, not a stray glyph */
.p-x3 .x3-stackc__arrow {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  display: none;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.28);
  color: var(--color-white);
  opacity: 0.55;
  transition: opacity 0.45s ease, background-color 0.3s ease, border-color 0.3s ease,
    color 0.3s ease, transform 0.3s ease;
}
.p-x3 .x3-stackc__arrow svg { width: 22px; height: 22px; }
@media (min-width: 900px) { .p-x3 .x3-stackc__arrow { display: flex; } }
.p-x3 .x3-stackc__row:hover .x3-stackc__arrow { opacity: 1; border-color: rgba(255, 255, 255, 0.55); }
.p-x3 .x3-stackc__row.is-active .x3-stackc__arrow {
  opacity: 1;
  background: var(--color-white);
  border-color: var(--color-white);
  color: var(--color-black);
}
.p-x3 .x3-stackc__row.is-active:hover .x3-stackc__arrow {
  transform: translateY(-50%) translate(2px, -2px);
}
/* ---------- trust stack layer modal ----------
   Click on a row opens the layer's detail card: question, answer, the
   "stops" chips, and the products that solve that question. Hover keeps
   the row-preview behavior; click is the drill-in. */
.p-x3 .x3-stackm {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.p-x3 .x3-stackm[hidden] { display: none; } /* redundant since base.css [hidden], kept as doc */
/* mid-fade the overlay must not eat clicks (siteModal fade window) */
.p-x3 .x3-stackm:not(.is-open) { pointer-events: none; }
.p-x3 .x3-stackm__backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--color-black) 72%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.p-x3 .x3-stackm.is-open .x3-stackm__backdrop { opacity: 1; }
.p-x3 .x3-stackm__panel {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: min(85dvh, 720px);
  overflow-y: auto;
  padding: 34px 26px 26px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 20px;
  /* same ink ground as the section, one step lifted, with the aurora
     bleeding in from the top corner */
  background:
    radial-gradient(120% 80% at 12% 0%, color-mix(in oklab, var(--color-x3-blue-deep) 32%, transparent), transparent 62%),
    color-mix(in oklab, var(--color-black) 94%, white);
  color: var(--color-white);
  opacity: 0;
  transform: translateY(14px) scale(0.985);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
@media (min-width: 640px) { .p-x3 .x3-stackm__panel { padding: 40px 36px 32px; } }
.p-x3 .x3-stackm.is-open .x3-stackm__panel {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .p-x3 .x3-stackm__backdrop,
  .p-x3 .x3-stackm__panel { transition: none; }
}
.p-x3 .x3-stackm__close {
  position: absolute;
  top: 16px;
  right: 16px;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 50%;
  background: none;
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.p-x3 .x3-stackm__close:hover {
  color: var(--color-white);
  border-color: rgba(255, 255, 255, 0.5);
}
.p-x3 .x3-stackm__eyebrow {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  color: rgba(255, 255, 255, 0.65);
}
.p-x3 .x3-stackm__q {
  margin-top: 14px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 26px;
  line-height: 1.05;
  color: var(--color-white);
}
@media (min-width: 640px) { .p-x3 .x3-stackm__q { font-size: 30px; } }
.p-x3 .x3-stackm__line {
  margin-top: 12px;
  max-width: 46ch;
  font-size: var(--fs-body);
  line-height: var(--leading-body);
  color: rgba(255, 255, 255, 0.8);
}
.p-x3 .x3-stackm__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
  padding: 0;
  list-style: none;
}
.p-x3 .x3-stackm__chip {
  padding: 6px 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  font-size: var(--fs-xs);
  line-height: 1;
  color: rgba(255, 255, 255, 0.85);
  white-space: nowrap;
}
.p-x3 .x3-stackm__products-label {
  margin-top: 30px;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-widest);
  color: rgba(255, 255, 255, 0.6);
}
.p-x3 .x3-stackm__products {
  margin-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.p-x3 .x3-stackm__product {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 2px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  color: inherit;
  text-decoration: none;
}
/* the products list closes the card — no hairline under the last row */
.p-x3 .x3-stackm__product:last-child { border-bottom: 0; }
.p-x3 .x3-stackm__product-glyph {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 12px;
  color: var(--color-white);
  transition: border-color 0.2s ease;
}
.p-x3 .x3-stackm__product:hover .x3-stackm__product-glyph { border-color: rgba(255, 255, 255, 0.4); }
.p-x3 .x3-stackm__product-icon {
  width: 22px;
  height: 22px;
}
.p-x3 .x3-stackm__product-copy {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.p-x3 .x3-stackm__product-name {
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.2;
  color: var(--color-white);
  transition: color 0.2s ease;
}
/* hover says "this is a link": name lights up blue (lightened for the ink
   background) while the glyph border and the arrow come up alongside */
.p-x3 .x3-stackm__product:hover .x3-stackm__product-name {
  color: var(--color-blue-200);
}
.p-x3 .x3-stackm__product-line {
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.7);
}
.p-x3 .x3-stackm__product-arrow {
  margin-left: auto;
  flex: none;
  color: var(--color-white);
  opacity: 0;
  transform: translate(-4px, 4px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.p-x3 .x3-stackm__product:hover .x3-stackm__product-arrow {
  opacity: 1;
  transform: none;
}
/* ---------- use cases (bright four-column map: one column per pillar) ----------
   Flat replacement for the tabbed one-pillar carousel (Sofia, 2026-07-21):
   all four trust pillars visible at once, each a hairline-topped column.
   Uneven item counts just leave shorter columns — no frame to fill, so
   2-item pillars no longer read as empty. */
.p-x3 .x3-cases {
  background: var(--color-black);
  color: var(--color-white);
}
.p-x3 .x3-cases__inner {
  margin-inline: auto;
  width: 100%;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-cases__inner { padding-block: var(--space-section); } }
@media (min-width: 1024px) { .p-x3 .x3-cases__inner { padding-inline: 24px; } }
/* heading left, paging arrows bottom-right on the same baseline */
.p-x3 .x3-cases__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
}
.p-x3 .x3-cases__title {
  margin-top: 24px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 26px;
  line-height: 1.05;
  color: var(--color-white);
}
@media (min-width: 640px) { .p-x3 .x3-cases__title { font-size: 32px; } }
@media (min-width: 768px) { .p-x3 .x3-cases__title { font-size: 38px; } }
@media (min-width: 1280px) { .p-x3 .x3-cases__title { font-size: 42px; } }
/* ---------- use cases: tabbed split (Sofia, 2026-08-06) ----------
   Type-over-photo legibility fix: audience TABS switch the pane (line +
   use-case ledger) beside the photo plate; pane and photo crossfade
   together. Site carousel contract: 6s auto-advance, a manual pick pins
   (x3.js [data-x3-uctabs]). The photo-card carousel lives in git. */
/* spotlight panels (Sofia, 2026-08-06 ×2): three photo panels, the
   active one widens and reveals its body; the others collapse to icon +
   name slivers. Compact: the row is 480px, not a viewport. */
.p-x3 .x3-uct {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 40px;
}
@media (min-width: 1024px) {
  .p-x3 .x3-uct {
    flex-direction: row;
    /* a notch shorter (Sofia, 2026-08-06 ×4) */
    height: 440px;
  }
}
.p-x3 .x3-uct__panel {
  position: relative;
  overflow: hidden;
  border-radius: 20px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 96px;
  transition: flex 0.75s var(--ease-out-expo);
}
@media (min-width: 1024px) {
  .p-x3 .x3-uct__panel { flex: 0.62 1 0; min-height: 0; }
  .p-x3 .x3-uct__panel.is-active { flex: 2.3 1 0; cursor: default; }
}
.p-x3 .x3-uct__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* collapsed slivers run dimmer; the spotlight photo opens up */
  filter: brightness(0.52);
  transform: scale(1.06);
  transition: filter 0.6s ease, transform 0.9s var(--ease-out-expo);
}
.p-x3 .x3-uct__panel.is-active .x3-uct__img {
  filter: brightness(0.72);
  transform: scale(1);
}
/* bottom-heavy legibility scrim, stronger while spotlighted (the body
   text sits over it) */
.p-x3 .x3-uct__panel-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    color-mix(in oklab, var(--color-black) 12%, transparent) 0%,
    color-mix(in oklab, var(--color-black) 30%, transparent) 45%,
    color-mix(in oklab, var(--color-black) 82%, transparent) 100%
  );
  opacity: 0.7;
  transition: opacity 0.6s ease;
}
/* the spotlight gets a far more dramatic floor (Sofia, 2026-08-06 ×3:
   legibility) — near-solid ink under the copy block, clearing by the
   panel's upper third so the photo still opens the frame */
.p-x3 .x3-uct__panel.is-active .x3-uct__panel-scrim {
  opacity: 1;
  background: linear-gradient(
    180deg,
    color-mix(in oklab, var(--color-black) 18%, transparent) 0%,
    color-mix(in oklab, var(--color-black) 46%, transparent) 34%,
    color-mix(in oklab, var(--color-black) 88%, transparent) 62%,
    color-mix(in oklab, var(--color-black) 97%, transparent) 100%
  );
}
.p-x3 .x3-uct__panel-copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px;
}
@media (min-width: 1024px) { .p-x3 .x3-uct__panel-copy { padding: 28px; } }
.p-x3 .x3-uct__panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.p-x3 .x3-uct__panel-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 12px;
  color: var(--color-white);
}
.p-x3 .x3-uct__panel-glyph svg,
.p-x3 .x3-uct__panel-glyph span,
.p-x3 .x3-uct__panel-glyph img { width: 18px; height: 18px; }
.p-x3 .x3-uct__panel-name {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: var(--fs-2xl);
  line-height: 1.1;
  color: var(--color-white);
  white-space: nowrap;
  transition: font-size 0.55s var(--ease-out-expo);
}
/* the spotlight's name steps up with the panel (Sofia, 2026-08-06 ×5) */
.p-x3 .x3-uct__panel.is-active .x3-uct__panel-name {
  font-size: 30px;
}
/* the body unfolds only in the spotlight (grid-rows so height animates) */
.p-x3 .x3-uct__panel-body {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.7s var(--ease-out-expo), opacity 0.45s ease;
}
.p-x3 .x3-uct__panel-body.is-active {
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows 0.7s var(--ease-out-expo), opacity 0.55s ease 0.2s;
}
.p-x3 .x3-uct__panel-reveal {
  /* clip ONLY the unfold axis: a full overflow:hidden also clipped the
     link arrows' 4px hover slide at the right edge (Sofia, 2026-08-07) */
  overflow-x: visible;
  overflow-y: clip;
  /* release the grid item's automatic minimum size — without this the
     0fr row holds its full content height and the collapsed panel's
     title floats mid-card instead of settling back down (Sofia,
     2026-08-10) */
  min-height: 0;
  min-width: min(520px, 62vw);
  max-width: 560px;
}
.p-x3 .x3-uct__line {
  max-width: 46ch;
  font-size: var(--fs-body);
  line-height: var(--leading-body);
  color: rgba(255, 255, 255, 0.75);
}
.p-x3 .x3-uct__list {
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}
.p-x3 .x3-uct__item { border-top: 1px solid rgba(255, 255, 255, 0.12); }
.p-x3 .x3-uct__item:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.12); }
.p-x3 .x3-uct__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 13px 0;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  transition: color 0.25s ease;
}
.p-x3 .x3-uct__link-name {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tight);
  font-size: 18px;
  line-height: 1.2;
}
.p-x3 .x3-uct__link-arrow {
  flex-shrink: 0;
  color: rgba(255, 255, 255, 0.45);
  /* GPU transform + expo ease: the 15px hairline arrow shimmered and
     read "wonky" while translating on the compositor-less path
     (Sofia, 2026-08-06) */
  transform: translate3d(0, 0, 0);
  will-change: transform;
  backface-visibility: hidden;
  transition: transform 0.3s var(--ease-out-expo), color 0.25s ease;
}
.p-x3 .x3-uct__link-arrow svg { display: block; width: 15px; height: 15px; }
.p-x3 .x3-uct__link:hover { color: var(--color-white); }
.p-x3 .x3-uct__link:hover .x3-uct__link-arrow {
  color: var(--color-blue-200);
  transform: translate3d(4px, 0, 0);
}


/* ---------- trionn-style curtain entrance (trionn.com ref, Sofia
   2026-08-04) ----------
   Applied by x3.js to the children of any [data-x3-curtain] group (the
   use-case cards + the why-incode cells): each item enters unmasking
   upward from its bottom edge while it settles the last 24px into
   place; a card photo starts a step deeper into its zoom and lands with
   the mask. --curtain-delay staggers the group left to right. x3.js
   strips the classes once the mask lands so this transition never
   bleeds into the hover motion; no-JS and reduced-motion never get the
   classes, so content stays visible. */
.p-x3 .x3-curtain {
  clip-path: inset(100% 0 0 0 round 16px);
  transform: translateY(24px);
}
.p-x3 .x3-curtain.is-in {
  clip-path: inset(0 round 16px);
  transform: none;
  transition:
    clip-path 0.9s var(--ease-out-expo) var(--curtain-delay, 0s),
    transform 0.9s var(--ease-out-expo) var(--curtain-delay, 0s);
}
.p-x3 .x3-case__name {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 28px;
  line-height: 1.12;
  color: var(--color-white);
}
.p-x3 .x3-case__line {
  margin: 10px 0 32px;
  font-size: var(--fs-sm);
  line-height: var(--leading-snug);
  color: var(--color-grey-on-black);
}
.p-x3 .x3-case__list {
  margin: auto 0 0;
  padding: 0;
  list-style: none;
}
.p-x3 .x3-case__item {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  transition: border-color 0.3s ease;
}
.p-x3 .x3-case__item:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.1); }
/* the hairlines framing the hovered row light up with it */
.p-x3 .x3-case__item:hover,
.p-x3 .x3-case__item:hover + .x3-case__item { border-top-color: rgba(255, 255, 255, 0.32); }
.p-x3 .x3-case__item:last-child:hover { border-bottom-color: rgba(255, 255, 255, 0.32); }
/* the whole row is the link: name left, arrow right */
.p-x3 .x3-case__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 15px 0;
  color: rgba(255, 255, 255, 0.86);
  transition: color 0.25s ease;
}
.p-x3 .x3-case__link:hover { color: var(--color-white); }
.p-x3 .x3-case__item-name { font-size: var(--fs-sm); }
.p-x3 .x3-case__item-arrow {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--color-grey-300);
  transition: color 0.25s ease, transform 0.25s ease;
}
.p-x3 .x3-case__link:hover .x3-case__item-arrow {
  color: var(--color-blue-200);
  transform: translateX(4px);
}
.p-x3 .x3-case__item-arrow svg { width: 15px; height: 15px; }

/* ---------- why incode: trionn composition (2026-08-04, round 4) ----------
   The trionn.com "Selected work" section, translated (Sofia's reference,
   confirmed after the quadrant round): the section title rides STICKY on
   the left while the four differentiators scroll past as tall media
   panels on the right of a full-height hairline. Each panel unmasks
   upward with the shared curtain as it enters ([data-x3-curtain-each] in
   x3.js) and its aurora scene drifts on a soft parallax (--wpar, set per
   frame by x3.js). Media = the canonical cta-fx aurora carrying an
   abstract white line scene per differentiator (no lettering). */
.p-x3 .x3-why {
  background: var(--color-background);
  color: var(--color-foreground);
}
.p-x3 .x3-why__inner {
  margin-inline: auto;
  width: 100%;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-why__inner { padding-block: var(--space-section); } }
@media (min-width: 1024px) {
  .p-x3 .x3-why__inner {
    padding-inline: 24px;
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.3fr);
    gap: 64px;
    align-items: start;
  }
  /* the rail pins under the fixed header while the feed scrolls by */
  .p-x3 .x3-why__rail { position: sticky; top: 120px; }
  .p-x3 .x3-why__feed {
    border-left: 1px solid var(--color-border-light);
    padding-left: 64px;
  }
}
.p-x3 .x3-why__title {
  margin-top: 16px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 26px;
  line-height: 1.05;
  color: var(--color-black);
}
/* phones: the title holds ONE line (Sofia 2026-08-06) — the desktop's
   hand-broken <br> stands down and a viewport step-down keeps the line
   inside the smallest screens */
@media (max-width: 639px) {
  .p-x3 .x3-why__title {
    white-space: nowrap;
    font-size: clamp(21px, 6.6vw, 26px);
  }
  .p-x3 .x3-why__title br { display: none; }
}
@media (min-width: 640px) { .p-x3 .x3-why__title { font-size: 34px; } }
@media (min-width: 768px) { .p-x3 .x3-why__title { font-size: 44px; } }
@media (min-width: 1280px) { .p-x3 .x3-why__title { font-size: 52px; } }
.p-x3 .x3-why__all {
  display: inline-flex;
  margin-top: 28px;
}
.p-x3 .x3-why__panel { margin-top: 48px; }
.p-x3 .x3-why__panel:first-child { margin-top: 40px; }
@media (min-width: 1024px) {
  .p-x3 .x3-why__panel { margin-top: 88px; }
  .p-x3 .x3-why__panel:first-child { margin-top: 0; }
}
/* the media plate. Product pass 2 (Natalia, 2026-08-05, her Figma
   designs for the gov + UX panels): real product mockups on a flat
   light plate — Scan-your-ID / Take-a-selfie phone screens with the
   product rasters (idcapture-3-card-laura.webp, selfie-3.jpg), an
   analytics dashboard, and the trust-network session cards. Scene svg
   is transparent; --wpar parallax drifts it over the plate. Scene
   animations are scroll-triggered: x3.js adds .will-anim on init
   (JS + motion available) and .is-live when the plate is ~55% in
   view; without both classes every scene renders in its complete
   static state (no-JS / reduced-motion safe). */
.p-x3 .x3-why__media {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: 16px;
  overflow: hidden;
}
.p-x3 .x3-why__media--product {
  background-color: var(--color-grey-100);
}
.p-x3 .x3-why__scene {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform: translateY(var(--wpar, 0px));
}
/* the moving-selfie video (hero-selfie.mp4), circle-cropped over the
   scene svg's phone — geometry mirrors the svg circle (cx 368 cy 312
   r 96 in the 737×460 viewBox), and it rides the same parallax var so
   svg and video drift together. x3.js pauses it under reduced motion. */
/* the why-scene phones use the abstract status top — the product
   screens' baked 09:41/signal/battery stay hidden in THIS scene only
   (the components render them everywhere else) */
.p-x3 .x3-why__scene .bc-status,
.p-x3 .x3-why__scene .s3-status,
.p-x3 .x3-why__scene .s7-status,
.p-x3 .x3-why__scene .s3-silhouette { display: none; }
/* looping success moment over the selfie capture (Natalia 2026-08-07,
   the product Success screen recipe): white takeover of the circle,
   green badge settles in, check draws — then back to the capture */
/* selfie loop, take 2 (Natalia 2026-08-07: the badge-in-the-ring read
   as a donut): the silhouette rides over the moving girl during the
   capture beat, then the WHOLE phone screen swaps to the product
   success state — quick crossfade, green badge settles, check draws,
   back to capture. */
.p-x3 .x3-why__scene-sil {
  position: absolute;
  z-index: 1;
  left: 36.91%;
  top: 40.43%;
  width: 26.05%;
  height: 41.74%;
  pointer-events: none;
  transform: translateY(var(--wpar, 0px));
}
.p-x3 .x3-why__scene-sil svg {
  width: 100%;
  height: 100%;
  display: block;
}
.p-x3 .x3-why__scene-success {
  position: absolute;
  z-index: 1;
  left: 32.56%;
  top: 28.7%;
  width: 34.74%;
  height: 71.3%;
  background: var(--color-white);
  transform: translateY(var(--wpar, 0px));
  opacity: 0;
}
.p-x3 .is-live .x3-why__scene-success {
  animation: wspUxSuccess 4.2s linear infinite;
}
.p-x3 .x3-why__scene-success svg {
  width: 100%;
  height: 100%;
  display: block;
}
.p-x3 .x3-why__scene-success .wsp-uxs-disc { fill: var(--color-green-500); }
.p-x3 .x3-why__scene-success .wsp-uxs-badge {
  transform-box: fill-box;
  transform-origin: center;
}
.p-x3 .is-live .x3-why__scene-success .wsp-uxs-badge {
  animation: wspUxBadge 4.2s linear infinite;
}
.p-x3 .x3-why__scene-success .wsp-uxs-word { fill: var(--color-grey-600); }
/* same success logic as the gov phone (CO step-4): the word rides the
   0.4s screen crossfade, badge pops 0→106→100 on incode-settle after a
   beat, and the check DRAWS via the stroked twin — the filled check
   stays hidden, exactly like s7-check / s7-check-draw. */
.p-x3 .x3-why__scene-success .wsp-uxs-checkfill { fill: var(--color-white); opacity: 0; }
.p-x3 .x3-why__scene-success .wsp-uxs-checkdraw {
  fill: none;
  stroke: var(--color-white);
  stroke-width: 2.83;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
}
.p-x3 .is-live .x3-why__scene-success .wsp-uxs-checkdraw {
  animation: wspUxCheckDraw 4.2s linear infinite;
}
.p-x3 .x3-why__scene-videowrap {
  position: absolute;
  left: 36.91%;
  top: 40.43%;
  width: 26.05%;
  height: 41.74%;
  border-radius: 50%;
  overflow: hidden;
  transform: translateY(var(--wpar, 0px));
}
/* zoomed so the face fills the silhouette opening (Natalia 2026-08-07) */
.p-x3 .x3-why__scene-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* nudged down so her face sits inside the silhouette (Natalia
     2026-08-10) */
  transform: translateY(3%) scale(1.35);
  transform-origin: 50% 42%;
}
/* ----- scene vocabulary: white product-UI cards ----- */
.p-x3 .x3-why__scene text { font-family: var(--font-sans); }
/* no background shadows (Natalia 2026-08-06) — cards sit flat on the
   plate; the white-on-grey contrast + hairline carry the separation.
   .wsp-float / .wsp-float-lg stay in the markup as grouping hooks. */
.p-x3 .x3-why__scene .wsp-float,
.p-x3 .x3-why__scene .wsp-float-lg {
  filter: none;
}
.p-x3 .x3-why__scene .wsp-card {
  fill: var(--color-white);
  stroke: color-mix(in srgb, var(--color-grey-200) 45%, transparent);
}
.p-x3 .x3-why__scene .wsp-hairline {
  fill: none;
  stroke: color-mix(in srgb, var(--color-grey-200) 45%, transparent);
}
.p-x3 .x3-why__scene .wsp-skel { fill: var(--color-grey-100); }
.p-x3 .x3-why__scene .wsp-skel-strong { fill: var(--color-grey-200); }
.p-x3 .x3-why__scene .wsp-avatar { fill: var(--color-grey-100); }
/* ----- phone chrome ----- */
.p-x3 .x3-why__scene .wsp-ptitle {
  font-size: 17.5px;
  font-weight: 700;
  fill: var(--color-grey-600);
  text-anchor: middle;
}
.p-x3 .x3-why__scene .wsp-psub {
  font-size: 11.5px;
  font-weight: 400;
  fill: var(--color-grey-400);
  text-anchor: middle;
}
.p-x3 .x3-why__scene .wsp-lock { fill: var(--color-grey-600); }
.p-x3 .x3-why__scene .wsp-lock-arc {
  fill: none;
  stroke: var(--color-grey-600);
  stroke-width: 1.6;
}
.p-x3 .x3-why__scene .wsp-plock {
  font-size: 11px;
  font-weight: 500;
  fill: var(--color-grey-600);
}
.p-x3 .x3-why__scene .wsp-cta { fill: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-ctatxt {
  font-size: 13px;
  font-weight: 500;
  fill: var(--color-white);
}
.p-x3 .x3-why__scene .wsp-tc { text-anchor: middle; }
/* ----- dashboard type ----- */
.p-x3 .x3-why__scene .wsp-label {
  font-size: 12px;
  font-weight: 500;
  fill: var(--color-grey-500);
}
.p-x3 .x3-why__scene .wsp-sub {
  font-size: 10.5px;
  font-weight: 400;
  fill: var(--color-grey-400);
}
.p-x3 .x3-why__scene .wsp-num {
  font-size: 34px;
  font-weight: 600;
  letter-spacing: var(--track-tighter);
  fill: var(--color-grey-600);
}
.p-x3 .x3-why__scene .wsp-num--xl { font-size: 52px; }
.p-x3 .x3-why__scene .wsp-num--lg { font-size: 30px; }
.p-x3 .x3-why__scene .wsp-num--sm { font-size: 17px; }
/* the selfie panel's proof numbers keep the stat gradient (Natalia
   2026-08-06 — analytics numbers stay plain ink) */
.p-x3 .x3-why__scene .wsp-numstop-blue { stop-color: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-numstop-ink { stop-color: var(--color-black); }
.p-x3 .x3-why__scene .wsp-num--grad2 { fill: url(#wspNum2); }
.p-x3 .x3-why__scene .wsp-num--md { font-size: 22px; }
/* ----- chips ----- */
.p-x3 .x3-why__scene .wsp-chiptxt {
  font-size: 10px;
  font-weight: 500;
  text-anchor: middle;
}
.p-x3 .x3-why__scene .wsp-chip--blue { fill: var(--color-blue-100); }
.p-x3 .x3-why__scene .wsp-chip--green { fill: var(--color-green-100); }
.p-x3 .x3-why__scene .wsp-chip--red { fill: var(--color-red-100); }
.p-x3 .x3-why__scene .wsp-chiptxt--blue { fill: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-chiptxt--green { fill: var(--color-green-600); }
.p-x3 .x3-why__scene .wsp-chiptxt--red { fill: var(--color-red-600); }
/* ----- charts / marks ----- */
.p-x3 .x3-why__scene .wsp-trend {
  fill: none;
  stroke: var(--color-blue-500);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.p-x3 .x3-why__scene .wsp-area {
  fill: color-mix(in srgb, var(--color-blue-100) 55%, transparent);
}
.p-x3 .x3-why__scene .wsp-bar { fill: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-bar--dim { fill: var(--color-blue-200); }
.p-x3 .x3-why__scene .wsp-ringdot {
  fill: none;
  stroke: var(--color-blue-200);
  stroke-width: 2.5;
}
/* the product scan ring (Selfie Animated asset recipe, per the
   wfh-fauth port): blue→white gradient comet tail, ambient rotation.
   Runs whenever motion is allowed — the reduced-motion block below
   freezes it. */
.p-x3 .x3-why__scene .wsp-stop--blue { stop-color: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-stop--white { stop-color: var(--color-white); }
.p-x3 .x3-why__scene .wsp-fauth-ring {
  fill: none;
  stroke-width: 6;
  transform-box: fill-box;
  transform-origin: center;
  /* 3.6s = exactly two turns per 7.2s loop, so the ring sits at the
     same phase every cycle and the whole scene restarts identically
     (Natalia 2026-08-10) */
  animation: wspOrbit 3.6s linear infinite;
}
/* capture frame around the license: the SAME comet recipe as the
   selfie ring, wrapped around the rounded rect — an HTML overlay
   whose rotating conic gradient (blue head → light tail) is masked
   to the border band. Geometry mirrors the svg license rect
   (96,198,246,164 in the 737×460 viewBox) and it rides --wpar so it
   drifts with the scene. */
.p-x3 .x3-why__scene-idring {
  position: absolute;
  /* follows the phone, centered while the gov side is parked
     (13.03% + 149.5/737) */
  left: 33.31%;
  top: 43.04%;
  width: 33.38%;
  height: 35.65%;
  border-radius: 16px;
  padding: 3.5px;
  /* the face-capture ring recipe verbatim: a LINEAR blue→light
     gradient whose angle rotates (the conic comet read as a broken
     segment on the rect's corners — Natalia 2026-08-06) */
  background: linear-gradient(
    var(--wsp-a, 0deg),
    var(--color-blue-500) 0%,
    var(--color-blue-200) 45%,
    transparent 78%
  );
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  transform: translateY(var(--wpar, 0px));
  animation: wspRingSpin 3.2s linear infinite;
}
.p-x3 .will-anim .x3-why__scene-hubring { opacity: 0; }
.p-x3 .is-live .x3-why__scene-hubring {
  animation:
    wspFade 0.4s ease-out 0.15s forwards,
    wspRingSpin 3.2s linear infinite;
}
@property --wsp-a {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
/* white glint sweeping across the gov icon (clipped to its shapes) */
.p-x3 .x3-why__scene .wsp-shstop--edge { stop-color: var(--color-white); stop-opacity: 0; }
.p-x3 .x3-why__scene .wsp-shstop--core { stop-color: var(--color-white); stop-opacity: 0.75; }
.p-x3 .x3-why__scene .wsp-gov-shine {
  animation: wspShineSweep 3.4s ease-in-out 2.7s infinite;
}
/* gov icon gradient breathe: the two gradients shift phase against
   each other so the fill reads as flowing, never a flat pulse */
.p-x3 .x3-why__scene .wsp-gstop-a1 {
  stop-color: var(--color-blue-200);
  animation: wspGradLight 3.4s ease-in-out infinite;
}
.p-x3 .x3-why__scene .wsp-gstop-a2 {
  stop-color: var(--color-blue-500);
  animation: wspGradDeep 3.4s ease-in-out infinite;
}
.p-x3 .x3-why__scene .wsp-gstop-b1 {
  stop-color: var(--color-blue-500);
  animation: wspGradDeep 3.4s ease-in-out -1.7s infinite;
}
.p-x3 .x3-why__scene .wsp-gstop-b2 {
  stop-color: var(--color-blue-200);
  animation: wspGradLight 3.4s ease-in-out -1.7s infinite;
}
.p-x3 .x3-why__scene .wsp-gdash { fill: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-conn {
  stroke: var(--color-grey-300);
  stroke-width: 1.5;
}
/* fraud-ring connector language: solid tinted lines, faint mesh
   between satellites, small node dots at the card junctions */
/* spokes: confident, anchored card-corner → hub-edge (Sofia
   2026-08-06 — the faint mesh + washed tints read "ai gen") */
.p-x3 .x3-why__scene .wsp-line--red {
  stroke: color-mix(in srgb, var(--color-red-brand) 55%, transparent);
  stroke-width: 2;
  stroke-linecap: round;
}
.p-x3 .x3-why__scene .wsp-line--green {
  stroke: color-mix(in srgb, var(--color-green-500) 50%, transparent);
  stroke-width: 2;
  stroke-linecap: round;
}
.p-x3 .x3-why__scene .wsp-dot--redfill { fill: var(--color-red-brand); }
.p-x3 .x3-why__scene .wsp-dot--flow { fill: var(--color-green-500); }
.p-x3 .x3-why__scene .wsp-avring--red {
  fill: none;
  stroke: var(--color-red-brand);
  stroke-width: 2;
}
.p-x3 .x3-why__scene .wsp-avring--green {
  fill: none;
  stroke: var(--color-green-500);
  stroke-width: 2;
}
.p-x3 .x3-why__scene .wsp-rowtxt {
  font-size: 10.5px;
  font-weight: 500;
  fill: var(--color-grey-500);
}
.p-x3 .x3-why__scene .wsp-checkw-sm {
  fill: none;
  stroke: var(--color-white);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.p-x3 .x3-why__scene .wsp-track { fill: var(--color-grey-100); }
.p-x3 .x3-why__scene .wsp-te { text-anchor: end; }
.p-x3 .x3-why__scene .wsp-grid {
  stroke: var(--color-grey-100);
  stroke-width: 1;
}
/* card titles ride the display face for hierarchy (Natalia 2026-08-06) */
.p-x3 .x3-why__scene .wsp-cardhead {
  font-family: var(--font-display);
  font-size: 13.5px;
  font-weight: 500;
  fill: var(--color-grey-600);
}
.p-x3 .x3-why__scene .wsp-cardtitle {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 500;
  fill: var(--color-grey-600);
}
.p-x3 .x3-why__scene .wsp-score--red {
  font-size: 15px;
  font-weight: 600;
  fill: var(--color-red-600);
}
.p-x3 .x3-why__scene .wsp-score--green {
  font-size: 15px;
  font-weight: 600;
  fill: var(--color-green-600);
}
/* hub: the face-capture ring at hub scale — an HTML overlay with the
   rotating linear gradient masked to the ring band (the same proven
   mechanism as the ID ring; Safari drops CSS transforms on svg
   circles, which froze the previous svg version). Geometry mirrors
   the hub disc (368,232 r 26.5 in the 737×460 viewBox). */
.p-x3 .x3-why__scene-hubring {
  position: absolute;
  left: 46.34%;
  top: 44.67%;
  width: 7.19%;
  height: 11.52%;
  border-radius: 50%;
  /* no masks (they failed to paint in Safari): the ring is a gradient
     disc with a plain white core painted over the middle */
  background: linear-gradient(
    var(--wsp-a, 0deg),
    var(--color-blue-500) 0%,
    var(--color-blue-200) 62%,
    var(--color-white) 96%
  );
  transform: translateY(var(--wpar, 0px));
  animation: wspRingSpin 3.2s linear infinite;
}
.p-x3 .x3-why__scene-hubring::after {
  content: "";
  position: absolute;
  inset: 4.75px;
  border-radius: 50%;
  background: var(--color-white);
}
.p-x3 .x3-why__scene .wsp-ripple {
  fill: none;
  stroke: var(--color-blue-200);
  stroke-width: 1.5;
  opacity: 0;
}
.p-x3 .x3-why__scene .wsp-dot--blue { fill: var(--color-blue-500); }
.p-x3 .x3-why__scene .wsp-dot--green { fill: var(--color-green-600); }
.p-x3 .x3-why__scene .wsp-disc--green { fill: var(--color-green-500); }
.p-x3 .x3-why__scene .wsp-disc--white { fill: var(--color-white); }
.p-x3 .x3-why__scene .wsp-checkw {
  fill: none;
  stroke: var(--color-white);
  stroke-width: 5.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* ----- scene animations (scroll-triggered) -----
   .will-anim arms the hidden initial states (added by x3.js only when
   JS + motion are available); .is-live fires the one-shot timeline.
   Every element ends exactly on its static composition. Delays ride
   per-element --d custom props set inline in the markup. */
/* gov scene · the Delaware ID back rides up into the capture frame —
   the customer-onboarding step-2 recipe verbatim: 1.5s incode-flow, the
   frame as a LIGHT MASK (.bc-card stays dimmed like the camera view,
   .bc-card-lit is clipped to the frame slot and reveals whatever portion
   has entered it). One-shot on .is-live; static complete state without
   JS / reduced motion. */
/* no filter hack: .bc-card is painted BETWEEN the camera view and the 80%
   black overlay in the SVG itself (Barcode4Screen), so the real overlay dims
   it — the ID sits under the frame, only the frame-slot copy (.bc-card-lit)
   stays lit above the overlay. */
.p-x3 .will-anim .bc-card,
.p-x3 .will-anim .bc-card-lit {
  transform: translateY(228px);
}
.p-x3 .is-live .bc-card,
.p-x3 .is-live .bc-card-lit {
  animation: wsp-a-idback 1.5s cubic-bezier(0.85, 0, 0.25, 1) 0.25s both;
}
@keyframes wsp-a-idback {
  from { transform: translateY(228px); }
  to { transform: translateY(0); }
}
/* gov scene · act 2 (Mauricio 2026-08-06). Timeline from .is-live:
     0.25s–1.75s  ID back rides up (wsp-a-idback above)
     1.75s–2.25s  capture frame confirms blue → green (CO recipe)
     2.50s–2.95s  quick dip to white; the screens swap under the peak
     T = 2.7s     capture screen: ring rotating constantly (2.4s/turn),
                  "Align your face…" holds to T+1.6, crossfades to
                  "Get ready…" (in 0.5 · hold 1.5 · out 0.5), ring
                  gradient lands on success green at T+3.9 — the CO
                  step-1 values verbatim, offset by the swap time. */
.p-x3 .is-live .bc-frame path {
  animation: wsp-a-framegreen 0.5s ease 1.75s both;
}
@keyframes wsp-a-framegreen {
  to { stroke: var(--color-green-500); }
}
.p-x3 .x3-why__scene .wsp-dip {
  fill: var(--color-white);
  opacity: 0;
}
.p-x3 .x3-why__scene .wsp-loopdip {
  fill: var(--color-white);
  opacity: 0;
}
.p-x3 .is-live .wsp-loopdip {
  animation:
    wsp-a-loopout 0.5s ease both,
    wsp-a-loopin 0.5s ease 11.7s forwards;
}
@keyframes wsp-a-loopout {
  from { opacity: 1; }
  to { opacity: 0; }
}
@keyframes wsp-a-loopin {
  to { opacity: 1; }
}
.p-x3 .is-live .wsp-dip {
  /* soft dip-to-white riding over the screen crossfade — eased both
     ways so it swells and recedes instead of flashing */
  animation: wsp-a-dip 1.4s ease-in-out 2.3s both;
}
@keyframes wsp-a-dip {
  0% { opacity: 0; }
  35%, 55% { opacity: 1; }
  100% { opacity: 0; }
}
.p-x3 .is-live .wsp-scr-barcode {
  animation: wsp-a-hide 0.9s ease 2.5s both;
}
@keyframes wsp-a-hide {
  to { opacity: 0; }
}
.p-x3 .will-anim .wsp-scr-selfie { opacity: 0; }
.p-x3 .will-anim .wsp-scr-success { opacity: 0; }
.p-x3 .is-live .wsp-scr-success {
  animation: wsp-a-show 0.4s ease 7.5s both;
}
/* CO step-4 recipe: 0.6s beat after the reveal, badge pops 0→106%→100%
   on incode-settle; the check draws itself over the back half */
.p-x3 .x3-why__scene .s7-check-draw { display: none; }
.p-x3 .is-live .s7-badge {
  transform-box: fill-box;
  transform-origin: center;
  animation: wsp-a-badge 0.6s cubic-bezier(0, 0.75, 0.25, 1) 8.1s both;
}
.p-x3 .is-live .wsp-scr-success .s7-check { opacity: 0; }
.p-x3 .is-live .wsp-scr-success .s7-check-draw {
  display: inline;
  stroke-dasharray: 1;
  animation: wsp-a-checkdraw 0.3s ease-out 8.4s both;
}
@keyframes wsp-a-badge {
  0% { transform: scale(0); }
  80% { transform: scale(1.06); }
  100% { transform: scale(1); }
}
@keyframes wsp-a-checkdraw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}
.p-x3 .is-live .wsp-scr-selfie {
  /* subtle crossfade with the barcode screen fading out underneath */
  animation: wsp-a-show 0.9s ease 2.5s both;
}
@keyframes wsp-a-show {
  to { opacity: 1; }
}
.p-x3 .x3-why__scene .s3-ring-scan {
  transform-box: fill-box;
  transform-origin: center;
  animation: wsp-a-ringspin 2.4s linear infinite;
}
@keyframes wsp-a-ringspin {
  to { transform: rotate(1turn); }
}
.p-x3 .x3-why__scene .s3-caption-ready { display: none; }
.p-x3 .is-live .s3-caption {
  animation: wsp-a-capout 0.4s ease 4s both;
}
.p-x3 .is-live .s3-caption-ready {
  display: inline;
  animation: wsp-a-capready 1.7s ease 4.3s both;
}
@keyframes wsp-a-capout {
  from { opacity: 1; }
  to { opacity: 0; }
}
@keyframes wsp-a-capready {
  0% { opacity: 0; }
  20% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; }
}
/* the gov icon's "loading" cue: the gradient breathe, faster and with a
   wider ramp (blue-100 ↔ blue-500) than the ambient 3.4s original */
.p-x3 .x3-why__scene .wsp-govicon .wsp-gstop-a1 { animation: wspGradLight2 2.2s ease-in-out infinite; }
.p-x3 .x3-why__scene .wsp-govicon .wsp-gstop-a2 { animation: wspGradDeep2 2.2s ease-in-out infinite; }
.p-x3 .x3-why__scene .wsp-govicon .wsp-gstop-b1 { animation: wspGradDeep2 2.2s ease-in-out -1.1s infinite; }
.p-x3 .x3-why__scene .wsp-govicon .wsp-gstop-b2 { animation: wspGradLight2 2.2s ease-in-out -1.1s infinite; }
@keyframes wspGradLight2 {
  0%, 100% { stop-color: var(--color-blue-100); }
  50% { stop-color: var(--color-blue-500); }
}
@keyframes wspGradDeep2 {
  0%, 100% { stop-color: var(--color-blue-500); }
  50% { stop-color: var(--color-blue-100); }
}
/* act 3 dressing: white disc + pulsing halo behind the gov icon; the
   scan ring rides ABOVE the veil via a synchronized twin (.wsp-ring-top,
   same gradient recipe + spin — the component's inner ring hands off to
   it as the veil lands, both spins restarted together on .is-live so
   their phases match); the phone gets the age-assurance glow rhythm. */
.p-x3 .x3-why__scene .wsp-gov-disc {
  fill: var(--color-white);
}
.p-x3 .x3-why__scene .wsp-gov-halo {
  fill: var(--color-blue-500);
  filter: blur(14px);
  opacity: 0;
}
.p-x3 .is-live .wsp-gov-halo {
  /* matches the phone glow exactly — same curve, same clock; both fade
     out as the chip exits */
  animation:
    wsp-a-breathe 2.8s ease-in-out 4.6s infinite,
    wsp-a-hide 0.5s ease 7.1s forwards;
}
.p-x3 .x3-why__scene .wsp-phone-glow {
  fill: var(--color-blue-500);
  filter: blur(16px);
  opacity: 0;
}
.p-x3 .is-live .wsp-phone-glow {
  /* a light slowly dimming and relighting — continuous, subtle */
  animation:
    wsp-a-breathe 2.8s ease-in-out 4.6s infinite,
    wsp-a-hide 0.5s ease 7.1s forwards;
}
@keyframes wsp-a-breathe {
  0%, 100% { opacity: 0; }
  50% { opacity: 0.5; }
}
@keyframes wsp-a-halopulse {
  0% { opacity: 0; }
  6% { opacity: 0.55; }
  60% { opacity: 0; }
  100% { opacity: 0; }
}
/* act 3: once "Get ready…" exits (6s), a white veil covers the
   phone and the government icon pops on top (--d 4.6s via wsp-a-pop).
   Static/no-JS default = the veiled end state, consistent with the
   scene system. */
.p-x3 .x3-why__scene .wsp-govveil {
  fill: var(--color-white);
  opacity: 0;
}
.p-x3 .is-live .wsp-govveil {
  animation: wsp-a-veil 3.6s linear 4.3s both;
}
@keyframes wsp-a-veil {
  0% { opacity: 0; }
  8.7%, 91.3% { opacity: 0.7; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .p-x3 .x3-why__scene .s3-ring-scan { animation: none; }
}
.p-x3 .will-anim .wsp-a-pop { opacity: 0; }
.p-x3 .will-anim .wsp-a-fade { opacity: 0; }
.p-x3 .will-anim .wsp-a-rise { opacity: 0; }
.p-x3 .will-anim .wsp-a-bar {
  transform: scaleY(0);
  transform-box: fill-box;
  transform-origin: bottom;
}
.p-x3 .will-anim .wsp-a-barx {
  transform: scaleX(0);
  transform-box: fill-box;
  transform-origin: left;
}
.p-x3 .will-anim .wsp-a-draw {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}
.p-x3 .will-anim .wsp-a-travel-gov,
.p-x3 .will-anim .wsp-a-travel-in,
.p-x3 .will-anim .wsp-a-travel-b,
.p-x3 .will-anim .wsp-a-travel-c,
.p-x3 .will-anim .wsp-a-travel-d { opacity: 0; }
.p-x3 .is-live .wsp-a-pop {
  transform-box: fill-box;
  transform-origin: center;
  animation: wspPop 0.5s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0s) forwards;
}
/* the gov chip: enters on incode-settle at 4.6s, holds while the icon's
   loading dim runs (from 5.1s), then exits at 6.9s — a 110%
   anticipation swell, then an incode-impact collapse to zero. Static
   default is hidden: the scene's end state is the success screen. */
.p-x3 .x3-why__scene .wsp-a-pop--settle { opacity: 0; }
.p-x3 .is-live .wsp-a-pop--settle {
  animation:
    wspPop 0.5s cubic-bezier(0, 0.75, 0.25, 1) var(--d, 0s) forwards,
    wsp-a-govexit 0.65s linear 6.9s forwards;
}
@keyframes wsp-a-govexit {
  0% {
    transform: scale(1);
    animation-timing-function: cubic-bezier(0.33, 0, 0.67, 1); /* anticipation swell */
  }
  40% {
    transform: scale(1.1);
    animation-timing-function: cubic-bezier(0.8, 0, 1, 0.3); /* incode-impact */
  }
  100% { transform: scale(0); }
}
/* the icon's loading dim: 100% → 50% → 100%, looping */
.p-x3 .is-live .wsp-govicon {
  animation: wsp-a-dimload 1.4s ease-in-out 5.1s infinite;
}
@keyframes wsp-a-dimload {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}
.p-x3 .is-live .wsp-a-fade {
  animation: wspFade 0.6s ease-out var(--d, 0s) forwards;
}
.p-x3 .is-live .wsp-a-rise {
  transform-box: fill-box;
  animation: wspRise 0.55s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0s) forwards;
}
.p-x3 .is-live .wsp-a-bar {
  animation: wspBar 0.7s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0s) forwards;
}
.p-x3 .is-live .wsp-a-barx {
  animation: wspBarX 0.7s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0s) forwards;
}
.p-x3 .is-live .wsp-a-draw {
  animation: wspDraw 1.1s var(--ease-out-expo) var(--d, 0s) forwards;
}
.p-x3 .is-live .wsp-a-draw--fast { animation-duration: 0.45s; }
.p-x3 .will-anim .wsp-a-cardin { opacity: 0; }
.p-x3 .is-live .wsp-a-cardin {
  transform-box: fill-box;
  transform-origin: center;
  animation: wspCardIn 0.5s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0s) forwards;
}
.p-x3 .is-live .wsp-a-pulse {
  animation: wspPulse 2.2s ease-in-out 1.4s infinite;
}
.p-x3 .is-live .wsp-a-ripple {
  transform-box: fill-box;
  transform-origin: center;
  animation: wspRipple 3.2s ease-out 2.2s infinite;
}
.p-x3 .is-live .wsp-a-travel-gov { animation: wspTravelGov 0.7s ease-in-out 1.5s forwards; }
/* staged gov entrance: the capture ring leads the sequence */
.p-x3 .will-anim .x3-why__scene-idring { opacity: 0; }
.p-x3 .is-live .x3-why__scene-idring {
  animation:
    wspFade 0.5s ease-out forwards,
    wspRingSpin 3.2s linear infinite;
}
.p-x3 .is-live .wsp-a-travel-in { animation: wspTravelIn 0.55s ease-in-out 1.8s forwards; }
.p-x3 .is-live .wsp-a-travel-b { animation: wspTravelB 0.55s ease-in-out 2.3s forwards; }
.p-x3 .is-live .wsp-a-travel-c { animation: wspTravelC 0.55s ease-in-out 2.4s forwards; }
.p-x3 .is-live .wsp-a-travel-d { animation: wspTravelD 0.55s ease-in-out 2.5s forwards; }
@keyframes wspCardIn {
  from { opacity: 0; transform: scale(0.92); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes wspPop {
  from { opacity: 0; transform: scale(0.5); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes wspFade { to { opacity: 1; } }
@keyframes wspRise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes wspBar { to { transform: scaleY(1); } }
@keyframes wspBarX { to { transform: scaleX(1); } }
@keyframes wspDraw { to { stroke-dashoffset: 0; } }
/* the proof boxes ride the selfie loop (Natalia 2026-08-10): they
   rise while the capture experience runs, hold through the success
   screen, and leave when it ends — back again with the next capture */
.p-x3 .x3-why__scene .wsp-a-boxa,
.p-x3 .x3-why__scene .wsp-a-boxb {
  transform-box: fill-box;
}
.p-x3 .is-live .wsp-a-boxa { animation: wspUxBoxA 7.2s linear infinite; }
.p-x3 .is-live .wsp-a-boxb { animation: wspUxBoxB 7.2s linear infinite; }
@keyframes wspUxBoxA {
  0%, 5% { opacity: 0; transform: translateY(10px); }
  9% { opacity: 1; transform: translateY(0); }
  65.6% { opacity: 1; transform: translateY(0); }
  69.6%, 100% { opacity: 0; transform: translateY(0); }
}
@keyframes wspUxBoxB {
  0%, 10% { opacity: 0; transform: translateY(10px); }
  14% { opacity: 1; transform: translateY(0); }
  66.1% { opacity: 1; transform: translateY(0); }
  70.1%, 100% { opacity: 0; transform: translateY(0); }
}
@keyframes wspOrbit { to { transform: rotate(360deg); } }
@keyframes wspUxSuccess {
  /* 4.2s loop: face shows ~1.5s (6%→41.7%), then the success screen covers
     it for the rest — verification-speed is the point, so the face beat is
     kept short (Nacim 2026-08-18). */
  0% { opacity: 1; }
  6%, 41.7% { opacity: 0; }
  47.6%, 100% { opacity: 1; }
}
/* the pop + draw match the Government-verification phone (wsp-a-badge /
   wsp-a-checkdraw): per-keyframe easing gives the pop the incode-settle snap
   and the check an ease-out draw, even though the scene runs on one linear
   7.2s loop — without this the pop/draw interpolate linearly (mechanical). */
@keyframes wspUxBadge {
  0% { transform: scale(0); }
  61.9% { transform: scale(0); animation-timing-function: cubic-bezier(0, 0.75, 0.25, 1); }
  76.2% { transform: scale(1.06); animation-timing-function: cubic-bezier(0, 0.75, 0.25, 1); }
  79.8%, 100% { transform: scale(1); }
}
@keyframes wspUxCheckDraw {
  0% { stroke-dashoffset: 1; }
  69% { stroke-dashoffset: 1; animation-timing-function: ease-out; }
  76.2%, 100% { stroke-dashoffset: 0; }
}
@keyframes wspRingSpin {
  to { --wsp-a: 360deg; }
}
@keyframes wspShineSweep {
  0% { transform: translateX(30px); }
  55% { transform: translateX(290px); }
  100% { transform: translateX(290px); }
}
@keyframes wspGradLight {
  0%, 100% { stop-color: var(--color-blue-200); }
  50% { stop-color: var(--color-blue-500); }
}
@keyframes wspGradDeep {
  0%, 100% { stop-color: var(--color-blue-500); }
  50% { stop-color: var(--color-blue-200); }
}
@keyframes wspPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@keyframes wspRipple {
  0% { opacity: 0.9; transform: scale(0.55); }
  100% { opacity: 0; transform: scale(1.25); }
}
@keyframes wspTravelGov {
  0% { opacity: 0; transform: translate(0, 0); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate(72px, 0); }
}
@keyframes wspTravelIn {
  0% { opacity: 0; transform: translate(0, 0); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate(62px, 48px); }
}
@keyframes wspTravelB {
  0% { opacity: 0; transform: translate(0, 0); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate(66px, -37px); }
}
@keyframes wspTravelC {
  0% { opacity: 0; transform: translate(0, 0); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate(62px, 29px); }
}
@keyframes wspTravelD {
  0% { opacity: 0; transform: translate(0, 0); }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate(-58px, 37px); }
}
@media (prefers-reduced-motion: reduce) {
  .p-x3 .x3-why__scene *,
  .p-x3 .x3-why__scene-idring,
  .p-x3 .x3-why__scene-hubring,
  .p-x3 .x3-why__scene-success,
  .p-x3 .x3-why__scene-success *,
  .p-x3 .x3-why__scene-sil { animation: none !important; }
}
.p-x3 .x3-why__body { margin-top: 24px; }
.p-x3 .x3-why__name {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: var(--fs-2xl);
  line-height: 1.08;
  color: var(--color-black);
}
@media (min-width: 900px) { .p-x3 .x3-why__name { font-size: 28px; } }
.p-x3 .x3-why__sub {
  margin-top: 8px;
  font-size: var(--fs-body);
  line-height: var(--leading-snug);
  color: var(--color-black); /* black, not blue (Sofia, 2026-08-04) */
}
.p-x3 .x3-why__proofs {
  margin: 18px 0 0;
  padding: 0;
  list-style: none;
  max-width: 56ch;
}
.p-x3 .x3-why__proof {
  border-top: 1px solid var(--color-border-light);
  padding: 10px 0;
  font-size: var(--fs-sm);
  line-height: var(--leading-snug);
  color: var(--color-grey-on-white);
}
.p-x3 .x3-why__proof:last-child { padding-bottom: 0; }

/* ---------- certifications (bright marquee band — pure white ground,
   Sofia 2026-08-05; the quotes chapter after it stays on the off-white
   --color-background) ---------- */
.p-x3 .x3-certs {
  border-top: 1px solid var(--color-border-light);
  background: var(--color-white);
  color: var(--color-foreground);
}
.p-x3 .x3-certs__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-certs__inner { padding-block: var(--space-section-md); } }
/* 32px matches the expertise inner, so the Gartner plate's margins line
   up with the platform card row above (Sofia, 2026-08-05) */
@media (min-width: 1024px) { .p-x3 .x3-certs__inner { padding-inline: 32px; } }
.p-x3 .x3-certs__label {
  text-align: center;
  color: var(--color-kicker-on-white);
}
.p-x3 .x3-certs__marquee {
  position: relative;
  margin-top: 32px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}
@media (min-width: 640px) { .p-x3 .x3-certs__marquee { margin-top: 40px; } }
.p-x3 .x3-certs__track {
  display: flex;
  align-items: center;
  /* NO track gap: the strip asset bakes half-gap margins on its edges,
     so the loop seam spaces exactly like the badges inside the strip at
     every size (Sofia, 2026-08-10: "even spacings without big gaps") */
  gap: 0;
  will-change: transform;
}
/* the strips ride inside <picture> now (mobile tight variant) — the
   picture is the flex item, keep it rigid like the img was */
.p-x3 .x3-certs__track picture {
  display: flex;
  flex-shrink: 0;
}
.p-x3 .x3-certs__track img {
  /* 72 on phones — 40 read tiny, 56 still short (Nacim, 2026-08-10 ×2);
     stepped 72→84 with the trust-band twin (Sofia 2026-08-18: "a bit larger") */
  height: 84px;
  width: auto;
  max-width: none;
  flex-shrink: 0;
  /* ink line-art on the white ground (was white-on-black) */
  opacity: 0.55;
  filter: brightness(0);
}
@media (min-width: 768px) { .p-x3 .x3-certs__track img { height: 96px; } }

/* summarized analyst recognitions (Gartner · Liminal · G2) — logo + one line
   + link, no quadrant/grid cards */
.p-x3 .x3-certs__awards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  margin-top: 48px;
  padding-top: 48px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
@media (min-width: 768px) {
  .p-x3 .x3-certs__awards {
    grid-template-columns: repeat(3, 1fr);
    gap: 48px;
    margin-top: 64px;
    padding-top: 56px;
  }
}
.p-x3 .x3-certs__award {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-decoration: none;
  color: inherit;
  text-align: center;
}
/* fixed-height slot, bottom-aligned — logos of different optical heights
   share a baseline so the claims below start on the same line */
.p-x3 .x3-certs__award-logobox {
  position: relative;
  display: flex;
  align-items: flex-end;
  height: 28px;
}
/* hover figure (Gartner Magic Quadrant): a white card rises above the
   logo while the pointer is anywhere on the award (whole-card trigger,
   Sofia 2026-08-04 — the logo-only hit box read as broken) */
.p-x3 .x3-certs__award-pop {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 18px);
  width: 320px;
  padding: 10px;
  border-radius: 14px;
  background: var(--color-white);
  box-shadow: none;
  opacity: 0;
  transform: translateX(-50%) translateY(16px) scale(0.94);
  transform-origin: 50% 100%;
  pointer-events: none;
  z-index: 5;
  will-change: transform, opacity;
  transition: opacity 0.35s ease, transform 0.6s var(--ease-out-expo);
}
.p-x3 .x3-certs__award-pop img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
}
.p-x3 .x3-certs__award:hover .x3-certs__award-pop,
.p-x3 .x3-certs__award:focus-visible .x3-certs__award-pop {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
}
.p-x3 .x3-certs__award-logo {
  height: var(--logo-h, 24px);
  width: auto;
  opacity: 0.85;
  filter: brightness(0) invert(1);
  transition: opacity 0.25s ease;
}
.p-x3 .x3-certs__award:hover .x3-certs__award-logo { opacity: 1; }
.p-x3 .x3-certs__award-claim {
  max-width: 38ch;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.72);
}
/* Gartner-only recognition (Sofia, 2026-08-05 ×2): one BRIGHT plate in
   the dark band — the white quadrant figure sits on white, no rough
   contrast edge. Figure left, copy right; the whole plate links to the
   report. Replaces the 3-award row on the home (Liminal + G2 retired);
   the award-* rules below stay: /agentic-fraud/ still renders that row. */
.p-x3 .x3-certs__gartner {
  display: grid;
  /* minmax(0,…): the 420px figure must not force the track past the
     plate on mobile */
  grid-template-columns: minmax(0, 1fr);
  gap: 40px;
  align-items: center;
  margin-top: 48px;
  padding: 32px 24px;
  border-radius: 20px;
  /* the card read is hairline + tint (no shadows canon): the plate went
     invisible when --color-background turned pure white (Sofia,
     2026-08-18) — the off-white tint is now explicit grey-50, and the
     hairline carries the card edge. The figure keeps its full-white
     rounded seat. HOME ONLY for now; the TrustBand twin follows on
     Sofia's approval. */
  border: 1px solid var(--color-border-light);
  background: var(--color-grey-50);
  color: var(--color-foreground);
  text-align: center;
  transition: transform 0.5s var(--ease-out-expo);
}
@media (min-width: 900px) {
  .p-x3 .x3-certs__gartner {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 72px;
    /* wide-and-slim plate (Sofia, 2026-08-05 ×5): full inner width — its
       margins line up with the platform card row; the figure width
       drives the (short) height */
    margin-top: 64px;
    padding: 20px 56px;
    text-align: left;
  }
}
@media (min-width: 900px) {
  /* keep the figure hard against the plate's left; the copy column
     stretches and its flex handles alignment */
  .p-x3 .x3-certs__gartner-fig { justify-self: start; }
}
.p-x3 .x3-certs__gartner:hover {
  transform: translateY(-3px);
  border-color: var(--color-grey-200);
}
.p-x3 .x3-certs__gartner-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}
@media (min-width: 900px) {
  .p-x3 .x3-certs__gartner-copy { align-items: flex-start; }
}
/* solid black on the bright plate (the asset is the mixed navy/white
   dark-ground cut) */
.p-x3 .x3-certs__gartner-logo {
  height: 20px;
  width: auto;
  filter: brightness(0);
}
.p-x3 .x3-certs__gartner-claim {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 22px;
  line-height: 1.25;
  color: var(--color-black);
}
@media (min-width: 768px) { .p-x3 .x3-certs__gartner-claim { font-size: 28px; } }
/* the figure sits flush on the plate: white on white */
.p-x3 .x3-certs__gartner-fig {
  display: block;
  /* definite width: a % here can't resolve inside the auto grid column
     (it collapsed the figure to 0). The near-square figure sets the
     plate's height — kept slim (Sofia, 2026-08-05 ×5). The full-white
     rounded seat frames the chart on the off-white plate. */
  /* a step bigger (Sofia, 2026-08-18: "make the grid a bit bigger") */
  width: 320px;
  max-width: 100%;
  padding: 16px;
  border-radius: 16px;
  background: var(--color-white);
  border: 1px solid var(--color-grey-100);
}
.p-x3 .x3-certs__gartner-fig img {
  display: block;
  width: 100%;
  height: auto;
}
/* phones (Sofia, 2026-08-07): the quadrant chart centers and takes the
   plate's full width instead of sitting as a small left-hung card */
@media (max-width: 899px) {
  .p-x3 .x3-certs__gartner-fig {
    width: 100%;
    justify-self: center;
  }
}
.p-x3 .x3-certs__gartner-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  color: var(--color-grey-on-white);
  transition: color 0.25s ease;
}
.p-x3 .x3-certs__gartner-cta svg { transition: transform 0.25s ease; }
.p-x3 .x3-certs__gartner:hover .x3-certs__gartner-cta { color: var(--color-blue); }
.p-x3 .x3-certs__gartner:hover .x3-certs__gartner-cta svg { transform: translate(2px, -2px); }

.p-x3 .x3-certs__award-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: auto;
  font-size: var(--fs-xs);
  color: rgba(255, 255, 255, 0.55);
  transition: color 0.25s ease;
}
.p-x3 .x3-certs__award-cta svg { transition: transform 0.25s ease; }
.p-x3 .x3-certs__award:hover .x3-certs__award-cta { color: var(--color-white); }
.p-x3 .x3-certs__award:hover .x3-certs__award-cta svg { transform: translate(2px, -2px); }

/* ---------- highlights ticker (slim, expandable — from the original design) ---------- */
@media (prefers-reduced-motion: reduce) {
  .p-x3 .x3-w { color: var(--color-black); transition: none; }
}

/* ---------- featured products (dark portfolio-style cards under #platform) ---------- */
.p-x3 .x3-products {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--color-black);
  color: var(--color-white);
}
.p-x3 .x3-products__inner {
  margin-inline: auto;
  max-width: var(--container-large);
  padding: var(--space-section-sm) var(--space-inline);
}
@media (min-width: 768px) { .p-x3 .x3-products__inner { padding-block: var(--space-section); } }
@media (min-width: 1024px) { .p-x3 .x3-products__inner { padding-inline: 24px; } }
.p-x3 .x3-products__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
}
.p-x3 .x3-products__title {
  margin-top: 24px;
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: 26px;
  line-height: 1.05;
}
@media (min-width: 640px) { .p-x3 .x3-products__title { font-size: 32px; } }
@media (min-width: 768px) { .p-x3 .x3-products__title { font-size: 36px; } }
.p-x3 .x3-products__grid {
  margin-top: 40px;
  display: grid;
  gap: 16px;
}
/* minmax(0, 1fr), not bare 1fr: a bare 1fr track can't shrink below its
   content's min width, and a long no-wrap line inside a card would push
   the whole row past the viewport */
@media (min-width: 768px) { .p-x3 .x3-products__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* one row of three on desktop — fixed-height tiles so every visual matches
   exactly regardless of copy length; descriptions wrap again */
@media (min-width: 1024px) {
  .p-x3 .x3-products__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .p-x3 .x3-prod__visual {
    aspect-ratio: auto;
    height: 300px;
  }
  .p-x3 .x3-prod__line {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
}
.p-x3 .x3-prod {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.03);
  padding: 10px 10px 16px;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.3s ease, transform 0.5s var(--ease-out-expo);
}
.p-x3 .x3-prod:hover {
  border-color: rgba(255, 255, 255, 0.22);
  transform: translateY(-4px);
}
.p-x3 .x3-prod__visual {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  aspect-ratio: 16 / 8.5;
  min-height: 216px;
  border-radius: 14px;
  overflow: hidden;
  padding: 16px;
}
/* narrow columns (phones + the 2-up tablet grid): aspect-ratio +
   min-height TRANSFERS a 406px min-width (216 × 16/8.5), so the visual
   forced its track past the viewport and the card bled off-screen
   (Nacim, 2026-08-10, screenshot). Drop the ratio — min-height alone
   sets the tile height. */
@media (max-width: 1023px) {
  .p-x3 .x3-prod__visual { aspect-ratio: auto; }
}
/* per-product aurora tiles — same token blues as the hero blobs, permuted */
.p-x3 .x3-prod__visual--1 {
  background:
    radial-gradient(120% 95% at 12% 0%, color-mix(in oklab, var(--color-x3-blue-deep) 80%, transparent), transparent 62%),
    radial-gradient(110% 100% at 92% 100%, color-mix(in oklab, var(--color-x3-indigo) 65%, transparent), transparent 65%),
    color-mix(in oklab, var(--color-black) 86%, var(--color-x3-blue-deep));
}
.p-x3 .x3-prod__visual--2 {
  background:
    radial-gradient(120% 95% at 88% 0%, color-mix(in oklab, var(--color-x3-blue-bright) 70%, transparent), transparent 62%),
    radial-gradient(110% 100% at 8% 100%, color-mix(in oklab, var(--color-x3-blue-deep) 60%, transparent), transparent 65%),
    color-mix(in oklab, var(--color-black) 86%, var(--color-x3-blue-bright));
}
.p-x3 .x3-prod__visual--3 {
  background:
    radial-gradient(120% 95% at 15% 100%, color-mix(in oklab, var(--color-x3-indigo) 75%, transparent), transparent 62%),
    radial-gradient(110% 100% at 90% 5%, color-mix(in oklab, var(--color-blue) 45%, transparent), transparent 65%),
    color-mix(in oklab, var(--color-black) 86%, var(--color-x3-indigo));
}
.p-x3 .x3-prod__visual--4 {
  background:
    radial-gradient(120% 95% at 85% 100%, color-mix(in oklab, var(--color-x3-blue-deep) 70%, transparent), transparent 62%),
    radial-gradient(110% 100% at 10% 0%, color-mix(in oklab, var(--color-x3-blue-bright) 50%, transparent), transparent 65%),
    color-mix(in oklab, var(--color-black) 88%, var(--color-blue));
}
.p-x3 .x3-prod__meta {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.p-x3 .x3-prod__pill {
  border: 1px solid rgba(204, 225, 255, 0.3);
  /* solid ink, not the 0.35 glass: static contrast checkers can't
     resolve an alpha background (WCAG 1.4.3, a11y audit 2026-08-05);
     blue-200 on black measures well past 4.5:1 */
  background: var(--color-black);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--track-wider);
  color: var(--color-blue-200);
}
/* big product glyph — in flow between the pill row and the title block
   (flex: 1), so it centers in the tile's FREE space instead of the full
   tile (the absolute inset-0 center crowded the title; Nacim, 2026-08-10:
   'haz más grandes los iconos y céntralos') */
.p-x3 .x3-prod__glyph {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.p-x3 .x3-prod__glyph-icon {
  width: 32px;
  height: 32px;
  -webkit-mask-size: contain;
  mask-size: contain;
  color: rgba(255, 255, 255, 0.9);
  transition: transform 0.5s var(--ease-out-expo);
}
.p-x3 .x3-prod:hover .x3-prod__glyph-icon { transform: scale(1.08); }
.p-x3 .x3-prod__id {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.p-x3 .x3-prod__name {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: var(--track-tighter);
  font-size: var(--fs-3xl);
  line-height: 1.1;
  color: var(--color-white);
}
@media (min-width: 640px) { .p-x3 .x3-prod__name { font-size: 24px; } }
.p-x3 .x3-prod__line {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  line-height: var(--leading-snug);
  color: rgba(255, 255, 255, 0.65);
}
/* single-line description on desktop cards */
@media (min-width: 768px) {
  .p-x3 .x3-prod__line {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
/* footer row: tags left, arrow right — the arrow lives with the tags now */
.p-x3 .x3-prod__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  padding-inline: 8px;
  flex: 1;
}
.p-x3 .x3-prod__arrow {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  background: var(--color-white);
  color: var(--color-black);
  transition: transform 0.3s ease;
}
.p-x3 .x3-prod:hover .x3-prod__arrow { transform: translate(2px, -2px); }
.p-x3 .x3-prod__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.p-x3 .x3-prod__tag {
  padding: 5px 12px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 9999px;
  font-size: var(--fs-xs);
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .p-x3 .x3-prod,
  .p-x3 .x3-prod__glyph-icon,
  .p-x3 .x3-prod__arrow { transition: none !important; }
}


/* ---------- tall screens (external monitors ≥1050px viewport height) ----
   The hero lockup rode margin-top:auto to the hero's foot — on a 1440px
   monitor it hugged the bottom edge with a void above (Sofia, 2026-08-05).
   Splitting the leftover with margin-block:auto centers it; MacBook-height
   viewports (≤~900px) never match this query and keep today's layout. */
@media (min-height: 1050px) {
  .p-x3 .x3-hero__inner { margin-block: auto; }
}
