# Buku Kasir — Panduan Gaya Visual (Style Guide)

> **URL resmi:** https://styleguide.bukukasir.biz.id
> **Dokumen machine-readable ini** menjadi acuan utama untuk menjaga konsistensi tampilan di seluruh fitur platform Buku Kasir (bukukasir.biz.id), termasuk dashboard analytics, superadmin dashboard, dan platform baru lainnya. AI/agent dapat membaca file ini langsung tanpa perlu crawl website.
>
> Framework acuan: **Vue 3 + TypeScript + Vite + Tailwind CSS v4** (CSS-first, tanpa `tailwind.config.js`).

---

## 1. CSS Framework

**Tailwind CSS v4** — CSS-first configuration. Semua styling via utility classes di Vue template.

```ts
// frontend/package.json
"tailwindcss": "^4.3.2",
"@tailwindcss/vite": "^4.3.2"
```

```css
/* frontend/src/style.css */
@import "tailwindcss";
```

---

## 2. Palet Warna

> **Aturan emas:** Jangan perkenalkan warna baru tanpa persetujuan. Gunakan teal sebagai primary, slate sebagai neutral, emerald/red/amber sebagai semantik.

### 2.1 Warna Primer — Teal

| Token        | Hex       | RGB                          | Penggunaan                                                    |
|-------------|-----------|------------------------------|----------------------------------------------------------------|
| `teal-50`   | `#f0fdfa` | `rgb(240, 253, 250)`         | Background total bayar, background tombol "Ubah", toast sukses |
| `teal-100`  | `#ccfbf1` | `rgb(204, 251, 241)`         | Background avatar pemilik                                      |
| `teal-600`  | `#0d9488` | `rgb(13, 148, 136)`          | Badge ring, bar chart, info QRIS/transfer, badge stok tak terbatas |
| `teal-700`  | `#0f766e` | `rgb(15, 118, 110)`          | **Tombol aksi utama**, teks nav aktif, teks harga, pill kategori (aktif), badge qty produk, FAB, banner Install, link, checkbox |
| `teal-800`  | `#115e59` | `rgb(17, 94, 89)`            | Hover/active state untuk teal-700                             |

**PWA Manifest:** `theme_color: '#0f766e'`, `background_color: '#f1f5f9'`

### 2.2 Warna Netral — Slate

| Token        | Hex       | RGB                          | Penggunaan                                                    |
|-------------|-----------|------------------------------|----------------------------------------------------------------|
| `slate-100` | `#f1f5f9` | `rgb(241, 245, 249)`         | **Background halaman**, background icon aktif, badge nonaktif |
| `slate-200` | `#e2e8f0` | `rgb(226, 232, 240)`         | Divider, background segment control, garis grid, garis separator |
| `slate-300` | `#cbd5e1` | `rgb(203, 213, 225)`         | **Border** input, card, tombol outline, garis putus-putus receipt |
| `slate-400` | `#94a3b8` | `rgb(148, 163, 184)`         | Teks nav nonaktif, teks sekunder, teks disabled, tick chart   |
| `slate-500` | `#64748b` | `rgb(100, 116, 139)`         | Teks body sekunder, label, subtitle landing page              |
| `slate-600` | `#475569` | `rgb(71, 85, 105)`           | Teks body, tombol sekunder, pill kategori (nonaktif)          |
| `slate-700` | `#334155` | `rgb(51, 65, 85)`            | Label kuat, teks input, label form, judul section             |
| `slate-900` | `#0f172a` | `rgb(15, 23, 42)`            | **Warna teks utama** (heading, body, harga, nama produk)      |

### 2.3 Warna Semantik

#### Sukses / Positif — Emerald

