/* stellar-hub.css — Stellar Hub front page (post 125), production-1.1.
 * Mengikuti Canva "Stellar Group Website" Page 1 - Home.
 * Spec: docs/superpowers/specs/2026-08-01-hub-canva-redesign-design.md
 *
 * Semua ukuran diukur dari docs/design-refs/canva/page-1-home.png pada lebar
 * referensi 1366px, lalu dijadikan clamp() supaya ikut menyusut di layar kecil.
 *
 * Sumber kebenaran style Hub. Edit DI SINI, bukan di database/Elementor. */

/* ===================== TOKEN ===================== */
:root {
  --hub-bg:      #000000;
  --hub-fg:      #ffffff;
  --hub-fg-dim:  rgba(255, 255, 255, 0.72);
  --hub-line:    rgba(255, 255, 255, 0.85);
  --hub-overlay: rgba(0, 0, 0, 0.55);

  --hub-side:    clamp(24px, 5.7vw, 80px);   /* margin sisi konten: 75-80px @1366 */
  --hub-nav-h:   clamp(64px, 7vw, 95px);     /* tinggi nav: 95px @1366 */

  /* Bebas Neue cap/em = 0,720. Heading di Home.svg cap 44-45px @1366
   * (terukur di 'GROW WITH US' dan 'CONTACT US', dua-duanya sama), jadi
   * font-size = 44,5 / 0,720 = 61,8px -> 4,52vw. Lebar hasilnya 268px
   * lawan 267px di desain. */
  --hub-display: clamp(34px, 4.52vw, 62px);
  --hub-body:    clamp(14px, 1.4vw, 19px);   /* Poppins — 19px @1366 */
  --hub-nav-fs:  clamp(15px, 1.9vw, 26px);   /* nav — 26px @1366 */
}

/* ===================== RESET HALAMAN ===================== */
/* 1.0 memaksa scroll-snap mandatory + scrollbar merah. Dua-duanya dibuang:
 * section 1.1 tingginya variatif, snap paksa memotong konten. */
html {
  scroll-snap-type: none;
  scroll-behavior: smooth;
  scroll-padding-top: var(--hub-nav-h);
  scrollbar-color: rgba(255, 255, 255, 0.35) #000;
  scrollbar-width: thin;
  overflow-x: hidden;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: #000; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.28); border-radius: 6px; border: 2px solid #000; }
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.45); }

body.home,
body.home .elementor-page {
  background-color: var(--hub-bg) !important;
  color: var(--hub-fg);
  font-family: 'Poppins', system-ui, -apple-system, sans-serif;
  overflow-x: clip;
}

/* Section 1.1 full-bleed: hilangkan boxed container + jarak antar section. */
body.home .elementor-section.elementor-section-boxed > .elementor-container {
  max-width: 100% !important;
  padding-left: 0;
  padding-right: 0;
}
body.home .elementor[data-elementor-type="wp-page"] > .elementor-section {
  background-color: var(--hub-bg);
  padding: 0;
  margin: 0;
}
body.home .elementor-widget:not(:last-child) { margin-bottom: 0; }

/* Wrapper konten bertepi. */
.hub-wrap {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--hub-side);
  width: 100%;
}

/* Paragraf badan — rata kiri-kanan seperti desain, dibatasi ~50% lebar. */
.hub-lead {
  font-size: var(--hub-body);
  line-height: 1.42;
  color: var(--hub-fg);
  text-align: justify;
  max-width: 46ch;
  margin: 0;
}

/* Heading display Anton. Sumber teks ditulis title-case, ditampilkan uppercase.
 * Warna dipaksa: Elementor Kit (post 5) menyetel warna heading global ke abu-abu
 * gelap, jadi tanpa !important heading nyaris tak terlihat di latar hitam.
 *
 * Bebas Neue, BUKAN Anton — lihat catatan pengujian di wp-content/fonts/global.css.
 * Anton dipertahankan sebagai cadangan kedua saja. */
body.home .hub-display,
body.home h2.hub-display {
  font-family: 'Bebas Neue', 'Anton', Impact, sans-serif !important;
  font-weight: 400;
  font-size: var(--hub-display);
  line-height: 1.05;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--hub-fg) !important;
  -webkit-text-fill-color: var(--hub-fg) !important;
  background: none !important;
  margin: 0 0 clamp(12px, 1.5vw, 20px);
}

/* Foto full-bleed (About 32:9, Career 32:9).
 * Frame ini juga host parallax: rasio dikunci DI SINI, gambarnya jadi layer
 * absolute yang LEBIH TINGGI dari frame sebanyak --px-travel di atas & bawah
 * supaya geseran tidak pernah menyingkap celah hitam. Lihat stellar-motion.css. */
.hub-band {
  margin: 0;
  width: 100%;
  aspect-ratio: 32 / 9;
  line-height: 0;
}
/* Career: 32:9 seperti band About. Sempat dicoba 16:9 penuh dan hasilnya
 * terlalu tinggi — di Home.svg foto tim ini terukur 387px tinggi @1366,
 * rasio 3,53:1. Framing default (tengah) sudah pas: kepala di atas, lutut
 * yang duduk di bawah, persis seperti desain. */
