/* The landing page, layered over style.css.
 *
 * A separate file on purpose: the homepage and legal pages are what platform
 * reviewers load, and a marketing stylesheet has no business changing how they
 * render. Everything here is scoped to classes only product.html uses.
 *
 * No framework, no web fonts, no build step -- same reasoning as style.css.
 * The page is mostly screenshots, and the screenshots are the argument.
 */

:root {
  /* The chart series, reused as category colours on the magnet cards so the
     page and the screenshots agree. Validated on the light surface -- the
     amber slot moved from #c98500, which fell to 2.99:1 against white. */
  --accent-2: #d95926;
  --good: #12805c;
  --warn: #8a5c00;
  --bad: #c9372c;

  /* On white a shadow does the lifting a border did on the dark theme. Kept
     shallow and neutral: a screenshot floating too far off the page reads as
     a sticker rather than a window. */
  --lift: 0 1px 2px rgba(16, 24, 40, 0.04), 0 12px 28px -10px rgba(16, 24, 40, 0.16);
}

/* A single wider measure for the landing page. The homepage stays at 1080 --
   a legal document reads badly at this width, and a screenshot reads badly
   below it. */
.hero-p .wrap,
.stats .wrap,
.band-p .wrap,
.close .wrap { max-width: 1140px; }

.eyebrow, .kicker {
  margin: 0 0 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
}

/* ---------------------------------------------------------------- hero -- */

.hero-p {
  padding: 76px 0 0;
  /* A single soft wash behind the headline. Gradients on a dark surface band
     badly at full width, so this one is wide, faint and centred rather than
     a hard sweep. */
  /* A faint cool wash rather than the dark theme's glow. On white a saturated
     gradient reads as a banner; this only has to keep the hero from being a
     flat white slab. */
  background:
    radial-gradient(62% 54% at 50% 0%, rgba(57, 135, 229, 0.07), transparent 72%),
    radial-gradient(42% 42% at 84% 6%, rgba(217, 89, 38, 0.045), transparent 72%);
}

.hero-p h1 {
  margin: 0 0 22px;
  font-size: clamp(36px, 5.6vw, 62px);
  line-height: 1.06;
  letter-spacing: -0.035em;
  max-width: 20ch;
}
.hero-p h1 em {
  font-style: normal;
  /* The one place a gradient earns its keep: a single word, large enough that
     the ramp is visible rather than muddy. */
  background: linear-gradient(96deg, #1a5fd0, #0f9e93 68%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-p .lede {
  margin: 0 0 30px;
  font-size: clamp(17px, 2.1vw, 21px);
  line-height: 1.55;
  color: var(--muted);
  max-width: 56ch;
}

/* ------------------------------------------------------------- capture -- */

.capture {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  max-width: 480px;
  margin: 0 0 12px;
}
.capture input {
  flex: 1 1 220px;
  min-width: 0;
  padding: 12px 14px;
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
}
.capture input::placeholder { color: var(--faint); }
.capture input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--on-accent);
}
.capture button {
  padding: 12px 22px;
  font-size: 15px;
  border: 0;
  cursor: pointer;
}
/* The browser's own :invalid fires while the field is still being typed into,
   which flags a half-written address as wrong. This class is set on submit. */
.capture.invalid input { border-color: var(--bad); }

.micro {
  margin: 0;
  font-size: 13.5px;
  color: var(--muted);
}
.micro a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.micro a:hover { color: var(--text); }

/* ---------------------------------------------------------- screenshots -- */

figure.shot { margin: 44px 0 0; }
figure.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--lift);
  /* The captures are of a white app on a white page, so the border and the
     shadow are what give the screenshot an edge at all. */
  background: var(--bg);
}
figure.shot.flat img { box-shadow: none; }
figure.shot.narrow { max-width: 900px; }
figure.shot figcaption {
  margin-top: 12px;
  font-size: 13px;
  color: var(--muted);
  text-align: center;
}

/* The hero screenshot is tall and its lower half is a data table nobody reads
   at this size. Cropping it in CSS keeps the fold tight without a second
   capture, and the fade makes the cut deliberate rather than clipped. */
