/* ---------------------------------------------------------------------------
 * Reveal animations — the native replacement for Webflow's IX2 slide/grow presets.
 *
 * Every number here was lifted from Webflow's own code, not eyeballed:
 *
 *   slideInBottom  opacity 0→1, translateY 100px→0   duration 1000ms, easing outQuart
 *   slideInLeft    opacity 0→1, translateX -100px→0  duration 1000ms, easing outQuart
 *   slideInRight   opacity 0→1, translateX 100px→0   duration 1000ms, easing outQuart
 *   growIn         opacity 0→1, scale 0.75→1         duration 1000ms, easing outQuart
 *
 * Easing: Webflow's outQuart is the Penner curve `1-(1-t)^4`, a JS function rather than
 * a bezier, so no cubic-bezier reproduces it exactly. Measured max error against it:
 *   cubic-bezier(.25, 1, .5, 1)     0.56%  ← chosen (0.56px peak on a 100px move)
 *   cubic-bezier(.165, .84, .44, 1) 4.43%  ← the value commonly cited for easeOutQuart; wrong
 *
 * Initial state is gated on .w-mod-js (Webflow's own class, set by the inline snippet we
 * kept). This is deliberate and is an improvement: today the elements ship an inline
 * style="opacity:0" and stay invisible forever if JS fails. Now, no JS means no reveal —
 * the content simply shows.
 * ------------------------------------------------------------------------- */

:root {
  --wf-reveal-duration: 1000ms;
  --wf-reveal-easing: cubic-bezier(0.25, 1, 0.5, 1);
  --wf-reveal-delay: 0ms;
}

.w-mod-js [data-reveal] {
  opacity: 0;
  will-change: opacity, transform;
}

.w-mod-js [data-reveal="slideInBottom"] { transform: translateY(100px); }
.w-mod-js [data-reveal="slideInLeft"]   { transform: translateX(-100px); }
.w-mod-js [data-reveal="slideInRight"]  { transform: translateX(100px); }
.w-mod-js [data-reveal="growIn"]        { transform: scale(0.75); }

.w-mod-js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--wf-reveal-duration) var(--wf-reveal-easing) var(--wf-reveal-delay),
    transform var(--wf-reveal-duration) var(--wf-reveal-easing) var(--wf-reveal-delay);
}

/* Webflow staggers groups by delay; these are the only values it uses. */
.w-mod-js [data-reveal-delay="100"] { --wf-reveal-delay: 100ms; }
.w-mod-js [data-reveal-delay="150"] { --wf-reveal-delay: 150ms; }
.w-mod-js [data-reveal-delay="200"] { --wf-reveal-delay: 200ms; }
.w-mod-js [data-reveal-delay="250"] { --wf-reveal-delay: 250ms; }
.w-mod-js [data-reveal-delay="300"] { --wf-reveal-delay: 300ms; }
.w-mod-js [data-reveal-delay="350"] { --wf-reveal-delay: 350ms; }
.w-mod-js [data-reveal-delay="400"] { --wf-reveal-delay: 400ms; }
.w-mod-js [data-reveal-delay="450"] { --wf-reveal-delay: 450ms; }
.w-mod-js [data-reveal-delay="500"] { --wf-reveal-delay: 500ms; }

