/* Motion is decorative. Content stays visible without JavaScript or observers. */
@keyframes hero-enter {
  from { opacity: .4; translate: 0 10px; }
  to { opacity: 1; translate: 0 0; }
}

/* Each ribbon is a static external image. Its paths and fade rasterize once;
   only the HTML image's compositing layer moves. A width cap keeps ultrawide
   screens from creating ever-larger animated surfaces. */
.hero .hero-mesh {
  inset: 0;
  overflow: hidden;
  contain: paint;
  opacity: 1;
  mask-image: none;
  -webkit-mask-image: none;
}
.hero-mesh .mesh-layer {
  position: absolute;
  display: block;
  left: 50%;
  top: 50%;
  width: min(2400px, max(1000px, calc(100% + 160px)));
  max-width: none;
  height: auto;
  translate: -50% -50%;
  pointer-events: none;
}
@keyframes mesh-front {
  0% { transform: translate3d(-68px, 25px, 0); }
  50% { transform: translate3d(2px, -26px, 0); }
  100% { transform: translate3d(68px, 16px, 0); }
}
@keyframes mesh-back {
  0% { transform: translate3d(60px, -24px, 0); }
  50% { transform: translate3d(-4px, 24px, 0); }
  100% { transform: translate3d(-62px, -8px, 0); }
}
@keyframes mesh-rise {
  from { transform: translate3d(-44px, 20px, 0); }
  to { transform: translate3d(44px, -24px, 0); }
}
.mesh-front { animation: mesh-front 12s ease-in-out infinite alternate; }
.mesh-back { opacity: .75; animation: mesh-back 15s ease-in-out -6s infinite alternate; }
.mesh-rise { opacity: .7; animation: mesh-rise 17s ease-in-out -10s infinite alternate; }
.hero[data-motion-running='true'] .mesh-layer { will-change: transform; }
.hero[data-motion-running='false'] .mesh-layer { animation-play-state: paused; will-change: auto; }
.hero-copy { animation: hero-enter 800ms var(--ease) backwards; }
.hero-service-nav { animation: hero-enter 800ms var(--ease) 120ms backwards; }
/* A small, feathered reading surface protects the paragraph while the
   surrounding mesh remains bright and moving. This layer never animates. */
.hero-sub { position: relative; }
.hero-sub::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -80px -100px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--bg) 85%, transparent) 100px,
    color-mix(in srgb, var(--bg) 85%, transparent) calc(100% - 100px), transparent);
  mask-image: linear-gradient(0deg, transparent, var(--bg) 80px,
    var(--bg) calc(100% - 80px), transparent);
}

/* Reveals begin when observed, not when the page loads. Unobserved content
   remains visible, including when an observer or script fails. Individual
   translate keeps the card hover transform independent of the entrance. */
@keyframes content-enter {
  from { opacity: .3; translate: 0 18px; }
  to { opacity: 1; translate: 0 0; }
}
.reveal-ready,
.reveal-ready.is-visible { opacity: 1; translate: 0 0; }
.reveal-ready { animation: none; }
.reveal-ready.is-visible {
  animation: content-enter 700ms var(--ease) var(--entry-delay, 0ms) backwards;
}
.service-card:nth-child(2),
.service-card:nth-child(4),
.reason:nth-child(even) { --entry-delay: 90ms; }
.step:nth-child(2), .price-card:nth-child(2) { --entry-delay: 130ms; }
.step:nth-child(3), .price-card:nth-child(3) { --entry-delay: 260ms; }
.reveal-ready:focus-within { animation: none; opacity: 1; translate: 0 0; }

/* One quiet line sweep and a number lift give each step its own beat. */
@keyframes accent-draw {
  from { opacity: .35; transform: scaleX(.08); }
  to { opacity: 1; transform: scaleX(1); }
}
@keyframes number-enter {
  from { opacity: .35; translate: 0 5px; }
  to { opacity: 1; translate: 0 0; }
}
.step .mono::after,
.price-card .mono::after {
  content: '';
  display: block;
  width: 32px;
  height: 1px;
  margin-top: 15px;
  background: currentColor;
  transform-origin: left;
}
.step.reveal-ready.is-visible .mono::after,
.price-card.reveal-ready.is-visible .mono::after {
  animation: accent-draw 850ms var(--ease) calc(var(--entry-delay, 0ms) + 140ms) backwards;
}
.step.reveal-ready.is-visible .mono,
.price-card.reveal-ready.is-visible .price-number {
  animation: number-enter 650ms var(--ease) calc(var(--entry-delay, 0ms) + 80ms) backwards;
}

@media (max-width: 800px) {
  .hero .hero-mesh { opacity: .7; }
  .mesh-front { animation-duration: 14s; }
  .mesh-back { animation-duration: 17s; }
  .mesh-rise { animation-duration: 19s; }
  .service-card:nth-child(n),
  .reason:nth-child(n),
  .step:nth-child(n),
  .price-card:nth-child(n) { --entry-delay: 0ms; }
  .step .mono::after { width: 24px; margin-top: 12px; }
}

/* Dense desktop displays keep two moving ribbons, with a bounded texture
   size. Screen width never disables the requested background animation. */