.hub-band--tall { aspect-ratio: 32 / 9; }

/* Band About: gedung SENGAJA dipotong di tengah, tidak menampilkan alasnya —
 * di Home.svg logo emas jatuh di 49% tinggi band, yang berarti jendela
 * tampilnya ada di y 217..649 dari sumber 1536x1024 -> object-position 37%.
 *
 * Tepi bawahnya dilembutkan gradien ("ambience"): tanpa itu potongan tengah
 * gedung berhenti mendadak sebagai garis lurus. Gradien ditaruh di FRAME,
 * bukan di layer, supaya tidak ikut bergeser saat parallax. */
#about .hub-band .hub-px-layer { object-position: 50% 37%; }
#about .hub-band::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 38%;
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,.55) 55%, var(--hub-bg) 100%);
}

/* ===================== 1. HERO ===================== */
/* JANGAN kembalikan `overflow: hidden` di sini. Dibuang 2026-08-25.
 *
 * Dulu ia memotong .hub-hero-bg (video starfield yang absolute inset:0 di dalam
 * hero). Lapisan itu sudah pindah ke .hub-stage di level <body> sejak 1.1, jadi
 * satu-satunya isi #home sekarang adalah lockup logo — dan logo itu
 * position:fixed (.hub-hero-mark.is-pinned) yang SENGAJA melintas keluar dari
 * kotak #home saat menempel di bawah nav.
 *
 * Blink & WebKit desktop membiarkan fixed lolos dari overflow induk, tapi Safari
 * iOS MEMOTONGNYA. Akibatnya di iPhone tulisan "STELLAR" hilang dan cuma
 * pusarannya yang tersisa — bukan kebetulan, tepi klipnya jatuh persis di sela
 * antara keduanya. Terukur 2026-08-25 pada logo 140px:
 *
 *   pusaran           viewport y 132,1 .. 269,9
 *   tepi bawah #home  viewport y 270,0      <- klip
 *   teks STELLAR      viewport y 278,9 .. 297,0
 *
 * Dan 270,0 itu keluar SAMA di semua iPhone (viewport 553/629/659/664/745),
 * karena posisi parkir logo diturunkan dari tinggi nav + konstanta di
 * stellar-motion.js, bukan dari tinggi layar. Jadi cacatnya kena 100% perangkat,
 * bukan sebagian.
 *
 * Kalau suatu saat hero butuh lapisan yang harus dipotong lagi, potong DI
 * LAPISAN ITU (bungkus sendiri ber-overflow), jangan di #home. */
#home {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex !important;
  align-items: center;
  justify-content: center;
}
#home > .elementor-container { width: 100%; }

/* ============ PANGGUNG LATAR: BINTANG SEPANJANG HALAMAN ============
 * Video starfield adalah lapisan PALING BAWAH untuk seluruh halaman, bukan
 * milik hero saja. position:fixed = ia tidak ikut scroll sama sekali, yang
 * membuatnya terbaca sebagai benda sangat jauh (prinsip sama dengan
 * background-attachment: fixed). Drift halusnya ditambahkan stellar-motion.js.
 *
 * Disuntik di level <body> oleh stellar-hub-overrides.php — di dalam section
 * ia akan terjebak stacking context section itu dan mustahil berada di
 * belakang section lain. */
html { background: #000; }
.hub-stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: #000;
}
.hub-stage-video {
  position: absolute;
  top: -8%;
  left: 0;
  width: 100%;
  height: 116%;          /* kelebihan tinggi = ruang gerak drift */
  object-fit: cover;
  display: block;
}

/* Agar bintang tembus, section HARUS transparan — hitamnya sekarang datang
 * dari panggung di belakang, bukan dari tiap section. Tetap naik di atas
 * panggung lewat z-index. */
body.home #page,
body.home .elementor-section,
body.home .elementor-column,
body.home .elementor-widget-wrap { background: transparent !important; }
body.home .elementor-section { position: relative; z-index: 1; }
/* #home diangkat di atas section lain. Logo yang menempel itu position:fixed
 * TAPI ia anak dari #home, jadi z-index-nya lokal terhadap stacking context
 * #home — dengan z-index sama (1), #about yang datang belakangan menimpanya
 * dan logonya hilang di balik gedung. #home sendiri sudah transparan dan
 * isinya cuma logo, jadi menaikkannya tidak menutupi apa pun. */
body.home #home { z-index: 5; }
/* Baris brand PUNYA lapisan hitamnya sendiri — permintaan user.
 *
 * Sempat dibuat transparan supaya panggung bintang tembus, tapi hasilnya
 * barisnya terbelah rasa: sisi video solid sementara sisi panel berbintik
 * bintang di belakang logo dan teksnya. Diberi hitam di tingkat BARIS supaya
 * kedua sisi (video dan panel) berdiri di atas alas yang sama, di Orion
 * maupun Nassa. */
