/* ============================================================================
   JANGAN edit di produk — sumber kebenaran: wtb-design-system/css/patterns.css
   ============================================================================
   WTB CINEMATIC SIGNATURE — POLA REUSABLE
   PT Widigital Tri Buana · patterns teruji dari widigitaltribuana.co.id
   ============================================================================

   PRASYARAT: import wtb-cinematic.css SEBELUM file ini.
     @import './wtb-cinematic.css';
     @import './patterns.css';

   Semua nilai merujuk token dari wtb-cinematic.css — tidak ada hardcoded color.
   Framework-agnostic: Astro / Next.js / SvelteKit / Vite / plain HTML semua kompatibel.
   ============================================================================ */


/* ============================================================================
   BASE RESET — opsional, bisa diganti reset framework masing-masing.
   WAJIB di dalam @layer base: rule tanpa layer selalu menang atas rule
   ber-layer, jadi reset unlayered mematikan SEMUA utility margin/padding
   framework yang hidup di @layer utilities (Tailwind v4) — insiden klinova.id
   25 Agu 2026: mx-auto/px-6 mati se-situs, konten mepet tepi viewport.
   Di situs tanpa framework perilaku tak berubah (selector * memang paling
   lemah; @layer didukung semua browser sejak 2022).
   ============================================================================ */

@layer base {
  *, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
}

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  font-family: var(--ff-body);
  background: var(--background);
  color: var(--foreground);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.65;
  overflow-x: hidden;
}

/* Grain overlay subtle — noise film 2% menambah persepsi premium di monitor 8-bit */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1000;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
  opacity: 0.02;
  background-size: 128px 128px;
}

a      { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
button { cursor: pointer; border: none; background: none; font-family: inherit; }


/* ============================================================================
   FOCUS RING — AA accessible
   ============================================================================ */

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

:focus:not(:focus-visible) { outline: none; }


/* ============================================================================
   SKIP LINK
   ============================================================================ */

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  background: var(--foreground);
  color: var(--background);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  font-weight: 500;
  z-index: 9999;
  transition: top var(--duration-normal) var(--ease-out);
}

.skip-link:focus { top: var(--space-4); }


/* ============================================================================
   CONTAINER / SHELL
   ============================================================================ */

.container,
.wtb-shell {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--space-6);
}

@media (min-width: 768px) {
  .container, .wtb-shell { padding-inline: var(--space-8);  }
}
@media (min-width: 1024px) {
  .container, .wtb-shell { padding-inline: var(--space-12); }
}
@media (min-width: 1440px) {
  .container, .wtb-shell { padding-inline: var(--space-16); }
}


/* ============================================================================
   TIPOGRAFI HEADING — Schibsted Grotesk 700 + Newsreader italic aksen
   ============================================================================ */

h1, h2, h3, h4 {
  font-family: var(--ff-display);
  color: var(--foreground);
  line-height: 1.08;
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.025em;
}

h1, .text-display {
  font-size: var(--text-display);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.04;
}

h2 {
  font-size: var(--text-h2);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
}

h3 {
  font-size: var(--text-h3);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
}

/* Aksen italic dalam heading = Newsreader serif (pasangan Tome master)
   Contoh: <h2>Bespoke <em>Agentic AI</em> Systems</h2> */
h1 em, h2 em, h3 em, h4 em, .text-display em {
  font-family: var(--ff-serif);
  font-weight: 400;
  font-style: italic;
  letter-spacing: -0.01em;
}

p {
  font-family: var(--ff-body);
  font-weight: 400;
  line-height: 1.7;
  margin: 0;
  font-size: 15px;
  color: var(--muted-foreground);
  /* IKUT parent (inherit), BUKAN justify global. Justify global bikin spasi
     antar-kata melar tak rata ("sungai" putih) pada teks pendek/kolom sempit/
     list ber-· → berantakan. Dengan inherit: parent `text-center` → tengah,
     default → kiri, utility text-* tetap dihormati. Editorial panjang yang
     butuh justify: pakai opt-in .text-justify di bawah. */
  text-align: inherit;
}

/* Opt-in justify — HANYA untuk blok editorial panjang & lebar (bukan UI/kartu). */
.text-justify {
  text-align: justify;
  text-align-last: left;
  -webkit-hyphens: auto;
  hyphens: auto;
}


/* ============================================================================
   EYEBROW / BADGE / LABEL — JetBrains Mono, uppercase, spasi lebar
   ============================================================================ */

/* Kontrak label master: SEMUA eyebrow/label kecil uppercase = JetBrains Mono */
.eyebrow {
  font-family: var(--ff-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--brand);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 3px var(--space-3);
  background: rgba(123, 63, 160, 0.08);
  color: var(--brand);
  border-radius: var(--radius-full);
  font-family: var(--ff-mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Eyebrow dengan garis aksen di kiri */
.eyebrow-line {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ff-body);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brand);
}

.eyebrow-line::before {
  content: '';
  width: 24px;
  height: 1px;
  background: var(--brand);
  flex-shrink: 0;
}

/* Aplikasikan mono ke semua varian eyebrow dan label struktural */
[class*="eyebrow"], .badge {
  font-family: var(--ff-mono) !important;
  letter-spacing: 0.12em;
}


/* ============================================================================
   AURORA LINE — garis aksen signature 3px (DNA logo sebagai aksen presisi)
   Contoh: <div class="aurora-line"></div> sebagai topline seksi
   ============================================================================ */

.aurora-line {
  height: 3px;
  border-radius: 2px;
  background: var(--sig-gradient);
}


