/* ============================================================
   Delto Web — Motion System
   Reveal-on-scroll utilities, stagger, scroll-driven helpers.
   Paired with useReveal() in components/shell.jsx — JS adds
   `.in` when an element with `.reveal` enters the viewport.

   IMPORTANT: respects prefers-reduced-motion at the bottom.
   ============================================================ */

/* ─── REVEAL VARIANTS ───────────────────────────────────────
   Default `.reveal` already exists (fade + translateY).
   Variants opt-in via `.reveal.r-{name}`.                     */

.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity   var(--dt-dur-reveal) var(--dt-ease-emph),
    transform var(--dt-dur-reveal) var(--dt-ease-emph);
  will-change: opacity, transform;
}
.reveal.in { opacity: 1; transform: translateY(0); }

.reveal.r-fade            { transform: none; }
.reveal.r-up              { transform: translateY(40px); }
.reveal.r-up-sm           { transform: translateY(16px); }
.reveal.r-down            { transform: translateY(-32px); }
.reveal.r-left            { transform: translateX(-48px); }
.reveal.r-right           { transform: translateX(48px); }
.reveal.r-scale           { transform: scale(.94); }
.reveal.r-scale-up        { transform: scale(.98) translateY(20px); }
.reveal.r-blur            { filter: blur(10px); }
.reveal.r-up.in,
.reveal.r-up-sm.in,
.reveal.r-down.in,
.reveal.r-left.in,
.reveal.r-right.in        { transform: translate(0, 0); }
.reveal.r-scale.in,
.reveal.r-scale-up.in     { transform: scale(1) translateY(0); }
.reveal.r-blur.in         { filter: blur(0); }

/* ─── STAGGER ───────────────────────────────────────────────
   Apply `.reveal-stagger` to a parent. Children get sequential
   delays (default 80ms). Override via `--stg`.                */
.reveal-stagger { --stg: var(--dt-stagger); }
.reveal-stagger > .reveal:nth-child(1)  { transition-delay: calc(var(--stg) * 0); }
.reveal-stagger > .reveal:nth-child(2)  { transition-delay: calc(var(--stg) * 1); }
.reveal-stagger > .reveal:nth-child(3)  { transition-delay: calc(var(--stg) * 2); }
.reveal-stagger > .reveal:nth-child(4)  { transition-delay: calc(var(--stg) * 3); }
.reveal-stagger > .reveal:nth-child(5)  { transition-delay: calc(var(--stg) * 4); }
.reveal-stagger > .reveal:nth-child(6)  { transition-delay: calc(var(--stg) * 5); }
.reveal-stagger > .reveal:nth-child(7)  { transition-delay: calc(var(--stg) * 6); }
.reveal-stagger > .reveal:nth-child(8)  { transition-delay: calc(var(--stg) * 7); }
.reveal-stagger > .reveal:nth-child(9)  { transition-delay: calc(var(--stg) * 8); }
.reveal-stagger > .reveal:nth-child(10) { transition-delay: calc(var(--stg) * 9); }
.reveal-stagger > .reveal:nth-child(11) { transition-delay: calc(var(--stg) * 10); }
.reveal-stagger > .reveal:nth-child(12) { transition-delay: calc(var(--stg) * 11); }

/* ─── HOVER LIFT / TILT UTILITIES ──────────────────────────
   Use on cards, mockups, CTA tiles. GPU-friendly only.        */
.lift {
  transition: transform var(--dt-dur-slow) var(--dt-ease-out),
              box-shadow var(--dt-dur-slow) var(--dt-ease-out);
}
.lift:hover { transform: translateY(-4px); }
.lift-strong:hover { transform: translateY(-6px) scale(1.01); }

/* ─── KEYFRAMES — ambient motion ───────────────────────────
   Reusable infinite animations. Use sparingly; keep short.    */
@keyframes dt-pulse        { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@keyframes dt-pulse-soft   { 0%, 100% { opacity: .65; } 50% { opacity: .25; } }
@keyframes dt-float        { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@keyframes dt-float-lg     { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-22px); } }
@keyframes dt-orbit        { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes dt-shimmer      { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
@keyframes dt-blink        { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes dt-rise-in {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes dt-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes dt-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.anim-pulse      { animation: dt-pulse 2.4s var(--dt-ease-in-out) infinite; }
.anim-pulse-soft { animation: dt-pulse-soft 3.2s var(--dt-ease-in-out) infinite; }
.anim-float      { animation: dt-float 6s var(--dt-ease-in-out) infinite; }
.anim-float-lg   { animation: dt-float-lg 9s var(--dt-ease-in-out) infinite; }
.anim-blink      { animation: dt-blink 1s steps(1) infinite; }
.anim-shimmer {
  background: linear-gradient(90deg,
    transparent 0%, rgba(255,255,255,.18) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: dt-shimmer 2.4s var(--dt-ease-in-out) infinite;
}

/* ─── SCROLL-DRIVEN HELPERS ────────────────────────────────
   `.scroll-pinned` — sticky container for scrolly-telling.
   `.scroll-progress` — element whose height/width tracks
   --scroll-p (0..1) set by JS via useScrollProgress().        */
.scroll-pinned {
  position: sticky;
  top: var(--nav-h, 68px);
  height: calc(100vh - var(--nav-h, 68px));
  overflow: hidden;
}
.scroll-progress {
  --scroll-p: 0;
  transform-origin: 0 50%;
  transform: scaleX(var(--scroll-p));
  transition: transform 60ms linear;
}

/* ─── SECTION TONES — alternating background palette ───────
   Apply via `<section class="sect on-{tone}">`. Pairs nicely
   with the existing `.on-dark` typography swap. Goal: no two
   consecutive sections share the same tone.                  */
.sect.on-cream      { background: var(--dt-tone-cream); }
.sect.on-sand-soft  { background: var(--dt-tone-sand-soft); }
.sect.on-lilac      { background: var(--dt-tone-lilac); }
.sect.on-lilac-deep { background: var(--dt-tone-lilac-deep); }
.sect.on-dark-deep  { background: var(--dt-tone-dark-deep); color: #fff; }
.sect.on-dark-deep h2,
.sect.on-dark-deep .sect-sub { color: #fff; }
.sect.on-dark-deep .eyebrow  { color: var(--dt-lime); }
.sect.on-dark-deep .eyebrow::before { background: var(--dt-lime); }

/* Subtle divider between two consecutive light tones —
   prevents flat hand-off. */
.sect.tone-divider-top::before {
  content: ''; position: absolute; inset: 0 0 auto 0;
  height: 1px; background: linear-gradient(90deg,
    transparent, rgba(1,55,61,.08), transparent);
}

/* ─── TEXTURE / GRAIN — opt-in noise overlay ───────────────
   Adds depth to flat surfaces without breaking the palette.   */
.bg-grain::after {
  content: ''; position: absolute; inset: 0;
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='4'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='1'/></svg>");
}

/* ─── REDUCED MOTION ───────────────────────────────────────
   Honor user preference: collapse durations and turn off all
   ambient looping animations.                                */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; filter: none !important; }
  .anim-pulse, .anim-pulse-soft, .anim-float, .anim-float-lg,
  .anim-blink, .anim-shimmer { animation: none !important; }
}
