/* ==========================================================
   Canvas by Urbando — animations
   Everything that moves lives here. All of it is wrapped in
   prefers-reduced-motion, so with motion off the page is
   simply static and fully visible.
   ========================================================== */

/* ---------- Page loader: the sheet lifts away plot by plot ---------- */
.js .loader { transition: opacity .4s ease, visibility 0s linear .4s; }
.js.is-loaded .loader { opacity: 0; visibility: hidden; }                       /* reduced-motion exit: plain fade */
@media (prefers-reduced-motion: no-preference) {
  .loader__logo { animation: loader-breathe 1.8s ease-in-out infinite; }
  @keyframes loader-breathe { 50% { opacity: .55; transform: scale(.97); } }
  .loader__bar span { transition: transform .35s ease-out; }

  /* exit: logo, bar and % rise out, then the strips lift bottom-to-top one after another */
  .js .loader { transition: visibility 0s linear 1.5s; }
  .js.is-loaded .loader { opacity: 1; }
  .loader__inner { transition: opacity .35s ease, transform .6s cubic-bezier(.5, 0, .2, 1); }
  .js.is-loaded .loader__inner { opacity: 0; transform: translateY(-40px); }
  .loader__strips span {
    transition: transform .95s cubic-bezier(.76, 0, .24, 1);
    transition-delay: calc(.2s + var(--i) * .075s);
    will-change: transform;
  }
  .js.is-loaded .loader__strips span { transform: translateY(-102%); }
}

/* ---------- Hero load sequence (one moment, then still) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js .lockup__canvas { opacity: 0; transform: translateY(6cqw); }
  .js .lockup__your   { opacity: 0; transform: translateY(2cqw); }
  .js .lockup__script { clip-path: inset(-40% 100% -40% -5%); }

  .js.is-ready .lockup__canvas {
    opacity: 1; transform: none;
    transition: opacity .9s ease .1s, transform 1.1s cubic-bezier(.2,.7,.2,1) .1s;
  }
  .js.is-ready .lockup__script--your {
    clip-path: inset(-40% -8% -40% -5%);
    transition: clip-path 1s ease .55s;
  }
  .js.is-ready .lockup__your {
    opacity: 1; transform: none;
    transition: opacity .6s ease 1.05s, transform .7s ease 1.05s;
  }
  .js.is-ready .lockup__script--story {
    clip-path: inset(-40% -8% -40% -5%);
    transition: clip-path 1.1s ease 1.3s;
  }
}

/* ---------- Scroll reveal ----------
   Add data-reveal to any element. Optional inline --d sets a delay:
   <p data-reveal style="--d:.2s">. main.js adds .is-in when it enters view. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity .8s ease var(--d, 0s), transform .9s cubic-bezier(.2,.7,.2,1) var(--d, 0s);
  }
  .js [data-reveal="fade"]  { transform: none; }
  .js [data-reveal="left"]  { transform: translateX(-32px); }
  .js [data-reveal="right"] { transform: translateX(32px); }
  .js [data-reveal].is-in { opacity: 1; transform: none; }
}

/* ---------- Script font: handwriting write-on ----------
   Every heading set in --font-script carries class "script" and
   data-reveal="write": the word is uncovered left to right, like a pen
   moving across the page. Negative insets keep the tall swashes and
   descenders of Ortisan Signature from being clipped.
   Tune per element with --d (delay) and --write (duration). */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal="write"] {
    opacity: 1;
    transform: none;
    clip-path: inset(-60% 100% -60% -12%);
    transition: clip-path var(--write, 1.5s) cubic-bezier(.55, .1, .3, 1) var(--d, 0s);
  }
  .js [data-reveal="write"].is-in { clip-path: inset(-60% -12% -60% -12%); }
}

