/* Page-level motion: the connective tissue between the section
   illustrations. Paired with page.js, which adds every am-* class below.

   Rules this file keeps:
   - It moves things with the INDIVIDUAL transform properties (translate,
     rotate, scale). Those compose with the `transform` that site.css and
     site.js already animate (.reveal, the hero rise), so nothing fights.
   - Only transform-family, opacity, clip-path and a little filter move.
   - Anything that loops is paused until page.js marks it .am-live (on screen).
   - Under prefers-reduced-motion everything rests on its final frame. */

:root {
  --am-ease: cubic-bezier(0.23, 1, 0.32, 1);
  --am-draw: cubic-bezier(0.33, 1, 0.68, 1);
  --am-sine: cubic-bezier(0.37, 0, 0.63, 1);
}

/* ---------- Keyframes shared by the load-time entrances ---------- */
@keyframes am-rise { from { opacity: 0; translate: 0 12px; } to { opacity: 1; translate: none; } }
@keyframes am-wipe {
  from { clip-path: inset(-0.3em 100% -0.3em -0.3em); filter: blur(3px); translate: 0 6px; }
  to { clip-path: inset(-0.3em); filter: none; translate: none; }
}
@keyframes am-wipe-rtl {
  from { clip-path: inset(-0.3em -0.3em -0.3em 100%); filter: blur(3px); translate: 0 6px; }
  to { clip-path: inset(-0.3em); filter: none; translate: none; }
}

/* ---------- a. Section headings: a wipe from the inline-start side ----------
   The heading's parent (.section-header) still rises via site.js; the h2
   inside wipes open and sharpens, so the two never touch one property. */
.am-h {
  clip-path: inset(-0.3em 100% -0.3em -0.3em); filter: blur(3px); translate: 0 6px;
  transition: clip-path 1000ms var(--am-ease), filter 700ms var(--am-ease), translate 800ms var(--am-ease);
}
[dir="rtl"] .am-h { clip-path: inset(-0.3em -0.3em -0.3em 100%); }
.am-h.am-in { clip-path: inset(-0.3em); filter: none; translate: none; }

/* Page titles (pricing / contact / refunds) are on screen at load, so they
   play from CSS at first paint — nothing is hidden by script, nothing blinks. */
main > .section:first-child .section-header > *,
main > .page-header:first-child .section-header > * { animation: am-rise 700ms var(--am-ease) backwards; }
main > .section:first-child .section-header > :nth-child(1),
main > .page-header:first-child .section-header > :nth-child(1) { animation-delay: 40ms; }
main > .section:first-child .section-header > :nth-child(2),
main > .page-header:first-child .section-header > :nth-child(2) { animation-delay: 110ms; }
main > .section:first-child .section-header > :nth-child(n+3),
main > .page-header:first-child .section-header > :nth-child(n+3) { animation-delay: 220ms; }
main > .section:first-child .section-header > h1,
main > .page-header:first-child .section-header > h1 { animation-name: am-wipe; animation-duration: 1000ms; }
[dir="rtl"] main > .section:first-child .section-header > h1,
[dir="rtl"] main > .page-header:first-child .section-header > h1 { animation-name: am-wipe-rtl; }

/* Contact / refunds body: what is on screen at load rises in from CSS; what
   is below the fold is taken over by page.js (.am-rv / .am-h). */
.page-header + .container > .prose > :not(.am-rv):not(.am-h) { animation: am-rise 700ms var(--am-ease) 260ms backwards; }
.page-header + .container > .prose > :nth-child(2):not(.am-rv):not(.am-h) { animation-delay: 320ms; }
.page-header + .container > .prose > :nth-child(3):not(.am-rv):not(.am-h) { animation-delay: 380ms; }
.page-header + .container > .prose > :nth-child(n+4):not(.am-rv):not(.am-h) { animation-delay: 440ms; }

/* ---------- Reveal once (things site.js does not reveal) ---------- */
.am-rv {
  opacity: 0; translate: 0 14px;
  transition: opacity 650ms var(--am-ease) var(--am-d, 0ms), translate 650ms var(--am-ease) var(--am-d, 0ms);
}
.am-rv.am-in { opacity: 1; translate: none; }

/* ---------- b. Icons draw themselves in ---------- */
.am-draw > * { stroke-dasharray: var(--am-len) var(--am-len); stroke-dashoffset: var(--am-len); }
.am-draw { opacity: 0; }
.am-draw.am-drawn { opacity: 1; transition: opacity 200ms ease; }
.am-draw.am-drawn > * { stroke-dashoffset: 0; transition: stroke-dashoffset 1100ms var(--am-draw); }
.am-draw.am-drawn > :nth-child(2) { transition-delay: 90ms; }
.am-draw.am-drawn > :nth-child(3) { transition-delay: 180ms; }

