/* ==========================================================================
   Ooalah HQ — motion layer
   Cursor blend-exclusion, smooth scroll, stacked cards, parallax,
   tombol morph, transisi antar halaman.
   Dipakai bareng assets/js/motion.js
   ========================================================================== */

/* --------------------------------------------------------------------------
   Transisi antar halaman

   Native cross-document View Transitions: tanpa router, tanpa init ulang
   Lenis/GSAP, tanpa urusan history. Browser yang belum mendukung
   mengabaikan blok ini dan navigasinya berjalan normal.

   Arahnya konsisten ke atas — halaman lama naik keluar, halaman baru
   naik masuk — sehingga navigasi terbaca sebagai satu gerakan menerus.
   -------------------------------------------------------------------------- */
@view-transition { navigation: auto; }

@keyframes oo-page-in {
  from { transform: translateY(26px); }
}

/* HANYA SATU lapisan yang bergerak, dan tidak ada opacity sama sekali.
   Halaman lama diam dan tetap pekat; halaman baru meluncur naik DI ATASNYA
   dalam keadaan pekat penuh.

   Jangan animasikan opacity di kedua lapisan sekaligus: di pertengahan
   transisi keduanya jadi semi-transparan, warna latar menembus, dan
   kecerahan layar turun-naik — itu terbaca sebagai kedipan yang bikin
   sakit mata. Durasi yang berbeda antar lapisan memperparahnya. */
::view-transition-old(root) { animation: none; }
::view-transition-new(root) {
  animation: 0.4s cubic-bezier(0.22, 1, 0.36, 1) both oo-page-in;
}

/* Logo dan tombol nav TIDAK ikut bergerak. Keduanya ada di keenam halaman,
   jadi browser memperlakukannya sebagai elemen yang sama dan mempertahankan
   posisinya. Kontras antara dua elemen yang diam dan isi halaman yang
   bergeser inilah yang bikin terbaca seperti satu aplikasi. */
nav a[aria-label="Ooalah HQ home"] { view-transition-name: oo-brand; }
nav a[data-magnetic] { view-transition-name: oo-nav-cta; }

/* Reduced motion: pertukaran halaman jadi seketika, tanpa gerakan dan
   tanpa cross-fade bawaan browser. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="on"])::view-transition-old(root),
  html:not([data-motion="on"])::view-transition-new(root) { animation: none; }
}

/* --------------------------------------------------------------------------
   Lenis smooth scroll
   -------------------------------------------------------------------------- */
html.lenis,
html.lenis body { height: auto; }

.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

/* Area yang scroll-nya harus native (modal, dropdown, <pre>) */
[data-lenis-prevent] { overscroll-behavior: contain; }

/* --------------------------------------------------------------------------
   Custom cursor
   Satu elemen, dua warna: mix-blend-mode exclusion bikin kursor otomatis
   membalik diri di atas background terang maupun gelap.
   -------------------------------------------------------------------------- */
.oo-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 500;
  pointer-events: none;
  mix-blend-mode: exclusion;
  will-change: transform;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.oo-cursor.is-active { opacity: 1; }

.oo-cursor__dot,
.oo-cursor__disc {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 9999px;
  background: #fff;
  transform: translate(-50%, -50%) scale(1);
  will-change: transform;
}

