/* ============================================================
   depth-motion.css — Colonial Aesthetics & Wellness
   ============================================================
   ADDITIVE enhancement layer. Load LAST, after site.css, every
   page stylesheet, and system.css:

     <link rel="stylesheet" href="site.css" />
     <link rel="stylesheet" href="...page....css" />
     <link rel="stylesheet" href="system.css" />
     <link rel="stylesheet" href="depth-motion.css" />   <-- here

   Design intent: quiet, expensive, calm. This does NOT introduce
   new colors, fonts, or type sizes. It reuses your locked tokens
   (--c-*, --ease-out, --d-*) and your existing .reveal system.

   Everything here is wrapped so it degrades safely:
     - prefers-reduced-motion fully disables motion (parity with
       your existing reset in site.css).
     - Scroll-driven effects are gated behind @supports; browsers
       without animation-timeline keep your current behavior.
     - Hero load cascade only touches elements that do NOT already
       carry .reveal (via :not(.reveal)), so it never double-runs.

   Sections:
     1. Elevation scale (teal-tinted depth tokens)
     2. Reveal enhancement (deeper lift + focus-blur)
     3. Directional + scale reveal variants
     4. Stagger for known grids
     5. Hero load cascade
     6. Card depth (photo cards only)
     7. Deep-Teal surface depth (lit wash + grain)
     8. Scroll progress hairline (header)
     9. Parallax on imagery (scroll-driven, progressive)
    10. Reduced-motion master guard
   ============================================================ */


/* ============================================================
   1) ELEVATION SCALE — systematized, teal-tinted
   ============================================================
   Your existing shadows already tint toward teal
   (rgba(15,79,87,…)). This formalizes three steps so depth is
   consistent wherever it's applied. Pure tokens; nothing styled
   yet — applied in sections 6–7.
   ============================================================ */
:root {
  --e-sm: 0 1px 2px rgba(15, 79, 87, 0.05),
          0 2px 6px rgba(15, 79, 87, 0.05);
  --e-md: 0 4px 10px rgba(15, 79, 87, 0.07),
          0 12px 28px rgba(15, 79, 87, 0.08);
  --e-lg: 0 8px 20px rgba(15, 79, 87, 0.08),
          0 24px 56px rgba(15, 79, 87, 0.10);
  /* Lift distance for reveals — a hair deeper than your 12px so
     entrances register without feeling theatrical. */
  --reveal-rise: 20px;
  /* Per-item stagger step for grids. */
  --reveal-step: 70ms;
}


/* ============================================================
   2) REVEAL ENHANCEMENT — build on your .reveal/.reveal.in
   ============================================================
   You already animate opacity + translateY(12px) and toggle
   .in via JS. We deepen the lift and add a 4px→0 blur so content
   reads as "coming into focus." We also extend the transition to
   cover filter. Your JS keeps doing the .in toggling unchanged.
   ============================================================ */
/* transform + opacity only. The 4px blur that used to ride along here is a
   non-composited property, so every section repainted as it scrolled in —
   expensive on a page that is already transpiling JSX in the browser. */
.reveal {
  transform: translateY(var(--reveal-rise));
  transition:
    opacity var(--d-enter) var(--ease-out),
    transform var(--d-enter) var(--ease-out);
}


/* ============================================================
   3) DIRECTIONAL + SCALE REVEAL VARIANTS
   ============================================================
   Add one of these classes ALONGSIDE .reveal on an element to
   vary its entrance direction. Mixing directions across the page
   is what stops reveals from feeling mechanical.

     .reveal.reveal-left   -> drifts in from the left
     .reveal.reveal-right  -> drifts in from the right
     .reveal.reveal-scale  -> settles in with a subtle scale
     .reveal.reveal-still  -> fade + focus only, no movement

   Suggested usage (requires adding the class in your JSX):
     - Two-up "Look refreshed / Feel restored": left card gets
       .reveal-left, right card .reveal-right.
     - Any zig-zag rows: alternate -left / -right.
     - Hero portrait, big imagery: .reveal-scale.
   These are opt-in; plain .reveal still works everywhere.
   ============================================================ */
.reveal.reveal-left  { transform: translateX(calc(-1 * var(--reveal-rise))); }
.reveal.reveal-right { transform: translateX(var(--reveal-rise)); }
.reveal.reveal-scale { transform: scale(0.97); }
.reveal.reveal-still { transform: none; }

.reveal.reveal-left.in,
.reveal.reveal-right.in,
.reveal.reveal-scale.in,
.reveal.reveal-still.in {
  transform: none;
}

/* On a phone there is no spare horizontal room, so an element that has
   not revealed yet sits 20px outside the viewport and gives the whole
   document a horizontal scrollbar on load. It corrects itself once the
   element scrolls into view, which is exactly the wrong time.
   Measured on the homepage at 414px: scrollWidth 429 vs viewport 414,
   traced to .consult-card.reveal-right.
   Swap the sideways drift for the standard vertical rise below 768px.
   A 20px horizontal drift is imperceptible at phone width anyway. */