/* Once revealed, drop the compositing hint — these elements never animate again. */
.w-mod-js [data-reveal].is-revealed { will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  .w-mod-js [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
 * The host element for the verbatim markup.
 *
 * dangerouslySetInnerHTML needs an element to live on, which puts one extra <div>
 * between <body> and the page. display:contents removes it from the box tree, so the
 * sections lay out as direct children of <body> exactly as they do on Webflow — no
 * stacking context, no containing block for position:fixed, no extra block box.
 * ------------------------------------------------------------------------- */
body > [data-wf-host] {
  display: contents;
}

/* ---------------------------------------------------------------------------
 * Accordions — replaces IX2 action lists a-23/a-27 and a-28/a-29.
 *
 * All four numbers come from those action lists: 500ms, icon rotateZ 0deg ↔ 135deg,
 * item background --color--gray-1 ↔ --color--gray-3, content height 0 ↔ auto.
 *
 * The resting state is applied by JS on the live site, not by its CSS — .accordion-content
 * only carries `overflow: hidden`, so with the engine gone every answer rendered expanded
 * (+475px on the homepage FAQ). The codemod stamps data-accordion="open|closed" per item
 * from Webflow's `useFirstGroupAsInitialState`, and the rules below make it declarative.
 * ------------------------------------------------------------------------- */

.w-mod-js [data-accordion] .accordion-content {
  height: 0;
  overflow: hidden;
  transition: height 500ms ease;
}
.w-mod-js [data-accordion] .accordion-inner {
  transition: transform 500ms ease;
}
.w-mod-js [data-accordion] {
  transition: background-color 500ms ease;
}

.w-mod-js [data-accordion="closed"] .accordion-inner { transform: rotate(0deg); }
.w-mod-js [data-accordion="closed"] { background-color: var(--color--gray-1); }

.w-mod-js [data-accordion="open"] .accordion-inner { transform: rotate(135deg); }
.w-mod-js [data-accordion="open"] { background-color: var(--color--gray-3); }

@media (prefers-reduced-motion: reduce) {
  .w-mod-js [data-accordion] .accordion-content,
  .w-mod-js [data-accordion] .accordion-inner,
  .w-mod-js [data-accordion] {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
 * Hover states — replaces IX2 action lists a-17/18, a-30/31, a-33/34, a-36/37,
 * a-40/41, a-45/46, a-48/49, a-50/51.
 *
 * Timing note: each [In] list has TWO groups. The first is the resting state and is
 * applied instantly (useFirstGroupAsInitialState) despite carrying duration 500 — the
 * real hover-in animation is the second group, at 300ms. Both directions are 300ms.
 * ("500ms in / 300ms out" is a misreading of that first group.)
 *
 * IX2's own hover pairs have no easing set, so these use the CSS default (ease).
 * ------------------------------------------------------------------------- */

.w-mod-js .button-icon,
.w-mod-js .hero-buton-icon {
  transform: rotate(0deg);
  transition: transform 300ms;
}
.w-mod-js .button-icon-primary:hover .button-icon,
.w-mod-js .button-icon-wrap:hover .button-icon,
.w-mod-js .hero-button:hover .hero-buton-icon {
  transform: rotate(180deg); /* a-40 / a-48 */
}

/* a-17/18 Button Link Hover: the icon sits at 92% grayscale and slides 4px on hover. */
.w-mod-js .button-link-icon {
  filter: grayscale(92%);
  transform: translateX(0);
  transition: filter 300ms, transform 300ms;
}
.w-mod-js .button-link:hover .button-link-icon {
  filter: grayscale(0%);
  transform: translateX(4px);
}

/* a-30/31 + a-45/46 Blog Hover: 1 → 1.08 */
.w-mod-js .blog-image,
.w-mod-js .blog-right-image {
  transform: scale(1);
  transition: transform 300ms;
}
.w-mod-js .blog-item:hover .blog-image,
.w-mod-js .blog-link:hover .blog-image,
.w-mod-js .blog-right-item:hover .blog-right-image,
.w-mod-js .blog-right-link:hover .blog-right-image {
  transform: scale(1.08);
}

/* a-33/34 Service Hover */
.w-mod-js .service-center-image {
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 300ms, transform 300ms;
}
.w-mod-js .service-right-icon {
  transform: rotate(0deg);
  transition: transform 300ms;
}
.w-mod-js .service-list {
  background-color: var(--color--gray-2);
  transition: background-color 300ms;
}
.w-mod-js .service-list:hover .service-center-image {
  opacity: 1;
  transform: scale(1);
}
.w-mod-js .service-list:hover .service-right-icon { transform: rotate(45deg); }
.w-mod-js .service-list:hover { background-color: var(--color--gray-3); }

/* a-36/37 Team Hover: the social list rises from +20px to -20px as it fades in. */
.w-mod-js .team-social-list {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 300ms, transform 300ms;
}
.w-mod-js .team-item:hover .team-social-list {
  opacity: 1;
  transform: translateY(-20px);
}

/* ---------------------------------------------------------------------------
 * Infinite loops — replaces a-42, a-44, a-47, a-32, a-35.
 *
 * All are linear and infinite; the durations are Webflow's. Moving these to CSS
 * keyframes drops IX2's rAF loop, so they run on the compositor instead of JS.
 *
 * a-11 "Client Marquee Move" and a-14 "Testimonial Marquee Move" are deliberately absent:
 * both have empty targets and their elements exist on no page. Dead interactions.
 * ------------------------------------------------------------------------- */

@keyframes wf-spin-cw  { from { transform: rotate(0deg); }   to { transform: rotate(360deg); } }
@keyframes wf-spin-ccw { from { transform: rotate(0deg); }   to { transform: rotate(-360deg); } }
@keyframes wf-ticker-x { from { transform: translateX(0); }  to { transform: translateX(-100%); } }
@keyframes wf-ticker-y { from { transform: translateY(0); }  to { transform: translateY(-100%); } }

/* a-42 Hero List Move — 100s, the slowest thing on the page. */
.w-mod-js .hero-avatar-list { animation: wf-spin-cw 100s linear infinite; }

/* a-47 Bento Move — the ring turns one way, its 8 avatars counter-turn so they stay upright. */
.w-mod-js .bento-avatar-list { animation: wf-spin-cw 60s linear infinite; }
.w-mod-js .bento-avatar-list > * { animation: wf-spin-ccw 60s linear infinite; }

/* a-44 / a-32 / a-35 — tickers, 60s each. */
.w-mod-js .bento-ticker { animation: wf-ticker-y 60s linear infinite; }
.w-mod-js .review-ticker { animation: wf-ticker-x 60s linear infinite; }
.w-mod-js .about-gallery-ticker { animation: wf-ticker-x 60s linear infinite; }

/* a-38/39 About Gallery Hover: Webflow "pauses" the ticker by swapping in a duration of
   23156498416884000ms on hover and 40000ms on leave. That is a hack around IX2 having no
   pause; CSS says it directly. */
.w-mod-js .about-gallery:hover .about-gallery-ticker { animation-play-state: paused; }

/* Webflow starts these on SCROLL_INTO_VIEW, not at load (only the hero list is
   PAGE_START), so they idle until their section is on screen. */
/* Must come after the animation shorthands above: `animation: …` resets
   animation-play-state to running, so declaring the gate earlier is silently undone. */
.w-mod-js [data-loop="on-view"],
.w-mod-js [data-loop="on-view"] > * {
  animation-play-state: paused;
}
.w-mod-js [data-loop="on-view"].is-running,
.w-mod-js [data-loop="on-view"].is-running > * {
  animation-play-state: running;
}

@media (prefers-reduced-motion: reduce) {
  .w-mod-js .hero-avatar-list,
  .w-mod-js .bento-avatar-list,
  .w-mod-js .bento-avatar-list > *,
  .w-mod-js .bento-ticker,
  .w-mod-js .review-ticker,
  .w-mod-js .about-gallery-ticker {
    animation: none;
  }
}

/* ---------------------------------------------------------------------------
 * Direct-contact CTA — replaces the removed appointment and contact forms.
 *
 * The only intentional break from 1:1 on the whole site, so it borrows rather than
 * invents: .button-icon-primary, .button-icon-wrap and .button-text are the site's own
 * button parts, and the filled variant is Webflow's own "button-arrow-dark". Both buttons
 * therefore inherit the existing hover (icon rotates 180deg, 300ms) for free.
 *
 * The opening hours come from the clinic's own MedicalClinic schema. If you ask someone to
 * phone you, telling them when someone picks up is the difference between a CTA and a
 * dead end — and it is the one thing the form used to imply ("revenim la tine") but the
 * page never actually said.
 * ------------------------------------------------------------------------- */

.cta-direct {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  grid-column-gap: var(--gap--gap-6);
  grid-row-gap: var(--gap--gap-6);
}

.cta-direct-hours {
  flex-basis: 100%;
  margin-bottom: 0;
  color: var(--color--body);
  font-size: var(--_typography---body--body-sm);
  line-height: var(--_typography---body--line-height);
}

/* Below Webflow's "small" tier the buttons stack, so let them fill the row. */
@media screen and (max-width: 479px) {
  .cta-direct > .button-icon-primary {
    width: 100%;
  }
}

/* The form was ~407px tall and the CTA is ~120px, but the card's height is set by the
   image beside it — so the left column kept the form's height and gained a void beneath.
   Centring the content lets that space fall above and below instead of pooling at the
   bottom. Scoped to columns that actually hold a CTA, so pages with real content are
   untouched. */
.appointment-left:has(.cta-direct),
.contact-left:has(.cta-direct) {
  justify-content: center;
  text-align: center;
}
/* Centre the whole group: heading + hours follow text-align, the button row needs its own
   justify-content since flex items ignore text-align. */
.appointment-left:has(.cta-direct) .cta-direct,
.contact-left:has(.cta-direct) .cta-direct {
  justify-content: center;
}
/* The title wrapper is a flex column with align-items:flex-start, so the heading pins left;
   align-items:center is what actually centres it (justify-content is the vertical axis here). */
.appointment-left:has(.cta-direct) .appointment-form-title,
.contact-left:has(.cta-direct) .contact-form-title {
  align-items: center;
  text-align: center;
  width: 100%;
}

/* ---------------------------------------------------------------------------
 * Mobile navigation menu — the open state.
 *
 * nav.js toggles .w--open on the menu (replacing Webflow's own nav JS), but the compiled
 * CSS only ever sets .nav-menu to display:none at <=991px and never had a rule to show it
 * again — Webflow drove that with inline styles from its runtime. So the hamburger did
 * nothing. This drops the menu down as a panel when open.
 * ------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  .navbar { position: relative; }
  /* Match Webflow's own selector specificity (.w-nav[data-collapse] .w-nav-menu = 0,3,0),
     which is what sets the menu to display:none — a plain .w-nav-menu.w--open loses to it. */
  .w-nav[data-collapse] .w-nav-menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0.25rem;
    padding: 1rem 1.5rem 1.5rem;
    background: var(--color--gray-1);
    box-shadow: 0 24px 48px rgba(45, 27, 37, 0.12);
    border-bottom-left-radius: 1.5rem;
    border-bottom-right-radius: 1.5rem;
    z-index: 900;
  }
  .w-nav[data-collapse] .w-nav-menu.w--open { display: flex; }
  .w-nav[data-collapse] .w-nav-menu .nav-link {
    padding: 0.85rem 0;
    font-size: 1.15rem;
    border-bottom: 1px solid var(--color--chestnut-10);
  }
  .w-nav[data-collapse] .w-nav-menu .nav-link:last-child { border-bottom: none; }
}

/* ---------------------------------------------------------------------------
 * WhatsApp CTA — green, so it stands out from the rose call button. Applies everywhere
 * .cta-direct is used (authored pages and the form-replacement CTAs).
 * ------------------------------------------------------------------------- */
.cta-direct a[href*="wa.me"].button-icon-primary {
  background-color: #25d366;
}
.cta-direct a[href*="wa.me"].button-icon-primary .button-text { color: #fff; }
.cta-direct a[href*="wa.me"].button-icon-primary:hover { background-color: #1fb457; }

/* ---------------------------------------------------------------------------
 * CTA button polish (applies wherever .cta-direct is used).
 * ------------------------------------------------------------------------- */

/* Call button sits on the rose/bronze fill — white text reads better than the default dark. */
.cta-direct a[href^="tel:"].button-icon-primary .button-text { color: #fff; }

/* WhatsApp: the real logo, sized up so it fills its white chip and reads clearly. */
.cta-direct a[href*="wa.me"].button-icon-primary .button-icon { width: 16px; height: 16px; }

/* ---------------------------------------------------------------------------
 * Homepage hero CTA — balance the space above/below the injected buttons.
 * The buttons sit at the bottom of the hero .container: 0 gap above (they touched the
 * sub-headline) and 64px below (.hero-bottom's margin-top). Even both to ~36px.
 * ------------------------------------------------------------------------- */
/* Both heroes that get an injected CTA (home + acnee) are centre-aligned, so centre the
   buttons to match. Only .cta-direct-hero is affected — the authored pages use plain
   .cta-direct in a left-aligned hero and stay as they are. */
.cta-direct-hero { justify-content: center; margin-top: 1.5rem; }
.hero-section .cta-direct-hero { margin-top: 2.25rem; }
.hero-section .hero-bottom { margin-top: 2.25rem; }

/* ---------------------------------------------------------------------------
 * Injectables accordions.
 *
 * Webflow's removed injectaccordionv4 script supplied these plus/minus images at runtime.
 * Keep native <details>/<summary> behaviour and restore only the missing affordance.
 * ------------------------------------------------------------------------- */
.inject-acc-sum {
  cursor: pointer !important;
}
.inject-acc-icon {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round'><path d='M12 5v14M5 12h14'/></svg>") !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
  background-size: 16px !important;
  transition: background-color 250ms, transform 250ms !important;
}
.inject-acc[open] .inject-acc-icon {
  background-color: #2d1b25 !important;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round'><path d='M5 12h14'/></svg>") !important;
}
.inject-acc-sum:focus-visible {
  outline: 3px solid rgba(212, 117, 158, 0.55);
  outline-offset: -3px;
  border-radius: 14px;
}

/* Long raw URLs in the cookie policy must remain inside the mobile viewport. */
.paragraph-3,
.paragraph-3 a {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* The longest all-caps Harmony title overflowed a 360px viewport by 24px. */
@media screen and (max-width: 479px) {
  .service-detail-title.is-laser {
    max-width: 100%;
    font-size: 3rem;
    overflow-wrap: anywhere;
  }
  .service-single-section .heads-title {
    font-size: clamp(1.85rem, 8vw, 2rem);
    overflow-wrap: anywhere;
  }
}
