Standar desain
Aturan yang mengikat seluruh halaman di dalam aplikasi: warna, jarak, huruf, keadaan, dan gerak.
tools/check.py.Prinsip
Latar hampir putih, satu warna aksen, aksen hanya untuk hal yang benar-benar penting. Warna kedua dipakai untuk peringatan, bukan hiasan.
Dua halaman yang berbeda harus terlihat seperti dibuat orang yang sama. Kalau sebuah pola muncul dua kali, pola itu naik jadi komponen.
Jarak 16 px bukan "16 px", tapi --ck-space-4. Kalau skalanya berubah, seluruh aplikasi ikut berubah tanpa menyunting komponen.
Kosong, memuat, gagal, dan nonaktif adalah bagian dari desain — bukan keadaan darurat. Komponen tanpa keadaan itu belum selesai.
Warna
Warna punya peran, bukan selera. Pakai token sesuai perannya.
| Peran | Token | Dipakai untuk |
|---|---|---|
| Permukaan halaman | --ck-background | Latar halaman |
| Permukaan terangkat | --ck-card | Kartu, panel, topbar, sidebar |
| Teks utama | --ck-foreground | Judul dan isi |
| Teks sekunder | --ck-muted-foreground | Keterangan, label, metadata |
| Aksi utama | --ck-primary | Tombol utama, tautan aktif, penanda terpilih |
| Permukaan sekunder | --ck-secondary | Tombol sekunder, baris tersorot, latar isian |
| Aksen hangat | --ck-accent | Penanda kecil, sorotan, bukan tombol utama |
| Bahaya | --ck-destructive | Hapus, tindakan tak bisa dibatalkan |
| Peringatan | --ck-warning | Butuh perhatian, belum gagal |
| Berhasil | --ck-success | Selesai, benar, tuntas |
| Informasi | --ck-info | Keterangan netral |
- Warna hanya lewat
hsl(var(--ck-…)). Tidak ada nilai hex, tidak adargb()langsung. - Jangan memakai warna status sebagai teks di atas latar terang —
successdanwarningtidak lolos kontras sebagai teks (lihat Aksesibilitas). Pakai sebagai isian, atau pakai variansubtle. - Warna aksen tidak dipakai untuk tombol utama. Tombol utama selalu
primary. - Warna tidak boleh jadi satu-satunya pembawa makna — selalu ada teks atau ikon pendamping.
Jarak
Satu skala, kelipatan 4 px. Tidak ada nilai di luar daftar ini.
| Token | Nilai | Dipakai untuk |
|---|---|---|
| --ck-space-1 | 4 px | Antara ikon dan teks di dalam tombol kecil |
| --ck-space-2 | 8 px | Antar elemen yang berpasangan rapat |
| --ck-space-3 | 12 px | Bantalan dalam komponen kecil |
| --ck-space-4 | 16 px | Bantalan standar, jarak antar kartu |
| --ck-space-5 | 20 px | Bantalan kartu sedang |
| --ck-space-6 | 24 px | Bantalan kartu besar, jarak antar bagian |
| --ck-space-8 | 32 px | Jarak antar blok besar |
| --ck-space-12 | 48 px | Pemisah antar bagian halaman |
Utilitas siap pakai: ck-mt-4, ck-mb-6, ck-p-6, ck-py-4, ck-px-4, ck-gap-3. Semuanya memakai token di atas.
Tipografi
| Kelas | Ukuran | Pakai untuk |
|---|---|---|
| ck-h1 | 36 px | Judul halaman pemasaran/hero |
| ck-h2 | 30 px | Judul halaman di dalam aplikasi |
| ck-h3 | 24 px | Judul bagian |
| ck-h4 | 20 px | Judul sub-bagian |
| ck-lead | 18 px | Satu paragraf pengantar di bawah judul |
| ck-text | 16 px | Isi standar |
| ck-text-sm | 14 px | Label, tombol, isi tabel |
| ck-text-xs | 12 px | Metadata dan catatan |
| ck-overline | 11 px | Label kelompok huruf besar berspasi |
Bobot huruf hanya empat: 400 normal, 500 medium (label dan tombol), 600 semibold (judul kecil), 700 bold (judul besar). Jangan memakai bobot lain.
Radius & bayangan
| Radius | Nilai | Dipakai untuk |
|---|---|---|
| ck-radius-sm | 4 px | Lencana, penanda kecil |
| ck-radius-md | 8 px | Tombol, input, tautan sidebar |
| ck-radius-lg | 12 px | Kartu, modal |
| ck-radius-xl | 16 px | Panel besar, kartu pratinjau |
| ck-radius-full | penuh | Avatar, pil, sakelar |
| Bayangan | Dipakai untuk |
|---|---|
| ck-shadow-sm | Kartu diam, tombol utama |
| ck-shadow-md | Kartu yang bisa disinggahi |
| ck-shadow-lg | Dropdown, popover |
| ck-shadow-xl | Modal, laci |
Kaidahnya: semakin dekat ke pengguna, semakin dalam bayangannya. Permukaan datar tidak diberi bayangan.
Keadaan interaktif
Setiap elemen yang bisa disentuh wajib punya lima keadaan ini. Yang tidak punya dianggap belum selesai.
| Keadaan | Perubahan |
|---|---|
| Diam | Gaya dasar |
| Hover | Latar naik satu langkah (secondary atau primary-600) |
| Fokus papan ketik | Cincin outline: 2px solid hsl(var(--ck-ring)) dengan jarak 2 px. Tidak boleh dihilangkan |
| Aktif/terpilih | Latar primary, teks primary-foreground |
| Nonaktif | Opasitas turun, kursor not-allowed, tidak menerima klik |
| Memuat | Spinner + teks tetap ada, lebar tidak berubah (ck-btn--loading) |
Gerak
| Token | Durasi | Dipakai untuk |
|---|---|---|
| --ck-dur-fast | 120 ms | Warna, latar, sorot |
| --ck-dur | 200 ms | Buka-tutup, geser, laci |
| --ck-dur-slow | 500 ms | Masuknya panel besar |
Gerak hanya untuk menjelaskan perubahan, tidak untuk hiburan. Semua gerak wajib berhenti saat pengguna mengaktifkan prefers-reduced-motion.
Larangan
| Dilarang | Alasan |
|---|---|
| Nilai warna atau ukuran mentah di komponen | Mode gelap tidak ikut berubah; sistem terpecah |
!important | Menandakan konflik yang belum diselesaikan |
Gaya sebaris (style="…") untuk warna atau jarak | Tidak bisa diubah lewat token, tidak bisa diuji |
Selektor berdasarkan id atau struktur dalam (> 3 tingkat) | Rapuh; satu perubahan markup merusak gaya |
| Ikon tanpa teks untuk aksi merusak | Tidak jelas dan tidak terbaca pembaca layar |
Tombol tanpa type | Di dalam form, tombol tanpa type mengirim form |