/* Sisi VIDEO berlapis hitam (lihat .hub-brand-media), sisi TEKS transparan —
 * permintaan user: keterangan brand dibiarkan tembus ke panggung bintang.
 * Baris sengaja TIDAK diberi latar: latar di tingkat baris akan menutupi
 * bintang di belakang teksnya juga. */
body.home .hub-brand-row { background: transparent; }
body.home .hub-brand-panel { background: transparent; }

/* Tanpa poster, area video brand harus hitam polos sebelum ter-buffer.
 * Hitamnya dipasang di FRAME, bukan hanya di elemen <video>: video yang belum
 * punya frame apa pun bisa merender transparan, dan panggung bintang di
 * belakangnya akan menembus. Frame yang opak menutup kemungkinan itu. */
.hub-brand-media { background: #000; }
.hub-brand-video { background: #000; }

/* Elementor memberi position:relative ke SEMUA container/column/widget-nya, jadi
 * background absolute (inset:0) menempel ke widget yang cuma setinggi kontennya —
 * bukan ke section. Dipaksa static supaya #home / #contact yang jadi acuan dan
 * background-nya benar-benar penuh satu layar.
 *
 * Terukur di #contact sebelum aturan ini: section 900px, background cuma 360px.
 * .hub-contact-inner sengaja TIDAK ikut — ia butuh position:relative untuk
 * z-index-nya, dan bukan wrapper Elementor. */
#home .elementor-container,
#home .elementor-column,
#home .elementor-column-wrap,
#home .elementor-element,
#home .elementor-widget-wrap,
#home .elementor-widget-html,
#contact .elementor-container,
#contact .elementor-column,
#contact .elementor-column-wrap,
#contact .elementor-element,
#contact .elementor-widget-wrap,
#contact .elementor-widget-html { position: static !important; }

/* Selector di-ID-kan DENGAN SENGAJA. stellar-motion.css menyetel
 * .hub-px { position: relative } dan file itu dimuat SESUDAH file ini, jadi
 * dengan spesifisitas sama (0,1,0) ia akan menang dan background hero runtuh
 * jadi setinggi kontennya. #home menaikkan spesifisitas ke (1,1,0) — menang
 * berapa pun urutan muatnya. Hal yang sama berlaku di #contact .hub-contact-bg. */
#home .hub-hero-bg { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.hub-hero-video { background: #000; }

/* Pembungkus kartu 3D. Background section (#home, #contact) sengaja BUKAN
 * anak dari sini — elemen ber-transform jadi containing block untuk anak
 * absolute, dan background yang inset:0 akan menyusut ke tinggi pembungkus.
 * Karena itu pembungkusnya cuma memuat konten, dan harus naik di atas
 * background lewat z-index. */
.hub-sec { position: relative; z-index: 1; width: 100%; }
#home .hub-sec--hero { display: flex; justify-content: center; }

.hub-hero-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
}
.hub-hero-mark {
  width: clamp(130px, 11.5vw, 170px);   /* lockup ±140px @1366 di desain */
  height: auto;
  display: block;
}

/* ============ LOGO MENEMPEL (start -> finish) ============
 * Logo menempel di tengah layar dari puncak halaman sampai gedung tampil
 * penuh, lalu BERHENTI di titik itu dan hanyut ke atas bersama halaman.
 *
 * Dibuat fixed + digeser transform oleh JS, bukan position:sticky: sticky
 * berhenti bekerja di ujung induknya, sedangkan rentang menempel di sini
 * melintasi dua section (#home ke #about). */
/* top:0 — SELURUH posisi vertikal dikendalikan transform dari JS. Memakai
 * top:50% berarti dua sumber kebenaran untuk satu koordinat, dan yang satu
 * (persen) tidak bisa dianimasikan mengikuti scroll. */
.hub-hero-mark.is-pinned {
  position: fixed;
  top: 0;
  left: 50%;
  margin: 0;
  z-index: 3;
  will-change: transform;
}
/* Placeholder menjaga tinggi hero saat logonya diangkat jadi fixed,
 * supaya layout tidak melompat. */
.hub-hero-ghost { display: block; width: 1px; }

/* ===================== 2. ABOUT ===================== */
#about {
  padding: clamp(60px, 9vw, 130px) 0 0 !important;
}
#about .hub-wrap { margin-bottom: clamp(40px, 6vw, 96px); }

/* ===================== 3. BRANDS ===================== */
.hub-brand-row {
  display: grid;
  grid-template-columns: 1fr 1fr;   /* split tepat 50% seperti desain */
  align-items: stretch;
  min-height: clamp(420px, 56vw, 768px);
}
/* position:relative + overflow:hidden datang dari .hub-px (stellar-motion.css).
 * Posisi & tinggi video diatur .hub-px-layer di sana — absolute, supaya tinggi
 * natural video TIDAK ikut menentukan tinggi baris. Kalau tidak, di viewport
 * lebar barisnya melar jauh melewati 768px. */
.hub-brand-media { line-height: 0; }

