@charset "utf-8";
/* =============================================================================
   Cakra Sandang Garment, desain contoh (perusahaan fiktif)
   Sumber desain: stitch/10-konveksi/ (DESIGN.md + PROMPTS-WEB/STATE)

   MODE WARNA DIKUNCI TERANG. Seluruh rasio di bawah dihitung untuk latar terang
   saja. Mencabut kuncian di <html data-tema="terang"> berarti menghitung ulang
   SETIAP pasangan warna lebih dulu, bukan sekadar menghapus atributnya.

   AKSEN INI ISIAN SAJA, DAN ITU DIHITUNG SENDIRI, BUKAN DIWARISI DARI SITUS 06.
   Koral #F4795B hanya 2,56:1 di atas latar #FAF7FF dan 2,34:1 di atas panel
   #F1ECFB. Dua-duanya DI BAWAH lantai 3:1 untuk border, ikon fungsional, dan
   cincin fokus, dan jauh di bawah 4,5:1 untuk teks. Teks DI ATAS aksen wajib
   TINTA (5,77:1); putih di atasnya 2,72:1 dan GAGAL AA.

   Angka DESIGN.md paket ini diperiksa ulang satu per satu dan TERBUKTI BENAR:
   5,77 · 2,72 · 14,79 · 6,37 cocok sampai dua desimal. Yang TIDAK ditulis
   DESIGN.md justru angka penentunya, aksen di atas latar, dan angka itulah
   yang membuat aksen di sini terkurung jadi isian.

   ⛔ RAMBU ISI (ATURAN-KONTEN.md + DESIGN.md): TIDAK ADA nomor sertifikat, nomor
   izin, nomor NIB, atau nomor registrasi di mana pun, cukup jenis, penerbit,
   masa berlaku, dan status. Harga selalu disebut RENTANG atau ESTIMASI berikut
   apa yang mengubahnya.

   DUA KELUARGA HURUF: Sora 700 untuk judul dan angka, Inter 400/600 untuk isi.
   Keduanya huruf VARIABEL, jadi satu berkas woff2 per keluarga sudah cukup.
   ⚠️ U+2192 (→) TIDAK ADA di subset latin Sora MAUPUN Inter, padahal rentang
   U+2000-206F dideklarasikan. Karena itu tidak ada satu pun aksara panah sebagai
   teks di paket ini; panah digambar sebagai SVG sprite. Aksara yang memang
   dipakai, ² · –, ± × …, sudah dibuktikan ADA di kedua huruf lewat fontTools.
   ========================================================================== */

@import url("aset/huruf/_font-face.css");

/* -----------------------------------------------------------------------------
   1. TOKEN, tiap warna punya PERAN dan RASIO TERHITUNG di sebelahnya.
   Angka di bawah DIHITUNG SENDIRI dengan rumus WCAG relative luminance.
   -------------------------------------------------------------------------- */
:root {
  /* Permukaan */
  --latar:        #FAF7FF;   /* alas halaman */
  --kertas:       #FFFFFF;   /* alas kartu; tinta 15,67:1 · redup 6,76:1 */
  --panel:        #F1ECFB;   /* panel "enam angka" + kepala tabel (DESIGN.md);
                                tinta di atasnya 13,53:1 · redup 5,83:1 */
  --sentuh:       #F0EAFA;   /* hover/tekan; tinta 13,32:1 · redup 5,74:1 */

  /* Teks */
  --tinta:        #241C4A;   /* 14,79:1 di atas --latar, teks utama, ukuran apa pun */
  --redup:        #5D5680;   /* 6,37:1 di atas --latar, teks sekunder, LULUS AA */

  /* Aksen, ISIAN SAJA */
  --aksen:        #F4795B;   /* 2,56:1 di atas --latar, 2,34:1 di atas --panel →
                                ISIAN saja: tombol, cip, pita, nomor langkah,
                                batang diagram, kartu hasil.
                                DILARANG jadi warna teks, garis, border kendali,
                                cincin fokus, atau ikon fungsional, semuanya
                                butuh minimal 3:1 dan koral ini tidak sampai.
                                Teks DI ATAS aksen wajib --tinta (5,77:1);
                                putih di atasnya 2,72:1 dan GAGAL AA. */
  --aksen-tekan:  #E8683F;   /* keadaan ditekan; tinta di atasnya 4,84:1 */
  --aksen-alas:   #FDEAE4;   /* alas lembut; tinta 13,48:1 · redup 5,81:1 */
  --nonaktif:     #EAE4F5;   /* alas kendali mati; redup di atasnya 5,44:1 */

  /* Garis */
  --garis:        #E8E2F5;   /* 1,19:1, DEKORATIF saja (pemisah, border kartu).
                                DILARANG untuk border kendali interaktif. */
  --garis-kendali:#5D5680;   /* 6,37:1 di atas latar, 6,76:1 di atas kertas, border input, checkbox, tombol outline. */

  /* Semantik, dihitung terhadap --latar */
  --sukses:       #0F6B45;   /* 6,17:1 */
  --galat:        #B3261E;   /* 6,17:1 */
  --peringatan:   #7A4B00;   /* 6,99:1 */
  --sukses-alas:  #E4F1EA;   /* tinta di atasnya 13,48:1 */
  --galat-alas:   #FBE9E6;   /* tinta di atasnya 13,36:1 */
  --peringatan-alas:#F7EFDD; /* tinta di atasnya 13,69:1 */

  /* Huruf. Sora untuk judul dan angka (sumbu wght 400–800), Inter untuk isi
     (sumbu wght 100–900). Rantai cadangan diisi huruf sistem supaya aksara di
     luar subset latin, termasuk panah U+2192 yang memang tidak ada, punya
     tempat jatuh, bukan kotak kosong. */
  --f-judul: "Sora", ui-sans-serif, "Segoe UI", system-ui, sans-serif;
  --f-isi:   "Inter", ui-sans-serif, "Segoe UI", system-ui, sans-serif;

  /* LANTAI UKURAN TEKS, jangan turun di bawah ini di mana pun. */
  --t-isi:   1rem;      /* 16px, teks isi */
  --t-kecil: 0.875rem;  /* 14px, sekunder */
  --t-label: 0.75rem;   /* 12px, label huruf besar, BATAS BAWAH */

  /* Ritme */
  --r1: .25rem; --r2: .5rem; --r3: .75rem; --r4: 1rem;
  --r5: 1.5rem; --r6: 2rem; --r7: 3rem; --r8: 4rem; --r9: 6rem;

  --radius: 10px;                   /* DESIGN.md paket 10: radius 10px */
  --lebar-isi: 1240px;
  --tepi: 1.25rem;

  --bar-atas: 0px;
  --bar-bawah: calc(56px + env(safe-area-inset-bottom, 0px));
}

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

/* Atribut `hidden` KALAH oleh `display` mana pun yang ditulis di CSS. Gejalanya
   mahal dan hanya terlihat setelah dirender: pesan galat formulir tampil sejak
   halaman dibuka karena .pesan menyetel display:flex. Satu aturan ini menutup
   seluruh kelasnya. */
[hidden] { display: none !important; }

html {
  /* Jangkar berhenti tepat di bawah bar, dan ini juga menyelamatkan elemen yang
     menerima fokus keyboard (teknik W3C C43 untuk WCAG 2.2 SC 2.4.11). */
  scroll-padding-top: calc(var(--bar-atas) + var(--r4));
  scroll-padding-bottom: calc(var(--bar-bawah) + var(--r4));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--latar);
  color: var(--tinta);
  font-family: var(--f-isi);
  font-size: var(--t-isi);
  line-height: 1.6;
  /* Ruang untuk bar tab bawah di mobile supaya isi terakhir tidak tertutup. */
  padding-bottom: var(--bar-bawah);
}