| Token         | Hex       | Penggunaan                                                   |
|--------------|-----------|---------------------------------------------------------------|
| `emerald-50` | `#ecfdf5` | Background jumlah perubahan positif, pelanggan dikenal       |
| `emerald-100`| `#d1fae5` | Background icon sukses, status printer                        |
| `emerald-400`| `#34d399` | Border input saat pelanggan ditemukan                         |
| `emerald-500`| `#10b981` | Icon checklist pelanggan                                      |
| `emerald-600`| `#059669` | **Background toast sukses**, tombol stock-in, share WhatsApp |
| `emerald-700`| `#047857` | Teks jumlah uang kembali (change)                             |

#### Bahaya / Error — Red

| Token    | Hex       | Penggunaan                                                   |
|---------|-----------|---------------------------------------------------------------|
| `red-50` | `#fef2f2` | Background badge void, tombol stock-out, stok menipis        |
| `red-200`| `#fecaca` | Border tombol logout, border tombol lupakan printer           |
| `red-500`| `#ef4444` | Teks "Stok habis", tombol stock-out, teks pergerakan negatif |
| `red-600`| `#dc2626` | **Tombol konfirmasi bahaya**, teks badge void, teks logout, teks "Nonaktifkan", background toast error |

#### Peringatan / Offline — Amber

| Token      | Hex       | Penggunaan                                                   |
|-----------|-----------|---------------------------------------------------------------|
| `amber-50` | `#fffbeb` | Background badge offline, info Bluetooth tidak didukung       |
| `amber-100`| `#fef3c7` | Background indikator offline                                  |
| `amber-500`| `#f59e0b` | Banner offline, titik offline                                 |
| `amber-700`| `#b45309` | Teks badge offline, teks info Bluetooth tidak didukung        |

### 2.4 Warna Lain

| Token       | Hex       | Penggunaan                                       |
|------------|-----------|---------------------------------------------------|
| `sky-50`   | `#f0f9ff` | Background badge stok "set"                       |
| `sky-700`  | `#0369a1` | Teks badge stok "set"                             |
| `green-600`| `#16a34a` | Background tombol share WhatsApp                  |
| `white`    | `#ffffff` | Background card, nav, input                        |
| `black/40` | `rgba(0,0,0,0.4)` | Overlay bottom sheet                     |

---

## 3. Tipografi

### Font Stack

```css
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
```

### Ukuran & Weight

| Penggunaan                   | Kelas Tailwind                        | Ukuran  | Weight |
|------------------------------|---------------------------------------|---------|--------|
| Judul halaman (h1)           | `text-xl font-extrabold`              | 20px    | 800    |
| Judul modal (h2)             | `text-base font-bold`                 | 16px    | 700    |
| Judul card / section         | `text-sm font-bold`                   | 14px    | 700    |
| Nama produk                  | `text-sm font-semibold`               | 14px    | 600    |
| Harga                        | `text-sm font-bold`                   | 14px    | 700    |
| Harga besar                  | `text-base font-extrabold`            | 16px    | 800    |
| Amount besar (laporan)       | `text-3xl font-extrabold tracking-tight` | 30px | 800    |
| Total (payment sheet)        | `text-3xl font-extrabold`             | 30px    | 800    |
| Body / label                 | `text-sm font-medium`                 | 14px    | 500    |
| Teks sekunder                | `text-xs text-slate-400/500`          | 12px    | 400    |
| Label navigasi               | `text-[11px] font-medium`             | 11px    | 500    |
| Teks badge                   | `text-[10px] font-bold`               | 10px    | 700    |
| TopBar title                 | `text-lg font-bold`                   | 18px    | 700    |
| Landing title                | `text-2xl font-extrabold`             | 24px    | 800    |
| Teks input                   | `text-sm font-semibold`               | 14px    | 600    |
| Stat summary (laporan)       | `text-lg font-extrabold`              | 18px    | 800    |
| Label axis chart             | `text-[11px]`                         | 11px    | 400    |

---

## 4. Layout & Container

### App Container

```html
<div class="relative mx-auto min-h-dvh w-full max-w-lg bg-slate-100 shadow-xl">
```

