/*
 * seller.id landing — public front door on the central domain, extending the
 * "Buku Kas" identity (docs/design/visual-direction.md §1 tokens + §3 rules).
 *
 * Long-form commercial structure, look tetap Buku Kas. Satu elemen berani:
 * mock kartu approval + stempel DISETUJUI di hero (pola stempel dari
 * dashboard.css). Layar produk yang dipajang TANGKAPAN LAYAR ASLI (WebP di
 * public/img/landing), dibungkus bingkai browser — kecuali chat Telegram yang
 * tetap mock CSS karena itu aplikasi orang lain. Tetap tanpa JS. Pembatas
 * antar seksi: garis perforasi "sobekan buku kas".
 *
 * Served as a plain file from public/css (copy of this source) — no build
 * step. Fonts bundled locally in public/fonts, NEVER a runtime CDN.
 */

/* ---------------------------------------------------------------- fonts */

@font-face {
    font-family: 'Bricolage Grotesque';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/fonts/bricolage-grotesque-latin-600-normal.woff2') format('woff2');
}

@font-face {
    font-family: 'Bricolage Grotesque';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/bricolage-grotesque-latin-700-normal.woff2') format('woff2');
}

@font-face {
    font-family: 'Public Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/public-sans-latin-400-normal.woff2') format('woff2');
}

@font-face {
    font-family: 'Public Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/public-sans-latin-500-normal.woff2') format('woff2');
}

@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
}

/* Fraunces & Archivo Black dulu di-load di sini buat mock storefront yang
   digambar CSS. Mock-nya udah diganti tangkapan layar asli — fontnya ikut
   kebawa di dalam gambar — jadi halaman ini nggak perlu ngunduhnya lagi. */

/* --------------------------------------------------------------- tokens */

