Pokémon · sv3-125
Charizard ex
Obsidian Flames
Rp 4.850.000
Keranjang Jastip · Sesi 1
Seluruh token dari DESIGN.md, dirender langsung dari tema Tailwind. Kalau ada yang tidak cocok dengan DESIGN.md, DESIGN.md yang benar dan tema yang harus diperbaiki.
Penamaan mengikuti Material Design 3. Pola on-X berarti warna konten di atas permukaan X — kalau memakai bg-primary, teksnya wajib text-on-primary. Jangan mengarang pasangan sendiri.
Aksi utama, state navigasi aktif, isi chart, momen brand. Kontras primary 6,7:1 di atas putih — aman jadi warna teks termasuk teks kecil.
#5f3add
primary
#ffffff
on-primary
#7857f8
primary-container
#fffbff
on-primary-container
#e6deff
primary-fixed
#cabeff
primary-fixed-dim
#1c0062
on-primary-fixed
#4918c8
on-primary-fixed-variant
#cabeff
inverse-primary
#613de0
surface-tint
Peran pendukung. Netral, tidak bersaing dengan primary.
#5e5e5e
secondary
#ffffff
on-secondary
#e2e2e2
secondary-container
#646464
on-secondary-container
#5a5c5f
tertiary
#ffffff
on-tertiary
#737477
tertiary-container
#fcfcff
on-tertiary-container
Tangga permukaan. lowest untuk kartu data, low untuk area yang sedikit tenggelam seperti isi input dan baris tabel bergaris.
#f9f9ff
background
#151c27
on-background
#f9f9ff
surface
#d3daea
surface-dim
#f9f9ff
surface-bright
#ffffff
surface-container-lowest
#f0f3ff
surface-container-low
#e7eefe
surface-container
#e2e8f8
surface-container-high
#dce2f3
surface-container-highest
#dce2f3
surface-variant
#151c27
on-surface
Teks utama + isian tombol gelap
#484555
on-surface-variant
Teks sekunder · 8,85:1 AAA
#2a313d
inverse-surface
#ebf1ff
inverse-on-surface
Garis pembatas 1px. Ini pengganti bayangan, bukan pelengkap.
#797587
outline
4,29:1 — GARIS SAJA, jangan untuk teks
#c9c4d8
outline-variant
Border standar 1px
success untuk lunas dan tren naik, warning untuk menunggu dan tenggat, error untuk gagal dan tren turun. Tidak ada warna aksen lain di luar ini.
#15803d
success
#ffffff
on-success
#d7f4e3
success-container
#04552a
on-success-container
#b45309
warning
#ffffff
on-warning
#fdeacd
warning-container
#6b3103
on-warning-container
#ba1a1a
error
#ffffff
on-error
#ffdad6
error-container
#93000a
on-error-container
Dua aturan yang paling sering dilanggar
outline #797587 kontrasnya 4,29:1 — cukup untuk garis, gagal untuk teks. Jangan pernah dipakai sebagai warna tulisan.Pakai utility type-* saat membangun halaman — itu menyetel ukuran, typeface, dan tabular figures sekaligus. Utility text-* bawaan hanya menyetel ukuran. type-label-caps sengaja tidak memaksa huruf besar: kode kartu sv3-125 harus tampil apa adanya. Untuk header kolom tabel, tambahkan kelas uppercase sendiri.
type-display-lg
Plus Jakarta Sans
32px / 40px · 700 · -0.02em · mobile 24px
Profit Bersih Bulan Ini
type-headline-md
Plus Jakarta Sans
24px / 32px · 600 · -0.01em · mobile 20px
Order Terbaru
type-title-sm
Plus Jakarta Sans
16px / 24px · 600
Charizard ex — Obsidian Flames
type-body-md
Inter
14px / 20px · 400
Badan antarmuka. Ini level yang paling banyak dipakai di seluruh sistem.
type-body-sm
Inter
12px / 18px · 400
Caption, teks bantuan di bawah field, dan metadata sekunder.
type-data-tabular
Inter
14px / 20px · 600 · tabular-nums
Rp 947.500.000 · Rp 111.111.111
type-metric-lg
Inter
30px / 36px · 700 · -0.02em · tabular-nums
Rp 947.500.000
type-label-caps
JetBrains Mono
11px / 16px · 500 · 0.05em
sv3-125 · KJ-1521 · 0O1l
Uji tabular figures: dua baris di bawah harus punya lebar yang sama persis. Kalau goyang, tabular-nums tidak aktif.
Rp 111.111.111
Rp 947.500.000
Jenjangnya bermakna: makin besar dan makin permanen sebuah elemen, makin besar radiusnya. Jangan menyeragamkan semuanya ke satu nilai.
rounded-sm
0.25rem · 4px
Checkbox, tag kecil
rounded
0.5rem · 8px
Tombol, input, dropdown
rounded-md
0.75rem · 12px
Kartu, panel, modal
rounded-lg
1rem · 16px
Panel besar
rounded-xl
1.5rem · 24px
Kontainer terluar
rounded-full
9999px
Badge, chip status, avatar
Semuanya kelipatan baseline 4px. Kerapatan sengaja tinggi — ini antarmuka padat data, dan whitespace berlebih memaksa scroll yang menyembunyikan angka.
xs
4px
Jarak terkecil, di dalam chip
sm
8px
Antar field yang berhubungan
md
16px
Padding standar dalam kartu
gutter
20px
Gutter grid
lg
24px
Antar section
xl
32px
Pemisah blok besar
container-max
1440px
Lebar maksimum area konten — dipakai halaman ini.
sidebar-width
240px
Sidebar kiri tetap di shell admin.
Datar dengan garis rambut. Kedalaman datang dari warna dan border 1px outline-variant, bukan dari bayangan. Arahkan kursor ke kartu kedua untuk melihat satu-satunya bayangan yang diizinkan.
Level 0
Latar
background #f9f9ff
Level 1
Permukaan + hover
surface-container-lowest, border 1px
Kartu kontras
Rp 947.500.000
Maksimal satu per layar. Tanpa bayangan sama sekali.
Pemetaan ini tetap. Tidak ada status kelima tanpa menambahkannya ke tabel di DESIGN.md terlebih dulu.
Yang ditampilkan di sini token warnanya saja. Komponen StatusChip yang memakainya ada di bagian Komponen di bawah.
Bagian dua
Semuanya ada di src/components/ui. Halaman berikutnya memakai komponen dari sini — jangan menyalin markup berulang antar halaman.
Border 1px outline-variant, padding 8px, body-md. Saat fokus, border berubah ke primary dengan cincin luar 2px primary beropasitas 10%.
Kode ditarik dari Pokémon TCG API.
Nomor harus diawali 628, bukan 08.
Ketik angkanya saja; titik pemisah muncul sendiri. Coba sisipkan digit di tengah — kursor tidak melompat.
Kartu memakai surface-container-lowest dengan border 1px outline-variant, radius 12px, padding 16px.
Level 1 — permukaan dengan garis rambut.
Kedalaman datang dari warna dan border, bukan bayangan.
Arahkan kursor ke sini.
Border sedikit menggelap plus bayangan ambient sangat tipis. Ini satu-satunya bayangan yang diizinkan.
StatusChip terkunci ke lima status di tabel DESIGN.md — menambah status keenam akan gagal saat compile, bukan diam-diam lolos dengan warna karangan. Label lain memakai Badge.
StatusChip
Badge caps
Badge biasa
DeltaBadge
Kenapa DeltaBadge punya prop `good` terpisah
Arah baik/buruk bergantung metrik, bukan tanda angka. Kenaikan “Order Belum Lunas” itu buruk dan harus merah meski angkanya naik. Logika ini ada di data, bukan di komponen.
Struktur tetap: label → angka → badge delta → sparkline → tautan detail, dengan ikon persegi membulat di kanan atas. Urutan ini tidak boleh diubah antar halaman.
Tanpa garis vertikal, hanya garis horizontal. Header label-caps, kolom nominal rata kanan dengan tabular figures, baris punya state hover. Perkecil jendela sampai di bawah 768px — tabel ini berubah jadi daftar kartu, bukan tabel yang digeser ke samping.
| Kartu | Set | Stok | Harga Jual | Status |
|---|---|---|---|---|
Charizard ex sv3-125 | Obsidian Flames | 12 pcs | Rp 4.500.000 | Tersedia |
Mewtwo GX sm3plus-082 | Shining Legends | 0 pcs | Rp 12.800.000 | Habis |
Monkey D. Luffy op05-119 | Awakening of the New Era | 3 pcs | Rp 2.150.000 | Tersedia |
Kartu produk untuk katalog publik. Badge tipe READY / PRE-ORDER wajib ada — kartu yang sama boleh muncul di kedua halaman dengan harga berbeda, dan badge inilah yang mencegah buyer bingung. Harga selalu rupiah penuh, tanpa singkatan.
Pokémon · sv3-125
Obsidian Flames
Rp 4.850.000
One Piece · op01-120
Romance Dawn
Rp 6.200.000
Pokémon · s6a-095
Eevee Heroes
Rp 18.500.000
Pokémon · sv2a-205
151
Rp 2.100.000
Dari kiri: stok normal, pre-order, sisa 1 dengan grading, dan habis (diredupkan). Gambar sengaja dikosongkan di sini supaya yang terlihat strukturnya, bukan fotonya.
Shell layout: sidebar kiri tetap 240px + top bar + area konten. Di bawah 768px sidebar jadi hamburger — tombolnya muncul di kiri judul, coba perkecil jendela lalu tekan tombolnya.
Theo
Super Admin
Area konten. Grid 12 kolom, lebar maksimum 1440px.
Tombol “Input Rekap” di sini gelap, bukan ungu. dashboard-desktop.png dan tambah-listing-desktop.png menampilkannya berbeda; DESIGN.md menang — aksi utama memakai isian on-surface.
Setiap tampilan yang mengambil data wajib punya tiga state ini. Skeleton, bukan spinner — skeleton menunjukkan bentuk yang akan datang, jadi layar tidak melompat saat data masuk.
Skeleton KPI
Skeleton tabel
Empty state
Dashboard baru bisa menghitung profit setelah trip pertama direkap.
Mengarahkan ke aksi berikutnya, bukan sekadar bertuliskan “Tidak ada data”.
Error state
Periksa koneksi lalu coba lagi. Kalau terus berulang, kabari admin.
Skeleton dasar