/* Account takeover — page additions on top of the shared solution template
   (/styles/pages/solution.css, scoped .p-solution). Everything here is
   scoped to .p-solution--account-takeover and is additions/overrides only.

   Storytelling-fix pass (2026-07-31): this page is HYBRID — the step-up
   re-verification is an end-user MOBILE moment (phone frame stays), while the
   signal detection is a DASHBOARD story. So the real /technology screenshots
   and /product-snapshots assets were swapped for schematic wireframe phone
   screens (G1), and the yellow placeholders were built into accurate fake
   mocks — a chart and a rule-list dashboard (G2). Delete the mock kit below
   when the final art lands. Tokens only. */

/* ─────────────────────────────────────────────────────────────────────────
   placeholder kit (kept for any future tile; the three visuals below are now
   built mocks rather than yellow hatch)
   ───────────────────────────────────────────────────────────────────────── */
.p-solution--account-takeover .ph-visual {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: var(--ph-ar, 16 / 9);
  border: 2px dashed var(--color-black);
  border-radius: 16px;
  background: repeating-linear-gradient(-45deg,
    color-mix(in oklab, var(--color-placeholder-yellow) 45%, transparent) 0 14px,
    transparent 14px 28px);
  overflow: hidden;
}
.p-solution--account-takeover .ph-visual__tag {
  max-width: 85%;
  padding: 6px 12px;
  border-radius: 6px;
  background: var(--color-placeholder-yellow);
  color: var(--color-black);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: var(--leading-snug);
  text-align: center;
}
.p-solution--account-takeover .ph-claim {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--color-placeholder-yellow);
  color: var(--color-black);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* ─────────────────────────────────────────────────────────────────────────
   G6 · hero proof stats stay on ONE row at 1440 and 1280. The hero copy
   column is only ~half width, so three nowrap captions overflow to a second
   row. From tablet up we force the three stats into equal thirds on a single
   non-wrapping row and let each caption wrap internally instead.
   ───────────────────────────────────────────────────────────────────────── */
@media (min-width: 640px) {
  .p-solution--account-takeover .sol-hero__stats { flex-wrap: nowrap; gap: 20px; }
  .p-solution--account-takeover .sol-hero__stat { flex: 1 1 0; min-width: 0; }
  .p-solution--account-takeover .sol-hero__stat + .sol-hero__stat { padding-left: 22px; }
  .p-solution--account-takeover .sol-hero__stat-cap { white-space: normal; }
}

/* ─────────────────────────────────────────────────────────────────────────
   how-it-works step floats (`at-sf-*`) — Camila 2026-08-07.
   The frxh floating-container pattern (face-recognition.css § frxh) ported
   to this page's traveling-phone walk: the float layer is a SIBLING of the
   phone slot in .sol-how__stage (never inside the phone frame — the frame
   clips), so the containers surround the phone in both float mode and the
   static fallback. Visibility keys off the ACTIVE RAIL BUTTON via :has(),
   no JS. Each .at-sf group belongs to one step; per-step content + fine
   positioning live in the per-step blocks below (one sub-agent lane each).
   ───────────────────────────────────────────────────────────────────────── */
.p-solution--account-takeover .sol-how__stage { position: relative; }
/* the z-order twin: a sticky sibling of the pin at z5 (above the phonecol
   clone's z4) — see the markup comment. The ghost reproduces the phone's
   footprint so the twin stage matches the real stage's height; the twin
   stage strips the panel visuals it inherits from .sol-how__stage. */
