/* =====================================================================
   Xtract-style animations v3 — measured from the original Framer
   template (excited-building-034592.framer.app/services)
   Part 1: page reveals (nav drop, hero, directional cards, chips)
   Part 2: in-card animated mockups w/ real brand assets + looping motion
   Load AFTER styles.css.
   ===================================================================== */

/* ============================ PART 1 — REVEALS ============================ */

@keyframes xtNavDrop {
  from { opacity: 0; transform: translateY(-150px); }
  to   { opacity: 1; transform: translateY(0); }
}
.nav {
  opacity: 0;
  animation: xtNavDrop .8s cubic-bezier(.22, 1, .36, 1) 1.2s forwards;
}

@keyframes xtHeroUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: none; }
}
.page-hero h1,
.page-hero .lead {
  opacity: 0;
  animation: xtHeroUp .9s cubic-bezier(.22, 1, .36, 1) .25s forwards;
}
.page-hero .lead { animation-delay: .4s; }

.reveal.rv-l-dn { transform: translate(-40px,  40px); }
.reveal.rv-l-up { transform: translate(-40px, -40px); }
.reveal.rv-r-dn { transform: translate( 40px,  40px); }
.reveal.rv-r-up { transform: translate( 40px, -40px); }

.reveal.rv-l-dn, .reveal.rv-l-up,
.reveal.rv-r-dn, .reveal.rv-r-up {
  transition: opacity .9s cubic-bezier(.22, 1, .36, 1),
              transform .9s cubic-bezier(.22, 1, .36, 1);
}
.reveal.in { opacity: 1; transform: none; }

.svc .svc__num {
  display: inline-block;
  opacity: 0;
  transform: scale(.65);
  transition: opacity .55s ease .2s,
              transform .55s cubic-bezier(.34, 1.4, .64, 1) .2s;
}
.svc.in .svc__num { opacity: 1; transform: none; }

.svc .chip {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s ease, transform .5s cubic-bezier(.22, 1, .36, 1);
}
.svc.in .chip { opacity: 1; transform: none; }
.svc.in .chip:nth-child(1) { transition-delay: .55s; }
.svc.in .chip:nth-child(2) { transition-delay: .67s; }
.svc.in .chip:nth-child(3) { transition-delay: .79s; }
.svc.in .chip:nth-child(4) { transition-delay: .91s; }

/* ===================== PART 2 — IN-CARD MOCKUPS ===================== */

/* ---- shared shell ---- */
.mock {
  position: relative;
  background: rgba(13, 13, 13, .85);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 12px;
  padding: 14px;
  margin: 14px 0 16px;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.35;
}
.mock::after {
  content: "";
  position: absolute; inset: auto -30% -55% -30%;
  height: 90%;
  background: radial-gradient(ellipse at center,
              rgba(10, 232, 240, .10), transparent 65%);
  pointer-events: none;
}

/* soft light sweep across each panel */
@keyframes mSweep {
  0%       { transform: translateX(-120%); }
  55%,100% { transform: translateX(120%); }
}
.mock::before {
  content: "";
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 45%;
  background: linear-gradient(100deg, transparent,
              rgba(255,255,255,.05) 45%, rgba(10,232,240,.07) 55%, transparent);
  transform: translateX(-120%);
  pointer-events: none;
  z-index: 1;
}
.svc.in .mock::before { animation: mSweep 7s ease-in-out 1.2s infinite; }

/* staggered inner reveal */
.mock .stag { opacity: 0; transform: translateY(9px); transition: opacity .5s ease, transform .5s cubic-bezier(.22,1,.36,1); }
.svc.in .mock .stag { opacity: 1; transform: none; }
.svc.in .mock .stag:nth-child(1) { transition-delay: .30s; }
.svc.in .mock .stag:nth-child(2) { transition-delay: .42s; }
.svc.in .mock .stag:nth-child(3) { transition-delay: .54s; }
.svc.in .mock .stag:nth-child(4) { transition-delay: .66s; }
.svc.in .mock .stag:nth-child(5) { transition-delay: .78s; }
.svc.in .mock .stag:nth-child(6) { transition-delay: .90s; }
.svc.in .mock .stag:nth-child(7) { transition-delay: 1.02s; }
.svc.in .mock .stag:nth-child(8) { transition-delay: 1.14s; }

/* ---- status dots ---- */
@keyframes mDotPulse {
  0%,100% { opacity:.5; transform:scale(.8); box-shadow:0 0 0 0 currentColor; }
  50%     { opacity:1;  transform:scale(1.1); box-shadow:0 0 7px 0 currentColor; }
}
.dot { width:8px; height:8px; border-radius:50%; flex:none; margin-left:auto;
       animation:mDotPulse 2.2s ease-in-out infinite; animation-delay:var(--d,0s); }
