/* App Purchase Vault — hero depth layer.
 *
 * Adds 3D perspective to the existing hero visual. It does NOT create the
 * scene: the phone, the glow and the floating chips already exist in the
 * homepage markup and stylesheet. This file only pushes them onto separate
 * Z planes and tilts the stage, so the composition reads as depth instead
 * of a flat card.
 *
 * Why CSS rather than WebGL: the phone screen is real DOM text (purchase
 * rows, prices, tags). Rasterising it into a texture would blur it and cost
 * ~150KB of framework to draw four planes. Everything here animates only
 * `transform`, which the compositor handles off the main thread — no layout,
 * no paint, and no way to shift the page.
 *
 * Load order matters: this must come AFTER the homepage's inline <style>,
 * which is where .phone / .hv-chip / .stage are defined.
 *
 * To remove the effect entirely, delete the two tags from the homepages.
 * Nothing else depends on this file.
 */

/* ---------- the 3D container ---------- */
.hero-visual {
  /* Long focal length. A small value here is what makes "3D on the web" look
     cheap — the phone would fan out at the edges. 1600px keeps it architectural. */
  perspective: 1600px;
  perspective-origin: 60% 45%;
}

.hero-visual .stage {
  transform-style: preserve-3d;
  /* Base pose, also the JS resting position. Deliberately shallow: the screen
     content has to stay readable, so this is a hint of angle, not a tilt. */
  transform:
    rotateY(var(--hero-ry, -9deg))
    rotateX(var(--hero-rx, 2.6deg))
    translateZ(0);
  transition: transform .5s cubic-bezier(.22, .61, .36, 1);
}

/* While the pointer is driving it, drop the easing so it tracks 1:1, and hint
   the compositor. will-change is scoped to this state on purpose: leaving it
   on permanently would hold a GPU layer for the largest element on the page
   for the whole session, for an effect that only runs on pointer hover. */
.hero-visual.is-tracking .stage { transition: none; will-change: transform; }

/* ---------- Z placement ---------- */
/* The 3D context has to be unbroken from .stage down to .phone: .shot is a
   plain flex wrapper and would otherwise flatten the phone's depth. */
.hero-visual .stage .shot { transform-style: preserve-3d; }

.hero-visual .stage .phone {
  transform-style: preserve-3d;
  /* Slightly forward of the origin so the chips can sit convincingly in front
     of and behind it. */
  transform: translateZ(28px);
  /* Deepen the existing shadow a touch to match the raised position. */
  box-shadow:
    0 46px 84px -30px rgba(11, 44, 107, .5),
    0 6px 18px rgba(11, 44, 107, .14);
}

/* Chips are direct children of .hero-visual, so they sit in its perspective
   space directly — no wrapper needed. Different Z values are what make them
   parallax against the phone and scale slightly as the scene turns. */
.hero-visual .hv-chip.c1 { --hv-z: 76px; }
.hero-visual .hv-chip.c2 { --hv-z: -46px; }
.hero-visual .hv-chip.c3 { --hv-z: 58px; }

/* The homepage `floaty` keyframe animates transform, so the Z offset has to be
   part of the same property. Redefining the keyframe here keeps both. */
.hero-visual .hv-chip {
  transform: translateZ(var(--hv-z, 0px));
  animation-name: hv-floaty-3d;
}
@keyframes hv-floaty-3d {
  0%, 100% { transform: translate3d(0, 0, var(--hv-z, 0px)); }
  50%      { transform: translate3d(0, -7px, var(--hv-z, 0px)); }
}

/* Third chip: spending stats, the one core message the other two don't carry.
   Positioned to balance c1 (top right) and c2 (bottom left). */
.hero-visual .hv-chip.c3 {
  top: 34%;
  right: -7%;
  animation-delay: -1.8s;
}

/* The glow sits furthest back and widens slightly, so the tilt doesn't reveal
   its edge against the hero background. */
.hero-visual .hv-glow {
  transform: translateZ(-120px) scale(1.12);
}

/* ---------- narrower screens ---------- */
/* The existing homepage rule hides .hv-chip below 1100px; c3 follows it. */
@media (max-width: 1100px) {
  .hero-visual .hv-chip.c3 { display: none; }
  /* Less horizontal room, so straighten up to protect the screen content. */
  .hero-visual .stage { transform: rotateY(-5deg) rotateX(1.6deg); }
}

/* Below the hero's single-column breakpoint the phone is centred and near
   full width. Any rotation there costs readability and gains nothing, so the
   scene flattens to the original composition. */
@media (max-width: 960px) {
  .hero-visual { perspective: none; }
  .hero-visual .stage { transform: none; }
  .hero-visual .stage .phone { transform: none; }
  .hero-visual .hv-glow { transform: none; }
}

/* Coarse pointers get no parallax anyway (the JS bails), and a tilt that can't
   be interacted with just costs legibility on a small screen. */
@media (hover: none) {
  .hero-visual .stage { transform: rotateY(-4deg) rotateX(1.2deg); }
}
@media (hover: none) and (max-width: 960px) {
  .hero-visual .stage { transform: none; }
}

/* ---------- reduced motion ---------- */
/* The static pose is kept — it is composition, not movement — but everything
   that moves on its own stops, and the JS refuses to attach. */
@media (prefers-reduced-motion: reduce) {
  .hero-visual .hv-chip { animation: none; transform: translateZ(var(--hv-z, 0px)); }
  .hero-visual .stage { transition: none; }
}
