/* ============================================================
   INSTALLIFY — MOTION.CSS  (one motion system, loaded after the page CSS)
   Principles: transform + opacity only · fast · subtle · nothing is hidden without JS or when motion is reduced.
   Tokens: ease / durations below are the ONLY timing values used in this file.
   ============================================================ */
:root {
  --mo-ease: cubic-bezier(.22, 1, .36, 1);
  --mo-hover: 180ms; --mo-btn: 220ms; --mo-card: 320ms; --mo-nav: 280ms;
  --mo-reveal: 650ms; --mo-image: 850ms; --mo-hero: 900ms;
}

/* ---- page transition: 140 ms fade-in on load (no delay on navigation) ---- */
@keyframes moPageIn { from { opacity: 0; } to { opacity: 1; } }
body { animation: moPageIn 140ms ease-out both; }

/* ---- hero entrance: CSS only, so it never waits for JavaScript ---- */
@keyframes moRise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
.hero-text.fade-up { opacity: 1; transform: none; transition: none; }          /* children animate instead */
.hero-text > * { animation: moRise var(--mo-hero) var(--mo-ease) both; }
.hero-text > :nth-child(1) { animation-delay: 0ms; }
.hero-text > :nth-child(2) { animation-delay: 150ms; }
.hero-text > :nth-child(3) { animation-delay: 300ms; }
.hero-text > :nth-child(4) { animation-delay: 450ms; }
.hero-text > :nth-child(n+5) { animation-delay: 550ms; }
.hero-img.fade-up { opacity: 1; transform: none; transition: none; animation: moRise var(--mo-hero) var(--mo-ease) 200ms both; }
/* Ken Burns (18 s, ~4.5 %) — parallax uses the separate `translate` property so the two never fight */
@keyframes moKenBurns { from { transform: scale(1); } to { transform: scale(1.045); } }
.hero-img img { animation: moKenBurns 18s ease-in-out infinite alternate; will-change: transform; }

/* ---- scroll reveal (existing .fade-up, refined timing; observer lives in main.js) ---- */
.fade-up { transition: opacity var(--mo-reveal) var(--mo-ease), transform var(--mo-reveal) var(--mo-ease); }

/* ---- image mask reveal (left -> right) on selected images; only active once motion.js is running ---- */
.mo-js .mo-mask img { clip-path: inset(0 100% 0 0); transition: clip-path var(--mo-image) var(--mo-ease), transform 600ms var(--mo-ease); }
.mo-js .mo-mask.mo-in img { clip-path: inset(0 0 0 0); }

/* ---- cards (homepage services row, product cards, website + Google review cards) ---- */
.service-card, .product-card, .review-card, .g-card { transition: transform var(--mo-card) var(--mo-ease), box-shadow var(--mo-card) var(--mo-ease); }
.svc-img img, .svc-block-img img { transition: transform 600ms var(--mo-ease); }
.svc-body h3 { transition: transform var(--mo-card) var(--mo-ease); }
.service-card .btn::after { content: '\2192'; display: inline-block; margin-left: 8px; transition: transform var(--mo-btn) var(--mo-ease); }
@media (hover: hover) and (pointer: fine) {
  .service-card:hover { transform: translateY(-5px); box-shadow: 0 14px 32px rgba(0,0,0,.16); }
  .service-card:hover .svc-img img { transform: scale(1.04) translateY(-2px); }
  .service-card:hover .svc-body h3 { transform: translateX(3px); }
  .service-card .btn:hover::after, .service-card:hover .btn::after { transform: translateX(4px); }
  .review-card:hover, .g-card:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(0,0,0,.14); }
}
.service-card:focus-within { box-shadow: 0 10px 24px rgba(0,0,0,.14); }
@media (hover: none) { .service-card:active { transform: scale(.985); } }   /* tap feedback, no extra tap needed */