.hub-brand-panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(20px, 3.2vw, 44px);
  padding: clamp(32px, 5.3vw, 72px);
  background: var(--hub-bg);
}
.hub-brand-logo {
  width: clamp(110px, 12vw, 165px);
  height: auto;
  display: block;
}
.hub-brand-copy {
  font-size: var(--hub-body);
  line-height: 1.42;
  text-align: justify;
  max-width: 42ch;
  margin: 0;
}

/* Baris kedua (Nassa) dibalik: panel kiri, media kanan. */
.hub-brand-row--flip .hub-brand-media { order: 2; }
.hub-brand-row--flip .hub-brand-panel { order: 1; }

/* Dua tombol ditumpuk rata kiri dan SENGAJA beda bobot — detail khas desain. */
.hub-brand-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.hub-btn-outline,
.hub-btn-solid {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .25s ease, color .25s ease, border-color .25s ease;
}
.hub-btn-outline {
  min-height: 48px;
  padding: 0 clamp(14px, 1.6vw, 22px);
  border: 1.5px solid var(--hub-line);
  color: var(--hub-fg);
  background: transparent;
  font-size: clamp(12px, 1.4vw, 19px);
  font-weight: 500;
  text-decoration: underline;          /* di desain teksnya bergaris bawah */
  text-underline-offset: 3px;
}
.hub-btn-outline:hover,
.hub-btn-outline:focus-visible {
  background: var(--hub-fg);
  color: #000;
  border-color: var(--hub-fg);
}
.hub-btn-solid {
  min-height: 57px;
  padding: 0 clamp(14px, 1.6vw, 22px);
  background: var(--hub-fg);
  color: #000;
  font-size: clamp(16px, 2.2vw, 30px);
  font-weight: 700;
  border: 1.5px solid var(--hub-fg);
}
.hub-btn-solid:hover,
.hub-btn-solid:focus-visible {
  background: transparent;
  color: var(--hub-fg);
}

/* ===================== 4. WHAT'S ON ===================== */
#whats-on { padding: clamp(50px, 7vw, 110px) 0 !important; }

/* Panel kaca buram di belakang carousel.
 *
 * Dipasang sebagai ::before pada SECTION, bukan sebagai background .hub-wo:
 * .hub-wo sengaja tanpa padding karena JS mengukur offsetLeft kartu dari
 * padding-edge stage — memberinya padding/background akan menggeser
 * perhitungan titik tengah carousel sebesar padding itu.
 *
 * backdrop-filter memburamkan yang ada di belakangnya, yaitu panggung bintang
 * yang position:fixed — itu yang membuat kacanya terbaca sebagai kaca. */
#whats-on::before {
  content: "";
  position: absolute;
  inset: 0;                       /* penuh, tanpa margin — panggung bintang
                                   * tidak boleh mengintip di tepinya */
  background: rgba(255, 255, 255, .045);
  border-top: 1px solid rgba(255, 255, 255, .09);
  border-bottom: 1px solid rgba(255, 255, 255, .09);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  backdrop-filter: blur(16px) saturate(130%);
  pointer-events: none;
  z-index: 0;
}
#whats-on > .elementor-container { position: relative; z-index: 1; }


/* .hub-wo tetap block: kalau flex, .hub-wo-dots ikut jadi item sebaris dan
 * tinggi stage-nya runtuh sehingga kartu terpotong.
 *
 * Semua ukuran carousel diturunkan dari EMPAT variabel di bawah — termasuk
 * --wo-step yang dibaca JS. Jadi jarak antar kartu disetel di sini, satu
 * tempat, bukan sebagai angka sihir di dalam JS. */
