/* ==========================================================================
   animations.css — reusable motion layer
   --------------------------------------------------------------------------
   Load AFTER styles.css. All motion for the site lives here so timing stays
   consistent and the utilities can be dropped onto any other page.

   1. Tokens            — durations, easings, distances
   2. Keyframes         — reusable, prefixed `a-`
   3. Entrance (load)   — `.enter`, `.enter--*`, `.u-delay-*`
   4. Entrance (scroll) — `.reveal`, `.reveal--*`, `.reveal-group`
   5. Interaction       — `.u-lift`, `.u-press`, `.u-zoom`, `.u-underline`
   6. Component motion  — hover/focus/active states for existing components
   7. Reduced motion    — honours prefers-reduced-motion: reduce
   ========================================================================== */

/* ---------- 1. Tokens ---------------------------------------------------- */

:root {
  /* Easing */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);      /* default: decelerating */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);   /* symmetric moves */
  --ease-spring: cubic-bezier(0.34, 1.28, 0.64, 1);/* small playful pops */

  /* Durations */
  --dur-1: 150ms;   /* micro — colour, opacity */
  --dur-2: 260ms;   /* default — hover, transform */
  --dur-3: 400ms;   /* larger UI moves */
  --dur-enter: 700ms;

  /* Entrance choreography */
  --stagger: 90ms;
  --delay: 0ms;
  --shift: 24px;    /* travel distance for entrance animations */

  /* Interaction */
  --lift: -5px;
  --shadow-hover: 0 18px 38px -22px oklch(0.24 0.02 55 / 0.55);
  --shadow-hover-dark: 0 18px 38px -20px oklch(0.1 0.02 55 / 0.7);
}

/* ---------- 2. Keyframes ------------------------------------------------- */

@keyframes a-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes a-fade-up {
  from { opacity: 0; transform: translateY(var(--shift)); }
  to   { opacity: 1; transform: none; }
}
@keyframes a-fade-down {
  from { opacity: 0; transform: translateY(calc(var(--shift) * -1)); }
  to   { opacity: 1; transform: none; }
}
@keyframes a-fade-left {
  from { opacity: 0; transform: translateX(calc(var(--shift) * -1)); }
  to   { opacity: 1; transform: none; }
}
@keyframes a-fade-right {
  from { opacity: 0; transform: translateX(var(--shift)); }
  to   { opacity: 1; transform: none; }
}
@keyframes a-zoom-in {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: none; }
}
@keyframes a-settle {
  /* slow, one-shot background settle — cinematic without being distracting */
  from { transform: scale(1.06); }
  to   { transform: scale(1); }
}
@keyframes a-pulse-ring {
  0%   { opacity: 0.45; transform: translate(-50%, -50%) scale(1); }
  70%  { opacity: 0;    transform: translate(-50%, -50%) scale(1.7); }
  100% { opacity: 0;    transform: translate(-50%, -50%) scale(1.7); }
}
@keyframes a-dot-pulse {
  from { opacity: 0.45; }
  to   { opacity: 1; }
}

/* ---------- 3. Entrance on load ------------------------------------------ */
/* `both` fill means these are safe without JS — they always end visible.     */

.enter {
  animation: a-fade-up var(--dur-enter) var(--ease-out) var(--delay) both;
}
.enter--fade  { animation-name: a-fade; }
.enter--down  { animation-name: a-fade-down; }
.enter--left  { animation-name: a-fade-left; }
.enter--right { animation-name: a-fade-right; }
.enter--zoom  { animation-name: a-zoom-in; }

/* Delay utilities — shared by .enter and .reveal */
.u-delay-1 { --delay: calc(var(--stagger) * 1); }
.u-delay-2 { --delay: calc(var(--stagger) * 2); }
.u-delay-3 { --delay: calc(var(--stagger) * 3); }
.u-delay-4 { --delay: calc(var(--stagger) * 4); }
.u-delay-5 { --delay: calc(var(--stagger) * 5); }
.u-delay-6 { --delay: calc(var(--stagger) * 6); }

/* ---------- 4. Entrance on scroll ---------------------------------------- */
/* Gated behind `.js` so content stays visible if scripting is unavailable.
   `.reveal`       — single element
   `.reveal-group` — observe the container, children cascade automatically   */

.js .reveal,
.js .reveal-group > * {
  opacity: 0;
  transition:
    opacity var(--dur-enter) var(--ease-out) var(--delay),
    transform var(--dur-enter) var(--ease-out) var(--delay);
  will-change: opacity, transform;
}

