/* ==========================================================================
   motion.css — sistem gerak bersama untuk semua halaman kasirin.xyz
   --------------------------------------------------------------------------
   Aturan yang mengikat (jangan dilanggar saat menambah animasi baru):

   1. TIDAK ADA konten yang disembunyikan lewat CSS. Elemen hanya "disiapkan"
      oleh motion.js (inline style) dan hanya bila elemen itu memang masih di
      bawah layar. Kalau JavaScript mati, halaman tetap terbaca utuh.
   2. Animasikan `transform`, `opacity`, dan `clip-path` saja. Jangan animasikan
      width, height, top, atau box-shadow berulang — itu memicu layout/paint
      per frame.
   3. Semua gerakan berhenti untuk `prefers-reduced-motion: reduce`.
   4. Durasi mengikuti jarak: elemen kecil 180–320 ms, section 560–900 ms.
   5. Gerak yang dipicu scroll memakai variabel --m-sy (posisi gulir) dan
      --p (progres elemen 0..1). Keduanya diisi motion.js, bukan CSS.
   ========================================================================== */

:root {
    --m-dur-1: 180ms;   /* hover, tekan, ikon */
    --m-dur-2: 320ms;   /* kartu, panel */
    --m-dur-3: 620ms;   /* elemen masuk */
    --m-dur-4: 900ms;   /* section besar, angka */
    --m-ease: cubic-bezier(.22, .68, .24, 1);
    --m-ease-out: cubic-bezier(.16, 1, .3, 1);
    --m-spring: cubic-bezier(.34, 1.56, .64, 1);
    --m-sy: 0px;        /* posisi gulir dokumen, diisi motion.js */
    --m-prog: 0;        /* 0..1 sepanjang halaman */
}

/* ---------- Latar ambient + garis kemajuan ----------
   Satu lapisan tetap di belakang konten: dua cahaya limau/zaitun yang bergerak
   berlawanan arah saat halaman digulir, plus kisi tipis. Konten `main` dan
   footer dinaikkan ke z-index 1 supaya tidak tertutup. */