.hero-shot {
  margin-top: 52px;
  max-height: 620px;
  overflow: hidden;
  position: relative;
  border-radius: 12px;
  /* The container clips the image, so the top edge has to be drawn here --
     on the image it would be cropped away along with the bottom. */
  border: 1px solid var(--border);
  border-bottom: 0;
  box-shadow: var(--lift);
}
.hero-shot::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 200px;
  background: linear-gradient(to bottom, rgba(255,255,255,0), #ffffff 86%);
  pointer-events: none;
}
.hero-shot img { border-bottom: 0; border-radius: 12px 12px 0 0; }
.hero-shot figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 14px;
  z-index: 1;
  margin: 0;
}

/* --------------------------------------------------------------- stats -- */

.stats { padding: 64px 0 8px; }
.stats dl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
  margin: 0;
}
.stats dl > div {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
  box-shadow: var(--shadow-sm);
}
.stats dt {
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}
.stats dd {
  margin: 6px 0 4px;
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.stats p { margin: 0; font-size: 13px; color: var(--muted); line-height: 1.5; }
.stats p em { font-style: italic; color: var(--text); }

/* --------------------------------------------------------------- bands -- */

.band-p { padding: 92px 0; border-top: 1px solid var(--border); }
.band-p.alt { background: var(--sunken); }

.band-p h2, .close h2 {
  margin: 0 0 16px;
  font-size: clamp(27px, 3.7vw, 40px);
  line-height: 1.14;
  letter-spacing: -0.028em;
}
.band-p .sub, .close .sub {
  margin: 0 0 40px;
  font-size: clamp(16px, 1.8vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  max-width: 62ch;
}

/* ---------------------------------------------------- floating evidence -- */

/* --------------------------------------------------------------- cards -- */

.grid-p {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
}
.two {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
}
.grid-p .card h3, .two .card h3 { font-size: 16.5px; margin-bottom: 9px; }
.grid-p .card p, .two .card p { font-size: 14px; line-height: 1.6; }

/* ------------------------------------------------------------- connect -- */

.connect-row {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 36px;
  align-items: center;
  margin-bottom: 36px;
}
.connect-row figure.shot { margin: 0; }

.steps { margin: 0; padding-left: 20px; counter-reset: step; }
.steps li {
  margin-bottom: 18px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
}
.steps li strong { display: block; color: var(--text); font-weight: 650; }

.trust {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  padding: 24px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.trust p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.trust strong { display: block; color: var(--text); margin-bottom: 3px; }

/* --------------------------------------------------------------- close -- */

.close {
  padding: 96px 0 104px;
  border-top: 1px solid var(--border);
  text-align: center;
  background: radial-gradient(58% 100% at 50% 100%, rgba(57, 135, 229, 0.07), transparent 72%);
}
.close .sub { margin-left: auto; margin-right: auto; }
.close .capture { margin-left: auto; margin-right: auto; }
.close h2 { max-width: 20ch; margin-left: auto; margin-right: auto; }

/* --------------------------------------------------------- narrow view -- */

@media (max-width: 860px) {
  .connect-row { grid-template-columns: 1fr; gap: 24px; }
  .band-p { padding: 66px 0; }
  .hero-p { padding: 48px 0 0; }
  .hero-shot { max-height: 420px; }
  .stats dd { font-size: 34px; }
}

/* The screenshots carry real detail -- axis labels, evidence figures -- that
   is unreadable on a phone. Below this width they become horizontally
   scrollable at a legible size rather than shrinking into a grey smear. */
@media (max-width: 620px) {
  .proof, .segs {
    /* Full-bleed scroller, so the crop reads as intentional. */
    margin-left: -24px;
    margin-right: -24px;
    padding: 0 24px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
  }
  /* These captures are wide -- an insight card is roughly 4:1 -- so at 88% of
     a 390px screen the body text lands near 4px and is unreadable. Scrolling
     them at well over the viewport width keeps the type legible; the peeking
     next card is what signals they scroll. */
  .proof { grid-auto-flow: column; grid-auto-columns: 250%; }
  .segs  { grid-auto-flow: column; grid-auto-columns: 200%; }
  .proof img, .segs figure { scroll-snap-align: start; }
  .hero-shot { max-height: 300px; }
  .capture { max-width: none; }
  .capture button { flex: 1 1 100%; }
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* ---------------------------------------------------------------------------
   Coverage: platforms on the left, what adlx does with them on the right.
   --------------------------------------------------------------------------- */

.split-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: start;
}
.split-col h2 { margin: 0 0 12px; }
.split-col .sub { margin-bottom: 28px; }

/* -- The platform tiles ---------------------------------------------------
   A plain list of what adlx reads, split into Live and Upcoming. This
   replaced a hub-and-spoke diagram: the diagram argued that the platforms
   converge, which the surrounding copy already says, and it spent a lot of
   space to name six things while rendering each logo at 22px.

   Two columns rather than three. The column this sits in is half the band,
   so at three across a tile is too narrow to set the icon beside the label
   and the logos go back to being small -- which was the original problem. */

.plat {
  margin: 4px 0 0;
}

.plat-head {
  margin: 0 0 10px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* The rule runs from the label to the end of the row, so the two groups read
   as sections without a heavier heading competing with the h2 above them. */
.plat-head::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* Live gets the brand dot. It is the one piece of colour that separates the
   two groups at a glance, without colouring the tiles themselves. */
.plat-head.is-live::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
  flex: none;
}

.plat-grid {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.plat-grid:last-child { margin-bottom: 0; }

.plat-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition:
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.plat-tile:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

.plat-tile.live {
  border-color: var(--brand-edge);
}

/* 40px, against the 22px the diagram gave these. The logos are the evidence
   that the integrations are real, so they are sized to be recognised rather
   than to fit a node. */
.plat-icon {
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  background: var(--sunken);
  border-radius: var(--radius-sm);
}
.plat-icon svg {
  width: 26px;
  height: 26px;
  display: block;
}

.plat-name {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text);
  line-height: 1.3;
}

/* Upcoming platforms are stated, not sold: same tile, quieter label, so the
   section stays honest about what is connectable today. */
.plat-tile:not(.live) .plat-name { color: var(--muted); }
.plat-tile:not(.live) .plat-icon svg { color: var(--faint); }

/* The "more soon" tile is a placeholder, not a platform. Dashed, and it does
   not lift on hover, so it does not read as another logo. */
.plat-tile.more {
  border-style: dashed;
  background: transparent;
  box-shadow: none;
}
.plat-tile.more:hover {
  transform: none;
  box-shadow: none;
  border-color: var(--border);
}
.plat-tile.more .plat-icon { background: transparent; }
.plat-tile.more .plat-icon svg { width: 20px; height: 20px; color: var(--faint); }

@media (prefers-reduced-motion: reduce) {
  .plat-tile { transition: none; }
  .plat-tile:hover { transform: none; }
}


/* ---------------------------------------------------------------------------
   Surface tiles.
   --------------------------------------------------------------------------- */

.tiles-band .sub.wide { max-width: 60ch; }

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-top: 40px;
}

/* 251x469 is the proportion Ryze uses and it is a good one: tall enough to
   read as a phone, short enough that three sit in a row without the section
   becoming a wall. */
.tile {
  position: relative;
  aspect-ratio: 300 / 470;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--panel);
}

.tile-label {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 34px 16px 14px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #fff;
  /* The label sits over product pixels of unknown colour, so it carries its
     own scrim rather than trusting the screenshot underneath it. */
  background: linear-gradient(to top, rgba(8, 12, 16, 0.86) 40%, rgba(8, 12, 16, 0));
  pointer-events: none;
}

/* -- The drawn tile ------------------------------------------------------- */

.tile-art { background: var(--sunken); }
.art {
  height: 100%;
  padding: 30px 20px 62px;
  display: flex;
  flex-direction: column;
  /* Spread rather than stacked: pinning the caption to the bottom with auto
     margin left a dead band through the middle of the tile. */
  justify-content: space-between;
  gap: 18px;
  color: var(--text);
}
.art-scatter { display: flex; gap: 10px; }
.art-card {
  flex: 1;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 11px;
}
.art-card.g { border-top: 2px solid #4285F4; }
.art-card.m { border-top: 2px solid #0866FF; }
.art-plat {
  display: block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.art-card b { display: block; font-size: 21px; letter-spacing: -0.02em; margin-top: 3px; }
.art-sub { display: block; font-size: 10.5px; color: var(--muted); margin-top: 1px; }

.art-flow { width: 100%; height: 34px; flex: none; color: var(--muted); }

.art-merged {
  background: var(--accent);
  color: #fff;
  border-radius: 8px;
  padding: 13px 14px;
}
.art-merged .art-plat { color: rgba(255, 255, 255, 0.65); }
.art-merged b {
  display: block;
  font-size: 27px;
  letter-spacing: -0.03em;
  margin-top: 3px;
  color: #fff;
}
.art-merged .art-sub { color: rgba(255, 255, 255, 0.72); line-height: 1.45; }

.art-caption {
  margin: 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
}

/* The tile is a fixed ratio, so when the caption wraps to a third line it
   runs under the label scrim. Below this width the two figures carry the
   point on their own and the sentence is repeated in the section's own
   copy -- so it goes rather than being shrunk to unreadability. */
@media (max-width: 1080px) {
  .art-caption { display: none; }
}

/* -- The phone tiles ------------------------------------------------------ */

.phone {
  height: 100%;
  padding: 20px 16px 0;
  display: flex;
  justify-content: center;
}
.phone-screen {
  width: 100%;
  border: 1px solid var(--border);
  border-top-left-radius: 14px;
  border-top-right-radius: 14px;
  border-bottom: 0;
  overflow: hidden;
  background: #fff;
}
.phone-screen img {
  width: 100%;
  height: auto;
  display: block;
  /* The whole effect: a tall capture translated behind a fixed window. No
     JavaScript, no video, and one image request. */
  /* One duration over different image heights means different speeds: the
     taller Optimize captures travel 719px against Reports' 440px, so a shared
     duration made them scroll 63% faster. The duration is set per tile from
     its own travel distance instead, so every tile moves at ~30px/s.

     Linear and non-alternating: the loop runs one way and starts over, so a
     reader who missed something waits for it to come round rather than
     watching it rewind. Easing would make a continuous loop pulse at the
     seam. */
  animation: tile-scroll var(--scroll-dur, 19s) linear infinite;
  animation-play-state: paused;
}
/* Runs when the tile is on screen, and faster while hovered. Paused otherwise
   so three animations are not burning compositor time above the fold. */
.tiles:hover .phone-screen img,
.tile:focus-within .phone-screen img { animation-play-state: running; }

@media (prefers-reduced-motion: no-preference) {
  .phone-screen img { animation-play-state: running; }
}

@keyframes tile-scroll {
  /* A continuous loop, so the seam has to be invisible: it holds the top
     briefly, travels, holds the end, then fades out and back in over the last
     8% while snapping back to the start. Cutting without the fade produces a
     visible jump every cycle. */
  0%, 8%    { transform: translateY(0); opacity: 1; }
  84%       { transform: translateY(calc(-100% + 420px)); opacity: 1; }
  92%       { transform: translateY(calc(-100% + 420px)); opacity: 0; }
  92.01%    { transform: translateY(0); opacity: 0; }
  100%      { transform: translateY(0); opacity: 1; }
}

/* A capture barely taller than its window has nothing to scroll: translating
   it by the full formula would drag it off the top and leave blank space.
   The merchant list is one screen, so it sits still and lets the two tiles
   beside it carry the motion. It is captured at the tile's own aspect ratio
   so its content fills the frame -- scaling it up instead would crop the
   sides, because .phone-screen clips. */
.tile-phone.still .phone-screen img { animation: none; }

/* Taller captures get proportionally longer, so speed stays constant. Only
   76% of the cycle is travel (the rest is the hold at each end plus the fade
   seam), which is folded into these numbers. */
.tile-phone.tall .phone-screen img { --scroll-dur: 31s; }

@media (prefers-reduced-motion: reduce) {
  .phone-screen img { animation: none; }
}

@media (max-width: 900px) {
  .split-grid { grid-template-columns: 1fr; gap: 44px; }
}

@media (max-width: 760px) {
  /* Three tiles at a third of a phone screen are unreadable. One and a bit,
     scrolled horizontally, keeps them at full size -- the peeking edge is what
     says there is more. */
  .tiles {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 68%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 8px;
  }
  .tile { scroll-snap-align: center; }
}

/* ===========================================================================
   Visual system primitives
   ---------------------------------------------------------------------------
   The pieces below are the reusable vocabulary: a raised surface, a floating
   stat badge, an interactive card, and scroll reveal. Everything on the page
   should be assembled from these rather than styled one-off, so a later
   section inherits the system instead of inventing a parallel one.
   =========================================================================== */

/* -- Raised surface -------------------------------------------------------
   The light-theme equivalent of the plan's "glass card". On white, real
   glassmorphism has nothing to refract, so depth comes from elevation and a
   hairline edge instead. A near-white gradient gives the face a subtle
   top-light rather than a flat fill. */
.surface {
  position: relative;
  background: linear-gradient(180deg, #fff 0%, var(--panel-2) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

/* -- Floating stat badge --------------------------------------------------
   Small, high-contrast, and deliberately overlapping whatever it sits on, so
   it reads as a layer above the page rather than a cell in it. */
.stat-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-xl);
  font-size: 13px;
  white-space: nowrap;
}
.stat-badge b {
  font-size: 16px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stat-badge .spark { flex: none; }

/* A quiet pulsing dot for "live". Two elements: a solid core and a ring that
   expands and fades, which reads as a heartbeat rather than a blink. */
.pulse-dot {
  position: relative;
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--good);
}
.pulse-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--good);
  animation: pulse-ring 2.4s var(--ease-out) infinite;
}
@keyframes pulse-ring {
  0%   { transform: scale(1); opacity: 0.55; }
  70%  { transform: scale(2.8); opacity: 0; }
  100% { transform: scale(2.8); opacity: 0; }
}

/* Gentle vertical drift, offset per element so a group does not bob in
   lockstep. */
.float { animation: float-y 7s var(--ease-in-out) infinite alternate; }
.float-2 { animation-duration: 8.5s; animation-delay: -2s; }
@keyframes float-y {
  from { transform: translateY(0); }
  to   { transform: translateY(-10px); }
}

/* -- Scroll reveal --------------------------------------------------------
   Progressive enhancement: the .reveal class only dims and offsets an element
   once JS has confirmed it can observe it (html.js-reveal). Without JS every
   element stays at its natural opacity, so the page is never blank because a
   script failed. */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}
.js-reveal .reveal.in {
  opacity: 1;
  transform: none;
}
/* Staggered children, for rows of cards. */
.js-reveal .reveal[data-delay="1"] { transition-delay: 80ms; }
.js-reveal .reveal[data-delay="2"] { transition-delay: 160ms; }
.js-reveal .reveal[data-delay="3"] { transition-delay: 240ms; }

@media (prefers-reduced-motion: reduce) {
  .float, .pulse-dot::after { animation: none; }
  .js-reveal .reveal { opacity: 1; transform: none; transition: none; }
}

/* -- Hero stage -----------------------------------------------------------
   The screenshot plus the two badges that overlap it. Positioned rather than
   flowed, because the whole point is that they sit above the image. */
.hero-stage {
  position: relative;
}
.hero-stage .stat-badge {
  position: absolute;
  z-index: 2;
}
/* Inside the figure's edges, not hung off them. Negative offsets pushed the
   badges past the .wrap padding, where the viewport clipped them -- the ROAS
   badge lost its right end and the spend badge its left. Overlapping the
   screenshot is the effect; overlapping the page edge is a bug. */
.badge-a { top: 7%; right: 3%; }
.badge-b { bottom: 22%; left: 3%; }

@media (max-width: 860px) {
  /* Below this the screenshot is small enough that overlapping badges cover
     the numbers they are quoting. They stack under it instead. */
  .hero-stage .stat-badge {
    position: static;
    display: inline-flex;
    margin: 10px 8px 0 0;
    box-shadow: var(--shadow-md);
  }
  .float { animation: none; }
}

/* -- Interactive action card ---------------------------------------------
   A working version of an insight card: press the button and the wasted-spend
   figure counts to zero while the projected return counts up. */
.act {
  max-width: 560px;
  margin: 28px 0 0;
  padding: 20px 22px;
  border-left: 3px solid var(--bad);
}
.act-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.act-badge {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bad);
}
.act-tag {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
}
.act-title { margin: 0 0 6px; font-size: 16px; letter-spacing: -0.01em; }
.act-detail { margin: 0 0 14px; font-size: 13.5px; line-height: 1.6; color: var(--muted); }