/* How it works: a ring closes around each step number, 1 → 2 → 3. */
.am-ring-host { position: relative; }
.ficon > .am-ring {
  position: absolute; inset: -8px; width: calc(100% + 16px); height: calc(100% + 16px); max-width: none;
  fill: none; stroke: var(--brand-400); stroke-width: 1.5; stroke-linecap: round;
  rotate: -90deg; pointer-events: none;
}
[dir="rtl"] .ficon > .am-ring { rotate: 90deg; scale: -1 1; }

/* Feature cards: a card surface materialises under the pointer. */
@media (hover: hover) and (pointer: fine) {
  .am-lift {
    position: relative; isolation: isolate;
    /* site.js's reveal values are repeated here, because one transition list
       has to carry both the reveal and the lift. */
    transition: opacity 600ms var(--am-ease), transform 600ms var(--am-ease), translate 200ms var(--am-ease);
  }
  .am-lift::after {
    content: ""; position: absolute; inset: -20px -16px; z-index: -1; pointer-events: none;
    border-radius: var(--radius-2xl); background: #fff;
    box-shadow: inset 0 0 0 1px var(--gray-200), var(--shadow-lg);
    opacity: 0; scale: 0.97;
    transition: opacity 200ms ease, scale 200ms var(--am-ease);
  }
  .am-lift:hover {
    translate: 0 -4px;
    transition: opacity 600ms var(--am-ease), transform 600ms var(--am-ease), translate 300ms var(--am-ease);
  }
  .am-lift:hover::after { opacity: 1; scale: 1; transition: opacity 250ms ease, scale 300ms var(--am-ease); }

  /* Contact card: the same lift. Shadow is a layer that fades, not a
     box-shadow that repaints. */
  .email-card { position: relative; isolation: isolate; transition: translate 200ms var(--am-ease); }
  .email-card::after {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    box-shadow: var(--shadow-lg); opacity: 0; transition: opacity 200ms ease;
  }
  .email-card:hover { translate: 0 -3px; transition-duration: 300ms; }
  .email-card:hover::after { opacity: 1; transition-duration: 300ms; }
}

/* ---------- c. Hero: an aurora behind the mockup, and a gentle tilt ----------
   Lit Paper (v5.112): toned down to a breath of light under the paper — the
   accent is a light from above, never a glow cloud. */
