/* ==========================================================================
   selfLove.Yoga — Warm Cream Calm — Taste & Motion System (v2, "impeccable")
   Implements /selflove-redesign/TASTE-AND-MOTION-SYSTEM.md verbatim.
   Load order: Tailwind CDN -> taste.css -> page inline <style> (page inline
   blocks have been stripped of the ad-hoc .reveal/.card-hover rules this
   file now owns, so there is nothing left to fight the cascade).
   ========================================================================== */

:root {
  /* ---- Motion tokens (spec section 4, verbatim) ---- */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);      /* entrances: fast start, gentle settle */
  --ease-in-out-quart: cubic-bezier(0.76, 0, 0.24, 1); /* state changes: toggles, modals */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);    /* gesture-driven / physically-interactive approximation */
  --duration-fast: 150ms;  /* hover, button press */
  --duration-base: 250ms;  /* card reveals, dropdowns */
  --duration-slow: 400ms;  /* modals, page-level transitions */
  --stagger-step: 50ms;    /* 40-60ms per spec, capped at 6 children */

  /* ---- Brand accent used by the photo color-grade + hover shadow tint ---- */
  --accent: #C97B4A;
  --accent-rgb: 201, 123, 74;
  --ink-rgb: 62, 58, 52;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms;
    --duration-base: 0ms;
    --duration-slow: 0ms;
  }
}

/* ==========================================================================
   1. Entrances — scroll reveal (used site-wide via .reveal / .reveal-visible,
   toggled by IntersectionObserver in script.js). Momentum-settle, not linear.
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(20px) scale(0.985);
  transition: opacity var(--duration-slow) var(--ease-out-expo),
              transform var(--duration-slow) var(--ease-out-expo);
  will-change: opacity, transform;
}
.reveal-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* Explicit staggered-reveal utility for hand-built asymmetric groups
   (index.html / ytt.html dominant-move sections). Apply `.stagger` to the
   parent; each of the first 6 children gets a 50ms-stepped entrance delay,
   capped at 6 per spec ("past that, cap it"). Children still need .reveal. */
.stagger > .reveal:nth-child(1) { transition-delay: 0ms; }
.stagger > .reveal:nth-child(2) { transition-delay: calc(var(--stagger-step) * 1); }
.stagger > .reveal:nth-child(3) { transition-delay: calc(var(--stagger-step) * 2); }
.stagger > .reveal:nth-child(4) { transition-delay: calc(var(--stagger-step) * 3); }
.stagger > .reveal:nth-child(5) { transition-delay: calc(var(--stagger-step) * 4); }
.stagger > .reveal:nth-child(n+6) { transition-delay: calc(var(--stagger-step) * 5); }

/* ==========================================================================
   2. Hover states — transform-only, 150ms, never color-only on cards/buttons.
   ========================================================================== */
/* NOTE: these set the full `transition` shorthand on purpose and are meant
   to be used WITHOUT Tailwind's transition-colors/transition-all utilities
   on the same element -- mixing the two creates two rules fighting over the
   same longhand properties, and since Tailwind's CDN script injects its
   stylesheet at an unpredictable point in <head>, the outcome is a coin
   flip. Each class below already covers color+background-color so it is a
   complete drop-in replacement for transition-colors/transition-all. */
.card-hover,
.u-hover-lift,
.u-hover-lift-sm {
  transition: transform var(--duration-fast) var(--ease-out-expo),
              box-shadow var(--duration-fast) var(--ease-out-expo),
              background-color var(--duration-fast) var(--ease-out-expo),
              color var(--duration-fast) var(--ease-out-expo),
              border-color var(--duration-fast) var(--ease-out-expo);
}
.card-hover:hover,
.card-hover:focus-visible,
.u-hover-lift:hover,
.u-hover-lift:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 12px 24px -10px rgba(var(--ink-rgb), 0.22);
}
.u-hover-lift-sm:hover,
.u-hover-lift-sm:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 8px 16px -8px rgba(var(--ink-rgb), 0.28);
}

/* Any remaining bare Tailwind transition-* utility (nav text-color hovers,
   etc.) still gets our tokens for duration/easing instead of Tailwind's
   ad-hoc 150ms/default-ease -- !important only on the two timing values so
   it wins regardless of where the Tailwind CDN happens to inject its
   runtime stylesheet in <head>, without touching transition-property. */
.transition-colors, .transition-transform, .transition-shadow, .transition-opacity, .transition {
  transition-duration: var(--duration-fast) !important;
  transition-timing-function: var(--ease-out-expo) !important;
}

/* State-change (open/close, toggle) transitions — modals, accordions, menus. */
.u-state-transition {
  transition: transform var(--duration-base) var(--ease-in-out-quart),
              opacity var(--duration-base) var(--ease-in-out-quart);
}
[data-modal-panel] {
  transition: transform var(--duration-base) var(--ease-in-out-quart),
              opacity var(--duration-base) var(--ease-in-out-quart);
}
[data-accordion-icon] {
  transition: transform var(--duration-base) var(--ease-in-out-quart);
}