/* ============================================================================
   AURORA HERO — latar aurora TER-RENDER untuk hero TERANG
   ============================================================================
   Latar menggunakan plate webp ter-render (anti-banding di monitor 8-bit)
   sebagai ganti gradasi CSS radial yang banding.

   ASET OVERRIDABLE — default resolve ke /images/aurora/aurora-porcelain.webp
   (jalur ABSOLUT dari root situs) lewat token --aurora-image.

   KENAPA ABSOLUT, BUKAN RELATIF (perbaikan 1.3.0, insiden produksi Studio 31 Agu):
   jalur relatif dihitung dari LOKASI AKHIR berkas CSS, bukan dari repo. Begitu
   bundler (Vite/webpack/Next) memindahkan CSS ke /_app/immutable/assets/,
   '../assets/aurora/' menunjuk folder yang tidak pernah ada -> 404 SENYAP: tidak
   ada galat build, halaman tetap jalan, hero cuma kehilangan plate auroranya dan
   jatuh ke background datar. Jalur absolut tidak ikut berpindah, jadi tahan bundler.
   KONSEKUENSINYA: konsumen WAJIB menyalin assets/aurora/ ke folder publiknya
   sebagai /images/aurora/ (lihat ADOPTION.md), atau menimpa --aurora-image.
   Proyek konsumen TIDAK perlu edit CSS ini — cukup timpa token --aurora-image di scope
   root mereka sendiri (path beda per stack: Next.js/Vite public/ vs Astro public/ vs
   custom CDN) — contoh kode lengkap ada di ADOPTION.md § "Override aset Aurora", BUKAN
   di sini (dijaga sengaja supaya berkas ini nol contoh literal ":root { ... }" yang
   bisa kebaca keliru sebagai deklarasi asli oleh parser token berbasis regex).
   Tanpa override, fallback var(--aurora-image, url(...)) di bawah yang dipakai.

   Intensitas per-halaman: set --aurora-opacity (default 0.85).
   Foolproof: plate dipasang di ::before z-index:-1 + isolation:isolate,
   jadi KONTEN mengalir di atasnya otomatis TANPA perlu z-index manual.
   ============================================================================ */

.aurora-hero {
  position: relative;
  isolation: isolate;
  background-color: var(--background);
}

.aurora-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(90deg, var(--background) 0%, rgba(244,242,247,0) 34%),
    linear-gradient(0deg, var(--background) 0%, rgba(244,242,247,0) 22%),
    var(--aurora-image, url('/images/aurora/aurora-porcelain.webp')) right top / cover no-repeat var(--background);
  opacity: var(--aurora-opacity, 0.85);
}

@media (max-width: 768px) {
  .aurora-hero::before {
    opacity: 0.5;
    background-position: 82% 0;
  }
}