.p-solution--account-takeover .sol-how { position: relative; }
.p-solution--account-takeover .at-sf-pin {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}
.p-solution--account-takeover .at-sf-pin__sticky {
  position: relative;
  display: flex;
  align-items: center;
  height: 100%;
}
.p-solution--account-takeover .sol-flow-wrap.is-float .at-sf-pin__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
}
.p-solution--account-takeover .at-sf-stage {
  background: none;
  box-shadow: none;
  border: 0;
}
.p-solution--account-takeover .at-sf-ghost {
  width: clamp(184px, 15vw, 228px);
  aspect-ratio: 390 / 844;
  visibility: hidden;
}
.p-solution--account-takeover .at-sf-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* above the traveling phonecol clone (z4 in the wrap's context) — Camila:
     the containers sit IN FRONT of the screen and may cover it a bit */
  z-index: 5;
}
.p-solution--account-takeover .at-sf {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition:
    opacity 0.45s var(--ease-out-expo),
    transform 0.45s var(--ease-out-expo),
    visibility 0s 0.45s;
}
.p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="0"]) .at-sf[data-at-sf="0"],
.p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="1"]) .at-sf[data-at-sf="1"],
.p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="2"]) .at-sf[data-at-sf="2"],
.p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="3"]) .at-sf[data-at-sf="3"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0.15s, 0.15s, 0.15s;
}
/* only the ACTIVE bullet carries the blue underline (Camila) — the shared
   template holds a full blue bar on walked-past steps; here done steps go
   back to the hairline. */
.p-solution--account-takeover .sol-flow-wrap.is-float .sol-how__step.is-done .sol-how__fill {
  transform: scaleX(0);
  transition: transform 0.4s ease;
}

/* shared float-card look — the sol-deploy__float--studio construction
   (white card, hairline border, stacked label) at walk scale */
.p-solution--account-takeover .at-sf__card {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 16px;
  border: 1px solid var(--color-border-light);
  border-radius: 14px;
  background: var(--color-white);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--color-grey-500);
  white-space: nowrap;
}
.p-solution--account-takeover .at-sf__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-grey-400);
}
@media (max-width: 899px) {
  .p-solution--account-takeover .at-sf-layer { display: none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   at-s0 · step 1 "Trigger the step-up" floats (data-at-sf="0")
   What prompted the step-up: a signals card left of the phone (the LIFE
   moments at watch scale — new-device sign-in live, two quieter signals)
   + a small verdict chip right of the phone. Cards sit BESIDE the phone;
   any overlap stays inside the 9px frame bezel, never on screen content.
   ───────────────────────────────────────────────────────────────────────── */
.p-solution--account-takeover .at-s0-signals {
  top: 19%;
  /* v1 scale restored (Camila: the slim containment pass went too narrow).
     Anchored to the stage's left edge; the card may ride onto the phone —
     the z5 twin keeps it IN FRONT — but can never exit the stage. */
  left: 10px;
  max-width: calc(100% - 20px);
  gap: 8px;
  padding: 12px 14px;
  font-size: var(--fs-sm);
}
.p-solution--account-takeover .at-s0-row {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--color-grey-400);
}
.p-solution--account-takeover .at-s0-row.is-live {
  color: var(--color-grey-600);
  font-weight: 500;
}
.p-solution--account-takeover .at-s0-glyph {
  display: grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--color-grey-100);
  color: var(--color-grey-400);
}
.p-solution--account-takeover .at-s0-row.is-live .at-s0-glyph {
  background: var(--color-blue-100);
  color: var(--color-blue-500);
}
.p-solution--account-takeover .at-s0-glyph-icon {
  width: 14px;
  height: 14px;
}
/* the single alert accent: a small dot on the live trigger row only */
.p-solution--account-takeover .at-s0-dot {
  flex: none;
  width: 6px;
  height: 6px;
  margin-left: 4px;
  border-radius: 50%;
  background: var(--color-red-brand);
}
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover .at-s0-dot {
    animation: at-s0-pulse 2.2s ease-in-out infinite;
  }
}
@keyframes at-s0-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.p-solution--account-takeover .at-s0-verdict {
  top: 58%;
  /* v1 one-line chip restored, anchored to the stage's right edge; may ride
     onto the phone (in front, via the z5 twin), never out of the stage */
  right: 10px;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-grey-600);
}
.p-solution--account-takeover .at-s0-verdict-glyph {
  background: var(--color-blue-100);
  color: var(--color-blue-500);
}
.p-solution--account-takeover .at-s0-verdict-glyph svg {
  width: 13px;
  height: 13px;
}

