/* =========================================================================
   VODA.MARKETING — Homepage-only styles
   Loaded on the homepage ONLY, AFTER css/site.css (which carries all the
   shared tokens/base/components). This file is just the homepage's signature
   motion + layout that no inner page uses: the mobile section-image shrink
   (makes room for the vine), the decorative hero orb, the hero entrance
   stagger, the desktop flightpath chip-strings, and the mobile page-path
   "vine". All rules resolve their var(--*) tokens from site.css / the inline
   critical CSS. Respects prefers-reduced-motion. See js/home.js for the
   drivers. Section numbers (24/28/29/30) mirror the old home.css for history.
   ========================================================================= */

/* ---------- 24b. HOMEPAGE MOBILE IMAGE SHRINK ---------- */
/* Mobile: shrink EVERY section image to the same reduced, side-padded size
   as the hero photo — smaller, centered, with cream breathing room on the
   sides (this also gives the page-path vine more room to read beside them).
   Natural aspect ratios are kept. */
@media (max-width: 767px) {
  .hero__photo,
  .guide-grid > figure,
  .photo-split figure,
  .campaign-card {
    width: 74%;
    margin-left: auto;
    margin-right: auto;
  }
}

/* =========================================================================
   28. MOTION — hero orb + hero entrance stagger (homepage hero only).
   The shared scroll-reveal system + nav.is-scrolled live in site.css.
   ========================================================================= */
/* Decorative orb behind the hero photo — soft coral glow, continuously and
   slowly rotating (an off-center gradient reads as gentle motion as it
   spins, even though the shape itself is a circle). Matches the "orbit"
   language in the reference's Decorative Orb component spec. */
.hero__orb {
  position: absolute;
  top: -8%;
  right: -10%;
  width: 55%;
  aspect-ratio: 1;
  border-radius: 50%;
  /* Soft coral glow. No blur() filter: the gradient is already soft, and a
     blur would be re-rasterized on every rotation frame (heavy Style/Layout
     work under mobile CPU throttle). will-change promotes the orb to its own
     compositor layer so the spin is a GPU transform, not a repaint. */
  background: radial-gradient(circle at 35% 35%, rgba(214, 90, 60, 0.4) 0%, rgba(214, 90, 60, 0) 72%);
  z-index: -1;
  pointer-events: none;
  will-change: transform;
}

/* Mobile: drop the decorative gradient/orb behind the hero photo entirely
   (Noah's call) — desktop keeps it. Also removes its animation cost on phones. */
@media (max-width: 767px) {
  .hero__orb { display: none; }
}

@keyframes orbit-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Hold the orbit paused until the page has fully loaded — starting a
   continuous animation at t=0 generated heavy main-thread Style/Layout work
   under mobile throttle and starved the hero entrance (LCP regression).
   home.js adds .loaded to <html> on the window 'load' event. */
.js-enabled .hero__orb {
  animation: orbit-spin 36s linear infinite;
  animation-play-state: paused;
}

.js-enabled.loaded .hero__orb {
  animation-play-state: running;
}

/* Hero — plays once on load (not scroll-gated, it's above the fold) with a
   short stagger between the eyebrow, headline clauses, body, and CTA row. */
/* Fast opacity ramp (full by 35% of the run) so the above-the-fold hero text —
   the mobile LCP element — reaches final paint quickly, while the translateY
   rise still plays to the end to keep the mockup's entrance feel. Shorter
   duration + tighter stagger than the mockup for the same reason. */
@keyframes hero-rise {
  0%   { opacity: 0; transform: translateY(16px); }
  35%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}

