/*
 * Motion: hover states and animations for the whole site.
 * Uses the motion tokens in tokens.css (--ease-out, --dur-fast, --dur, --dur-slow).
 * Everything here is switched off for people who ask their system for reduced motion (bottom of file).
 */

/* ========== Hover and press states ========== */

/* Buttons: lift slightly, the icon nudges in the arrow's direction, press sinks back. */
.btn { transition: background-color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out), translate var(--dur) var(--ease-out); }
.btn:hover { filter: none; translate: 0 -1px; box-shadow: 0 8px 20px rgb(from var(--green-950) r g b / 0.14); }
.btn:active { translate: 0 0; box-shadow: none; transition-duration: var(--dur-fast); }
.btn__icon { transition: translate var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out); }
.btn:hover .btn__icon { translate: 2px -2px; }
.btn--solid:hover { background: var(--green-700); }
.btn--light:hover { background: var(--white); }
.btn--glass:hover { background: rgb(from var(--green-975) r g b / 0.45); border-color: rgb(from var(--green-25) r g b / 0.45); }
.btn--dark:hover { background: var(--green-950); }
.btn--outline:hover { background: var(--green-100); border-color: var(--green-800); }
.btn--soft:hover { border-color: var(--green-600); }
.btn--mint:hover { background: var(--green-200); }

/* Nav: an underline that draws in from the left. */
.site-nav > a { position: relative; }
.site-nav > a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: currentColor;
  scale: 0 1;
  transform-origin: left;
  transition: scale var(--dur) var(--ease-out);
}
.site-nav > a:hover::after, .site-nav > a[aria-current]::after { scale: 1 1; }

/* Text links and footer links */
.text-link { transition: color var(--dur-fast); }
.text-link:hover { color: var(--green-700); }
.site-footer__links a, .legal a { transition: color var(--dur-fast); }
.social a { transition: background-color var(--dur) var(--ease-out), translate var(--dur) var(--ease-out); }
.social a:hover { background: var(--green-700); translate: 0 -2px; }
.tag { transition: background-color var(--dur-fast); }
a.chip { transition: background-color var(--dur-fast); }

/* Cards that link somewhere: lift with a soft shadow. */
.practice-card, .logo-card, .network-card, .doctor-card, .side-card, .choose-card, .testimonial, .help-card, .bento-card, .location-card {
  /* Lift uses transform (not translate) so it adds to the scroll-reveal's translate instead of fighting it. */
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
}
.logo-card:hover, .network-card:hover, .doctor-card:hover, .side-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 32px rgb(from var(--green-950) r g b / 0.1);
}
/* Only things you can click move on hover. Information cards (choose, help, bento, testimonials, directory
   practices) stay still: a lift or photo zoom there promises a click that does nothing. */
.side-card:hover .icon-btn--light, .logo-card:hover .icon-btn--green { rotate: 45deg; }

/* Rows that open */
.faq-item summary, .subspecialty summary { transition: color var(--dur-fast); }
.faq-item:hover { border-color: var(--green-600); }
.faq-item:hover .faq-item__icon { scale: 1.1; }
.faq-item__icon { transition: rotate 0.5s var(--ease-in-out), scale var(--dur) var(--ease-out); }
.accordion summary:hover h2 { color: var(--green-800); }

/* Map pins */
.map-pin { transition: transform var(--dur) var(--ease-out), background-color var(--dur-fast); cursor: pointer; }
.map-pin:hover { transform: scale(1.12); background: var(--green-300); }

/* ========== Animations ========== */

/* Opening answers fade in as they slide down (accordion.js animates the height itself). */
.faq-item[open] .faq-item__answer, .subspecialty[open] .subspecialty__body, .accordion[open] .accordion__body, .practice-card__doctors[open] ul {
  animation: open-down 0.5s var(--ease-in-out);
}
@keyframes open-down { from { opacity: 0; translate: 0 -6px; } }

/* Hero: heading, intro and buttons rise in on page load. */
.hero__title, .hero__body, .hero__actions { animation: rise-in var(--dur-slow) var(--ease-out) both; }
.hero__body { animation-delay: 120ms; }
.hero__actions { animation-delay: 240ms; }
.hero__actions--inline { animation-delay: 240ms; }
@keyframes rise-in { from { opacity: 0; translate: 0 24px; } }

/* Scroll reveals: motion.js marks elements with [data-reveal] and adds .is-in when they scroll into view.
   Only applies when JavaScript runs, so content is never hidden if the script fails. */