/* ── ON-AURORA — alas untuk teks kecil yang duduk DI ATAS plate .aurora-hero ──
   Plate aurora bukan warna, melainkan FOTO: nilainya berjalan dari periwinkle pucat
   sampai ungu pekat dalam satu bidang. Teks yang kebetulan mendarat di bagian pekat
   kehilangan kontras, dan tidak ada satu warna teks pun yang aman di seluruh bidang —
   karena itu warna teks saja TIDAK bisa menyelesaikannya, dan text-shadow hanya
   mengaburkan masalah tanpa menjamin rasio.

   Insiden yang melahirkan kelas ini (31 Agu 2026): begitu plate aurora dipulihkan dari
   404, dua teks kecil yang selama ini duduk di atas Porcelain polos mendarat di ungu
   pekat — tautan di bawah mockup hero .co.id jatuh ke 2,99:1 dan label kartu klinova.id
   ke 4,30:1. Keduanya LOLOS sebelum plate ada. Memperbaiki aset memunculkan cacat yang
   selama ini disembunyikan oleh aset yang hilang.

   Pakai pada teks kecil (di bawah ~16 px) yang harus berada di dalam bidang aurora.
   Untuk judul besar tidak perlu: ukurannya sendiri sudah memberi keterbacaan.
   Markup: <p class="on-aurora">...</p> atau <span class="on-aurora">...</span>
*/
.on-aurora {
  /* Tinta tautan DI DALAM alas (1.4.1). Alas mengangkat latar, tapi anak yang menimpa
     warna induk — tautan, tanda, em berwarna — tetap memakai tintanya sendiri. Tautan
     merek #7b3fa0 di atas alas terukur 5,74:1: LOLOS AA, tetapi dua penilai independen
     membacanya lemah bersebelahan dengan teks arang di paragraf yang sama. Ambang AA
     itu lantai, bukan sasaran; di dalam alas kita naikkan satu anak tangga ramp.
     Terang 8,32:1 (dari 6,17), gelap 9,76:1 (dari 7,73), identitas merek tetap ungu. */
  --on-aurora-link: var(--brand-600);
  background: color-mix(in srgb, var(--background) 90%, transparent);
  border-radius: var(--radius-md);
  padding: 0.15em 0.45em;
  /* inline-block supaya alas mengikuti baris teks, bukan melebar ke seluruh kolom */
  display: inline-block;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

html.dark .on-aurora,
.dark .on-aurora { --on-aurora-link: var(--brand-300); }

.on-aurora a { color: var(--on-aurora-link); }

/* Di register gelap plate tidak dirender (lihat aturan di bawah), tapi kelas ini tetap
   sah dipakai: alasnya ikut token, jadi ia menjadi Deep Space, bukan porcelain terang. */

/* Register GELAP (html.dark): aurora-porcelain.webp = aset register TERANG —
   JANGAN dirender saat gelap; hero jatuh ke background-color token (ikut .dark).
   Dulu hanya guidance ADOPTION.md + preview.html (M145); dibakukan ke pattern
   ini pada JOB DEWAN kontras 25 Agu 2026 — insiden .co.id: plate terang tetap
   render di mode gelap sehingga teks hero (foreground terang) tenggelam. */
html.dark .aurora-hero::before { content: none; }

/* LEGIBILITAS teks di atas zona aurora — PENTING:
   Teks (terutama caption/label muted) yang duduk di area aurora-dominan
   (mis. sisi kanan hero) kontrasnya rendah jika pakai --muted-foreground.
   Gunakan .on-aurora: warna gelap + halo putih lembut mengangkat teks dari
   latar aurora yang ramai. Untuk body panjang di zona aurora, pakai
   --foreground (bukan --muted-foreground). */
.on-aurora,
.aurora-hero .caption,
.aurora-hero figcaption {
  color: var(--foreground);
  text-shadow: 0 0 10px rgba(244, 242, 247, 0.9), 0 1px 2px rgba(244, 242, 247, 0.75);
}


/* ============================================================================
   DEEP WASH — wash aurora soft-light di atas orb (elemen anak dalam .deep-field)
   Taruh sebagai div anak langsung dalam seksi gelap:
   <section class="deep-field">
     <div class="deep-wash"></div>
     <div class="container">…konten…</div>
   </section>
   ============================================================================ */

.deep-wash {
  position: absolute;
  inset: 0;
  background: var(--sig-gradient);
  mix-blend-mode: soft-light;
  opacity: 0.3;
  pointer-events: none;
}


/* ============================================================================
   DEEP FIELD — SEKSI DEEP SPACE PREMIUM reusable (resep 5-lapis)
   ============================================================================
   Cukup pasang kelas .deep-field ke elemen seksi gelap:
     base gradasi + vignette (background)
     + orb aurora (::before, z-index:-1)
     + wash soft-light (::after, z-index:-1)
   Semua self-contained — konten mengalir di atas tanpa perlu z-index manual.

   Tambah <div class="aurora-line"> di awal seksi untuk garis pemisah 3px.
   Varian .deep-field--alt = luminance lebih terang (tangga antar seksi gelap).

   WAJIB: elemen .deep-field harus punya position (sudah di-set),
   dan isolation:isolate agar ::before/::after tidak escape ke parent.
   ============================================================================ */

.deep-field {
  position: relative;
  isolation: isolate;
  color: var(--deepspace-foreground);
  background:
    radial-gradient(120% 80% at 50% 0%, transparent 55%, rgba(0,0,0,0.45)),
    linear-gradient(180deg, #141130 0%, #0d0b1f 60%);
  /* glass tokens — re-deklarasi agar kartu/tombol di .deep-field pakai nilai gelap */
  --glass-bg:     rgba(20,16,35,0.78);
  --glass-border: rgba(255,255,255,0.16);
  --glass-blur:   14px;

  /* KONTRAK SHADCN — re-deklarasi lokal (JOB DEWAN-M146, 24 Agu 2026, dual-mode toggle).
     .deep-field WAJIB jadi pulau gelap mandiri (self-contained) TERLEPAS dari register
     halaman (:root Porcelain terang vs .dark Deep Space) — sebelum toggle dua-mode ada,
     ini otomatis benar karena seluruh halaman selalu .dark. Sejak halaman terang bisa jadi
     default (M145), komponen di dalam .deep-field yang pakai var(--foreground) dkk langsung
     (mis. aturan dasar h1-h4{color:var(--foreground)} di wtb-cinematic.css, atau utility
     text-foreground/text-muted-foreground/border-border/bg-card) ikut kebaca warna TERANG
     dari :root — teks jadi nyaris tak kelihatan di atas plat gelap. Nilai di bawah IDENTIK
     dengan blok .dark di wtb-cinematic.css (nol warna baru) — cuma discope ulang supaya
     berlaku lokal tanpa butuh <html class="dark">. JANGAN ubah nilainya di sini — kalau
     .dark berubah, sinkronkan manual (belum ada mekanisme @property share otomatis). */
  --background:             #0d0b1f;
  --foreground:             #edeaf5;
  --card:                   #221c34;
  --card-foreground:        #edeaf5;
  --popover:                #16121e;
  --popover-foreground:     #edeaf5;
  --primary:                #7b2fd6;
  --primary-foreground:     #ffffff;
  --secondary:              #1c1729;
  --secondary-foreground:   #d9d3e8;
  --muted:                  #17131f;
  --muted-foreground:       #9b92b5;
  --accent:                 #241a33;
  --accent-foreground:      #d6c4ea;
  --destructive:            #e5654f;
  --destructive-foreground: #1c0b08;
  --border:                 rgba(237, 234, 245, 0.13);
  --input:                  rgba(237, 234, 245, 0.18);
  --ring:                   #7b2fd6;

  /* EKSTENSI WTB — ikut re-deklarasi (nilai MIRROR blok .dark; keputusan lini desain 28 Agu 2026).
     Tanpa ini, .eyebrow/text-brand di pulau gelap memakai --brand register TERANG (#7b3fa0)
     = 1,9-2,8:1 di plat gelap (temuan Asisten di /pricing Studio, produksi).
     CATATAN: --brand-navy dan --cta BUKAN warna TEKS di latar gelap (3,6-4,2 / 2,5-3,0) —
     hanya aksen/garis/latar tombol; teks di atas --cta putih (±5,7:1). */
  --brand:           #bd92e3;
  --brand-secondary: #8ea5d3;
  --brand-navy:      #5a74b0;
  --cta:             #7b2fd6;
  --cta-hover:       #9a5cf0;

  /* STATUS — mirror blok .dark verbatim (1.1.3): tanpa ini centang fitur/status
     di pulau gelap memakai nilai register terang (terukur 2,6:1 di /pricing). */
  --success:            #34c776;
  --success-foreground: #061a0e;
  --warning:            #f5a623;
  --warning-foreground: #2a1500;
  --info:               #8ea5d3;
  --info-foreground:    #0d1a2e;
}

/* Lapisan orb aurora — 3 radial ellipse bertumpuk (z-index:-1 agar di bawah konten) */
.deep-field::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 64% 52% at 12% 42%, rgba(107,91,196,0.30)  0%, transparent 62%),
    radial-gradient(ellipse 60% 56% at 88% 14%, rgba(142,165,211,0.22) 0%, transparent 58%),
    radial-gradient(ellipse 52% 46% at 60% 92%, rgba(123,63,160,0.18)  0%, transparent 56%);
}