.js .reveal,
.js .reveal-group > * { transform: translateY(var(--shift)); }
.js .reveal--down     { transform: translateY(calc(var(--shift) * -1)); }
.js .reveal--left     { transform: translateX(calc(var(--shift) * -1)); }
.js .reveal--right    { transform: translateX(var(--shift)); }
.js .reveal--zoom     { transform: scale(0.96); }
.js .reveal--fade     { transform: none; }

.js .reveal.is-visible,
.js .reveal-group.is-visible > * {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Cascade for grouped children (covers up to 8 items, then holds) */
.reveal-group > *:nth-child(1) { --delay: 0ms; }
.reveal-group > *:nth-child(2) { --delay: calc(var(--stagger) * 1); }
.reveal-group > *:nth-child(3) { --delay: calc(var(--stagger) * 2); }
.reveal-group > *:nth-child(4) { --delay: calc(var(--stagger) * 3); }
.reveal-group > *:nth-child(5) { --delay: calc(var(--stagger) * 4); }
.reveal-group > *:nth-child(6) { --delay: calc(var(--stagger) * 5); }
.reveal-group > *:nth-child(7) { --delay: calc(var(--stagger) * 6); }
.reveal-group > *:nth-child(n + 8) { --delay: calc(var(--stagger) * 7); }

/* ---------- 5. Interaction utilities ------------------------------------- */

.u-lift {
  transition:
    transform var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out);
}
.u-lift:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow-hover); }

.u-press { transition: transform var(--dur-1) var(--ease-out); }
.u-press:active { transform: scale(0.975); }

/* Image zoom — put on the (overflow: hidden) wrapper, not the image */
.u-zoom { overflow: hidden; }
.u-zoom img { transition: transform var(--dur-3) var(--ease-out); }
.u-zoom:hover img { transform: scale(1.05); }

/* Sweeping underline for text links */
.u-underline { position: relative; }
.u-underline::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease-out);
}
.u-underline:hover::after,
.u-underline:focus-visible::after { transform: scaleX(1); }

/* ---------- 6. Component motion ------------------------------------------ */

/* Focus visibility — consistent, keyboard-only */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Hero */
.hero__bg { animation: a-settle 1800ms var(--ease-out) both; }
.eyebrow--pill .dot { animation: a-dot-pulse 1.8s var(--ease-in-out) infinite alternate; }

/* Eyebrow rule draws itself in as its section arrives. Defaults to drawn, so
   it degrades safely anywhere the reveal utilities aren't used. */
.eyebrow .rule {
  transform-origin: left center;
  transition: transform var(--dur-3) var(--ease-out) calc(var(--delay) + 200ms);
}
.js .reveal:not(.is-visible) .eyebrow .rule,
.js .reveal-group:not(.is-visible) .eyebrow .rule { transform: scaleX(0); }

/* Nav */
.nav__links a:not(.nav__cta) {
  position: relative;
  transition: color var(--dur-1) var(--ease-out);
}
.nav__links a:not(.nav__cta)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -5px;
  width: 100%;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease-out);
}
.nav__links a:not(.nav__cta):hover::after { transform: scaleX(1); }

.nav__toggle span {
  transition:
    transform var(--dur-2) var(--ease-out),
    opacity var(--dur-1) linear;
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; transform: scaleX(0.3); }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Buttons */
.btn,
.contact__form button {
  transition:
    opacity var(--dur-1) var(--ease-out),
    background-color var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out);
}
.btn:hover,
.contact__form button:hover { transform: translateY(-2px); }
.btn--accent:hover,
.contact__form button:hover { box-shadow: 0 12px 26px -14px oklch(0.68 0.13 75 / 0.85); }
.btn:active,
.contact__form button:active { transform: translateY(0) scale(0.98); }

.arrow-circle { transition: transform var(--dur-2) var(--ease-spring); }
.btn--arrow:hover .arrow-circle { transform: translate(3px, -3px); }

/* Feature columns */
.feature-icon { transition: transform var(--dur-3) var(--ease-spring), border-color var(--dur-2) var(--ease-out); }
.feature-col:hover .feature-icon { transform: scale(1.1); }
.feature-col:hover .feature-icon--diamond { transform: rotate(45deg) scale(1.1); }