.hub-wo {
  position: relative;
  /* Lebar kartu TENGAH (kartu samping = lebar ini x --wo-side, lihat di bawah).
   *
   * Batas atasnya dinaikkan dari 386px desain -> 460px atas permintaan: kartu
   * tengah harus lebih dominan. Yang membatasi BUKAN cuma lebar layar tapi juga
   * TINGGI: tinggi kartu = 1,42 x lebarnya, jadi 460px lebar = 653px tinggi.
   * Di layar pendek (laptop 1366x768) itu lebih tinggi dari layarnya sendiri.
   * min(34vw, 55vh) menjaga rasio 1:1,42 tetap utuh — yang dikecilkan LEBARnya,
   * bukan tingginya dimampatkan — dengan batas tinggi ~78vh, masih utuh terlihat
   * saat carouselnya berada di tengah layar. Di 1440x900 batas ini tidak
   * menggigit: 55vh = 495px, jadi kartu tetap 460px penuh. */
  --wo-card-w: clamp(200px, min(34vw, 55vh), 460px);
  --wo-card-h: calc(var(--wo-card-w) * 548 / 386);   /* 1:1.42 — bukan 4:5 */
  --wo-pad:    clamp(20px, 3vw, 40px);

  /* Skala kartu samping. Terukur dari Home.svg awalnya 0,795 (230,6 / 290,1),
   * tapi kartu tengah sekarang dibesarkan sendirian: 0,667 x 460 = 307px, yaitu
   * lebar RENDER kartu samping yang lama persis. Jadi yang berubah hanya kartu
   * tengah — sampingnya tetap sebesar sebelumnya, kontras tengah/samping yang
   * menguat. Angka ini WAJIB sama dengan SCALE_SIDE di stellar-hub.js. */
  --wo-side:   .667;

  /* Geometri asal dari Home.svg (viewBox 1024,5 — kalikan 1,3333 utk px desain):
   *   kartu tengah  x 366,8  lebar 290,1  tinggi 411,5   -> 386 x 548 px
   *   kartu samping x  96,9  lebar 230,6                 -> skala 0,795
   *   jarak antar titik pusat 299,65                     -> 1,034 x lebar
   *
   * --wo-gap = celah KOSONG yang benar-benar terlihat antara tepi kartu tengah
   * dan tepi kartu samping, diminta 75px. Bukan jarak antar titik pusat: setengah
   * lebar kartu tengah + setengah lebar kartu samping = (1 + --wo-side) / 2 kali
   * lebar. Itu yang harus ditambahkan ke celahnya untuk mendapat --wo-step.
   *
   * Nilainya 75px MATI, bukan proporsional. Sempat dibungkus min() supaya
   * mengecil sendiri di layar sempit, tapi begitu lebar kartu ikut dibatasi vh,
   * pembungkus itu menggigit di layar besar juga: di 1440x900 kartunya 405px
   * sehingga celahnya jadi 66px, padahal yang diminta 75px. Layar sempit sudah
   * diurus media query <=768px yang menimpa --wo-gap sendiri, jadi di sini
   * tidak perlu penjaga apa pun. */
  --wo-gap:    75px;
  --wo-step:   calc(var(--wo-card-w) * (1 + var(--wo-side)) / 2 + var(--wo-gap));

  /* Panah dari Home.svg. Di Canva bentuknya BUKAN segitiga: punggungnya
   * bertakik cekung dan keempat sudutnya membulat, seperti ikon "send".
   * Aslinya gambar mask 311x480; poligonnya direkonstruksi dengan mencocokkan
   * hasil render ke mask itu (IoU 0,985), lalu sudutnya dibulatkan memakai
   * stroke-linejoin:round selebar 2r — jauh lebih ringkas daripada menghitung
   * delapan busur sendiri. Dipakai sebagai mask supaya warnanya tetap ikut
   * --hub-fg dan tidak perlu file terpisah. */
  --wo-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 311 480'%3E%3Cpath d='M43 54L268 240L43 426L96 240Z' fill='%23000' stroke='%23000' stroke-width='50' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.hub-wo-stage {
  position: relative;
  overflow: hidden;
  /* Geser horizontal ditangani JS (drag kartu), geser vertikal tetap milik
   * halaman. Menyerahkannya ke browser lewat touch-action jauh lebih mulus
   * daripada menebak arah gestur lalu preventDefault di JS. */
  touch-action: pan-y;
  /* Tanpa ini, menyeret carousel malah menyorot gambar/teks: browser
   * menganggapnya seleksi, dan begitu seleksi jalan gesturnya direbut. */
  -webkit-user-select: none;
          user-select: none;
}
/* Track TIDAK lagi digeser sebagai satu blok. Dulu ia flex-row yang di-translate
 * sejauh offsetLeft kartu aktif; cara itu tidak bisa melingkar — di indeks 0
 * tidak ada apa pun di sebelah kiri, jadi loopnya bolong. Sekarang tiap kartu
 * ditempatkan sendiri terhadap TENGAH berdasarkan jarak melingkar bertanda
 * (lihat render() di stellar-hub.js), sehingga tetangga kiri dari item pertama
 * adalah item terakhir. Track tinggal jadi kanvas ber-tinggi tetap. */