- Semua halaman: `max-w-lg` (512px), center, mobile-first.
- Bottom padding untuk nav: `pb-24` (umum), `pb-48` (halaman Kasir).
- Header sticky: `sticky top-0 z-20 bg-slate-100/95 px-4 pt-4 backdrop-blur`
- Konten: `px-4`

### Bottom Navigation

```html
<nav class="fixed inset-x-0 bottom-0 z-30 mx-auto w-full max-w-lg border-t border-slate-200 bg-white safe-bottom">
```

### Safe Area

```css
.safe-bottom {
  padding-bottom: env(safe-area-inset-bottom);
}
```

### Hide Scrollbar

```css
.no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.no-scrollbar::-webkit-scrollbar {
  display: none;
}
```

---

## 5. Komponen

### 5.1 Tombol

#### Primary (Teal)
```html
<button class="h-13 w-full rounded-xl bg-teal-700 py-3.5 font-bold text-white active:bg-teal-800 disabled:opacity-60">
```

#### Secondary / Outline
```html
<button class="h-12 rounded-xl border border-slate-300 font-semibold text-slate-700 active:bg-slate-50">
```

#### Outline Teal
```html
<button class="rounded-xl border border-teal-700 font-bold text-teal-700 active:bg-teal-50">
```

#### Category Pill
```html
<!-- Active -->
<button class="h-9 shrink-0 rounded-full bg-teal-700 px-4 text-sm font-semibold text-white shadow-sm">
<!-- Inactive -->
<button class="h-9 shrink-0 rounded-full bg-white px-4 text-sm font-semibold text-slate-600 shadow-sm">
```

#### Quick Amount
```html
<button class="h-10 rounded-lg border border-teal-600/40 bg-teal-50 px-3 text-sm font-semibold text-teal-700 active:bg-teal-100">
```

#### FAB (Floating Action Button)
```html
<div class="fixed z-30 flex h-14 w-14 items-center justify-center rounded-full bg-teal-700 text-white shadow-lg shadow-teal-700/40 active:bg-teal-800">
```

#### Danger (Red)
```html
<!-- Outline -->
<button class="h-12 rounded-xl border border-red-200 font-bold text-red-600 active:bg-red-50">
<!-- Solid -->
<button class="flex h-12 flex-1 items-center justify-center gap-2 rounded-xl bg-red-600 font-semibold text-white active:bg-red-700">
```

#### Load More
```html
<button class="mx-auto flex h-11 items-center gap-2 rounded-full bg-white px-6 text-sm font-semibold text-slate-600 shadow-sm active:bg-slate-50">
```

### 5.2 Card

#### Product Card (Grid)
```html
<div class="relative select-none rounded-xl bg-white p-3 shadow-sm transition active:scale-[0.98]">
```

#### Info Card
```html
<div class="rounded-2xl bg-white p-5 shadow-sm">
```

#### List Card
```html
<div class="mx-4 divide-y divide-slate-100 rounded-2xl bg-white shadow-sm">
```

#### Summary Card
```html
<div class="rounded-xl bg-slate-50 p-4 text-sm">
```

#### Payment Total
```html
<div class="rounded-xl bg-teal-50 p-4 text-center">
```

### 5.3 Input

#### Text Input
```html
<input class="w-full rounded-xl border border-slate-300 bg-white px-4 py-3 outline-none focus:border-teal-600 focus:ring-2 focus:ring-teal-600/20" />
```

#### Search Input
```html
<input class="w-full rounded-full border border-slate-200 bg-white py-3 pl-12 pr-4 shadow-sm outline-none focus:border-teal-600 focus:ring-2 focus:ring-teal-600/20" />
```

#### Select
```html
<select class="w-full appearance-none rounded-xl border border-slate-300 bg-white px-4 py-3 outline-none focus:border-teal-600 focus:ring-2 focus:ring-teal-600/20">
```