.act-figures {
  display: flex;
  gap: 26px;
  padding: 12px 14px;
  background: var(--sunken);
  border-radius: var(--radius);
  margin-bottom: 16px;
}
.act-figures dt {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  margin-bottom: 2px;
}
.act-figures dd {
  margin: 0;
  font-size: 19px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  transition: color var(--dur-base) var(--ease-out);
}
/* The two figures move in opposite directions, so they are coloured by what
   the movement means once the card has been acted on. */
.act.done .act-waste { color: var(--good); }
.act.done .act-roas { color: var(--good); }

/* The severity edge has to move too. Leaving it red on a resolved card says
   "still urgent" louder than the tick says "handled". */
.act { transition: border-left-color var(--dur-base) var(--ease-out); }
.act.done { border-left-color: var(--good); }
.act.done .act-badge { color: var(--good); }

.act-foot { display: flex; align-items: center; min-height: 38px; }
.act-go { transition: opacity var(--dur-fast) var(--ease-out); }
.act.done .act-go { display: none; }

.act-done {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  font-weight: 500;
  color: var(--good);
}
.act-done[hidden] { display: none; }
/* The tick draws itself rather than appearing, which is what makes the
   completion feel earned. */
.act.done .tick {
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
  animation: tick-draw 420ms var(--ease-out) forwards;
}
@keyframes tick-draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .act.done .tick { animation: none; stroke-dashoffset: 0; }
}

