/* Organic — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see readme.md. */
/* Font di-self-host lewat fonts.css (DESAIN.md 5.5) — @import ke Google Fonts
   dihapus supaya PWA tetap benar tanpa sinyal.

   PALET: monokrom (17 Agu 2026, permintaan pemilik). Palet krem/terakota/sage
   bawaan Organic diganti abu-abu murni — chroma nol, tanpa rona sama sekali.
   Struktur token TIDAK diubah: nama & jumlah langkah tetap sama, jadi seluruh
   komponen ikut menyesuaikan tanpa disentuh satu per satu.

   Karena rona hilang, status TIDAK boleh lagi dibedakan lewat warna saja.
   Pembeda dipindah ke BOBOT: isi pekat = butuh perhatian, isi tipis = aman,
   garis saja = belum terjadi. Lihat .tag-* dan .notif-* di app.css. */
@import url('fonts.css');

:root {
  --color-bg: #ffffff;
  --color-surface: #f2f2f2;
  --color-text: #121212;
  --color-accent: #121212;
  --color-accent-2: #6e6e6e;
  --color-divider: color-mix(in srgb, #000000 16%, transparent);

  /* Tonal ramps — abu-abu netral (chroma 0) pada tangga terang yang sama,
     jadi langkah yang sama di tiap peran punya bobot visual yang sama.
     600 adalah satu-satunya nilai "teks redup" — dipatok gelap supaya lolos
     4,5:1 bukan cuma di atas putih (5,3:1) tapi juga di atas --color-surface
     (4,8:1), karena label redup lebih sering duduk di dalam panel daripada
     di atas kertas putih. 500 ke bawah untuk garis saja, bukan teks. */
  --color-neutral-100: #f7f7f7;
  --color-neutral-200: #ededed;
  --color-neutral-300: #dedede;
  --color-neutral-400: #b8b8b8;
  --color-neutral-500: #949494;
  --color-neutral-600: #6b6b6b;
  --color-neutral-700: #565656;
  --color-neutral-800: #333333;
  --color-neutral-900: #000000;

  --color-accent-100: #f0f0f0;
  --color-accent-200: #e2e2e2;
  --color-accent-300: #c9c9c9;
  --color-accent-400: #a0a0a0;
  --color-accent-500: #6e6e6e;
  --color-accent-600: #3a3a3a;
  --color-accent-700: #262626;
  --color-accent-800: #1a1a1a;
  --color-accent-900: #0d0d0d;

  --color-accent-2-100: #f5f5f5;
  --color-accent-2-200: #e8e8e8;
  --color-accent-2-300: #d1d1d1;
  --color-accent-2-400: #ababab;
  --color-accent-2-500: #8a8a8a;
  --color-accent-2-600: #5e5e5e;
  --color-accent-2-700: #444444;
  --color-accent-2-800: #2b2b2b;
  --color-accent-2-900: #1a1a1a;

  /* SATU keluarga huruf untuk semuanya (17 Agu 2026, permintaan pemilik:
     judul Caprasimo susah dibaca). Caprasimo adalah huruf display bertangkai
     tebal — enak untuk satu nama merek besar, tapi jadi lambat dibaca begitu
     dipakai untuk judul panel, label, dan tombol yang jumlahnya puluhan per
     layar. Hierarki sekarang dibawa BERAT dan UKURAN, bukan pergantian huruf:
     judul Figtree 700, isi Figtree 400.

     Konsekuensi yang harus diingat: dulu --font-heading hanya punya satu berat,
     jadi rule yang menyetel font-family TANPA font-weight tetap terlihat benar.
     Sekarang tidak — setiap pemakai --font-heading wajib ikut menyetel
     --font-heading-weight, kalau tidak judulnya jadi setipis teks biasa. */
  --font-heading: "Figtree", system-ui, sans-serif;
  --font-heading-weight: 700;
  --font-body: "Figtree", system-ui, sans-serif;

  --space-1: 4.4px;
  --space-2: 8.8px;
  --space-3: 13.2px;
  --space-4: 17.6px;
  --space-6: 26.4px;
  --space-8: 35.2px;

  /* JARAK ANTAR PANEL vs JARAK DI DALAM PANEL — dua token terpisah, dan
     `--panel-gap` HARUS lebih besar dari `--panel-pad`.

     Dulu keduanya sama-sama `--space-4`: padding panel, jarak bar judul ke
     isinya, DAN jarak panel ke panel berikutnya semuanya 17,6px. Tak ada satu
     angka pun yang salah — yang salah adalah semuanya SAMA. Kalau jarak ANTAR
     kelompok setara jarak DI DALAM kelompok, mata tak punya dasar untuk
     memisahkan mana yang satu kesatuan; seluruh halaman terbaca sebagai satu
     blok padat. Itu sebabnya halaman terasa dempet meski tiap angkanya wajar.

     `--panel-pad` dipakai BERSAMA oleh padding panel, margin negatif bar judul,
     dan padding mendatar bar judul. Ketiganya wajib bergerak bareng: margin
     negatif yang tak sama dengan padding meninggalkan celah setipis rambut di
     tepi bar (sudah pernah terjadi), dan padding mendatar bar yang berbeda
     bikin teks judul tak lurus dengan isi di bawahnya. Satu token = tak bisa
     melenceng lagi. */
  --panel-pad: var(--space-6);
  --panel-gap: var(--space-8);

  /* Anggota KETIGA keluarga itu: jarak antar BLOK DI DALAM satu panel.
     Urutannya wajib menurun — antar panel (35,2) > padding panel (26,4) >
     antar blok (17,6) — supaya mata bisa membaca mana yang satu kesatuan.

     Token ini dulu tidak ada, dan akibatnya persis keluhan yang berulang:
     tiap template mengarang jaraknya sendiri lewat `style="margin-top:..."`
     (terhitung 154 kali di 60 berkas), jadi satu halaman bisa punya 13px,
     18px, dan 26px sekaligus — dan setiap blok baru yang lupa diberi inline
     style langsung menempel ke blok di atasnya. Sekarang jaraknya datang dari
     sistem (lihat aturan ritme di app.css); template tidak perlu memikirkannya
     lagi, dan yang lupa pun tetap benar. */
  --panel-ritme: var(--space-4);

  /* Dipotong separuh dari skala asli (sm 8/md 16/lg 28) atas permintaan
     pemilik — sudut dianggap terlalu bulat di seluruh app. Rasio antar token
     DIJAGA SAMA (masih 1:2:3,5) supaya elemen kecil tetap terasa lebih tajam
     dibanding elemen besar, bukan cuma semuanya diseragamkan kecil. Tombol/
     tag/badge/input TIDAK ikut berubah — itu `border-radius: 999px` (pil
     penuh, bukan turunan token ini), bentuknya memang disengaja bulat total
     terlepas dari skala sudut yang lain. */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  /* ── PENGECUALIAN warna, dua layar gudang saja ────────────────────────
     Aplikasi ini monokrom (chroma nol). Dua nilai di bawah adalah SATU-SATUNYA
     warna ber-rona, dipasang atas permintaan pemilik: layar Proses dan layar BS
     tertukar saat dipakai cepat di gudang.

     Namanya sengaja menyebut LAYAR, bukan makna (--warna-sukses/--warna-bahaya)
     supaya tidak ada yang tergoda memakainya sebagai penanda status. Status
     tetap dibedakan lewat bobot (lihat .tag-* di atas) — kalau status ikut
     berwarna, merah akan terbaca "bahaya" padahal itu identitas layar.

     Nilai redup sengaja lebih gelap dari --color-neutral-600: teks redup di
     atas latar merah muda jatuh ke ~4,4:1 dan gagal ambang 4,5:1. */
  --layar-proses-bg:    #f4fbf6;
  --layar-proses-panel: #e4f5e9;
  --layar-proses-redup: #5a5a5a;
  --layar-bs-bg:        #fff6f6;
  --layar-bs-panel:     #ffecec;
  --layar-bs-redup:     #5a5a5a;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 1px 2px color-mix(in srgb, #000000 12%, transparent);
  --shadow-md: 0 3px 10px color-mix(in srgb, #000000 14%, transparent);
  --shadow-lg: 0 12px 32px color-mix(in srgb, #000000 20%, transparent);
}

/* Di layar sempit ruangnya sendiri yang jadi barang langka, jadi lapang di
   desktop berubah jadi boros di ponsel. Diturunkan satu tingkat, TAPI selisih
   pad<gap tetap dijaga — itulah yang bikin kelompok terbaca, bukan besarnya.
   Cukup dua baris karena keduanya token: seluruh panel, bar judul, dan
   pratinjau ikut menyesuaikan tanpa satu pun aturan tambahan. */
@media (max-width: 680px) {
  :root {
    --panel-pad: var(--space-4); --panel-gap: var(--space-6);
    --panel-ritme: var(--space-3);
  }
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
h1, h2, h3, h4 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }

.washed{filter:saturate(0.6) contrast(0.85) brightness(1.1) opacity(0.94)}

/* ══════════════════════════════════════════════════════════════════════════
   Components — built with the tokens above. Plain CSS
   on plain HTML: no JavaScript, no build step. Each class is documented in
   readme.md and demonstrated in foundations/ and components/.
   ══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-size: 15px; line-height: 1.55; font-weight: 400; }
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.12; letter-spacing: -0.015em; margin: 0 0 var(--space-2);
}
h1 { font-size: 42px; }
h2 { font-size: 32px; }
h3 { font-size: 25px; }
h4 { font-size: 20px; }
h5 { font-size: 16px; }
h6 { font-size: 13px; }
h6 { letter-spacing: 0.08em; text-transform: uppercase; }
p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent); text-underline-offset: 3px; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: var(--color-neutral-600);
}
.text-muted { color: var(--color-neutral-600); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* — rules — */
.hr {
  height: 1px; border: 0; margin: var(--space-4) 0;
  background: var(--color-divider);
}

/* — buttons — */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  /* Berat 600, bukan --font-heading-weight (700): tombol adalah KONTROL, bukan
     judul. Pada teks 14px, 700 terbaca berteriak dan bersaing dengan judul
     panel di sekitarnya. Hurufnya tetap satu keluarga. */
  font-family: var(--font-heading); font-weight: 600;
  font-size: 14px; line-height: 1.2; color: var(--color-text); /* matches the .input's 14px —
     the pair sits side by side in sign-up rows */
  background: transparent; border: 1px solid transparent;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: var(--radius-md);
}
.btn svg { display: block; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--color-accent); color: var(--color-bg); }
.btn-primary:hover { background: var(--color-accent-600); }
.btn-primary:active { background: var(--color-accent-700); }
.btn-secondary { border-color: var(--color-divider); }
.btn-secondary:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
.btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
.btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
.btn-icon { width: 36px; height: 36px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); }

