/* ==========================================================================
   Fansys — sistem desain Material (tema gelap + emas)
   --------------------------------------------------------------------------
   Nada visualnya hitam pekat dengan aksen emas mengikuti identitas logo:
   permukaan gelap bertingkat, garis tipis, dan kedalaman yang dibentuk oleh
   bayangan berlapis (elevation) alih-alih garis tebal. Aksen warna hanya
   muncul pada elemen yang bisa ditindaklanjuti.

   Tiga hal yang perlu diketahui sebelum mengubah berkas ini:

   1. Seluruh warna merek berasal dari variabel `--brand`, `--brand-dark`, dan
      `--accent` yang ditimpa saat proses berjalan oleh applyBranding() di
      app.js. Karena itu jangan pernah menulis nilai heksadesimal merek secara
      langsung — pakai variabelnya, atau perubahan warna dari Panel Branding
      tidak akan ikut terpakai.

   2. Nama kelas lama (.card, .stat, .badge, .btn, .alert, .shell, .sidebar,
      dan seterusnya) sengaja dipertahankan. 28 halaman HTML memakainya, dan
      mengganti nama kelas berarti menyunting semuanya tanpa manfaat nyata.
      Yang berubah adalah tampilannya, bukan kontraknya.

   3. Animasi apa pun di berkas ini harus mati saat pengguna meminta
      `prefers-reduced-motion`. Aturan itu ada satu blok di bagian paling
      bawah; tambahkan animasi baru ke dalamnya.

   4. Etalase publik (halaman dengan <body class="shop-body"> atau
      class="auth-page"> — beranda, katalog, produk, keranjang, toko mitra,
      halaman informasi, masuk/daftar) memakai lapisan gaya "boutique"
      tersendiri di bagian ETALASE, di bawah selektor `.shop-body`/`.auth-page`.
      Panel admin & dashboard mitra TIDAK disentuh lapisan ini — keduanya
      tetap memakai bentuk pil/shadow Material di atas. Jangan pindahkan gaya
      boutique ke selektor global (mis. `button, .btn` polos) atau dashboard
      ikut berubah tanpa diminta.
   ========================================================================== */

@import url('/assets/vendor/roboto/roboto.css');
@import url('/assets/vendor/playfair-display/playfair-display.css');
@import url('/assets/vendor/fontawesome/css/fontawesome.min.css');
@import url('/assets/vendor/fontawesome/css/solid.min.css');
@import url('/assets/vendor/fontawesome/css/regular.min.css');
@import url('/assets/vendor/fontawesome/css/brands.min.css');

:root {
  /* -- warna merek (ditimpa applyBranding) -------------------------------- */
  --brand: #cda86a;
  --brand-dark: #b3894a;
  --brand-light: #2b2314;
  --brand-ink: #241a08; /* teks gelap di atas permukaan/tombol berwarna emas */
  --accent: #e8c07d;

  /* -- permukaan: hitam dengan tingkat keabuan bertahap -------------------- */
  --bg: #0a0a0a;
  --surface: #141414;
  --surface-1: #181818;
  --surface-2: #1e1e1e;
  --surface-3: #262626;
  --border: #2a2a2a;
  --border-strong: #3a3a3a;

  /* -- teks --------------------------------------------------------------- */
  --text: #f2ece0;
  --text-2: #c9bfa8;
  --muted: #8f8672;

  /* -- warna semantik ----------------------------------------------------- */
  --ok: #4ade80;
  --ok-bg: #12291b;
  --warn: #fbbf24;
  --warn-bg: #33230a;
  --danger: #f87171;
  --danger-bg: #331414;
  --info: #60a5fa;
  --info-bg: #101f33;

  /* -- bentuk (shape scale Material) -------------------------------------- */
  --r-xs: 6px;
  --r-sm: 10px;
  --r: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-full: 999px;
  --radius: var(--r); /* alias lama */

  /* -- elevation ---------------------------------------------------------- */
  --e1: 0 1px 2px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .32);
  --e2: 0 2px 4px rgba(0, 0, 0, .32), 0 4px 10px rgba(0, 0, 0, .34);
  --e3: 0 4px 8px rgba(0, 0, 0, .34), 0 10px 24px rgba(0, 0, 0, .38);
  --e4: 0 8px 16px rgba(0, 0, 0, .40), 0 20px 44px rgba(0, 0, 0, .44);
  --e5: 0 12px 28px rgba(0, 0, 0, .44), 0 32px 72px rgba(0, 0, 0, .50);
  --shadow: var(--e1); /* alias lama */

  /* -- motion (kurva easing standar Material) ----------------------------- */
  --ease: cubic-bezier(.2, 0, 0, 1);
  --ease-emph: cubic-bezier(.2, 0, 0, 1);
  --ease-out: cubic-bezier(0, 0, 0, 1);
  --t-fast: 120ms;
  --t: 220ms;
  --t-slow: 400ms;

  --topbar-h: 60px;
}

* { box-sizing: border-box; }
::selection { background: color-mix(in srgb, var(--brand) 35%, transparent); color: var(--text); }

html { scroll-behavior: smooth; }

/* ------------------------------------------------------------ scrollbar
   Tipis dan bernada emas, bukan bawaan browser yang tebal & putih —
   berlaku di seluruh halaman (Firefox lewat scrollbar-color, Chrome/Edge/
   Safari lewat ::-webkit-scrollbar). */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background-color: var(--border-strong);
  border-radius: var(--r-full);
  border: 2px solid var(--bg);
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--brand); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Roboto', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--brand); text-decoration: none; transition: color var(--t-fast) var(--ease); }
a:hover { color: var(--brand-dark); text-decoration: none; }

h1, h2, h3, h4 { margin: 0 0 .5rem; line-height: 1.22; font-weight: 500; letter-spacing: -.01em; }
h1 { font-size: 1.65rem; font-weight: 500; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75rem; color: var(--text-2); }
small { color: var(--muted); }
strong, b { font-weight: 500; color: var(--text); }

/* Font Awesome: sedikit turun agar sejajar dengan garis dasar teks. */
.fa-solid, .fa-regular, .fa-brands { vertical-align: -.05em; }

/* ------------------------------------------------------------------ fokus
   Cincin fokus dipisah dari :focus biasa supaya tidak muncul saat elemen
   diklik dengan tetikus — hanya saat navigasi papan ketik. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
:focus:not(:focus-visible) { outline: none; }

/* ==========================================================================
   Tata letak aplikasi (topbar + sidebar + main)
   ========================================================================== */
.topbar {
  background: var(--surface);
  color: var(--text);
  padding: 0 1.1rem;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: .9rem;
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid var(--border);
  box-shadow: var(--e1);
}
.topbar .brand {
  font-weight: 500; font-size: 1.08rem; letter-spacing: -.01em; color: var(--text);
  display: inline-flex; align-items: center; gap: .55rem;
}
.topbar .brand span { color: var(--text); }
.topbar .spacer { flex: 1; }
.topbar a { color: var(--text); }
.topbar .who {
  font-size: .82rem; text-align: right; line-height: 1.35; color: var(--muted);
}
.topbar .who strong { color: var(--text); font-weight: 500; }

.shell { display: flex; min-height: calc(100vh - var(--topbar-h)); align-items: flex-start; }

.sidebar {
  width: 244px; flex: 0 0 244px;
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: .9rem .6rem 2rem;
  position: sticky; top: var(--topbar-h);
  max-height: calc(100vh - var(--topbar-h));
  overflow-y: auto;
  scrollbar-width: thin;
}
/* Item nav memakai bentuk pil penuh — ciri khas navigation rail Material 3. */
.sidebar a {
  display: flex; align-items: center; gap: .7rem;
  padding: .58rem .9rem;
  border-radius: var(--r-full);
  color: var(--text-2);
  font-size: .9rem; font-weight: 400;
  margin-bottom: 2px;
  position: relative; overflow: hidden;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.sidebar a i { width: 1.15rem; text-align: center; font-size: .95rem; color: var(--muted); transition: color var(--t-fast) var(--ease); }
.sidebar a:hover { background: var(--surface-2); color: var(--text); }
.sidebar a:hover i { color: var(--text-2); }
.sidebar a.active { background: var(--brand-light); color: var(--brand); font-weight: 500; }
.sidebar a.active i { color: var(--brand); }
.sidebar .group {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); margin: 1.1rem .95rem .35rem; font-weight: 500;
}

