/* =========================================================
   Vivenda — Motion tokens & utilities
   Reference: vivenda.es/projects/north-pearl-two
   Pair with colors_and_type.css.
   ========================================================= */

:root {
  /* ---------- Durations ---------- */
  --motion-fast:    160ms;   /* press, micro feedback */
  --motion-quick:   300ms;   /* nav shrink, hover */
  --motion-base:    600ms;   /* clip-path reveals, divider draw, page fade */
  --motion-soft:    800ms;   /* image fade-up on scroll */
  --motion-slow:    1200ms;  /* hero zoom-on-load */

  /* ---------- Easings ---------- */
  --ease-out:       cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out:    cubic-bezier(0.65, 0, 0.35, 1);
  --ease-cinematic: cubic-bezier(0.16, 1, 0.3, 1);  /* hero / clip-path reveals */

  /* ---------- Stagger ---------- */
  --stagger-tight:  0.08s;   /* footer link list */
  --stagger-base:   0.10s;
  --stagger-loose:  0.15s;   /* heading line-by-line reveal */
  --stagger-section:0.20s;   /* sibling blocks */

  /* ---------- Distances ---------- */
  --rise-sm:  20px;
  --rise-md:  30px;          /* gallery images */
  --rise-lg:  40px;          /* generic scroll-reveal blocks */
}

/* =========================================================
   1. Page entry — fade in the whole content over 0.6s
   ========================================================= */
@keyframes viv-page-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.viv-page-enter {
  animation: viv-page-in var(--motion-base) var(--ease-out) both;
}

/* =========================================================
   2. Hero image — slight zoom-in on load (1.00 → 1.05)
   ========================================================= */
@keyframes viv-hero-zoom {
  from { transform: scale(1.00); filter: saturate(0.85); }
  to   { transform: scale(1.05); filter: saturate(1.00); }
}
.viv-hero-img {
  animation: viv-hero-zoom var(--motion-slow) var(--ease-out) both;
  will-change: transform, filter;
}
/* Bottom legibility gradient — pair with hero */
.viv-hero-overlay::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 50%, rgba(0,0,0,0.55) 100%);
  pointer-events: none;
}

/* =========================================================
   3. Parallax — hero moves slower than the page on scroll.
   Apply via JS (translateY = -scrollY * 0.25) on .viv-parallax,
   or via CSS scroll-driven animations where supported.
   ========================================================= */
@supports (animation-timeline: scroll()) {
  @keyframes viv-parallax-shift {
    from { transform: translate3d(0, 0, 0) scale(1.05); }
    to   { transform: translate3d(0, -120px, 0) scale(1.05); }
  }
  .viv-parallax {
    animation: viv-parallax-shift linear both;
    animation-timeline: scroll();
    animation-range: 0 100vh;
  }
}

/* =========================================================
   4. Scroll-reveal — opacity 0 → 1 + translateY 40 → 0
   Toggle .is-in (set by IntersectionObserver) to play.
   ========================================================= */
.viv-reveal {
  opacity: 0;
  transform: translateY(var(--rise-lg));
  transition:
    opacity var(--motion-soft) var(--ease-out),
    transform var(--motion-soft) var(--ease-out);
  will-change: opacity, transform;
}
.viv-reveal.is-in {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger children — give each child its own delay */
.viv-reveal-stagger > * {
  opacity: 0;
  transform: translateY(var(--rise-lg));
  transition:
    opacity var(--motion-soft) var(--ease-out),
    transform var(--motion-soft) var(--ease-out);
}
.viv-reveal-stagger.is-in > *:nth-child(1)  { transition-delay: calc(var(--stagger-base) * 0); }
.viv-reveal-stagger.is-in > *:nth-child(2)  { transition-delay: calc(var(--stagger-base) * 1); }
.viv-reveal-stagger.is-in > *:nth-child(3)  { transition-delay: calc(var(--stagger-base) * 2); }
.viv-reveal-stagger.is-in > *:nth-child(4)  { transition-delay: calc(var(--stagger-base) * 3); }
.viv-reveal-stagger.is-in > *:nth-child(5)  { transition-delay: calc(var(--stagger-base) * 4); }
.viv-reveal-stagger.is-in > *:nth-child(6)  { transition-delay: calc(var(--stagger-base) * 5); }
.viv-reveal-stagger.is-in > *:nth-child(7)  { transition-delay: calc(var(--stagger-base) * 6); }
.viv-reveal-stagger.is-in > *:nth-child(8)  { transition-delay: calc(var(--stagger-base) * 7); }
.viv-reveal-stagger.is-in > * {
  opacity: 1;
  transform: translateY(0);
}

/* =========================================================
   5. Headings — clip-path reveal (text slides up from behind a mask)
   Wrap each line in <span class="viv-line"><span>...</span></span>
   ========================================================= */
.viv-line {
  display: block;
  overflow: hidden;
  line-height: 1.1;
}
.viv-line > * {
  display: inline-block;
  transform: translateY(110%);
  transition: transform var(--motion-base) var(--ease-cinematic);
}
.viv-clip-reveal.is-in .viv-line:nth-child(1) > * { transition-delay: calc(var(--stagger-loose) * 0); transform: translateY(0); }
.viv-clip-reveal.is-in .viv-line:nth-child(2) > * { transition-delay: calc(var(--stagger-loose) * 1); transform: translateY(0); }
.viv-clip-reveal.is-in .viv-line:nth-child(3) > * { transition-delay: calc(var(--stagger-loose) * 2); transform: translateY(0); }
.viv-clip-reveal.is-in .viv-line:nth-child(4) > * { transition-delay: calc(var(--stagger-loose) * 3); transform: translateY(0); }

/* =========================================================
   6. Eyebrow labels — letter-spacing expansion
   PROJECT / ARCHITECT / LOCATION animate in first
   ========================================================= */
@keyframes viv-eyebrow-in {
  from { opacity: 0; letter-spacing: 0; }
  to   { opacity: 1; letter-spacing: 0.18em; }
}
.viv-eyebrow {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  color: var(--fg-2);
  display: inline-block;
}
.viv-eyebrow.is-in {
  animation: viv-eyebrow-in var(--motion-base) var(--ease-out) both;
}

/* =========================================================
   7. Divider line — expand left → right
   ========================================================= */
.viv-divider {
  display: block;
  width: 100%;
  height: 1px;
  background: rgba(255,255,255,0.3);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--motion-base) var(--ease-out);
}
.viv-divider.is-in { transform: scaleX(1); }