/* ---------- Watercolour art: blooms out from the centre ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal="bloom"] {
    opacity: 0;
    transform: scale(.94);
    -webkit-mask-image: radial-gradient(circle at 50% 55%, #000 0, #000 var(--bloom, 0%), transparent calc(var(--bloom, 0%) + 22%));
            mask-image: radial-gradient(circle at 50% 55%, #000 0, #000 var(--bloom, 0%), transparent calc(var(--bloom, 0%) + 22%));
    transition: opacity .9s ease, transform 1.8s cubic-bezier(.2,.7,.2,1), --bloom 2s cubic-bezier(.3,.6,.2,1);
  }
  .js [data-reveal="bloom"].is-in { opacity: 1; transform: none; --bloom: 100%; }
}
@property --bloom { syntax: "<percentage>"; inherits: false; initial-value: 0%; }

/* ---------- Starting points: the divider draws outward from the painting ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js .starts__grid::before { transform: scaleX(0); transition: transform 1.6s cubic-bezier(.4,.1,.2,1) .5s; }
  .js .starts__grid.is-in::before { transform: scaleX(1); }
}

/* ---------- Location: the site pin pulses on the map ---------- */
@media (prefers-reduced-motion: no-preference) {
  .location__pin::before, .location__pin::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: clamp(34px, 3.4vw, 64px); aspect-ratio: 2 / 1;      /* flattened: it lies on the ground */
    border-radius: 50%;
    border: 2px solid rgba(225, 45, 45, .7);
    translate: -50% -50%;
    opacity: 0;
    animation: pin-pulse 2.6s ease-out infinite;
  }
  .location__pin::after { animation-delay: 1.3s; }
  @keyframes pin-pulse { 0% { scale: .2; opacity: .9; } 80%, 100% { scale: 1.5; opacity: 0; } }
}

/* ---------- Tabs: the incoming panel's cards rise in one after another ---------- */
@media (prefers-reduced-motion: no-preference) {
  .amen__panel.is-entering .slick-slide { animation: card-in .7s cubic-bezier(.2,.7,.2,1) both; }
  .amen__panel.is-entering .slick-slide:nth-child(2) { animation-delay: .08s; }
  .amen__panel.is-entering .slick-slide:nth-child(3) { animation-delay: .16s; }
  .amen__panel.is-entering .slick-slide:nth-child(4) { animation-delay: .24s; }
  @keyframes card-in { from { opacity: 0; transform: translateY(28px); } }
}

/* ---------- Gallery: tiles pop in after a filter change or Load more ---------- */
@media (prefers-reduced-motion: no-preference) {
  .g-item.is-entering { animation: tile-in .6s cubic-bezier(.2,.7,.2,1) both; animation-delay: calc(var(--i, 0) * 55ms); }
  @keyframes tile-in { from { opacity: 0; transform: translateY(22px) scale(.96); } }
  .lightbox[open] { animation: fade-in .3s ease; }
  .lightbox__slide img { transition: transform .7s cubic-bezier(.2,.7,.2,1), opacity .5s ease; transform: scale(.94); opacity: .4; }
  .lightbox__main .slick-current img { transform: none; opacity: 1; }
}

/* ---------- FAQ: answers open and close smoothly ---------- */
@media (prefers-reduced-motion: no-preference) {
  .faq__a { transition: grid-template-rows .5s cubic-bezier(.3,.7,.2,1); }
  .faq__a p { opacity: 0; translate: 0 -6px; transition: opacity .35s ease, translate .45s ease; }
  .faq__item.is-open .faq__a p { opacity: 1; translate: 0 0; transition-delay: .12s; }
}

/* ---------- Closing CTA: the avenue eases towards you as the section arrives ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js .cta__bg { transform: scale(1.08); transform-origin: 50% 100%; transition: transform 2.6s cubic-bezier(.2,.6,.2,1); }
  .js .cta.is-in .cta__bg { transform: none; }
}

/* ---------- Footer wordmark: endless drift, pauses under the pointer ---------- */
@media (prefers-reduced-motion: no-preference) {
  .footer__track { animation: marquee 38s linear infinite; }
  .footer__marquee:hover .footer__track { animation-play-state: paused; }
  @keyframes marquee { to { transform: translateX(-50%); } }      /* -50% = exactly one of the two groups */
}

