Proyek ini dimulai dari keputusan, bukan dari komponen. Sebelum menulis satu pun kartu, kita sepakati dulu bahasa visual halaman: warna apa yang boleh dipakai, seberapa besar jarak antarelemen, dan seberapa cepat transisi bergerak. Semua keputusan itu kita beri nama melalui custom property di dalam :root, lalu seluruh stylesheet menengok ke nama-nama tersebut. Berkas styles.css pada tahap ini masih pendek, tetapi isinya adalah fondasi yang dipakai empat bagian berikutnya.

Token Warna Semantik #

Perhatikan bahwa setiap warna dinamai menurut perannya, bukan menurut nilainya: --warna-latar untuk latar halaman, --warna-permukaan untuk bidang komponen seperti kartu dan header, --warna-teks untuk teks utama, dan --warna-teks-lembut untuk teks sekunder. Ada juga --warna-garis untuk border tipis. Penamaan per-peran penting karena komponen tidak perlu tahu warna apa yang sedang dipakai; ia hanya perlu tahu fungsinya.

Warna utama cokelat mendapat empat turunan: --warna-utama sebagai dasar, --warna-utama-pekat untuk keadaan hover tombol, --warna-utama-kontras sebagai warna teks di atas tombol utama, dan --warna-utama-lembut untuk lencana serta tombol sekunder. Dua warna status, --warna-sukses dan --warna-bahaya, disiapkan sejak sekarang agar Bagian 2 tidak perlu menambah token baru. Terakhir, --warna-fokus sengaja dipilih biru yang kontras dengan palet cokelat; ia akan dipakai sebagai cincin fokus keyboard di Bagian 5.

Skala Spasi, Radius, Bayangan, dan Gerak #

Token --jarak-1 sampai --jarak-8 membentuk skala berbasis 4 px dan 8 px: 4, 8, 12, 16, 24, 32, 48, 64. Dengan skala ini, setiap jarak di halaman berasal dari satu kelipatan yang sama, sehingga hasilnya terasa teratur tanpa perlu mengukur ulang. Tiga token --radius-* mengatur kelengkungan sudut, dari kecil 6 px untuk tombol, standar 12 px untuk kartu, sampai --radius-penuh untuk lencana bentuk pil.

Tiga token --bayangan-* menampung tiga tingkat elevasi dalam rgba yang diambil dari rona warna teks, bukan hitam murni, agar bayangan menyatu dengan palet hangat halaman. Bagian 3 akan memakai ketiganya. Skala tipografi berisi ukuran teks dari kecil sampai judul, keluarga huruf dasar, tinggi baris 1.55, dan --jejak-huruf-lebar untuk lencana berhuruf kapital. Token gerak --durasi-cepat, --durasi, dan --pelunakan dipakai Bagian 5, sementara --lebar-isi membatasi lebar konten pada 1080 px.

Base Reset Minimal #

Blok terakhir adalah reset kecil yang sengaja tidak berlebihan. Selector universal *, *::before, *::after menerapkan box-sizing: border-box agar padding tidak menambah lebar elemen. body mengambil keluarga huruf, tinggi baris, warna latar, dan warna teks langsung dari token. Margin h1–h3, p, dan figure dinolkan supaya jarak antarelemen nanti diputuskan per komponen, bukan oleh bawaan browser. img dibuat display: block dengan max-width: 100% agar gambar tidak meluber dari kartunya.

css
/* ============================================================
   Koleksi Kartu UI — stylesheet utama
   Urutan: token → base → kerangka halaman → tombol → kartu
   → varian → elevasi → tipografi → state → tema gelap
   ============================================================ */

/* ---------- 1. Design token ---------- */
:root {
  /* Warna semantik, tema terang */
  --warna-latar: #f6f1e7;        --warna-permukaan: #ffffff;
  --warna-teks: #2a2118;         --warna-teks-lembut: #6d5c48;
  --warna-garis: #e4d9c6;        --warna-utama: #7a4a21;
  --warna-utama-pekat: #5c3517;  --warna-utama-kontras: #ffffff;
  --warna-utama-lembut: #f0e2cf; --warna-aksen: #b3541e;
  --warna-sukses: #1f7a4d;       --warna-bahaya: #b3372b;
  --warna-fokus: #1d4ed8;

  /* Skala spasi, basis empat dan delapan piksel */
  --jarak-1: 4px;  --jarak-2: 8px;
  --jarak-3: 12px; --jarak-4: 16px;
  --jarak-5: 24px; --jarak-6: 32px;
  --jarak-7: 48px; --jarak-8: 64px;

  /* Radius sudut */
  --radius-kecil: 6px; --radius: 12px;
  --radius-penuh: 999px;

  /* Elevasi bayangan, tiga tingkat */
  --bayangan-1: 0 1px 2px rgba(42, 33, 24, 0.08);
  --bayangan-2: 0 4px 12px rgba(42, 33, 24, 0.14);
  --bayangan-3: 0 12px 28px rgba(42, 33, 24, 0.18);

  /* Skala tipografi */
  --font-dasar: system-ui, "Segoe UI", sans-serif;
  --ukuran-teks-kecil: 0.8125rem;
  --ukuran-teks-sedang: 0.9375rem;
  --ukuran-teks-dasar: 1rem;
  --ukuran-teks-subjudul: 1.25rem;
  --ukuran-teks-judul: 1.5rem;
  --ukuran-angka: 2.25rem;
  --tinggi-baris: 1.55;
  --jejak-huruf-lebar: 0.08em;

  /* Gerak */
  --durasi-cepat: 120ms; --durasi: 200ms; --pelunakan: ease-out;

  /* Kerangka halaman */
  --lebar-isi: 1080px;
}

/* ---------- 2. Base ---------- */
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-dasar);
  line-height: var(--tinggi-baris);
  background-color: var(--warna-latar);
  color: var(--warna-teks);
}

h1, h2, h3, p, figure {
  margin: 0;
}

img {
  display: block;
  max-width: 100%;
}

Ringkasan #

Tahap pertama tidak menghasilkan komponen terlihat, tetapi menetapkan kosakata desain: warna per-peran, skala spasi 4/8 px, radius, tiga tingkat bayangan, skala huruf, dan durasi gerak. Base reset memastikan semua browser mulai dari titik yang sama. Sejak Bagian 2, setiap aturan CSS akan memanggil token ini, bukan nilai mentah.