/* ==========================================================================
   Exeter Plumbing Co. — motion layer
   Active only when <html> has .motion (set by a tiny inline script in <head>
   unless the visitor prefers reduced motion). One timing system throughout:
   0.6s ease-out reveals fired 20% into the viewport, 40ms word stagger.
   Every effect is a keyframe animation with `backwards` fill, so elements
   settle into their normal styles afterwards and hover transitions survive.
   ========================================================================== */
:root {
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-slide: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-wipe: cubic-bezier(0.76, 0, 0.24, 1);
  --ease-pop: cubic-bezier(0.22, 0.68, 0, 1.2);
}

/* ---------- Foundation: Lenis smooth scroll, no bounce, thin scrollbar ---------- */
html,
body { overscroll-behavior: none; }
html { scrollbar-width: thin; scrollbar-color: rgba(9, 38, 49, 0.32) transparent; }
html.lenis,
html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto !important; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ---------- Keyframes ---------- */
@keyframes rv-up { from { opacity: 0; translate: 0 26px; } }
@keyframes rv-left { from { opacity: 0; translate: -48px 0; } }
@keyframes rv-fade { from { opacity: 0; } }
@keyframes word-up { from { opacity: 0; translate: 0 0.42em; } }
@keyframes media-in { from { opacity: 0; translate: 0 32px; } }
@keyframes img-settle { from { scale: 1.08; } }
@keyframes img-settle-px { from { scale: 1.2; } }
@keyframes hero-zoom { from { scale: 1.08; } }
@keyframes pop-in { from { opacity: 0; scale: 0.2; } }
@keyframes pipe-draw { from { transform: translateX(-50%) scaleX(0); } }
@keyframes pipe-draw-v { from { transform: scaleY(0); } }
@keyframes sheet-in { from { opacity: 0; translate: 0 70px; rotate: 7deg; } }
@keyframes stamp-in { from { opacity: 0; scale: 2.2; rotate: -28deg; } }
@keyframes badge-in { from { opacity: 0; translate: -28px 0; } }
@keyframes shimmer { 0%, 55% { background-position: 160% 0, 0 0; } 100% { background-position: -60% 0, 0 0; } }

/* ---------- Load sequence: home hero ---------- */
.motion .hero__media img { animation: hero-zoom 1.3s var(--ease-out) backwards; }
.motion .hero__content > .eyebrow { animation: rv-up 0.8s var(--ease-out) 0.1s backwards; }
.motion .hero__lead { animation: rv-up 0.8s var(--ease-out) 0.55s backwards; }
.motion .hero__actions { animation: rv-up 0.8s var(--ease-out) 0.7s backwards; }

/* ---------- Load sequence: inner page intros ---------- */
.motion .page-intro .breadcrumb { animation: rv-fade 0.6s var(--ease-out) backwards; }
.motion .page-intro .eyebrow { animation: rv-up 0.7s var(--ease-out) 0.08s backwards; }
.motion .intro-split__body,
.motion .services-intro__text > .lead { animation: rv-up 0.8s var(--ease-out) 0.45s backwards; }
.motion .services-intro__text > .btn { animation: rv-up 0.8s var(--ease-out) 0.6s backwards; }
.motion .page-intro .media-caption,
.motion .team-hero__caption { animation: rv-fade 0.8s var(--ease-out) 0.9s backwards; }
.motion .jump,
.motion .filter-bar { animation: rv-up 0.8s var(--ease-out) 0.7s backwards; }
/* The top-of-page photo is each page's largest paint: a quick fade keeps LCP early. */
.motion .services-intro__media .media,
.motion .team-hero .media,
.motion .featured__media { animation: rv-fade 0.45s var(--ease-out) 0.05s backwards; }
.motion .services-intro__media .media img,
.motion .team-hero .media img,
.motion .featured__media img { animation: img-settle-px 0.9s var(--ease-out) 0.05s backwards; }

/* Headings are split into words by motion.js; keep them hidden until then. */
.motion .hero h1:not(.wsplit),
.motion .page-intro h1:not(.wsplit) { opacity: 0; }

/* ---------- Word-stagger headings ---------- */
.motion .wsplit .w { display: inline-block; }
.motion .wsplit:not(.is-in) .w { opacity: 0; }
.motion .wsplit.is-in .w {
  animation: word-up 0.7s var(--ease-slide) calc(var(--wi, 0) * 40ms + var(--split-delay, 0ms)) backwards;
}

/* ---------- Scroll reveals ---------- */
.motion .rv:not(.is-in) { opacity: 0; }
.motion .rv.is-in { animation: rv-up 0.6s var(--ease-out) var(--rv-delay, 0s) backwards; }
.motion .rv-x:not(.is-in) { opacity: 0; }
.motion .rv-x.is-in { animation: rv-left 0.8s var(--ease-out) var(--rv-delay, 0s) backwards; }