main { flex: 1; padding: 1.5rem 1.6rem 4rem; min-width: 0; }

.page-head { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.page-head .spacer { flex: 1; }
.page-head h1 { display: flex; align-items: center; gap: .6rem; }
.page-head h1 i { color: var(--brand); font-size: .9em; }

/* ==========================================================================
   Kartu & petak
   ========================================================================== */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 1.15rem 1.25rem;
  box-shadow: var(--e1);
  margin-bottom: 1.1rem;
  transition: box-shadow var(--t) var(--ease), transform var(--t) var(--ease);
}
.card h2, .card h3 { margin-top: 0; }
.card.flat { box-shadow: none; }
.card.raised { box-shadow: var(--e3); border-color: transparent; }
/* Dipakai pada daftar yang bisa diklik; jangan pasang ke kartu statis. */
.card.hoverable:hover { box-shadow: var(--e3); transform: translateY(-2px); }

.grid { display: grid; gap: 1.1rem; }
.grid.c2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid.c3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.grid.c4 { grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); }

.stat {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
  padding: 1rem 1.1rem; box-shadow: var(--e1); min-width: 0;
  transition: box-shadow var(--t) var(--ease), transform var(--t) var(--ease);
}
.stat:hover { box-shadow: var(--e2); transform: translateY(-1px); }
.stat .label {
  font-size: .74rem; color: var(--muted); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 500;
  display: flex; align-items: center; gap: .4rem;
}
.stat .value {
  font-size: 1.6rem; font-weight: 500; margin-top: .2rem; letter-spacing: -.025em;
  color: var(--text); font-variant-numeric: tabular-nums; overflow-wrap: break-word;
}
.stat .sub { font-size: .8rem; color: var(--muted); }
.stat.brand {
  background: linear-gradient(135deg, var(--brand), var(--brand-dark));
  color: var(--brand-ink); border-color: transparent; box-shadow: var(--e2);
}
.stat.brand .label, .stat.brand .sub { color: color-mix(in srgb, var(--brand-ink) 72%, transparent); }
.stat.brand .value { color: var(--brand-ink); }

/* ==========================================================================
   Tabel
   ========================================================================== */
table { width: 100%; border-collapse: collapse; font-size: .89rem; }
th, td { padding: .68rem .6rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
th {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
  font-weight: 500; background: transparent; white-space: nowrap;
  border-bottom: 1px solid var(--border-strong);
}
tbody tr { transition: background var(--t-fast) var(--ease); }
tbody tr:hover { background: var(--surface-2); }
tbody tr:last-child td { border-bottom: 0; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.table-wrap { overflow-x: auto; margin: 0 -.25rem; padding: 0 .25rem; }

/* ==========================================================================
   Badge / chip
   ========================================================================== */
.badge {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .2rem .6rem; border-radius: var(--r-full);
  font-size: .74rem; font-weight: 500; line-height: 1.5;
  background: var(--surface-3); color: var(--text-2); white-space: nowrap;
}
.badge.ok, .badge.active, .badge.delivered, .badge.paid, .badge.released, .badge.verified { background: var(--ok-bg); color: var(--ok); }
.badge.warn, .badge.pending, .badge.pending_payment, .badge.submitted, .badge.requested,
.badge.frozen, .badge.waiting_verification { background: var(--warn-bg); color: var(--warn); }
.badge.danger, .badge.cancelled, .badge.rejected, .badge.terminated, .badge.reversed,
.badge.returned { background: var(--danger-bg); color: var(--danger); }
.badge.info, .badge.shipped, .badge.processing, .badge.packed, .badge.open { background: var(--info-bg); color: var(--info); }
.badge.master { background: #332708; color: #f3ce85; }
.badge.brand { background: var(--brand-light); color: var(--brand); }

/* ==========================================================================
   Formulir
   ========================================================================== */
label { display: block; font-size: .82rem; font-weight: 500; margin-bottom: .3rem; color: var(--text-2); }

input, select, textarea {
  width: 100%; padding: .62rem .8rem;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  font: inherit; font-size: .92rem;
  background: var(--surface); color: var(--text);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--muted); }
input:hover, select:hover, textarea:hover { border-color: var(--muted); }
/* Garis fokus dibuat dari box-shadow, bukan outline, supaya sudut membulatnya
   ikut dan tidak ada lompatan tata letak. */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent);
}
select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238f8672'%3E%3Cpath d='M4.4 6.2 8 9.8l3.6-3.6 1.1 1.1L8 12 3.3 7.3z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .55rem center; background-size: 1.1rem;
  padding-right: 2.1rem;
}
input[type="checkbox"], input[type="radio"] { width: auto; accent-color: var(--brand); }
textarea { resize: vertical; min-height: 4.5rem; }