/* Checklist */
.checklist .bullet { transition: transform var(--dur-2) var(--ease-spring); }
.checklist li:hover .bullet { transform: rotate(45deg) scale(1.2); }

/* Service rows */
.service-row > div { transition: transform var(--dur-2) var(--ease-out); }
.service-row h3 { transition: color var(--dur-1) var(--ease-out); }
.service-row .arrow { transition: transform var(--dur-2) var(--ease-out); }
.service-row:hover > div { transform: translateX(6px); }
.service-row:hover h3 { color: var(--accent); }
.service-row:hover .arrow { transform: translateX(6px); }

/* Process steps */
.process-step__number {
  transition:
    transform var(--dur-2) var(--ease-spring),
    background-color var(--dur-2) var(--ease-out),
    color var(--dur-2) var(--ease-out);
}
.process-step:hover .process-step__number {
  transform: scale(1.08);
  background: var(--accent);
  color: var(--cream);
}

/* Gallery */
.gallery-item {
  transition:
    transform var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out);
}
.gallery-item:hover { transform: translateY(var(--lift)); }
.gallery-item__label { transition: color var(--dur-1) var(--ease-out); }
.gallery-item:hover .gallery-item__label { color: var(--accent); }

/* Compare widget */
.compare__handle { transition: transform var(--dur-2) var(--ease-spring); }
.compare:hover .compare__handle { transform: translate(-50%, -50%) scale(1.1); }
.compare__handle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 1px solid var(--cream);
  transform: translate(-50%, -50%);
  animation: a-pulse-ring 2600ms var(--ease-out) infinite;
  pointer-events: none;
}
.compare:hover .compare__handle::after { animation-play-state: paused; opacity: 0; }

.compare__tag { transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out); }
.compare:hover .compare__tag { opacity: 0.55; }

.compare { transition: box-shadow var(--dur-2) var(--ease-out); }
.compare:has(.compare__range:focus-visible) { box-shadow: 0 0 0 2px var(--accent); }

/* Testimonials */
.testimonial-card {
  transition:
    transform var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out);
}
.testimonial-card:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow-hover); }
.testimonial-card__avatar { transition: transform var(--dur-2) var(--ease-spring); }
.testimonial-card:hover .testimonial-card__avatar { transform: scale(1.08); }

/* Contact form */
.contact__form input,
.contact__form select,
.contact__form textarea {
  transition:
    border-color var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out),
    background-color var(--dur-2) var(--ease-out);
}
.contact__form input:focus,
.contact__form select:focus,
.contact__form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px oklch(0.68 0.13 75 / 0.22);
}

/* Footer */
.footer__col a {
  transition:
    color var(--dur-1) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
}
.footer__col a:hover { transform: translateX(4px); }

.social-icon {
  transition:
    background-color var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    color var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-spring);
}
.social-icon:hover { transform: translateY(-3px); }

/* ---------- Responsive tuning -------------------------------------------- */
/* Shorter travel on small screens keeps motion from feeling sluggish and
   guarantees no horizontal overflow from translated elements.               */

@media (max-width: 640px) {
  :root {
    --shift: 16px;
    --stagger: 70ms;
    --dur-enter: 600ms;
    --lift: -4px;
  }
}

/* Mobile menu items cascade in with the panel */
@media (max-width: 860px) {
  .nav__links a {
    opacity: 0;
    transform: translateY(-6px);
    transition:
      opacity var(--dur-2) var(--ease-out) var(--delay),
      transform var(--dur-2) var(--ease-out) var(--delay);
  }
  .nav__links.is-open a { opacity: 1; transform: none; }
  .nav__links a:nth-child(1) { --delay: 40ms; }
  .nav__links a:nth-child(2) { --delay: 80ms; }
  .nav__links a:nth-child(3) { --delay: 120ms; }
  .nav__links a:nth-child(4) { --delay: 160ms; }
  .nav__links a:nth-child(5) { --delay: 200ms; }
}

/* Touch devices: hover styles never stick, so drop the pure-hover flourishes */
@media (hover: none) {
  .u-zoom:hover img,
  .compare:hover .compare__handle { transform: none; }
  .compare:hover .compare__tag { opacity: 1; }
}

/* ---------- 7. Reduced motion -------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Never leave content hidden or displaced */
  .js .reveal,
  .js .reveal-group > *,
  .nav__links a {
    opacity: 1 !important;
    transform: none !important;
  }
  .compare__handle::after { display: none; }
}