h1, h2, h3, h4 { font-family: var(--f-judul); font-weight: 700; line-height: 1.2; margin: 0; }
h1 { font-size: clamp(2.125rem, 5vw, 3.375rem); letter-spacing: -0.01em; }
h2 { font-size: clamp(1.5rem, 3.2vw, 2.25rem); letter-spacing: -0.01em; }
h3 { font-size: clamp(1.125rem, 1.9vw, 1.375rem); }
p  { margin: 0; }
img { max-width: 100%; height: auto; display: block; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }

/* Angka statistik, harga, dan gramasi: Sora 700 dengan angka TABULAR.
   DESIGN.md menyebutnya eksplisit, dan halaman ini punya EMPAT tabel angka
   sekaligus (harga per tingkat, gramasi bahan, biaya teknik, tabel ukuran).
   Fitur `tnum` sudah dibuktikan ada di GSUB Sora maupun Inter, deklarasi ini
   benar-benar bekerja, bukan sekadar ditulis. */
.angka { font-family: var(--f-judul); font-weight: 700;
         font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* CINCIN FOKUS, SELALU 2px tinta dengan offset 2px. Di paket ini bukan pilihan
   melainkan keharusan: koral 2,56:1 tidak sampai ke lantai 3:1, jadi cincin fokus
   beraksen adalah cincin fokus yang tidak terlihat. Lembar state S1/S2/S8 memang
   menggambarkannya beraksen; itu satu-satunya tempat brief bertabrakan dengan
   angka, dan angkanya yang menang. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Lewati ke konten, wajib ada, dan wajib terlihat saat difokus. */
.lewati {
  position: absolute; left: var(--tepi); top: -100px; z-index: 100;
  background: var(--tinta); color: #fff; padding: var(--r3) var(--r4);
  border-radius: var(--radius); font-weight: 600; text-decoration: none;
}
.lewati:focus-visible { top: var(--r3); }

/* -----------------------------------------------------------------------------
   3. TATA LETAK
   -------------------------------------------------------------------------- */
.bungkus { width: 100%; max-width: var(--lebar-isi); margin-inline: auto; padding-inline: var(--tepi); }
.bagian { padding-block: var(--r7); }
.bagian + .bagian { border-top: 1px solid var(--garis); }
@media (min-width: 768px) { .bagian { padding-block: var(--r8); } }

.kepala-bagian { margin-bottom: var(--r5); max-width: 62ch; }
.kepala-bagian p { color: var(--redup); margin-top: var(--r2); }

.kisi { display: grid; gap: var(--r4); }
@media (min-width: 640px)  { .kisi-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px)  { .kisi-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
                             .kisi-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 640px) and (max-width: 899px) { .kisi-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Tiap anak kisi WAJIB boleh menyusut, kalau tidak isi yang lebar mendorong
   lebar halaman dan yang dilaporkan meluber justru elemen lain. */
.kisi > * { min-width: 0; }

/* -----------------------------------------------------------------------------
   4. PITA "DESAIN CONTOH", tidak bisa ditutup, wajib di tiap halaman
   -------------------------------------------------------------------------- */
.pita {
  background: var(--tinta); color: #fff;   /* 15,67:1 */
  font-size: 0.8125rem; text-align: center;
  padding: var(--r2) var(--tepi);
}

/* -----------------------------------------------------------------------------
   5. NAVBAR (desktop), di mobile digantikan bar tab bawah
   -------------------------------------------------------------------------- */
.navbar { border-bottom: 1px solid var(--garis); background: var(--latar); }
.navbar-isi { display: flex; align-items: center; gap: var(--r4); min-height: 64px; }
.wordmark {
  font-family: var(--f-judul); font-weight: 700; letter-spacing: .06em;
  font-size: 0.9375rem; text-decoration: none; white-space: nowrap;
}
.nav-tautan { display: none; gap: var(--r5); margin-inline: auto; }
.nav-tautan a { text-decoration: none; color: var(--redup); font-size: var(--t-kecil); }
.nav-tautan a:hover { color: var(--tinta); }
/* Item aktif TIDAK dibedakan warna saja, ada garis bawah tebal juga. */
.nav-tautan a[aria-current="page"] {
  color: var(--tinta); font-weight: 600;
  box-shadow: inset 0 -3px 0 0 var(--aksen);
}
@media (min-width: 900px) { .nav-tautan { display: flex; } }
.navbar .tombol { margin-left: auto; }
@media (min-width: 900px) { .navbar .tombol { margin-left: 0; } }

/* -----------------------------------------------------------------------------
   6. TOMBOL, target sentuh minimal 48px, tombol utama 52px di mobile
   -------------------------------------------------------------------------- */
.tombol {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--r2);
  min-height: 48px; padding: var(--r3) var(--r5);
  font-family: var(--f-isi); font-size: var(--t-kecil); font-weight: 600;
  border-radius: var(--radius); border: 1px solid transparent;
  text-decoration: none; cursor: pointer; background: none; color: var(--tinta);
  transition: background-color .15s ease, border-color .15s ease;
}
.tombol-utama { background: var(--aksen); color: var(--tinta); }   /* 5,77:1 */
.tombol-utama:hover { background: var(--aksen-tekan); }            /* 4,84:1 */
.tombol-utama:active { background: var(--aksen-tekan); }
.tombol-kedua { border-color: var(--garis-kendali); color: var(--tinta); }  /* 6,37:1 */
.tombol-kedua:hover { background: var(--sentuh); }
.tombol-blok { width: 100%; }
.tombol[disabled], .tombol[aria-disabled="true"] {
  background: var(--nonaktif); color: var(--redup); border-color: transparent;
  cursor: not-allowed;
}
.tombol-alasan { font-size: var(--t-kecil); color: var(--redup); margin-top: var(--r2); }

/* Keadaan memuat: tombol punya LABELNYA SENDIRI, bukan cuma spinner. */
.tombol[data-memuat="ya"] { pointer-events: none; }
.pemintal {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: putar .7s linear infinite; flex: none;
}
@keyframes putar { to { transform: rotate(360deg); } }

/* -----------------------------------------------------------------------------
   7. IKON, SVG sebaris, BUKAN emoji dan bukan font ikon.
   Brief menyebut Material Symbols; yang dipakai di sini SVG sebaris dengan bentuk
   yang sama maknanya. Alasannya bukan selera: font ikon berbasis ligatur
   menampilkan nama glyph sebagai teks mentah sebelum fontnya termuat, dan itu
   berarti kata "request_quote" sempat terbaca di layar pembeli.
   -------------------------------------------------------------------------- */
.ikon { width: 20px; height: 20px; flex: none; stroke: currentColor;
        fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ikon-besar { width: 28px; height: 28px; }
.ikon-redup { color: var(--redup); }
/* TIDAK ADA .ikon-aksen di paket ini: ikon fungsional berkoral cuma 2,56:1, di
   bawah lantai 3:1. Ikon memakai --tinta (14,79:1) atau --redup (6,37:1).
   Brief W2 meminta "icon in accent at the top left" pada enam kartu angka, permintaan itu SENGAJA TIDAK dituruti, dan alasannya angka, bukan selera:
   ikon 20px berkoral di atas panel #F1ECFB cuma 2,34:1. Warnanya jadi tinta;
   yang beraksen kotak alasnya (.ikon-kotak), bukan garis ikonnya. */

/* -----------------------------------------------------------------------------
   8. KARTU, border 1px, TANPA bayangan (DESIGN.md)
   -------------------------------------------------------------------------- */
.kartu {
  background: var(--kertas); border: 1px solid var(--garis);
  border-radius: var(--radius); padding: var(--r4);
}
.kartu h3 { margin-bottom: var(--r2); }
.kartu > .angka-label { font-size: var(--t-label); font-weight: 600; letter-spacing: .06em;
                        text-transform: uppercase; color: var(--redup); margin: 0; }  /* 6,76:1 di atas kertas */
.kartu > .angka-besar { font-family: var(--f-judul); font-weight: 700; font-size: 1.5rem;
                        line-height: 1.25; color: var(--tinta); margin: var(--r1) 0 var(--r2);
                        font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.kartu p { color: var(--redup); font-size: var(--t-kecil); }

.cip {
  display: inline-block; background: var(--aksen); color: var(--tinta);  /* 5,77:1 */
  font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; padding: 2px var(--r2); border-radius: 4px;
}
.cip-netral { background: var(--nonaktif); color: var(--tinta); }
/* Cip bergaris: teks TINTA di atas kertas, dan bordernya TINTA, bukan aksen.
   Koral 2,56:1 tidak sampai ke lantai 3:1 untuk garis. */
.cip-garis {
  /* inline-flex, BUKAN inline-block warisan .cip: cip bergaris hampir selalu
     membawa ikon, dan sebagai inline-block ikonnya duduk di garis dasar teks lalu
     terlihat seperti glyph yang rusak. Terlihat jelas di kisi cip layanan. */
  display: inline-flex; align-items: center; gap: var(--r2);
  background: var(--kertas); color: var(--tinta);
  border: 1px solid var(--tinta); text-transform: none; letter-spacing: 0;
  font-size: var(--t-kecil); padding: var(--r1) var(--r3);
}

.tautan-panah {
  display: inline-flex; align-items: center; gap: var(--r1);
  font-size: var(--t-kecil); font-weight: 600; text-decoration: none;
  color: var(--tinta); text-underline-offset: 3px;   /* koral GAGAL sebagai teks: 2,56:1 */
}
.tautan-panah:hover { text-decoration: underline; }

/* -----------------------------------------------------------------------------
   9. HERO
   -------------------------------------------------------------------------- */
.hero { display: grid; gap: var(--r5); align-items: center; }
@media (min-width: 900px) { .hero { grid-template-columns: 1.05fr .95fr; gap: var(--r7); } }
.hero-mata { font-size: var(--t-kecil); font-weight: 600; color: var(--redup); letter-spacing: .06em; text-transform: uppercase; }
.hero h1 { margin-block: var(--r3); }
.hero-sub { color: var(--redup); font-size: 1.0625rem; max-width: 56ch; }
.hero-aksi { display: flex; flex-wrap: wrap; gap: var(--r3); margin-top: var(--r5); }
.hero-aksi .tombol { min-height: 52px; }      /* aksi utama di mobile 52px */
.hero-statistik { display: flex; flex-wrap: wrap; gap: var(--r5); margin-top: var(--r5);
                  padding-top: var(--r4); border-top: 1px solid var(--garis); }
.hero-statistik div { min-width: 0; }
.hero-statistik .angka { font-size: 1.25rem; display: block; }
.hero-statistik span:last-child { font-size: var(--t-kecil); color: var(--redup); }
.hero-foto { border-radius: var(--radius); border: 1px solid var(--garis); overflow: hidden; }
.hero-foto img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

/* -----------------------------------------------------------------------------
   10. PANEL DAN PITA BERWARNA
   Dua alas berbeda dan JANGAN tertukar:
   · .panel-lembut  → alas #F1ECFB, dipakai section "Enam angka" (DESIGN.md W2).
                      Teks di atasnya tinta 13,53:1 dan redup 5,83:1, dua-duanya lulus.
   · .pita-statistik / .pita-aksen / .kartu-aksen → alas AKSEN, dan SELURUH teks
                      di atasnya wajib TINTA (5,77:1). Putih di atasnya 2,72:1 GAGAL.
   -------------------------------------------------------------------------- */
.panel-lembut { background: var(--panel); padding-block: var(--r8); }
.panel-lembut .kepala-bagian p { color: var(--redup); }   /* 5,83:1 di atas panel */

.pita-statistik { background: var(--aksen); color: var(--tinta); padding-block: var(--r6); }
.pita-statistik .kisi { gap: var(--r5); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 900px) { .pita-statistik .kisi { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.pita-statistik .angka { font-size: clamp(1.5rem, 3vw, 2rem); display: block; }
.pita-statistik span:last-child:not(.cip):not(.angka) { font-size: var(--t-kecil); }
/* Pita koral ini TERANG, jadi cincin fokus tinta justru paling terlihat di sana.
   Tidak ada pengecualian warna fokus di mana pun pada paket ini. */

/* Kartu hasil kalkulator: isian aksen, SELURUH teksnya tinta (5,77:1). */
.kartu-aksen { background: var(--aksen); color: var(--tinta); border-radius: var(--radius);
               padding: var(--r5); }
.kartu-aksen .rincian > div { border-bottom: 1px solid rgba(36, 28, 74, .18); padding-bottom: var(--r3); }
.kartu-aksen .rincian > div:last-child { border-bottom: 0; }
.kartu-aksen .rincian-nilai { font-family: var(--f-judul); font-weight: 700; font-size: 1.25rem; }

/* Pita kalimat beraksen, sama aturannya, teks tinta. */
.pita-aksen {
  background: var(--aksen); color: var(--tinta); border-radius: var(--radius);
  padding: var(--r5); font-size: 1.0625rem;
}

/* -----------------------------------------------------------------------------
   11. BARIS DAFTAR NATIVE, padanan mobile untuk tabel dan dropdown.
   Tinggi minimal 56px. Dipakai juga di desktop karena polanya memang terbaca.
   -------------------------------------------------------------------------- */
.daftar { border: 1px solid var(--garis); border-radius: var(--radius); background: var(--kertas); }
.baris {
  display: flex; align-items: center; gap: var(--r3);
  min-height: 56px; padding: var(--r3) var(--r4);
  border-bottom: 1px solid var(--garis);
}
.baris:last-child { border-bottom: 0; }
.baris-isi { min-width: 0; flex: 1; }
/* Keduanya WAJIB blok. Sebagai span inline, judul dan keterangannya menyambung
   jadi satu paragraf dan barisnya berhenti terbaca sebagai baris daftar native, terlihat jelas di 390px, tidak terlihat sama sekali dari kode. */
.baris-label { display: block; font-weight: 600; font-size: var(--t-kecil); }
.baris-nilai { display: block; font-size: var(--t-kecil); color: var(--redup); }
/* Baris dua kolom (label kiri, nilai kanan) tetap sebaris: di situ keterangannya
   pendek dan memang berpasangan, bukan judul-dan-penjelasan. */
.baris > .baris-nilai:first-child { display: inline; }
/* TANPA nowrap. Nilai panjang seperti "Monday to Friday 08.00 to 17.00, Saturday
   08.00 to 13.00, GMT+7" tidak bisa membungkus dan mendorong lebar halaman:
   terukur meluber 54px di 320px pada situs 02, dan yang dilaporkan meluber justru
   <main>, bukan span penyebabnya. */
.baris-kanan { margin-left: auto; font-weight: 600; font-size: var(--t-kecil);
               text-align: right; min-width: 0; overflow-wrap: anywhere; }
.baris-kanan.angka { font-weight: 600; }
a.baris { text-decoration: none; }
a.baris:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   12. TABEL, GARIS MENDATAR SAJA, tinggi baris 48px (DESIGN.md).
   Di bawah 768px tabel lebar tetap bisa digulir mendatar di dalam kotaknya
   sendiri; halamannya TIDAK ikut bergeser.
   -------------------------------------------------------------------------- */
.tabel-bungkus { overflow-x: auto; border: 1px solid var(--garis); border-radius: var(--radius);
                 background: var(--kertas);
                 /* WAJIB. Lihat komentar panjang di atas: tanpa ini .hanya-layar-baca
                    di dalam tabel lolos dari pangkasan overflow dan menarik lebar
                    dokumen sampai 263px melewati layar 390px. */
                 position: relative; }
table { border-collapse: collapse; width: 100%; font-size: var(--t-kecil); }
th, td { text-align: left; padding: var(--r3) var(--r4); border-bottom: 1px solid var(--garis);
         height: 48px; }
th { font-weight: 600; background: var(--panel); white-space: nowrap; }  /* tinta 13,53:1 */
/* Angka lajur dua dan seterusnya dibandingkan lawan lajur → tabular. */
td:not(:first-child) { font-variant-numeric: tabular-nums; }
tr:last-child td { border-bottom: 0; }
/* Tabel harga per tingkat kuantitas: kolom "Harga per pcs" ditebalkan supaya
   angka yang dicari pembeli menonjol tanpa harus diwarnai.
   Baris "600–1.199 pcs" disorot dengan ALAS LEMBUT #FDEAE4 (tinta di atasnya
   13,48:1), BUKAN dengan isian aksen penuh: satu baris tabel beraksen penuh
   membuat empat baris lainnya terbaca sebagai nonaktif. Sorotannya tidak pernah
   sendirian, barisnya juga membawa cip bertuliskan "Paling sering dipesan". */
.tabel-harga td:nth-child(2) { font-weight: 700; }
.tabel-harga tr[data-sorot="ya"] > * { background: var(--aksen-alas); }
.tabel-harga tr[data-sorot="ya"] td:first-child { font-weight: 700; }

/* Tabel ukuran dan tabel teknik: seluruh kolom angka rata KANAN dan tabular. */
.tabel-angka-kanan td:not(:first-child), .tabel-angka-kanan th:not(:first-child) { text-align: right; }
.tabel-angka-kanan td:not(:first-child) { font-family: var(--f-judul); font-weight: 700;
                                          font-feature-settings: "tnum" 1; }
/* Sel angka di dalam tabel TIDAK boleh membungkus: "140-150 g/m2" yang patah jadi
   dua baris membuat kolom gramasi terbaca seperti dua nilai berbeda. Aman karena
   tiap tabel duduk di dalam .tabel-bungkus yang overflow-x:auto DAN position:relative,
   jadi kelebihannya bergulir di dalam kotaknya sendiri, bukan menarik lebar halaman.
   Sengaja dibatasi ke td, BUKAN ke .angka: .angka juga dipakai pita statistik hero
   yang tidak punya kotak gulir, dan di sana nowrap justru meluberkan halaman. */
td.angka { white-space: nowrap; }

caption { caption-side: top; text-align: left; padding: var(--r3) var(--r4);
          font-size: var(--t-kecil); color: var(--redup); }

/* -----------------------------------------------------------------------------
   13. CAROUSEL GESER, kartu berikutnya mengintip, ada titik indikator
   -------------------------------------------------------------------------- */
.carousel {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(78%, 320px);
  gap: var(--r4); overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: var(--r3); scrollbar-width: thin;
  /* Geser mendatar ditangkap carousel, gulir tegak halaman tetap jalan. */
  touch-action: pan-y;
}
.carousel > * { scroll-snap-align: start; }
@media (min-width: 900px) {
  .carousel { grid-auto-flow: row; grid-template-columns: repeat(3, minmax(0,1fr));
              overflow: visible; scroll-snap-type: none; }
}
.titik { display: flex; gap: var(--r2); justify-content: center; margin-top: var(--r3); }
.titik span { width: 6px; height: 6px; border-radius: 50%; background: var(--garis-kendali); opacity: .35; }
.titik span[data-aktif="ya"] { opacity: 1; width: 18px; border-radius: 3px; }
@media (min-width: 900px) { .titik { display: none; } }

/* -----------------------------------------------------------------------------
   14. TIMELINE, tegak di mobile, mendatar di layar lebar.
   ⚠️ ENAM kolom di paket ini, bukan lima. Alur "Dari brief sampai barang dikirim"
   punya enam langkah (W9), dan grid lima kolom membuat langkah keenam turun
   sendirian ke baris kedua, terlihat jelas sesudah dirender, tidak terlihat
   sama sekali dari kode. Jumlah kolom timeline karena itu selalu ikut diperiksa
   saat menyalin tema.
   -------------------------------------------------------------------------- */
.timeline { position: relative; padding-left: 44px; }
.timeline::before {
  content: ""; position: absolute; left: 15px; top: 12px; bottom: 12px;
  width: 2px; background: var(--garis);
}
.langkah { position: relative; padding-bottom: var(--r5); }
.langkah:last-child { padding-bottom: 0; }
.langkah-nomor {
  position: absolute; left: -44px; top: 0; width: 32px; height: 32px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--aksen); color: var(--tinta);         /* 5,77:1 */
  font-family: var(--f-judul); font-weight: 700; font-size: var(--t-kecil);
}
.langkah h3 { font-size: 1.0625rem; }
.langkah p { color: var(--redup); font-size: var(--t-kecil); margin-top: var(--r1); }
@media (min-width: 900px) {
  .timeline { display: grid; grid-template-columns: repeat(3, minmax(0,1fr));
              gap: var(--r6) var(--r4); padding-left: 0; }
  .timeline::before { display: none; }        /* diganti border per langkah */
  .langkah { padding: calc(var(--r5) + 16px) 0 0; border-top: 2px solid var(--garis); }
  .langkah-nomor { left: 0; top: -16px; }
}
@media (min-width: 1180px) {
  .timeline-6 { grid-template-columns: repeat(6, minmax(0,1fr)); }
}

/* -----------------------------------------------------------------------------
   15. AKORDEON FAQ, <details> asli, jadi tetap bisa dibuka tanpa JavaScript
   -------------------------------------------------------------------------- */
.faq { border: 1px solid var(--garis); border-radius: var(--radius); background: var(--kertas); }
.faq details { border-bottom: 1px solid var(--garis); }
.faq details:last-child { border-bottom: 0; }
.faq summary {
  display: flex; align-items: center; gap: var(--r3); cursor: pointer;
  min-height: 56px; padding: var(--r3) var(--r4);
  font-weight: 600; font-size: var(--t-kecil); list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .ikon { margin-left: auto; transition: transform .2s ease; }
.faq details[open] summary .ikon { transform: rotate(180deg); }
.faq .jawab { padding: 0 var(--r4) var(--r4); color: var(--redup); font-size: var(--t-kecil); }

/* -----------------------------------------------------------------------------
   16. FORMULIR, border kendali WAJIB --garis-kendali (6,37:1), bukan --garis (1,19:1)
   -------------------------------------------------------------------------- */
.bidang { display: block; margin-bottom: var(--r4); }
.bidang > label, .label { display: block; font-size: var(--t-kecil); font-weight: 600; margin-bottom: var(--r2); }
.kolom {
  width: 100%; min-height: 48px; padding: var(--r3);
  /* 16px WAJIB: di bawah itu Safari iOS ikut memperbesar layar saat kolom difokus. */
  font-size: var(--t-isi); font-family: var(--f-isi); color: var(--tinta);
  background: var(--kertas); border: 1px solid var(--garis-kendali);
  border-radius: var(--radius);
}
.kolom::placeholder { color: #6E6790; }   /* 5,24:1 di atas --kertas */
textarea.kolom { min-height: 120px; resize: vertical; }
.bantuan { font-size: var(--t-kecil); color: var(--redup); margin-top: var(--r2); }
.bantuan-galat { color: var(--galat); font-weight: 600; }      /* 6,17:1 */
.bantuan-sukses { color: var(--sukses); font-weight: 600; }    /* 6,17:1 */
.kolom[aria-invalid="true"] { border-color: var(--galat); border-width: 2px; }
.kolom[disabled] { background: var(--nonaktif); color: var(--redup); cursor: not-allowed; }

/* Radio sebaris (W14: tiga pilihan dalam satu baris), target sentuh 48px penuh,
   dan yang terpilih ditandai border DAN alas, bukan warna titik saja. */
.pilihan { display: grid; gap: var(--r2); }
@media (min-width: 640px) { .pilihan { grid-auto-flow: column; grid-auto-columns: 1fr; } }
.pilihan label {
  display: flex; align-items: center; gap: var(--r2); min-height: 48px;
  padding: var(--r2) var(--r3); border: 1px solid var(--garis-kendali);
  border-radius: var(--radius); background: var(--kertas);
  font-size: var(--t-kecil); cursor: pointer;
}
/* accent-color menggambar isian kendali DAN centangnya PUTIH. Putih di atas koral
   cuma 2,72:1, jadi kendalinya bertinta. */
.pilihan input { width: 20px; height: 20px; accent-color: var(--tinta); flex: none; }
.pilihan label:has(input:checked) { border-color: var(--tinta); border-width: 2px; background: var(--aksen-alas); }

/* Segmented control, padanan mobile untuk radio 2 sampai 3 opsi */
.segmen { display: flex; border: 1px solid var(--garis-kendali); border-radius: var(--radius); overflow: hidden; }
.segmen button {
  flex: 1; min-height: 48px; border: 0; background: var(--kertas); cursor: pointer;
  font-family: var(--f-isi); font-size: var(--t-kecil); font-weight: 600; color: var(--tinta);
}
.segmen button + button { border-left: 1px solid var(--garis-kendali); }
.segmen button[aria-pressed="true"] { background: var(--aksen); color: var(--tinta); }

/* -----------------------------------------------------------------------------
   17. PESAN DALAM HALAMAN, supaya implementasi tidak jatuh ke alert() peramban.
   Tidak pernah membawa makna lewat warna saja: selalu ada ikon dan kata.
   -------------------------------------------------------------------------- */
.pesan {
  display: flex; gap: var(--r3); align-items: flex-start;
  padding: var(--r3) var(--r4); border-radius: var(--radius);
  border-left: 4px solid; font-size: var(--t-kecil);
}
.pesan-galat { background: var(--galat-alas); border-color: var(--galat); color: var(--tinta); }
.pesan-peringatan { background: var(--peringatan-alas); border-color: var(--peringatan); color: var(--tinta); }
.pesan-sukses { background: var(--sukses-alas); border-color: var(--sukses); color: var(--tinta); }
.pesan b { display: block; }

/* -----------------------------------------------------------------------------
   18. BAR TAB BAWAH (mobile), navigasi UTAMA di mobile, bukan hamburger
   -------------------------------------------------------------------------- */
.tab-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--kertas); border-top: 1px solid var(--garis);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tab-bar a {
  display: grid; place-items: center; gap: 2px;
  min-height: 56px; padding: var(--r2) var(--r1);
  text-decoration: none; color: var(--redup); font-size: var(--t-label);
}
/* Tab aktif dibedakan warna DAN tebal DAN garis atas, bukan warna saja. */
.tab-bar a[aria-current="page"] { color: var(--tinta); font-weight: 600; box-shadow: inset 0 3px 0 0 var(--aksen); }
.tab-bar .ikon { width: 22px; height: 22px; }
@media (min-width: 900px) { .tab-bar { display: none; } body { padding-bottom: 0; } }

/* -----------------------------------------------------------------------------
   19. BOTTOM SHEET, padanan mobile untuk dropdown
   -------------------------------------------------------------------------- */
.lapis { position: fixed; inset: 0; z-index: 50; background: rgba(36,28,74,.55); display: grid; align-items: end; }
.lapis[hidden] { display: none; }
.sheet {
  background: var(--kertas); border-radius: 12px 12px 0 0;
  padding-bottom: env(safe-area-inset-bottom, 0px); max-height: 80vh; overflow-y: auto;
}
.sheet-pegangan { width: 36px; height: 4px; background: var(--garis-kendali); opacity: .5;
                  border-radius: 2px; margin: var(--r3) auto; }
.sheet-kepala { display: flex; align-items: center; gap: var(--r3); padding: 0 var(--r4) var(--r3);
                border-bottom: 1px solid var(--garis); }
.sheet-kepala h3 { font-size: 1rem; }
.sheet-tutup { margin-left: auto; min-width: 48px; min-height: 48px; display: grid; place-items: center;
               background: none; border: 0; cursor: pointer; color: var(--tinta); }
@media (min-width: 900px) {
  .lapis { align-items: center; justify-items: center; }
  .sheet { border-radius: var(--radius); max-width: 480px; width: 100%; }
}

/* Lightbox foto */
.lightbox img { width: 100%; max-height: 80vh; object-fit: contain; background: #000; }

/* -----------------------------------------------------------------------------
   20. SKELETON MEMUAT, bukan spinner, supaya bentuk halaman sudah terbaca
   -------------------------------------------------------------------------- */
/* display:block WAJIB. Skeleton di lembar komponen ditulis sebagai <span>, dan
   span sebaris mengabaikan height, kedelapan baris tulang runtuh jadi satu garis
   tipis, terlihat hanya sesudah dirender dan tidak terlihat sama sekali dari kode.
   position:relative sudah ada di situs 06 untuk kilau ::after; keduanya dipisah
   supaya alasannya tidak tertukar. */
.tulang { display: block; background: var(--nonaktif); border-radius: var(--radius);
          position: relative; overflow: hidden; }
.tulang::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.65), transparent);
  animation: kilau 1.4s ease-in-out infinite;
}
@keyframes kilau { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.tulang-baris { height: 14px; margin-bottom: var(--r2); }
.tulang-judul { height: 28px; width: 60%; margin-bottom: var(--r3); }
.tulang-foto { aspect-ratio: 4 / 3; }

/* -----------------------------------------------------------------------------
   21. HALAMAN GALAT
   DITINJAU ULANG, KEENAM KALINYA, dan hasilnya BLOK lagi. Angka "404" berkoral
   di atas latar cuma 2,56:1, teks besar sekalipun butuh 3:1, jadi angka
   beraksen di sini gagal dua kali lipat. Polanya karena itu: aksen jadi BLOK,
   angkanya BERTINTA di atasnya (5,77:1). Blok ini tidak pernah boleh disalin
   ke paket berikutnya tanpa dihitung ulang lebih dulu.
   -------------------------------------------------------------------------- */
.galat-kode { font-family: var(--f-judul); font-weight: 700; font-size: clamp(3rem, 12vw, 6rem);
              line-height: 1.1; display: inline-block; padding-inline: var(--r4);
              background: var(--aksen); color: var(--tinta); }           /* 5,77:1 */
/* :not(.galat-kode) WAJIB, dan ini tambalan cacat WARISAN dari situs 01.
   Tanpa itu aturan ini (spesifisitas 0,1,1) menang atas .galat-kode (0,1,0)
   karena ditulis belakangan, dan angka besar 404/500 diam-diam mewarisi
   --redup alih-alih warna yang ditulis untuknya. Terukur di kelima situs:
   02 seharusnya 11,38 jadi 3,87 - 03 seharusnya 4,76 jadi 6,15 -
   04 seharusnya 6,67 jadi 2,60 - 05 seharusnya 4,71 jadi 5,51 -
   06 seharusnya 7,20 jadi 2,56. Angka galat ini teks BESAR, jadi ambang AA-nya
   3:1; yang benar-benar gagal karena itu situs 04 dan 06.
   Cacat ini lolos dari KETIGA audit karena ketiganya membaca teks dan kotak,
   bukan warna terhitung. Yang menemukannya cuma melihat halamannya sendiri. */
.galat-halaman p:not(.galat-kode) { color: var(--redup); }
.galat-aksi { display: flex; flex-wrap: wrap; gap: var(--r3); justify-content: center; }

/* Anak yang dipusatkan lewat place-items:center TIDAK melar: lebarnya lahir dari
   isinya sendiri, jadi satu paragraf panjang bisa melewati viewport, terukur
   10px di 320px pada situs 02, dan yang dilaporkan meluber cuma "p" tanpa kelas,
   mustahil ditebak dari kode. max-width:100% saja TIDAK menutupnya; grid-nya yang
   dicabut. Halaman galat di sini karena itu blok sejak awal, bukan grid. */
.galat-halaman { display: block; text-align: center; padding-block: var(--r9);
                 max-width: 56ch; margin-inline: auto; }
.galat-halaman > * + * { margin-top: var(--r4); }
.galat-halaman > * { max-width: 100%; }

/* -----------------------------------------------------------------------------
   22. FOOTER
   -------------------------------------------------------------------------- */
.footer { background: var(--tinta); color: #fff; padding-block: var(--r7); margin-top: var(--r7); }
.footer a { color: #CFC9E4; text-decoration: none; font-size: var(--t-kecil); }  /* 9,80:1 */
.footer a:hover { color: #fff; text-decoration: underline; }
.footer h4 { font-size: var(--t-label); letter-spacing: .08em; text-transform: uppercase; margin-bottom: var(--r3); }
.footer li { margin-bottom: var(--r2); }
.footer-atas { display: grid; gap: var(--r5); }
@media (min-width: 768px) { .footer-atas { grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--r6); } }
.footer-tentang { color: #CFC9E4; font-size: var(--t-kecil); margin-top: var(--r3); max-width: 40ch; }
.footer-bawah {
  margin-top: var(--r6); padding-top: var(--r4); border-top: 1px solid #453C74;
  display: flex; flex-wrap: wrap; gap: var(--r3); justify-content: space-between;
  font-size: var(--t-kecil); color: #CFC9E4;
}
.footer :focus-visible { outline-color: #fff; }

/* -----------------------------------------------------------------------------
   23. UTILITAS
   -------------------------------------------------------------------------- */
.hanya-layar-baca {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.tumpuk-2 { display: grid; gap: var(--r2); }
.tumpuk-3 { display: grid; gap: var(--r3); }
.tumpuk-4 { display: grid; gap: var(--r4); }
.redup { color: var(--redup); }
.kecil { font-size: var(--t-kecil); }
@media (min-width: 900px) { .hanya-mobile { display: none !important; } }
@media (max-width: 899px) { .hanya-desktop { display: none !important; } }

/* -----------------------------------------------------------------------------
   24. GERAK DIKURANGI, hormati preferensi sistem
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .tulang::after { animation: none; }
}

/* -----------------------------------------------------------------------------
   25. FOTO, POTRET, DAN PENGGANTI FOTO
   Run paket ini hanya menghasilkan DUA foto, dan keduanya memuat teks milik orang
   lain. Lambung kapal di foto pelabuhan membawa wordmark perusahaan pelayaran
   NYATA berukuran besar; polo di potret petugas dibordir "LOGISTICS HUB
   COORDINATOR". Keduanya diselesaikan dengan MEMOTONG BINGKAI.

   Kontainer milik pihak lain di lapangan penumpukan sengaja DIBIARKAN: lapangan
   penumpukan memang berisi kotak orang lain, dan itu tidak menyiratkan afiliasi, sekelas merek mesin (Komatsu) di paket 02. Yang tidak boleh justru wordmark
   pelayaran di lambung kapal, karena forwarder tidak memiliki kapal dan gambarnya
   akan terbaca sebagai klaim kemitraan.

   Lima orang lain yang disebut brief (kepala gudang, kepala perwakilan, spesialis
   kepabeanan) tidak punya potret sama sekali dan memakai .potret-inisial.
   -------------------------------------------------------------------------- */
.gambar-lebar, .foto-kosong {
  aspect-ratio: 4 / 3; width: 100%; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--garis); background: var(--nonaktif);
}
.foto-kosong {
  display: grid; place-content: center; justify-items: center; gap: var(--r2);
  color: var(--redup);                                  /* 5,44:1 di atas --nonaktif */
  background-color: var(--nonaktif);
  background-image: linear-gradient(var(--garis) 1px, transparent 1px),
                    linear-gradient(90deg, var(--garis) 1px, transparent 1px);
  background-size: 16px 16px;
}
.foto-kosong span {
  font-family: var(--f-isi); font-weight: 600; font-size: var(--t-label);
  letter-spacing: .08em; background: var(--kertas); padding: 2px var(--r2);
  border-radius: 4px; border: 1px solid var(--garis); text-align: center;
}

.potret {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--garis); margin-bottom: var(--r3);
}
.potret-inisial {
  display: grid; place-items: center; background: var(--aksen-alas); color: var(--tinta);
  font-family: var(--f-judul); font-weight: 700; font-size: 1.75rem; letter-spacing: .04em;
}   /* 13,48:1 */

/* Tombol pembungkus foto yang bisa diperbesar, tetap terlihat sebagai gambar */
.foto-tombol { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }
.foto-tombol img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
                   border-radius: var(--radius); border: 1px solid var(--garis); }

/* Pengganti peta, tidak memuat peta pihak ketiga, jadi tidak ada penjejak. */
.peta {
  display: grid; place-content: center; justify-items: center; gap: var(--r3);
  aspect-ratio: 4 / 3; border-radius: var(--radius); border: 1px solid var(--garis);
  color: var(--redup); text-align: center; padding: var(--r4);
  background-color: var(--nonaktif);
  background-image: linear-gradient(var(--garis) 1px, transparent 1px),
                    linear-gradient(90deg, var(--garis) 1px, transparent 1px);
  background-size: 24px 24px;
}
.peta span { font-size: var(--t-kecil); max-width: 28ch; }

/* Dua kolom di layar lebar, satu kolom di mobile. */
@media (min-width: 900px) {
  [data-dua-kolom] { grid-template-columns: 1fr 1fr; align-items: start; }
  /* Kalkulator: kartu kendali di kiri, kartu hasil beraksen di kanan (W7). */
  .kalk-tata { grid-template-columns: 1.1fr .9fr; gap: var(--r6) !important; align-items: start; }
  /* Bahan: tabel gramasi dua-pertiga di kiri, kartu stok sepertiga di kanan (W5). */
  .bahan-tata { grid-template-columns: 2fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Mesin: foto lantai produksi di kiri, enam baris kapasitas di kanan (W10). */
  .mesin-tata { grid-template-columns: 1fr 1.1fr; gap: var(--r6) !important; align-items: start; }
  /* Tabel ukuran: tabel di kiri, ilustrasi berlabel di kanan (W8). */
  .ukuran-tata { grid-template-columns: 1.5fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Kontak: pengganti peta di kiri, alamat dan jam kerja di kanan (W15). */
  .kontak-tata { grid-template-columns: 1fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Minta penawaran: formulir di kiri, kartu ringkasan yang lebih sempit di kanan.
     align-items:start WAJIB, tanpa itu kartu ringkasan yang isinya empat baris
     ikut melar setinggi formulir tiga belas kolom, dan yang terlihat pengunjung
     adalah kartu setengah kosong sepanjang layar. */
  .rfq-tata { grid-template-columns: 1.5fr 1fr; gap: var(--r6) !important; align-items: start; }
}

/* -----------------------------------------------------------------------------
   26. PENCARI, bar pencari produk (W4): tiga <select> berdampingan + tombol
   -------------------------------------------------------------------------- */
.pencari { display: grid; gap: var(--r3); align-items: end; margin-bottom: var(--r6); }
@media (min-width: 900px) { .pencari { grid-template-columns: repeat(3, minmax(0,1fr)) auto; } }
.pencari .bidang { margin: 0; }
.pencari .tombol { min-height: 48px; }

/* -----------------------------------------------------------------------------
   27. RAPI-RAPI DI BAWAH 900px, semuanya hanya terlihat setelah dirender
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {
  /* Tombol navbar membungkus jadi dua baris dan mendesak wordmark sampai nyaris
     tak terbaca. Di mobile aksi ini juga sudah ada di bar tab bawah, jadi di sini
     ia cukup ringkas: tanpa ikon, tanpa membungkus, padding lebih rapat. */
  .navbar .tombol { padding-inline: var(--r3); white-space: nowrap; font-size: var(--t-label); }
  .navbar .tombol .ikon { display: none; }
  .wordmark { font-size: 0.75rem; letter-spacing: .04em; }

  /* Aksi utama melebar penuh supaya lebarnya seragam dan mudah dijangkau jempol. */
  .hero-aksi { flex-direction: column; align-items: stretch; }
  .hero-aksi .tombol { width: 100%; }
}

/* -----------------------------------------------------------------------------
   28. PONSEL SEMPIT (≤ 380px), iPhone SE dan Android kecil
   Label tab turun ke 11px dan padding dirapatkan. Wordmark paket ini tiga kata,
   jadi ia ikut mengecil.
   -------------------------------------------------------------------------- */
@media (max-width: 380px) {
  :root { --tepi: 1rem; }
  .tab-bar a { font-size: 0.6875rem; padding-inline: 2px; min-width: 0; }
  .tab-bar a > :last-child { max-width: 100%; overflow-wrap: anywhere; text-align: center; line-height: 1.15; }
  .tab-bar .ikon { width: 20px; height: 20px; }
  .wordmark { font-size: 0.625rem; }

  /* TERUKUR, bukan ditaksir: di 320px wordmark panjang plus tombol berlabel panjang
     yang TIDAK boleh membungkus mendorong lebar halaman. Label tombol didiktekan
     brief dan diuji verbatim, jadi yang dicabut nowrap-nya. Diwarisi dari situs 03
     dan 04; wordmark paket ini "CAKRA SANDANG GARMENT" tiga kata dan tombolnya
     berlabel "Minta Penawaran", dua-duanya panjang, jadi nowrap-nya yang dicabut. */
  .navbar .tombol { white-space: normal; text-align: center; line-height: 1.2;
                    padding-inline: var(--r2); }
}

/* Tombol sunting di baris ringkasan wizard */
.sunting {
  margin-left: auto; min-width: 44px; min-height: 44px;
  display: grid; place-items: center; background: none;
  border: 1px solid var(--garis); border-radius: var(--radius); cursor: pointer;
}
.sunting:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   29. TABEL BIAYA, kolom rupiah rata KANAN dan tabular
   -------------------------------------------------------------------------- */
.tabel-biaya td:last-child, .tabel-biaya th:last-child { text-align: right; }
.tabel-biaya td:last-child { font-weight: 600; font-variant-numeric: tabular-nums; }

/* -----------------------------------------------------------------------------
   30. KOTAK IKON, bingkai lembut untuk ikon lima aksi, layanan, dan industri.
   Alasnya --aksen-alas dan ikonnya TINTA (13,48:1). Ikon beraksen dilarang di
   sini: koral di atas alas lembut jatuh jauh di bawah 3:1.
   -------------------------------------------------------------------------- */
.ikon-kotak {
  width: 44px; height: 44px; flex: none; display: grid; place-items: center;
  border-radius: var(--radius); background: var(--aksen-alas); color: var(--tinta);
  margin-bottom: var(--r3);
}

/* -----------------------------------------------------------------------------
   31. BARIS INFO BERIKON, dipakai untuk rambu harga, catatan gramasi, dan syarat.
   Ikonnya --redup (6,37:1): barisnya sering panjang dan ikon di sini berfungsi
   sebagai penanda jenis, bukan sebagai aksi.
   -------------------------------------------------------------------------- */
.info-baris { display: flex; gap: var(--r3); align-items: flex-start;
              font-size: var(--t-kecil); color: var(--redup); }
.info-baris .ikon { margin-top: 2px; }
.info-baris b { color: var(--tinta); }

/* Rambu "ini estimasi", muncul di beberapa tempat dan sengaja seragam.
   Garis kirinya PERINGATAN (6,90:1), bukan aksen: ia bukan promosi, ia batas. */
.rambu {
  display: flex; gap: var(--r3); align-items: flex-start;
  background: var(--peringatan-alas); border-left: 4px solid var(--peringatan);
  border-radius: var(--radius); padding: var(--r3) var(--r4);
  font-size: var(--t-kecil); color: var(--tinta);
}

/* Cip berbentuk KALIMAT (pil status di hero, cip "hampir penuh"). Cip biasa memakai
   huruf besar semua dan itu benar untuk satu-dua kata; untuk satu kalimat penuh ia
   berhenti terbaca. Bentuknya sama, hurufnya tidak dipaksa. */
.cip-kalimat {
  display: inline-flex; align-items: center; gap: var(--r2);
  text-transform: none; letter-spacing: 0; font-size: var(--t-kecil);
  padding: var(--r2) var(--r4);
}

/* Lima kolom hanya di layar yang benar-benar cukup lebar. Di bawah itu ia turun ke
   tiga lalu dua, bukan memaksa lima kartu sempit yang judulnya patah tiap kata. */
/* Pil status hero berdiri sendiri di atas eyebrow. p{margin:0} membuat keduanya
   berdempetan sampai terbaca seperti satu blok, terlihat di 390px maupun 1440px,
   dan tidak terlihat sama sekali dari kode. */
.hero .cip { margin-bottom: var(--r3); }

/* Pesan "ini desain contoh" yang muncul sesudah tombol yang memang tidak punya
   tujuan nyata. Tersembunyi sampai ditekan, dan isinya ditulis JS. */
.pesan-contoh { margin-top: var(--r3); }

@media (min-width: 1100px) { .kisi-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 900px) and (max-width: 1099px) { .kisi-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 640px) and (max-width: 899px) { .kisi-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* -----------------------------------------------------------------------------
   33. PENGGESER JUMLAH PESANAN (W7), <input type="range"> asli, jadi tetap bisa
   dipakai keyboard dan pembaca layar tanpa satu baris JavaScript pun.
   Alurnya diberi border --garis-kendali (6,76:1 di atas kertas) supaya tepinya
   terlihat tanpa mengandalkan warna; ibu jarinya isian aksen bergaris tinta.
   -------------------------------------------------------------------------- */
.penggeser { width: 100%; height: 48px; margin: 0; background: none; accent-color: var(--tinta); }
.penggeser-tanda { display: flex; justify-content: space-between; font-size: var(--t-label);
                   color: var(--redup); font-variant-numeric: tabular-nums; }
.penggeser-nilai { font-family: var(--f-judul); font-weight: 700; font-size: 1.5rem;
                   font-feature-settings: "tnum" 1; display: block; }

/* Baris berkas terlampir di bawah area unggah (W14). */
.berkas-baris { display: flex; align-items: center; gap: var(--r3); min-height: 56px;
                padding: var(--r2) var(--r3); margin-top: var(--r3);
                border: 1px solid var(--garis); border-radius: var(--radius);
                background: var(--kertas); font-size: var(--t-kecil); }
.berkas-baris .berkas-ukuran { margin-left: auto; color: var(--redup);
                               font-variant-numeric: tabular-nums; white-space: nowrap; }
.berkas-hapus { min-width: 44px; min-height: 44px; display: grid; place-items: center;
                background: none; border: 1px solid var(--garis); border-radius: var(--radius);
                color: var(--tinta); cursor: pointer; }
.berkas-hapus:hover { background: var(--sentuh); }

/* Deret wordmark klien, TEKS abu-abu, bukan logo merek nyata (ATURAN-KONTEN §2c). */
.wordmark-klien { display: grid; gap: var(--r4); grid-template-columns: repeat(2, minmax(0,1fr));
                  align-items: center; margin-top: var(--r6); }
@media (min-width: 700px) { .wordmark-klien { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 1024px) { .wordmark-klien { grid-template-columns: repeat(6, minmax(0,1fr)); } }
.wordmark-klien span { font-family: var(--f-judul); font-weight: 700; font-size: var(--t-label);
                       letter-spacing: .08em; color: var(--redup); text-align: center;
                       overflow-wrap: anywhere; }   /* 6,37:1 */

/* -----------------------------------------------------------------------------
   34. LIMA UBIN AKSI, baris pertama di bawah lipatan, dan yang menentukan
   vertikal ini. Lima kolom hanya di layar yang cukup lebar; di bawah itu turun ke
   tiga lalu dua, bukan lima ubin sempit yang labelnya patah tiap kata.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) { .kisi-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 900px) and (max-width: 1099px) { .kisi-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 560px) and (max-width: 899px) { .kisi-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
a.kartu { text-decoration: none; display: block; }
a.kartu:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   35. BATANG KETEPATAN, dihidupkan kembali (kelas ini ada di situs 04, dibuang di
   situs 05 karena tidak terpakai). Koral 2,56:1 tidak pernah sendirian membawa
   makna: tiap batang membawa label kiri, persen bertinta, dan keterangan kanan.
   Alurnya diberi border supaya tepinya terlihat tanpa mengandalkan warna.
   -------------------------------------------------------------------------- */
.batang { display: grid; gap: var(--r4); }
/* EMPAT kolom, bukan tiga: barisnya memang punya empat anak (label, persen, alur,
   jumlah sampel). Dengan tiga kolom anak keempat jatuh ke baris berikutnya dan
   jumlah sampel tampil di bawah labelnya, terlihat jelas sesudah dirender, dan
   tidak terlihat sama sekali dari kode. */
.batang-baris { display: grid; grid-template-columns: 12rem 5rem 1fr 11rem; gap: var(--r3);
                align-items: center; font-size: var(--t-kecil); }
.batang-nilai { font-family: var(--f-judul); font-weight: 700; font-size: 1.25rem;
                font-variant-numeric: tabular-nums; }
.batang-alur { height: 12px; background: var(--garis); border: 1px solid var(--garis-kendali);
               border-radius: 999px; overflow: hidden; }
.batang-isi { display: block; height: 100%; background: var(--aksen); }
.batang-sampel { color: var(--redup); }
.batang-total { border-top: 2px solid var(--tinta); padding-top: var(--r4); }
@media (max-width: 700px) {
  .batang-baris { grid-template-columns: 1fr auto; }
  .batang-alur, .batang-sampel { grid-column: 1 / -1; }
}

/* -----------------------------------------------------------------------------
   36. KARTU PRODUK DAN KARTU PORTOFOLIO, foto di atas, isi di bawah.
   Rasio fotonya dikunci supaya enam kartu sejajar walaupun berkas sumbernya
   berbeda-beda bentuk; object-fit:cover yang memotongnya, bukan tata letak.
   -------------------------------------------------------------------------- */
.kartu-foto { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.kartu-foto > img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.kartu-foto-isi { padding: var(--r4); display: flex; flex-direction: column; gap: var(--r2);
                  flex: 1; min-width: 0; }
.kartu-foto-isi .harga { font-family: var(--f-judul); font-weight: 700; font-size: 1.0625rem;
                         font-feature-settings: "tnum" 1; }
.kartu-foto-isi .tautan-panah { margin-top: auto; }
.kartu-hasil { display: grid; gap: var(--r2); margin-top: var(--r3); }
.kartu-hasil > div { display: flex; gap: var(--r3); font-size: var(--t-kecil);
                     border-top: 1px solid var(--garis); padding-top: var(--r2); }
.kartu-hasil dt, .kartu-hasil .hasil-label { flex: 1; min-width: 0; color: var(--redup); }
.kartu-hasil dd, .kartu-hasil .hasil-nilai { margin: 0; font-weight: 600; text-align: right;
                                             min-width: 0; overflow-wrap: anywhere; }

/* -----------------------------------------------------------------------------
   37. UNGGAH BERKAS, area seret-dan-lepas desain pada formulir penawaran (W14).
   Bordernya --garis-kendali (6,76:1), bukan --garis: ia area yang bisa diklik.
   -------------------------------------------------------------------------- */
.unggah {
  display: grid; place-items: center; gap: var(--r2); text-align: center;
  padding: var(--r6) var(--r4); border: 2px dashed var(--garis-kendali);
  border-radius: var(--radius); background: var(--kertas); cursor: pointer;
  font-size: var(--t-kecil); color: var(--redup);
}
.unggah:hover { background: var(--sentuh); }

/* -----------------------------------------------------------------------------
   38. PENANDA PETA BERNOMOR, isian aksen dengan angka BERTINTA di atasnya
   -------------------------------------------------------------------------- */
/* Kolom bersatuan (kg, m³). DESIGN.md meminta satuannya menempel di kolomnya,
   bukan jadi baris bantuan terpisah di bawah, di baris bantuan ia terbaca sebagai
   keterangan, bukan sebagai bagian dari angka yang sedang diketik. */
.kolom-satuan { display: flex; align-items: center; gap: var(--r2); }
.kolom-satuan .kolom { flex: 1; min-width: 0; }
.kolom-satuan span { font-weight: 600; white-space: nowrap; }

.pin { display: inline-grid; place-items: center; width: 28px; height: 28px; flex: none;
       border-radius: 50%; background: var(--aksen); color: var(--tinta);
       font-family: var(--f-judul); font-weight: 700; font-size: var(--t-kecil); }

/* -----------------------------------------------------------------------------
   39. BARIS RINCIAN BIAYA, label kiri, angka kanan tabular
   -------------------------------------------------------------------------- */
.rincian { display: grid; gap: var(--r3); }
.rincian > div { display: flex; gap: var(--r3); align-items: baseline; font-size: var(--t-kecil); }
.rincian dt, .rincian .rincian-label { flex: 1; min-width: 0; }
.rincian dd, .rincian .rincian-nilai { margin: 0; font-variant-numeric: tabular-nums;
                                       font-weight: 600; white-space: nowrap; }
.rincian-total { border-top: 2px solid var(--tinta); padding-top: var(--r3); font-size: var(--t-isi) !important; }
.rincian-total .rincian-nilai { font-size: 1.25rem; font-family: var(--f-judul); }