/* Lapisan wash soft-light — sig-gradient di-blend soft-light */
.deep-field::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--sig-gradient);
  mix-blend-mode: soft-light;
  opacity: 0.30;
}

/* Varian --alt: luminance lebih terang, untuk tangga antar seksi gelap */
.deep-field--alt {
  background:
    radial-gradient(120% 80% at 50% 0%, transparent 55%, rgba(0,0,0,0.45)),
    linear-gradient(180deg, #171331 0%, #12102a 55%);
}

.deep-field--alt::before {
  background:
    radial-gradient(ellipse 62% 58% at 84% 30%, rgba(123,63,160,0.30)  0%, transparent 60%),
    radial-gradient(ellipse 56% 48% at 8%  78%, rgba(142,165,211,0.22) 0%, transparent 56%),
    radial-gradient(ellipse 46% 42% at 32% 6%,  rgba(123,47,214,0.18)  0%, transparent 54%);
}


/* ============================================================================
   BUTTONS — pil CTA premium
   ============================================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.8rem 1.65rem;
  min-height: 44px;
  border-radius: var(--radius-pill);
  font-family: var(--ff-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background-color var(--duration-normal) var(--ease-hover),
    transform        var(--duration-fast)   var(--ease-hover),
    box-shadow       var(--duration-normal) var(--ease-hover),
    border-color     var(--duration-normal) var(--ease-hover);
  border: 1px solid transparent;
  text-decoration: none;
  white-space: nowrap;
}

/* ── Solid escape hatch — nilai lama .btn--primary sebelum glass.
   Pakai untuk form, email, UI datar yang backdrop-filter tidak cocok. */
.btn--solid {
  background: var(--cta);
  color: var(--cta-foreground);
  border-color: var(--cta);
  box-shadow: 0 4px 16px rgba(123,63,160,0.24);
}
.btn--solid:hover {
  background: var(--cta-hover);
  border-color: var(--cta-hover);
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(123,63,160,0.32);
}
.btn--solid:active { transform: translateY(0); box-shadow: none; }

/* Primary = glass violet tebal (DEFAULT baru).
   .btn--glass / .btn--glass-brand = alias identik — ketiganya menulis efek yang sama. */
.btn--primary,
.btn--glass,
.btn--glass-brand {
  background: linear-gradient(135deg, rgba(123,47,214,0.96), rgba(107,51,144,0.94));
  -webkit-backdrop-filter: blur(8px) saturate(185%);
  backdrop-filter: blur(8px) saturate(185%);
  border: 1px solid rgba(255,255,255,0.5);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.80),
    inset 0 -1px 1px rgba(255,255,255,0.28),
    inset 0 0 16px rgba(255,255,255,0.12),
    0 8px 28px -8px rgba(123,63,160,0.55),
    0 2px 6px rgba(31,22,50,0.14);
  text-shadow: 0 1px 6px rgba(31,22,50,0.35);
  color: #fff;
  position: relative;
  isolation: isolate;
}

/* specular top-sheen — cahaya jatuh di tepi atas pil, tidak menutup teks */
.btn--primary::after,
.btn--glass::after,
.btn--glass-brand::after {
  content: '';
  position: absolute;
  left: 7%; right: 7%; top: 1px;
  height: 46%;
  border-radius: inherit;
  background: linear-gradient(to bottom, rgba(255,255,255,0.55), rgba(255,255,255,0));
  opacity: 0.55;
  pointer-events: none;
}

.btn--primary:hover,
.btn--glass:hover,
.btn--glass-brand:hover {
  background: linear-gradient(135deg, rgba(123,47,214,1), rgba(107,51,144,0.98));
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.95),
    inset 0 0 20px rgba(255,255,255,0.20),
    0 14px 36px -8px rgba(123,63,160,0.65),
    0 2px 8px rgba(31,22,50,0.16);
}

.btn--primary:active,
.btn--glass:active,
.btn--glass-brand:active { transform: translateY(0); box-shadow: none; }