.hub-wo-track {
  position: relative;
  /* INI penyebab kartu terpotong di bawah, dan bukan karena ukurannya.
   *
   * Elementor memasang `.elementor *{ box-sizing: border-box }`, jadi
   * `height: var(--wo-card-h)` + `padding: var(--wo-pad) 0` yang lama BUKAN
   * berarti "setinggi kartu, plus jarak aman". Padding ikut termakan ke dalam
   * tinggi itu: tinggi total track tetap --wo-card-h, sementara kartu ditaruh
   * di `top: var(--wo-pad)` sehingga sisi bawahnya menjulur --wo-pad (20-40px)
   * melewati track — dan .hub-wo-stage yang overflow:hidden memotongnya persis
   * sebanyak itu. Makin besar --wo-pad di layar lebar, makin banyak terpotong.
   *
   * Sekarang jarak amannya ditulis sebagai bagian dari TINGGI, bukan padding,
   * jadi border-box tidak bisa memakannya. Kartu (top 50%, ditarik balik
   * separuh tingginya) mendarat tepat --wo-pad dari atas dan menyisakan
   * --wo-pad di bawah. */
  height: calc(var(--wo-card-h) + 2 * var(--wo-pad));
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Desain hanya memperlihatkan TIGA kartu: tengah + satu di kiri-kanan.
 * Sisanya opacity 0 — tetap di DOM supaya transisinya mulus saat masuk. */
.hub-wo-card {
  position: absolute;
  /* Vertikal DAN horizontal dipatok ke titik tengah track, bukan ke tepinya:
   * top/left 50% lalu ditarik balik separuh ukurannya sendiri. Sebelumnya
   * top: var(--wo-pad) — kebetulan hasilnya sama selama semua kartu setinggi
   * --wo-card-h, tapi begitu ada satu kartu berbeda tinggi (atau --wo-pad
   * berubah di media query) kartunya rata-ATAS, bukan rata-tengah. Dengan cara
   * ini semua kartu selalu satu garis sumbu, berapa pun skalanya — kartu samping
   * mengecil ke arah titik tengahnya sendiri (transform-origin bawaan 50% 50%),
   * jadi sumbu horizontalnya tetap berimpit dengan kartu tengah yang membesar. */
  top: 50%;
  left: 50%;
  width: var(--wo-card-w);
  height: var(--wo-card-h);
  margin-top: calc(var(--wo-card-h) / -2);
  margin-left: calc(var(--wo-card-w) / -2);
  transform: scale(.72);              /* ditimpa JS; ini keadaan sebelum render */
  opacity: 0;
  pointer-events: none;
  transition: transform .5s cubic-bezier(.22, 1, .36, 1), opacity .5s ease;
  will-change: transform, opacity;
}
.hub-wo-card.is-near   { opacity: .55; pointer-events: auto; }
.hub-wo-card.is-active { opacity: 1;   pointer-events: auto; }
/* Saat jari menyeret, kartu harus mengikuti 1:1 — transisi .5s membuatnya
 * terasa molor dan tertinggal di belakang jari. */
.hub-wo.is-dragging .hub-wo-card { transition: none; }
.hub-wo-card a { display: block; width: 100%; height: 100%; }
.hub-wo-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
  display: block;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .14);
  /* <img> bisa diseret sebagai berkas secara bawaan. Di tengah gestur slide,
   * yang muncul justru bayangan drag-and-drop dan slidenya batal. Firefox
   * mengabaikan properti ini, jadi ada juga penjaga dragstart di JS. */
  -webkit-user-drag: none;
}

/* Panah mengikuti bentuk asli di Home.svg (lihat --wo-arrow di .hub-wo).
 * Dipakai mask, bukan karakter: glyph panah bentuknya berbeda-beda per font/OS
 * dan font di sini self-hosted subset latin — glyphnya belum tentu ada. */
.hub-wo-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  /* HARUS di atas kartu, bukan sekadar "di atas latar". render() di
   * stellar-hub.js menulis z-index inline ke tiap kartu (10 - |slot|), jadi
   * kartu aktif duduk di 10. Nilai lama 2 kalah telak; di desktop tidak
   * kelihatan karena panahnya memang di luar area kartu, tapi di mobile lebar
   * kartu naik ke min(74vw, 45vh) dan --wo-gap mengecil sehingga kartu aktif
   * menutupi posisi panah dan panahnya hilang. 20 memberi ruang seandainya
   * skala z-index kartu itu suatu saat dinaikkan. */
  z-index: 20;
  width: 46px;
  height: 56px;              /* tap target tetap >= 44px */
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  font-size: 0;              /* buang karakter fallback di dalam tombol */
  cursor: pointer;
  opacity: .88;
  /* Konsekuensi dari z-index di atas: begitu panah menang, di mobile ia
   * menumpang di ATAS foto kartu, bukan di latar hitam. Putih di atas foto
   * terang bisa lenyap juga — bayangan tipis ini yang menjaga siluetnya tetap
   * terbaca. Hover menimpanya dengan glow putih (filter tidak menumpuk). */
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, .75));
  transition: opacity .2s ease, filter .2s ease;
  /* Tombol ini hidup di dalam konten Elementor, yang punya banyak aturan warna
   * bawaan untuk <button> beserta state-nya. Semuanya dinetralkan di SEMUA
   * state supaya tidak ada warna aksen yang bisa menyembul saat hover/aktif —
   * satu-satunya warna panah adalah var(--hub-fg) di ::before. */
  color: inherit;
  -webkit-tap-highlight-color: transparent;
}
.hub-wo-nav,
.hub-wo-nav:hover,
.hub-wo-nav:focus,
.hub-wo-nav:active {
  background: transparent !important;
  background-image: none !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
.hub-wo-nav::before {
  content: "";
  width: 20px;
  height: 31px;                        /* 311:480, proporsi asli mask */
  background: var(--hub-fg);
  -webkit-mask: var(--wo-arrow) center / contain no-repeat;
          mask: var(--wo-arrow) center / contain no-repeat;
}
/* Satu bentuk saja, yang kiri tinggal dicerminkan. */
.hub-wo-prev::before { transform: scaleX(-1); }
/* Hover = cahaya putih, angkanya disalin PERSIS dari state aktif menu nav
 * (`a.hub-nav-active` di stellar-header.css) supaya satu bahasa visual.
 * Bedanya di sana text-shadow — panah ini bentuk hasil mask, bukan teks, jadi
 * drop-shadow: ia mengikuti siluet panahnya, bukan kotak elemennya. */
.hub-wo-nav:hover,
.hub-wo-nav:focus-visible {
  opacity: 1;
  filter: drop-shadow(0 0 18px rgba(255, 255, 255, .85))
          drop-shadow(0 0 6px rgba(255, 255, 255, .6));
}
.hub-wo-nav:focus-visible { outline: 2px solid var(--hub-fg); outline-offset: 4px; opacity: 1; }
.hub-wo-prev { left: clamp(8px, 2.2vw, 42px); }
.hub-wo-next { right: clamp(8px, 2.2vw, 42px); }

.hub-wo-dots {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: clamp(16px, 2.4vw, 30px);
}
.hub-wo-dot {
  width: 13px;
  height: 13px;
  padding: 0;
  border-radius: 50%;
  background: transparent;
  border: 1.5px solid var(--hub-line);
  cursor: pointer;
  transition: background-color .25s ease;
}
.hub-wo-dot.is-active { background: var(--hub-fg); }

/* ===================== 5. CAREER ===================== */
#career { padding: 0 0 clamp(60px, 9vw, 130px) !important; }
#career .hub-wrap { margin-top: clamp(40px, 6vw, 96px); }

/* ===================== 6. CONTACT ===================== */
#contact {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex !important;
  align-items: center;
  overflow: hidden;
}
#contact > .elementor-container { width: 100%; }

