/**
 * DocuPOW — Infinity page styles (page-templates/infinity.php only).
 *
 * Scope: everything lives under .page-infinity (BEM). Global chrome,
 * container, buttons, scroll-reveal and the gradient border come from
 * main.css — this file adds the soft-gradient hero, the chat panel mock,
 * the scope band and the page-specific motion only.
 *
 * Contrast contract (computed against the worst-case surface):
 *  - Hero canvas is linear-gradient(180deg, var(--gray), var(--border)); the
 *    darkest point is var(--border) #E2E8F0.
 *      - h1 "Meet Infinity." var(--indigo): 10.5:1 on #E2E8F0 (AA).
 *      - h1 accent line var(--techblue): 4.15:1 on #E2E8F0 — 64px/700
 *        large text, passes the 3:1 large-text threshold.
 *      - Lead var(--text-muted): 8.5:1 on #E2E8F0 (AA).
 *  - "Active Session" caption is #0A7B56 (darkened --ok, documented
 *    precedent — raw --ok fails at caption size): 5.28:1 on white (AA).
 *  - Citation chips (13px mono) are #276CC1 (the documented ~8%-darkened
 *    --techblue from the main.css button hover): 4.7:1 on the
 *    rgba(43, 118, 210, .12) tint over the gray reply bubble — raw
 *    --techblue is 4.09:1 there and fails AA.
 *  - User bubble: var(--ink) on rgba(43, 118, 210, .12) over white (~14:1).
 *  - The only shadows are var(--shadow) on the chat panel (floating
 *    product-UI exception per DESIGN.md) and the mascot's drop-shadow
 *    (floating-imagery exception, same as home.css).
 *
 * Motion contract (transform/opacity only; RICH tier):
 *  - Hidden "entrance" base states sit inside
 *    @media (prefers-reduced-motion: no-preference), so with reduced motion
 *    (or if infinity.js never runs under that preference) everything is
 *    visible. The ONLY float is the mascot's gentle 6s idle bob (on the img,
 *    inside the entrance wrapper, so the two transforms never fight).
 *  - infinity.js hooks: .is-ready on .page-infinity__hero (staged entrance:
 *    mascot -> h1 -> lead -> CTA at 0/80/160/240ms); .is-visible fades
 *    [data-inf-user] then [data-inf-reply] in; .is-active shows the
 *    [data-inf-pulse] dot row for ~1s between them. main.js owns
 *    [data-dp-reveal] and the stagger delays (infinity.js clears the inline
 *    delays post-reveal, established pattern).
 *  - A final prefers-reduced-motion: reduce block forces every animated
 *    element fully visible and static (belt-and-braces over main.css).
 */

/* =========================================================================
   Page scope — light canvas, section rhythm
   ========================================================================= */
.page-infinity {
  overflow-x: clip; /* insurance: nothing may cause horizontal scroll @320px */
}

/* 96px section padding on desktop, 64px under 768. */
.page-infinity__hero,
.page-infinity__chat,
.page-infinity__scope,
.page-infinity__cta {
  padding-block: var(--space-7);
}

@media (max-width: 767.98px) {
  .page-infinity__hero,
  .page-infinity__chat,
  .page-infinity__scope,
  .page-infinity__cta {
    padding-block: var(--space-6);
  }
}

/* =========================================================================
   S1 — Hero (soft-gradient canvas, centered column)
   ========================================================================= */
.page-infinity__hero {
  /* Per the export's .bg-soft-gradient (#F5F7FA -> #E2E8F0), token-mapped. */
  background: linear-gradient(180deg, var(--gray) 0%, var(--border) 100%);
  text-align: center;
}

/* Centered column — max 768px per the export's max-w-3xl. */
.page-infinity__hero-inner {
  max-width: 768px;
  margin-inline: auto;
}

/* Entrance wrapper — infinity.js/CSS translate THIS, the bob animates the
   img inside, so entrance transform and idle loop never conflict. */
.page-infinity__mascot-wrap {
  display: block;
}

/* Mascot render — 256px wide (export w-64), drop-shadow is the documented
   floating-imagery exception (same treatment as home.css). */
.page-infinity__mascot {
  display: block;
  width: 256px;
  height: auto;
  margin-inline: auto;
  margin-bottom: var(--space-4);
  filter: drop-shadow(0 12px 24px rgba(28, 28, 40, .18));
}