/* Di latar gelap: primary glass lebih translusen (violet dingin) */
.dark .btn--primary, .dark .btn--glass, .dark .btn--glass-brand,
.deep-field .btn--primary, .deep-field .btn--glass, .deep-field .btn--glass-brand {
  background: linear-gradient(135deg, rgba(123,47,214,0.42), rgba(123,63,160,0.34));
}
.dark .btn--primary:hover, .dark .btn--glass:hover, .dark .btn--glass-brand:hover,
.deep-field .btn--primary:hover, .deep-field .btn--glass:hover, .deep-field .btn--glass-brand:hover {
  background: linear-gradient(135deg, rgba(123,47,214,0.52), rgba(123,63,160,0.44));
}

/* Ghost = clear glass (DEFAULT baru) — terang */
.btn--ghost {
  background: rgba(255,255,255,0.40);
  -webkit-backdrop-filter: blur(8px) saturate(185%);
  backdrop-filter: blur(8px) saturate(185%);
  border: 1px solid rgba(123,63,160,0.22);
  color: var(--ink, var(--foreground));
  position: relative;
  isolation: isolate;
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.80),
    inset 0 -1px 1px rgba(255,255,255,0.25),
    0 4px 12px -4px rgba(26,22,38,0.08);
}

.btn--ghost::after {
  content: '';
  position: absolute;
  left: 7%; right: 7%; top: 1px;
  height: 46%;
  border-radius: inherit;
  background: linear-gradient(to bottom, rgba(255,255,255,0.55), rgba(255,255,255,0));
  opacity: 0.55;
  pointer-events: none;
}

.btn--ghost:hover {
  background: rgba(255,255,255,0.58);
  border-color: rgba(123,63,160,0.38);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.95),
    inset 0 0 16px rgba(255,255,255,0.18),
    0 8px 20px -6px rgba(26,22,38,0.12);
}

/* Ghost gelap — clear glass putih translusen */
.dark .btn--ghost,
.deep-field .btn--ghost {
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.38);
  color: var(--deepspace-foreground);
}
.dark .btn--ghost:hover,
.deep-field .btn--ghost:hover {
  background: rgba(255,255,255,0.18);
  border-color: rgba(255,255,255,0.55);
}

/* White — surface terang (untuk tombol di atas plat gelap) */
.btn--white {
  background: var(--card);
  color: var(--foreground);
  border-color: var(--card);
}

.btn--white:hover { background: var(--secondary); }

/* Active state semua tombol */
.btn:active { transform: scale(0.98); }

/* Size modifiers */
.btn--size-sm  { font-size: 13px; padding: 0.5rem 1rem;    min-height: 36px; }
.btn--size-md  { font-size: 13px; padding: 0.75rem 1.5rem; min-height: 44px; }
.btn--size-lg  { font-size: 13px; padding: 1rem 2rem;      min-height: 52px; }


/* ============================================================================
   CARDS — kartu mengambang (radius 18px + elevasi kontekstual)
   ============================================================================ */

/* ATURAN KANONIK GLASS CONTRAST (Fable art-director, 2026-07-30):
   Kartu glass di atas latar VARIATIF (aurora/foto): alpha material ≥0.78 gelap / ≥0.85 terang,
   ATAU wajib scrim gradient internal di belakang teks. Tint kartu SELALU ikut register;
   kartu lawan-register = objek produk opaque (≥0.95, tanpa backdrop-filter).
   Kesan glass di TEPI (rim+sheen≤0.2+hairline), bukan transparansi bodi.
   QC: teks terkecil vs titik paling terang latar ≥ 4.5:1 (AA). */

/* Card = GLASS by default. Escape hatch: .card--solid. Opt-in refraksi: .card--refract. */
.card {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(160%);
  backdrop-filter: blur(var(--glass-blur)) saturate(160%);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-card);
  padding: var(--space-6);
  isolation: isolate;
  position: relative;
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,0.90),
    inset 0 -1px 1px rgba(255,255,255,0.25),
    0 1px 3px rgba(26,22,38,0.08),
    0 12px 32px -16px rgba(26,22,38,0.16);
  transition:
    box-shadow    var(--duration-normal) var(--ease-hover),
    transform     var(--duration-normal) var(--ease-hover),
    border-color  var(--duration-normal) var(--ease-hover);
}

/* specular sheen di tepi atas kartu — tidak animasikan backdrop-filter */
.card::after {
  content: '';
  position: absolute;
  top: 1px;
  left: 0; right: 0;
  height: 38%;
  border-radius: inherit;
  background: linear-gradient(to bottom, rgba(255,255,255,0.50), rgba(255,255,255,0));
  opacity: 0.45;
  pointer-events: none;
}

/* Dark register — shadow lebih dalam, sheen lebih redup */
.dark .card,
.deep-field .card {
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.18),
    0 24px 60px -24px rgba(0,0,0,0.85);
}
.dark .card::after,
.deep-field .card::after { opacity: 0.25; }

/* Dense modifier — alpha lokal lebih tinggi untuk kartu di atas orb terang */
.card--dense { background: rgba(255,255,255,0.82); }
.dark .card--dense,
.deep-field .card--dense { background: rgba(20,16,35,0.85); }

/* Hover interaktif — angkat + border violet */
.card--interactive:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-3px);
  border-color: var(--brand);
}

/* Opt-in refraksi — backdrop-filter url(#wtb-glass).
   Jangan jadikan default: berat GPU, hanya efektif di atas aurora/deep-space. */
.card--refract {
  -webkit-backdrop-filter: url("#wtb-glass") blur(var(--glass-blur)) saturate(160%);
  backdrop-filter: url("#wtb-glass") blur(var(--glass-blur)) saturate(160%);
}

/* ── Solid escape hatch (P3) — untuk form / tabel data / teks panjang
   dimana backdrop-filter tidak cocok atau latar tidak berwarna. */