/* Di-ID-kan supaya menang atas .hub-px { position: relative } di
 * stellar-motion.css yang dimuat belakangan (lihat catatan di #home).
 * background-image pindah ke .hub-px-layer di dalamnya; frame ini tinggal jadi
 * pemotong + tempat overlay. background-attachment: fixed tidak relevan lagi
 * (dan memang JANGAN dipakai — patah di iOS): gambarnya digerakkan transform. */
#contact .hub-contact-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
/* Overlay menempel di frame yang DIAM, bukan ikut bergeser bersama gambar. */
.hub-contact-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--hub-overlay);
}
.hub-contact-inner { position: relative; z-index: 1; }

.hub-contact-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 3vw, 40px);
  margin-bottom: clamp(40px, 7vw, 110px);
}
.hub-contact-col { display: flex; flex-direction: column; gap: 4px; }
.hub-contact-label {
  font-size: clamp(15px, 1.75vw, 24px);
  color: var(--hub-fg);
}
/* Warnanya dikunci di SEMUA state link. Tanpa :hover/:active yang ditulis
 * eksplisit, `a:active, a:hover { color: #336 }` di hello-elementor reset.css
 * (spesifisitas 0,1,1) menang atas rule dasar ini (0,1,0) dan nomornya berubah
 * biru navy saat di-hover. */
.hub-contact-num,
.hub-contact-num:link,
.hub-contact-num:visited,
.hub-contact-num:hover,
.hub-contact-num:focus,
.hub-contact-num:active {
  font-size: clamp(16px, 1.9vw, 26px);
  color: var(--hub-fg);
  text-decoration: none;
  transition: text-shadow .2s ease;
}
/* Hover = garis bawah + cahaya putih. Angka text-shadow-nya disalin PERSIS dari
 * state aktif menu nav (`a.hub-nav-active` di stellar-header.css) supaya satu
 * bahasa visual — sama seperti panah carousel What's On. */
.hub-contact-num:hover,
.hub-contact-num:focus-visible {
  text-decoration: underline;
  text-underline-offset: .18em;
  text-shadow: 0 0 18px rgba(255, 255, 255, .85), 0 0 6px rgba(255, 255, 255, .6);
}
.hub-contact-num:focus-visible { outline: 2px solid var(--hub-fg); outline-offset: 4px; }

.hub-contact-addr {
  font-style: normal;
  font-size: clamp(13px, 1.25vw, 17px);
  line-height: 1.62;
  color: var(--hub-fg);
}

/* Footer 1.0 tidak dimatikan dari sini. Menyembunyikannya lewat CSS tetap
 * mengirim markup + alamat ganda ke mesin pencari, jadi rendernya dicegat di
 * PHP — lihat filter enable_hfe_render_footer di stellar-hub-overrides.php. */

/* ===================== RESPONSIVE ===================== */
@media (max-width: 1024px) {
  .hub-lead, .hub-brand-copy { text-align: left; }   /* justify bikin sungai teks di kolom sempit */
}

