Sampai Bagian 3, sistem desain ini sudah lengkap secara struktur, tetapi nilai-nilai spasi masih ditulis sebagai angka px yang tersebar di tiap komponen: 16 px di sini, 24 px di sana. Bagian 4 merapikannya dengan cara khas proyek nyata: nilai yang sudah benar diikat kembali ke token --jarak-* dan --ukuran-teks-* yang dibuat sejak Bagian 1. Hasil render praktis tidak berubah; yang berubah adalah siapa yang memegang kendali. Setelah bagian ini, menggeser ritme seluruh halaman cukup dengan mengedit satu baris token.
Mengikat Spasi ke Token #
Sekelompok deklarasi di bagian 8 stylesheet mengulang selector lama dengan nilai token: .laman-kepala { padding-block: var(--jarak-5); }, .laman-utama { padding-block: var(--jarak-7) var(--jarak-8); }, .galeri-kartu dengan gap dan margin-top token, hingga .kartu dengan gap: var(--jarak-3) dan padding: var(--jarak-4). Karena --jarak-3 bernilai 12 px dan --jarak-4 bernilai 16 px, tidak ada piksel yang bergeser; kartu, header, dan footer tetap persis seperti sebelumnya. Bedanya kini ada di sumber kebenaran: bila besok ritme halaman perlu dilonggarkan, cukup nilai token yang diubah.
Satu deklarasi baru ditambahkan untuk ritme antarseksi: .laman-utama section { margin-top: var(--jarak-7); }. Setiap seksi galeri kini berjarak 48 px dari seksi sebelumnya, satu nilai yang sama dengan padding utama halaman, sehingga ritme vertikal terasa konsisten dari atas ke bawah.
Penyempurnaan Tipografi #
Selain spasi, bagian ini menyentuh huruf. .pengantar kini memakai font-size: var(--ukuran-teks-sedang) dengan line-height: 1.65 — ukurannya sama seperti sebelumnya, tetapi kini terikat ke skala. .section-judul mendapat letter-spacing: -0.01em; huruf judul besar memang biasanya lebih rapat sedikit daripada teks isi agar tidak terasa renggang. Satuan em dipilih untuk letter-spacing karena nilainya ikut menskalakan bersama ukuran huruf elemen: judul yang membesar tetap merapatkan jarak antarhurufnya secara proporsional, bukan dengan jarak piksel yang mandek. Catatan kecil tentang urutan: karena seluruh deklarasi bagian 8 ditulis setelah aturan aslinya, susunan berkas kini menjadi bagian dari desain — kelompok penyempurnaan selalu berada di bawah kelompok komponen.
Perubahan yang paling terlihat ada pada .kartu-lencana: text-transform: uppercase plus letter-spacing: var(--jejak-huruf-lebar) mengubah pil kecil itu menjadi label berhuruf kapital dengan jarak antarhuruf yang lega, konvensi umum untuk lencana kategori. .token-nama di pamer token diberi keluarga huruf monospace berukuran --ukuran-teks-kecil, menandai bahwa teks itu adalah nama kode, bukan kalimat biasa. Terakhir, .kartu-teks dinaikkan line-height-nya ke 1.6 agar paragraf pendek di dalam kartu tetap nyaman dibaca.
Semua deklarasi ini sengaja diletakkan setelah aturan aslinya. Cascade memutuskan deklarasi terakhir menang bila spesifisitas sama, sehingga penyempurnaan bisa ditambah tanpa menyentuh berkas bagian sebelumnya.
/* ============================================================
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%; }
/* ---------- 3. Kerangka halaman ---------- */
.pembungkus {
max-width: var(--lebar-isi);
margin-inline: auto;
padding-inline: 16px;
}
.laman-kepala {
padding-block: 24px;
background-color: var(--warna-permukaan);
border-bottom: 1px solid var(--warna-garis);
}
.kepala-baris {
display: flex; align-items: center;
justify-content: space-between;
gap: 16px; flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand img { width: 40px; height: 40px; }
.brand-nama { font-size: 20px; font-weight: 700; }
.laman-utama { padding-block: 48px 64px; }
.section-judul { font-size: 28px; font-weight: 800; }
.pengantar { margin-top: 8px; max-width: 65ch; color: var(--warna-teks-lembut); font-size: 15px; }
.pamer-token {
display: flex; flex-wrap: wrap;
gap: 12px 24px; margin-top: 24px;
padding: 16px; background-color: var(--warna-permukaan);
border: 1px solid var(--warna-garis); border-radius: 12px;
}
.token { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.token-contoh { width: 24px; height: 24px; border-radius: 6px; border: 1px solid var(--warna-garis); }
.token-nama { color: var(--warna-teks-lembut); }
.galeri-kartu {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px; margin-top: 32px;
}
.laman-kaki {
background-color: var(--warna-permukaan);
border-top: 1px solid var(--warna-garis);
}
.kaki-baris {
display: flex; justify-content: space-between;
flex-wrap: wrap; gap: 8px 16px;
padding-block: 24px; font-size: 13.5px;
color: var(--warna-teks-lembut);
}
/* ---------- 4. Tombol ---------- */
.tombol {
display: inline-block;
padding: 9px 18px; border: none; border-radius: 6px;
background-color: var(--warna-utama);
color: var(--warna-utama-kontras);
font: inherit; font-weight: 600; cursor: pointer;
}
.tombol:hover { background-color: var(--warna-utama-pekat); }
.tombol--sekunder { background-color: var(--warna-utama-lembut); color: var(--warna-utama-pekat); }
.tombol--sekunder:hover { background-color: var(--warna-garis); }
/* ---------- 5. Kartu ---------- */
.kartu {
display: flex; flex-direction: column;
gap: 12px; padding: 16px;
background-color: var(--warna-permukaan);
border: 1px solid var(--warna-garis); border-radius: 12px;
}
.kartu-lencana {
align-self: flex-start;
padding: 4px 12px; border-radius: var(--radius-penuh);
background-color: var(--warna-utama-lembut); color: var(--warna-utama-pekat);
font-size: 11.5px; font-weight: 700;
}
.kartu--produk .kartu-lencana { background-color: var(--warna-aksen); color: #ffffff; }
.kartu-media {
aspect-ratio: 16 / 10;
border-radius: 8px;
background: linear-gradient(135deg, #d8a26a 0%, #7a4a21 100%);
}
.kartu-judul { font-size: 20px; line-height: 1.3; font-weight: 700; }
.kartu-teks { font-size: 14.5px; color: var(--warna-teks-lembut); }
.kartu-meta {
display: flex; align-items: center;
gap: 8px; font-size: 12.5px;
color: var(--warna-teks-lembut);
}
.kartu-aksi {
margin-top: auto;
display: flex; align-items: center;
justify-content: space-between; gap: 8px;
}
.kartu-harga { font-size: 16px; font-weight: 700; color: var(--warna-utama-pekat); }
/* ---------- 6. Varian kartu ---------- */
.kartu--artikel { color: inherit; text-decoration: none; }
.kartu--artikel .kartu-meta { margin-top: auto; padding-top: 4px; }
.kartu--profil { align-items: center; text-align: center; }
.kartu-avatar {
width: 72px; height: 72px;
display: grid; place-items: center;
border-radius: var(--radius-penuh);
background: linear-gradient(135deg, #b3541e, #7a4a21);
color: #ffffff; font-size: 26px; font-weight: 700;
}
.kartu-peran { font-size: 13px; color: var(--warna-teks-lembut); }
.kartu-angka { font-size: 34px; font-weight: 800; line-height: 1.1; }
.kartu-tren { align-self: flex-start; padding: 2px 10px; border-radius: var(--radius-penuh); font-size: 12.5px; font-weight: 700; }
.kartu-tren--naik { color: var(--warna-sukses); }
.kartu-tren--turun { color: var(--warna-bahaya); }
/* ---------- 7. Elevasi dan aksen border ---------- */
.kartu { box-shadow: var(--bayangan-1); }
/* Kartu promosi naik satu tingkat dan melepas garis */
.kartu--produk {
box-shadow: var(--bayangan-2);
border-color: transparent;
}
/* Kartu artikel mengandalkan garis, bukan bayangan */
.kartu--artikel { box-shadow: none; }
/* Aksen kiri menandai kartu angka */
.kartu--statistik { border-left: 4px solid var(--warna-utama); }
.kartu-avatar {
border: 3px solid var(--warna-permukaan);
box-shadow: var(--bayangan-1);
}
/* ---------- 8. Tipografi dan ritme ---------- */
/* Nilai yang sama diikat ke token: satu perubahan token
menggerakkan ritme seluruh halaman, bukan rule per rule. */
.laman-kepala { padding-block: var(--jarak-5); }
.laman-utama { padding-block: var(--jarak-7) var(--jarak-8); }
.laman-utama section { margin-top: var(--jarak-7); }
.pengantar {
font-size: var(--ukuran-teks-sedang);
line-height: 1.65;
}
.section-judul { letter-spacing: -0.01em; }
.pamer-token {
margin-top: var(--jarak-5);
padding: var(--jarak-4);
}
.token-nama {
font-family: ui-monospace, "Cascadia Mono", monospace;
font-size: var(--ukuran-teks-kecil);
}
.galeri-kartu {
gap: var(--jarak-5);
margin-top: var(--jarak-5);
}
.kartu {
gap: var(--jarak-3);
padding: var(--jarak-4);
}
.kartu-lencana {
letter-spacing: var(--jejak-huruf-lebar);
text-transform: uppercase;
}
.kartu-teks { line-height: 1.6; }
.kaki-baris { padding-block: var(--jarak-5); }Ringkasan #
Bagian ini memindahkan kendali spasi dan tipografi ke token tanpa menggambar ulang satu pun komponen: nilai lama dipetakan ke --jarak-* dan --ukuran-teks-*, ritme antarseksi disatukan pada 48 px, lencana berubah menjadi label kapital berjarak, dan nama token tampil monospace. Sistem desain kini bisa diatur dari satu tempat — fondasi yang tepat sebelum Bagian 5 menambahkan gerak dan tema gelap.