Fitur lengkap: - Auth JWT + RBAC (Admin/Teacher) + halaman login - Shell 3 kolom (left nav, topbar, right rail dashboard) - CRUD siswa + follow up kanban + status calon/student/ex - Dashboard: siswa aktif, kehadiran, bar sumber lead, perlu follow up - Pembayaran prorata per pertemuan (cash/transfer/qris) - Kelas, enrollment, generate sesi, kehadiran bulk - Jurnal aktivitas + upload multi-foto - Raport + placement test (tampil di detail siswa) - Pengaturan & seed data contoh Stack: Next.js 16, TypeScript, Tailwind v4, Prisma (SQLite), Recharts, Zod
22 KiB
DESIGN.md — Kodeva Design System
Panduan visual & UX untuk Kodeva. Tema: Colorful · Ed-Tech · Playful · Rapi (bukan childish). Bayangkan antarmuka produk SaaS modern untuk akademi coding — ceria, berenergi, tapi tetap kredibel dan enak dipakai kerja 8 jam.
1. Brand & Personality
| Atribut | Nilai |
|---|---|
| Nama | Kodeva |
| Tagline | "Kelola kelas coding, tumbuhkan pembuat masa depan." |
| Karakter | Ceria, cerdas, hangat, terpercaya, sedikit jenaka |
| Bukan | Kaku korporat, norak, kekanak-kanakan (tanpa kartun balita / font comic) |
| Metafora | Papan tulis digital yang penuh warna, blok kode berwarna, sticky notes |
Referensi rasa: Linear (kerapian) × Duolingo (keceriaan) × Notion (keruang) × Figma (warna).
2. Design Principles
- Warna membawa makna, bukan sekadar hiasan. Tiap warna punya peran semantik (status, sumber lead, kehadiran). Konsisten di seluruh app.
- Playful lewat bentuk & gerak, bukan lewat font kekanak-kanakan. Sudut membulat, gradient halus, blob dekoratif tipis, micro-animation.
- Data dulu. Angka penting (perlu follow up, siswa aktif) langsung terlihat tanpa klik.
- Satu layar, satu fokus. Hierarki jelas: judul → aksi utama → konten → detail.
- Hangat & manusiawi. Foto profil bulat, sapaan personal ("Hai, Sari 👋"), bahasa Indonesia santai-profesional.
3. Color System
3.1 Brand Palette
| Token | Hex | Preview | Pemakaian |
|---|---|---|---|
--brand-50 |
#F2EFFE |
🟪 | background lembut |
--brand-100 |
#E4DEFD |
🟪 | chip, hover |
--brand-300 |
#B9A9FB |
🟪 | border aktif |
--brand-500 |
#7C5CFC |
🟪 | primary, tombol, ikon aktif |
--brand-600 |
#6A46EF |
🟪 | hover primary |
--brand-700 |
#5533CE |
🟪 | pressed / teks di bg terang |
3.2 Accent & Semantic
| Token | Hex | Makna |
|---|---|---|
--coral-500 |
#FF7A59 |
aksi sekunder, highlight, CTA promo |
--amber-500 |
#FFB020 |
warning, CALON_STUDENT, banner |
--mint-500 |
#12B886 |
success, STUDENT aktif, hadir |
--sky-500 |
#2AA9FF |
info, social media, link |
--pink-500 |
#F65FA7 |
aksen dekoratif, tag kreatif |
--danger-500 |
#F04438 |
error, alpa, hapus |
--violet-soft |
#A78BFA |
grafik pelengkap |
3.3 Neutral
| Token | Hex | Pemakaian |
|---|---|---|
--ink-900 |
#131A2B |
teks utama, heading |
--ink-700 |
#3A4560 |
teks sekunder |
--ink-500 |
#6B7590 |
placeholder, caption |
--ink-300 |
#C4CAD8 |
border |
--ink-100 |
#EEF1F7 |
divider, bg hover |
--surface |
#FFFFFF |
kartu |
--canvas |
#F7F8FC |
background halaman |
--canvas-tint |
linear-gradient(180deg,#F7F8FC 0%,#F1F0FE 100%) | background app |
3.4 Gradient (signature)
--grad-primary: linear-gradient(135deg, #7C5CFC 0%, #2AA9FF 100%); /* tombol utama, hero */
--grad-coral: linear-gradient(135deg, #FF7A59 0%, #FFB020 100%); /* kartu highlight */
--grad-mint: linear-gradient(135deg, #12B886 0%, #2AA9FF 100%); /* stat positif */
--grad-pink: linear-gradient(135deg, #F65FA7 0%, #7C5CFC 100%); /* dekorasi */
Gunakan gradient hanya untuk: tombol primary, avatar ring, header kartu statistik, dan 1 blob dekoratif per halaman. Jangan gradient di teks panjang.
3.5 Warna Mapping Semantik (WAJIB konsisten)
Status Siswa
| Status | Warna | Badge |
|---|---|---|
CALON_STUDENT |
Amber #FFB020 |
bg #FFF4E0, teks #9A6100 |
STUDENT |
Mint #12B886 |
bg #E4F8F1, teks #0A7A58 |
EX_STUDENT |
Slate #6B7590 |
bg #EEF1F7, teks #4A5470 |
Sumber Lead (dipakai di bar chart & chip)
| Sumber | Warna | Ikon |
|---|---|---|
WHATSAPP |
#22C55E |
MessageCircle |
REFERRAL |
#7C5CFC |
Users |
BANNER |
#FFB020 |
Flag |
SOCIAL_MEDIA |
#2AA9FF |
Instagram |
Kehadiran
| Status | Warna | Label |
|---|---|---|
PRESENT |
Mint #12B886 |
Hadir |
LATE |
Amber #FFB020 |
Terlambat |
EXCUSED |
Sky #2AA9FF |
Izin |
SICK |
Violet #A78BFA |
Sakit |
ABSENT |
Danger #F04438 |
Alpa |
Follow Up : NEW #94A3B8 · CONTACTED #2AA9FF · TRIAL #7C5CFC · OFFER_SENT #FFB020 · ENROLLED #12B886 · LOST #F04438
Metode Bayar : CASH #12B886 · TRANSFER #2AA9FF · QRIS #7C5CFC
4. Typography
| Peran | Font | Weight | Size |
|---|---|---|---|
| Display / H1 | Plus Jakarta Sans | 800 | 30–36px, tracking -0.02em |
| H2 | Plus Jakarta Sans | 700 | 24px |
| H3 / Card title | Plus Jakarta Sans | 600 | 18px |
| Body | Inter | 400/500 | 14–15px, line-height 1.6 |
| Caption / label | Inter | 500 | 12–13px, tracking 0.01em |
| Angka dashboard | Sora | 700 | 28–32px, tabular-nums |
| Kode / invoice | JetBrains Mono | 500 | 13px |
font-display : "Plus Jakarta Sans", Inter, system-ui, sans-serif
font-body : "Inter", system-ui, sans-serif
font-num : "Sora", Inter, sans-serif
font-mono : "JetBrains Mono", ui-monospace, monospace
Aturan: heading selalu gelap (--ink-900), jangan pakai warna brand untuk heading panjang. Warna brand untuk aksen kata (mis. "3 siswa perlu follow up").
5. Spacing · Radius · Shadow
- Spacing scale: 4 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 48 · 64 (kelipatan 4).
- Radius:
sm 8px(input kecil) ·md 12px(button, input) ·lg 16px(dropdown) ·xl 20px(card) ·2xl 24px(panel besar) ·full(pill, avatar). - Shadow:
--shadow-xs: 0 1px 2px rgba(19,26,43,.06);
--shadow-sm: 0 2px 8px rgba(19,26,43,.06);
--shadow-md: 0 8px 24px rgba(19,26,43,.08);
--shadow-lg: 0 16px 40px rgba(19,26,43,.10);
--shadow-brand: 0 8px 20px rgba(124,92,252,.28); /* tombol primary */
- Border: 1px
--ink-100; kartu aktif 1.5px--brand-300. - Focus ring:
0 0 0 3px rgba(124,92,252,.28).
6. Iconography & Illustration
- Ikon:
lucide-react, stroke 2, ukuran 18/20/24. Selalu dalam container bulat saat jadi aksi. - Ilustrasi/dekorasi: bentuk blob, lingkaran, blok kode melayang — opacity 6–12%, gradient brand. Maksimal 1–2 elemen per halaman, jangan menghalangi konten.
- Avatar: bulat penuh, ukuran 32/40/56/96px, ring gradient
--grad-primaryuntuk siswa aktif. - Emoji: boleh untuk sapaan & empty state yang ramah, maksimal 1 per layar. Jangan di tombol/heading formal.
7. Layout & Navigasi
7.1 Shell Desktop (≥1280px) — 3 kolom
┌──────────────┬────────────────────────────────────────────┬───────────────────────┐
│ LEFT NAV │ MAIN CONTENT │ RIGHT RAIL │
│ 248px │ flex-1 (min 640px) │ 340px (sticky) │
│ │ │ │
│ ✦ Kodeva │ Topbar: breadcrumb · search · +Aksi · 🔔 │ ┌─────────────────┐ │
│ │ │ │ Siswa Aktif 128│ │
│ ▸ Dashboard │ ┌──────────────────────────────────────┐ │ ├─────────────────┤ │
│ ▸ Follow Up │ │ Konten halaman / tabel / kanban │ │ │ Perlu Follow 12 │ │
│ (12) 🔴 │ │ │ │ ├─────────────────┤ │
│ ▸ Siswa │ │ │ │ │ Ex Student 7 │ │
│ ▸ Kelas │ │ │ │ └─────────────────┘ │
│ ▸ Kehadiran │ └──────────────────────────────────────┘ │ ┌─────────────────┐ │
│ ▸ Pembayaran│ │ │ Kehadiran (donut)│ │
│ ▸ Jurnal │ │ └─────────────────┘ │
│ ▸ Raport │ │ ┌─────────────────┐ │
│ ▸ Placement │ │ │ Siswa Aktif (line)│ │
│ ▸ Pengaturan│ │ └─────────────────┘ │
│ │ │ ┌─────────────────┐ │
│ 👤 Sari W. │ │ │ Sumber Lead (bar)│ │
│ Admin │ │ └─────────────────┘ │
└──────────────┴────────────────────────────────────────────┴───────────────────────┘
- Left nav: background
--surface, lebar 248px, item aktif = pill gradient brand dengan teks putih +--shadow-brand. Badge angka merah untuk follow up due. Dapat collapse jadi 72px (ikon saja). - Right rail ("Insight Panel"): hanya muncul penuh di Dashboard; di halaman lain bisa dibuka lewat tombol toggle (
PanelRight), default tersembunyi agar konten lega. Sticky, scroll independen, tiap widget = karturadius xl. - Topbar: tinggi 64px, sticky, blur backdrop
rgba(247,248,252,.8).
7.2 Breakpoint
| Breakpoint | Perilaku |
|---|---|
≥1440px |
3 kolom penuh, rail 340px |
1280–1439px |
3 kolom, rail 300px |
1024–1279px |
rail jadi drawer kanan (default tutup) |
768–1023px |
left nav collapse ikon; rail drawer |
<768px |
bottom nav 5 item utama; tabel → kartu; rail = sheet |
7.3 Bottom Nav (mobile)
Dashboard · Siswa · Follow Up · Kelas · Lainnya
8. Komponen
8.1 Tombol
| Varian | Style |
|---|---|
| Primary | --grad-primary, teks putih, radius md, --shadow-brand, hover naik 1px |
| Secondary | bg --brand-50, teks --brand-700 |
| Outline | border --ink-300, teks --ink-900 |
| Ghost | transparan, hover --ink-100 |
| Danger | bg #F04438, teks putih |
| Pill/Chip | radius full, padding 6×12 |
Ukuran: sm 32px · md 40px · lg 48px. Sertakan ikon kiri untuk aksi utama.
8.2 Kartu
- Stat Card: ikon bulat gradient + label caption + angka besar (
font-num) + delta (+8%mint /-3%coral). Tinggi 112px. - Content Card: header (judul + aksi "Lihat semua") + body + padding 20–24px.
- Student Card: avatar + nama + badge status + chip sumber + info kelas; hover shadow-md, cursor pointer.
- Class Card: strip warna kelas di kiri, nama, level chip, guru,
6/12 siswaprogress bar, jadwal.
8.3 Form
- Label di atas, 13px
--ink-700, wajib ada*coral untuk required. - Input tinggi 40px, radius md, border
--ink-300, fokus ring brand. - Upload foto profil: dropzone lingkaran dengan preview + tombol kamera; maks 5MB, JPG/PNG/WebP.
- Pilihan sumber lead & status: segmented control berikon (bukan select biasa) agar playful.
- Validasi inline: border danger + pesan 12px di bawah field.
8.4 Badge & Chip
- Status siswa pakai badge pill (dot + label).
- Sumber lead pakai chip berikon dengan warna mapping §3.5.
- Level kelas: Beginner (mint), Intermediate (sky), Advanced (violet).
8.5 Tabel
Header --ink-100, teks uppercase 12px --ink-500. Baris hover --brand-50/50, tinggi 56px. Kolom aksi sticky kanan. Di mobile berubah jadi kartu bertumpuk.
8.6 Kanban Follow Up
Kolom berisi header warna status + count + total value; kartu bisa drag (dnd-kit), sudut membulat, tampilkan avatar, sumber, "due 2 hari lalu" merah.
8.7 Empty · Loading · Error
- Empty: ilustrasi blob + judul ramah ("Belum ada calon siswa nih") + CTA.
- Loading: skeleton shimmer bentuk sama dengan konten, bukan spinner penuh layar.
- Error: kartu coral lembut + pesan jelas + tombol "Coba lagi".
9. Charts & Data Viz
Semua chart pakai Recharts, tinggi 180–220px di rail, kartu putih, grid horizontal tipis --ink-100, tanpa garis sumbu Y penuh.
| Chart | Tipe | Warna | Isi |
|---|---|---|---|
| Siswa Aktif | Area/donut mini | --grad-primary |
Tren 6 bulan; angka besar di tengah |
| Kehadiran | Donut / radial | PRESENT mint, LATE amber, ABSENT danger | % kehadiran hari ini + ring |
| Sumber Lead | Bar horizontal | mapping §3.5 | Jumlah per WhatsApp/Referral/Banner/Social |
| Siswa per Kelas | Bar vertikal | --violet-soft |
Kapasitas terpakai |
| Pendapatan | Line/area | --mint-500 |
Opsional di halaman pembayaran |
Aturan chart:
- Tooltip rounded, shadow-md, label Bahasa Indonesia.
- Angka
font-num, animasi masuk 400ms ease-out. - Selalu sediakan legend berwarna + label teks (jangan andalkan warna saja).
- Bar chart sumber lead: tampilkan angka di ujung bar.
9.1 Right Rail Widgets (Dashboard)
- Stat stack: Siswa Aktif · Perlu Follow Up · Ex Student (3 kartu mini).
- Kehadiran Hari Ini: donut +
86%+ rincian Hadir/Terlambat/Alpa. - Tren Siswa Aktif: area chart 6 bulan.
- Sumber Lead: bar chart 4 kategori.
- Perlu Follow Up Hari Ini: list 4 nama + tombol WhatsApp; link "Lihat semua".
- Kelas Hari Ini: sesi + jam + guru.
10. Spesifikasi Halaman
10.1 Dashboard
Hero sapaan + 4 stat card besar (Siswa Aktif, Perlu Follow Up, Ex Student, Kehadiran %). Bawahnya: grafik Tren Siswa Aktif & Sumber Lead (2 kolom). Right rail = widget §9.1.
10.2 Halaman Siswa (list)
- Filter segmented: Semua · Calon Student · Student · Ex Student.
- Search nama/email/telepon, filter sumber lead, filter kelas.
- Toggle tampilan tabel ⇄ kartu.
- Tombol "+ Tambah Siswa" primary.
- Kolom: Siswa (avatar+nama+email) · Telepon · Orang Tua · Kelas · Sumber · Status · Aksi.
10.3 Form Tambah/Edit Siswa
Grid 2 kolom:
- Kiri: Foto profil (dropzone), Nama lengkap*, No. telepon*, Email, Nama orang tua, No. telepon orang tua, Tanggal lahir, Gender.
- Kanan: Tahu dari mana* (segmented: WhatsApp/Referral/Banner/Social Media), Status* (segmented: Calon/Student/Ex), Pilih Kelas (multi-select, hanya aktif bila status Student), Catatan.
- Sticky footer: Batal · Simpan.
10.4 Detail Siswa
Header profil: avatar besar ring gradient, nama, badge status, chip sumber, tombol WhatsApp/Call/Edit. Tab: Ringkasan · Kelas & Kehadiran · Pembayaran · Placement Test · Raport · Jurnal.
- Placement Test selalu tampil sebagai kartu: level hasil, skor per kategori (bar), rekomendasi kelas, tanggal, pemeriksa.
- Pembayaran: ringkasan prorata —
Kuota 10 sesi · Terpakai 6 · Sisa 4 · Nilai sisa Rp 800.000.
10.5 Kelas (CRUD)
Grid kartu kelas dengan strip warna + progress kapasitas. Form: nama, kode, level, guru, total pertemuan, harga paket, kapasitas, jadwal, warna, status. Preview Rp per pertemuan otomatis saat mengisi harga & jumlah pertemuan.
10.6 Kehadiran
Pilih kelas → pilih pertemuan → daftar siswa dengan tombol status (segmented H/T/I/S/A) + tombol "Hadir Semua". Progress "12/12 terisi". Simpan.
10.7 Pembayaran
Form: pilih siswa → pilih kelas (auto ambil harga) → jumlah pertemuan dibayar (stepper) → tampil kalkulasi prorata besar: 10 × Rp 200.000 = Rp 2.000.000 → metode (Cash/Transfer/QRIS segmented) → tanggal → upload bukti (opsional). List pembayaran: invoice mono, siswa, kelas, sesi, nominal, metode chip, status.
10.8 Jurnal Aktivitas
Feed masonry/card: cover foto, judul, kelas, tanggal, tag, author, jumlah siswa. Tombol "+ Buat Jurnal": upload multi-foto (drag reorder), judul, deskripsi, kelas, sesi, tag, tandai siswa yang terlibat.
10.9 Raport
Pilih kelas → pilih siswa → form aspek penilaian (slider/input 0–100): Logika, Computational Thinking, Problem Solving, Kreativitas, Kolaborasi → kesimpulan guru, grade otomatis, ringkasan kehadiran. Preview raport bertema (header gradient, tanda tangan guru).
10.10 Placement Test
Form: siswa, tanggal, pemeriksa, skor kategori (bar input), level hasil otomatis dari rata-rata + rekomendasi kelas. Riwayat list.
10.11 Pengaturan
Sumber lead (label + warna + aktif), daftar guru/user, info akademi (nama, logo, alamat, kontak), preferensi (mata uang, timezone).
11. Motion
| Aksi | Durasi | Easing |
|---|---|---|
| Hover kartu/tombol | 150ms | ease-out |
| Masuk halaman (fade+up 8px) | 250ms | cubic-bezier(.2,.8,.2,1) |
| Chart render | 400ms | ease-out |
| Drawer/sheet | 240ms | cubic-bezier(.2,.8,.2,1) |
| Konfeti saat siswa enroll 🎉 | 800ms | sekali, opsional |
Hormati prefers-reduced-motion: matikan animasi non-esensial.
12. Aksesibilitas
- Kontras teks minimal AA (4.5:1 body, 3:1 besar). Jangan taruh teks putih di amber/kuning.
- Fokus terlihat di semua elemen interaktif (ring brand).
- Jangan sampaikan status hanya lewat warna — selalu ada label/ikon.
- Semua input punya
<label>; ikon-only button punyaaria-label. - Target sentuh ≥ 44×44px di mobile.
- Chart punya ringkasan teks/table alternatif.
13. Design Tokens (CSS)
:root {
/* brand */
--brand-50:#F2EFFE; --brand-100:#E4DEFD; --brand-300:#B9A9FB;
--brand-500:#7C5CFC; --brand-600:#6A46EF; --brand-700:#5533CE;
/* accent */
--coral-500:#FF7A59; --amber-500:#FFB020; --mint-500:#12B886;
--sky-500:#2AA9FF; --pink-500:#F65FA7; --danger-500:#F04438; --violet-soft:#A78BFA;
/* neutral */
--ink-900:#131A2B; --ink-700:#3A4560; --ink-500:#6B7590;
--ink-300:#C4CAD8; --ink-100:#EEF1F7; --surface:#FFFFFF; --canvas:#F7F8FC;
/* gradients */
--grad-primary:linear-gradient(135deg,#7C5CFC 0%,#2AA9FF 100%);
--grad-coral:linear-gradient(135deg,#FF7A59 0%,#FFB020 100%);
--grad-mint:linear-gradient(135deg,#12B886 0%,#2AA9FF 100%);
--grad-pink:linear-gradient(135deg,#F65FA7 0%,#7C5CFC 100%);
/* radius */
--r-sm:8px; --r-md:12px; --r-lg:16px; --r-xl:20px; --r-2xl:24px; --r-full:9999px;
/* shadow */
--shadow-xs:0 1px 2px rgba(19,26,43,.06);
--shadow-sm:0 2px 8px rgba(19,26,43,.06);
--shadow-md:0 8px 24px rgba(19,26,43,.08);
--shadow-lg:0 16px 40px rgba(19,26,43,.10);
--shadow-brand:0 8px 20px rgba(124,92,252,.28);
/* font */
--font-display:"Plus Jakarta Sans",Inter,system-ui,sans-serif;
--font-body:"Inter",system-ui,sans-serif;
--font-num:"Sora",Inter,sans-serif;
--font-mono:"JetBrains Mono",ui-monospace,monospace;
/* layout */
--nav-w:248px; --rail-w:340px; --topbar-h:64px;
}
14. Contoh Konten & Data untuk UI
Data grafik right rail (contoh):
{
"activeStudents": 128,
"activeStudentsDelta": "+8%",
"followUpDue": 12,
"exStudents": 7,
"attendanceToday": { "present": 34, "late": 4, "absent": 3, "rate": 86 },
"activeTrend": [
{ "month": "Apr", "value": 92 }, { "month": "Mei", "value": 101 },
{ "month": "Jun", "value": 97 }, { "month": "Jul", "value": 110 },
{ "month": "Agu", "value": 119 }, { "month": "Sep", "value": 128 }
],
"leadSources": [
{ "source": "WhatsApp", "value": 58 },
{ "source": "Referral", "value": 34 },
{ "source": "Banner", "value": 21 },
{ "source": "Social Media", "value": 15 }
]
}
Kelas:
| Kelas | Level | Guru | Sesi | Harga | Rp/Sesi | Warna |
|---|---|---|---|---|---|---|
| Scratch Junior | Beginner | Rina Kartika | 8 | Rp 1.200.000 | Rp 150.000 | #2AA9FF |
| Python Dasar | Beginner | Budi Santoso | 10 | Rp 2.000.000 | Rp 200.000 | #7C5CFC |
| Web Dev: HTML & CSS | Beginner | Ahmad Fauzi | 12 | Rp 2.400.000 | Rp 200.000 | #12B886 |
| JavaScript Intermediate | Intermediate | Budi Santoso | 10 | Rp 2.500.000 | Rp 250.000 | #FFB020 |
| Arduino & Robotics | Intermediate | Rina Kartika | 8 | Rp 1.800.000 | Rp 225.000 | #F65FA7 |
Siswa (contoh tampilan):
| Nama | Orang Tua | Sumber | Status | Kelas |
|---|---|---|---|---|
| Andi Pratama | Budi Pratama | Referral | Student | Python Dasar |
| Citra Lestari | Sari Lestari | Calon Student | — | |
| Dimas Anggara | Hendra Anggara | Banner | Student | Scratch Junior |
| Elsa Maharani | Rina Maharani | Social Media | Calon Student | — |
| Fajar Nugroho | Agus Nugroho | Student | Web Dev | |
| Gita Permata | Dwi Permata | Referral | Ex Student | JavaScript |
| Hadi Susanto | Tono Susanto | Social Media | Student | Arduino |
| Intan Puspita | Maya Puspita | Banner | Calon Student | — |
| Joko Wijaya | Slamet Wijaya | Student | Python Dasar | |
| Kirana Dewi | Ratna Dewi | Referral | Ex Student | Scratch Junior |
Jurnal contoh: "Membuat Game Ular dengan Scratch" · Scratch Junior · tag game, scratch, logika · 6 siswa · 4 foto.
Raport contoh: Andi Pratama · Python Dasar · Logika 88 · Computational Thinking 85 · Problem Solving 82 · Kreativitas 90 · Kolaborasi 86 · Grade A.
Placement contoh: Elsa Maharani · total 78 · Level Intermediate · rekomendasi JavaScript Intermediate.
Microcopy (nada santai-profesional):
- Empty follow up: "Yeay, tidak ada follow up yang telat hari ini 🎉"
- Tombol: "Tambah Siswa", "Catat Pembayaran", "Simpan Jurnal", "Publish Raport"
- Konfirmasi prorata: "Siswa membayar Rp 2.000.000 untuk 10 pertemuan (Rp 200.000/pertemuan). Sisa kuota saat ini 4 pertemuan."
15. Checklist Desain untuk Setiap Halaman
- Pakai font & token warna dari dokumen ini (tidak ada hex baru).
- Ada state loading (skeleton), empty, error.
- Responsif 3 breakpoint besar (desktop / tablet / mobile).
- Kontras AA & fokus terlihat.
- Angka uang pakai
formatIDR+font-num. - Status/lead memakai warna mapping §3.5 + label teks.
- Right rail tersedia di Dashboard, toggle-able di halaman lain.
- Micro-animation halus & hormati
prefers-reduced-motion.