@media (min-width: 1400px) and (min-resolution: 1.5dppx) {
  .hero .mesh-rise { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-mesh .mesh-layer { animation: none; transform: none; will-change: auto; }
  .hero-copy,
  .hero-service-nav,
  .reveal-ready,
  .reveal-ready.is-visible,
  .step .mono,
  .price-card .price-number,
  .step .mono::after,
  .price-card .mono::after { animation: none !important; opacity: 1; translate: none; transform: none; }
}

/* Motion marks three moments: the hero, light Services and the dark statement.
   The other sections use flat surfaces and keep their content entrances. */
#services, .statement { overflow: clip; }
.section-atmosphere {
  position: absolute;
  z-index: -1;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  contain: paint;
  mask-image: linear-gradient(transparent, var(--bg) 12%, var(--bg) 86%, transparent);
}
.statement > .section-atmosphere { background: var(--surface); }
.atmosphere-layer {
  position: absolute;
  display: block;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100% 100%;
  animation-play-state: paused;
}
.atmosphere-waves .atmosphere-layer {
  width: min(1800px, max(1100px, calc(100% + 220px)));
  aspect-ratio: 1600 / 680;
}
.atmosphere-waves .atmosphere-front {
  background-image: url('/img/bg-hero-reference-mesh.svg');
  opacity: .85;
  animation: section-wave-front 14s ease-in-out -4s infinite paused;
}
.atmosphere-waves .atmosphere-back {
  background-image: url('/img/mesh-back.svg');
  opacity: .65;
  animation: section-wave-back 18s ease-in-out -11s infinite paused;
}
@keyframes section-wave-front {
  0%, 100% { transform: translate3d(-62px, 18px, 0) rotate(-4deg) scaleY(.91); }
  35% { transform: translate3d(40px, -32px, 0) rotate(1deg) scaleY(1.08); }
  70% { transform: translate3d(62px, 26px, 0) rotate(4deg) scaleY(.97); }
}
@keyframes section-wave-back {
  0%, 100% { transform: translate3d(48px, -28px, 0) rotate(3deg) scaleY(1.06); }
  40% { transform: translate3d(-50px, 24px, 0) rotate(-3deg) scaleY(.9); }
  75% { transform: translate3d(8px, 36px, 0) rotate(-1deg) scaleY(1.03); }
}
/* Tool and guide pages: the same ribbons as a band behind the heading, faded
   out before the article's light panels so body text never sits on a wave. */
.tool-main > .page { position: relative; isolation: isolate; overflow: clip; }
.tool-main > .page > .page-atmosphere {
  inset: 0 0 auto;
  height: 900px;
  mask-image: linear-gradient(transparent, var(--bg) 8%, var(--bg) 52%, transparent 92%);
}
.page-atmosphere .atmosphere-front { top: 46%; left: 66%; opacity: .7; }
.page-atmosphere .atmosphere-back { top: 34%; left: 40%; opacity: .45; }
.statement .atmosphere-front { top: 70%; left: 45%; }
.statement .atmosphere-back { top: 30%; left: 54%; }
.statement .atmosphere-waves::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 550px 180px at 50% 52%, color-mix(in srgb, var(--surface) 82%, transparent), transparent);
}
/* Reading veils share their local surface color; their edges never cover text. */
#services .section-head, .statement .wrap { position: relative; isolation: isolate; }
#services .section-head p { position: relative; }
#services .section-head p::before, .statement .wrap::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -40px -50px;
  pointer-events: none;
  background: color-mix(in srgb, var(--reading-bg, var(--bg)) 82%, transparent);
  mask-image: linear-gradient(transparent, var(--bg) 40px, var(--bg) calc(100% - 40px), transparent),
    linear-gradient(90deg, transparent, var(--bg) 50px, var(--bg) calc(100% - 50px), transparent);
  mask-composite: intersect;
}
.statement .wrap { --reading-bg: var(--surface); }
.atmosphere-orbits .atmosphere-layer {
  width: 1100px;
  height: 900px;
  background-image: url('/img/section-orbits-paper.svg?v=paper-1');
}
.atmosphere-orbits .atmosphere-front {
  left: calc(50% + 560px);
  top: 16%;
  opacity: .64;
  animation: orbit-drift 25s ease-in-out -7s infinite paused;
}
.atmosphere-orbits .atmosphere-back {
  left: calc(50% - 670px);
  top: 73%;
  opacity: .4;
  animation: orbit-return 30s ease-in-out -17s infinite paused;
}
#services .atmosphere-front { opacity: .92; }
#services .atmosphere-back { opacity: .62; }
@keyframes orbit-drift {
  0%, 100% { transform: translate3d(-18px, -25px, 0) rotate(-12deg); }
  50% { transform: translate3d(24px, 25px, 0) rotate(8deg); }
}
@keyframes orbit-return {
  0%, 100% { transform: translate3d(20px, 15px, 0) rotate(165deg); }
  50% { transform: translate3d(-20px, -18px, 0) rotate(188deg); }
}
[data-motion-running='true'] > .section-atmosphere .atmosphere-layer {
  animation-play-state: running;
  will-change: transform;
}
[data-motion-running='false'] > .section-atmosphere .atmosphere-layer {
  animation-name: none;
  transform: none;
  will-change: auto;
}
@media (max-width: 800px) {
  .atmosphere-waves .atmosphere-layer { width: 1100px; }
  .atmosphere-orbits .atmosphere-layer { width: 850px; height: 695px; }
  .atmosphere-orbits .atmosphere-front { left: calc(50% + 230px); }
  .atmosphere-orbits .atmosphere-back { left: calc(50% - 260px); }
  .tool-main > .page > .page-atmosphere { height: 640px; }
  .page-atmosphere .atmosphere-front { top: 40%; left: 60%; opacity: .5; }
  .page-atmosphere .atmosphere-back { opacity: .32; }
  .statement .atmosphere-waves::after {
    background: radial-gradient(ellipse at 25% 50%, color-mix(in srgb, var(--surface) 80%, transparent), transparent);
  }
}
@media (prefers-reduced-motion: reduce) {
  .section-atmosphere .atmosphere-layer { animation: none; transform: none; will-change: auto; }
}