/* ─────────────────────────────────────────────────────────────────────────
   step 2 · "Catch the impersonation" — animated face match (`at-s2-*`) —
   Camila 2026-08-07 (sub-agent lane). Two parts:

   1 · The deck's screen 2 is now the shared FaceMatch1Screen component
       (the real "Verifying identity" selfie-vs-ID screen), animated with
       the site's canonical face-match choreography — the face-recognition
       compare scene / kyc-aml "Match the person" motion: the Selfie and ID
       portraits glide toward each other (±25px in the 390-wide user space)
       while the bubble tags fade out just before they meet. Re-declared
       here with at-s2- keyframes so this page owns its timing (solution.css
       ships the same values as co-fm-*; this file loads after it and wins).
       Keyed to .is-active so it replays every time the step activates.

   2 · The step's float card (data-at-sf="2"): "Face match" + the page's own
       step-copy phrase, with a resolving check — a blue ring spins while
       the portraits travel, then the green "matched" check pops in as they
       meet (green-for-the-final-check mirrors the face-recognition
       reference's verified op). Sits fully BESIDE the phone (left of the
       frame edge), never over the screen.
   ───────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover svg[data-sol-screen="2"].is-active .fm-face-selfie {
    animation: at-s2-selfie-in 1.5s cubic-bezier(0.85, 0, 0.25, 1) 0.3s both;
  }
  .p-solution--account-takeover svg[data-sol-screen="2"].is-active .fm-face-id {
    animation: at-s2-id-in 1.5s cubic-bezier(0.85, 0, 0.25, 1) 0.3s both;
  }
  .p-solution--account-takeover svg[data-sol-screen="2"].is-active .fm-tag-selfie,
  .p-solution--account-takeover svg[data-sol-screen="2"].is-active .fm-tag-id {
    animation: at-s2-tag-out 0.4s ease 1.2s both;
  }
}
@keyframes at-s2-selfie-in {
  from { transform: translateX(0); }
  to { transform: translateX(25px); }
}
@keyframes at-s2-id-in {
  from { transform: translateX(0); }
  to { transform: translateX(-25px); }
}
@keyframes at-s2-tag-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* the float card — a slim stacked column in the strip between the stage's
   left edge and the phone (Camila: floats must sit FULLY inside the stage,
   AND never cover the screen). Anchored on BOTH edges — 10px inside the
   stage, 10px short of the phone frame (half-phone = half of
   clamp(184px, 15vw, 228px)) — so it can't escape either bound at any
   width; measured strip is 124-143px across 1280/1440/1728. Top 33% seats
   it beside the screen's portrait row. */
.p-solution--account-takeover .at-s2-card {
  top: 55%;
  /* v1 width restored (the slim containment pass went too narrow): anchored
     to the stage's left edge, may ride onto the phone (in front via the z5
     twin), never out of the stage */
  left: 10px;
  width: 208px;
  max-width: calc(100% - 20px);
  padding: 13px 15px;
  white-space: normal;
}
.p-solution--account-takeover .at-s2-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.p-solution--account-takeover .at-s2-line {
  font-size: 13px;
  line-height: 1.5;
}
/* resolving check: an 18px slot stacking the blue progress ring and the
   green "matched" check */
.p-solution--account-takeover .at-s2-mark {
  position: relative;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}
.p-solution--account-takeover .at-s2-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid color-mix(in oklab, var(--color-blue-500) 22%, transparent);
  border-top-color: var(--color-blue-500);
  opacity: 0;
}
.p-solution--account-takeover .at-s2-check {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--color-white);
  background: var(--color-green-500);
}
.p-solution--account-takeover .at-s2-check svg {
  width: 11px;
  height: 11px;
}
/* under motion the ring spins while the portraits glide (0.3–1.8s), fades
   as they meet, and the check pops in — keyed to the SAME :has() chain
   that shows the float, so it replays on every activation. Base state
   (reduced motion / no :has support) is the settled green check. */
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="2"]) .at-s2-ring {
    opacity: 1;
    animation:
      at-s2-spin 0.9s linear infinite,
      at-s2-ring-out 0.35s ease 1.9s forwards;
  }
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="2"]) .at-s2-check {
    animation: at-s2-check-in 0.45s cubic-bezier(0, 0.75, 0.25, 1) 1.95s both;
  }
}
@keyframes at-s2-spin {
  to { transform: rotate(360deg); }
}
@keyframes at-s2-ring-out {
  to { opacity: 0; }
}
@keyframes at-s2-check-in {
  from { opacity: 0; transform: scale(0); }
  60% { opacity: 1; transform: scale(1.12); }
  to { opacity: 1; transform: scale(1); }
}