.am-stage { position: relative; perspective: 1600px; }
.am-stage > .mockup { transform-origin: 50% 100%; }
.am-aurora {
  position: absolute; inset-inline: -10%; top: 0; height: 100%; z-index: -1; pointer-events: none;
  /* Soft at both ends: the hero clips its overflow, so a glow that ran to
     its edge would end in a hard line. The blobs stay inside this box. */
  -webkit-mask-image: linear-gradient(transparent, #000 24%, #000 58%, transparent 97%);
  mask-image: linear-gradient(transparent, #000 24%, #000 58%, transparent 97%);
  /* The glow belongs to the mockup: it arrives with it (site.css rises the
     mockup at 340ms), never as a lone blue cloud before it. Opacity only. */
  animation: am-glow-in 1400ms var(--am-ease) 420ms backwards;
}
@keyframes am-glow-in { from { opacity: 0; } }
.am-aurora > i {
  position: absolute; border-radius: 50%;
  animation: am-float 24s var(--am-sine) infinite alternate paused;
}
.am-aurora.am-live > i { animation-play-state: running; }
.am-aurora > i:nth-child(1) {
  inset-inline-start: 4%; top: 6%; width: 52%; aspect-ratio: 1.35;
  background: radial-gradient(closest-side, rgba(83, 177, 253, .16), rgba(83, 177, 253, 0));
  --am-x: 9%; --am-y: 7%;
}
.am-aurora > i:nth-child(2) {
  inset-inline-end: 2%; top: 16%; width: 50%; aspect-ratio: 1.2;
  background: radial-gradient(closest-side, rgba(21, 112, 239, .10), rgba(21, 112, 239, 0));
  animation-duration: 29s; animation-delay: -11s; --am-x: -8%; --am-y: -5%;
}
.am-aurora > i:nth-child(3) {
  inset-inline-start: 22%; bottom: 6%; width: 56%; aspect-ratio: 2.1;
  background: radial-gradient(closest-side, rgba(178, 221, 255, .38), rgba(178, 221, 255, 0));
  animation-duration: 33s; animation-delay: -19s; --am-x: 7%; --am-y: -8%;
}
@keyframes am-float { from { translate: 0 0; scale: 1; } to { translate: var(--am-x) var(--am-y); scale: 1.14; } }

/* ---------- d. Pricing ---------- */
/* pricing.html: the plans are on screen at load, so they stagger in from CSS.
   `:not(.reveal)` hands any card site.js hid (below the fold) back to site.js. */
@keyframes am-plan { from { opacity: 0; translate: 0 24px; scale: 0.98; } to { opacity: 1; translate: none; scale: none; } }
main > .section:first-child .plans > .plan:not(.reveal) { animation: am-plan 800ms var(--am-ease) 240ms backwards; }
main > .section:first-child .plans > .plan:nth-child(2):not(.reveal) { animation-delay: 300ms; }
main > .section:first-child .plans > .plan:nth-child(3):not(.reveal) { animation-delay: 360ms; }
main > .section:first-child .plans > .plan:nth-child(4):not(.reveal) { animation-delay: 420ms; }

/* The recommended plan: a highlight travels its border. A rotating conic
   gradient, masked to the 2px ring the card already draws. */
.am-shine-host { position: relative; }
.am-shine {
  position: absolute; inset: 0; z-index: 1; padding: 2px; border-radius: inherit; overflow: hidden; pointer-events: none;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity 1200ms ease;
}
.am-shine.am-live { opacity: 1; }
.am-shine > i {
  position: absolute; top: 50%; left: 50%; width: 200%; aspect-ratio: 1; translate: -50% -50%;
  /* brand-400 → a pale brand-200 core → brand-400: the ring looks lit,
     never broken (a white core read as a gap on the white page). */
  background: conic-gradient(from 0turn,
    rgba(83, 177, 253, 0) 0turn, rgba(83, 177, 253, 0) .62turn,
    rgba(83, 177, 253, .95) .72turn, #B2DDFF .78turn, rgba(83, 177, 253, .95) .84turn,
    rgba(83, 177, 253, 0) .93turn);
  animation: am-spin 7s linear infinite paused;
}
.am-shine.am-live > i { animation-play-state: running; }
[dir="rtl"] .am-shine { scale: -1 1; }
@keyframes am-spin { to { rotate: 1turn; } }
/* ---------- e. Final CTA: chord chips drift, rings breathe from the button ---------- */
.am-cta { position: relative; isolation: isolate; overflow: hidden; }
.am-cta-deco { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
/* page.js lays .am-rings exactly over the primary button and sets --am-sx/-sy
   so each ring ends ~9px past the button's edge. The layer sits behind the
   content, so only the part outside the button ever shows. */
.am-rings { position: absolute; left: 50%; top: 70%; width: 0; height: 0; }
.am-rings > i {
  position: absolute; inset: 0; border-radius: var(--radius-md);
  box-shadow: 0 0 0 1.5px var(--brand-300), 0 0 12px 2px rgba(83, 177, 253, .22);
  opacity: 0; animation: am-ring 3.6s var(--am-ease) infinite paused;
}
/* On the lit CTA card the rings are paper-white lines, not a blue glow. */
.cta .am-rings > i { border-radius: var(--r-md, 10px); box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .55); }
.am-rings > i:nth-child(2) { animation-delay: 1.8s; }
.am-live.am-rings-on .am-rings > i { animation-play-state: running; }
@keyframes am-ring {
  0% { opacity: 0; scale: 1; }
  12% { opacity: .85; }
  100% { opacity: 0; scale: var(--am-sx, 1.1) var(--am-sy, 1.35); }
}

.am-chip {
  position: absolute; display: inline-flex; align-items: center;
  padding: 3px 9px; border-radius: var(--radius-full); background: #fff;
  box-shadow: inset 0 0 0 1px var(--gray-200), var(--shadow-xs);
  color: var(--brand-700); font: 700 12px/18px var(--font); letter-spacing: 0;
  direction: ltr; unicode-bidi: isolate; white-space: nowrap;
  opacity: 0; scale: 0.92;
  transition: opacity 900ms var(--am-ease), scale 900ms var(--am-ease);
  animation: am-drift var(--am-t, 10s) var(--am-sine) var(--am-dl, 0s) infinite alternate paused;
}
.am-live .am-chip { animation-play-state: running; }
.am-chip.am-on { opacity: var(--am-o, 1); scale: 1; }
@keyframes am-drift { from { translate: 0 0; } to { translate: var(--am-dx, 6px) var(--am-dy, 4px); } }
/* Depth: nearer chips are larger, more opaque and move faster. */
.am-near { --am-o: 1; --am-t: 8s; box-shadow: inset 0 0 0 1px var(--gray-200), var(--shadow-md); }
.am-mid { --am-o: .78; --am-t: 11s; }
.am-far { --am-o: .5; --am-t: 14s; color: var(--brand-600); box-shadow: inset 0 0 0 1px var(--gray-200); }
@media (min-width: 768px) {
  .am-chip { padding: 4px 11px; font-size: 13px; }
  .am-near { font-size: 15px; line-height: 22px; padding: 5px 13px; }
  .am-far { font-size: 12px; padding: 3px 9px; }
}

/* Phones: four chips in the padding bands above and below the text. */
.am-p1 { top: 8px; inset-inline-start: 6%; --am-dx: 10px; --am-dy: 2px; }
.am-p2 { top: 7px; inset-inline-end: 8%; --am-dx: -9px; --am-dy: 3px; --am-dl: -3s; }
.am-p3 { bottom: 8px; inset-inline-start: 13%; --am-dx: 8px; --am-dy: -2px; --am-dl: -6s; }
.am-p4 { bottom: 9px; inset-inline-end: 5%; --am-dx: -10px; --am-dy: -3px; --am-dl: -2s; }
.am-p5, .am-p6, .am-p7, .am-p8 { display: none; }
@media (min-width: 768px) {
  .am-p5, .am-p6, .am-p7, .am-p8 { display: inline-flex; }
  .am-p1 { top: 18px; inset-inline-start: 9%; --am-dx: 12px; --am-dy: 6px; }
  .am-p2 { top: auto; bottom: 18px; inset-inline-end: 12%; --am-dx: -10px; --am-dy: -5px; }
  .am-p3 { bottom: auto; top: 40%; inset-inline-start: 2.2%; --am-dx: 3px; --am-dy: 14px; }
  .am-p4 { bottom: auto; top: 14px; inset-inline-end: 22%; --am-dx: -12px; --am-dy: 5px; }
  .am-p5 { bottom: 14px; inset-inline-start: 25%; --am-dx: 11px; --am-dy: -4px; --am-dl: -5s; }
  .am-p6 { top: 44%; inset-inline-end: 2.4%; --am-dx: -3px; --am-dy: 12px; --am-dl: -4s; }
  .am-p7 { top: 20px; inset-inline-start: 36%; --am-dx: -9px; --am-dy: 4px; --am-dl: -7s; }
  .am-p8 { bottom: 22px; inset-inline-end: 36%; --am-dx: 10px; --am-dy: -4px; --am-dl: -9s; }
}
@media (min-width: 1200px) {
  .am-p3 { inset-inline-start: 7%; --am-dx: 10px; }
  .am-p6 { inset-inline-end: 7%; --am-dx: -10px; }
}

/* ---------- f. FAQ: plus turns into minus; the answer eases open ---------- */
.am-faq summary::after { content: none; display: none; }
.am-plus { flex: none; width: 24px; height: 24px; margin-top: 2px; color: var(--gray-400); }
.am-plus .am-plus-v { transform-box: view-box; transform-origin: 12px 12px; transition: transform 300ms var(--am-ease); }
.am-faq details[open]:not(.am-closing) .am-plus-v { transform: rotate(90deg); }

/* ---------- Reduced motion: every piece rests on its final frame ---------- */
@media (prefers-reduced-motion: reduce) {
  .am-h, .am-rv { clip-path: none; filter: none; translate: none; opacity: 1; transition: none; }
  main > .section:first-child .section-header > *,
  main > .page-header:first-child .section-header > *,
  .page-header + .container > .prose > *,
  main > .section:first-child .plans > .plan { animation: none; }
  .am-aurora, .am-aurora > i, .am-shine > i, .am-chip { animation: none; }
  .am-shine, .am-rings { display: none; }
  .am-chip { scale: none; transition: none; }
  .am-lift, .am-lift::after, .email-card, .email-card::after, .am-plus .am-plus-v { transition: none; }
}

/* ---------- Print: nothing waits for a scroll that never comes ----------
   Printed straight after load (a refund policy, a price list), everything
   below the fold is still in its hidden reveal state and would print blank.
   site.js's .reveal has the same trap, so it is released here too. */
@media print {
  .am-h, .am-rv, .am-draw, .reveal {
    opacity: 1 !important; clip-path: none !important; filter: none !important;
    translate: none !important; transform: none !important; transition: none !important;
  }
  .am-draw > * { stroke-dashoffset: 0 !important; transition: none !important; }
}