.js [data-reveal] {
  opacity: 0;
  translate: 0 28px;
  transition: opacity var(--dur-slow) var(--ease-out), translate var(--dur-slow) var(--ease-out),
    transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.js [data-reveal].is-in { opacity: 1; translate: 0 0; }
/* Revealed cards still need their hover transitions; motion.js resets --i to 0 after the reveal so hovers aren't delayed. */

/* Booking card: glides in, toggle switches on (components.css), then Accept pulses. */
.js .booking-card[data-reveal] { translate: 0 40px; scale: 0.96; transition: opacity var(--dur-slow) var(--ease-out), translate var(--dur-slow) var(--ease-out), scale var(--dur-slow) var(--ease-out); }
.js .booking-card[data-reveal].is-in { scale: 1; }
.js .booking-card--ris[data-reveal].is-in { scale: 0.758; }
.booking-card .toggle, .booking-card .toggle > span { transition-delay: 600ms; }
.booking-card .booking-card__time { transition: opacity var(--dur-slow) var(--ease-out) 300ms; }
.js .booking-card:not(.is-in) .booking-card__time { opacity: 0; }
.booking-card.is-in .booking-card__accept { animation: pulse 2.4s var(--ease-out) 1.2s infinite; }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgb(from var(--green-400) r g b / 0.45); }
  70%, 100% { box-shadow: 0 0 0 12px rgb(from var(--green-400) r g b / 0); }
}
/* Once it has arrived, the card floats gently. */
.booking-card.is-in { animation: float 6s ease-in-out 1s infinite; }

/* Floating chips pop in one after another, then bob. */
.js .float-chip[data-reveal] { translate: 0 12px; scale: 0.9; transition: opacity var(--dur) var(--ease-out), translate var(--dur) var(--ease-out), scale var(--dur) var(--ease-out); transition-delay: calc(400ms + var(--i, 0) * 140ms); }
.js .float-chip[data-reveal].is-in { scale: 1; animation: float 5s ease-in-out calc(1.2s + var(--i, 0) * 400ms) infinite; }
@keyframes float { 50% { translate: 0 -6px; } }

/* Decorative swirls drift very slowly so the art feels alive. */
.cta-band .swirl img, .hero .swirl img, .join .swirl img { animation: drift 22s ease-in-out infinite alternate; }
.swirl:nth-child(2) img { animation-duration: 28s; animation-direction: alternate-reverse; }
@keyframes drift { to { translate: 1.5% -1%; } }

/* Scroll-linked glass: motion.js sets --p (-1 → 1) as a section moves up the screen. Each swirl layer
   moves at a different speed (--depth), so the glass appears to have depth as you scroll. */
.swirl, .art-img, .practice__doctor {
  translate: 0 calc(var(--p, 0) * var(--depth, 1) * -90px);
  rotate: calc(var(--p, 0) * var(--depth, 1) * 3deg);
  will-change: translate, rotate;
}
.art > :nth-child(2) { --depth: 1.6; }
.art > :nth-child(3) { --depth: 0.6; }
.art > :nth-child(4) { --depth: 2; }
.art-img { --depth: 0.8; }
.practice__doctor { rotate: none; --depth: -0.5; } /* the photo drifts the other way, against the glass */

/* Stats columns drift at different speeds, exaggerating their staggered layout. Uses transform, not
   translate, so it stacks with the reveal animation. Digits are fixed-width so counting doesn't jitter. */
.stat { transform: translateY(calc(var(--p, 0) * var(--depth, 0) * -80px)); will-change: transform; }
.stat:nth-child(1) { --depth: 0.4; }
.stat:nth-child(2) { --depth: 1.2; }
.stat:nth-child(3) { --depth: 0.8; }
.stat:nth-child(4) { --depth: 1.5; }
.stat dd { font-variant-numeric: tabular-nums; }

/* How-it-works flow: steps not yet playing are dimmed; the active one's top rule fills over its duration (--step-dur).
   The hub's rings pulse outward while Radian is matching. */
.js .flow.is-playing .flow__step:not(.is-active) { opacity: 0.6; }
.flow__step.is-active::before { scale: 1 1; transition: scale var(--step-dur, 2s) linear; }
.flow__hub.is-busy .flow__ring { animation: ring-pulse 1.2s var(--ease-out) infinite; }
.flow__hub.is-busy .flow__ring + .flow__ring { animation-delay: 0.3s; }
@keyframes ring-pulse { 0% { scale: 0.9; opacity: 1; } 100% { scale: 1.12; opacity: 0; } }

/* The steps timeline line draws across. */
.js .steps__list::before { scale: 0 1; transform-origin: left; transition: scale 1.4s var(--ease-out); }
.js .steps__list.is-in::before { scale: 1 1; }

/* ========== Reduced motion ==========
   People who set "reduce motion" on their device get the final state straight away, with no movement. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: 0.01ms !important; transition-delay: 0ms !important; scroll-behavior: auto !important; }
  .js [data-reveal] { opacity: 1; translate: none; scale: none; }
  .js .booking-card:not(.is-in) .booking-card__time { opacity: 1; }
  .btn:hover, .social a:hover { translate: none; }
  .swirl, .art-img, .practice__doctor { translate: none; rotate: none; }
  .stat { transform: none; }
  .logo-card:hover, .network-card:hover, .doctor-card:hover, .side-card:hover { transform: none; }
}