/* ─────────────────────────────────────────────────────────────────────────
   at-dep · sol-deploy Studio floats pulled off the phone (Camila,
   2026-08-07: "the containers are covering the screen a bit too much").
   The shared template positions the four controls with %-offsets from the
   panel edges, which lands them well over the phone screen (Brand color
   over the capture circle's instruction text, Your logo over the wordmark,
   Font/Corner radius over the caption + CTA). Instead of edge-%s, anchor
   each card's inner edge to the PHONE's edge: --at-dep-phone-w mirrors the
   phone width formula from solution.css (.sol-deploy__phone), and each
   float sits at 50% ± half of it, minus a constant 12px kiss — a sliver of
   overlap so they still read as attached, never as covers. Outer edges must
   ALSO stay fully inside the panel (Camila follow-up: no poking out of the
   parent frame), so every card carries a max-width equal to the gutter
   (panel edge → kiss line) and its chip rows wrap when clamped.
   Position/size-only: opacity/transform/transition reveal choreography from
   solution.css is untouched.
   ───────────────────────────────────────────────────────────────────────── */
.p-solution--account-takeover .sol-deploy__stage {
  --at-dep-phone-w: min(clamp(208px, 18vw, 262px), 33svh - 40px);
  --at-dep-kiss: 12px;
}
.p-solution--account-takeover .sol-deploy__float--l {
  left: auto;
  right: calc(50% + var(--at-dep-phone-w) / 2 - var(--at-dep-kiss));
}
.p-solution--account-takeover .sol-deploy__float--tr {
  right: auto;
  left: calc(50% + var(--at-dep-phone-w) / 2 - var(--at-dep-kiss));
}
.p-solution--account-takeover .sol-deploy__float--bl {
  left: auto;
  right: calc(50% + var(--at-dep-phone-w) / 2 - var(--at-dep-kiss));
}
.p-solution--account-takeover .sol-deploy__float--br {
  right: auto;
  left: calc(50% + var(--at-dep-phone-w) / 2 - var(--at-dep-kiss));
}
/* inside-the-panel guarantee: each card may be at most as wide as the
   gutter it lives in (50% − phone/2, plus the kiss it's allowed onto the
   phone, minus a 4px inset so it never touches the panel edge). Cards
   narrower than the gutter hug the phone; wider ones (Your logo / Corner
   radius run ~270-280px in one row, Font ~233px) get clamped and wrap
   their chips into rows — the same multi-row grid the Brand color card
   already uses. */
.p-solution--account-takeover .sol-deploy__float--l,
.p-solution--account-takeover .sol-deploy__float--tr,
.p-solution--account-takeover .sol-deploy__float--bl,
.p-solution--account-takeover .sol-deploy__float--br {
  max-width: calc(50% - var(--at-dep-phone-w) / 2 + var(--at-dep-kiss) - 4px);
}
.p-solution--account-takeover .sol-deploy__float--studio .sdm-opts { flex-wrap: wrap; }
/* narrow desktop (1024–1359): below ~1360 the gutter clamp starts biting
   into the Brand color card's 4-swatch rows (they'd wrap 3+1). Compact the
   controls (smaller chips + swatches) so whole rows keep fitting, and allow
   a slightly deeper kiss at the narrow end (the phone screen's own side
   whitespace still clears it). (Below 1024 solution.css hides the studio
   floats.) */