.card--solid {
  background: var(--card);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

/* Mobile: kurangi blur agar lebih ringan di perangkat lambat */
@media (max-width: 768px) {
  .card { --glass-blur: 8px; }
}

/* Fallback: browser tanpa backdrop-filter — alpha tinggi supaya tetap terbaca */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .card { background: rgba(255,255,255,0.92); }
  .dark .card,
  .deep-field .card { background: rgba(34,28,52,0.92); }
}


/* ============================================================================
   SECTION RHYTHM — padding blok seragam per level
   ============================================================================ */

.section      { padding-block: var(--space-20); }
.section--lg  { padding-block: var(--space-32); }
.section--sm  { padding-block: var(--space-12); }
.section--subtle { background: var(--secondary); }

@media (min-width: 768px) {
  .section     { padding-block: var(--space-24); }
  .section--lg { padding-block: var(--space-32); }
}


/* ============================================================================
   NAV LINK — underline sweep dari kiri
   ============================================================================ */

.nav-link {
  position: relative;
  text-decoration: none;
  font-family: var(--ff-body);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  transition: color var(--duration-normal) var(--ease-out);
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: -3px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-normal) var(--ease-snap);
}

.nav-link:hover { color: var(--foreground); }
.nav-link:hover::after { transform: scaleX(1); }

.nav-link.is-active { color: var(--foreground); }
.nav-link.is-active::after { transform: scaleX(1); }


/* ============================================================================
   KEYFRAMES — CSS-only auto-play
   ============================================================================ */

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes drawLine {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes pulseDot {
  0%, 100% { opacity: 0.8; }
  50%       { opacity: 1; box-shadow: 0 0 0 4px rgba(46,204,113,0.20); }
}


/* ============================================================================
   REVEAL — CSS-only, fail-open (konten visible by default tanpa JS)
   Animasi hanya bila user tidak prefer reduced-motion.
   ============================================================================ */

@media (prefers-reduced-motion: no-preference) {
  .reveal   { animation: fadeUp 0.7s var(--ease-silk) both; }
  .reveal-1 { animation: fadeUp 0.7s var(--ease-silk) 0.08s both; }
  .reveal-2 { animation: fadeUp 0.7s var(--ease-silk) 0.16s both; }
  .reveal-3 { animation: fadeUp 0.7s var(--ease-silk) 0.24s both; }
}


/* ============================================================================
   REVEAL ON-SCROLL — IntersectionObserver + fail-open
   ============================================================================
   Tanpa JS: elemen [data-reveal] tampil penuh (tidak ada state tersembunyi di CSS).
   JS meng-arm elemen yang masih di bawah viewport (.io-armed),
   lalu IntersectionObserver tambahkan .io-in saat masuk.
   Reduced-motion: JS tidak jalan (tidak perlu guard di sini).
   ============================================================================ */

@media (prefers-reduced-motion: no-preference) {
  .io-armed {
    opacity: 0;
    transform: translateY(16px);
  }

  .io-in {
    opacity: 1;
    transform: none;
    transition:
      opacity   0.65s var(--ease-enter),
      transform 0.65s var(--ease-enter);
  }
}


/* ============================================================================
   AKSESIBILITAS — reduced motion + keterbacaan mobile
   ============================================================================ */

/* Keterbacaan mobile: teks isi tidak boleh di bawah 16px di layar kecil */
@media (max-width: 480px) {
  p, li, dd, dt {
    font-size: max(16px, 1em);
  }
}

/* Hard stop semua animasi dan transisi */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ============================================================================
   LIQUID GLASS — refraksi SVG (Chromium-only, progressive enhancement).
   Base kaca (blur + bevel + sheen) sudah di .btn--primary / .btn--ghost di atas —
   jalan di semua browser. Blok ini menambah displacement refraksi untuk Chromium.
   Konsumen WAJIB menaruh <svg> filter #wtb-glass sekali di layout:

   <svg width="0" height="0" style="position:absolute" aria-hidden="true">
     <filter id="wtb-glass" x="-20%" y="-20%" width="140%" height="140%"
             color-interpolation-filters="sRGB">
       <feTurbulence type="fractalNoise" baseFrequency="0.013 0.013"
                     numOctaves="2" seed="7" result="noise"/>
       <feGaussianBlur in="noise" stdDeviation="1.4" result="blurred"/>
       <feDisplacementMap in="SourceGraphic" in2="blurred" scale="24"
                          xChannelSelector="R" yChannelSelector="G"/>
     </filter>
   </svg>

   Card TIDAK dapat refraksi by default (terlalu berat GPU).
   Opt-in per-card: tambahkan kelas .card--refract.
   ============================================================================ */

/* Refraksi tombol — Chromium only, degradasi mulus di browser lain */
@supports (backdrop-filter: url("#wtb-glass")) or (-webkit-backdrop-filter: url("#wtb-glass")) {
  .btn--primary,
  .btn--glass,
  .btn--glass-brand,
  .btn--ghost {
    -webkit-backdrop-filter: url("#wtb-glass") blur(6px) saturate(185%);
    backdrop-filter: url("#wtb-glass") blur(6px) saturate(185%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn--primary,
  .btn--glass,
  .btn--glass-brand,
  .btn--ghost { transition: none; }
  .btn--primary:hover,
  .btn--glass:hover,
  .btn--glass-brand:hover,
  .btn--ghost:hover { transform: none; }
}


/* ============================================================================
   GLASS BLOOM — div dekoratif absolut untuk memberi warna sub-latar
   pada seksi kartu glass (backdrop punya sesuatu untuk di-blur di porcelain).
   Pasang sebagai anak langsung dalam seksi — parent butuh position:relative.
   Opsional per-section.
   ============================================================================ */

.glass-bloom {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(60% 50% at 20% 20%, rgba(142,165,211,0.09), transparent 60%),
    radial-gradient(55% 45% at 85% 75%, rgba(107,91,196,0.08), transparent 60%);
}


/* ============================================================================
   THEME TOGGLE — tombol switch mode terang/gelap (JOB DEWAN-M145)
   Pasangan: bootstrap inline <head> (no-FOUC, cegah kedipan) + wtb-theme-toggle.js
   (klik + sinkron localStorage). Lihat ADOPTION.md § "Mode gelap/terang".

   Markup kanonik:
     <button type="button" class="theme-toggle" data-wtb-theme-toggle
             aria-pressed="false" aria-label="Ganti ke mode gelap">
       <svg class="theme-toggle__icon theme-toggle__icon--sun" ...>...</svg>
       <svg class="theme-toggle__icon theme-toggle__icon--moon" ...>...</svg>
     </button>

   Ikon sun/moon di-swap murni via ancestor selector `html.dark` — SATU sumber
   kebenaran (class .dark yang sama menggerakkan semua token warna di
   wtb-cinematic.css). JS hanya update aria-pressed/aria-label (a11y), bukan
   ikon — jadi ikon tidak pernah "telat"/tidak sinkron dengan token warna.
   Hanya pakai token semantik yang sudah ada — nol hex baru.
   ============================================================================ */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--foreground);
  cursor: pointer;
  transition:
    background-color var(--duration-normal) var(--ease-hover),
    border-color      var(--duration-normal) var(--ease-hover),
    transform         var(--duration-fast)   var(--ease-hover);
}

.theme-toggle:hover  { background: var(--muted); border-color: var(--ring); }
.theme-toggle:active { transform: scale(0.94); }

.theme-toggle__icon {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  pointer-events: none;
}

/* default: mode terang → tampilkan matahari, sembunyikan bulan */
.theme-toggle__icon--moon { display: none; }

/* mode gelap aktif (html.dark) → tampilkan bulan, sembunyikan matahari */
html.dark .theme-toggle__icon--sun  { display: none; }
html.dark .theme-toggle__icon--moon { display: block; }

@media (prefers-reduced-motion: reduce) {
  .theme-toggle { transition: none; }
}


/* ============================================================================
   v1.1.0 — 10 KOMPONEN BARU (form + editorial + data)
   Semua flat/UI-datar (form/data — bukan glass, lihat ADOPTION.md "escape hatch")
   kecuali cta-ribbon/aurora-panel/blockquote yang tetap register-invariant lewat
   token shadcn (--background/--foreground/--border/--input/--ring/--muted*)
   yang SUDAH di-override otomatis di dalam .dark dan .deep-field — nol CSS
   tambahan dibutuhkan supaya komponen ini benar di kedua register.
   ============================================================================ */

/* ── INPUT — bidang teks formulir. Markup: <input class="input">; state error:
   tambah class .input--error (pesan error: elemen teks biasa, warna var(--destructive)). ── */
.input {
  display: block;
  width: 100%;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  background: var(--card);
  color: var(--foreground);
  outline: none;
  transition:
    border-color var(--duration-normal) var(--ease-hover),
    box-shadow   var(--duration-normal) var(--ease-hover);
}
.input::placeholder { color: var(--muted-foreground); }
.input:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 32%, transparent);
}
.input--error { border-color: var(--destructive); }
.input--error:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--destructive) 28%, transparent);
}
.input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: var(--muted);
}