.oo-cursor__dot {
  width: 12px;
  height: 12px;
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.oo-cursor__disc {
  display: flex;
  width: 76px;
  height: 76px;
  align-items: center;
  justify-content: center;
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Ikon digambar hitam di atas disc putih; exclusion membalik keduanya
   sekaligus, jadi kontras ikon selalu benar tanpa logika warna. */
.oo-cursor__disc svg {
  width: 26px;
  height: 26px;
  stroke: #000;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.3s ease 0.08s, transform 0.45s cubic-bezier(0.16, 1, 0.3, 1) 0.08s;
}

/* State: hover di atas tombol / link biasa.
   Sengaja kecil. Dot yang membesar terlalu jauh akan menutupi tombolnya
   sendiri, padahal tombolnya punya animasi morph yang justru mau dilihat. */
.oo-cursor.is-hovering .oo-cursor__dot {
  transform: translate(-50%, -50%) scale(1.7);
}

/* State: hover di atas area besar seperti kartu.
   Di sini tidak ada yang tertutupi, jadi dot boleh membesar jauh. */
.oo-cursor.is-card .oo-cursor__dot {
  transform: translate(-50%, -50%) scale(4);
}

/* State: hover di atas elemen ber-data-cursor-icon (pemutar video, tombol
   tutup modal). Ditaruh paling akhir supaya menang atas dua state di atas. */
.oo-cursor.has-icon .oo-cursor__dot { transform: translate(-50%, -50%) scale(0); }
.oo-cursor.has-icon .oo-cursor__disc { transform: translate(-50%, -50%) scale(1); }
.oo-cursor.has-icon .oo-cursor__disc svg { opacity: 1; transform: scale(1); }

/* Sembunyikan kursor bawaan hanya kalau kursor custom benar-benar aktif */
html.oo-has-cursor,
html.oo-has-cursor * { cursor: none !important; }

/* --------------------------------------------------------------------------
   Magnetic button
   -------------------------------------------------------------------------- */
[data-magnetic] {
  will-change: transform;
  display: inline-flex;
}

/* --------------------------------------------------------------------------
   Tombol: circle-to-pill morph + arrow cycle

   Dua gerakan yang di-stagger, bukan barengan:
     t+0ms    lingkaran melebar jadi pil
     t+60ms   panah lama terbang keluar ke kanan-atas
     t+140ms  panah salinannya masuk dari kiri-bawah

   Panahnya ADA DUA dan bertumpuk. Kalau cuma satu panah yang
   bolak-balik, gerakannya akan terbaca "mundur" saat kursor pergi.
   -------------------------------------------------------------------------- */
.oo-btn {
  --oo-btn-bg: rgba(255, 255, 255, 0.15);
  --oo-btn-bg-hover: #ffffff;
  --oo-btn-fg: #ffffff;
  --oo-btn-fg-hover: #0b1220;

  position: relative;
  display: inline-flex;
  width: fit-content;
  align-items: center;
  gap: 12px;
  padding: 4px 26px 4px 4px;
  border-radius: 9999px;
  color: var(--oo-btn-fg);
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
}

/* Varian untuk kartu berlatar terang */
.oo-btn--dark {
  --oo-btn-bg: rgba(11, 18, 32, 0.1);
  --oo-btn-bg-hover: #0b1220;
  --oo-btn-fg: #0b1220;
  --oo-btn-fg-hover: #ffffff;
}

/* Pil yang melebar. Saat diam ukurannya persis selingkaran ikon,
   sehingga terbaca sebagai tombol bundar biasa. */
.oo-btn__bg {
  position: absolute;
  left: 0;
  top: 0;
  z-index: -1;
  width: 44px;
  height: 44px;
  border-radius: 9999px;
  background: var(--oo-btn-bg);
  backdrop-filter: blur(4px);
  will-change: width;
}

.oo-btn__icon {
  position: relative;
  display: flex;
  width: 36px;
  height: 36px;
  flex: none;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 9999px;
}

.oo-btn__arrow {
  position: absolute;
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  will-change: transform;
}

/* Panah kedua menunggu di luar frame, arah kiri-bawah — searah
   dengan mata panahnya sendiri, jadi masuknya terasa natural.

   PENTING: hanya untuk jalur CSS. Kalau GSAP yang menyetir, posisi rest
   ini di-set lewat gsap.set(). Menaruhnya di dua tempat bikin GSAP
   melipat transform CSS jadi basis x/y lalu menambah xPercent di atasnya
   — posisinya terhitung dua kali dan panah tidak pernah sampai ke tengah. */
html:not(.oo-btn-js) .oo-btn__arrow--in { transform: translate(-150%, 150%); }

.oo-btn__label {
  position: relative;
  white-space: nowrap;
}

/* --- Varian ikon-di-kanan -------------------------------------------------
   Anatomi pil-terisi yang sudah dipakai di seluruh situs: [ Teks (→) ].
   Morph "lingkaran jadi pil" tidak berlaku di sini karena bentuknya sudah
   pil. Yang melebar justru lingkaran kecilnya, ke arah KIRI, menelan pil
   dan membalik warnanya. Morph yang sama, arah berlawanan.
   -------------------------------------------------------------------------- */
.oo-btn--end {
  padding: 4px 4px 4px 26px;
  background: var(--oo-btn-base);
}
.oo-btn--end .oo-btn__bg {
  left: auto;
  right: 0;
  backdrop-filter: none;
}

/* Ikon tidak ikut membalik warna: panahnya selalu berada di atas overlay
   yang sama, baik saat lingkaran kecil maupun saat sudah melebar penuh. */
.oo-btn--end .oo-btn__icon { color: var(--oo-btn-icon); }

/* Pil putih, lingkaran gelap */
.oo-btn--on-light {
  --oo-btn-base: #ffffff;
  --oo-btn-bg: #16233b;
  --oo-btn-bg-hover: #16233b;
  --oo-btn-fg: #16233b;
  --oo-btn-fg-hover: #ffffff;
  --oo-btn-icon: #ffffff;
}

/* Pil hitam, lingkaran putih */
.oo-btn--on-dark {
  --oo-btn-base: #000000;
  --oo-btn-bg: #ffffff;
  --oo-btn-bg-hover: #ffffff;
  --oo-btn-fg: #ffffff;
  --oo-btn-fg-hover: #0b1220;
  --oo-btn-icon: #0b1220;
}

/* Fallback tanpa JS / tanpa GSAP: morph yang sama, hanya lewat
   transition biasa. motion.js menaruh .oo-btn-js kalau ia mengambil alih. */
html:not(.oo-btn-js) .oo-btn,
html:not(.oo-btn-js) .oo-btn__bg,
html:not(.oo-btn-js) .oo-btn__arrow {
  transition:
    width 0.5s cubic-bezier(0.65, 0, 0.35, 1),
    background-color 0.4s cubic-bezier(0.65, 0, 0.35, 1),
    color 0.35s ease,
    transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
html:not(.oo-btn-js) .oo-btn:hover,
html:not(.oo-btn-js) .oo-btn:focus-visible { color: var(--oo-btn-fg-hover); }
html:not(.oo-btn-js) .oo-btn:hover .oo-btn__bg,
html:not(.oo-btn-js) .oo-btn:focus-visible .oo-btn__bg {
  width: 100%;
  background: var(--oo-btn-bg-hover);
}
html:not(.oo-btn-js) .oo-btn:hover .oo-btn__arrow,
html:not(.oo-btn-js) .oo-btn:focus-visible .oo-btn__arrow { transform: translate(150%, -150%); }
html:not(.oo-btn-js) .oo-btn:hover .oo-btn__arrow--in,
html:not(.oo-btn-js) .oo-btn:focus-visible .oo-btn__arrow--in {
  transform: translate(0, 0);
  transition-delay: 0.08s;
}

/* Panah lurus "→" bergerak mendatar, bukan diagonal */
html:not(.oo-btn-js) .oo-btn[data-arrow="right"] .oo-btn__arrow--in { transform: translate(-150%, 0); }
html:not(.oo-btn-js) .oo-btn[data-arrow="right"]:hover .oo-btn__arrow,
html:not(.oo-btn-js) .oo-btn[data-arrow="right"]:focus-visible .oo-btn__arrow { transform: translate(150%, 0); }
html:not(.oo-btn-js) .oo-btn[data-arrow="right"]:hover .oo-btn__arrow--in,
html:not(.oo-btn-js) .oo-btn[data-arrow="right"]:focus-visible .oo-btn__arrow--in { transform: translate(0, 0); }

/* --------------------------------------------------------------------------
   Stacked cards
   Tidak ada position:sticky — GSAP ScrollTrigger yang melakukan pinning,
   sama seperti cuberto.com.
   -------------------------------------------------------------------------- */
[data-stack] {
  position: relative;
}

[data-stack-item] {
  will-change: transform;
  transform-origin: center top;
  backface-visibility: hidden;
}

/* --------------------------------------------------------------------------
   Parallax
   -------------------------------------------------------------------------- */
[data-parallax] { will-change: transform; }

/* Media di-oversize sedikit supaya tidak muncul celah saat digeser */
[data-parallax-media] {
  transform: scale(1.12);
  will-change: transform;
}

/* --------------------------------------------------------------------------
   Aksesibilitas + preview override

   motion.js menaruh data-motion="on" / "off" di <html> kalau ada override
   preview. Tanpa override atributnya tidak ada sama sekali, sehingga
   pengunjung asli selalu jatuh ke perilaku prefers-reduced-motion.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="on"]) .oo-cursor { display: none !important; }
  html:not([data-motion="on"]).oo-has-cursor,
  html:not([data-motion="on"]).oo-has-cursor * { cursor: auto !important; }
  html:not([data-motion="on"]) [data-parallax],
  html:not([data-motion="on"]) [data-parallax-media] { transform: none !important; }

  /* Tombol tetap punya affordance hover, tapi tanpa gerakan:
     pil tidak melebar, panah tidak berputar, hanya warnanya berganti. */
  html:not([data-motion="on"]) .oo-btn,
  html:not([data-motion="on"]) .oo-btn__bg,
  html:not([data-motion="on"]) .oo-btn__arrow { transition: none !important; }
  html:not([data-motion="on"]) .oo-btn:hover .oo-btn__bg,
  html:not([data-motion="on"]) .oo-btn:focus-visible .oo-btn__bg { width: 44px !important; }
  html:not([data-motion="on"]) .oo-btn:hover .oo-btn__arrow,
  html:not([data-motion="on"]) .oo-btn:focus-visible .oo-btn__arrow { transform: none !important; }
  html:not([data-motion="on"]) .oo-btn:hover .oo-btn__arrow--in,
  html:not([data-motion="on"]) .oo-btn:focus-visible .oo-btn__arrow--in { transform: translate(-150%, 150%) !important; }
}

/* Preview dipaksa mati, walau sistem tidak minta reduced motion */
html[data-motion="off"] .oo-cursor { display: none !important; }
html[data-motion="off"].oo-has-cursor,
html[data-motion="off"].oo-has-cursor * { cursor: auto !important; }
html[data-motion="off"] [data-parallax],
html[data-motion="off"] [data-parallax-media] { transform: none !important; }

/* Perangkat sentuh tidak punya pointer — kursor custom dimatikan total.
   Ini tidak bisa di-override preview: tidak ada pointer untuk digambar. */
@media (hover: none), (pointer: coarse) {
  .oo-cursor { display: none !important; }
  html.oo-has-cursor,
  html.oo-has-cursor * { cursor: auto !important; }
}

/* --------------------------------------------------------------------------
   Indikator preview — hanya tampil saat override aktif
   -------------------------------------------------------------------------- */
.oo-motion-flag {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 600;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px 7px 11px;
  border: 0;
  border-radius: 9999px;
  background: rgba(17, 24, 39, 0.9);
  color: #fff;
  font: 500 12px/1 'Manrope', ui-sans-serif, system-ui, sans-serif;
  letter-spacing: 0.01em;
  cursor: pointer;
  backdrop-filter: blur(6px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
}
.oo-motion-flag:hover { background: rgba(17, 24, 39, 1); }

.oo-motion-flag__dot {
  width: 7px;
  height: 7px;
  border-radius: 9999px;
  background: #2b9b88;
}
html[data-motion="off"] .oo-motion-flag__dot { background: #9ca3af; }