@media (max-width: 639.98px) {
  .page-infinity__mascot {
    width: 192px;
  }
}

/* The single h1 — headline-xl (64/1.1/-0.02em/700), "Meet Infinity." in
   Royal Indigo (10.5:1 on the gradient's darkest stop). */
.page-infinity__title {
  font-size: 64px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--indigo);
  margin-bottom: var(--space-3);
}

/* Second line — Tech Blue: 4.15:1 on #E2E8F0, passes the 3:1 large-text
   threshold at 64px/700. */
.page-infinity__title-accent {
  color: var(--techblue);
}

/* body-lg lead — var(--text-muted) is 8.5:1 on the gradient's darkest stop. */
.page-infinity__lead {
  font-size: 18px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 672px;
  margin-inline: auto;
  margin-bottom: var(--space-5);
}

/* CTA row — shared by the hero and S4 (single primary button, centered). */
.page-infinity__cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

/* =========================================================================
   S2 — Chat panel (the page's ONLY gradient-border element)
   ========================================================================= */
.page-infinity__panel,
.page-infinity [data-inf-chat] {
  max-width: 960px;
  margin-inline: auto;
  background-color: var(--white);
  border: 1px solid var(--border);
  border-radius: 12px; /* outranks .dp-gradient-border-active (later sheet) */
  padding: var(--space-4);
  box-shadow: var(--shadow); /* soft shadow allowed — floating product UI */
}

@media (max-width: 639.98px) {
  .page-infinity__panel,
  .page-infinity [data-inf-chat] {
    padding: var(--space-3);
  }
}

/* Header row — avatar + name/status, hairline divider below. */
.page-infinity__chat-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
}

/* Avatar circle — 40px gray roundel with a hairline ring. */
.page-infinity__avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: var(--gray);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex: none;
}

.page-infinity__avatar-img {
  display: block;
  width: 32px;
  height: 32px;
  object-fit: contain;
}

/* Name + status stack. */
.page-infinity__chat-id {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* Heading order preserved: this is the page's first h2, styled small. */
.page-infinity__chat-name {
  font-size: 16px;
  line-height: 1.4;
  letter-spacing: normal;
  font-weight: 600;
  color: var(--ink);
}

/* Status caption — #0A7B56 is the darkened --ok (documented precedent —
   raw --ok fails 4.5:1 at caption size on white; 5.28:1 here). */
.page-infinity__chat-status {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 13px;
  line-height: 1.4;
  color: #0A7B56;
}

/* Status dot — display:block so the 8px box always renders (spans as
   inline boxes ignore width/height; build rule). Colour-only never carries
   the status — the "Active Session" text does. */
.page-infinity__status-dot {
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--ok);
  flex: none;
}