.m-ambient {
    position: fixed; inset: 0; z-index: 0; pointer-events: none;
    overflow: hidden; contain: strict;
}
.m-ambient i { position: absolute; display: block; }
.m-ambient .m-blob {
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(201, 242, 92, .30), rgba(201, 242, 92, 0));
}
.m-ambient .m-blob-a {
    width: min(74vw, 760px); aspect-ratio: 1; left: -16vw; top: -22vh;
    transform: translate3d(0, calc(var(--m-sy, 0px) * -.10), 0);
    animation: mDriftA 26s ease-in-out infinite alternate;
}
.m-ambient .m-blob-b {
    width: min(62vw, 580px); aspect-ratio: 1; right: -14vw; top: 26vh;
    background: radial-gradient(closest-side, rgba(36, 51, 15, .16), rgba(36, 51, 15, 0));
    transform: translate3d(0, calc(var(--m-sy, 0px) * .07), 0);
    animation: mDriftB 34s ease-in-out infinite alternate;
}
.m-ambient .m-grid {
    inset: 0;
    background-image:
        linear-gradient(to right, rgba(17, 19, 16, .035) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(17, 19, 16, .035) 1px, transparent 1px);
    background-size: 92px 92px;
    transform: translate3d(0, calc(var(--m-sy, 0px) * -.035), 0);
    mask-image: radial-gradient(90% 60% at 50% 0%, #000 0%, transparent 72%);
    -webkit-mask-image: radial-gradient(90% 60% at 50% 0%, #000 0%, transparent 72%);
}
@keyframes mDriftA {
    from { translate: -1.5% -1%; scale: 1; }
    to   { translate: 3.5% 2.5%; scale: 1.08; }
}
@keyframes mDriftB {
    from { translate: 1% 1%; scale: 1.04; }
    to   { translate: -3% -2%; scale: .96; }
}

/* Konten di atas lapisan ambient. */
main, .site-foot { position: relative; z-index: 1; }

/* Garis kemajuan gulir — 2 px limau di tepi atas, tumbuh dari kiri. */
body::after {
    content: ""; position: fixed; left: 0; right: 0; top: 0; height: 2px;
    background: linear-gradient(90deg, #c9f25c, #9ccf36);
    transform: scaleX(var(--m-prog, 0)); transform-origin: left center;
    z-index: 400; pointer-events: none;
}

/* ---------- Elemen masuk (scroll reveal) ---------- */

/* Transisi hanya aktif setelah motion.js menandai <html class="js-motion">,
   supaya browser tanpa JS tidak pernah memakai state transisi ini. */
.js-motion [data-motion] {
    transition:
        opacity var(--m-dur-3) var(--m-ease-out),
        transform var(--m-dur-3) var(--m-ease-out),
        clip-path var(--m-dur-3) var(--m-ease-out);
    transition-delay: var(--m-delay, 0ms);
    will-change: opacity, transform;
}

/* Varian gerak. Nilai awal dipasang motion.js (inline), jadi CSS hanya
   mengatur irama: pop/drop memakai pegas yang memantul, wipe memakai tirai. */
.js-motion [data-motion="pop"],
.js-motion [data-motion="drop"] {
    transition-duration: 780ms;
    transition-timing-function: var(--m-spring);
}
.js-motion [data-motion="wipe"] {
    transition-duration: 900ms;
    transition-timing-function: var(--m-ease-out);
}
.js-motion [data-motion="flip"] {
    transition-duration: 860ms;
    transition-timing-function: var(--m-ease-out);
}

/* Setelah selesai, lepaskan will-change supaya memori GPU tidak menumpuk. */
.js-motion [data-motion].is-in { will-change: auto; }

/* ---------- Judul terpecah per kata ----------
   motion.js memecah teks jadi <span class="m-w"><span class="m-wi">. Tanpa JS
   tidak ada span sama sekali, jadi judul tetap utuh. */

.m-w {
    display: inline-block; overflow: hidden; vertical-align: top;
    padding-bottom: .10em; margin-bottom: -.10em;
}
.m-wi { display: inline-block; }
.js-motion .m-words:not(.is-in) .m-wi {
    transform: translate3d(0, 118%, 0) rotate(3.5deg);
}
.js-motion .m-words .m-wi {
    transition: transform 820ms var(--m-ease-out) var(--m-delay, 0ms);
}
.m-words.is-in .m-wi { transform: none !important; }

/* ---------- Untai berjalan (marquee) ---------- */

.m-marquee {
    position: relative; overflow: hidden; display: flex; align-items: center;
    padding: 14px 0; user-select: none;
}
.m-marquee-track {
    display: flex; align-items: center; gap: 34px; white-space: nowrap;
    will-change: transform;
}
.m-marquee-track > * { flex: none; }

/* ---------- Rel bagian (titik navigasi samping) ---------- */

.m-rail {
    position: fixed; right: 18px; top: 50%; transform: translateY(-50%);
    z-index: 60; display: none; flex-direction: column; gap: 12px;
    padding: 12px 8px; border-radius: 999px;
    background: rgba(244, 241, 232, .72);
    backdrop-filter: blur(8px) saturate(140%);
    border: 1px solid rgba(17, 19, 16, .08);
    opacity: 0; transition: opacity 400ms var(--m-ease);
}
.m-rail.is-on { opacity: 1; }
.m-rail.is-over-dark { background: rgba(11, 12, 13, .55); border-color: rgba(255, 255, 255, .12); }
.m-rail a {
    position: relative; display: block; width: 8px; height: 8px; border-radius: 50%;
    background: rgba(17, 19, 16, .22); transition: transform 260ms var(--m-spring), background 260ms;
}
.m-rail.is-over-dark a { background: rgba(255, 255, 255, .34); }
.m-rail a .m-rail-name {
    position: absolute; right: 18px; top: 50%; transform: translateY(-50%) translateX(6px);
    font-family: var(--font-mono, ui-monospace, monospace); font-size: .625rem;
    letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
    background: #111310; color: #f4f1e8; padding: 3px 7px; border-radius: 4px;
    opacity: 0; pointer-events: none; transition: opacity 200ms, transform 200ms;
}
.m-rail a:hover .m-rail-name, .m-rail a:focus-visible .m-rail-name {
    opacity: 1; transform: translateY(-50%) translateX(0);
}
.m-rail a:hover { transform: scale(1.6); }
.m-rail a.is-active { background: #55672f; transform: scale(1.75); }
.m-rail.is-over-dark a.is-active { background: #c9f25c; }
@media (min-width: 1200px) { .m-rail { display: flex; } }

/* ---------- Interaksi: angkat, tekan, sorot ---------- */

.m-lift {
    transition: transform var(--m-dur-2) var(--m-ease), box-shadow var(--m-dur-2) var(--m-ease),
                border-color var(--m-dur-2) var(--m-ease);
}
.m-lift:hover { transform: translate3d(0, -4px, 0); }
.m-lift:active { transform: translate3d(0, -1px, 0) scale(.997); }

.m-press { transition: transform var(--m-dur-1) var(--m-ease); }
.m-press:active { transform: scale(.97); }

/* Garis bawah yang tumbuh dari kiri saat hover (untuk tautan teks). */
.m-underline { position: relative; }
.m-underline::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1.5px;
    background: currentColor; transform: scaleX(0); transform-origin: left;
    transition: transform var(--m-dur-2) var(--m-ease);
}
.m-underline:hover::after, .m-underline:focus-visible::after { transform: scaleX(1); }

/* Kartu yang sedikit menoleh ke arah kursor. Nilai --tx/--ty diisi motion.js
   hanya untuk perangkat bertunjuk presisi; tanpa itu kartu diam. */
.js-motion .m-tilt { transform-style: preserve-3d; }
.js-motion .m-tilt.is-tilting {
    transition: transform 120ms linear;
    transform: perspective(900px) rotateX(var(--tx, 0deg)) rotateY(var(--ty, 0deg)) translate3d(0, -4px, 0);
}

/* Tombol magnetis: ikut tertarik sedikit ke kursor. */
.js-motion .m-magnet { will-change: transform; }

/* ---------- Gerak ambient kecil (halus, tidak mengganggu) ---------- */

@keyframes mFloat {
    0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
    50%      { transform: translate3d(0, -10px, 0) rotate(-1.2deg); }
}
.m-float { animation: mFloat 6s ease-in-out infinite; }

@keyframes mBlink {
    0%, 92%, 100% { transform: scaleY(1); }
    95%           { transform: scaleY(.08); }
}
.m-blink { transform-origin: center; animation: mBlink 5.5s ease-in-out infinite; }

@keyframes mPulseRing {
    0%   { transform: scale(.9); opacity: .7; }
    70%  { transform: scale(1.9); opacity: 0; }
    100% { transform: scale(1.9); opacity: 0; }
}
.m-pulse::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    border: 1.5px solid currentColor; animation: mPulseRing 2.4s var(--m-ease-out) infinite;
}

@keyframes mShimmer {
    0%   { transform: translate3d(-120%, 0, 0); }
    100% { transform: translate3d(220%, 0, 0); }
}
.m-shimmer { position: relative; overflow: hidden; }
.m-shimmer::after {
    content: ""; position: absolute; top: 0; bottom: 0; width: 40%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.28), transparent);
    animation: mShimmer 3.6s var(--m-ease) infinite;
    pointer-events: none;
}

@keyframes mDash { to { stroke-dashoffset: 0; } }
.m-draw {
    stroke-dasharray: var(--m-len, 240);
    stroke-dashoffset: var(--m-len, 240);
    animation: mDash 1.6s var(--m-ease-out) forwards;
}

@keyframes mGrowY { from { transform: scaleY(.04); } to { transform: scaleY(1); } }
.m-grow { transform-origin: bottom; animation: mGrowY .9s var(--m-ease-out) both; }

@keyframes mSlideIn { from { transform: translate3d(-8px, 0, 0); opacity: 0; } to { transform: none; opacity: 1; } }
.m-slide-in { animation: mSlideIn var(--m-dur-3) var(--m-ease-out) both; }

/* ---------- Maskot ---------- */

.mascot { display: block; overflow: visible; }
.mascot .ms-arm-l, .mascot .ms-arm-r { transform-origin: 50% 20%; }
.mascot .ms-eyes { transition: transform 220ms var(--m-ease-out); }
.mascot .ms-coin { animation: mFloat 4.4s ease-in-out infinite; }
.mascot .ms-coin-2 { animation-delay: .8s; }
.mascot .ms-spark { animation: mPulseRing 3s var(--m-ease-out) infinite; transform-origin: center; }

/* Lambaian tangan: saat kursor menyentuh maskot, saat maskot melompat, dan
   sekali saat pertama terlihat di layar. */
.mascot:hover .ms-arm-r,
.mascot.is-hop .ms-arm-r,
.mascot.is-hello .ms-arm-r { animation: msWave 1.05s var(--m-ease) 1; }
@keyframes msWave {
    0%, 100% { transform: rotate(0deg); }
    22%      { transform: rotate(-22deg); }
    48%      { transform: rotate(10deg); }
    72%      { transform: rotate(-12deg); }
}

/* Napas pelan supaya karakter terasa hidup walau kursor diam. */
.mascot.is-live { animation: msBreathe 5.2s ease-in-out infinite; }
@keyframes msBreathe {
    0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
    50%      { transform: translate3d(0, -5px, 0) rotate(-.8deg); }
}

/* Lompat: badan naik dulu, mendarat dengan sedikit memantul. Dideklarasikan
   SETELAH is-live supaya lompatan menang saat keduanya aktif. */
.mascot.is-hop { animation: msHop 900ms var(--m-ease-out); }
@keyframes msHop {
    0%   { transform: translate3d(0, 0, 0) scale(1, 1); }
    18%  { transform: translate3d(0, 4px, 0) scale(1.05, .93); }
    46%  { transform: translate3d(0, -26px, 0) scale(.96, 1.06) rotate(-2deg); }
    72%  { transform: translate3d(0, 0, 0) scale(1.04, .95) rotate(1deg); }
    86%  { transform: translate3d(0, -6px, 0) scale(.99, 1.01); }
    100% { transform: translate3d(0, 0, 0) scale(1, 1); }
}
/* ---------- Angka yang menghitung ---------- */

[data-count] { font-variant-numeric: tabular-nums; }
[data-count].is-counted { animation: mPopIn 560ms var(--m-spring); }
@keyframes mPopIn {
    0%   { transform: scale(1); }
    42%  { transform: scale(1.14); }
    100% { transform: scale(1); }
}

/* ---------- Hormati preferensi pengguna ---------- */

@media (prefers-reduced-motion: reduce) {
    .js-motion [data-motion],
    .js-motion [data-motion].is-in {
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
        clip-path: none !important;
    }
    .js-motion .m-words .m-wi,
    .js-motion .m-words:not(.is-in) .m-wi {
        transition: none !important; transform: none !important;
    }
    .m-ambient .m-blob, .m-ambient .m-grid { animation: none !important; }
    .m-float, .m-blink, .m-shimmer::after, .m-pulse::after,
    .m-draw, .m-grow, .m-slide-in, .mascot .ms-coin, .mascot .ms-spark,
    .mascot:hover .ms-arm-r, .mascot.is-hop, .mascot.is-live,
    [data-count].is-counted {
        animation: none !important;
    }
    .m-draw { stroke-dashoffset: 0 !important; }
    .m-grow { transform: none !important; }
    .m-lift:hover, .m-press:active,
    .js-motion .m-tilt.is-tilting { transform: none !important; }
    .m-marquee-track { transform: none !important; }
    body::after { display: none; }
}