/* ---------- WhatsApp: one soft pulse every few seconds ---------- */
@media (prefers-reduced-motion: no-preference) {
  .wa-float::after {
    content: ""; position: absolute; inset: 0; border-radius: 50%;
    box-shadow: 0 0 0 0 rgba(37, 211, 102, .5);
    animation: wa-pulse 3.2s ease-out infinite;
  }
  @keyframes wa-pulse { 0% { box-shadow: 0 0 0 0 rgba(37,211,102,.5); } 45%, 100% { box-shadow: 0 0 0 16px rgba(37,211,102,0); } }
}

/* ---------- Counters ----------
   Numbers are counted up by main.js; this only adds the settle at the end. */
@media (prefers-reduced-motion: no-preference) {
  .stat__num.is-done { animation: count-settle .45s cubic-bezier(.3,1.5,.5,1); }
  @keyframes count-settle { 0% { transform: scale(1); } 45% { transform: scale(1.06); } 100% { transform: scale(1); } }
  .stat__num { display: inline-block; transform-origin: left bottom; }
}

/* ---------- About scenery: slow drift in as the section arrives ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js .about__bg { transform: scale(1.06); transform-origin: 70% 100%; transition: transform 2.4s cubic-bezier(.2,.6,.2,1); }
  .js .about.is-in .about__bg { transform: none; }
}

/* ---------- Popups ---------- */
@media (prefers-reduced-motion: no-preference) {
  .modal[open] { animation: modal-in .28s cubic-bezier(.2,.7,.2,1); }
  .modal[open]::backdrop { animation: fade-in .28s ease; }
  @keyframes modal-in { from { opacity: 0; transform: translateY(14px); } }
  @keyframes fade-in  { from { opacity: 0; } }
}

/* Pre-launch badge (sequenced by main.js): pops in once the headline has finished, or when it
   scrolls into view on phones (.is-on); the words rise, the price counts up, then the old price
   is struck through and the ribbon note appears (.is-struck). Still after that. */
@media (prefers-reduced-motion: no-preference) {
  .js .hero-badge { opacity: 0; scale: .6; rotate: -14deg; }
  .js .hero-badge.is-on {
    opacity: 1; scale: 1; rotate: 0deg;
    transition: opacity .45s ease, scale .7s cubic-bezier(.34,1.56,.64,1), rotate .7s cubic-bezier(.34,1.56,.64,1);
  }
  .js .hero-badge.is-on:hover { scale: 1.04; transition: scale .35s cubic-bezier(.3,.7,.2,1); }

  .js .hero-badge__title > span { opacity: 0; translate: 0 .7em; }
  .js .hero-badge.is-on .hero-badge__title > span {
    opacity: 1; translate: none;
    transition: opacity .45s ease, translate .55s cubic-bezier(.2,.7,.2,1);
    transition-delay: calc(.35s + var(--i) * .14s);
  }

  .js .hero-badge__price { opacity: 0; scale: .8; }
  .js .hero-badge.is-on .hero-badge__price {
    opacity: 1; scale: 1;
    transition: opacity .35s ease .6s, scale .5s cubic-bezier(.34,1.56,.64,1) .6s;
  }

  .js .hero-badge__strike { scale: 0 1; }
  .js .hero-badge.is-struck .hero-badge__strike { scale: 1 1; transition: scale .35s cubic-bezier(.6,0,.3,1); }

  .js .hero-badge__note { opacity: 0; translate: 0 .6em; }
  .js .hero-badge.is-struck .hero-badge__note {
    opacity: 1; translate: none;
    transition: opacity .45s ease .25s, translate .5s cubic-bezier(.2,.7,.2,1) .25s;
  }
}
