/* =====================================================================
   JGuard Desktop — Animations & Motion
===================================================================== */

/* ── Scroll-revealed elements ──────────────────────────────────────
   Add [data-animate="fade-up"] / "fade-in" / "scale-in" / "slide-left"
   etc. to elements. motion.js toggles the .is-visible class when the
   element enters the viewport.
*/

[data-animate] {
    opacity: 0;
    will-change: transform, opacity;
    transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
}

[data-animate="fade-up"]    { transform: translateY(40px); }
[data-animate="fade-down"]  { transform: translateY(-40px); }
[data-animate="fade-in"]    { transform: none; }
[data-animate="scale-in"]   { transform: scale(0.94); }
[data-animate="slide-left"] { transform: translateX(60px); }
[data-animate="slide-right"]{ transform: translateX(-60px); }
[data-animate="rotate-in"]  { transform: rotate(-6deg) translateY(20px); }

[data-animate].is-visible {
    opacity: 1;
    transform: none;
}

/* Stagger delays — apply with data-delay="100" through "900" */
[data-delay="100"] { transition-delay: 100ms; }
[data-delay="150"] { transition-delay: 150ms; }
[data-delay="200"] { transition-delay: 200ms; }
[data-delay="300"] { transition-delay: 300ms; }
[data-delay="400"] { transition-delay: 400ms; }
[data-delay="500"] { transition-delay: 500ms; }
[data-delay="600"] { transition-delay: 600ms; }
[data-delay="700"] { transition-delay: 700ms; }
[data-delay="900"] { transition-delay: 900ms; }

/* ── Marquee (continuous horizontal scroll for trust strip) ──── */
@keyframes marquee-x {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}
.marquee {
    overflow: hidden;
    mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
}
.marquee-track {
    display: inline-flex;
    gap: var(--s-7);
    animation: marquee-x 40s linear infinite;
    white-space: nowrap;
}
.marquee:hover .marquee-track { animation-play-state: paused; }

/* ── Floating background blobs (used in hero) ───────────────────── */
@keyframes float-blob {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33%      { transform: translate(40px, -30px) scale(1.05); }
    66%      { transform: translate(-30px, 30px) scale(0.96); }
}

.blob {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.34;
    pointer-events: none;
    animation: float-blob 18s ease-in-out infinite;
}
.blob--orange { background: var(--primary); }
.blob--cream  { background: #ffd9b8; }
.blob--teal   { background: #a3d8d2; }

/* ── Spotlight cursor follow (used on hero / cards) ─────────────── */
.spotlight {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(400px circle at var(--mx, 50%) var(--my, 50%),
                                rgba(243, 112, 33, 0.18),
                                transparent 50%);
    transition: opacity var(--d-base);
    opacity: 0;
}
.spotlight-host:hover .spotlight { opacity: 1; }

/* ── Subtle pulsing dot (used for "live" indicators) ─────────────── */
@keyframes pulse-ring {
    0%   { box-shadow: 0 0 0 0   rgba(243, 112, 33, 0.55); }
    100% { box-shadow: 0 0 0 14px rgba(243, 112, 33, 0); }
}
.live-dot {
    width: 8px;
    height: 8px;
    background: var(--primary);
    border-radius: 50%;
    animation: pulse-ring 1.6s ease-out infinite;
    display: inline-block;
}

/* ── Reveal mask text (clip-path text reveal on scroll) ─────────── */
.reveal-mask {
    display: inline-block;
    overflow: hidden;
    vertical-align: top;
}
.reveal-mask > span {
    display: inline-block;
    transform: translateY(110%);
    transition: transform var(--d-slower) var(--ease-out);
}
[data-animate].is-visible .reveal-mask > span,
.reveal-mask.is-visible > span {
    transform: translateY(0);
}

/* ── Counter rolling for stat numbers ───────────────────────────── */
.counter { font-variant-numeric: tabular-nums; }

/* ── Number ticker for "live booking" feed ──────────────────────── */
@keyframes ticker-up {
    from { transform: translateY(100%); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}
.ticker-item { animation: ticker-up var(--d-slow) var(--ease-out); }

/* ── Page transition (used by smooth-link interceptor) ──────────── */
@keyframes page-out {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(-12px); }
}
@keyframes page-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}
body.is-leaving main { animation: page-out var(--d-base) var(--ease-in-out) forwards; }
body.is-entering main { animation: page-in  var(--d-base) var(--ease-out)    forwards; }

/* ── Loading shimmer ─────────────────────────────────────────────── */
@keyframes shimmer {
    0%   { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}
.shimmer {
    background: linear-gradient(90deg,
                                var(--bg-soft) 0%,
                                #fff 50%,
                                var(--bg-soft) 100%);
    background-size: 200% 100%;
    animation: shimmer 1.6s ease-in-out infinite;
    color: transparent;
    border-radius: var(--r-sm);
}

/* ── Hero headline: lines rise from blur into focus ─────────────
   motion.js wraps each <br>-separated line of [data-split-lines] in
   a .hline span at runtime, so admin-edited headings still work. */
[data-split-lines] .hline {
    display: block;
    opacity: 0;
    transform: translateY(28px);
    filter: blur(10px);
    transition: opacity 0.9s var(--ease-out),
                transform 0.9s var(--ease-out),
                filter 0.9s var(--ease-out);
    transition-delay: calc(180ms + var(--i, 0) * 160ms);
}
[data-split-lines].is-visible .hline {
    opacity: 1;
    transform: none;
    filter: blur(0);
}

/* ── Drawn swash under the hero accent ──────────────────────────── */
.accent-swash { position: relative; display: inline-block; }
.accent-swash .swash {
    position: absolute;
    left: -1%;
    bottom: -0.16em;
    width: 102%;
    height: 0.3em;
    overflow: visible;
    pointer-events: none;
}
.accent-swash .swash path {
    fill: none;
    stroke: var(--primary);
    stroke-width: 5px;
    vector-effect: non-scaling-stroke;
    stroke-linecap: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    opacity: 0.9;
    transition: stroke-dashoffset 0.8s var(--ease-in-out) 1.1s;
}
[data-split-lines].is-visible .accent-swash .swash path {
    stroke-dashoffset: 0;
}

/* ── Tactile tilt (service tiles) — JS sets the transform ─────────
   Fast transform easing only WHILE hovered, so the scroll-reveal
   transition from [data-animate] is left untouched. */
[data-tilt] { transform-style: preserve-3d; }
[data-tilt]:hover { transition: transform 0.16s var(--ease-out); }

/* ── Respect reduced motion ─────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    [data-animate] {
        opacity: 1;
        transform: none !important;
    }
}