/* ── SELECT — dropdown pilihan. Chevron SVG pakai stroke='currentColor' (nol hex,
   ikut var(--foreground) elemen) — bukan warna literal. Markup: <select class="select">. ── */
.select {
  display: block;
  width: 100%;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  padding-right: 2.5rem;
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  background-color: var(--card);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
  color: var(--foreground);
  cursor: pointer;
  outline: none;
  transition:
    border-color var(--duration-normal) var(--ease-hover),
    box-shadow   var(--duration-normal) var(--ease-hover);
}
.select:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 32%, transparent);
}
.select--error { border-color: var(--destructive); }
.select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background-color: var(--muted);
}

/* ── CHECKBOX — accent-color nativa (nol SVG kustom, nol hex). Markup:
   <input type="checkbox" class="checkbox" id="x"><label class="checkbox-label" for="x">. ── */
.checkbox {
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
  cursor: pointer;
  flex-shrink: 0;
}
.checkbox:disabled { cursor: not-allowed; opacity: 0.45; }

.checkbox-label {
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  color: var(--foreground);
  cursor: pointer;
}
.checkbox-label--disabled { color: var(--muted-foreground); cursor: not-allowed; }

/* ── TEXTAREA — area teks multi-baris. Markup: <textarea class="textarea">. ── */
.textarea {
  display: block;
  width: 100%;
  min-height: 120px;
  resize: vertical;
  border: 1px solid var(--input);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  line-height: 1.65;
  background: var(--card);
  color: var(--foreground);
  outline: none;
  transition:
    border-color var(--duration-normal) var(--ease-hover),
    box-shadow   var(--duration-normal) var(--ease-hover);
}
.textarea::placeholder { color: var(--muted-foreground); }
.textarea:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 32%, transparent);
}
.textarea--error { border-color: var(--destructive); }
.textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  resize: none;
  background: var(--muted);
}