@media (max-width: 767px) {
  .reveal.reveal-left,
  .reveal.reveal-right {
    transform: translateY(var(--reveal-rise));
  }
}


/* ============================================================
   4) STAGGER FOR KNOWN GRIDS
   ============================================================
   Cascades children in sequence INSTEAD of popping together.

   IMPORTANT: this only takes effect if each child individually
   carries .reveal (so it has its own transition to delay). If a
   grid currently reveals as one block (only the wrapper has
   .reveal), add `reveal` to each child in your JSX to get the
   cascade — or tell me your reveal JS and I'll wire stagger
   without markup changes.

   Targets confirmed grid containers only.
   ============================================================ */
.services-grid > .reveal:nth-child(1),
.trust-grid > .reveal:nth-child(1),
.mem-benefits > .reveal:nth-child(1),
.mem-how-grid > .reveal:nth-child(1),
.ig-grid > .reveal:nth-child(1),
.shop-brand-grid > .reveal:nth-child(1),
.pay-financing-grid > .reveal:nth-child(1) { transition-delay: 0ms; }

.services-grid > .reveal:nth-child(2),
.trust-grid > .reveal:nth-child(2),
.mem-benefits > .reveal:nth-child(2),
.mem-how-grid > .reveal:nth-child(2),
.ig-grid > .reveal:nth-child(2),
.shop-brand-grid > .reveal:nth-child(2),
.pay-financing-grid > .reveal:nth-child(2) { transition-delay: calc(1 * var(--reveal-step)); }

.services-grid > .reveal:nth-child(3),
.trust-grid > .reveal:nth-child(3),
.mem-benefits > .reveal:nth-child(3),
.mem-how-grid > .reveal:nth-child(3),
.ig-grid > .reveal:nth-child(3),
.shop-brand-grid > .reveal:nth-child(3) { transition-delay: calc(2 * var(--reveal-step)); }

.trust-grid > .reveal:nth-child(4),
.mem-benefits > .reveal:nth-child(4),
.ig-grid > .reveal:nth-child(4),
.shop-brand-grid > .reveal:nth-child(4) { transition-delay: calc(3 * var(--reveal-step)); }

.ig-grid > .reveal:nth-child(5),
.shop-brand-grid > .reveal:nth-child(5) { transition-delay: calc(4 * var(--reveal-step)); }
.ig-grid > .reveal:nth-child(6),
.shop-brand-grid > .reveal:nth-child(6) { transition-delay: calc(5 * var(--reveal-step)); }

/* Contact page contact-method cells: children carry .reveal but had no
   per-cell delays, so all four popped in as one block. Same cadence as
   the other audited grids. */
.methods-grid > .reveal:nth-child(1) { transition-delay: 0ms; }
.methods-grid > .reveal:nth-child(2) { transition-delay: calc(1 * var(--reveal-step)); }
.methods-grid > .reveal:nth-child(3) { transition-delay: calc(2 * var(--reveal-step)); }
.methods-grid > .reveal:nth-child(4) { transition-delay: calc(3 * var(--reveal-step)); }


/* ============================================================
   5) HERO LOAD CASCADE
   ============================================================
   A gentle on-load entrance for the homepage hero text: eyebrow
   -> headline -> sub -> CTAs, each rising into focus in sequence.

   Guarded with :not(.reveal) so if your hero text already uses
   the reveal system, this no-ops and your reveal handles it (no
   double animation). If the hero text is NOT reveal-driven, this
   gives it a polished entrance with zero JS.
   ============================================================ */
@keyframes cw-hero-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

.hero-eyebrow:not(.reveal),
.hero-headline:not(.reveal),
.hero-sub:not(.reveal),
.hero-ctas:not(.reveal) {
  opacity: 0;
  animation: cw-hero-rise var(--d-hero) var(--ease-out) forwards;
}
.hero-eyebrow:not(.reveal)  { animation-delay: 80ms; }
.hero-headline:not(.reveal) { animation-delay: 180ms; }
.hero-sub:not(.reveal)      { animation-delay: 300ms; }
.hero-ctas:not(.reveal)     { animation-delay: 420ms; }


/* ============================================================
   6) CARD DEPTH — photo cards only
   ============================================================
   Depth communicates hierarchy on image-led cards. We give the
   photo cards a resting elevation and a deeper lift on hover.

   We deliberately DO NOT touch your treatment price-menu cards —
   a quiet 1px bordered card is the right call for a price list.

   Audited photo-card classes: .service-card (homepage two-up),
   .sig-card (homepage signature-treatment row), .brand-card
   (Shop), .pay-fcard (Payments). All four are interactive links
   that already clip overflow + carry a hover translateY(-2/-3px)
   in site.css/shop.css; we only add resting elevation + deepen
   the hover shadow (depth-motion loads last, so --e-lg wins over
   the page's hover shadow without touching its transform).
   Portrait/team cards are intentionally excluded — they are not
   links, so a hover lift would imply false affordance.
   ============================================================ */