/* =========================================================
   8. Gallery image — fade up + hover scale + brightness
   ========================================================= */
.viv-gallery-img {
  opacity: 0;
  transform: translateY(var(--rise-md));
  transition:
    opacity var(--motion-soft) var(--ease-in-out),
    transform var(--motion-soft) var(--ease-in-out),
    filter var(--motion-quick) var(--ease-out);
  filter: saturate(0.92);
  will-change: opacity, transform, filter;
}
.viv-gallery-img.is-in {
  opacity: 1;
  transform: translateY(0);
  filter: saturate(1);
}
.viv-gallery-img-wrap {
  overflow: hidden;
  display: block;
  cursor: zoom-in;
}
.viv-gallery-img-wrap > img,
.viv-gallery-img-wrap > .viv-gallery-img {
  transition:
    transform 400ms var(--ease-out),
    filter 400ms var(--ease-out),
    opacity var(--motion-soft) var(--ease-in-out);
}
.viv-gallery-img-wrap:hover > img,
.viv-gallery-img-wrap:hover > .viv-gallery-img {
  transform: scale(1.03);
  filter: brightness(1.06) saturate(1);
}

/* =========================================================
   9. Lightbox — fade + slight zoom entrance
   ========================================================= */
@keyframes viv-lightbox-in {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1.00); }
}
.viv-lightbox {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(0,0,0,0.92);
  display: flex; align-items: center; justify-content: center;
  animation: viv-lightbox-in var(--motion-base) var(--ease-cinematic) both;
}
.viv-lightbox img { max-width: 92vw; max-height: 92vh; display: block; }

/* =========================================================
   10. Sticky nav — shrink + glassmorphism on scroll
   Toggle .is-scrolled on the nav (set by JS at scrollY > 32)
   ========================================================= */
.viv-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  height: 96px;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 64px;
  background: transparent;
  backdrop-filter: blur(0);
  transition:
    height var(--motion-quick) var(--ease-out),
    background-color var(--motion-quick) var(--ease-out),
    backdrop-filter var(--motion-quick) var(--ease-out),
    border-color var(--motion-quick) var(--ease-out);
  border-bottom: 1px solid transparent;
}
.viv-nav.is-scrolled {
  height: 64px;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  border-bottom-color: rgba(255,255,255,0.08);
}
.viv-nav .viv-wordmark {
  transition: font-size var(--motion-quick) var(--ease-out);
}
.viv-nav.is-scrolled .viv-wordmark { font-size: 20px; }

/* =========================================================
   11. Footer link list — staggered fade-in from bottom (0.08s)
   ========================================================= */
.viv-footer-list > * {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--motion-soft) var(--ease-out),
    transform var(--motion-soft) var(--ease-out);
}
.viv-footer-list.is-in > *:nth-child(1) { transition-delay: calc(var(--stagger-tight) * 0); }
.viv-footer-list.is-in > *:nth-child(2) { transition-delay: calc(var(--stagger-tight) * 1); }
.viv-footer-list.is-in > *:nth-child(3) { transition-delay: calc(var(--stagger-tight) * 2); }
.viv-footer-list.is-in > *:nth-child(4) { transition-delay: calc(var(--stagger-tight) * 3); }
.viv-footer-list.is-in > *:nth-child(5) { transition-delay: calc(var(--stagger-tight) * 4); }
.viv-footer-list.is-in > *:nth-child(6) { transition-delay: calc(var(--stagger-tight) * 5); }
.viv-footer-list.is-in > *:nth-child(7) { transition-delay: calc(var(--stagger-tight) * 6); }
.viv-footer-list.is-in > * { opacity: 1; transform: translateY(0); }

/* =========================================================
   Reduced motion — respect user preference
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  .viv-page-enter,
  .viv-hero-img,
  .viv-parallax,
  .viv-reveal,
  .viv-reveal-stagger > *,
  .viv-line > *,
  .viv-eyebrow,
  .viv-divider,
  .viv-gallery-img,
  .viv-footer-list > *,
  .viv-lightbox {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
}