#### Checkbox
```html
<input type="checkbox" class="h-6 w-6 accent-teal-700" />
```

#### Label Form
```html
<label class="block text-sm font-medium text-slate-700 mb-1.5">
```

### 5.4 Bottom Sheet

```html
<!-- Backdrop -->
<div class="fixed inset-0 z-40 bg-black/40" />
<!-- Sheet -->
<div class="fixed inset-x-0 bottom-0 z-50 flex justify-center">
  <div class="w-full max-w-lg rounded-t-2xl bg-white shadow-2xl">
    <div class="mx-auto mt-2 h-1.5 w-10 rounded-full bg-slate-200" />
    <div class="max-h-[80dvh] overflow-y-auto px-5 pb-6 pt-3 safe-bottom">
      <slot />
    </div>
  </div>
</div>
```

### 5.5 Toast Notification

```html
<div class="fixed inset-x-0 top-4 z-[60] mx-auto flex w-full max-w-lg flex-col items-center gap-2 px-4">
  <div class="w-full rounded-xl px-4 py-3 text-sm font-medium text-white shadow-lg"
       :class="type === 'success' ? 'bg-emerald-600' : 'bg-red-600'">
```

Durasi: 3000ms, auto-dismiss.

### 5.6 Badge

| Jenis    | Kelas Tailwind                                                                 |
|----------|---------------------------------------------------------------------------------|
| Void     | `rounded bg-red-50 px-1.5 py-0.5 text-[10px] font-bold text-red-600`          |
| Nonaktif | `rounded bg-slate-100 px-1.5 py-0.5 text-[10px] font-bold text-slate-500`     |
| Stok ∞   | `rounded bg-teal-50 px-1.5 py-0.5 text-[10px] font-bold text-teal-600`        |
| Offline  | `rounded-full bg-amber-100 px-2.5 py-0.5 text-xs font-semibold text-amber-700`|

### 5.7 Segment / Tab Control

```html
<div class="grid grid-cols-2 gap-1 rounded-xl bg-slate-200/70 p-1">
  <button class="h-9 rounded-lg text-sm font-semibold"
          :class="active ? 'bg-white text-slate-900 shadow-sm' : 'text-slate-500'">
```

### 5.8 Top Bar

```html
<header class="sticky top-0 z-20 border-b border-slate-200 bg-white">
  <div class="flex h-14 items-center gap-2 px-4">
    <!-- Back button: rounded-full text-slate-600 active:bg-slate-100 -->
    <!-- Title: text-lg font-bold text-slate-900 -->
  </div>
</header>
```

---

## 6. Shadow

| Kelas        | Penggunaan                              |
|-------------|------------------------------------------|
| `shadow-sm` | Card, product item, segment tab, pill   |
| `shadow-lg` | Toast, FAB                               |
| `shadow-xl` | App container, bottom sheet              |
| `shadow-teal-700/30` | Cart FAB CTA                  |
| `shadow-teal-700/40` | Product FAB                   |

---

## 7. Border Radius

| Kelas          | Value   | Penggunaan                                  |
|---------------|---------|----------------------------------------------|
| `rounded-full`| 9999px  | Category pill, search input, back button, load-more |
| `rounded-2xl` | 16px    | Card, bottom sheet, list container           |
| `rounded-xl`  | 12px    | Button, input, product card, receipt, badge  |
| `rounded-lg`  | 8px     | Increment/decrement, quick amount, tab aktif |
| `rounded-md`  | 6px     | Badge tipe pergerakan stok                   |

---

## 8. Transisi

```css
/* Bottom Sheet */
.sheet-enter-active,
.sheet-leave-active { transition: transform 0.25s ease; }
.sheet-enter-from,
.sheet-leave-to { transform: translateY(100%); }

/* Fade */
.fade-enter-active,
.fade-leave-active { transition: opacity 0.2s ease; }
.fade-enter-from,
.fade-leave-to { opacity: 0; }

/* Product Card Press */
transition active:scale-[0.98]

/* Spinner */
animate-spin
```