.field { margin-bottom: .9rem; }
.row { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

/* -- toggle tampil/sembunyi kata sandi ------------------------------------ */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 2.6rem; }
.pw-toggle {
  position: absolute; top: 0; right: 0; bottom: 0; width: 2.6rem;
  display: grid; place-items: center; font-size: .95rem;
  background: transparent; color: var(--muted); box-shadow: none; border: 0; padding: 0;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.pw-toggle:hover { background: transparent; color: var(--text-2); box-shadow: none; }

/* ==========================================================================
   Tombol — filled / tonal / outlined / text, plus efek riak
   ========================================================================== */
button, .btn {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .58rem 1.15rem;
  border: 1px solid transparent;
  background: var(--brand); color: var(--brand-ink);
  border-radius: var(--r-full);
  font: inherit; font-size: .89rem; font-weight: 500; letter-spacing: .01em;
  cursor: pointer; text-align: center; white-space: nowrap;
  box-shadow: var(--e1);
  transition: box-shadow var(--t) var(--ease), background var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
button:hover, .btn:hover { background: var(--brand-dark); color: var(--brand-ink); box-shadow: var(--e2); }
button:active, .btn:active { transform: scale(.97); box-shadow: var(--e1); }
button:disabled, .btn.disabled { opacity: .42; cursor: not-allowed; box-shadow: none; transform: none; }
button:disabled:hover { background: var(--brand); }

/* Tonal — latar merek yang sangat terang, untuk aksi sekunder yang sering dipakai. */
button.ghost, .btn.ghost {
  background: var(--brand-light); color: var(--brand); box-shadow: none;
}
button.ghost:hover, .btn.ghost:hover {
  background: color-mix(in srgb, var(--brand) 30%, black); color: var(--brand); box-shadow: var(--e1);
}

/* Outlined — aksi netral yang tetap terlihat sebagai tombol. */
button.neutral, .btn.neutral {
  background: var(--surface); color: var(--text-2); border-color: var(--border-strong); box-shadow: none;
}
button.neutral:hover, .btn.neutral:hover { background: var(--surface-2); color: var(--text); border-color: var(--muted); }

/* Text — aksi tersier, tanpa latar sampai disentuh. */
button.text, .btn.text { background: transparent; color: var(--brand); box-shadow: none; }
button.text:hover, .btn.text:hover { background: var(--brand-light); color: var(--brand); box-shadow: none; }

button.danger, .btn.danger { background: var(--danger); color: var(--brand-ink); }
button.danger:hover, .btn.danger:hover { background: color-mix(in srgb, var(--danger) 82%, black); color: #fff; }

button.accent, .btn.accent { background: var(--accent); color: var(--brand-ink); }
button.accent:hover, .btn.accent:hover { background: color-mix(in srgb, var(--accent) 85%, #000); color: var(--brand-ink); }

button.sm, .btn.sm { padding: .34rem .8rem; font-size: .8rem; gap: .35rem; }
button.lg, .btn.lg { padding: .78rem 1.7rem; font-size: .98rem; }
button.block, .btn.block { width: 100%; }

/* Tombol ikon bulat — dipakai di topbar dan kartu produk. */
button.icon, .btn.icon {
  width: 40px; height: 40px; padding: 0; border-radius: 50%;
  background: transparent; color: var(--text-2); box-shadow: none; flex: 0 0 auto;
}
button.icon:hover, .btn.icon:hover { background: var(--surface-2); color: var(--text); box-shadow: none; }
button.icon.sm, .btn.icon.sm { width: 32px; height: 32px; font-size: .82rem; }

/* Tombol aksi mengambang (FAB) — hanya satu per layar. */
.fab {
  position: fixed; right: 1.5rem; bottom: 1.5rem; z-index: 90;
  width: 58px; height: 58px; padding: 0; border-radius: var(--r-lg);
  font-size: 1.15rem; box-shadow: var(--e4);
}
.fab:hover { box-shadow: var(--e5); }

/* Riak. Elemen <span class="ripple"> disuntikkan oleh app.js saat tombol
   ditekan, lalu dibuang sendiri setelah animasinya selesai. */
.ripple {
  position: absolute; border-radius: 50%; transform: scale(0);
  background: currentColor; opacity: .28; pointer-events: none;
  animation: ripple-out 560ms var(--ease-out) forwards;
}
@keyframes ripple-out { to { transform: scale(2.6); opacity: 0; } }

/* ==========================================================================
   Alert
   ========================================================================== */
.alert {
  display: flex; gap: .7rem; align-items: flex-start;
  padding: .8rem 1rem; border-radius: var(--r-sm); margin-bottom: .9rem;
  font-size: .89rem; border: 1px solid transparent; line-height: 1.5;
}
.alert > i:first-child { font-size: 1rem; margin-top: .12rem; flex: 0 0 auto; }
.alert.info { background: var(--info-bg); border-color: color-mix(in srgb, var(--info) 35%, transparent); color: var(--info); }
.alert.ok { background: var(--ok-bg); border-color: color-mix(in srgb, var(--ok) 35%, transparent); color: var(--ok); }
.alert.warn { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 35%, transparent); color: var(--warn); }
.alert.danger { background: var(--danger-bg); border-color: color-mix(in srgb, var(--danger) 35%, transparent); color: var(--danger); }

/* ==========================================================================
   Bar kemajuan
   ========================================================================== */
.bar { height: 8px; border-radius: var(--r-full); background: var(--surface-3); overflow: hidden; margin: .4rem 0; }
.bar > i {
  display: block; height: 100%; background: var(--brand); border-radius: var(--r-full);
  transition: width var(--t-slow) var(--ease);
}
.bar > i.warn { background: var(--warn); }
.bar > i.ok { background: var(--ok); }

/* Indikator memuat tak tentu — dipakai di kepala kartu saat menunggu data. */
.progress-line { height: 3px; background: var(--surface-3); overflow: hidden; border-radius: var(--r-full); }
.progress-line::after {
  content: ''; display: block; height: 100%; width: 40%;
  background: var(--brand); border-radius: var(--r-full);
  animation: indeterminate 1.4s var(--ease) infinite;
}
@keyframes indeterminate {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}

/*
 * Area unggah seret-lepas.
 *
 * Berupa <label> yang membungkus <input type=file>, bukan div berpendengar
 * klik: label memberi aktivasi keyboard dan pembacaan pembaca layar secara
 * cuma-cuma. Input-nya tetap ada di DOM (tidak display:none) supaya tetap
 * dapat difokus dengan Tab.
 */
.drop {
  border: 2px dashed var(--border); border-radius: var(--r-md);
  padding: .9rem 1rem; text-align: center; cursor: pointer;
  background: var(--surface-2); transition: border-color .15s var(--ease), background .15s var(--ease);
}
.drop:hover, .drop:focus-within { border-color: var(--brand); }
.drop.over { border-color: var(--brand); background: var(--brand-soft, var(--surface-3)); }
.drop input[type=file] { display: block; width: 100%; margin-bottom: .5rem; font-size: .85rem; }
.drop input[type=file]:disabled { opacity: .5; cursor: not-allowed; }
.drop:has(input:disabled) { opacity: .6; cursor: not-allowed; }

/* Kerangka (skeleton) untuk katalog yang belum termuat. */
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }

/* ==========================================================================
   Utilitas
   ========================================================================== */
.muted { color: var(--muted); }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.mono { font-variant-numeric: tabular-nums; }
.flex { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.hidden { display: none !important; }
.mt { margin-top: 1rem; } .mb { margin-bottom: 1rem; }
.divider { height: 1px; background: var(--border); border: 0; margin: 1.1rem 0; }

/* ==========================================================================
   Badge ajakan instal PWA
   ========================================================================== */
.pwa-banner {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
  background: var(--surface); border-top: 1px solid var(--border); box-shadow: var(--e4);
  padding: .85rem 1rem calc(.85rem + env(safe-area-inset-bottom, 0px));
  animation: pwa-banner-in 320ms var(--ease-out);
}
.pwa-banner-in { max-width: 640px; margin: 0 auto; display: flex; align-items: center; gap: .8rem; }
.pwa-banner-ic {
  width: 40px; height: 40px; border-radius: var(--r-sm); object-fit: cover; flex: 0 0 auto;
  color: var(--brand); font-size: 1.6rem; display: grid; place-items: center;
}
.pwa-banner-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
.pwa-banner-txt strong { font-size: .88rem; }
.pwa-banner-txt span { font-size: .78rem; color: var(--text-2); line-height: 1.35; }
@keyframes pwa-banner-in { from { transform: translateY(100%); } }
@media (max-width: 560px) {
  .pwa-banner-txt span { display: none; }
}

/* ==========================================================================
   Toast (snackbar Material)
   ========================================================================== */
.toast-wrap {
  position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 999;
  display: flex; flex-direction: column; gap: .55rem; max-width: 400px;
}
.toast {
  display: flex; align-items: center; gap: .6rem;
  padding: .8rem 1.1rem; border-radius: var(--r-sm); color: #fff;
  box-shadow: var(--e4); font-size: .88rem; background: var(--surface-3);
  animation: snackbar-in 260ms var(--ease-out);
}
.toast.ok { background: var(--ok); color: #072311; }
.toast.danger { background: var(--danger); color: #350707; }
.toast.warn { background: var(--warn); color: #332204; }
@keyframes snackbar-in {
  from { transform: translateY(14px) scale(.96); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* ==========================================================================
   Modal / dialog
   ========================================================================== */
#modal { animation: fade-in var(--t) var(--ease); }
#modal > .card { animation: dialog-in 260ms var(--ease-out); }
@keyframes fade-in { from { opacity: 0; } }
@keyframes dialog-in {
  from { transform: translateY(18px) scale(.97); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* ==========================================================================
   Halaman masuk / daftar — gaya boutique, lihat catatan (4) di atas
   ========================================================================== */
.auth-page {
  display: flex; align-items: center; justify-content: center; min-height: 100vh;
  padding: 1.5rem; position: relative; overflow-x: hidden;
  background: var(--bg);
}
/* Garis emas tipis di keempat sisi jendela — pengganti gradasi mencolok versi
   lama; tanda tangan "bingkai" ala butik alih-alih warna penuh satu layar. */
.auth-page::before {
  content: ''; position: fixed; inset: 18px; border: 1px solid var(--border-strong);
  pointer-events: none; z-index: 0;
}
.auth-page::after { content: none; }
/*
 * `overflow-x`, bukan `overflow` penuh, dengan sengaja — .auth-page adalah body
 * (lihat public/daftar.html, masuk.html). Body dengan overflow:hidden pada
 * kedua sumbu ikut MENGUNCI SCROLL SELURUH DOKUMEN: karena <html> tidak
 * menyatakan overflow sendiri, peramban meneruskan (propagate) overflow body
 * ke viewport. Pada formulir pendaftaran yang lebih tinggi dari layar, itu
 * berarti bagian bawah formulir — termasuk tombol "Daftar sekarang" — tidak
 * pernah bisa digulir sampai terlihat.
 */
.auth-card {
  width: 100%; max-width: 440px; background: var(--surface); border: 1px solid var(--border);
  padding: 2.6rem 2.4rem; position: relative; z-index: 1;
  animation: dialog-in 420ms var(--ease-out);
}
.auth-card.wide { max-width: 760px; }
.auth-card .logo {
  font-family: 'Playfair Display', serif; font-size: 1.7rem; font-weight: 600;
  color: var(--text); margin-bottom: 1.3rem; letter-spacing: .01em;
  display: flex; align-items: center; gap: .6rem; justify-content: center;
}
.auth-card .logo span { color: var(--text); }
.auth-card > p.muted { text-align: center; margin-bottom: 1.6rem; }
.auth-card h3 {
  font-family: 'Playfair Display', serif; font-weight: 600; font-size: 1.15rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--border); margin-bottom: 1.1rem;
}

/* ==========================================================================
   Sisa halaman lama
   ========================================================================== */
.tree-row td:first-child { padding-left: calc(var(--d, 0) * 20px + .6rem); }
.legal-foot {
  font-size: .78rem; color: var(--muted); padding: 1.2rem 0 0;
  border-top: 1px solid var(--border); margin-top: 2rem; line-height: 1.7;
}

/* ==========================================================================
   ETALASE — komponen khusus halaman publik & katalog belanja
   --------------------------------------------------------------------------
   Bahasa desainnya sengaja BEDA dari panel admin di atas: judul serif
   (Playfair Display), sudut tajam (tanpa border-radius) ganti pil membulat,
   garis tipis satu piksel ganti bayangan berlapis untuk kedalaman, dan huruf
   kapital kecil berspasi lebar untuk label/navigasi — kosakata visual toko
   butik/editorial, bukan aplikasi Material. Token warna (--brand, --surface,
   --text, dst.) tetap dipakai sepenuhnya; yang berubah hanya bentuk.
   ========================================================================== */

/* -- kerangka halaman toko ------------------------------------------------ */
.shop-body { background: var(--bg); }
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 1.5rem; }
.section { padding: 4rem 0; }
.section-head { text-align: center; max-width: 640px; margin: 0 auto 2.5rem; }
.section-head h2 { font-size: 2rem; }
.section-head p { color: var(--muted); font-size: 1.02rem; }

/* Judul serif di seluruh etalase — satu-satunya tempat Playfair Display
   dipakai. Panel admin tetap Roboto di semua bobot (lihat catatan berkas). */
.shop-body h1, .shop-body h2, .shop-body h3,
.auth-page h1, .auth-page h2, .auth-page h3 {
  font-family: 'Playfair Display', serif; font-weight: 600; letter-spacing: 0;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .18em;
  color: var(--brand); background: none; border: 0;
  padding: 0 0 .6rem; margin-bottom: 1rem; border-bottom: 1px solid var(--border);
}

/* Garis tipis emas — satu elemen dekoratif yang dipakai berulang sebagai
   pemisah antara judul dan isi (pengganti bayangan/pil versi lama). */
.rule-gold { width: 56px; height: 2px; background: var(--brand); border: 0; margin: 1.1rem 0; }
.section-head .rule-gold { margin: 1.1rem auto; }

/* -- tombol etalase — sudut tajam, huruf kapital berspasi, TANPA menyentuh
   selektor `button, .btn` global yang dipakai dashboard di atas ------------ */
.shop-body button, .shop-body .btn,
.auth-page button, .auth-page .btn {
  border-radius: 0; box-shadow: none;
  font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  padding: .75rem 1.5rem;
}
.shop-body button:hover, .shop-body .btn:hover,
.auth-page button:hover, .auth-page .btn:hover { box-shadow: none; }
.shop-body button.sm, .shop-body .btn.sm, .auth-page button.sm, .auth-page .btn.sm { padding: .5rem 1rem; font-size: .7rem; }
.shop-body button.lg, .shop-body .btn.lg, .auth-page button.lg, .auth-page .btn.lg { padding: 1rem 2rem; font-size: .82rem; }
.shop-body button.icon, .shop-body .btn.icon,
.auth-page button.icon, .auth-page .btn.icon { border-radius: 0; padding: 0; }
.shop-body button.neutral, .shop-body .btn.neutral,
.auth-page button.neutral, .auth-page .btn.neutral { border: 1px solid var(--border-strong); }
.shop-body button.ghost, .shop-body .btn.ghost,
.auth-page button.ghost, .auth-page .btn.ghost { border: 1px solid var(--brand); background: none; }
.shop-body button.ghost:hover, .shop-body .btn.ghost:hover,
.auth-page button.ghost:hover, .auth-page .btn.ghost:hover { background: var(--brand-light); }
.shop-body .badge, .auth-page .badge { border-radius: 0; }
.shop-body .card, .auth-page .card { border-radius: 0; box-shadow: none; }
.shop-body .card.raised, .auth-page .card.raised { box-shadow: none; border: 1px solid var(--border); }
.shop-body input, .shop-body select, .shop-body textarea,
.auth-page input, .auth-page select, .auth-page textarea { border-radius: 0; }
.shop-body .alert, .auth-page .alert { border-radius: 0; }
.shop-body .pwa-banner { box-shadow: none; border-top: 1px solid var(--border-strong); }

/* -- bilah navigasi toko -------------------------------------------------- */
.shopbar {
  position: sticky; top: 0; z-index: 60;
  background: rgba(10, 10, 10, .92);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--border);
}
.shopbar.stuck { box-shadow: 0 1px 0 var(--border); }
.shopbar-in { display: flex; align-items: center; gap: 2.2rem; height: 76px; }
.shopbar .brand { display: inline-flex; align-items: center; }
.shopbar .brand span {
  font-family: 'Playfair Display', serif; font-weight: 600; font-size: 1.2rem; letter-spacing: .01em;
}
.shopbar .links { display: flex; gap: 1.7rem; margin-left: .4rem; }
.shopbar .links a {
  position: relative; padding: .3rem 0; font-size: .78rem; color: var(--text-2);
  text-transform: uppercase; letter-spacing: .12em; font-weight: 500;
  transition: color var(--t-fast) var(--ease);
}
.shopbar .links a::after {
  content: ''; position: absolute; left: 0; right: 100%; bottom: 0; height: 1px;
  background: var(--brand); transition: right var(--t) var(--ease);
}
.shopbar .links a:hover, .shopbar .links a.active { background: none; color: var(--text); }
.shopbar .links a:hover::after, .shopbar .links a.active::after { right: 0; }

/* -- lencana jumlah item keranjang --------------------------------------- */
.cart-btn { position: relative; }
.cart-count {
  position: absolute; top: -2px; right: -2px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 0; background: var(--accent); color: var(--brand-ink);
  font-size: .64rem; font-weight: 700; line-height: 17px; text-align: center;
  box-shadow: 0 0 0 2px var(--bg);
}
.cart-count:empty, .cart-count.zero { display: none; }
.cart-count.bump { animation: bump 420ms var(--ease-out); }
@keyframes bump {
  0% { transform: scale(1); } 35% { transform: scale(1.45); } 100% { transform: scale(1); }
}

/* -- hero — susunan asimetris, satu foto besar berbingkai (bukan tumpukan
   kartu melayang) ---------------------------------------------------------- */
.hero { position: relative; overflow: hidden; padding: 4.5rem 0 5rem; background: var(--bg); }
.hero-in { position: relative; z-index: 1; display: grid; gap: 4rem; align-items: center; grid-template-columns: 1fr .85fr; }
.hero h1 { font-size: clamp(2.3rem, 4.8vw, 3.6rem); line-height: 1.08; color: var(--text); font-weight: 600; }
.hero p.lead { font-size: 1.08rem; color: var(--text-2); max-width: 50ch; }
.hero-cta { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 2rem; }
.hero-proof {
  display: flex; gap: 0; margin-top: 2.8rem; flex-wrap: wrap;
  border-top: 1px solid var(--border);
}
.hero-proof > div { padding: 1.1rem 1.6rem 0 0; margin-right: 1.6rem; border-right: 1px solid var(--border); }
.hero-proof > div:last-child { border-right: 0; margin-right: 0; }
.hero-proof .n { font-size: 1.4rem; font-weight: 600; color: var(--text); font-family: 'Playfair Display', serif; }
.hero-proof .l { font-size: .74rem; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }

/* Satu foto produk besar dalam bingkai bergaris tipis — lihat index.html,
   fungsi renderHeroArt(); bukan lagi tiga kartu melayang bertumpuk. */
.hero-art { position: relative; }
.hero-art .frame {
  position: relative; aspect-ratio: 3 / 4; border: 1px solid var(--border-strong);
  padding: 14px; background: var(--surface);
}
.hero-art .frame-in {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  background: linear-gradient(135deg, var(--surface-2), var(--surface-3));
  display: flex; align-items: center; justify-content: center;
}
.hero-art .frame-in img { width: 100%; height: 100%; object-fit: cover; }
.hero-art .frame-in .ph { font-size: 3.4rem; color: color-mix(in srgb, var(--brand) 40%, #fff); }
.hero-art .tag {
  position: absolute; left: -1px; bottom: 22px; background: var(--brand); color: var(--brand-ink);
  padding: .6rem 1.1rem; font-size: .82rem; font-weight: 600;
}

/* -- kartu produk etalase — media persegi, sudut tajam, tanpa bayangan ---- */
.product-grid { display: grid; gap: 0; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.product-grid .product-card { border-width: 1px 0 1px 1px; }
.product-grid .product-card:last-child,
.product-grid .product-card:nth-last-child(-n+12) { border-right-width: 1px; }

.product-card {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  transition: border-color var(--t) var(--ease);
}
.product-card:hover { border-color: var(--brand); }

.product-media {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden;
  background: linear-gradient(135deg, var(--surface-2), var(--surface-3));
  display: flex; align-items: center; justify-content: center;
}
.product-media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease); }
.product-card:hover .product-media img { transform: scale(1.04); }
.product-media .ph { font-size: 2.6rem; color: color-mix(in srgb, var(--brand) 40%, #fff); }
.product-media .tags { position: absolute; top: 0; left: 0; display: flex; gap: 0; flex-wrap: wrap; }
.product-media .tags .badge { border-radius: 0; box-shadow: none; background: var(--bg); }

.product-quick {
  position: absolute; left: 0; right: 0; bottom: 0; padding: .6rem;
  display: flex; gap: .5rem; background: rgba(10, 10, 10, .82);
  opacity: 0; transform: translateY(8px);
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.product-card:hover .product-quick, .product-card:focus-within .product-quick { opacity: 1; transform: none; }
@media (hover: none) {
  .product-quick { opacity: 1; transform: none; position: static; margin-top: .7rem; background: none; padding: 0; }
}

.product-body { padding: 1.2rem 1.2rem 1.3rem; display: flex; flex-direction: column; flex: 1; gap: .3rem; }
.product-body .cat { font-size: .68rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); font-weight: 600; }
.product-body h3 { font-size: 1.05rem; font-weight: 600; margin: .15rem 0 0; line-height: 1.35; }
.product-body h3 a { color: var(--text); }
.product-body h3 a:hover { color: var(--brand); }
.product-body .desc {
  font-size: .84rem; color: var(--muted); margin: .3rem 0 .4rem;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.product-price {
  margin-top: auto; padding-top: .7rem; border-top: 1px solid var(--border);
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
}
.product-price .now {
  font-size: .92rem; font-weight: 600; color: var(--text); letter-spacing: .04em;
  font-variant-caps: all-small-caps;
}
.product-price .was { font-size: .8rem; color: var(--muted); text-decoration: line-through; }
.product-price .save { font-size: .72rem; font-weight: 500; color: var(--ok); background: var(--ok-bg); padding: .1rem .4rem; }
.product-foot { display: flex; gap: .5rem; margin-top: .9rem; }
.product-foot .btn, .product-foot button { flex: 1; }

/* -- panel penyaring ------------------------------------------------------ */
.filter-bar {
  display: flex; gap: .7rem; align-items: center; flex-wrap: wrap;
  padding: 1rem 1.2rem; background: var(--surface); border: 1px solid var(--border);
  margin-bottom: 0;
}
.filter-bar .search { position: relative; flex: 1; min-width: 220px; }
.filter-bar .search i { position: absolute; left: .85rem; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: .9rem; }
.filter-bar .search input { padding-left: 2.4rem; }

/* Kategori sebagai tab bergaris bawah — bukan lagi pil terisi ala Material. */
.chips {
  display: flex; gap: 0; flex-wrap: wrap; border: 1px solid var(--border); border-top: 0;
  background: var(--surface); margin-bottom: 1.8rem;
}
.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .8rem 1.1rem; border: 0; border-right: 1px solid var(--border);
  background: none; border-radius: 0;
  font-size: .76rem; text-transform: uppercase; letter-spacing: .08em; font-weight: 500;
  color: var(--text-2); cursor: pointer; white-space: nowrap;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.chip:hover { color: var(--text); background: var(--surface-2); }
.chip.active { background: var(--brand-light); border-color: var(--border); color: var(--brand); font-weight: 600; }
.chip.active::before { content: ''; }

/* -- laci keranjang ------------------------------------------------------- */
.drawer-scrim {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0, 0, 0, .6);
  animation: fade-in var(--t) var(--ease);
}
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 201;
  width: min(430px, 100%); background: var(--surface); border-left: 1px solid var(--border);
  display: flex; flex-direction: column;
  animation: drawer-in 300ms var(--ease-out);
}
@keyframes drawer-in { from { transform: translateX(100%); } }
.drawer-head {
  display: flex; align-items: center; gap: .7rem;
  padding: 1.3rem 1.4rem; border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.drawer-head h2 { margin: 0; flex: 1; font-size: 1.15rem; }
.drawer-body { flex: 1; overflow-y: auto; padding: 0 1.4rem; }
.drawer-foot { flex: 0 0 auto; padding: 1.2rem 1.4rem; border-top: 1px solid var(--border); background: var(--surface-1); }

.cart-line { display: flex; gap: .9rem; padding: 1rem 0; border-bottom: 1px solid var(--border); }
.cart-line:last-child { border-bottom: 0; }
.cart-line .thumb {
  width: 64px; height: 64px; flex: 0 0 auto; border: 1px solid var(--border); overflow: hidden;
  background: var(--surface-2); display: flex; align-items: center; justify-content: center;
  color: color-mix(in srgb, var(--brand) 45%, #fff);
}
.cart-line .thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-line .info { flex: 1; min-width: 0; }
.cart-line .info .n { font-size: .9rem; font-weight: 500; line-height: 1.35; }
.cart-line .info .p { font-size: .82rem; color: var(--muted); }

/* Penambah/pengurang jumlah. */
.stepper {
  display: inline-flex; align-items: center; border: 1px solid var(--border-strong);
  overflow: hidden; background: var(--surface);
}
.stepper button {
  width: 32px; height: 32px; padding: 0; border-radius: 0; background: transparent;
  color: var(--text-2); box-shadow: none; font-size: .75rem;
}
.stepper button:hover { background: var(--surface-2); color: var(--text); box-shadow: none; }
.stepper button:disabled { opacity: .3; }
.stepper .q { min-width: 32px; text-align: center; font-size: .88rem; font-variant-numeric: tabular-nums; font-weight: 500; }

.total-row { display: flex; justify-content: space-between; font-size: .9rem; padding: .35rem 0; color: var(--text-2); }
.total-row.grand {
  font-size: 1.05rem; font-weight: 600; color: var(--text); font-family: 'Playfair Display', serif;
  padding-top: .8rem; margin-top: .5rem; border-top: 1px solid var(--border);
}

/* -- keadaan kosong ------------------------------------------------------- */
.empty { text-align: center; padding: 3rem 1rem; color: var(--muted); }
.empty i { font-size: 2.6rem; color: var(--border-strong); display: block; margin-bottom: .9rem; }
.empty h3 { color: var(--text-2); font-weight: 500; }

/* -- langkah checkout — nomor dalam kotak bergaris tipis, bukan lingkaran
   terisi ---------------------------------------------------------------- */
.steps { display: flex; align-items: center; gap: .5rem; margin-bottom: 1.8rem; flex-wrap: wrap; }
.steps .step {
  display: flex; align-items: center; gap: .5rem; font-size: .78rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: .08em; font-weight: 500;
}
.steps .step .n {
  width: 24px; height: 24px; border: 1px solid var(--border-strong); flex: 0 0 auto;
  display: grid; place-items: center; font-size: .74rem; font-weight: 600;
  background: none; color: var(--muted);
  transition: background var(--t) var(--ease), color var(--t) var(--ease), border-color var(--t) var(--ease);
}
.steps .step.active { color: var(--text); }
.steps .step.active .n { background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }
.steps .step.done .n { background: none; color: var(--ok); border-color: var(--ok); }
.steps .sep { flex: 1; min-width: 18px; height: 1px; background: var(--border-strong); }

/* Tata letak checkout: daftar produk di kiri, ringkasan lengket di kanan.
   Ambang 900px sengaja lebih tinggi dari titik henti umum — di bawah itu
   ringkasan yang menyempit membuat angka rupiah terpotong. */
.checkout-grid { grid-template-columns: 1.55fr 1fr; align-items: start; gap: 0; }
.checkout-grid > div:first-child .card { border-right: 0; }
@media (max-width: 900px) {
  .checkout-grid { grid-template-columns: 1fr; }
  .checkout-grid #ringkasan { position: static !important; }
  .checkout-grid > div:first-child .card { border-right: 1px solid var(--border); }
}

/* -- kartu fitur pada halaman depan — ikon dalam kotak bergaris, tanpa
   latar terisi ------------------------------------------------------------ */
.feature { display: flex; gap: 1.1rem; align-items: flex-start; }
.feature .ic {
  width: 48px; height: 48px; flex: 0 0 auto; border: 1px solid var(--border-strong);
  display: grid; place-items: center; font-size: 1.1rem;
  background: none; color: var(--brand);
}
.feature h3 { margin-bottom: .3rem; font-size: 1.02rem; }
.feature p { margin: 0; font-size: .9rem; }

/* ==========================================================================
   HALAMAN DOKUMEN — kebijakan, syarat & ketentuan, bantuan
   --------------------------------------------------------------------------
   Aturan di bawah `.doc-body` menata HTML yang datang dari editor WYSIWYG.
   Karena markup itu tidak membawa kelas apa pun, penataannya harus lewat
   selektor elemen — dan karena itu semuanya WAJIB dibatasi di dalam .doc-body
   agar tidak bocor ke tabel dan daftar di halaman lain.
   ========================================================================== */
.doc-layout { display: grid; grid-template-columns: 268px 1fr; gap: 3rem; align-items: start; }

.doc-nav { position: sticky; top: 88px; }
.doc-nav .group {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); margin: 1.2rem .9rem .4rem; font-weight: 500;
}
.doc-nav .group:first-child { margin-top: 0; }
.doc-nav a {
  display: flex; align-items: center; gap: .65rem;
  padding: .5rem .9rem; border-left: 2px solid transparent;
  color: var(--text-2); font-size: .85rem; margin-bottom: 2px;
  text-transform: uppercase; letter-spacing: .05em;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.doc-nav a i { width: 1.05rem; text-align: center; font-size: .88rem; color: var(--muted); }
.doc-nav a:hover { border-left-color: var(--border-strong); color: var(--text); }
.doc-nav a.active { border-left-color: var(--brand); color: var(--brand); font-weight: 600; }
.doc-nav a.active i { color: var(--brand); }

/* Lebar baca dibatasi: teks hukum yang membentang penuh layar lebar sangat
   melelahkan dibaca, dan halaman ini justru yang paling perlu terbaca. */
.doc-head { max-width: 74ch; margin-bottom: 2rem; }
.doc-ic {
  width: 56px; height: 56px; border: 1px solid var(--border-strong); margin-bottom: 1.2rem;
  display: grid; place-items: center; font-size: 1.4rem;
  background: none; color: var(--brand);
}
.doc-head h1 { font-size: clamp(1.8rem, 3.4vw, 2.4rem); }
.doc-head .lead { font-size: 1.06rem; color: var(--text-2); max-width: 68ch; }

.doc-body { max-width: 74ch; font-size: .97rem; line-height: 1.75; color: var(--text-2); }
.doc-body > *:first-child { margin-top: 0; }
.doc-body h2 {
  font-size: 1.22rem; margin: 2.4rem 0 .7rem; color: var(--text);
  padding-top: 1.4rem; border-top: 1px solid var(--border);
}
.doc-body h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.doc-body h3 { font-size: 1.02rem; margin: 1.6rem 0 .5rem; color: var(--text); }
.doc-body h4 { font-size: .94rem; margin: 1.2rem 0 .4rem; color: var(--text); }
.doc-body p { margin: 0 0 1rem; }
.doc-body ul, .doc-body ol { margin: 0 0 1.15rem; padding-left: 1.35rem; }
.doc-body li { margin-bottom: .5rem; }
.doc-body li::marker { color: var(--brand); }
.doc-body a { text-decoration: underline; text-underline-offset: 2px; }
.doc-body blockquote {
  margin: 1.2rem 0; padding: .3rem 0 .3rem 1.15rem;
  border-left: 3px solid var(--brand); color: var(--muted); font-style: italic;
}
.doc-body hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }
.doc-body table { margin: 1.2rem 0; font-size: .9rem; }
.doc-body img { max-width: 100%; height: auto; border-radius: var(--r-sm); margin: 1rem 0; }
.doc-body figure { margin: 1.4rem 0; }
.doc-body figcaption { font-size: .84rem; color: var(--muted); margin-top: .5rem; }
.doc-body .alert { margin: 1.3rem 0; }

.doc-foot { max-width: 74ch; margin-top: 3rem; padding-top: 1.4rem; border-top: 1px solid var(--border); }
.doc-foot p { margin: 0; font-size: .89rem; }

@media (max-width: 900px) {
  .doc-layout { grid-template-columns: 1fr; gap: 1.6rem; }
  /* Di layar sempit daftar isi menjadi baris chip yang dapat digulir mendatar,
     bukan kolom setinggi layar yang mendorong isi halaman ke bawah lipatan. */
  .doc-nav {
    position: static; display: flex; gap: .4rem; overflow-x: auto;
    padding-bottom: .5rem; scrollbar-width: thin;
  }
  .doc-nav .group { display: none; }
  .doc-nav a {
    flex: 0 0 auto; border: 1px solid var(--border-strong); border-left: 1px solid var(--border-strong);
    background: var(--surface); white-space: nowrap;
  }
  .doc-nav a.active { border-color: var(--brand); }
}

/* -- footer toko -----------------------------------------------------------
   Tanda merek besar berhuruf serif di tengah, garis emas tipis, lalu kolom
   tautan seperti biasa dan baris legal di bawahnya — pola "majalah" alih-alih
   footer gelap kebiruan versi lama. */
.shop-foot { background: var(--bg); color: var(--muted); padding: 4rem 0 2.5rem; font-size: .88rem; margin-top: 4rem; border-top: 1px solid var(--border); }
.shop-foot-brand { text-align: center; max-width: 46ch; margin: 0 auto; }
.shop-foot-mark { font-family: 'Playfair Display', serif; font-size: 1.6rem; font-weight: 600; color: var(--text); }
.shop-foot-tagline { color: var(--muted); line-height: 1.75; margin: .8rem 0 0; }
.shop-foot .rule-gold { margin: 2rem auto; }
.shop-foot a { color: var(--text-2); }
.shop-foot a:hover { color: var(--brand); }
.shop-foot h4 { color: var(--text); font-size: .74rem; text-transform: uppercase; letter-spacing: .12em; margin-bottom: 1rem; font-weight: 600; }
.shop-foot .cols { display: grid; gap: 2.2rem; grid-template-columns: 1fr 1fr 1fr; text-align: center; }
.shop-foot .bottom { border-top: 1px solid var(--border); margin-top: 2.4rem; padding-top: 1.5rem; font-size: .8rem; line-height: 1.9; text-align: center; }
.shop-foot .social { display: flex; gap: .5rem; margin-top: 1.2rem; justify-content: center; }
.shop-foot .social a {
  width: 36px; height: 36px; border: 1px solid var(--border-strong); display: grid; place-items: center;
  background: none; color: var(--text-2);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.shop-foot .social a:hover { background: var(--brand); color: var(--brand-ink); border-color: var(--brand); }

/* ==========================================================================
   EDITOR WYSIWYG (panel admin)
   ========================================================================== */
.editor {
  border: 1px solid var(--border-strong); border-radius: var(--r);
  background: var(--surface); overflow: hidden;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.editor:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 14%, transparent); }

.editor-bar {
  display: flex; align-items: center; gap: .15rem; flex-wrap: wrap;
  padding: .45rem .55rem; background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  position: sticky; top: var(--topbar-h); z-index: 10;
}
.editor-sep { width: 1px; height: 20px; background: var(--border-strong); margin: 0 .35rem; }
.editor-spacer { flex: 1; }

.editor-btn {
  width: 32px; height: 32px; padding: 0; border-radius: var(--r-xs);
  background: transparent; color: var(--text-2); box-shadow: none;
  font-size: .82rem; flex: 0 0 auto;
}
.editor-btn:hover { background: var(--surface-3); color: var(--text); box-shadow: none; }
.editor-btn.aktif { background: var(--brand-light); color: var(--brand); }
.editor-btn:disabled { opacity: .3; }

.editor-blok {
  width: auto; min-width: 150px; padding: .3rem 1.9rem .3rem .55rem;
  font-size: .84rem; border-radius: var(--r-xs); background-position: right .35rem center;
}

/* Isi editor memakai kelas .doc-body juga, sehingga apa yang terlihat saat
   menyunting sama persis dengan tampilannya setelah terbit. */
.editor-isi {
  padding: 1.6rem 1.8rem; min-height: 420px; max-height: 62vh; overflow-y: auto;
  outline: none; max-width: none;
}
.editor-isi:empty::before {
  content: 'Mulai menulis di sini…'; color: var(--muted);
}
/* Batas bantu lebar baca — memperlihatkan di mana teks akan terpotong saat
   terbit, tanpa benar-benar membatasi area sunting. */
.editor-isi > * { max-width: 74ch; }

.editor-sumber {
  width: 100%; min-height: 420px; max-height: 62vh; border: 0; border-radius: 0;
  padding: 1.2rem 1.4rem; font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: .84rem; line-height: 1.65; resize: vertical; background: var(--surface-2);
}
.editor-sumber:focus { box-shadow: none; }

.editor-kaki {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .5rem .9rem; border-top: 1px solid var(--border);
  background: var(--surface-1); font-size: .78rem; color: var(--muted);
}

/* Pratinjau di dalam dialog */
.doc-preview { max-height: 62vh; overflow-y: auto; padding: .3rem; }

@media (max-width: 860px) {
  .editor-bar { position: static; }
  .editor-isi, .editor-sumber { padding: 1rem; min-height: 320px; }
}

/* ==========================================================================
   DOKUMEN PENGIRIMAN — label alamat & surat jalan
   --------------------------------------------------------------------------
   Ditata dalam milimeter, bukan piksel: keluarannya kertas, dan satu-satunya
   satuan yang berarti di kertas adalah satuan fisik. Ukuran font pun memakai
   `pt` supaya hasil cetak sama di layar mana pun.

   Blok ini berlaku di layar (sebagai pratinjau) maupun di printer. Perbedaan
   khusus cetak ada di @media print pada akhir berkas.
   ========================================================================== */
.cetak-body { background: var(--surface-3); }

.cetak-bar {
  position: sticky; top: 0; z-index: 50;
  background: var(--surface); border-bottom: 1px solid var(--border); box-shadow: var(--e1);
}
.divider-v { width: 1px; height: 22px; background: var(--border-strong); }

#lembar { padding: 1.5rem 0 3rem; }

/* -- label alamat --------------------------------------------------------- */
.label-wrap { display: flex; flex-direction: column; align-items: center; gap: 1.2rem; }
.label-wrap.a4 {
  display: grid; grid-template-columns: repeat(2, 100mm); justify-content: center;
}

/*
 * `.ship-label`, bukan `.label` — nama generik itu sebelumnya bentrok dengan
 * `<div class="label">` yang dipakai `.stat` di puluhan halaman (caption kecil
 * di atas angka statistik, lihat `.stat .label`). Spesifisitas CSS membuat
 * warna/ukuran fontnya menang dari aturan `.stat .label`, tapi width:100mm;
 * height:150mm; background:#fff di sini ikut menempel karena properti itu
 * tidak disentuh `.stat .label` sama sekali — hasilnya kotak putih raksasa di
 * balik setiap label statistik. Di tema terang lama itu tak kelihatan (putih
 * di atas putih); di tema gelap ini jadi kotak putih mencolok. */
.ship-label {
  width: 100mm; height: 150mm;
  background: #fff; color: #000;
  padding: 5mm; box-sizing: border-box;
  display: flex; flex-direction: column;
  font-size: 9pt; line-height: 1.35;
  border: 1px solid var(--border-strong);
  box-shadow: var(--e2);
  /* Label tidak boleh terpotong di tengah halaman, apa pun modenya. */
  break-inside: avoid; page-break-inside: avoid;
}

.label-atas {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 3mm;
  padding-bottom: 2mm; border-bottom: 0.6mm solid #000;
}
.label-merek strong { font-size: 13pt; letter-spacing: -.02em; display: block; }
.label-kurir {
  font-size: 8.5pt; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  margin-top: .8mm;
}
.label-bc { text-align: right; }
.label-bc svg { display: block; }

.label-blok { padding: 2.5mm 0; border-bottom: 0.3mm dashed #999; }
.label-judul {
  font-size: 7pt; text-transform: uppercase; letter-spacing: .12em;
  color: #444; font-weight: 700; margin-bottom: 1mm;
}
.label-pengirim { font-size: 8pt; line-height: 1.3; }

/* Blok penerima mengambil sisa ruang dan dicetak paling besar — ini satu-satunya
   bagian yang benar-benar dibaca kurir di jalan. */
.label-penerima-blok { flex: 1; border-bottom: 0; }
.label-penerima-nama { font-size: 14pt; font-weight: 700; line-height: 1.2; }
.label-penerima-hp { font-size: 11pt; font-weight: 700; margin: .6mm 0 1.2mm; }
.label-penerima-alamat { font-size: 10pt; line-height: 1.4; }

.label-bawah { border-top: 0.6mm solid #000; padding-top: 2mm; }
.label-kv { display: inline-block; margin-right: 4mm; font-size: 9pt; }
.label-kv b { font-size: 11pt; }
.label-awb { margin-top: 2mm; text-align: center; }
.label-awb svg { display: inline-block; }
.label-awb-kosong {
  font-size: 8pt; color: #666; border: 0.3mm dashed #999;
  padding: 3mm; border-radius: 1mm;
}

/* -- surat jalan ---------------------------------------------------------- */
.surat {
  width: 194mm; min-height: 270mm;
  margin: 0 auto 1.5rem; padding: 10mm;
  background: #fff; color: #000; box-sizing: border-box;
  font-size: 9.5pt; line-height: 1.45;
  border: 1px solid var(--border-strong); box-shadow: var(--e2);
  break-after: page; page-break-after: always;
}
.surat:last-child { break-after: auto; page-break-after: auto; }

.surat-kop {
  display: flex; justify-content: space-between; gap: 10mm;
  padding-bottom: 4mm; border-bottom: 0.6mm solid #000; margin-bottom: 5mm;
}
.surat-merek { font-size: 16pt; font-weight: 700; letter-spacing: -.02em; }
.surat-alamat { font-size: 8.5pt; line-height: 1.4; color: #333; margin-top: 1mm; }
.surat-judul { font-size: 13pt; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.surat-no { font-size: 11pt; font-weight: 700; }
.surat-tgl { font-size: 8.5pt; color: #333; }

.surat-pihak {
  display: grid; grid-template-columns: 1.4fr 1fr; gap: 8mm; margin-bottom: 5mm;
}

.surat-tabel { width: 100%; border-collapse: collapse; font-size: 9pt; }
.surat-tabel th, .surat-tabel td {
  border: 0.25mm solid #999; padding: 1.8mm 2mm; text-align: left; vertical-align: top;
}
.surat-tabel thead th {
  background: #eee; font-size: 8pt; text-transform: uppercase; letter-spacing: .05em;
  border-bottom-width: 0.5mm; color: #000;
}
.surat-tabel tfoot th { background: #f6f6f6; font-weight: 700; }
.surat-tabel .num { text-align: right; }

.surat-catatan {
  margin-top: 4mm; padding: 2.5mm 3mm; border-left: 0.8mm solid #000;
  background: #f7f7f7; font-size: 9pt;
}

.surat-ttd {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10mm;
  margin-top: 14mm; text-align: center; font-size: 8.5pt;
}
.surat-ttd-garis { border-bottom: 0.3mm solid #000; height: 16mm; margin-bottom: 1.5mm; }

.surat-kaki {
  margin-top: 8mm; padding-top: 3mm; border-top: 0.25mm solid #ccc;
  font-size: 7.5pt; color: #444; line-height: 1.5;
}

@media (max-width: 640px) {
  .label-wrap.a4 { grid-template-columns: 100mm; }
}

/* ==========================================================================
   Animasi masuk saat digulir
   --------------------------------------------------------------------------
   Elemen ber-[data-reveal] mulai transparan dan sedikit turun; app.js memasang
   IntersectionObserver yang menambahkan .in begitu elemen terlihat.

   Perhatikan selektor `.js` di depan: kelas itu dipasang app.js pada <html>
   saat berkasnya dieksekusi. Arah ini disengaja — bila app.js gagal dimuat,
   aturan di bawah tidak pernah berlaku dan seluruh konten tetap terlihat.
   Menulisnya terbalik (sembunyikan dulu, tampilkan lewat JS) berarti satu
   kegagalan memuat skrip menghasilkan halaman kosong.
   ========================================================================== */
.js [data-reveal] {
  opacity: 0; transform: translateY(22px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.js [data-reveal].in { opacity: 1; transform: none; }

/* Penundaan bertingkat untuk daftar kartu, supaya masuknya berurutan. */
.js [data-reveal][data-delay="1"] { transition-delay: 70ms; }
.js [data-reveal][data-delay="2"] { transition-delay: 140ms; }
.js [data-reveal][data-delay="3"] { transition-delay: 210ms; }
.js [data-reveal][data-delay="4"] { transition-delay: 280ms; }
.js [data-reveal][data-delay="5"] { transition-delay: 350ms; }

/* ==========================================================================
   Responsif
   ========================================================================== */
@media (max-width: 1000px) {
  .hero-in { grid-template-columns: 1fr; }
  .hero-art { display: none; }
  .shop-foot .cols { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  .shell { flex-direction: column; }
  .sidebar {
    width: 100%; flex: none; position: static; max-height: none;
    display: flex; flex-wrap: wrap; gap: .3rem;
    border-right: 0; border-bottom: 1px solid var(--border); padding: .7rem;
  }
  .sidebar a { flex: 0 0 auto; }
  .sidebar .group { display: none; }
  main { padding: 1.1rem 1rem 3rem; }
  .topbar { padding: 0 .8rem; gap: .55rem; }
  .topbar .who { display: none; }
  .shopbar .links { display: none; }
  .section { padding: 2.8rem 0; }
  .section-head h2 { font-size: 1.5rem; }
  .shop-foot .cols { grid-template-columns: 1fr; }
  .product-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: .9rem; }
  .fab { right: 1rem; bottom: 1rem; }
}

@media (max-width: 480px) {
  .wrap { padding: 0 .8rem; }
  .shopbar-in { gap: .5rem; height: 60px; }
  .shopbar .brand span { display: none; }
  .shop-body .btn.sm, .auth-page .btn.sm {
    padding: .35rem .55rem; font-size: .66rem; letter-spacing: .04em;
  }
}

/* ==========================================================================
   Gerak yang dikurangi & cetak
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
  .product-card:hover { transform: none; }
  .product-quick { opacity: 1; transform: none; }
}

@media print {
  .topbar, .sidebar, .shopbar, .drawer, .drawer-scrim, .fab, .toast-wrap, .pwa-banner,
  button, .btn, .no-print { display: none !important; }
  body { background: #fff; }
  main { padding: 0; }
  .card, .stat { box-shadow: none; border-color: #ccc; break-inside: avoid; }

  /* -------------------------------------------------- dokumen pengiriman
     Latar dan garis pada label/surat jalan bukan hiasan: kepala tabel abu-abu
     dan garis tebal pemisah adalah penanda yang dibaca petugas sekilas.
     Tanpa print-color-adjust, peramban membuang seluruh latar demi menghemat
     tinta dan dokumennya kehilangan strukturnya. */
  .cetak-body { background: #fff; }
  .cetak-body * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  #lembar { padding: 0; }

  .ship-label, .surat {
    border: 0 !important;
    box-shadow: none !important;
    margin: 0 auto;
  }

  /* Mode termal: satu label memenuhi satu halaman 100×150 mm tanpa margin. */
  .cetak-body[data-ukuran="termal"] .label-wrap { display: block; }
  .cetak-body[data-ukuran="termal"] .ship-label {
    width: 100mm; height: 150mm;
    break-after: page; page-break-after: always;
  }
  .cetak-body[data-ukuran="termal"] .ship-label:last-child {
    break-after: auto; page-break-after: auto;
  }

  /* Mode A4: dua label per halaman, tetap 100×150 mm supaya bisa digunting
     dan ditempel tanpa penyesuaian. */
  .cetak-body[data-ukuran="a4"] .label-wrap {
    display: grid; grid-template-columns: repeat(2, 100mm);
    justify-content: center; gap: 4mm;
  }

  .surat { width: auto; min-height: 0; padding: 0; }
}