/* ---- buttons ---- */
.btn, .nav-cta { transition: transform var(--mo-btn) var(--mo-ease), box-shadow var(--mo-btn) var(--mo-ease), background-color var(--mo-btn), color var(--mo-btn); }
.btn:active, .nav-cta:active { transform: scale(.97); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover, .nav-cta:hover { transform: scale(1.02); box-shadow: 0 8px 20px rgba(0,0,0,.2); }
  .btn i.fa-arrow-right, .btn i.fa-chevron-right { transition: transform var(--mo-btn) var(--mo-ease); }
  .btn:hover i.fa-arrow-right, .btn:hover i.fa-chevron-right { transform: translateX(3px); }
}
/* restrained gold light-sweep: only on primary yellow CTAs, only on hover (+ once on the hero CTA) */
.btn-yellow, .nav-cta { position: relative; overflow: hidden; isolation: isolate; }
.btn-yellow::before, .nav-cta::before { content: ''; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%; z-index: -1; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.42), transparent); transform: skewX(-18deg) translateX(0); opacity: 0; }
@keyframes moSweep { 0% { transform: skewX(-18deg) translateX(0); opacity: 0; } 15% { opacity: 1; } 100% { transform: skewX(-18deg) translateX(520%); opacity: 0; } }
@media (hover: hover) and (pointer: fine) { .btn-yellow:hover::before, .nav-cta:hover::before { animation: moSweep 750ms var(--mo-ease) both; } }
.hero-btns .btn-yellow::before { animation: moSweep 1100ms var(--mo-ease) 1400ms 1 both; }   /* one sweep after the hero has settled */

/* ---- navigation ---- */
.nav-inner { transition: padding var(--mo-nav) var(--mo-ease); }
.navbar.is-compact .nav-inner { padding-top: 7px; padding-bottom: 7px; }
@media (min-width: 769px) {
  .nav-links > li > a:not(.nav-cta) { position: relative; }
  .nav-links > li > a:not(.nav-cta)::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: 2px; height: 2px; background: var(--yellow); border-radius: 2px;
    transform: scaleX(0); transform-origin: left center; transition: transform var(--mo-nav) var(--mo-ease); }
  .nav-links > li > a[aria-current="page"]::after, .nav-links > li > a:hover::after { transform: scaleX(1); }
}

/* ---- scroll progress (2 px) ---- */
.mo-progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 9997; pointer-events: none; background: var(--yellow); transform: scaleX(0); transform-origin: left center; will-change: transform; }

/* ---- logo (home, first visit of the session only) ---- */
@keyframes moLogo { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
.nav-logo.mo-logo-in { animation: moLogo 650ms var(--mo-ease) both; }

/* ---- Luminarvis product: reveal, gentle float, hover zoom ---- */
@keyframes moFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
.ph-img { animation: moFloat 4.6s ease-in-out infinite; }
.ph-img img, .ap-img img { transition: transform 600ms var(--mo-ease); }
@media (hover: hover) and (pointer: fine) { .ph-img:hover img, .ap-img:hover img { transform: scale(1.04); } }
@media (max-width: 768px) { .ph-img { animation-name: moFloatSm; } }
@keyframes moFloatSm { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* ---- services galleries: calmer outer edges (soft fade) ---- */
.svc-gallery { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%); mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%); }
/* touch devices: swipeable row; motion.js/services-gallery.js drives the slow auto-scroll and yields to the finger */
.svc-gallery.is-touch { overflow-x: auto; overflow-y: hidden; touch-action: pan-x pan-y; scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; }
.svc-gallery.is-touch::-webkit-scrollbar { display: none; }
.svc-gallery.is-touch .svc-gallery-track { animation: none; transform: none; }