/* ── STAT — metrik angka besar + label + indikator perubahan. Markup:
   <div class="stat"><p class="stat-number">12.847</p><p class="stat-label">...</p>
   <span class="stat-change stat-change--up">↑ 18.4%</span></div>
   Komponen TANPA chrome kartu sendiri — gabungkan dengan .card/.card--solid
   untuk tile berbingkai (lihat contoh preview.html). ── */
.stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.stat-number {
  font-family: var(--ff-display);
  font-size: clamp(2rem, 1.5rem + 2vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--foreground);
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.stat-label {
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  color: var(--muted-foreground);
  margin: 0;
}
.stat-change {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-3);
  border-radius: var(--radius-full);
  font-family: var(--ff-mono);
  font-size: var(--text-xs);
  font-weight: 500;
}
.stat-change--up {
  background: color-mix(in srgb, var(--success) 12%, transparent);
  color: var(--success);
}
.stat-change--down {
  background: color-mix(in srgb, var(--destructive) 12%, transparent);
  color: var(--destructive);
}

/* ── FEATURE ROW — baris horizontal ikon + judul + body. Markup:
   <div class="feature-row"><div class="feature-row-icon"><svg>...</svg></div>
   <div><h3 class="feature-row-title">Judul</h3><p class="feature-row-body">Body</p></div></div>
   Judul/body pakai class khusus (BUKAN selektor tag polos) supaya aman kalau
   konsumen menyisipkan <p class="eyebrow"> sebagai kicker di dalam baris. ── */
.feature-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}
.feature-row-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
  color: var(--brand);
  flex-shrink: 0;
}
.feature-row-title {
  font-family: var(--ff-display);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--foreground);
  margin: 0 0 4px;
}
.feature-row-body {
  font-family: var(--ff-body);
  font-size: var(--text-sm);
  color: var(--muted-foreground);
  margin: 0;
}

/* ── CTA RIBBON — pita ajakan bertindak lebar penuh. Gabungkan dengan
   .deep-field (gelap) atau .aurora-hero (terang) untuk latar. Markup:
   <div class="deep-field cta-ribbon"><p class="eyebrow">...</p>
   <h2>...</h2><p class="cta-ribbon-body">...</p><div class="cta-ribbon-actions">
   <a class="btn btn--primary">...</a></div></div>
   Body pakai class khusus (BUKAN selektor tag polos) supaya tidak menimpa
   .eyebrow kalau eyebrow dipasang sebagai <p> anak langsung juga. ── */
.cta-ribbon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-16) var(--space-8);
  border-radius: var(--radius-card);
  text-align: center;
}
.cta-ribbon h2 {
  font-family: var(--ff-display);
  font-size: var(--text-h2);
  color: var(--foreground);
  max-width: 42rem;
  margin: 0;
}
.cta-ribbon-body {
  max-width: 34rem;
  font-size: var(--text-lg);
  color: var(--muted-foreground);
  margin: 0;
}
.cta-ribbon-actions {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  justify-content: center;
}

/* Kompak — baris horizontal, judul kiri + CTA kanan */
.cta-ribbon--compact {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  text-align: left;
  padding: var(--space-8) var(--space-10);
  gap: var(--space-6);
  flex-wrap: wrap;
}

/* ── PRODUCT CARD — kartu produk WTB. Gabungkan dengan .card + .card--solid.
   Markup: <div class="card card--solid product-card"><div class="product-card-accent"
   style="background:var(--accent-studio)"></div><div class="product-card-header">
   <p class="eyebrow">Studio WTB</p><span class="badge">Unggulan</span></div>
   <h3>...</h3><p>...</p><ul class="product-card-features"><li>...</li></ul>
   <a class="btn btn--primary btn--size-sm">...</a></div> ── */
.product-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.product-card-accent {
  width: 36px;
  height: 4px;
  border-radius: var(--radius-sm);
}
.product-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}
.product-card h3 {
  font-family: var(--ff-display);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--foreground);
  margin: 0;
}
.product-card > p {
  font-size: var(--text-sm);
  color: var(--muted-foreground);
  flex: 1;
  margin: 0;
}
.product-card-features {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.product-card-features li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--muted-foreground);
}
.product-card-features li::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: var(--radius-full);
  background: var(--brand);
  flex-shrink: 0;
}

/* ── BLOCKQUOTE — kutipan editorial, garis kiri brand violet. Markup:
   <blockquote class="blockquote"><p>Kutipan...</p><footer>Atribusi</footer></blockquote> ── */
.blockquote {
  border-left: 3px solid var(--brand);
  padding: var(--space-4) var(--space-6);
  margin: 0;
  max-width: 640px;
}
.blockquote p {
  font-family: var(--ff-serif);
  font-size: 1.125rem;
  font-style: italic;
  color: var(--foreground);
  line-height: 1.7;
  margin: 0;
}
.blockquote footer {
  margin-top: var(--space-3);
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.blockquote footer::before { content: "— "; }

/* ── AURORA PANEL — plat kaca gelap dengan latar aurora sinematik. Selalu
   gabungkan dengan .deep-field (pemasok orb aurora + token gelap); kelas ini
   HANYA mengurus bentuk (radius + clip). Markup:
   <div class="deep-field aurora-panel" style="padding:40px"><p class="eyebrow">...</p>
   <h3>...</h3><p>...</p></div> ── */
.aurora-panel {
  border-radius: var(--radius-card);
  overflow: hidden;
}