.dot--g { background:#2ecc71; color:#2ecc71; }
.dot--r { background:#ff5a5f; color:#ff5a5f; animation-duration:1.1s; }
.dot--b { background:#0AE8F0; color:#0AE8F0; }

/* ---- chat mockup ---- */
.m-chat .chatrow {
  position: relative;
  display:flex; align-items:center; gap:10px;
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.06);
  border-radius:10px; padding:8px 10px; margin-bottom:8px;
}
@keyframes mRowLive {
  0%, 72%, 100% { background:rgba(255,255,255,.04); border-color:rgba(255,255,255,.06); transform:translateX(0); }
  10%, 24%      { background:rgba(10,232,240,.09); border-color:rgba(10,232,240,.32); transform:translateX(4px); }
}
.svc.in .m-chat .chatrow { animation: mRowLive 6.4s ease-in-out infinite; animation-delay: var(--d,0s); }

.m-chat .av {
  width:26px; height:26px; border-radius:50%; flex:none;
  display:flex; align-items:center; justify-content:center;
  font-weight:600; font-size:12px; color:#000;
  object-fit:cover; background:rgba(255,255,255,.08);
}
.av--p { background:#e6b8ff; } .av--b { background:#9ad0ff; }
.av--o { background:#ffcf9a; } .av--t { background:#81DAE2; }
.m-chat .cb { display:flex; flex-direction:column; min-width:0; }
.m-chat .cb b { color:#fff; font-weight:600; font-size:12.5px; }
.m-chat .cb span { color:#9a9a9a; font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.m-chat .ver { margin-left:auto; color:#2ecc71; font-size:11px; font-style:normal; flex:none; }

.m-chat .typing { display:flex; gap:5px; padding:6px 4px 0; }
@keyframes mType { 0%,60%,100% { transform:translateY(0); opacity:.35;} 30% { transform:translateY(-4px); opacity:1;} }
.m-chat .typing i {
  width:6px; height:6px; border-radius:50%; background:#0AE8F0;
  animation:mType 1.2s ease-in-out infinite;
}
.m-chat .typing i:nth-child(2) { animation-delay:.15s; }
.m-chat .typing i:nth-child(3) { animation-delay:.3s; }

/* ---- task tracker ---- */
.m-track .trow {
  display:flex; align-items:center; gap:10px;
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.06);
  border-radius:10px; padding:9px 11px; margin-bottom:8px;
  transition: opacity .5s ease, border-color .5s ease;
}
@keyframes mStage {
  0%, 100%  { opacity:.45; border-color:rgba(255,255,255,.06); }
  8%, 30%   { opacity:1;   border-color:rgba(129,218,226,.35); }
  45%       { opacity:.75; border-color:rgba(255,255,255,.06); }
}
.svc.in .m-track .trow { animation: mStage 6s ease-in-out infinite; animation-delay: var(--d,0s); }
.m-track .tico { flex:none; font-size:14px; }
.m-track .tb { flex:1; min-width:0; }
.m-track .tb b { display:block; color:#fff; font-weight:600; font-size:12.5px; margin-bottom:5px; }
.m-track .tbar { display:block; height:3px; border-radius:2px; background:rgba(255,255,255,.09); overflow:hidden; }
.m-track .tbar i { display:block; height:100%; width:0; background:#81DAE2; border-radius:2px; }
@keyframes mFill { 0% { width:0; } 25%,100% { width:100%; } }
.svc.in .m-track .tbar i { animation: mFill 6s ease-in-out infinite; animation-delay: var(--d,0s); }
@keyframes mBarLive { 0%,100% { width:18%; } 50% { width:82%; } }
.m-track .tbar--live i { background:#f5a623; animation:mBarLive 2.4s ease-in-out infinite !important; }
.m-track .badge {
  flex:none; width:20px; height:20px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:11px; font-style:normal; color:#000; background:#2ecc71;
}
@keyframes mSpin { to { transform:rotate(360deg); } }
.m-track .badge--live {
  background:transparent; border:2px solid #f5a623; border-top-color:transparent;
  animation:mSpin 1s linear infinite;
}

/* ---- phone waveform ---- */
.m-wave { display:flex; align-items:center; justify-content:center; gap:12px; padding:22px 14px; }
.m-wave .phone {
  width:52px; height:52px; border-radius:50%; flex:none;
  background:rgba(255,255,255,.07); border:1px solid rgba(255,255,255,.1);
  display:flex; align-items:center; justify-content:center; font-size:20px;
  animation: mRing 2.6s ease-in-out infinite;
}
@keyframes mRing {
  0%,100% { box-shadow:0 0 0 0 rgba(129,218,226,.35); }
  50%     { box-shadow:0 0 0 9px rgba(129,218,226,0); }
}
.m-wave .eq { display:flex; align-items:center; gap:4px; }
@keyframes mEq { 0%,100% { transform:scaleY(.22); opacity:.55; } 50% { transform:scaleY(1); opacity:1; } }
.m-wave .eq i {
  width:3px; height:26px; border-radius:2px; background:#81DAE2;
  transform-origin:center; animation:mEq .95s ease-in-out infinite;
  animation-delay:var(--d,0s);
}

/* ---- app panel ---- */
.m-panel .phead {
  display:flex; align-items:center; justify-content:space-between;
  padding-bottom:9px; margin-bottom:9px;
  border-bottom:1px solid rgba(255,255,255,.07);
  color:#fff; font-weight:600; font-size:13px;
}
.m-panel .phead > span:first-child { display:flex; align-items:center; gap:7px; }
/* brand logo in the panel header — keep aspect ratio (this was the Meta bug) */
.m-panel .ilogo-inline { height:15px; width:auto; max-width:62px; object-fit:contain; display:block; }
.m-panel .lights { display:flex; gap:5px; }
.m-panel .lights i { width:7px; height:7px; border-radius:50%; }
.m-panel .l--r { background:#ff5a5f; } .m-panel .l--y { background:#f5a623; } .m-panel .l--g { background:#2ecc71; }
.m-panel .psearch {
  display:flex; align-items:center; gap:8px;
  color:#cccccc; font-size:12.5px;
  background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.06);
  border-radius:8px; padding:7px 10px; margin-bottom:9px;
}
@keyframes mCaret { 0%,45% { opacity:1;} 50%,100% { opacity:0;} }
.m-panel .caret {
  display:inline-block; width:1.5px; height:12px; background:#0AE8F0;
  margin-left:2px; vertical-align:middle; animation:mCaret 1s steps(1) infinite;
}
.m-panel .prow {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  color:#cccccc; font-size:12.5px; padding:5px 2px;
}
.m-panel .prow--dim { opacity:.45; }
.m-panel .prow > span:first-child { display:flex; align-items:center; gap:8px; min-width:0; }
/* small brand icons inside rows */
.m-panel .rico { width:16px; height:16px; flex:none; object-fit:contain; display:block; }

.m-panel .tog {
  position:relative; flex:none; width:26px; height:14px; border-radius:8px;
  background:rgba(255,255,255,.16); transition:background .35s;
}
.m-panel .tog::after {
  content:""; position:absolute; top:2px; left:2px;
  width:10px; height:10px; border-radius:50%; background:#fff;
  transition:left .35s cubic-bezier(.34,1.5,.64,1);
}
.m-panel .tog--on { background:#0AE8F0; }
.m-panel .tog--on::after { left:14px; background:#000; }
@keyframes mFlip     { 0%,18%,88%,100% { background:rgba(255,255,255,.16);} 28%,80% { background:#0AE8F0;} }
@keyframes mFlipKnob { 0%,18%,88%,100% { left:2px; background:#fff;}        28%,80% { left:14px; background:#000;} }
.svc.in .m-panel .tog--flip        { animation:mFlip 7s ease-in-out infinite;     animation-delay:var(--d,0s); }
.svc.in .m-panel .tog--flip::after { animation:mFlipKnob 7s ease-in-out infinite; animation-delay:var(--d,0s); }

/* ---- dashboard ---- */
.m-dash .dstats { display:flex; gap:14px; margin-bottom:10px; }
.m-dash .dstats > div { min-width:0; }
.m-dash .dstats small { display:block; color:#9a9a9a; font-size:9.5px; letter-spacing:.6px; }
.m-dash .dstats b { color:#fff; font-size:15.5px; font-weight:600; white-space:nowrap; }
.m-dash .dchart { width:100%; height:58px; display:block; margin-bottom:10px; }
.m-dash .dchart polygon { transform-origin:bottom; transform:scaleY(0); transition:transform 1.1s cubic-bezier(.22,1,.36,1) .5s; }
.svc.in .m-dash .dchart polygon { transform:scaleY(1); }
.m-dash .dchart .dline {
  fill:none; stroke:#0AE8F0; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:420; stroke-dashoffset:420;
  transition: stroke-dashoffset 1.6s cubic-bezier(.22,1,.36,1) .55s;
}
.svc.in .m-dash .dchart .dline { stroke-dashoffset:0; }

.m-dash .dlistwrap { max-height:118px; overflow:hidden; position:relative; }
.m-dash .dlistwrap::after {
  content:""; position:absolute; inset:0;
  background:linear-gradient(rgba(13,13,13,0) 55%, rgba(13,13,13,.95));
  pointer-events:none;
}
@keyframes mScrollY { from { transform:translateY(0); } to { transform:translateY(-50%); } }
.svc.in .m-dash .dlist--loop { animation:mScrollY 16s linear infinite; }
.m-dash .drow {
  display:grid; grid-template-columns:1fr auto 64px;
  align-items:center; gap:8px;
  color:#cccccc; font-size:12px; padding:5px 2px;
}
.m-dash .drow b { color:#fff; font-weight:600; font-size:12px; }
.m-dash .dbar { height:3px; border-radius:2px; background:rgba(255,255,255,.09); overflow:hidden; }
.m-dash .dbar i { display:block; height:100%; width:0; background:#81DAE2; border-radius:2px;
                  transition: width 1.1s cubic-bezier(.22,1,.36,1); }
.svc.in .m-dash .dbar i { width:var(--w,60%); }
.svc.in .m-dash .drow:nth-child(1) .dbar i { transition-delay:.55s; }
.svc.in .m-dash .drow:nth-child(2) .dbar i { transition-delay:.68s; }
.svc.in .m-dash .drow:nth-child(3) .dbar i { transition-delay:.81s; }
.svc.in .m-dash .drow:nth-child(4) .dbar i { transition-delay:.94s; }
.svc.in .m-dash .drow:nth-child(5) .dbar i { transition-delay:1.07s; }
.m-dash .dlist--loop .dbar i { width:var(--w,60%); transition:none; }

/* ---- glowing CTA button ---- */
@keyframes mGlow {
  0%,100% { box-shadow:0 0 12px rgba(10,232,240,.10); border-color:rgba(129,218,226,.28); }
  50%     { box-shadow:0 0 26px rgba(10,232,240,.36); border-color:rgba(129,218,226,.6); }
}
@keyframes mArrow { 0%,100% { transform:translateX(0); } 50% { transform:translateX(4px); } }
.mock .ctabtn {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  width:100%; text-align:left;
  background:rgba(255,255,255,.05);
  border:1px solid rgba(129,218,226,.35);
  border-radius:10px; padding:11px 13px;
  color:#fff; font:inherit; font-weight:600; font-size:13px;
  text-decoration:none; cursor:pointer;
  animation:mGlow 2.6s ease-in-out infinite;
  transition: background .25s ease, transform .25s ease;
  position:relative; z-index:2;
}
.mock a.ctabtn:hover { background:rgba(10,232,240,.12); transform:translateY(-1px); }
.mock .ctabtn b { color:#0AE8F0; font-weight:700; display:inline-block; animation:mArrow 1.8s ease-in-out infinite; }
.m-cta { padding:26px 14px; }

/* ---- review remover ---- */
.m-review .rrows { margin-top:10px; }
@keyframes mStrike {
  0%,18%   { opacity:.8;  transform:translateX(0); }
  34%,52%  { opacity:.5;  transform:translateX(0); }
  70%,100% { opacity:0;   transform:translateX(28px); }
}
@keyframes mStrikeLine { 0%,20% { width:0; } 40%,100% { width:100%; } }
.m-review .rrow {
  position:relative; display:inline-block;
  color:#9a9a9a; font-size:12.5px; padding:5px 2px;
  animation:mStrike 5.4s ease-in-out infinite;
  animation-delay:var(--d,0s);
}
.m-review .rrow::after {
  content:""; position:absolute; left:0; top:52%; height:1px; width:0;
  background:#ff5a5f;
  animation: mStrikeLine 5.4s ease-in-out infinite;
  animation-delay:var(--d,0s);
}
.m-review .rrow .rstar { color:#f5a623; margin-right:6px; }

/* ---- integrations ---- */
.m-int .irow {
  display:flex; align-items:center; gap:10px;
  background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.06);
  border-radius:10px; padding:8px 10px; margin-bottom:8px;
}
@keyframes mConnect {
  0%,100%  { border-color:rgba(255,255,255,.06); background:rgba(255,255,255,.04); }
  12%,26%  { border-color:rgba(129,218,226,.4); background:rgba(10,232,240,.07); }
}
.svc.in .m-int .irow { animation: mConnect 7.5s ease-in-out infinite; animation-delay: var(--d,0s); }
.m-int .ilogo {
  width:26px; height:26px; border-radius:8px; flex:none;
  display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:12.5px; color:#000; background:var(--c,#81DAE2);
  overflow:hidden;
}
.m-int .ilogo--img { background:#fff; padding:4px; }
.m-int .ilogo--plain { background:transparent; padding:0; }
.m-int .ilogo img { width:100%; height:100%; object-fit:contain; display:block; }
.m-int .ib { display:flex; flex-direction:column; min-width:0; }
.m-int .ib b { color:#fff; font-weight:600; font-size:12.5px; }
.m-int .ib span { color:#9a9a9a; font-size:11.5px; }

/* ---- restock + report ---- */
.m-report .stockrow {
  display:flex; justify-content:center; gap:12px;
  font-size:22px; padding:8px 0 14px;
}
@keyframes mBob { 0%,100% { transform:translateY(0);} 50% { transform:translateY(-6px);} }
.m-report .stockrow span { animation:mBob 2.4s ease-in-out infinite; animation-delay:var(--d,0s); }
.m-report .repline { color:#9a9a9a; font-size:12px; padding-top:9px; }
.m-report .repline .rstar { color:#f5a623; margin-right:5px; }

/* ---- accessibility ---- */
@media (prefers-reduced-motion: reduce) {
  .nav, .page-hero h1, .page-hero .lead { opacity: 1; animation: none; }
  .reveal, .svc .chip, .svc .svc__num, .mock .stag {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
  .mock *, .mock::before, .mock .ctabtn { animation: none !important; }
  .m-track .tbar i, .m-dash .dbar i { width: var(--w,100%) !important; transition:none; }
  .m-dash .dchart polygon { transform:none; }
  .m-dash .dchart .dline { stroke-dashoffset:0; }
  .m-review .rrow { opacity:.8 !important; transform:none !important; }
}

/* =====================================================================
   PART 3 — HOME PAGE (index.html)
   Page-load sequence measured from the Framer home page 27 Jul 2026 via
   #__framer__appearAnimationsContent. Reuses the Part 2 keyframe library.
   ===================================================================== */

/* ---- straight-up variants for odd-column grids (see xtract-animate.js) ---- */
.reveal.rv-up { transform: translateY(-40px); }
.reveal.rv-dn { transform: translateY( 40px); }
.reveal.rv-up, .reveal.rv-dn {
  transition: opacity .9s cubic-bezier(.22, 1, .36, 1),
              transform .9s cubic-bezier(.22, 1, .36, 1);
}

/* ============ page-load sequence ============
   Framer measured values:
     0.6s  background glow    tween,  duration 2.0
     1.2s  nav (from y -150)  spring, damping 60 / stiffness 320  (no bounce)
     1.5s  hero badge         spring, bounce 0.2, duration 0.4    (snaps)
     1.7s  hero headline      spring, bounce 0.2, duration 1.2    (drifts)
   The nav rule already lives in Part 1. bounce:0.2 springs overshoot slightly,
   so they use a different curve from the nav's overdamped one.               */

@keyframes xtFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes xtPop {
  from { opacity: 0; transform: translateY(9px) scale(.965); }
  to   { opacity: 1; transform: none; }
}

.hero .orb,
.hero .stars {
  opacity: 0;
  animation: xtFadeIn 2s linear .6s forwards;
}

.hero .badge-duo {
  opacity: 0;
  animation: xtPop .4s cubic-bezier(.34, 1.26, .64, 1) 1.5s forwards;
}

.hero h1,
.hero .lead,
.hero .hero__actions,
.hero .hero__trust {
  opacity: 0;
  animation: xtHeroUp 1.2s cubic-bezier(.34, 1.26, .64, 1) 1.7s forwards;
}
.hero .lead          { animation-delay: 1.82s; }
.hero .hero__actions { animation-delay: 1.94s; }
.hero .hero__trust   { animation-delay: 2.06s; }

/* ---- trust bar (real platform marks) ---- */
.hero__trust    { display: block; }
.trust__label   { display: block; color: #9a9a9a; font-size: 13.5px; margin-bottom: 13px; }
.trustbar {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: center;
  gap: 11px 26px;
}
.trustbar span {
  display: inline-flex; align-items: center; gap: 7px;
  color: #9a9a9a; font-size: 13px; font-weight: 500;
  opacity: 0;
  animation: xtPop .55s cubic-bezier(.22, 1, .36, 1) forwards;
  animation-delay: calc(2.25s + var(--i, 0) * .085s);
}
.trustbar img {
  height: 16px; width: auto; max-width: 24px;
  object-fit: contain;
  filter: grayscale(1); opacity: .7;
  transition: filter .35s ease, opacity .35s ease;
}
.trustbar span:hover img { filter: none; opacity: 1; }

/* ============ home in-card mockups ============
   styles.css already sizes .mock on the home page; Part 2's .mock rule would
   otherwise re-pad it and shift the bento layout, so restore the originals. */
.bento__card .mock,
.step .mock {
  padding: 20px;
  margin: 0;
  border-radius: var(--r-inner, 12px);
}

/* stagger — Part 2 defines the base .mock .stag state, this adds the
   home containers to the "revealed" side of it */
.bento.in .mock .stag,
.step.in  .mock .stag { opacity: 1; transform: none; }

.bento.in .mock .stag:nth-child(1), .step.in .mock .stag:nth-child(1) { transition-delay: .30s; }
.bento.in .mock .stag:nth-child(2), .step.in .mock .stag:nth-child(2) { transition-delay: .42s; }
.bento.in .mock .stag:nth-child(3), .step.in .mock .stag:nth-child(3) { transition-delay: .54s; }
.bento.in .mock .stag:nth-child(4), .step.in .mock .stag:nth-child(4) { transition-delay: .66s; }
.bento.in .mock .stag:nth-child(5), .step.in .mock .stag:nth-child(5) { transition-delay: .78s; }
.bento.in .mock .stag:nth-child(6), .step.in .mock .stag:nth-child(6) { transition-delay: .90s; }
.bento.in .mock .stag:nth-child(7), .step.in .mock .stag:nth-child(7) { transition-delay: 1.02s; }
.bento.in .mock .stag:nth-child(8), .step.in .mock .stag:nth-child(8) { transition-delay: 1.14s; }

/* chips inside bento copy fade up in sequence, matching .svc .chip */
.bento .chip {
  opacity: 0; transform: translateY(10px);
  transition: opacity .5s ease, transform .5s cubic-bezier(.22, 1, .36, 1);
}
.bento.in .chip { opacity: 1; transform: none; }
.bento.in .chip:nth-child(1) { transition-delay: .55s; }
.bento.in .chip:nth-child(2) { transition-delay: .67s; }
.bento.in .chip:nth-child(3) { transition-delay: .79s; }

/* ---- 01 live inbox: rows light up in sequence ---- */
.bento.in .m-inbox .mock__row {
  animation: mRowLive 7.5s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

/* ---- 02 ask-us: blinking caret + orbit spinner ---- */
.m-ask .caret {
  display: inline-block; width: 1.5px; height: 12px;
  background: #0AE8F0; margin-left: 3px; vertical-align: middle;
  animation: mCaret 1s steps(1) infinite;
}
.m-ask .spin { animation: mSpin 8s linear infinite; }
.m-ask .mock__chips span {
  transition: border-color .3s ease, color .3s ease;
}
.bento.in .m-ask .mock__input {
  animation: mGlow 4.5s ease-in-out infinite;
}

/* ---- 03 booking campaign: funnel rows + verified tags ---- */
.bento.in .m-campaign .mock__row {
  animation: mRowLive 6.6s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
@keyframes mTagPop {
  0%, 6%   { opacity: 0; transform: scale(.75); }
  14%, 78% { opacity: 1; transform: none; }
  100%     { opacity: 1; transform: none; }
}
.bento.in .m-campaign .mock__tag {
  animation: mTagPop 6.6s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
.m-campaign .ota { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 14px; }
.m-campaign .ota span { display: inline-flex; align-items: center; gap: 5px; }
.m-campaign .ota img  { height: 13px; width: auto; max-width: 18px; object-fit: contain; }

/* ---- 04 owner dashboard: spinning task, pulsing day ---- */
.m-owner .tick--spin { display: inline-block; animation: mSpin 2.6s linear infinite; }
/* single-day pulse removed — superseded by mDayCycle in Part 3b,
   which matches Framer's travelling highlight. */
.bento.in .m-owner .mock__row {
  animation: mRowLive 7.8s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

/* ---- process steps: checkmarks land in sequence ---- */
.step .mock .tick {
  opacity: 0; transform: scale(.5);
  transition: opacity .4s ease, transform .4s cubic-bezier(.34, 1.4, .64, 1);
}
.step.in .mock .tick { opacity: 1; transform: none; }
.step.in .mock .mock__row:nth-child(2) .tick { transition-delay: .55s; }
.step.in .mock .mock__row:nth-child(3) .tick { transition-delay: .70s; }
.step.in .mock .mock__row:nth-child(4) .tick { transition-delay: .85s; }
.step.in .mock .mock__row:nth-child(5) .tick { transition-delay: 1.00s; }
.step.in .mock .mock__row:nth-child(6) .tick { transition-delay: 1.15s; }
.step .mock .caret {
  display: inline-block; width: 1.5px; height: 11px;
  background: #0AE8F0; margin-left: 3px; vertical-align: middle;
  animation: mCaret 1s steps(1) infinite;
}

/* ---- comparison table: rows stagger in ---- */
.compare__card li {
  opacity: 0; transform: translateX(-10px);
  transition: opacity .45s ease, transform .45s cubic-bezier(.22, 1, .36, 1);
}
.compare__card--pro li { transform: translateX(10px); }
.compare__card.in li { opacity: 1; transform: none; }
.compare__card.in li:nth-child(1) { transition-delay: .30s; }
.compare__card.in li:nth-child(2) { transition-delay: .40s; }
.compare__card.in li:nth-child(3) { transition-delay: .50s; }
.compare__card.in li:nth-child(4) { transition-delay: .60s; }
.compare__card.in li:nth-child(5) { transition-delay: .70s; }
.compare__card.in li:nth-child(6) { transition-delay: .80s; }

/* ---- pricing: the "Popular" tag pops after its card lands ---- */
.price .price__pop {
  opacity: 0; transform: scale(.7);
  transition: opacity .5s ease .45s, transform .5s cubic-bezier(.34, 1.4, .64, 1) .45s;
}
.price.in .price__pop { opacity: 1; transform: none; }

/* ---- reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  .hero .orb, .hero .stars, .hero .badge-duo,
  .hero h1, .hero .lead, .hero .hero__actions, .hero .hero__trust,
  .trustbar span {
    opacity: 1 !important; animation: none !important; transform: none !important;
  }
  .bento .chip, .compare__card li, .price .price__pop, .step .mock .tick {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
  .m-ask .spin, .m-owner .tick--spin { animation: none !important; }
}

/* =====================================================================
   PART 3b — behaviours measured off Framer's Framer-Motion runtime
   (27 Jul 2026, by sampling computed styles over time).

   Framer drives all of these in JavaScript, so these are CSS reproductions
   matched on shape and period rather than identical output. Measured values
   are noted per block.
   ===================================================================== */

/* ---- rotating concentric rings ----
   Framer: two circles (49px + 71px), matrix[0] traces 1 -> 0 -> -1 -> 0,
   i.e. a full rotation every ~4.5s, linear. Inner ring counter-rotates. */
.m-ask .spin { position: relative; animation: mSpin 4.5s linear infinite; }
.m-ask .spin::after {
  content: ""; position: absolute; inset: 22%;
  border-radius: 50%;
  border: 1.5px solid transparent;
  border-top-color: rgba(129, 218, 226, .55);
  border-left-color: rgba(10, 232, 240, .25);
  animation: mSpin 3.1s linear infinite reverse;
}

/* ---- width-driven typewriter, three cycling messages ----
   Framer reveals the message by animating `width` (not by clipping
   characters), and cycles between several messages. 3 slots x 4.5s. */
.m-ask .typer {
  position: relative; display: block;
  flex: 1 1 auto; min-width: 0;
  height: 17px; overflow: hidden;
}
.m-ask .typer b {
  position: absolute; left: 0; top: 0;
  font-weight: 400; white-space: nowrap; overflow: hidden;
  width: 0; max-width: 100%; opacity: 0;
  animation: mTypeSlot 13.5s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * 4.5s);
}
.m-ask .typer b::after {              /* caret rides the growing edge */
  content: ""; position: absolute; right: 0; top: 2px;
  width: 1.5px; height: 12px; background: #0AE8F0;
  animation: mCaret 1s steps(1) infinite;
}
@keyframes mTypeSlot {
  0%       { width: 0;    opacity: 1; }
  11%      { width: 100%; opacity: 1; }
  26%      { width: 100%; opacity: 1; }
  32%      { width: 0;    opacity: 1; }
  33%,100% { width: 0;    opacity: 0; }
}

/* ---- week strip: days take the highlight in turn ----
   Framer cycles the background across several days (Mo / Th / Su all
   observed changing), rather than holding one fixed day. */
@keyframes mDayCycle {
  0%,  7%  { background: #81DAE2; border-color: #81DAE2; color: #000; }
  15%,100% { background: #131316; border-color: rgba(255,255,255,.08); color: #9a9a9a; }
}
.bento.in .m-owner .mock__week span,
.bento.in .m-owner .mock__week span.on {
  animation: mDayCycle 7s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

/* ---- progress bar under the live task ----
   Framer: a 290x1 bar animating transform + width. */
.m-owner .pbar {
  height: 3px; margin: 9px 0 2px;
  background: rgba(255, 255, 255, .07);
  border-radius: 3px; overflow: hidden;
}
.m-owner .pbar i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #81DAE2, #0AE8F0);
  border-radius: 3px;
}
.bento.in .m-owner .pbar i { animation: mBarGrow 7s ease-in-out infinite; }
@keyframes mBarGrow {
  0%       { width: 0;    opacity: 1; }
  72%      { width: 100%; opacity: 1; }
  88%,100% { width: 100%; opacity: .45; }
}

/* ---- status dot shifts colour through the pipeline ----
   Framer's 9x9 dots change background-color, they do not merely pulse. */
@keyframes mDotShift {
  0%,  30% { background: #f5a623; box-shadow: 0 0 7px rgba(245, 166, 35, .55); }
  40%, 68% { background: #0AE8F0; box-shadow: 0 0 7px rgba(10, 232, 240, .55); }
  78%,100% { background: #2ecc71; box-shadow: 0 0 7px rgba(46, 204, 113, .55); }
}
.dot--shift {
  width: 8px; height: 8px; border-radius: 50%; flex: none; margin-left: auto;
  animation: mDotShift 6.6s ease-in-out infinite;
}

/* =====================================================================
   PART 3c — ABOUT / CONTACT
   Framer About has ZERO CSS animations and only three appear entries:
     nav          y -150, spring damping 60 / stiffness 320, delay 1.2s
     "About Us"   spring bounce 0.2, duration 1.2, delay 0.3s
     hero block   y 80 -> 0, TWEEN, duration 2.0, delay 0.4s
   Part 1 already covers .page-hero h1 / .lead at .25s / .4s, which is
   within a rounding error of the badge timing. The 2s tween below is the
   one piece that was missing.
   ===================================================================== */
.page-hero .orb,
.page-hero .stars {
  opacity: 0;
  animation: xtFadeIn 2s linear .4s forwards;
}

/* about: values + team grids, contact: info cards */
.team__card, .values .why__card { will-change: transform, opacity; }

@media (prefers-reduced-motion: reduce) {
  .m-ask .spin, .m-ask .spin::after,
  .m-ask .typer b, .m-ask .typer b::after,
  .m-owner .pbar i, .dot--shift,
  .bento.in .m-owner .mock__week span,
  .page-hero .orb, .page-hero .stars {
    animation: none !important;
  }
  .m-ask .typer b { opacity: 1 !important; width: auto !important; }
  .m-ask .typer b:not(:last-child) { display: none; }
  .m-owner .pbar i { width: 100% !important; }
  .page-hero .orb, .page-hero .stars { opacity: 1 !important; }
}

/* =====================================================================
   PART 3d — process-step mockups + client logo marquee
   Rebuilt to match the Framer originals (screenshots 27 Jul 2026).
   ===================================================================== */

/* ---------- Step 1: radar dial + audit checklist ---------- */
.m-audit .audit { display: grid; grid-template-columns: 1fr 1.15fr; gap: 14px; align-items: center; }
.m-audit .audit__dial { text-align: center; }
.m-audit .radar {
  position: relative; display: block;
  width: 104px; height: 104px; margin: 2px auto 10px;
  border-radius: 50%; overflow: hidden;
  border: 1px solid rgba(255,255,255,.07);
  background: radial-gradient(circle, rgba(10,232,240,.06), transparent 68%);
}
.m-audit .radar::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(10,232,240,.5), rgba(10,232,240,.02) 58deg, transparent 92deg);
  animation: mSpin 2.6s linear infinite;
}
.m-audit .radar::after {
  content: ""; position: absolute; inset: 30%; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.09);
  background: rgba(0,0,0,.55);
}
.m-audit .audit__dial em {
  display: block; font-style: normal;
  font-size: 11.5px; color: #9a9a9a; letter-spacing: -.2px;
}
.m-audit .audit__dial .caret {
  display: inline-block; width: 1.5px; height: 10px; background: #0AE8F0;
  margin-left: 3px; vertical-align: middle; animation: mCaret 1s steps(1) infinite;
}
.m-audit .audit__list { display: flex; flex-direction: column; gap: 7px; }
.m-audit .arow {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: #cccccc;
  background: #131316; border: 1px solid rgba(255,255,255,.08);
  border-radius: 8px; padding: 8px 10px;
}
.m-audit .arow i { font-style: normal; color: #81DAE2; font-size: 12px; }
.step.in .m-audit .arow { animation: mConnect 6.5s ease-in-out infinite; animation-delay: var(--d,0s); }

/* ---------- Step 2: editor window ---------- */
.m-editor .win {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 8px 8px 0 0;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08);
  border-bottom: 0;
}
.m-editor .win__nav { color: #6f6f74; font-size: 12px; letter-spacing: 3px; }
.m-editor .win__tab { flex: 1; height: 8px; border-radius: 4px; background: rgba(255,255,255,.09); }
.m-editor .win__ctl { display: flex; gap: 6px; }
.m-editor .win__ctl i { width: 8px; height: 8px; border-radius: 2px; background: rgba(255,255,255,.18); }
.m-editor .edit {
  display: flex; align-items: stretch;
  border: 1px solid rgba(255,255,255,.08); border-radius: 0 0 8px 8px;
  background: rgba(0,0,0,.5); overflow: hidden;
}
.m-editor .rail {
  display: flex; flex-direction: column; gap: 12px;
  padding: 11px 9px; color: #6f6f74; font-size: 13px;
  border-right: 1px solid rgba(255,255,255,.07);
}
.m-editor .rail i { font-style: normal; }
.m-editor .codewrap { flex: 1; height: 132px; overflow: hidden; padding: 9px 11px; min-width: 0; }
.step.in .m-editor .code { animation: mScrollY 22s linear infinite; }
.m-editor .code p {
  margin: 0 0 3px; font-size: 10.5px; line-height: 1.45;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: #0AE8F0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.m-editor .code p.cdim { color: #4d8f95; }
.m-editor .code p.chi  { color: #cfeff2; font-weight: 600; }

/* ---------- Step 3: our team <-> your property ---------- */
.m-handover .handover {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 8px;
  padding: 16px 4px 18px;
}
.m-handover .hnode { display: flex; flex-direction: column; align-items: center; gap: 9px; }
.m-handover .hnode b { font-size: 11.5px; color: #9a9a9a; font-weight: 500; }
.m-handover .horb {
  width: 46px; height: 46px; border-radius: 50%;
  background: radial-gradient(circle at 34% 32%, #0AE8F0, rgba(10,232,240,.12) 62%, transparent 74%);
  box-shadow: 0 0 16px rgba(10,232,240,.35);
  animation: mSpin 4.5s linear infinite;
}
.m-handover .hlogo {
  width: 46px; height: 46px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  background: #fff; overflow: hidden;
}
.m-handover .hlogo img { width: 26px; height: 26px; object-fit: contain; }
.m-handover .hwires { display: flex; flex-direction: column; gap: 6px; width: 76px; }
.m-handover .hwires i {
  height: 1px; width: 100%;
  background: linear-gradient(90deg, transparent, rgba(129,218,226,.85), transparent);
  background-size: 55% 100%; background-repeat: no-repeat;
}
.step.in .m-handover .hwires i {
  animation: mWire 2.2s linear infinite;
  animation-delay: var(--d, 0s);
}
@keyframes mWire {
  from { background-position: -60% 0; }
  to   { background-position: 160% 0; }
}

/* ---------- Step 4: trial rows ---------- */
.m-trial .ricon {
  flex: none; width: 26px; height: 26px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.08);
  color: #81DAE2; font-size: 12px;
}
.m-trial .mock__row > div { flex: 1; min-width: 0; }
.step.in .m-trial .mock__row { animation: mStage 6.6s ease-in-out infinite; animation-delay: var(--d,0s); }

/* ---------- About: client logo marquee ----------
   Framer: <ul> of 32 items, translating left at a constant ~25.1 px/s,
   linear, no easing. 8 unique logos in circles. */
.trustloop__label {
  text-align: center; color: #cccccc;
  font-size: 14.5px; font-weight: 500; margin: 0 0 22px;
}
.trustloop {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.trustloop__track {
  display: flex; align-items: center; gap: 26px;
  width: max-content; margin: 0; padding: 0; list-style: none;
  animation: mMarquee 62s linear infinite;
}
.trustloop__track li {
  flex: none; width: 72px; height: 72px; border-radius: 50%;
  overflow: hidden; background: #131316;
  border: 1px solid rgba(255,255,255,.09);
}
.trustloop__track li img { width: 100%; height: 100%; object-fit: cover; display: block; }
@keyframes mMarquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.trustloop:hover .trustloop__track { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .m-audit .radar::before, .m-audit .arow, .m-audit .caret,
  .m-editor .code, .m-handover .horb, .m-handover .hwires i,
  .m-trial .mock__row, .trustloop__track {
    animation: none !important;
  }
}

@media (max-width: 620px) {
  .m-audit .audit { grid-template-columns: 1fr; }
  .m-audit .radar { width: 84px; height: 84px; }
  .trustloop__track li { width: 58px; height: 58px; }
}

/* ---------- containment fixes ----------
   Grid and flex items default to min-width:auto, so the nowrap monospace
   lines in the step-2 editor (and the absolutely-positioned typewriter
   slots) set a min-content width the container refused to shrink below.
   At 420px that pushed the document to 697px wide. */
.steps .step,
.m-editor .edit,
.m-editor .codewrap,
.m-audit .audit,
.m-audit .audit > *,
.m-handover .handover,
.m-handover .hnode { min-width: 0; }

.step .mock,
.bento__card .mock { max-width: 100%; }

.m-editor .code p { max-width: 100%; }

.m-ask .mock__input { min-width: 0; }
.m-ask .typer { flex: 1 1 0; width: 0; }
.m-ask .typer b { max-width: 100%; }

/* On narrow viewports the ±40px horizontal entrance briefly pushes cards
   past the viewport edge, which shows up as a horizontal scrollbar while
   the reveal is in flight. Drop to a purely vertical entrance below 720px. */
@media (max-width: 720px) {
  .reveal.rv-l-dn, .reveal.rv-r-dn,
  .reveal.rv-l-up, .reveal.rv-r-up,
  .reveal.rv-dn,   .reveal.rv-up { transform: translateY(34px); }
}

/* The nav drop animation makes .nav a containing block, which re-parents the
   off-canvas mobile menu and makes its 420px panel count toward document
   width (a 28px horizontal scrollbar on phones). The drop is imperceptible
   on a burger menu anyway, so skip it there. */
@media (max-width: 720px) {
  .nav { opacity: 1; animation: none; }
}

/* ---- About: team photos ----
   Framer renders these as 283x320 tiles with an 8px radius and object-fit:
   cover, not circles. Aspect-ratio keeps that proportion at any card width. */
.team__photo {
  width: 100%;
  aspect-ratio: 283 / 320;
  border-radius: 8px;
  overflow: hidden;
  background: #131316;
  margin-bottom: 16px;
}
.team__photo img {
  width: 100%; height: 100%;
  display: block;
  object-fit: cover;
  object-position: center top;   /* faces sit high in both portraits */
  transition: transform .6s cubic-bezier(.22, 1, .36, 1);
}
.team__card:hover .team__photo img { transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
  .team__card:hover .team__photo img { transform: none; }
}

/* Two-person team grid. Was an inline style, which mobile rules could not
   override without !important; as a class it collapses cleanly to one column
   so the portraits stay a usable size on phones. */
.team--duo { grid-template-columns: repeat(2, 1fr); max-width: 660px; }
@media (max-width: 620px) {
  .team--duo { grid-template-columns: 1fr; max-width: 320px; }
  .team--duo .team__card { padding: 20px; }
}

/* Three-person team grid. styles.css collapses .team straight to one column
   at 980px, which is far too early for three portraits — this steps it
   3 -> 2 -> 1 instead, and centres the odd card left over in the 2-up row. */
.team--trio { grid-template-columns: repeat(3, 1fr); max-width: 1000px; }
@media (max-width: 980px) {
  .team--trio { grid-template-columns: repeat(2, 1fr); max-width: 660px; }
  .team--trio .team__card:last-child { grid-column: 1 / -1; max-width: 317px; margin: 0 auto; }
}
@media (max-width: 620px) {
  .team--trio { grid-template-columns: 1fr; max-width: 320px; }
  .team--trio .team__card { padding: 20px; }
  .team--trio .team__card:last-child { max-width: none; }
}
/* Long role titles (e.g. "Director of Growth & Operations") should not wrap
   awkwardly tight against the name. */
.team__card small { display: block; margin-top: 4px; line-height: 1.35; }