/* The confirmation that replaces the form after a successful signup. It sits
   where the input was, so the layout does not jump. */
.sent-note {
  margin: 0;
  padding: 11px 0;
  font-size: 15px;
  font-weight: 500;
  color: var(--good);
}


/* ---------------------------------------------------------------------------
   PRICING
   --------------------------------------------------------------------------- */

.price-hero {
  padding: 72px 0 92px;
  text-align: center;
}
.price-hero .kicker { justify-content: center; }
.price-hero h1 {
  font-size: clamp(34px, 4.4vw, 46px);
  line-height: 1.08;
  letter-spacing: -0.03em;
  margin: 0 0 14px;
}
.price-hero .sub {
  margin: 0 auto;
  max-width: 46ch;
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--muted);
}

/* -- The plan card --------------------------------------------------------
   One card, centred, with the feature list on its own inset panel. The inset
   is what keeps a single card from reading as a plain box: it gives the
   features their own ground and lets the price sit on the card itself. */

.plan {
  max-width: 380px;
  margin: 30px auto 0;
  padding: 26px;
  text-align: left;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}

.plan-name {
  margin: 0 0 20px;
  font-size: 21px;
  letter-spacing: -0.02em;
}

.plan-inner {
  padding: 20px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.plan-feats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}
.plan-feats li {
  position: relative;
  padding-left: 20px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
}
/* A square marker rather than a tick: a tick claims each line is a benefit
   being granted, which reads as sales copy on a list this plain. */