/* Photos: a quick lift-and-fade while the image eases out of a gentle zoom (~0.6s). */
.motion .rv-media:not(.is-in) { opacity: 0; }
.motion .rv-media.is-in { animation: media-in 0.6s var(--ease-out) var(--rv-delay, 0s) backwards; }
.motion .rv-media.is-in img { animation: img-settle 0.9s var(--ease-out) var(--rv-delay, 0s) backwards; }
.motion .rv-media.px.is-in img { animation-name: img-settle-px; }

/* Parallax photos sit slightly enlarged so the drift never shows an edge. */
.motion .px img { scale: 1.12; }

/* ---------- Home: promises pipe draws in, couplings pop on ---------- */
.motion .promises:not(.is-in) .promises__list::before,
.motion .promises:not(.is-in) .promise__fitting,
.motion .promises:not(.is-in) .promise > :not(.promise__fitting) { opacity: 0; }
.motion .promises.is-in .promises__list::before { animation: pipe-draw 1.4s var(--ease-wipe) backwards; }
.motion .promises.is-in .promise__fitting { animation: pop-in 0.55s var(--ease-pop) calc(0.45s + var(--i, 0) * 0.28s) backwards; }
.motion .promises.is-in .promise > :not(.promise__fitting) { animation: rv-up 0.7s var(--ease-out) calc(0.6s + var(--i, 0) * 0.28s) backwards; }

/* ---------- Home: room explorer hotspots pop in ---------- */
.motion .rooms:not(.is-in) .rooms__spot { opacity: 0; }
.motion .rooms.is-in .rooms__spot { animation: pop-in 0.6s var(--ease-pop) calc(0.7s + var(--i, 0) * 0.14s) backwards; }

/* ---------- Testimonial job sheet slides in, stamp thumps down ---------- */
.motion .review:not(.is-in) .job-sheet,
.motion .review:not(.is-in) .job-sheet__stamp { opacity: 0; }
.motion .review.is-in .job-sheet { animation: sheet-in 1s var(--ease-out) 0.2s backwards; }
.motion .review.is-in .job-sheet__stamp { animation: stamp-in 0.45s var(--ease-pop) 1.15s backwards; }
.motion .fill .w { display: inline-block; opacity: 0.18; }

/* ---------- About: name badges slide out after the portrait ---------- */
.motion .member:not(.is-in) .member__tag { opacity: 0; }
.motion .member.is-in .member__tag { animation: badge-in 0.7s var(--ease-out) calc(0.55s + var(--rv-delay, 0s)) backwards; }

/* ---------- Header: hide on scroll down, copper progress line ---------- */
.motion .site-header { transition: translate 0.45s var(--ease-out), box-shadow 0.3s var(--ease-out); }
.motion .site-header.is-hidden { translate: 0 -100%; }
.motion .site-header.is-scrolled { box-shadow: 0 12px 30px -20px rgba(9, 38, 49, 0.45); }
.motion .site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: linear-gradient(90deg, #a94a22, #e08a55 45%, #ffd9b5 70%, #d8804a);
  transform: scaleX(var(--progress, 0));
  transform-origin: left center;
  pointer-events: none;
}

/* ---------- Magnetic buttons (fine pointers only; JS sets translate) ---------- */
.motion .btn.magnetic {
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease), translate 0.5s var(--ease-out);
}
.motion .circle-btn.magnetic {
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease), translate 0.5s var(--ease-out);
}

/* ---------- Footer: copper sheen on the slogan, reveal from behind ---------- */
.motion .footer-mark span {
  background:
    linear-gradient(105deg, transparent 38%, rgba(255, 244, 232, 0.85) 50%, transparent 62%) no-repeat,
    linear-gradient(180deg, #ffd9b5 0%, #e9935c 32%, #b8592c 62%, #e59b67 100%);
  background-size: 260% 100%, 100% 100%;
  background-position: 160% 0, 0 0;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: shimmer 6s var(--ease-slide) 1s infinite;
}
.footer-reveal main {
  position: relative;
  z-index: 1;
  background: var(--ivory);
  box-shadow: 0 40px 60px -40px rgba(0, 20, 24, 0.6);
}
.footer-reveal .site-footer {
  position: sticky;
  bottom: 0;
  z-index: 0;
}

@media (max-width: 720px) {
  .motion .promises.is-in .promises__list::before { animation-name: pipe-draw-v; transform-origin: center top; }
}

/* ---------- Page transitions between routes (cross-document) ---------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
  ::view-transition-old(root) { animation: vt-out 0.32s var(--ease-wipe) both; }
  ::view-transition-new(root) { animation: vt-in 0.6s var(--ease-out) both; }
}
@keyframes vt-out { to { opacity: 0; transform: translateY(-18px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(28px); } }