/* The exchange — user bubble, pulse row, reply row. */
.page-infinity__thread {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Message rows. */
.page-infinity__msg {
  display: flex;
  gap: var(--space-2);
  min-width: 0;
}

.page-infinity__msg--user,
.page-infinity [data-inf-user] {
  justify-content: flex-end;
}

.page-infinity__msg--reply,
.page-infinity [data-inf-reply] {
  justify-content: flex-start;
}

/* Reply-row bot roundel — 32px, brand techblue icon (decorative). */
.page-infinity__avatar--sm {
  width: 32px;
  height: 32px;
  margin-top: 4px;
  color: var(--techblue);
}

.page-infinity__avatar--sm svg {
  width: 18px;
  height: 18px;
  flex: none;
}

/* Bubbles — soft 12px shells with a squared "tail" corner per the export. */
.page-infinity__bubble {
  max-width: 672px;
  padding: var(--space-2) var(--space-3);
  border-radius: 12px;
  min-width: 0;
}

/* User bubble — light techblue tint, ink text (~14:1 over white). */
.page-infinity__bubble--user {
  background-color: rgba(43, 118, 210, .12);
  color: var(--ink);
  border-top-right-radius: 4px;
}

.page-infinity__bubble--user p {
  font-size: 18px;
  line-height: 1.6;
}

/* Reply bubble — workspace-gray, hairline ring. */
.page-infinity__bubble--reply {
  background-color: var(--gray);
  border: 1px solid var(--border);
  border-top-left-radius: 4px;
  color: var(--ink);
}

.page-infinity__reply-intro {
  font-size: 18px;
  line-height: 1.6;
  margin-bottom: var(--space-2);
}

/* Findings list — warn triangles + verbatim text + citation chips. */
.page-infinity__findings {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}

.page-infinity__finding {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  font-size: 16px;
  line-height: 1.6;
  min-width: 0;
}

/* Warning triangle — status icon; never colour-alone (the text carries the
   "over by" meaning). --err reads as an icon accent on the gray bubble. */
.page-infinity__finding svg {
  width: 16px;
  height: 16px;
  color: var(--err);
  flex: none;
  margin-top: 4px;
}

.page-infinity__finding-text {
  min-width: 0;
}

/* Citation chips — NON-INTERACTIVE mono chips (the export's href="#"
   anchors, sanctioned correction). #276CC1 is the documented ~8%-darkened
   --techblue (main.css button hover): 4.7:1 on this tint over the gray
   bubble — raw --techblue is 4.09:1 at 13px and fails AA. */
.page-infinity__cite {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.4;
  font-weight: 500;
  color: #276CC1;
  background-color: rgba(43, 118, 210, .12);
  border-radius: 4px;
  padding: 1px 6px;
  margin-left: 4px;
  white-space: nowrap;
}

.page-infinity__reply-closing {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* Agent pulse row — hidden until infinity.js shows it (established pulse
   pattern). Indented to align with the reply bubble. */
.page-infinity__pulse,
.page-infinity [data-inf-pulse] {
  display: none;
  align-items: center;
  gap: var(--space-1);
  padding-left: 48px; /* 32px roundel + 16px gap — aligns with the reply */
}

.page-infinity__pulse.is-active,
.page-infinity [data-inf-pulse].is-active {
  display: flex;
}

/* Pulse dots — display:block so the 8px boxes always render (build rule). */
.page-infinity__pulse-dot,
.page-infinity__pulse > *,
.page-infinity [data-inf-pulse] > * {
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--indigo);
  flex: none;
}

/* =========================================================================
   S3 — Scope band (gray rounded band, three centered columns)
   ========================================================================= */
.page-infinity__scope-band {
  background-color: var(--gray);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: var(--space-5) var(--space-3);
}

/* The 3-column grid — a NAMED wrapper (build rule) and the
   data-dp-reveal-stagger container. */
.page-infinity__scope-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

.page-infinity__scope-col {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-inline: var(--space-3);
}

/* Column hairlines — left dividers between the three columns (export
   md:border-l), swapping to top dividers when stacked below. */
.page-infinity__scope-col + .page-infinity__scope-col {
  border-left: 1px solid var(--border);
}

/* <768 — single column with top hairlines between stacked items. */
@media (max-width: 767.98px) {
  .page-infinity__scope-grid {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }

  .page-infinity__scope-col + .page-infinity__scope-col {
    border-left: 0;
    border-top: 1px solid var(--border);
    padding-top: var(--space-4);
  }
}

/* Icons — 32px Royal Indigo. */
.page-infinity__scope-col svg {
  width: 32px;
  height: 32px;
  color: var(--indigo);
  flex: none;
  margin-bottom: var(--space-2);
}

/* headline-md (24/1.3/500) in ink. */
.page-infinity__scope-col h3 {
  font-size: 24px;
  line-height: 1.3;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: var(--space-1);
}

.page-infinity__scope-col p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* =========================================================================
   S4 — Final CTA
   ========================================================================= */
.page-infinity__cta {
  text-align: center;
}

/* headline-lg (36/1.2/-0.01em/600) in Royal Indigo. */
.page-infinity__cta h2 {
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 600;
  color: var(--indigo);
  max-width: 768px;
  margin-inline: auto;
  margin-bottom: var(--space-4);
}

/* =========================================================================
   Mobile type scale (<768) — 64->44 and 36->28 (scope h3 stays 24)
   ========================================================================= */
@media (max-width: 767.98px) {
  .page-infinity__title {
    font-size: 44px;
    line-height: 1.1;
  }

  .page-infinity__cta h2 {
    font-size: 28px;
    line-height: 1.2;
  }
}

/* =========================================================================
   Motion — entrance base states, idle bob, pulse (no-preference only)
   ========================================================================= */
@media (prefers-reduced-motion: no-preference) {

  /* Hero entrance — infinity.js adds .is-ready to the hero on init
     (double rAF); mascot -> h1 -> lead -> CTA rise in at 0/80/160/240ms. */
  .page-infinity__hero .page-infinity__mascot-wrap,
  .page-infinity__hero .page-infinity__title,
  .page-infinity__hero .page-infinity__lead,
  .page-infinity__hero .page-infinity__cta-row {
    opacity: 0;
    transform: translateY(12px);
    transition:
      opacity .5s cubic-bezier(0.16, 1, 0.3, 1),
      transform .5s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .page-infinity__hero .page-infinity__title {
    transition-delay: 80ms;
  }

  .page-infinity__hero .page-infinity__lead {
    transition-delay: 160ms;
  }

  .page-infinity__hero .page-infinity__cta-row {
    transition-delay: 240ms;
  }

  .page-infinity__hero.is-ready .page-infinity__mascot-wrap,
  .page-infinity__hero.is-ready .page-infinity__title,
  .page-infinity__hero.is-ready .page-infinity__lead,
  .page-infinity__hero.is-ready .page-infinity__cta-row {
    opacity: 1;
    transform: none;
  }

  /* Idle bob — the img loops while the wrapper carries the entrance
     transform (no conflict). 6s, gentle 12px rise. */
  .page-infinity__mascot {
    animation: dp-inf-bob 6s ease-in-out infinite;
  }

  /* Chat bubbles — hidden until infinity.js sequences .is-visible on
     [data-inf-user] then [data-inf-reply] (visible from the start under
     reduced motion because this base state only exists here). */
  .page-infinity__msg--user,
  .page-infinity [data-inf-user],
  .page-infinity__msg--reply,
  .page-infinity [data-inf-reply] {
    opacity: 0;
    transform: translateY(8px);
    transition:
      opacity .5s cubic-bezier(0.16, 1, 0.3, 1),
      transform .5s cubic-bezier(0.16, 1, 0.3, 1);
  }

  /* Pulse dots — staggered opacity loop while the row is shown. */
  .page-infinity__pulse > *,
  .page-infinity [data-inf-pulse] > * {
    animation: dp-inf-dot 1.2s ease-in-out infinite;
  }

  .page-infinity__pulse > :nth-child(2),
  .page-infinity [data-inf-pulse] > :nth-child(2) {
    animation-delay: .2s;
  }

  .page-infinity__pulse > :nth-child(3),
  .page-infinity [data-inf-pulse] > :nth-child(3) {
    animation-delay: .4s;
  }
}

/* Shown-state class hooks (outside the media query: harmless no-ops when
   reduced motion already forces everything visible). */
.page-infinity__msg--user.is-visible,
.page-infinity [data-inf-user].is-visible,
.page-infinity__msg--reply.is-visible,
.page-infinity [data-inf-reply].is-visible {
  opacity: 1;
  transform: none;
}

/* Keyframes (only ever attached inside the no-preference block above). */
@keyframes dp-inf-bob {
  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-12px);
  }
}