@media (min-width: 1024px) and (max-width: 1359px) {
  .p-solution--account-takeover .sol-deploy__stage { --at-dep-kiss: 16px; }
  .p-solution--account-takeover .sol-deploy__float--studio { padding: 10px 12px; gap: 8px; }
  .p-solution--account-takeover .sol-deploy .sdm-opts { gap: 6px; }
  .p-solution--account-takeover .sol-deploy .sdm-opt { min-height: 30px; padding: 0 8px; }
  .p-solution--account-takeover .sol-deploy .sdm-opt:has(> i) { padding: 0 4px; }
  .p-solution--account-takeover .sol-deploy .sdm-opt i { width: 16px; height: 16px; }
  .p-solution--account-takeover .sol-deploy .sdm-opt svg { width: 16px; height: 16px; }
}

/* ─────────────────────────────────────────────────────────────────────────
   at-s3 · step 4 "Decide in real time" (data-at-sf="3" + deck screen 3)
   — Camila 2026-08-07: "make the loader spin and add a floating container
   with the checks being performed."
   (a) The verifying capture's baked-in ring gets a LIVE spinner: an SVG
       overlay seated exactly on the jpg's own spinner (measured on the
       780×1688 capture: center 50% / 48.34%, outer Ø 12.3% of width,
       stroke 15/96; track #E5F0FF = blue-100, arc = blue-500) with a white
       mask disc hiding the static original. Reduced motion: the overlay
       holds the capture's original pose, no spin.
   (b) The float card: three checks from the page's own vocabulary resolve
       sequentially (spin → green check, the frx timed-resolve pattern).
       Animations exist ONLY under the step-3 :has() active selector, so
       the sequence replays from zero every time the step re-activates.
       Green marks resolved checks — same as face-recognition's checks card.
   ───────────────────────────────────────────────────────────────────────── */
/* (a) the spinning-loader screen (both decks: sol-how + phonecol) */
.p-solution--account-takeover .at-s3-screen {
  position: relative;
  overflow: hidden;
}
.p-solution--account-takeover .at-s3-screen__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  border-radius: 34px;
}
.p-solution--account-takeover .at-s3-spinbox {
  position: absolute;
  left: 50%;
  top: 48.34%;
  width: 12.4%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  display: grid;
}
.p-solution--account-takeover .at-s3-spin {
  width: 100%;
  height: 100%;
  display: block;
  /* the mask disc (r=60 in a 96-box) reaches past the viewBox to also hide
     the baked arc's soft right-hand shadow — don't clip it */
  overflow: visible;
}
.p-solution--account-takeover .at-s3-spin__mask { fill: var(--color-white); }
.p-solution--account-takeover .at-s3-spin__track,
.p-solution--account-takeover .at-s3-spin__arc {
  fill: none;
  stroke-width: 15;
}
.p-solution--account-takeover .at-s3-spin__track { stroke: var(--color-blue-100); }
.p-solution--account-takeover .at-s3-spin__arc {
  stroke: var(--color-blue-500);
  stroke-linecap: round;
  /* 25/100 arc starting at 12 o'clock — the capture's original pose */
  stroke-dasharray: 25 75;
  stroke-dashoffset: 25;
}
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover .at-s3-screen.is-active .at-s3-spin {
    animation: at-s3-spin 1.1s linear infinite;
  }
}
@keyframes at-s3-spin {
  to { transform: rotate(1turn); }
}

/* (b) the checks float — right of the phone, FULLY INSIDE the stage box
   (Camila: floats must not poke out of the parent frame). The side band
   between the phone frame and the stage edge is only ~124px at 1280-1440,
   so the card hugs the stage's right edge and its max-width lets it reach
   at most into the phone's 9px bezel (the at-s0 allowance) — never onto
   screen content, whose right edge sits at 50% + ~86.5px of the stage.
   Rows run at 11px (the frx checklist size) and wrap with a hanging dot
   when the band is at its narrowest. */