/* ---- services hero slideshow: crossfade 1.2 s + slow Ken Burns on the active slide ---- */
.svc-hero-img.has-slides .svc-slide { transform: scale(1); transition: opacity 1.2s ease, transform 0s linear 1.2s; }
.svc-hero-img.has-slides .svc-slide.is-active { transform: scale(1.05); transition: opacity 1.2s ease, transform 9s linear; }
@media (max-width: 768px) { .svc-hero-img.has-slides .svc-slide.is-active { transform: scale(1.025); } }

/* ---- review carousel (website + Google cards): swipe on touch, arrows + dots everywhere ---- */
.mo-carousel { display: flex !important; grid-template-columns: none !important; overflow-x: auto; scroll-snap-type: x mandatory; gap: 14px; scrollbar-width: none; overscroll-behavior-x: contain; padding: 4px 2px 10px; margin-bottom: 8px; }
.mo-carousel::-webkit-scrollbar { display: none; }
.mo-carousel > * { flex: 0 0 100%; max-width: 100%; scroll-snap-align: start; min-width: 0; }
@media (min-width: 640px)  { .mo-carousel > * { flex-basis: calc((100% - 14px) / 2); } }
@media (min-width: 1024px) { .mo-carousel > * { flex-basis: calc((100% - 28px) / 3); } }
.mo-car-ctrl { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 0 0 22px; }
.mo-car-btn { width: 40px; height: 40px; border-radius: 50%; border: 0; background: var(--yellow); color: #111; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; transition: transform var(--mo-btn) var(--mo-ease), opacity var(--mo-btn); }
.mo-car-btn:disabled { opacity: .35; cursor: default; }
.mo-car-btn:focus-visible, .mo-car-dot:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; }
.mo-car-dots { display: flex; gap: 2px; }
.mo-car-dot { width: 24px; height: 24px; padding: 0; border: 0; background: transparent; cursor: pointer; position: relative; }
.mo-car-dot::after { content: ''; position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: currentColor; opacity: .3; transition: opacity var(--mo-hover), transform var(--mo-hover); }
.mo-car-dot[aria-current="true"]::after { opacity: 1; transform: scale(1.3); }
.mo-car-ctrl { color: var(--green); } .section--dark .mo-car-ctrl { color: var(--yellow); }
/* card entrance when reviews load */
@keyframes moCardIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.mo-js .review-card, .mo-js .g-card { animation: moCardIn 450ms var(--mo-ease) both; }
/* Google stars: sequential reveal, once */
.mo-js .g-card:not(.is-seen) .g-star { opacity: 0; transform: scale(.5); }
.g-star { display: inline-block; transition: opacity 220ms ease, transform 260ms var(--mo-ease); transition-delay: calc(var(--i, 0) * 70ms); }

/* ---- reduced motion: keep every piece of content and control, remove the movement ---- */
@media (prefers-reduced-motion: reduce) {
  body, .hero-text > *, .hero-img.fade-up, .hero-img img, .ph-img, .nav-logo.mo-logo-in, .review-card, .g-card { animation: none !important; }
  .mo-js .mo-mask img { clip-path: none !important; transition: none !important; }
  .mo-js .g-card:not(.is-seen) .g-star { opacity: 1 !important; transform: none !important; }
  .btn-yellow::before, .nav-cta::before { display: none; }
  .mo-progress { display: none; }
  .mo-carousel { scroll-behavior: auto; }
  .svc-hero-img.has-slides .svc-slide, .svc-hero-img.has-slides .svc-slide.is-active { transform: none !important; }
}

/* cards that are also scroll-reveal elements keep BOTH transitions */
.service-card.fade-up, .product-card.fade-up { transition: opacity var(--mo-reveal) var(--mo-ease), transform var(--mo-card) var(--mo-ease), box-shadow var(--mo-card) var(--mo-ease); }
.service-card.fade-up:not(.visible), .product-card.fade-up:not(.visible) { transition: opacity var(--mo-reveal) var(--mo-ease), transform var(--mo-reveal) var(--mo-ease); }
.mo-car-dot { color: inherit; }