@keyframes dp-inf-dot {
  0%,
  100% {
    opacity: .25;
  }

  50% {
    opacity: 1;
  }
}

/* =========================================================================
   Reduced motion — every animated element visible and static
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .page-infinity__hero .page-infinity__mascot-wrap,
  .page-infinity__hero .page-infinity__title,
  .page-infinity__hero .page-infinity__lead,
  .page-infinity__hero .page-infinity__cta-row,
  .page-infinity__msg--user,
  .page-infinity [data-inf-user],
  .page-infinity__msg--reply,
  .page-infinity [data-inf-reply] {
    opacity: 1;
    transform: none;
  }

  .page-infinity__mascot,
  .page-infinity__pulse > *,
  .page-infinity [data-inf-pulse] > * {
    animation: none;
  }

  /* The "thinking" pulse row is purely decorative — never shown. */
  .page-infinity__pulse,
  .page-infinity [data-inf-pulse] {
    display: none !important;
  }
}

/* -------------------------------------------------------------------------
   Named markup hooks that intentionally carry no styles of their own:
   block-flow divs or text styled contextually by their parents. Named here
   so every markup class resolves in this sheet (build rule).
   ------------------------------------------------------------------------- */
.page-infinity__hero-inner,
.page-infinity__chat,
.page-infinity__scope,
.page-infinity__msg,
.page-infinity__bubble,
.page-infinity__finding-text {
  /* no-op: inherits/contextual (also styled above where applicable) */
}