.p-solution--account-takeover .at-s3-checks {
  top: 33%;
  /* v1 one-line rows restored: anchored to the stage's right edge, may ride
     onto the phone (in front via the z5 twin), never out of the stage */
  right: 10px;
  width: max-content;
  max-width: calc(100% - 20px);
  padding: 12px 14px;
  white-space: nowrap;
}
.p-solution--account-takeover .at-s3-checks .at-sf__label {
  white-space: nowrap;
}
.p-solution--account-takeover .at-s3-list {
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.p-solution--account-takeover .at-s3-check {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  font-size: 11px;
  line-height: 1.35;
  font-weight: 600;
  color: var(--color-grey-500);
}
.p-solution--account-takeover .at-s3-name { white-space: nowrap; }
/* dot rest state = resolved (green + check): what no-animation contexts
   (reduced motion) show; the active-step animations below rewind it */
.p-solution--account-takeover .at-s3-dot {
  position: relative;
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--color-green-500);
  background: var(--color-green-500);
}
.p-solution--account-takeover .at-s3-dot::before {
  /* busy ring (spins while the check runs) */
  content: "";
  position: absolute;
  inset: -1.5px;
  border-radius: 50%;
  border: 1.5px solid var(--color-grey-200);
  border-top-color: var(--color-blue-500);
  opacity: 0;
}
.p-solution--account-takeover .at-s3-dot::after {
  /* the check mark */
  content: "";
  position: absolute;
  inset: 3px;
  background: var(--color-white);
  -webkit-mask: url(/icons/check.svg) center / contain no-repeat;
          mask: url(/icons/check.svg) center / contain no-repeat;
}
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover .at-s3-check:nth-child(1) { --at-s3-d: 0.7s; }
  .p-solution--account-takeover .at-s3-check:nth-child(2) { --at-s3-d: 1.5s; }
  .p-solution--account-takeover .at-s3-check:nth-child(3) { --at-s3-d: 2.3s; }
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="3"]) .at-s3-dot {
    /* holds the busy look until this row's delay, then flips green */
    animation: at-s3-resolve 0.01s linear var(--at-s3-d) both;
  }
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="3"]) .at-s3-dot::before {
    opacity: 1;
    animation:
      at-s3-busy-spin 0.7s linear infinite,
      at-s3-busy-out 0.2s linear var(--at-s3-d) forwards;
  }
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="3"]) .at-s3-dot::after {
    animation: at-s3-check-pop 0.35s var(--ease-out-expo) var(--at-s3-d) both;
  }
}
@keyframes at-s3-resolve {
  from {
    background: var(--color-white);
    border-color: var(--color-grey-200);
  }
  to {
    background: var(--color-green-500);
    border-color: var(--color-green-500);
  }
}
@keyframes at-s3-busy-spin {
  to { transform: rotate(1turn); }
}
@keyframes at-s3-busy-out {
  to { opacity: 0; }
}
@keyframes at-s3-check-pop {
  from {
    opacity: 0;
    transform: scale(0.4);
  }
  to {
    opacity: 1;
    transform: none;
  }
}


/* ─────────────────────────────────────────────────────────────────────────
   at-s1 · step 2 "Re-verify with a selfie" — Camila 2026-08-07:
   "add the video of the person instead of the static image mockup, and
   spin the ring… also add a container saying something like verifying
   identity". The deck's step-1 screen becomes a composite (frx-phone
   pattern, face-recognition.css § frx): Selfie3Screen (the real "Align
   your face" product screen) with the live selfie loop clipped to its
   capture circle, the screen's own blue gradient ring spinning around it,
   plus a liveness-check float card beside the phone (data-at-sf="1").
   ───────────────────────────────────────────────────────────────────────── */

/* the composited screen — .sol-stage__screen (solution.css) supplies the
   deck sizing (width 100%, 390/844 aspect, radius 34, crossfade) */
.p-solution--account-takeover .at-s1-screen {
  position: relative;
  overflow: hidden;
}
.p-solution--account-takeover .at-s1-screen .at-s1-svg {
  display: block;
  width: 100%;
  height: auto;
}
/* the screen's static photo/scene circles + silhouette hide — the live
   video replaces them (the caption and grey ring track stay) */