.plan-feats li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 6px;
  background: var(--text);
}

.plan-price {
  margin: 22px 0 0;
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.plan-amount {
  font-size: 42px;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1;
}
.plan-per {
  font-size: 15px;
  color: var(--muted);
}

.plan-cta {
  display: block;
  margin: 18px 0 0;
  width: 100%;
  text-align: center;
  padding: 12px 20px;
  font-size: 15px;
}

.plan-note {
  margin: 10px 0 0;
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
}

/* -- Agency add-ons -------------------------------------------------------
   Not a second plan -- the same product, counted -- so these are rows under
   the card rather than a card beside it. A second card would imply a choice
   between two things, and there is only one thing. */

.addons {
  max-width: 380px;
  margin: 26px auto 0;
  text-align: left;
}

.addons-head {
  margin: 0 0 10px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.addon-rows {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.addon-rows > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 16px;
  background: var(--panel);
}
.addon-rows > div + div { border-top: 1px solid var(--border); }

.addon-rows dt {
  font-size: 13.5px;
  color: var(--muted);
}
.addon-rows dd {
  margin: 0;
  flex: none;
  font-size: 13.5px;
  color: var(--text);
}
.addon-rows dd b { font-weight: 700; }
.addon-rows dd span { color: var(--muted); font-weight: 400; }

.addons-note {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--muted);
}

/* -- Pricing FAQ ---------------------------------------------------------- */

.faq { margin-top: 26px; }
.faq .card p { margin: 0; }
/* Four questions, so two columns rather than the .two default's auto-fit --
   at four across the last card sits alone on a second row. */
@media (min-width: 861px) {
  .faq { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .price-hero { padding: 52px 0 66px; }
  .plan { padding: 22px; }
  .plan-amount { font-size: 38px; }
}