.service-card,
.sig-card,
.brand-card,
.pay-fcard {
  box-shadow: var(--e-sm);
}

@media (hover: hover) and (pointer: fine) {
  .service-card:hover,
  .sig-card:hover,
  .brand-card:hover,
  .pay-fcard:hover {
    box-shadow: var(--e-lg);
  }
}


/* ============================================================
   7) DEEP-TEAL SURFACE DEPTH — lit wash + fine grain
   ============================================================
   Flat Deep Teal fills read as paint. A faint off-center radial
   wash + a barely-there grain makes them read as a lit, physical
   surface. Applied to the Deep-Teal CTA closers and Deep-Teal
   heroes. The pseudo-element is layered UNDER content.

   These containers must establish a stacking context for the
   ::before to sit behind text — they already have backgrounds,
   so we set position/overflow defensively and lift inner content.
   ============================================================ */
.pay-consult,
.gc-final,
.pr-consult,
.pay-hero,
.shop-hero,
.gc-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.pay-consult::before,
.gc-final::before,
.pr-consult::before,
.pay-hero::before,
.shop-hero::before,
.gc-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Lit wash: a soft aqua-tinted glow off the top, plus a
     subtle SVG grain so the fill has tooth. Both very low alpha. */
  background-image:
    radial-gradient(120% 80% at 25% 0%,
      rgba(127, 192, 196, 0.10) 0%,
      rgba(127, 192, 196, 0) 55%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.018'/%3E%3C/svg%3E");
  background-repeat: no-repeat, repeat;
}


/* ============================================================
   8) SCROLL PROGRESS HAIRLINE — header
   ============================================================
   A 2px Sea-Teal line across the bottom of your already-sticky
   header that fills as the page scrolls. Pure CSS via scroll
   timeline; only renders where supported. No JS, no markup.
   ============================================================ */
@supports (animation-timeline: scroll()) {
  .header { position: sticky; } /* re-assert; required for the bar */
  .header::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -1px;            /* sits on the existing hairline border */
    height: 2px;
    width: 100%;
    transform-origin: left center;
    transform: scaleX(0);
    background: var(--c-sea);
    animation: cw-progress linear both;
    animation-timeline: scroll(root);
  }
}
@keyframes cw-progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}


/* ============================================================
   9) PARALLAX ON IMAGERY — scroll-driven, progressive
   ============================================================
   A whisper of drift (≈22px) on large imagery as it passes
   through the viewport, using native view() timelines. This is
   GPU-friendly and runs off the main thread, so it won't fight
   the in-browser Babel/React load. Gated behind @supports; any
   browser without it simply shows the static image.

   Audited image classes: .hero-photo (homepage portrait), plus
   the real card-image elements .service-card-img, .sig-card-img
   (homepage) and .brand-card-logo-img (Shop). The original
   .service-card .placeholder.card selector matched a typographic
   placeholder that production no longer uses, so it never fired —
   repointed at the live <img> classes. All three card images sit
   inside overflow:hidden cards, so the scale(1.04) drift is
   masked and never bleeds past the card edge.
   ============================================================ */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    .hero-photo {
      animation: cw-parallax-up linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
      will-change: transform;
    }

    /* Gentle drift on card image panels as their card scrolls
       through view. Subtle enough to feel like depth, not motion. */
    .brand-card-logo-img,
    .service-card-img,
    .sig-card-img {
      animation: cw-parallax-soft linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
      will-change: transform;
    }
  }
}

@keyframes cw-parallax-up {
  from { transform: translateY(22px); }
  to   { transform: translateY(-22px); }
}
@keyframes cw-parallax-soft {
  from { transform: translateY(12px) scale(1.04); }
  to   { transform: translateY(-12px) scale(1.04); }
}


/* ============================================================
   10) REDUCED-MOTION MASTER GUARD
   ============================================================
   Parity with your existing site.css reset. Anyone who asks for
   reduced motion gets the calm, static site: no reveal movement,
   no blur, no hero cascade, no parallax, no progress bar fill.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal.reveal-left,
  .reveal.reveal-right,
  .reveal.reveal-scale {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .hero-eyebrow:not(.reveal),
  .hero-headline:not(.reveal),
  .hero-sub:not(.reveal),
  .hero-ctas:not(.reveal) {
    opacity: 1 !important;
    animation: none !important;
  }
  .hero-photo,
  .brand-card-logo-img,
  .service-card-img,
  .sig-card-img {
    animation: none !important;
    transform: none !important;
  }
  .header::after { animation: none !important; transform: scaleX(0) !important; }
}