@media (max-width: 768px) {
  .hub-brand-row {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  /* Di 1 kolom tinggi baris tidak lagi ditentukan grid, jadi frame-nya yang
   * mengunci rasio (layer di dalamnya tetap absolute — lihat .hub-px-layer).
   *
   * `width: 100%` WAJIB, bukan hiasan. Frame ini grid item yang isinya HANYA
   * anak position:absolute, jadi lebar fit-content-nya 0. Biasanya ia tetap
   * selebar track karena justify-self:normal = stretch — tapi CSS Box
   * Alignment menyatakan `normal` berperilaku `start`, bukan `stretch`, untuk
   * item yang punya aspect-ratio. WebKit menerapkan aturan itu, Blink tidak.
   *
   * Akibatnya di iPhone/Safari: track 390px, item 0x0, dan karena .hub-px
   * overflow:hidden <video> di dalamnya terpotong habis — video brand HILANG
   * total sementara logo/teks/tombol tetap tampil. Terukur 2026-08-25 di
   * WebKit (0x0) lawan Chromium (390x292) pada halaman yang sama.
   *
   * Jangan diganti `justify-self: stretch`: itu memperbaiki sumbu inline saja
   * dan tetap bergantung pada tafsir engine. Lebar eksplisit tidak ambigu. */
  .hub-brand-media { aspect-ratio: 4 / 3; width: 100%; }
  /* Di mobile urutannya selalu media dulu, teks menyusul — di kedua baris. */
  .hub-brand-row--flip .hub-brand-media { order: 0; }
  .hub-brand-row--flip .hub-brand-panel { order: 0; }

  .hub-lead, .hub-brand-copy { max-width: none; }
  .hub-band { aspect-ratio: 4 / 3; }

  .hub-contact-grid { grid-template-columns: 1fr; gap: 18px; }
  #contact { min-height: 0; padding: clamp(60px, 14vw, 100px) 0 !important; }

  /* Yang diubah VARIABELNYA, bukan .hub-wo-card { width }. Lebar kartu dipakai
   * juga oleh tinggi (rasio 1:1,42), oleh margin-left yang memusatkannya, dan
   * oleh --wo-step. Menimpa width saja membuat ketiganya memakai lebar lama:
   * kartu jadi melebar tapi pendek, tergeser dari tengah, dan celahnya tidak
   * lagi sesuai. */
  .hub-wo {
    padding: 0 40px;
    --wo-card-w: min(66vw, 320px, 45vh);
    /* Celahnya diperkecil di sini, dan ini bukan sekadar selera: layar sempit
     * cuma punya (50vw - setengah kartu) untuk mengintip kartu samping, dan
     * celah 75px-proporsional memakan habis jatah itu — kartu sampingnya jadi
     * cuma segaris tipis dan carouselnya tidak terbaca sebagai carousel. */
    --wo-gap: clamp(16px, 4.5vw, 40px);
  }
}

@media (max-width: 480px) {
  .hub-hero-mark { width: 140px; }
  .hub-wo { --wo-card-w: min(74vw, 45vh); }
}

/* Tap target minimal 44px. */
@media (pointer: coarse) {
  .hub-wo-dot { width: 22px; height: 22px; border-width: 4px; border-color: transparent; background-clip: padding-box; box-shadow: inset 0 0 0 1.5px var(--hub-line); }
  .hub-wo-dot.is-active { box-shadow: inset 0 0 0 11px var(--hub-fg); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hub-wo-track, .hub-wo-card { transition: none; }
}

/* ---------- WHAT'S ON KOSONG ----------
 * Section TETAP TAMPIL saat belum ada item — keputusan user 2026-08-24.
 * Markup dari stellar-hub-aggregate.php, dan HANYA blok ini yang membawa judul
 * "What's On": saat terisi, section Hub cuma berisi carousel poster tanpa judul.
 *
 * #whats-on::before (pita kaca) tetap terpasang, jadi latarnya sudah benar dan
 * blok ini butuh z-index di atasnya seperti .elementor-container. */
/* Tinggi menyamai carousel (permintaan user 2026-08-24) — alasan sama dengan
 * .nx-wo-empty di nassa-home.css. Blok ini memakai kelas .hub-wo juga, jadi
 * --wo-card-h dan --wo-pad diwarisi; carousel JS berpegang pada atribut
 * [data-hub-carousel] sehingga blok kosong tidak ikut di-init.
 *
 * min-height = tinggi kartu + padding stage atas-bawah + baris dot (13px) +
 * jaraknya. */
.hub-wo-empty {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: calc(var(--wo-card-h) + 2 * var(--wo-pad)
                   + 13px + clamp(16px, 2.4vw, 30px));
  padding-left: 24px;
  padding-right: 24px;
}
.hub-wo-empty > * { max-width: 660px; }
/* Warna, font, dan !important-nya datang dari .hub-display (lihat aturan di
 * bagian atas berkas ini). Di sini HANYA ukurannya yang diturunkan — judul
 * hero-size di atas satu paragraf pendek terlihat timpang. */
body.home h2.hub-wo-empty-head {
  margin: 0 0 14px;
  font-size: clamp(26px, 3.1vw, 42px);
}
.hub-wo-empty-title {
  margin: 0;
  font-family: 'Poppins', system-ui, sans-serif;
  font-weight: 600;
  font-size: clamp(16px, 1.54vw, 21px);
  line-height: 1.3;
  color: #fff;
}
.hub-wo-empty-sub {
  margin: 10px 0 0;
  font-family: 'Poppins', system-ui, sans-serif;
  font-size: clamp(13px, 1.1vw, 15px);
  line-height: 1.55;
  color: rgba(255, 255, 255, .68);
}