---

## 9. Icon

Semua icon menggunakan **inline SVG** gaya Heroicons:

```html
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
  <path stroke-linecap="round" stroke-linejoin="round" d="..." />
</svg>
```

| Elemen              | Stroke Width |
|--------------------|-------------|
| Icon umum          | `1.5` atau `2` |
| Icon navigasi      | `1.8`       |
| Icon FAB plus      | `2.5`       |

---

## 10. Grid & Layout Pattern

| Pattern                     | Kelas Tailwind                                       |
|----------------------------|-------------------------------------------------------|
| Grid produk                | `grid grid-cols-2 gap-3`                             |
| Grid pembayaran            | `grid grid-cols-3 gap-2`                             |
| Grid statistik             | `grid grid-cols-3 divide-x divide-slate-100`         |
| Grid form 2 kolom          | `grid grid-cols-2 gap-3`                             |
| Scroll kategori            | `no-scrollbar flex gap-2 overflow-x-auto`            |
| List dengan divider        | `divide-y divide-slate-100`                          |
| List item                  | `flex items-center gap-3 px-4 py-3.5 active:bg-slate-50` |

---

## 11. Aturan untuk Fitur Baru / Platform Baru

### Dashboard Analytics & Superadmin Dashboard

1. **Ikuti palet warna di atas** — jangan perkenalkan warna baru tanpa persetujuan. Gunakan teal sebagai primary, slate sebagai neutral, emerald/red/amber sebagai semantik.

2. **Container**: Jika dashboard diakses di layar lebar (>768px), gunakan container terpusat `mx-auto max-w-6xl px-6` atau layout full-width sesuai kebutuhan. Untuk tampilan mobile, tetap gunakan `max-w-lg`.

3. **Konsistensi komponen**: Gunakan pola komponen yang sudah ada (BottomSheet, Toast, Button, Card, Input, dll). Jangan buat ulang dari nol.

4. **Chart & Data Visualization**: Gunakan Chart.js (via vue-chartjs) yang sudah terintegrasi. Warna chart: teal-600 untuk bar utama, slate-300 untuk grid line, slate-400/500 untuk tick label.

5. **Tabel Data**:
   - Header: `text-sm font-bold text-slate-700`
   - Cell: `text-sm text-slate-900`
   - Row hover: `hover:bg-slate-50`
   - Border: `border-b border-slate-100`

6. **Loading State**: Gunakan komponen Spinner yang sudah ada (`animate-spin` dengan `currentColor`).

7. **Empty State**: Gunakan card dengan `text-sm text-slate-400 text-center py-8`

8. **Responsivitas**: Semua halaman baru harus mobile-first. Gunakan `min-h-dvh` untuk full-height layout.

9. **Aksesibilitas**: Semua tombol minimal `h-12` (touch-friendly), input minimal 16px font size (cegah iOS zoom).

10. **Bahasa**: Gunakan Bahasa Indonesia (`lang="id"`) dengan format `id-ID` untuk currency (`Rp 1.000`, bukan `Rp 1,000`).

---

## 12. Referensi File

| File                                     | Deskripsi                              |
|------------------------------------------|----------------------------------------|
| `frontend/src/style.css`                 | CSS global, utility classes            |
| `frontend/src/components/`               | Komponen reusable (BottomSheet, Toast, dll) |
| `frontend/src/views/`                    | Halaman aplikasi                       |
| `frontend/src/stores/toast.ts`           | State management untuk toast           |
| `frontend/src/utils/format.ts`           | Formatter Rupiah, tanggal              |
| `frontend/src/types.ts`                  | TypeScript types                       |
| `landingpage.html`                       | Halaman landing (independen)           |
| `styleguide.bukukasir.biz.id`            | Styleguide interaktif & dokumen ini    |