/* — forms — */
.field > label {
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.input {
  width: 100%; min-height: 36px; padding: 6px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
.input:hover { border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.input:focus-visible { border-color: var(--color-accent); outline-offset: 0; }
/* Kotak isian satu baris memang dibulatkan penuh (aturan pil di bagian bawah
   berkas ini). Textarea TIDAK ikut: sudut 999px pada kotak setinggi beberapa
   baris membuat tepi kiri-kanannya melengkung sepanjang isian — teksnya jadi
   terlihat tidak lurus dengan kotaknya, dan barisnya seperti masuk ke dalam
   lengkungan. Elemen besar memakai --radius-lg, ritme yang sama dengan panel
   dan kartu. Selektor ini (0,1,1) menang atas aturan pil `.input` (0,1,0)
   terlepas urutan berkas. */
textarea.input {
  min-height: 90px; resize: vertical;
  border-radius: var(--radius-lg);
}
.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.radio input, .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.radio .dot {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}
.radio:hover .dot { border-color: var(--color-accent); }
.radio input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}
.radio input:focus-visible + .dot { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.seg {
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
.seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; font-size: 13px; cursor: pointer;
}
.seg-opt + .seg-opt { border-left: 1px solid var(--color-divider); }
.seg-opt:has(input:checked) { background: var(--color-accent); color: var(--color-bg); }
.seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* — cards — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}
.card-kicker { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
.card-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; line-height: 1.2;
}
.card-body { margin: 0; font-size: 13px; opacity: 0.8; flex: 1; }
.card-meta {
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: var(--color-neutral-600);
}
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — tags — */
.tag {
  display: inline-flex; align-items: center; font-size: 11px;
  letter-spacing: 0.02em; padding: 3px 10px;
  border-radius: calc(var(--radius-md) * 0.75);
}
/* Monokrom: empat status dibedakan lewat BENTUK, bukan rona — isi pekat =
   butuh perhatian, isi tipis = sudah beres, garis kosong = belum terjadi,
   polos = sudah lewat. Di tabel padat ini justru lebih terbaca daripada
   versi berwarna: dulu "cocok" dan "selisih" sama nyaringnya, cuma beda
   rona; sekarang yang bermasalah memang yang paling menonjol. */
.tag-accent { background: var(--color-text); color: var(--color-bg); }
.tag-accent-2 { background: var(--color-neutral-200); color: var(--color-neutral-800); }
.tag-outline { border: 1px solid var(--color-neutral-400); color: var(--color-neutral-700); }
.tag-neutral { background: transparent; color: var(--color-neutral-600); padding-inline: 0; }

/* — navigation — */
.nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: none;
}
.nav-brand {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; margin-right: auto;
}
.nav a { color: inherit; text-decoration: none; font-size: 14px; }
.nav a:hover, .nav a[aria-current='page'] { color: var(--color-accent); }

/* — tables — */
/* display:block + overflow-x:auto membuat TABEL ITU SENDIRI jadi wadah gulir —
   tanpa perlu bungkus <div> di sekitar 90-an titik pakainya di seluruh app.
   Diverifikasi tak merusak apa pun: kolom thead/tbody tetap sinkron sempurna
   (browser tetap membentuk satu kotak tabel anonim yang menaungi thead+tbody),
   dan tabel yang dipakai sbg flex item (mis. kolom Aset|Kewajiban berdampingan
   di Neraca) tetap diperlakukan sbg flex item — blockify tidak melepas
   keanggotaan flex-nya. Sebelum ini, tabel lebar di layar sempit mendorong
   SELURUH halaman melebar (bukan cuma dirinya sendiri): panel-nya jadi
   kepotong (background pendek, tulisan lanjut keluar) dan viewport mobile
   ikut melebar mengikuti kontennya. Nota/invoice cetak DIKECUALIKAN di bawah —
   kertas tidak punya scrollbar, jadi harus tetap tabel penuh apa adanya. */
/* Di layar lega tabel HARUS `display: table` supaya algoritma lebar-kolom
   browser jalan dan isinya benar-benar memenuhi panel. `display: block` bikin
   browser membungkus thead/tbody dalam kotak tabel ANONIM yang menyusut ke isi
   (width:100% menempel di kotak block terluar, bukan di kotak anonim itu) —
   gejalanya whitespace menganga DI DALAM panel; terukur 161px di Daftar PO.
   Kotak-gulir hanya dinyalakan di layar sempit (<=900px), tempat masalah yang
   dulu ditambal F16 sungguh terjadi: di sana tabel LEBIH LEBAR dari wadahnya,
   jadi menyusut-ke-isi tak pernah kejadian dan viewport tak ikut melebar. */
.table { display: table; width: 100%; border-collapse: collapse; font-size: 14px; }
@media (max-width: 900px) { .table { display: block; overflow-x: auto; } }
.table th {
  text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-neutral-600);
  padding: var(--space-2); border-bottom: 1px solid var(--color-divider);
}
.table td {
  padding: var(--space-2);
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent);
}
.table tbody tr:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }
@media print {
  /* Kertas tak bisa digulir — konten yang "aman" karena bisa discroll di
     layar akan KEPOTONG kalau tetap overflow:auto saat dicetak. Nota/struk/
     invoice harus kembali jadi tabel biasa yang melebar apa adanya. */
  .table { display: table; overflow-x: visible; }
}

/* — dialog — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}
.dialog {
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}
.dialog-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px;
}
.dialog-body { font-size: 14px; opacity: 0.85; }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

/* — rounded frame: everything softens, small controls go pill — */
.card, .dialog { border-radius: calc(var(--radius-lg) * 1.15); }
.btn, .tag, .seg, .input { border-radius: 999px; }
.input { padding-inline: 14px; }