.p-solution--account-takeover .at-s1-screen .s3-photo,
.p-solution--account-takeover .at-s1-screen .s3-scene,
.p-solution--account-takeover .at-s1-screen .s3-silhouette { display: none; }
/* the live selfie loop, clipped to the screen's capture circle — geometry
   from the 390×844 viewBox (circle cx195 cy313.5 r145.5):
   left (195−145.5)/390, top (313.5−145.5)/844, size 291/390 × 291/844 */
.p-solution--account-takeover .at-s1-cam {
  position: absolute;
  left: 12.692%;
  top: 19.905%;
  width: 74.615%;
  height: 34.479%;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-grey-50);
}
/* "spin the ring" — the screen's own blue gradient capture ring
   (.s3-ring-scan, display:none by default per solution.css), revealed
   here; static under reduced motion (matching the solution.css fallback:
   the plain blue ring), orbiting otherwise */
.p-solution--account-takeover .at-s1-screen .s3-ring-scan {
  display: inline;
  transform-box: fill-box;
  transform-origin: center;
}
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover .at-s1-screen .s3-ring-scan {
    animation: at-s1-ring-spin 2.4s linear infinite;
  }
}
@keyframes at-s1-ring-spin {
  to { transform: rotate(1turn); }
}

/* the float: liveness status card at the phone's left side (Camila: the
   under-phone toast read as a snackbar — stacked column instead, subtitle
   below the title, moved to the side and up; mirrors the s2 face-match
   card's composition). Rides onto the phone in front via the z5 twin,
   never outside the stage. */
.p-solution--account-takeover .at-s1-float {
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  padding: 13px 15px;
  left: 10px;
  top: 28%;
  width: 208px;
  max-width: calc(100% - 20px);
}
.p-solution--account-takeover .at-s1-float .at-sf__label { line-height: 1.4; }
.p-solution--account-takeover .at-s1-float__line { color: var(--color-black); }
/* spinner → check affordance: both stacked in one slot; the spinner spins
   then hands off to the check each time the step lands (the :has() chain
   re-applies the animations on every activation, so the beat restarts) */
.p-solution--account-takeover .at-s1-float__slot {
  display: grid;
  place-items: center;
  /* explicit box: base.css's `svg { max-width: 100% }` would otherwise
     collapse the auto-sized grid track (16px item ↔ 100% max-width cycle) */
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
.p-solution--account-takeover .at-s1-float__slot > svg {
  grid-area: 1 / 1;
  width: 16px;
  height: 16px;
}
.p-solution--account-takeover .at-s1-spin-track { stroke: var(--color-blue-100); }
.p-solution--account-takeover .at-s1-spin-arc {
  stroke: var(--color-blue-500);
  stroke-linecap: round;
  stroke-dasharray: 30 70;
}
.p-solution--account-takeover .at-s1-float__check {
  opacity: 0;
  color: var(--color-blue-500);
}
@media (prefers-reduced-motion: no-preference) {
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="1"]) .at-s1-float__spinner {
    animation:
      at-s1-spin 0.9s linear infinite,
      at-s1-spin-out 0.25s ease 2.15s both;
  }
  .p-solution--account-takeover .sol-how:has(.sol-how__step.is-active[data-sol-step="1"]) .at-s1-float__check {
    animation: at-s1-check-in 0.35s var(--ease-out-expo) 2.3s both;
  }
}
/* reduced motion: the check shows resolved, no spinner */
@media (prefers-reduced-motion: reduce) {
  .p-solution--account-takeover .at-s1-float__spinner { display: none; }
  .p-solution--account-takeover .at-s1-float__check { opacity: 1; }
}
@keyframes at-s1-spin {
  to { transform: rotate(1turn); }
}
@keyframes at-s1-spin-out {
  to { opacity: 0; }
}
@keyframes at-s1-check-in {
  from {
    opacity: 0;
    transform: scale(0.4);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