/* Gesture-driven / physically-interactive elements (booking calendar day
   select, draggable cart rows) — spring signature, not a flat ease. */
.u-spring,
.cal-day {
  transition: transform 350ms var(--ease-spring),
              box-shadow 350ms var(--ease-spring),
              background-color var(--duration-fast) var(--ease-out-expo);
}
.cal-day[data-bookable="true"]:hover {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 10px 20px -8px rgba(var(--accent-rgb), 0.35);
}

/* Purposeful state pulse (e.g. a capacity chip crossing a threshold) —
   trigger by toggling this class on/off via JS, not on every repaint. */
@keyframes u-pulse-once {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.12); }
  70%  { transform: scale(0.97); }
  100% { transform: scale(1); }
}
.u-pulse-once { animation: u-pulse-once var(--duration-slow) var(--ease-spring) 1; }

/* Collapse-and-slide for removable rows (cart line item removal) instead of
   a hard vanish. Trigger by adding this class, then remove the node on
   transitionend. */
.u-collapse-remove {
  transition: opacity var(--duration-base) var(--ease-in-out-quart),
              transform var(--duration-base) var(--ease-in-out-quart),
              max-height var(--duration-base) var(--ease-in-out-quart),
              margin var(--duration-base) var(--ease-in-out-quart);
  overflow: hidden;
}
.u-collapse-remove.is-removing {
  opacity: 0;
  transform: translateX(24px);
  max-height: 0;
  margin-top: 0;
  margin-bottom: 0;
}

/* ==========================================================================
   3. Imagery — single consistent brand color-grade + framed treatment.
   Apply `.u-photo-grade` directly to every <img>/<video>. Apply
   `.u-photo-frame` to its immediate wrapper (the existing rounded-*
   overflow-hidden div most images already sit in) to add the gradient
   overlay + 1px inset border called for in spec section 6.
   ========================================================================== */
.u-photo-grade {
  filter: saturate(1.08) sepia(8%) hue-rotate(-8deg) brightness(0.99) contrast(1.02);
}
.u-photo-frame {
  position: relative;
  isolation: isolate;
}
.u-photo-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(150deg, rgba(var(--accent-rgb), 0.15) 0%, rgba(var(--accent-rgb), 0.03) 45%, rgba(var(--ink-rgb), 0.10) 100%);
  mix-blend-mode: multiply;
  pointer-events: none;
  border-radius: inherit;
}
.u-photo-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
  pointer-events: none;
  border-radius: inherit;
}

/* ==========================================================================
   4. Type scale utilities (12/16/21/28/37/50/67/89 — perfect-fourth 1.333
   from a 16px base). Use sparingly: 4-5 steps per page, never all 8.
   ========================================================================== */
.text-scale-1 { font-size: 12px; line-height: 1.5; }
.text-scale-2 { font-size: 16px; line-height: 1.6; }
.text-scale-3 { font-size: 21px; line-height: 1.5; }
.text-scale-4 { font-size: 28px; line-height: 1.3; }
.text-scale-5 { font-size: 37px; line-height: 1.15; letter-spacing: -0.01em; }
.text-scale-6 { font-size: 50px; line-height: 1.05; letter-spacing: -0.02em; }
.text-scale-7 { font-size: 67px; line-height: 0.98; letter-spacing: -0.02em; }
.text-scale-8 { font-size: 89px; line-height: 0.94; letter-spacing: -0.02em; }

/* Oversized watermark numerals for the "dominant visual move" compositions. */
.u-watermark-stat {
  font-family: "Fraunces", serif;
  font-weight: 600;
  color: var(--accent);
  opacity: 0.16;
  line-height: 0.8;
  letter-spacing: -0.03em;
  pointer-events: none;
  font-size: clamp(140px, 26vw, 420px);
}

/* Hero H1 — spec's 67/89px modular-scale steps (never Tailwind's default
   jumps), tight tracking, weight 700. Used by the flagship pages' dominant
   off-center headline treatment. */
.u-hero-headline {
  font-size: 50px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 0.98;
}
@media (min-width: 640px) { .u-hero-headline { font-size: 67px; } }
@media (min-width: 1024px) { .u-hero-headline { font-size: 89px; } }

/* Diagonal image break — interrupts a rectangular 2-col split. Apply to the
   image wrapper; pairs with a negative margin on the sibling to let it bleed. */
.u-diagonal-break {
  clip-path: polygon(9% 0, 100% 0, 100% 100%, 0 100%);
}
@media (min-width: 1024px) {
  .u-diagonal-break { clip-path: polygon(14% 0, 100% 0, 100% 100%, 0 100%); }
}

/* Arrow-nudge: transform-only alternative to animating `gap` (a layout
   property that isn't transform/opacity and would jank per spec section 4). */
.u-arrow-nudge {
  display: inline-block;
  transition: transform var(--duration-fast) var(--ease-out-expo);
}
a:hover .u-arrow-nudge,
button:hover .u-arrow-nudge {
  transform: translateX(4px);
}