:root {
    --paper: #F6F7F4;        /* kertas buku kas, sejuk — BUKAN cream hangat */
    --ink: #1C2B33;          /* tinta pena, teal-hitam — bukan #000 */
    --ruling: #DDE3DC;       /* garis ruling — encoding, bukan hiasan */
    --stamp-green: #0F6B54;  /* stempel DISETUJUI — primary action */
    --stamp-red: #C2453A;    /* stempel DITOLAK — destructive */
    --pending-ink: #B7791F;  /* kuning tembaga: menunggu keputusan */
    --data-blue: #2563A8;    /* angka metrik/link/ikon, dipakai hemat */
    --chart-green: #12915A;  /* seri 2 chart (BUKAN stamp-green, §3) */
    --muted: #5C6B72;
    --kartu: #FFFFFF;
    /* Isian + label tombol utama. Jadi token supaya tanah gelap bisa nukernya
       tanpa nulis ulang aturan tombolnya (lihat blok tanah di bawah). */
    --utama-teks: #FFFFFF;
    --utama-tekan: #0C5947;
    --display: 'Bricolage Grotesque', system-ui, sans-serif;
    --body: 'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* ---------------------------------------------------------------- tanah */

/*
 * GROUND PER SEKSI — irama halaman panjang.
 *
 * Sebelum ini halaman ini satu warna kertas dari nav sampai footer: tiap seksi
 * kebaca sama pentingnya dan mata nggak punya tempat berhenti. Sekarang terang
 * tetap KEADAAN NORMAL, dan gelap dipakai TIGA kali doang sebagai penekanan:
 *
 *   nav + hero          kertas
 *   showcase            kertas
 *   deep-dive 1 toko    kertas
 *   deep-dive 2 iklan   GELAP tinta   <- "sihir" produknya
 *   deep-dive 3 izin    kertas
 *   kemampuan           tint          <- kertas yang sedikit lebih dalam
 *   bukti/angka jujur   GELAP hijau   <- janji yang distempel ke sistemnya
 *   cara kerja          kertas
 *   paket               kertas        <- harga wajib paling terbaca, jangan diutak-atik
 *   band CTA + footer   GELAP tinta   <- satu blok penutup
 *
 * Dua momen gelapnya sengaja beda tanah (tinta vs hijau stempel) biar nggak
 * kebaca sebagai band yang sama diulang, dan hijaunya nyambung ke metafora
 * stempel — seksi itu isinya memang janji yang dicap ke dalam sistem.
 *
 * CARANYA LEWAT TOKEN, bukan nulis ulang warna di tiap komponen: kelas tanah
 * cuma nge-redefine --paper/--ink/--muted/--ruling/--kartu (plus aksen yang
 * perlu dinaikin terangnya) di scope-nya sendiri, terus kartu, tombol, chip,
 * bingkai, dan garis di dalamnya nyesuaiin otomatis. Nambah komponen baru?
 * Nggak perlu mikirin ground-nya sama sekali.
 *
 * `color` HARUS ikut diset di kelas tanahnya: `body` udah nge-compute
 * warnanya dari --ink versi :root, dan anak-anaknya mewarisi warna hasil
 * hitungan itu, bukan variabelnya.
 *
 * TANPA WARNA BARU: yang gelap turunan --ink #1C2B33, yang hijau turunan
 * --stamp-green #0F6B54, yang tint turunan --paper #F6F7F4.
 *
 * KONTRAS (diukur, WCAG 2.1 non-large text ≥ 4.5:1, batas kontrol ≥ 3:1):
 *   gelap  teks utama 14,7:1 · teks sekunder 8,5:1 · eyebrow hijau 5,2:1
 *          angka data-blue 7,8:1 · tombol utama isian↔tanah 5,2:1,
 *          label↔isian 5,2:1 (hover 6,6:1) · tombol garis 12,7:1
 *   hijau  teks utama 9,0:1 · teks sekunder 5,8:1 (di ubin 4,7:1)
 *          angka data-blue di ubin 4,7:1
 *   tint   teks utama 12,4:1 · teks sekunder 4,7:1
 */
.tanah {
    background: var(--paper);
    color: var(--ink);
}

.tanah--gelap {
    --paper: #14222A;   /* --ink didalemin */
    --ink: #F1F4F1;     /* teks jadi kertas */
    --muted: #ADBEC6;
    --ruling: #2E434D;
    --kartu: #1C2E38;   /* kartu = tinta yang setingkat lebih terang dari tanah */
    /* Aksen dinaikin terangnya. Hijau stempel #0F6B54 di tanah ini cuma
       2,5:1 — kebaca sebagai lubang, bukan tombol. */
    --stamp-green: #2FA483;
    --stamp-red: #E2796E;
    --pending-ink: #E3B25C;
    --data-blue: #86B8EA;
    /* Putih di atas hijau seterang itu jatuh ke 3,1:1, jadi label tombol
       utama dibalik jadi warna tanahnya. */
    --utama-teks: #14222A;
    --utama-tekan: #45B899;
}

.tanah--stempel {
    --paper: #0C4B3C;   /* --stamp-green didalemin */
    --ink: #ECF4F0;
    --muted: #A7CCC0;
    --ruling: #1C6151;
    --kartu: #105948;
    --stamp-green: #4CBE9A;
    --stamp-red: #E88E82;
    --pending-ink: #EBBE6E;
    --data-blue: #9CC8EC;
    --utama-teks: #0C4B3C;
    --utama-tekan: #63CBAA;
}

/* Tint bukan momen gelap — cuma kertas yang sedikit lebih dalam, jadi yang
   diganti CUMA tanahnya. Tinta, garis, dan kartu putihnya tetap sama, dan
   kartu putih di atasnya malah naik selangkah. */
.tanah--tint {
    --paper: #ECEEE7;
}

/* ----------------------------------------------------------------- base */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    /* Anchor nav scrolls smooth; motion switch below turns it off. */
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

body.landing {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--body);
    font-size: 1rem;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

img,
svg {
    max-width: 100%;
}

a {
    color: inherit;
}

:focus-visible {
    outline: 2px solid var(--data-blue);
    outline-offset: 2px;
}

/* Angka rupiah & metrik SELALU mono tabular — ini buku kas. */
.mono {
    font-family: var(--mono);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 20;
    padding: 0.5rem 1rem;
    background: var(--ink);
    color: var(--paper);
}

.skip-link:focus {
    left: 0;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.wadah {
    max-width: 1040px;
    margin: 0 auto;
    padding: 0 1.25rem;
}

/* Sticky nav needs anchor offsets. */
section[id] {
    scroll-margin-top: 4.5rem;
}

/* --------------------------------------------------------------- tombol */

/*
 * SATU set tombol buat seluruh landing: `.tombol` (geometri) + modifier warna
 * (`--utama` terisi / `--garis` bergaris / `--tolak` destruktif) + modifier
 * ukuran (`--kecil` buat bar nav). Geometri — tinggi, padding, radius —
 * hidup HANYA di sini.
 *
 * Kenapa: sebelum ini nav punya override sendiri (`.nav .tombol`), jadi satu
 * kelas `.tombol` punya dua tinggi (36px di nav vs 44px di badan halaman) dan
 * dua ukuran teks, dan tombol di kartu paket ke-stretch full-width dengan
 * label nempel ke kiri sementara tombol lain label-nya di tengah. Tinggi
 * dijaga `min-height` (bukan padding vertikal) supaya font-size beda nggak
 * pernah bikin tinggi beda.
 *
 * Nama tetap `.tombol`, BUKAN `.tbl`: dashboard.css dan kedua CSS storefront
 * udah pakai konvensi `.tombol`/`.tombol--utama` yang sama, jadi ganti nama
 * cuma di landing malah mecah konvensinya, bukan nyatuin.
 */
.tombol {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 1.2rem;
    border: 1.5px solid var(--ink);
    border-radius: 8px;
    background: var(--kartu);
    color: var(--ink);
    font-family: var(--body);
    font-weight: 500;
    font-size: 0.925rem;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.tombol:hover {
    background: var(--paper);
}

.tombol:active {
    transform: translateY(1px);
}

.tombol--utama {
    background: var(--stamp-green);
    border-color: var(--stamp-green);
    color: var(--utama-teks);
}

.tombol--utama:hover {
    background: var(--utama-tekan);
    border-color: var(--utama-tekan);
}

/* Varian bergaris — sama dengan gaya dasar, tapi ditulis eksplisit di markup
   biar tiap tombol nyatain perannya sendiri (terisi vs bergaris) dan nggak
   ada yang jadi tombol utama gara-gara lupa nulis modifier. */
.tombol--garis {
    background: var(--kartu);
    border-color: var(--ink);
    color: var(--ink);
}

.tombol--tolak {
    background: transparent;
    border-color: var(--stamp-red);
    color: var(--stamp-red);
}

.tombol--tolak:hover {
    background: #FBF1F0;
}

/* Ukuran bar nav: satu-satunya tinggi alternatif. Radius tetap 8px biar
   sudutnya serumpun sama tombol di badan halaman. */
.tombol--kecil {
    min-height: 2.25rem;
    padding: 0 1rem;
    font-size: 0.875rem;
}

/* ------------------------------------------------------------------ nav */

.nav {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--paper);
    border-bottom: 1px solid var(--ruling);
}

/* Tiga blok di satu baris: wordmark — [auto] — kelompok navigasi — hairline —
   kelompok akun. `flex-wrap` cuma jaring pengaman buat text-zoom ekstrem;
   di lebar normal nav SELALU satu baris (lihat media query di bawah). */
.nav__baris {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.5rem;
    padding: 0.75rem 1.25rem;
    max-width: 1040px;
    margin: 0 auto;
}

.nav__merek {
    font-family: var(--display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: 0.01em;
    text-decoration: none;
    margin-right: auto;
}

/* Wordmark: "seller.id" is one word, so the .id only steps back a weight and
   a shade — never far enough to read as a separate token. Same rule serves
   the nav and the footer. */
.merek__id {
    font-weight: 500;
    color: var(--muted);
}

/* KELOMPOK 1 — navigasi halaman (Fitur · Cara Kerja · Paket · Lihat Demo).
   Disembunyiin di layar sempit; alasan lengkapnya ditulis di komentar nav
   landing.blade.php (ringkasnya: bar ini sticky, tautan yang sama udah ada
   di footer, dan tanpa JS nggak ada drawer). */
.nav__tautan {
    display: none;
    align-items: center;
    gap: 0 1.25rem;
}

/* KELOMPOK 2 — akun. "Masuk" + "Daftar Gratis" itu pasangan setara, jadi
   mereka duduk berdampingan dengan jarak pasangan yang rapat, dan nggak ada
   tombol lain yang boleh nyempil di antaranya. */
.nav__akun {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* Semua kontrol di nav — tautan navigasi, "Masuk", dan tombol "Daftar
   Gratis" — dipatok satu tinggi (2.25rem, sama kayak `.tombol--kecil`) dan
   satu radius, jadi cincin fokus keyboard-nya sebentuk dan area kliknya
   sebaris. */
.nav__tautan a,
.nav__masuk {
    display: inline-flex;
    align-items: center;
    min-height: 2.25rem;
    padding: 0 0.25rem;
    border-radius: 8px;
    font-weight: 500;
    font-size: 0.925rem;
    line-height: 1.2;
    text-decoration: none;
}

/* Serumpun tapi beda peran: ukuran & jenis huruf identik, yang beda cuma
   warna tintanya — navigasi resesif (muted), "Masuk" setinta badan teks
   (ink) karena dia aksi akun. Sengaja BUKAN dibedain lewat berat huruf:
   Public Sans di sini cuma di-bundle 400 & 500, jadi 600 bakal disintesis
   browser dan kelihatan kotor. */
.nav__tautan a {
    color: var(--muted);
}

.nav__tautan a:hover {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* "Masuk" = tautan teks, sengaja BUKAN tombol: cuma satu aksi di nav
   (Daftar Gratis) yang boleh bergaya tombol terisi. Dia nggak kelihatan
   nyempil karena berpasangan di dalam .nav__akun, bukan diapit tombol. */
.nav__masuk {
    color: var(--ink);
}

.nav__masuk:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

@media (min-width: 720px) {
    .nav__tautan {
        display: flex;
    }

    /* Garis pemisah tipis --ruling: batas antara kelompok navigasi dan
       kelompok akun. Tinggi garisnya = tinggi kontrol, jadi kebaca sebagai
       pembatas, bukan hiasan. */
    .nav__akun {
        padding-left: 1.5rem;
        border-left: 1px solid var(--ruling);
    }
}

/* ----------------------------------------------------------------- hero */

.hero {
    padding: 3rem 0 3.5rem;
}

.hero__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2.5rem;
    align-items: center;
}

@media (min-width: 880px) {
    .hero__grid {
        grid-template-columns: 11fr 9fr;
        gap: 3rem;
    }

    .hero {
        padding: 4.5rem 0 5rem;
    }
}

.hero__eyebrow {
    margin: 0 0 0.75rem;
    font-family: var(--mono);
    font-weight: 500;
    font-size: 0.78rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--stamp-green);
}

.hero__judul {
    margin: 0 0 1rem;
    font-family: var(--display);
    font-weight: 700;
    font-size: clamp(2rem, 5.5vw, 3.1rem);
    line-height: 1.12;
    letter-spacing: -0.02em;
}

.hero__sub {
    margin: 0 0 1.5rem;
    font-size: 1.05rem;
    max-width: 34rem;
}

.hero__aksi {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* Catatan jujur di bawah CTA: gratisnya cuma soal bikin akun, paket
   berbayar belum ada. Antrian hidup di sini sebagai CTA tersier. */
.hero__catatan {
    margin: 0.85rem 0 0;
    max-width: 34rem;
    font-size: 0.875rem;
    color: var(--muted);
}

.hero__catatan .tautan {
    color: var(--data-blue);
    text-underline-offset: 2px;
}

/* Kata berputar: jendela 1 baris, daftar kata digulung ke atas per 2,5s.
   Kata terakhir = duplikat kata pertama biar loop-nya mulus. Tanpa animasi
   (reduced-motion / fallback) yang tampil kata pertama, statis. */
.putar-kata {
    display: inline-block;
    overflow: hidden;
    height: 1.15em;
    vertical-align: bottom;
    color: var(--stamp-green);
}

.putar-kata__gulung {
    display: block;
}

.putar-kata__gulung > span {
    display: block;
    height: 1.15em;
    line-height: 1.15;
}

/* ------------------------------------ hero mock (SIGNATURE, satu-satunya) */

/*
 * Static mock: kartu approval di depan, kartu kedua miring di belakang yang
 * sudah distempel DISETUJUI. Pure CSS, no JS.
 *
 * Komposisi: kartu belakang nempel kanan-atas dengan judul kiri-atas dan
 * stempel di kanan-BAWAH — stempel mendarat di badan dokumen, bukan di
 * judulnya. Kartu depan mulai 9.5rem dari atas, jadi cuma numpuk strip
 * bawah kartu belakang (±0.5-1rem) — stempel dan judul dua-duanya kebaca.
 */
.mock {
    position: relative;
}

.mock-kartu {
    background: var(--kartu);
    border: 1px solid var(--ruling);
    border-radius: 10px;
    padding: 1.25rem;
}

.mock-kartu--depan {
    position: relative;
    z-index: 2;
    max-width: 24rem;
    margin-top: 9.5rem;
}

.mock-kartu--belakang {
    position: absolute;
    z-index: 1;
    top: 0;
    right: 0;
    width: 17rem;
    max-width: 80%;
    min-height: 10rem;
    transform: rotate(-2deg);
    color: var(--muted);
    font-size: 0.8rem;
}

.mock-kartu__chip {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border: 1.5px solid var(--pending-ink);
    border-radius: 6px;
    color: var(--pending-ink);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 0.6rem;
}

.mock-kartu__judul {
    margin: 0 0 0.4rem;
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.05rem;
}

.mock-kartu--belakang .mock-kartu__judul {
    font-size: 0.875rem;
}

.mock-kartu__narasi {
    margin: 0 0 0.75rem;
    font-size: 0.875rem;
    color: var(--muted);
}

.mock-bukti {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0 0 0.9rem;
    padding: 0;
    list-style: none;
}

.mock-bukti li {
    padding: 0.15rem 0.55rem;
    border: 1px solid var(--ruling);
    border-radius: 6px;
    font-size: 0.75rem;
    color: var(--muted);
}

.mock-aksi {
    display: flex;
    gap: 0.6rem;
}

/* Tombol di mock cuma GAMBAR — bukan kontrol beneran (pointer-events: none),
   jadi dia satu-satunya yang dikecualiin dari kontrak tinggi `.tombol`:
   skalanya harus ngikut kartu mock yang kecil, bukan kontrol halaman. */
.mock-aksi .tombol {
    pointer-events: none;
    opacity: 0.85;
    min-height: 2rem;
    padding: 0 1rem;
    font-size: 0.85rem;
}

/*
 * Stempel bertinta miring ~-8°: border ganda, teks uppercase display,
 * tekstur tinta tidak rata via mask noise — pola dari dashboard.css §1.
 */
.stempel {
    position: absolute;
    bottom: 1.4rem;
    right: 1.2rem;
    transform: rotate(-8deg);
    padding: 0.3rem 0.7rem;
    border: 2.5px solid currentColor;
    border-radius: 6px;
    box-shadow: inset 0 0 0 1px currentColor;
    font-family: var(--display);
    font-weight: 700;
    font-size: 0.82rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.9;
    -webkit-mask-image:
        radial-gradient(circle at 18% 32%, transparent 0 1.5%, #000 4%),
        radial-gradient(circle at 66% 71%, transparent 0 1.2%, #000 3.5%),
        radial-gradient(circle at 84% 22%, transparent 0 1%, #000 3%);
    -webkit-mask-composite: source-in;
    mask-image:
        radial-gradient(circle at 18% 32%, transparent 0 1.5%, #000 4%),
        radial-gradient(circle at 66% 71%, transparent 0 1.2%, #000 3.5%),
        radial-gradient(circle at 84% 22%, transparent 0 1%, #000 3%);
    mask-composite: intersect;
}

.stempel--setuju {
    color: var(--stamp-green);
}

/* -------------------------------------------------------------- divider */

/*
 * "Sobekan buku kas": garis perforasi putus-putus selebar halaman antara
 * seksi — satu idiom pembatas untuk seluruh landing, tanpa ornamen lain.
 */
.sobek {
    width: 100%;
    height: 1.5px;
    margin: 0;
    border: 0;
    background: repeating-linear-gradient(
        90deg,
        var(--ruling) 0 8px,
        transparent 8px 14px
    );
}

/* ---------------------------------------------------------------- seksi */

.seksi {
    padding: 3.5rem 0;
}

.seksi__judul {
    margin: 0 0 0.5rem;
    font-family: var(--display);
    font-weight: 700;
    font-size: clamp(1.5rem, 3.5vw, 2rem);
    letter-spacing: -0.01em;
}

.seksi__sub {
    margin: 0 0 2rem;
    color: var(--muted);
    max-width: 36rem;
}

/* ----------------------------------------------- galeri (scroll-snap) */

/*
 * Carousel murni CSS: overflow-x + scroll-snap, tanpa JS.
 *
 * TINGGI SERAGAM & CAPTION SEJAJAR: track-nya grid dua baris — baris 1 (1fr)
 * buat bingkai, baris 2 (auto) buat caption — dan tiap <figure> ikut baris itu
 * lewat `grid-template-rows: subgrid`. Jadi semua bingkai setinggi bingkai
 * tertinggi DAN semua figcaption mulai di garis yang sama, nggak peduli
 * caption tetangganya kepake berapa baris. (Kalau subgrid nggak didukung,
 * figure-nya jatuh ke grid biasa: kartunya tetap kebaca, cuma caption-nya
 * balik ragged.) Sisa ruang di bingkai yang isinya lebih pendek diserap isi
 * kartunya sendiri — potret melebar/ke-crop dari bawah, chat Telegram turun ke
 * bawah — bukan ruang kosong yang diregangin.
 *
 * LEBAR KARTU dihitung dari lebar track: n kartu utuh + satu "peek" sempit
 * (--peek) sebagai isyarat masih ada lanjutannya. Tepi kanan dikasih mask
 * gradasi selebar peek, jadi kartu yang keiris cuma memudar — nggak pernah
 * motong kalimat. `--ujung` (padding-inline-end) lebih lebar dari fade-nya
 * biar kartu terakhir + caption-nya bisa di-scroll utuh sampai ujung.
 */
.galeri {
    --sela: 1rem;
    --tepi: 1.25rem;
    --ujung: 2.5rem;
    --peek: 1rem;
    /* Fade-nya mulai tepat di tepi kanan kartu terakhir yang utuh (--peek +
       --sela dari tepi track), jadi kartu utuh nggak pernah kesenggol, dan
       sliver peek-nya udah tinggal ±18% — kelihatan sebagai tepi bingkai yang
       pudar, isyarat "masih ada lanjutannya", tanpa sepotong huruf pun kebaca. */
    --fade: calc(var(--peek) + var(--sela));
    /* 1 kartu + peek: (100% + --ujung) - --peek - 1 × --sela */
    --lebar-kartu: calc(100% + 0.5rem);

    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: var(--lebar-kartu);
    grid-template-rows: 1fr auto;
    gap: 0 var(--sela);
    align-items: stretch;
    max-width: 1040px;
    margin: 0 auto;
    padding: 0.25rem var(--ujung) 1rem var(--tepi);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--tepi);
    scrollbar-width: thin;
    scrollbar-color: var(--ruling) transparent;
    -webkit-mask-image: linear-gradient(
        to right,
        transparent 0,
        #000 var(--tepi),
        #000 calc(100% - var(--fade)),
        rgba(0, 0, 0, 0.18) calc(100% - var(--peek)),
        transparent 100%
    );
    mask-image: linear-gradient(
        to right,
        transparent 0,
        #000 var(--tepi),
        #000 calc(100% - var(--fade)),
        rgba(0, 0, 0, 0.18) calc(100% - var(--peek)),
        transparent 100%
    );
}

/* 2 kartu + peek: (100% + --ujung) - --peek - 2 × --sela, dibagi 2. */
@media (min-width: 560px) {
    .galeri {
        --lebar-kartu: calc((100% - 0.5rem) / 2);
    }
}

/* 3 kartu + peek: (100% + --ujung) - --peek - 3 × --sela, dibagi 3. */
@media (min-width: 900px) {
    .galeri {
        --lebar-kartu: calc((100% - 1.5rem) / 3);
    }
}

.galeri__item {
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
    margin: 0;
    scroll-snap-align: start;
    scroll-margin-left: var(--tepi);
}

.galeri__item figcaption {
    margin-top: 0.5rem;
    font-size: 0.8rem;
    color: var(--muted);
}

/* Bingkai ngisi baris 1 penuh, isinya kolom flex biar isinya bisa nyerap
   sisa ruang (lihat .bingkai__potret di carousel dan .mock-tele). */
.galeri__item .bingkai {
    display: flex;
    flex-direction: column;
}

.galeri__item .bingkai__isi {
    display: flex;
    flex-direction: column;
    flex: 1;
}

/* --------------------------------------------- bingkai browser (mock) */

.bingkai {
    background: var(--kartu);
    border: 1px solid var(--ruling);
    border-radius: 10px;
    overflow: hidden;
}

.bingkai__bar {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.45rem 0.6rem;
    border-bottom: 1px solid var(--ruling);
    background: var(--paper);
}

.bingkai__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--ruling);
}

.bingkai__url {
    flex: 1;
    min-width: 0;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border: 1px solid var(--ruling);
    border-radius: 99px;
    background: var(--kartu);
    font-family: var(--mono);
    font-size: 0.62rem;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Bantalan buat isi yang digambar CSS (mock Telegram). Tangkapan layar
   nggak pakai ini — gambarnya nempel ke tepi bingkai kayak viewport asli. */
.bingkai__isi {
    padding: 0.75rem;
}

/*
 * Tangkapan layar di dalam bingkai: nempel penuh ke tepi dalam bingkai, dan
 * `width`/`height` intrinsiknya ditulis di markup supaya browser udah tahu
 * rasionya sebelum gambarnya kedownload (nggak ada layout shift).
 */
.bingkai__potret {
    display: block;
    width: 100%;
    height: auto;
}

/*
 * Di carousel semua kartu setinggi kartu tertinggi (subgrid). Potret dikasih
 * `flex: 1` + `object-fit: cover` biar dia yang NGISI sisa tinggi itu — kalau
 * nggak, kartu yang gambarnya lebih pendek nyisain pita kosong di bawah
 * gambar, dan pita kosong di dalam bingkai browser kebaca kayak halaman gagal
 * dimuat. Yang kepotong selalu bagian bawah layar, persis kayak viewport
 * browser yang kependekan.
 */
.galeri__item .bingkai__potret {
    flex: 1;
    min-height: 0;
    object-fit: cover;
    object-position: top center;
}

/*
 * Potret di tanah gelap. Ini kesalahan paling gampang kejadian: layar aplikasi
 * kita latarnya putih, jadi kalau ditaruh mentah di ground gelap dia kebaca
 * sebagai kotak putih melayang, bukan jendela.
 *
 * Obatnya bukan ngeredupin gambarnya (itu bohong soal produknya) tapi bikin
 * bingkainya kebaca sebagai JENDELA di atas meja gelap: krom bingkainya udah
 * ikut gelap sendiri lewat token (--kartu buat badan, --paper buat bilah
 * alamat, --ruling buat garisnya), tinggal ditambah bayangan jatuh + hairline
 * terang tipis di tepinya biar ada pemisah antara putih layar dan tanah.
 */
.tanah--gelap .bingkai {
    box-shadow:
        0 0 0 1px rgb(241 244 241 / 8%),
        0 18px 40px rgb(0 0 0 / 45%);
}

/* ------------------------------------------------------- bingkai HP */

/*
 * Bingkai ponsel buat potret lebar 390: bingkai browser (bilah alamat + tiga
 * titik) kebaca salah di layar setinggi ini. Rasio dijaga sama gambar
 * 560x1212-nya sendiri; bingkainya cuma badan + garis speaker.
 */
.bingkai-hp {
    position: relative;
    padding: 0.5rem 0.35rem 0.35rem;
    border: 1px solid var(--ruling);
    border-radius: 14px;
    background: var(--kartu);
    box-shadow: 0 6px 18px rgb(28 43 51 / 12%);
}

.bingkai-hp__speaker {
    position: absolute;
    top: 0.22rem;
    left: 50%;
    translate: -50% 0;
    width: 22%;
    height: 3px;
    border-radius: 99px;
    background: var(--ruling);
}

.bingkai-hp__potret {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 9px;
}

/* --------------------------------------------------- mock chat Telegram */

/*
 * Kolom flex: pesan yang masih nunggu keputusan didorong ke bawah
 * (margin-top: auto) kayak chat beneran — pesan baru paling bawah — dan sisa
 * tinggi kartu jadi jarak antar pesan, bukan ruang kosong di ujung.
 */
.mock-tele {
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: 0.4rem;
}

.mock-tele__pesan {
    margin-top: auto;
}

.mock-tele__gelembung {
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--ruling);
    border-radius: 10px 10px 10px 2px;
    background: var(--paper);
}

.mock-tele__gelembung p {
    margin: 0;
    font-size: 0.72rem;
    color: var(--ink);
}

.mock-tele__gelembung p + p {
    margin-top: 0.35rem;
}

/* Pesan lama yang udah diputusin: bot nge-edit pesannya dan nambah baris
   hasil di bawah — makanya warnanya stempel, bukan tinta biasa. */
.mock-tele__gelembung--lama {
    opacity: 0.85;
}

.mock-tele__gelembung .mock-tele__hasil {
    color: var(--stamp-green);
    font-weight: 500;
}

/* Jam pesan, kanan-bawah gelembung — kebiasaan Telegram. */
.mock-tele__gelembung .mock-tele__waktu {
    margin-top: 0.25rem;
    font-size: 0.6rem;
    text-align: right;
    color: var(--muted);
}

.mock-tele__bukti {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    margin: 0.35rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.68rem;
    color: var(--muted);
}

/* Telegram naruh tiap tombol inline di barisnya sendiri (dua baris keyboard
   di AiActionNotification::toTelegram) — mock-nya ikut, bukan sebaris. */
.mock-tele__aksi {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-top: 0.4rem;
}

.mock-tele__tombol {
    padding: 0.25rem 0;
    border: 1.5px solid var(--stamp-green);
    border-radius: 6px;
    color: var(--stamp-green);
    font-size: 0.65rem;
    font-weight: 500;
    text-align: center;
}

.mock-tele__tombol--tolak {
    border-color: var(--stamp-red);
    color: var(--stamp-red);
}

/* --------------------------------------------------- deep-dive (selam) */

.selam {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem 3.5rem;
    align-items: center;
    padding: 2rem 0;
}

@media (min-width: 880px) {
    .selam {
        grid-template-columns: 1fr 1fr;
    }

    .selam--balik .selam__teks {
        order: 2;
    }

    .selam--balik .selam__visual {
        order: 1;
    }
}

.selam__eyebrow {
    margin: 0 0 0.5rem;
    font-family: var(--mono);
    font-weight: 500;
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--stamp-green);
}

.selam__judul {
    margin: 0 0 0.75rem;
    font-family: var(--display);
    font-weight: 700;
    font-size: clamp(1.4rem, 3vw, 1.9rem);
    letter-spacing: -0.01em;
}

.selam__teks p {
    margin: 0 0 0.9rem;
}

/* Potret desktop boleh selebar kolomnya — di lebar 24rem yang lama teks di
   dalam layar produknya udah nggak kebaca sama sekali. */
.selam__visual .bingkai {
    max-width: 30rem;
    margin: 0 auto;
}

/* Kecuali mock CSS (chat Telegram): itu gambar layar HP, diregangin selebar
   potret desktop malah kebaca salah. */
.selam__visual--mock .bingkai {
    max-width: 24rem;
}

/*
 * Duet desktop + HP di deep-dive "Toko instan": bingkai HP nangkring di pojok
 * kanan-bawah, sebagian nimpa bingkai desktop. Ruangnya dibikin lewat padding
 * kanan/bawah wadahnya — jadi HP-nya nggak pernah keluar dari kolom, dan yang
 * ketutup cuma pojok kanan-bawah potret (kartu produk terakhir), bukan hero
 * atau harganya.
 */
.selam__visual--duet {
    position: relative;
    padding: 0 2.5rem 1.5rem 0;
}

.selam__visual--duet .bingkai {
    max-width: none;
    margin: 0;
}

.selam__visual--duet .bingkai-hp {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 24%;
    max-width: 7.5rem;
}

.selam-cta {
    padding-top: 1.5rem;
    text-align: center;
}

/* ------------------------------------------------------ grid kemampuan */

.kemampuan-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

@media (min-width: 720px) {
    .kemampuan-grid {
        grid-template-columns: 1fr 1fr 1fr;
    }
}

.kemampuan-kartu {
    background: var(--kartu);
    border: 1px solid var(--ruling);
    border-radius: 10px;
    padding: 1.1rem;
}

.kemampuan-kartu h3 {
    margin: 0 0 0.35rem;
    font-family: var(--display);
    font-weight: 600;
    font-size: 1rem;
}

.kemampuan-kartu p {
    margin: 0;
    font-size: 0.875rem;
    color: var(--muted);
}

/* -------------------------------------------- trust (fakta engineering) */

.trust-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

@media (min-width: 880px) {
    .trust-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

.trust-ubin {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    background: var(--kartu);
    border: 1px solid var(--ruling);
    border-radius: 10px;
    padding: 1.1rem;
}

.trust-ubin__angka {
    font-size: 1.5rem;
    color: var(--data-blue);
}

.trust-ubin__ket {
    font-size: 0.85rem;
    color: var(--muted);
}

.trust-catatan {
    margin: 1.25rem 0 0;
    font-size: 0.875rem;
    color: var(--muted);
}

/* ----------------------------------------------------------- cara kerja */

.langkah-daftar {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: langkah;
}

@media (min-width: 720px) {
    .langkah-daftar {
        grid-template-columns: 1fr 1fr 1fr;
    }
}

.langkah {
    counter-increment: langkah;
    border-top: 2px solid var(--ink);
    padding-top: 0.9rem;
}

.langkah::before {
    content: counter(langkah);
    display: block;
    font-family: var(--mono);
    font-weight: 500;
    font-size: 1.5rem;
    color: var(--data-blue);
    font-variant-numeric: tabular-nums;
    margin-bottom: 0.25rem;
}

.langkah h3 {
    margin: 0 0 0.35rem;
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.1rem;
}

.langkah p {
    margin: 0;
    font-size: 0.925rem;
    color: var(--muted);
}

/* ---------------------------------------------------------------- paket */

.paket-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    align-items: stretch;
}

@media (min-width: 800px) {
    .paket-grid {
        grid-template-columns: 1fr 1fr 1fr;
    }
}

.paket-kartu {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--kartu);
    border: 1px solid var(--ruling);
    border-radius: 10px;
    padding: 1.5rem 1.25rem 1.25rem;
}

/* Motion halus: hover lift kartu paket (transform, biar composable sama
   reveal yang animasi `translate`). */
@media (prefers-reduced-motion: no-preference) {
    .paket-kartu {
        transition: transform 150ms ease-out;
    }

    .paket-kartu:hover {
        transform: translateY(-3px);
    }
}

.paket-kartu--utama {
    border: 1.5px solid var(--stamp-green);
    box-shadow: inset 0 0 0 1px var(--stamp-green);
}

/* Chip stempel-mini "PALING PAS" nangkring di border atas kartu tengah. */
.paket-kartu__badge {
    position: absolute;
    top: -0.75rem;
    left: 1rem;
    padding: 0.15rem 0.55rem;
    border: 1.5px solid var(--stamp-green);
    border-radius: 6px;
    background: var(--kartu);
    color: var(--stamp-green);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transform: rotate(-2deg);
}

.paket-kartu h3 {
    margin: 0 0 0.15rem;
    font-family: var(--display);
    font-weight: 700;
    font-size: 1.25rem;
}

.paket-kartu__untuk {
    margin: 0 0 0.9rem;
    font-size: 0.875rem;
    color: var(--muted);
}

/* Area harga: chip pending-ink, mono — TANPA angka harga karangan. */
.paket-kartu__harga {
    align-self: flex-start;
    padding: 0.2rem 0.6rem;
    border: 1.5px solid var(--pending-ink);
    border-radius: 6px;
    color: var(--pending-ink);
    font-family: var(--mono);
    font-weight: 500;
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 1rem;
}

.paket-kartu ul {
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
    font-size: 0.9rem;
    flex-grow: 1;
}

.paket-kartu li {
    padding: 0.4rem 0;
    border-top: 1px solid var(--ruling);
}

.paket-kartu li:last-child {
    border-bottom: 1px solid var(--ruling);
}

/* Tombol kartu paket sengaja selebar kartu (dia flex item di kartu kolom,
   jadi ke-stretch) — dan labelnya sekarang di tengah karena `.tombol` udah
   inline-flex + justify-content: center. Sebelum ini labelnya nempel ke kiri
   sementara semua tombol lain di halaman labelnya di tengah. TANPA aturan
   tinggi/padding sendiri di sini: ukurannya ikut `.tombol`. */

.paket-catatan {
    margin: 1.5rem 0 0;
    font-size: 0.875rem;
    color: var(--muted);
}

/* ----------------------------------------------------- band CTA penutup */

/* Dulu band ini dibatasi dua garis --ruling karena tanahnya sama persis
   dengan seksi di atas-bawahnya. Sekarang dia berdiri di tanah gelap bareng
   footer, jadi PERGANTIAN TANAH-nya sendiri yang jadi batas — garisnya cuma
   bakal jadi coretan gelap di atas gelap. */
.band {
    padding: 3.5rem 0 2.5rem;
}

.band__isi {
    text-align: center;
}

.band__judul {
    margin: 0 0 1.25rem;
    font-family: var(--display);
    font-weight: 700;
    font-size: clamp(1.6rem, 4vw, 2.3rem);
    letter-spacing: -0.01em;
}

.band__isi .hero__aksi {
    justify-content: center;
}

/* --------------------------------------------------------------- footer */

/* Footer nempel di tanah band CTA — satu blok gelap penutup. Garis pemisah
   halus di antara keduanya cukup buat misahin ajakan dari daftar tautan
   tanpa mecah bloknya jadi dua. */
.footer {
    padding: 2.5rem 0 3rem;
}

.footer.tanah--gelap {
    border-top: 1px solid var(--ruling);
}

.footer__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
}

@media (min-width: 720px) {
    .footer__grid {
        grid-template-columns: 2fr 1fr 1fr 1fr;
        gap: 2rem;
    }
}

.footer__merek {
    font-family: var(--display);
    font-weight: 700;
    font-size: 1.05rem;
}

.footer__satu-baris {
    margin: 0.5rem 0 0;
    font-size: 0.875rem;
    color: var(--muted);
    max-width: 18rem;
}

.footer__kolom-judul {
    margin: 0 0 0.5rem;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
}

.footer__tautan {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.875rem;
}

.footer__tautan a {
    color: var(--ink);
    text-decoration: none;
}

.footer__tautan a:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.footer__legal {
    margin: 2rem 0 0;
    font-size: 0.8rem;
    color: var(--muted);
}

/* -------------------------------------------------------------- animasi */

/*
 * Semua motion di blok no-preference: reduced-motion = halaman diam total
 * (kata berputar jadi statis di kata pertama). Reveal pakai properti
 * `translate` (bukan `transform`) supaya nggak bentrok sama rotate/
 * hover-lift yang hidup di `transform`.
 */
@media (prefers-reduced-motion: no-preference) {
    /* Kata berputar di H1: 5 kata × 2,5s = siklus 12,5s; frame terakhir
       geser ke duplikat kata pertama biar nyambung mulus. */
    @keyframes putar-kata {
        0%, 17% {
            translate: 0 0;
        }

        20%, 37% {
            translate: 0 -1.15em;
        }

        40%, 57% {
            translate: 0 -2.3em;
        }

        60%, 77% {
            translate: 0 -3.45em;
        }

        80%, 97% {
            translate: 0 -4.6em;
        }

        100% {
            translate: 0 -5.75em;
        }
    }

    .putar-kata__gulung {
        animation: putar-kata 12.5s ease-in-out infinite;
    }

    /* Hero load: kartu depan naik, kartu belakang nyusul, stempel nge-cap. */
    @keyframes kartu-naik {
        from {
            opacity: 0;
            translate: 0 14px;
        }

        to {
            opacity: 1;
            translate: 0 0;
        }
    }

    .mock-kartu--depan {
        animation: kartu-naik 400ms ease-out both;
    }

    .mock-kartu--belakang {
        animation: kartu-naik 400ms ease-out 150ms both;
    }

    /* "Cap" dari dashboard.css: scale 1.15 → 1, 150ms ease-out. */
    @keyframes cap {
        from {
            transform: rotate(-8deg) scale(1.15);
            opacity: 0;
        }

        to {
            transform: rotate(-8deg) scale(1);
            opacity: 0.9;
        }
    }

    .mock-kartu--belakang .stempel {
        animation: cap 150ms ease-out 700ms both;
    }

    /*
     * Scroll reveal kartu-kartu — progressive enhancement murni CSS
     * (tanpa JS/IntersectionObserver): browser tanpa scroll-driven
     * animations langsung nampilin kartunya tanpa animasi.
     */
    @supports (animation-timeline: view()) {
        @keyframes kartu-muncul {
            from {
                opacity: 0;
                translate: 0 12px;
            }

            to {
                opacity: 1;
                translate: 0 0;
            }
        }

        .galeri__item,
        .kemampuan-kartu,
        .trust-ubin,
        .paket-kartu {
            animation: kartu-muncul linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 25%;
        }
    }
}

/* -------------------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
    .tombol:active {
        transform: none;
    }
}

/* Lihat catatan yang sama di dashboard.css: ukuran asli di HTML mencegah
   halaman melompat, tinggi tampil diatur di sini. */
.nav__merek img {
    display: block;
    width: auto;
    height: 1.65rem;
}