.js-enabled .hero-rise {
  opacity: 0;
  animation: hero-rise 600ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.js-enabled .hero-rise:nth-child(1) { animation-delay: 0ms; }
.js-enabled .hero-rise:nth-child(2) { animation-delay: 60ms; }
.js-enabled .hero-rise:nth-child(3) { animation-delay: 110ms; }
.js-enabled .hero-rise:nth-child(4) { animation-delay: 160ms; }

@media (prefers-reduced-motion: reduce) {
  .hero__orb { animation: none; }
  .js-enabled .hero-rise {
    opacity: 1;
    animation: none;
  }
}

/* =========================================================================
   29. FLIGHTPATH — a string of platform chips travels continuously along an
   SVG curve. The curve is rebuilt in pixel space per element size so each
   chip's tangent rotation stays correct at any width (same idea as Wispr's
   motion-path app-icon arc, plus their "string across the screen" hero
   move). Two instances: one sweeps up from under the hero copy and vanishes
   behind the photo; one arcs across the dark closing band behind the CTA.
   The JS at the bottom of the page drives position + rotation every frame;
   CSS here only styles the line and the chips. Desktop-only — at narrow
   widths the curve has no room to read.
   ========================================================================= */
.flightpath {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Desktop uses the per-section flightpaths (hero + footer). On mobile they're
   replaced by one continuous page-path (§30), so both are desktop-only here. */
.flightpath--hero { display: none; }
.flightpath--footer { display: none; }
@media (min-width: 768px) {
  .flightpath--hero { display: block; }
}
@media (min-width: 1024px) {
  .flightpath--footer { display: block; }
}

.flightpath__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.flightpath__line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.3;
}

.flightpath__line--dash {
  stroke-dasharray: 2 10;
  opacity: 0.42;
}

.flightpath__icon {
  position: absolute;
  top: 0;
  left: 0;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: var(--bg-primary);
  border: 1px solid var(--border-soft);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-primary);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.18);
  opacity: 0;
  will-change: transform, opacity;
}

.flightpath__icon img,
.flightpath__icon svg {
  width: 58%;
  height: 58%;
  object-fit: contain;
  display: block;
  pointer-events: none;
}

/* Hero string sits a touch larger than the base chip. */
.flightpath--hero .flightpath__icon {
  width: 46px;
  height: 46px;
  border-radius: 13px;
}

.flightpath--footer .flightpath__icon {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  font-size: 12px;
}

.flightpath--dark .flightpath__line { opacity: 0.5; }
.flightpath--dark .flightpath__icon {
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
}

/* =========================================================================
   30. PAGE-PATH (mobile) — one continuous curve down the whole page. It lives
   on a z-index:-1 layer, so it paints above the page's cream background but
   behind all section content. Cream/tinted sections are made transparent on
   mobile so the path shows through them; the dark rounded panels stay opaque,
   so the path visibly ducks behind each one. JS sizes the layer to the full
   document height and pins the logos along the curve.
   ========================================================================= */
.pagepath { display: none; }

@media (max-width: 767px) {
  .pagepath {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
  }

  /* The page-path sits at z-index:-1; an opaque body background would paint
     over it, so on mobile the cream lives on <html> and <body> is clear. */
  body { background: transparent; }

  /* Let the page-path show through the tinted sections. */
  .section--alt { background: transparent; }
  .section--alt .service-tile,
  .section--alt .plan__step { background: #ffffff; }

  /* The dot-row divider had an opaque tinted background + ink border that
     painted over the vine — clear both so the logos show through behind the
     dots (the dots stay on top as normal content). */
  .dot-row { background: transparent; border-bottom-color: transparent; }
}

.pagepath__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.pagepath__line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 2 10;
  opacity: 0.4;
}

/* Page-path logos travel via CSS offset-path (compositor-driven, so 60 of
   them stay smooth on mobile) instead of per-frame JS. The serpentine `d` is
   set on each icon's offset-path in the builder; the animation just sweeps
   offset-distance, and offset-rotate keeps each logo tangent to the curve. */
@keyframes vine-travel {
  from { offset-distance: 0%; }
  to   { offset-distance: 100%; }
}

.pagepath .flightpath__icon {
  width: 44px;
  height: 44px;
  border-radius: 13px;
  opacity: 1;
  offset-rotate: auto;
  /* Real-device iOS perf: WebKit animates motion-path on the MAIN thread, so
     every vine chip repaints each frame. Kill the drop-shadow (shadows
     re-rasterize every frame on moving elements) and do NOT promote layers —
     ~28 promoted layers would spike iOS memory and WebKit can't composite
     motion-path anyway. See home.js for the count cut + scroll-pause. */
  box-shadow: none;
  will-change: auto;
}

/* Count-up numerals: fixed-width (tabular) digits so a ticking value doesn't
   re-shape its row on every update. Pairs with the throttled textContent
   writes in home.js — together they cut the count-up's per-frame layout cost
   on real-device iOS. Homepage-only (only home.css loads here). */
.stat__value,
.campaign-card__metric-num {
  font-variant-numeric: tabular-nums;
}


