/* CatchaCRM website v4 — animated design layer. Linked by index.html only.
   Transform+opacity throughout, so it stays on the compositor.
   Gate: <html class="motion">, set by a one-liner in each page's <head>.
   That one-liner is the ONLY off switch — it skips the class when
   localStorage.catchaMotion === 'off' (the footer's "Motion" toggle). No OS
   media query gates anything in this file; do not add one back.
   Without it nothing is ever hidden, so no-JS still renders the full page.
   NOTE: the pill nav itself lives at the bottom of style.css, not here, so
   already-generated blog posts pick it up without being regenerated. */

/* ══════════════════════════════════════
   1. LANDING HERO — full-bleed scene, headline, SVG fishing animation
   ══════════════════════════════════════ */
/* The hook, the line and the fish ARE the hero — no product screenshot.
   100svh, not vh, so mobile browser chrome cannot clip it. */
.hero-a{
  position:relative; min-height:100svh; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  padding:150px 28px 110px;
  background:radial-gradient(60% 50% at 50% 0%, #dbeafe 0%, rgba(219,234,254,0) 70%);
}
.hero-a-in{
  position:relative; z-index:10; width:100%; max-width:var(--max); min-width:0;
  display:flex; flex-direction:column; align-items:center; text-align:center; gap:22px;
}
.hero-a h1{
  margin:0; font-weight:800; font-size:clamp(38px,10vw,84px);
  line-height:1.05; letter-spacing:-.03em; text-wrap:balance;
  max-width:100%;
}
.hero-a .lead{ margin:0; max-width:min(560px,100%); font-size:clamp(16px,1.4vw,18px); color:var(--muted); text-wrap:pretty; }
.hero-a .fine{ margin:0; max-width:100%; font-size:13px; color:var(--ghost); text-wrap:pretty; }
.hero-a .cta-row{ display:flex; flex-wrap:wrap; justify-content:center; gap:12px; margin-top:6px; min-width:0; max-width:100%; }

.pill-badge{
  display:inline-flex; align-items:center; gap:9px;
  background:var(--glass); backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  border:1px solid var(--glass-brd); box-shadow:var(--shadow-sm);
  border-radius:999px; padding:7px 16px;
  font-size:13px; font-weight:600; color:var(--ink-soft);
}
.pill-badge .dotb{ width:6px; height:6px; border-radius:999px; background:var(--blue); flex:none; }
.pill-badge svg{ flex:none; }

.scene{ position:absolute; inset:0; z-index:0; pointer-events:none; }

.slab{
  position:relative; z-index:10; margin-top:-32px;
  background:var(--bg-dim); border-radius:32px 32px 0 0;
  padding:clamp(72px,9vw,112px) 24px;
}
.slab-narrow{ max-width:760px; margin:0 auto; text-align:center; display:flex; flex-direction:column; align-items:center; gap:20px; }
.eyebrow-a{ font-size:12px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.h2-a{ margin:0; font-weight:800; font-size:clamp(28px,4.6vw,48px); line-height:1.12; letter-spacing:-.025em; text-wrap:balance; }
.rule{ display:flex; align-items:center; gap:14px; width:100%; max-width:520px; margin-top:26px; }
.rule i{ width:8px; height:8px; border-radius:999px; background:var(--line); flex:none; }
.rule span{ flex:1; height:1px; background:var(--line); }

/* ══════════════════════════════════════
   3. MODULE CARD STACK + WHEEL RAIL
   ══════════════════════════════════════ */
.mods{ background:var(--bg); padding:clamp(72px,8vw,120px) clamp(20px,4vw,48px) clamp(40px,5vw,72px); }
.mod-grid{
  display:grid; grid-template-columns:230px minmax(0,1fr);
  gap:clamp(28px,4vw,64px); max-width:1280px; margin:clamp(40px,5vw,72px) auto 0;
  align-items:start;
}
.mod-rail-wrap{ position:sticky; top:0; height:100vh; display:flex; align-items:center; overflow:visible; }
.mod-rail{ display:flex; flex-direction:column; gap:4px; transition:transform .45s cubic-bezier(.22,1,.36,1); will-change:transform; }
.mod-rail button{
  text-align:left; border:0; background:transparent; color:var(--muted);
  border-radius:999px; padding:10px 18px; font:600 15px/1.4 var(--sans);
  cursor:pointer; white-space:nowrap; transform-origin:left center;
  transition:background .35s ease,color .35s ease,opacity .35s ease,transform .35s ease;
}
.mod-rail button[aria-current="true"]{ background:#dbeafe; color:var(--blue-ink); }
.mod-rail button:focus-visible{ outline:2px solid var(--blue); outline-offset:2px; }

.mod-list{ display:flex; flex-direction:column; gap:14vh; padding-bottom:10vh; min-width:0; }
.mod-card{
  position:sticky; top:calc(28px + var(--i,0) * 24px);
  background:rgba(255,255,255,.92);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  border:1px solid var(--glass-brd); border-radius:24px; box-shadow:var(--shadow);
  padding:clamp(18px,2vw,28px); transform-origin:center top; will-change:transform;
}
.mod-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:16px; }
.mod-head-l{ display:flex; align-items:center; gap:12px; min-width:0; }
.mod-ico{ width:36px; height:36px; border-radius:10px; background:#dbeafe; display:flex; align-items:center; justify-content:center; flex:none; }
.mod-card h3{ margin:0; min-width:0; font-weight:700; font-size:clamp(18px,1.6vw,21px); letter-spacing:-.015em; }
.mod-num{ font-size:12px; font-weight:700; letter-spacing:.08em; color:var(--ghost); white-space:nowrap; }
.mod-shot{
  position:relative; overflow:hidden; aspect-ratio:1920/940;
  max-height:min(62vh, calc(100vh - 250px));
  border-radius:14px; border:1px solid var(--line); box-shadow:var(--shadow); background:#fff;
}
.mod-shot img{ display:block; width:100%; height:auto; }
.mod-shot .ovl{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:2; }
.mod-card p{ margin:16px 0 0; color:var(--ink-soft); font-size:clamp(15px,1.2vw,16px); line-height:1.7; text-wrap:pretty; }

/* ══════════════════════════════════════
   4. CLOSING CTA SLAB
   ══════════════════════════════════════ */
.cta-slab{
  position:relative; overflow:hidden; background:var(--bg-dim);
  border-radius:32px; margin:0 20px 20px; padding:clamp(72px,8vw,96px) 24px;
}
.cta-slab .mark{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); width:280px; height:280px; opacity:.07; pointer-events:none; }
.cta-slab-in{ position:relative; z-index:1; max-width:640px; margin:0 auto; text-align:center; display:flex; flex-direction:column; align-items:center; gap:18px; }

.btn-pill{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  white-space:nowrap; flex:0 0 auto;
  background:var(--blue); color:#fff; border-radius:999px; padding:12px 24px;
  font-weight:700; box-shadow:var(--shadow-blue);
  transition:background .2s ease, transform .2s ease;
}
.btn-pill:hover{ background:var(--blue-dark); color:#fff; transform:translateY(-2px); }
.btn-pill.ghost{ background:#fff; border:1px solid var(--line); color:var(--ink); box-shadow:none; }
.btn-pill.ghost:hover{ background:#fff; color:var(--ink); transform:translateY(-2px); box-shadow:var(--shadow); }

/* ════════════════════════════════════════════════════════════════
   5. MOTION — one story per element, no shared 9s metronome.
      Transform/opacity throughout; the one exception is the closing CTA
      hook's stroke-dashoffset draw (two thin paths, once, at opacity .07).
      Scroll-driven values arrive as custom properties on <html> (--hero-p,
      --scroll-p) from landing.js's single rAF loop and CSS interpolates
      them. Without JS they are unset, every var() falls back to 0, and the
      page renders at its resting state.
   ════════════════════════════════════════════════════════════════ */
:root{ --e:cubic-bezier(.22,.61,.36,1); }

/* mouse parallax (±6px, pointer:fine only), inset so the nudge never bares
   an edge inside the hero's overflow:hidden. */
.scene{ inset:-10px; width:auto; height:auto; transform:translate3d(var(--mx,0px),var(--my,0px),0); will-change:transform; }

/* reel: line + hook rise together over the hero's first 60%. Because the line
   runs up past the top of the viewBox, the visible span between the top of
   frame and the hook eye shortens — the line is never seen to detach. */
.anim-reel{ transform:translateY(calc(var(--hero-p,0) * -178px)); will-change:transform; }
.anim-hook{ filter:drop-shadow(0 4px 10px rgba(59,130,246,.35)); }

/* ---------- keyframes ---------- */
@keyframes a-sway{ from{transform:rotate(-.9deg)} to{transform:rotate(.9deg)} }
/* THE 27s CYCLE — three 9s passes on one clock, so a-hookjig and a-swim
   below always land on the same beats.
     pass 1   0% – 33.333%   enter left, approach, nudge, dart off right
     pass 2  33.333% – 66.667%  the same again
     pass 3  66.667% – 100%  enter, approach, and this time TAKE the hook:
             hook + fish rise out of the top together (82.2% → 89%), hold
             1s (89% → 92.7%), hook drops back empty (→ 98.5%), and the
             loop restart puts a fresh fish back at the left edge.
   Both fish and hook are off-screen at 100%, so the instant jump back to
   0% is never visible.

   The pass-3 move is split across two nested groups on the same 27s clock:
   a-catch does every TRANSLATE on .anim-catch, which wraps the line AND the
   hook so they rise as one piece; a-hookjig does every ROTATE on .anim-hook
   inside it, about the eye at 860,288, so the shank flinches without dragging
   the line off the eye. Both sit INSIDE .anim-reel — the reel's scroll
   transform (--hero-p) stays on the outer group, so the three compose instead
   of overwriting one another; the sway on the outermost group runs right
   through all of it. */
@keyframes a-catch{
  /* pass 1 flinch */
  0%,11.333%{transform:translateY(0)}
  12.667%{transform:translateY(3px)}
  14.333%{transform:translateY(0)}
  16%{transform:translateY(1px)}
  18%,44.667%{transform:translateY(0)}
  /* pass 2 flinch */
  46%{transform:translateY(3px)}
  47.667%{transform:translateY(0)}
  49.333%{transform:translateY(1px)}
  51.333%,78%{transform:translateY(0)}
  /* pass 3 — the take, the rise, the hold, the drop back empty */
  80%{transform:translateY(3px)}
  81.5%{transform:translateY(0)}
  82.2%{transform:translateY(4px)}
  83%{transform:translateY(8px)}
  89%,92.7%{transform:translateY(-500px)}
  98.5%,100%{transform:translateY(0)}
}
@keyframes a-hookjig{
  /* pass 1 flinch */
  0%,11.333%{transform:rotate(0deg)}
  12.667%{transform:rotate(9deg)}
  14.333%{transform:rotate(-7deg)}
  16%{transform:rotate(4deg)}
  18%,44.667%{transform:rotate(0deg)}
  /* pass 2 flinch */
  46%{transform:rotate(9deg)}
  47.667%{transform:rotate(-7deg)}
  49.333%{transform:rotate(4deg)}
  51.333%,78%{transform:rotate(0deg)}
  /* pass 3 */
  80%{transform:rotate(9deg)}
  81.5%{transform:rotate(-7deg)}
  82.2%{transform:rotate(-2deg)}
  83%{transform:rotate(-1deg)}
  89%,92.7%{transform:rotate(3deg)}
  98.5%,100%{transform:rotate(0deg)}
}
/* the story, on a loop: enter from the left, cruise up to the hook, nudge it
   twice, think better of it, dart off right, rest off-stage, re-enter — and
   on the third pass, take it and get lifted out of frame.
   Absolute viewBox coordinates — the fish is a direct child of the <svg>, so
   no parent transform shifts them.
   Each lap ends with a teleport back to the left edge, and each teleport is
   covered by opacity: the fish fades out while it is already off-stage right,
   the transform snaps across with opacity:0 held for >1% either side of the
   snap, and it fades back in still off-stage left. Opacity-only keyframes do
   not interrupt the transform interpolation, so the swim path is unchanged.
   The 100% frame is byte-identical to 0% (same transform, same opacity), so
   the loop restart is a no-op rather than a jump. */
@keyframes a-swim{
  /* pass 1 */
  0%{transform:translate(-280px,352px); opacity:0}
  2%{opacity:1}
  5.333%{transform:translate(240px,330px)}
  9.333%{transform:translate(580px,354px)}   12%{transform:translate(742px,344px)}
  13.667%{transform:translate(766px,338px)}  15.333%{transform:translate(730px,356px)}
  16.667%{transform:translate(762px,340px)}  19.333%{transform:translate(1500px,318px)}
  20.333%{opacity:1}                         21.333%{opacity:0}
  23%{transform:translate(1500px,318px)}     23.333%{transform:translate(-280px,352px)}
  25%{opacity:0}
  /* pass 2 */
  33.333%{transform:translate(-280px,352px); opacity:0}
  35.333%{opacity:1}
  38.667%{transform:translate(240px,330px)}
  42.667%{transform:translate(580px,354px)}  45.333%{transform:translate(742px,344px)}
  47%{transform:translate(766px,338px)}      48.667%{transform:translate(730px,356px)}
  50%{transform:translate(762px,340px)}      52.667%{transform:translate(1500px,318px)}
  53.667%{opacity:1}                         54.667%{opacity:0}
  56.333%{transform:translate(1500px,318px)} 56.667%{transform:translate(-280px,352px)}
  58.333%{opacity:0}
  /* pass 3 — hooked. The rotate is only on these frames; a shorter transform
     list is a prefix of a longer one, so CSS pads the earlier frames with
     rotate(0deg) and interpolates component-wise. */
  66.667%{transform:translate(-280px,352px); opacity:0}
  68.667%{opacity:1}
  72%{transform:translate(240px,330px)}
  76%{transform:translate(580px,354px)}      79.333%{transform:translate(742px,344px)}
  81%{transform:translate(766px,338px)}
  82.2%{transform:translate(775px,360px) rotate(-3deg)}
  83%{transform:translate(775px,366px) rotate(-10deg)}
  /* lifted out of frame, held while the hook drops back empty, then reset to
     the pass-1 start behind opacity:0 */
  89%,95%{transform:translate(775px,-142px) rotate(-26deg)}
  93%{opacity:1}                             94%{opacity:0}
  95.333%{transform:translate(-280px,352px)}
  /* opacity has to be restated here: a property missing from the 100% frame
     gets an IMPLICIT keyframe at its underlying value (1), which would fade
     the fish back in over the reset. */
  100%{transform:translate(-280px,352px); opacity:0}
}
@keyframes a-drifta{ 0%{transform:translate(-1500px,0) scale(var(--s,1))} 100%{transform:translate(1500px,0) scale(var(--s,1))} }
@keyframes a-driftb{ 0%{transform:translate(1500px,0) scale(var(--s,1)) scaleX(-1)} 100%{transform:translate(-1500px,0) scale(var(--s,1)) scaleX(-1)} }
@keyframes a-bobber{ from{transform:translateY(-14px)} to{transform:translateY(14px)} }
@keyframes a-rise{ from{opacity:0;transform:translateY(22px)} to{opacity:1;transform:none} }
@keyframes a-settle{ 0%{transform:scale(1.13)} 62%{transform:scale(.985)} 100%{transform:scale(1)} }
/* a loop per card: fade in at rest, travel, press, hold, fade back out.
   --cx0/--cy0 → --cx1/--cy1 are per-card in the markup, aimed at a real thing
   in that screenshot; --dly staggers the six cards against each other. */
@keyframes a-cursor{
  0%{opacity:0;transform:translate(var(--cx0),var(--cy0)) scale(1)}
  6%{opacity:1;transform:translate(var(--cx0),var(--cy0)) scale(1)}
  34%{opacity:1;transform:translate(var(--cx1),var(--cy1)) scale(1)}
  40%{opacity:1;transform:translate(var(--cx1),var(--cy1)) scale(.84)}
  46%{opacity:1;transform:translate(var(--cx1),var(--cy1)) scale(1)}
  76%{opacity:1;transform:translate(var(--cx1),var(--cy1)) scale(1)}
  90%,100%{opacity:0;transform:translate(var(--cx0),var(--cy0)) scale(1)}
}
@keyframes a-ring{ 0%,36%{opacity:0;transform:scale(.2)} 41%{opacity:.6;transform:scale(.55)} 60%,100%{opacity:0;transform:scale(2)} }
/* the screenshot pans down and back on the same 7s clock as its cursor */
@keyframes a-shotpan{ 0%,20%{transform:translateY(0)} 44%,68%{transform:translateY(-7%)} 92%,100%{transform:translateY(0)} }

/* --- gates: nothing below runs without <html class="motion"> --- */
html.motion .anim-sway  { animation:a-sway 5s ease-in-out infinite alternate; transform-origin:860px 0; }
html.motion .anim-catch { animation:a-catch 27s ease-in-out infinite; }
html.motion .anim-hook  { animation:a-hookjig 27s ease-in-out infinite; transform-origin:860px 288px; }
html.motion .anim-swim  { animation:a-swim 27s ease-in-out infinite; }
html.motion .anim-bob   { animation:a-bobber var(--dur,7s) ease-in-out infinite alternate; }
html.motion .anim-drifta{ animation:a-drifta var(--dur,22s) linear infinite; animation-delay:var(--dly,0s); }
html.motion .anim-driftb{ animation:a-driftb var(--dur,28s) linear infinite; animation-delay:var(--dly,0s); }
html.motion .anim-up    { animation:a-rise .6s var(--e) var(--dly,0s) both; }

/* headline: 40ms word stagger, blue word settles 200ms later */
.hero-a h1 .w,.hero-a h1 .settle{ display:inline-block; }
html.motion .hero-a h1 .w{ animation:a-rise .62s var(--e) calc(.18s + var(--wi,0) * 40ms) both; }
html.motion .hero-a h1 .settle{ animation:a-settle .55s var(--e) calc(.38s + var(--wi,0) * 40ms + .2s) both; }

/* ---------- module cards. The cursor, the click ring and the screenshot pan
   all LOOP on all six cards, staggered by each card's --dly, so the section is
   alive whichever card the reader happens to be looking at. Nothing here waits
   on landing.js; .play below only lands the callout pill. ---------- */
.anim-cursor{
  transform:translate(var(--cx1),var(--cy1)) scale(1);
  transform-box:fill-box; transform-origin:0 0;
  filter:drop-shadow(0 3px 6px rgba(15,23,42,.4));
}
.anim-ring{ transform-box:fill-box; transform-origin:center; }
html.motion .anim-cursor{ animation:a-cursor 7s var(--e) var(--dly,0s) infinite; }
html.motion .anim-ring  { animation:a-ring 7s ease-out var(--dly,0s) infinite; }
html.motion .anim-shot  { animation:a-shotpan 7s var(--e) var(--dly,0s) infinite; }
/* card 2's shot is a 1.45x crop anchored at 22% 96%: a transform animation
   REPLACES the property rather than composing with it, so its pan keyframe
   has to carry the scale or the crop would snap back to full frame. */
@keyframes a-shotpan-crop{
  0%,20%{transform:scale(1.45) translateY(0)}
  44%,68%{transform:scale(1.45) translateY(-4%)}
  92%,100%{transform:scale(1.45) translateY(0)}
}
html.motion .mod-shot--crop img.anim-shot{ animation-name:a-shotpan-crop; }

/* callout pills land after the cursor's click, never before it */
html.motion .mod-callout{ opacity:0; transform:translateY(8px); transition:opacity .5s var(--e), transform .5s var(--e); }
html.motion .mod-card.play .mod-callout{ opacity:1; transform:none; transition-delay:2.5s; }

/* ---------- scroll reveal, hidden ONLY when .motion is present. One easing
   family; the per-section curve is the transform each group starts FROM, the
   sequence is the --d landing.js writes. ---------- */
html.motion [data-reveal-a]{
  opacity:0; transform:translate3d(0,16px,0);
  transition:opacity .62s var(--e), transform .62s var(--e);
  transition-delay:var(--d,0ms);
}
html.motion [data-reveal-a].is-in{ opacity:1; transform:none; }
html.motion .proof-cell[data-reveal-a]{ transform:translate3d(-22px,0,0); }
html.motion .trade[data-reveal-a]{ transform:translate3d(0,20px,0) scale(.975); }
html.motion .faq dt[data-reveal-a]{ transform:perspective(700px) rotateX(-18deg) translateY(-6px); transform-origin:top center; }

/* closing CTA: the hook mark reels itself in as the band arrives */
html.motion .mark[data-draw] circle{ stroke-dasharray:57; stroke-dashoffset:57; transition:stroke-dashoffset 1s var(--e); }
html.motion .mark[data-draw] path{ stroke-dasharray:200; stroke-dashoffset:200; transition:stroke-dashoffset 1.5s var(--e) .3s; }
html.motion .mark[data-draw].is-in circle,
html.motion .mark[data-draw].is-in path{ stroke-dashoffset:0; }

/* 2px scroll-progress line on the pill nav's bottom edge (homepage only —
   index is the only page that links this file). */
.nav .nav-in{ position:relative; }
.nav .nav-in::after{
  content:""; position:absolute; left:26px; right:26px; bottom:7px; height:2px;
  border-radius:2px; background:var(--blue); opacity:.85; pointer-events:none;
  transform:scaleX(var(--scroll-p,0)); transform-origin:left center;
}
.nav.open .nav-in::after{ display:none; }

/* ══════════════════════════════════════
   5b. HOMEPAGE SELLING SECTIONS (proof · trades · pricing row ·
       questions · second path). All light, all glass-free where
       the brief calls for a plain surface.
   ══════════════════════════════════════ */

/* --- proof strip: label+value cells split by hairlines, not cards --- */
.proof{
  position:relative; z-index:10; margin-top:-32px;
  background:var(--bg-dim); border-radius:32px 32px 0 0;
  padding:clamp(34px,4vw,48px) 24px clamp(28px,3vw,38px);
}
.proof + .slab{ margin-top:0; border-radius:0; }
.proof-in{
  max-width:var(--max); margin:0 auto;
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
}
.proof-cell{ padding:2px 22px; border-left:1px solid var(--line); text-align:left; }
.proof-cell:first-child{ border-left:0; padding-left:0; }
.proof-cell b{ display:block; font-size:clamp(20px,2.2vw,28px); font-weight:800; letter-spacing:-.02em; color:var(--ink); line-height:1.15; }
.proof-cell span{ display:block; margin-top:6px; font-size:13.5px; font-weight:600; color:var(--muted); text-wrap:pretty; }

/* --- pick your trade: plain tiles, 1px line, hover lift --- */
.trades{ background:var(--bg); padding:clamp(64px,7vw,96px) clamp(20px,4vw,48px); }
.trade-grid{
  max-width:var(--max); margin:clamp(30px,4vw,44px) auto 0;
  display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:12px;
}
.trade{
  display:flex; flex-direction:column; gap:8px;
  background:#fff; border:1px solid var(--line); border-radius:14px;
  padding:16px 15px 15px; color:var(--ink); min-width:0;
  transition:transform .28s cubic-bezier(.22,.61,.36,1), box-shadow .28s cubic-bezier(.22,.61,.36,1), border-color .28s ease;
}
.trade:hover{ transform:translateY(-4px); box-shadow:var(--shadow); border-color:#cbd5e1; color:var(--ink); }
.trade:focus-visible{ outline:2px solid var(--blue); outline-offset:2px; }
.trade svg{ color:var(--blue); flex:none; }
.trade b{ font-size:15px; font-weight:700; letter-spacing:-.01em; }
.trade span{ font-size:12.5px; line-height:1.5; color:var(--muted); text-wrap:pretty; }
.trade--all{ grid-column:span 2; background:#eff6ff; border-color:#bfdbfe; justify-content:center; }
.trade--all b{ color:var(--blue-ink); }

.mod-shot--crop img{
  width:100%; height:100%; object-fit:cover; object-position:22% 96%;
  transform:scale(1.45); transform-origin:22% 96%;
}
.mod-callout{
  position:absolute; z-index:3; left:auto; max-width:min(300px,62%);
  display:inline-flex; align-items:center; gap:8px;
  background:rgba(255,255,255,.94); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border:1px solid var(--glass-brd); box-shadow:var(--shadow);
  border-radius:100px; padding:9px 16px;
  font-size:13px; font-weight:700; line-height:1.35; color:var(--ink); text-wrap:pretty;
}
.mod-callout::before{ content:""; width:7px; height:7px; border-radius:100px; background:var(--blue); flex:none; }
.mod-callout--br{ right:4%; bottom:7%; }
.mod-callout--tr{ right:4%; top:8%; }
.mod-callout--bl{ left:4%; bottom:7%; }

/* card 3: the quote -> invoice strip above the screenshot */
.mod-step{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  margin:0 0 14px; font-size:13px; font-weight:700;
}
.mod-step i{
  font-style:normal; border-radius:100px; padding:6px 14px;
  border:1px solid var(--line); background:#fff; color:var(--muted); white-space:nowrap;
}
.mod-step i.now{ border-color:#bfdbfe; background:#eff6ff; color:var(--blue-ink); }
.mod-step svg{ color:var(--ghost); flex:none; }

/* card 5: a 390-wide phone viewport over a faded desktop shot */
.mod-shot--field{ background:var(--bg-dim); }
.mod-shot--field .desk{ opacity:.3; filter:saturate(.65); }
.mod-phone{
  position:absolute; right:6%; bottom:0; z-index:3;
  width:390px; aspect-ratio:390/844;
  transform-origin:100% 100%; transform:scale(var(--ph,.56));
  background:var(--navy); border-radius:46px; padding:9px;
  box-shadow:0 26px 60px rgba(15,23,42,.34);
}
.mod-phone::after{
  content:""; position:absolute; top:20px; left:50%; transform:translateX(-50%);
  width:112px; height:26px; border-radius:100px; background:var(--navy);
}
.mod-phone img{
  width:100%; height:100%; object-fit:cover; object-position:58% 6%;
  border-radius:38px; background:#fff;
}

/* --- questions: the one question table on the page (objections and FAQ are
   a single [data-faq] block). This slab inherited the pricing teaser's job,
   so it carries its radius and top padding. --- */
.obj{
  position:relative; background:var(--bg-dim); border-radius:32px 32px 0 0;
  padding:clamp(72px,9vw,112px) 24px clamp(72px,8vw,100px);
}
.obj-in{ max-width:var(--max); margin:0 auto; }
/* the thirteen questions are the shared [data-faq] table (assets/faq.css) —
   one component, one behaviour, one schema source. */
.obj-more{ margin:clamp(26px,3vw,34px) 0 0; }
/* the one price line on the homepage — the number comes from pricing.js */
.obj-price{ margin:10px 0 0; font-size:15px; color:var(--ink-soft); text-wrap:pretty; }
.obj-price span[data-price]{ font-weight:800; color:var(--ink); }

/* --- second conversion path: slim band before the closing CTA --- */
.path-band{
  max-width:var(--max); margin:0 auto; padding:26px 28px;
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px 10px;
  font-size:15.5px; font-weight:600; color:var(--ink-soft); text-align:center;
}
.path-band a{ color:var(--blue-ink); font-weight:700; text-decoration:underline; text-underline-offset:3px; }
.path-band a:hover{ color:var(--blue-dark); }

/* ══════════════════════════════════════
   6. RESPONSIVE
   ══════════════════════════════════════ */
@media (max-width:1099px){
  .trade-grid{ grid-template-columns:repeat(4,minmax(0,1fr)); }
  .mod-phone{ --ph:.44; right:4%; }
}

@media (max-width:899px){
  .scene{ transform:scale(.62); opacity:.8; }
  .mod-grid{ grid-template-columns:minmax(0,1fr); gap:56px; }
  .mod-rail-wrap{ display:none; }
  .mod-list{ gap:32px; padding-bottom:0; }
  .mod-card{ position:static; transform:none !important; }
  .mod-shot{ max-height:none; }
  .hero-a{ padding:130px 20px 80px; }
  .cta-slab{ margin:0 12px 12px; }
  .proof-in{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:22px 0; }
  .proof-cell:nth-child(odd){ border-left:0; padding-left:0; }
  /* the phone is the point of card 5 on a phone: drop the desktop shot and
     centre the device, which needs a bottom-CENTRE origin for the scale. */
  .mod-shot--field{ aspect-ratio:4/3; }
  .mod-shot--field .desk{ display:none; }
  .mod-phone{ --ph:.42; right:50%; transform-origin:50% 100%; transform:translateX(50%) scale(var(--ph)); }
  .mod-callout{ max-width:min(280px,84%); font-size:12px; padding:8px 13px; }
}

@media (max-width:639px){
  .trade-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .proof-cell{ padding:2px 14px; }
  .mod-shot--field{ aspect-ratio:3/4; }
}

/* Below ~480px the two hero pills stop fitting on one nowrap line: stack
   them full-width rather than let flex:0 0 auto force overflow. */
@media (max-width:480px){
  .hero-a .cta-row{ flex-direction:column; align-items:stretch; }
  .hero-a .btn-pill{ flex:1 1 auto; min-width:0; white-space:normal; }
}
