@charset "utf-8";
/* =============================================================================
   Tirtamuara Kargo — desain contoh (perusahaan fiktif)
   Sumber desain: stitch/06-logistik/ (DESIGN.md + PROMPTS-WEB/MOBILE/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 BERAYUN LAGI, DAN ARAHNYA BERBALIK DARI PAKET 05. Cyan #06B6D4 cuma
   2,26:1 di atas latar — di BAWAH lantai 3:1 untuk border, ikon fungsional, dan
   cincin fokus, dan jauh di bawah 4,5:1 untuk teks. Ia ISIAN saja. Teks DI ATAS
   aksen wajib TINTA (7,20:1); putih di atasnya cuma 2,43:1 dan GAGAL AA.

   Cyan adalah warna klasik yang TERLIHAT berkontras tinggi dan sebenarnya tidak.
   Itu sebabnya tiap tempat aksen dipakai ditinjau ulang saat menyalin dari situs
   05, bukan diikutkan begitu saja: di situs 05 aksen boleh jadi teks, di sini
   tidak boleh sama sekali. Rantainya sekarang berselang-seling penuh —
   02 isian · 03 teks · 04 isian · 05 teks · 06 isian.

   ⛔ RAMBU ISI (DESIGN.md): TIDAK ADA nomor izin, nomor registrasi PPJK, nomor
   NIB, maupun nomor sertifikat di mana pun — cukup jenis, penerbit, dan status.
   Tarif dan waktu transit selalu disebut ESTIMASI berikut apa yang mengubahnya.

   SATU KELUARGA HURUF SAJA (IBM Plex Sans). Judul 600, isi 400 — dan 600 juga
   dipakai untuk teks tebal, jadi benar-benar dua bobot, bukan tiga.
   ========================================================================== */

@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, bukan disalin dari brief.
   Catatan: berbeda dengan paket 02, angka di DESIGN.md paket ini TERBUKTI BENAR —
   4,76 · 5,01 · 3,25 · 15,48 · 6,15 semuanya cocok sampai dua desimal.
   -------------------------------------------------------------------------- */
:root {
  /* Permukaan */
  --latar:        #F4F7FA;   /* alas halaman */
  --kertas:       #FFFFFF;   /* alas kartu di atas --latar */
  --sentuh:       #E9EFF6;   /* hover/tekan; tinta di atasnya 15,00:1 */

  /* Teks */
  --tinta:        #0A1A2F;   /* 16,25:1 di atas --latar — teks utama, ukuran apa pun */
  --redup:        #55617A;   /* 5,78:1 di atas --latar — teks sekunder, LULUS AA */

  /* Aksen — ISIAN SAJA, dan larangannya lebih ketat daripada paket mana pun */
  --aksen:        #06B6D4;   /* 2,26:1 di atas latar → ISIAN saja: tombol, cip, pita,
                                nomor langkah, batang diagram, penanda peta.
                                DILARANG jadi warna teks, garis, border kendali,
                                cincin fokus, atau ikon fungsional — semuanya butuh
                                minimal 3:1 dan cyan ini tidak sampai.
                                Teks DI ATAS aksen wajib --tinta (7,20:1);
                                putih di atasnya 2,43:1 dan GAGAL AA. */
  --aksen-tekan:  #04A0BC;   /* keadaan ditekan; tinta di atasnya 5,63:1 */
  --aksen-alas:   #DCF2F7;   /* alas lembut; yang di atasnya wajib tinta */
  --nonaktif:     #E4EAF2;   /* alas kendali mati; redup di atasnya 4,93:1 */

  /* Garis */
  --garis:        #D9E1EC;   /* 1,23:1 — DEKORATIF saja (pemisah, border kartu).
                                DILARANG untuk border kendali interaktif. */
  --garis-kendali:#55617A;   /* 5,78:1 — border input, checkbox, tombol outline. */

  /* Semantik — dihitung terhadap --latar */
  --sukses:       #0F6B45;   /* 6,10:1 */
  --galat:        #B3261E;   /* 6,09:1 */
  --peringatan:   #7A4B00;   /* 6,90:1 */
  --sukses-alas:  #E3F0E9;
  --galat-alas:   #F9E9E7;
  --peringatan-alas:#F6EEDD;

  /* Huruf. IBM Plex Sans, DUA bobot: 400 untuk isi, 600 untuk judul DAN untuk
     teks tebal. Berkas woff2-nya satu untuk kedua bobot — Plex v23 huruf VARIABEL
     dengan sumbu wght 100–700, persis seperti Inter di situs 01–05. Itu benar,
     bukan salah salin.
     ⚠️ U+2192 (→) TIDAK ADA di subset latin Plex, padahal rentangnya menyebutnya.
     Tabel rute memakai tanda itu belasan kali, jadi belasan aksara dirender huruf
     cadangan sistem. Dibiarkan dengan sengaja: menggantinya dengan ikon membuat
     teks layar berhenti sama dengan kalimat brief, dan uji verbatim membandingkan
     TEKS, bukan rupa. Rantai cadangan karena itu diisi huruf sistem yang pasti
     punya glif panah. */
  --f-judul: "IBM Plex Sans", ui-sans-serif, "Segoe UI", system-ui, sans-serif;
  --f-isi:   "IBM Plex Sans", 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: 8px;                    /* DESIGN.md: radius 8px maksimum */
  --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: 600; 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, tarif, dan waktu transit: Plex 600 dengan angka TABULAR.
   DESIGN.md menyebutnya eksplisit — tabel tarif hanya sejajar kalau angkanya
   tabular, dan halaman ini punya tiga tabel angka sekaligus. */
.angka { font-family: var(--f-judul); font-weight: 600; font-variant-numeric: tabular-nums; }

/* CINCIN FOKUS — SELALU 2px tinta dengan offset 2px. Di paket ini bukan lagi
   pilihan melainkan keharusan: cyan 2,26:1 tidak sampai ke lantai 3:1, jadi cincin
   fokus beraksen adalah cincin fokus yang tidak terlihat. DESIGN.md menyebutnya
   eksplisit bersama border dan ikon fungsional. */
: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;   /* 16,29: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: 600; 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); }   /* 7,20:1 */
.tombol-utama:hover { background: var(--aksen-tekan); }            /* 5,63:1 */
.tombol-utama:active { background: var(--aksen-tekan); }
.tombol-kedua { border-color: var(--garis-kendali); color: var(--tinta); }  /* 5,78: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 bercyan cuma 2,26:1, di bawah
   lantai 3:1. Ikon memakai --tinta (16,25:1) atau --redup (5,78:1). Kelas ini ADA
   di situs 05 dan sengaja DICABUT di sini — inilah tempat menyalin paling berbahaya. */

/* -----------------------------------------------------------------------------
   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 p { color: var(--redup); font-size: var(--t-kecil); }

.cip {
  display: inline-block; background: var(--aksen); color: var(--tinta);  /* 7,20: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); }
/* DESIGN.md paket ini: cip status = teks TINTA di atas alas lembut, plus kata
   statusnya dieja. Bordernya TINTA, bukan aksen — cyan 2,26:1 tidak sampai ke
   lantai 3:1 untuk garis. Persis kebalikan aturan cip situs 05. */
.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;   /* cyan GAGAL sebagai teks: 2,26: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. PITA STATISTIK BERAKSEN — SELURUH teks di atasnya wajib TINTA.
   Terhitung: tinta di atas cyan #06B6D4 7,20:1 LULUS, putih di atasnya 2,43:1 GAGAL.
   Persis KEBALIKAN paket 05, yang persis kebalikan paket 04. Berayun, bukan
   berkembang — dan itu sebabnya blok ini tidak pernah boleh disalin tanpa dihitung.
   -------------------------------------------------------------------------- */
.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(5, minmax(0,1fr)); } }
.pita-statistik .angka { font-size: clamp(1.5rem, 3vw, 2rem); display: block; }
.pita-statistik span:last-child { font-size: var(--t-kecil); }
/* Pita cyan ini TERANG, jadi cincin fokus tinta justru paling terlihat di sana.
   Pengecualian warna fokus yang ada di situs 05 DICABUT di sini — sekali lagi
   karena diukur, bukan karena selera. */

/* 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(--sentuh); white-space: nowrap; }  /* 13,93: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 rute: kolom "Mulai dari" ditebalkan supaya angka yang dicari pengirim
   menonjol tanpa harus diwarnai. Baris subjudul kelompok (Domestik / Internasional)
   memakai th yang membentang penuh, jadi kelompoknya terbaca pembaca layar juga. */
.tabel-rute td:nth-child(5) { font-weight: 600; }
.tabel-rute th[colspan] { background: var(--sentuh); text-transform: uppercase;
                          letter-spacing: .06em; font-size: var(--t-label); }
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.
   ⚠️ Paket ini TIDAK memakai timeline mendatar sama sekali. Yang dibutuhkan
   riwayat pelacakan enam langkah yang SELALU tegak (halaman /lacak), karena
   urutannya kronologis dan tiap langkah membawa tanggal, jam, judul, dan
   keterangan — empat baris yang tidak pernah muat di satu kolom mendatar.
   Kelasnya .timeline-tegak di bagian 36; .timeline mendatar dibiarkan utuh
   supaya struktur berkas tetap sebangun dengan situs 01–05.
   -------------------------------------------------------------------------- */
.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);         /* 7,20:1 */
  font-family: var(--f-judul); font-weight: 600; 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(5, minmax(0,1fr));
              gap: var(--r5) 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; }
}

/* -----------------------------------------------------------------------------
   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,15:1), bukan --garis (1,24: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: #6B7280; }
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,75:1 */
.bantuan-sukses { color: var(--sukses); font-weight: 600; }    /* 6,93: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 cyan
   cuma 2,43:1, jadi kendalinya bertinta — kebalikan situs 05, sama seperti 04. */
.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(10,26,47,.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
   -------------------------------------------------------------------------- */
.tulang { 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
   DITUKAR LAGI — KELIMA KALINYA. Peringatan yang ditulis di situs 05 ("jangan
   menyalin blok ini ke paket 06 tanpa menghitung ulang") ternyata memang perlu:
   cyan 2,26:1 membuat angka beraksen nyaris tak terbaca, jadi polanya kembali ke
   bentuk situs 02 dan 04 — aksen jadi BLOK, angkanya bertinta di atasnya (7,20:1).
   -------------------------------------------------------------------------- */
.galat-kode { font-family: var(--f-judul); font-weight: 600; font-size: clamp(3rem, 12vw, 6rem);
              line-height: 1.1; display: inline-block; padding-inline: var(--r4);
              background: var(--aksen); color: var(--tinta); }           /* 7,20:1 */
.galat-halaman p { 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: #C3C9D6; text-decoration: none; font-size: var(--t-kecil); }  /* 9,60: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: #C3C9D6; 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 #24334A;
  display: flex; flex-wrap: wrap; gap: var(--r3); justify-content: space-between;
  font-size: var(--t-kecil); color: #C3C9D6;
}
.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);                                  /* 4,93: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: 600; font-size: 1.75rem; letter-spacing: .04em;
}

/* 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 pelacak. */
.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; }
  /* Hitung tarif: formulir dua-pertiga di kiri, kartu hasil sepertiga di kanan. */
  .tarif-tata { grid-template-columns: 2fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Jaringan: peta di kiri, daftar enam lokasi di kanan. */
  .jaringan-tata { grid-template-columns: 1fr 1.1fr; gap: var(--r6) !important; align-items: start; }
  /* Pelacakan: riwayat di kiri, dua kartu sisi di kanan. */
  .lacak-tata { grid-template-columns: 1.6fr 1fr; gap: var(--r6) !important; align-items: start; }
  /* Minta tarif: 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 — dipakai di halaman rute sebagai penyaring asal dan tujuan
   -------------------------------------------------------------------------- */
.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 "TIRTAMUARA KARGO" dua kata tapi tombolnya
     berlabel "Minta Tarif" dan tetap tidak boleh membungkus. */
  .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 TARIF — 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. Di situs 05 ikonnya beraksen; di sini
   tidak boleh, karena cyan 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, catatan tarif, dan syarat dokumen.
   Ikonnya --redup (5,78: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. KARTU LACAK — kolom resi di dalam hero, dengan tombol di sebelahnya
   -------------------------------------------------------------------------- */
.lacak-kartu { background: var(--kertas); border: 1px solid var(--garis);
               border-radius: var(--radius); padding: var(--r4); margin-top: var(--r5); }
.lacak-baris { display: grid; gap: var(--r3); }
@media (min-width: 560px) { .lacak-baris { grid-template-columns: 1fr auto; align-items: end; } }
.lacak-baris .bidang { margin: 0; }
.lacak-baris .tombol { min-height: 48px; }

/* -----------------------------------------------------------------------------
   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). Cyan 2,26:1 tidak pernah sendirian membawa
   makna: tiap batang membawa label kiri, persen bertinta, dan jumlah sampel 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: 600; 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. RIWAYAT PELACAKAN — timeline yang SELALU tegak, tidak pernah mendatar.
   Langkah berjalan ditandai isian aksen DAN kata "Berjalan sekarang"; langkah
   mendatang bertinta redup DAN berlabel "Perkiraan". Tidak ada keadaan yang
   maknanya hanya di warna.
   -------------------------------------------------------------------------- */
.riwayat { position: relative; padding-left: 44px; }
.riwayat::before { content: ""; position: absolute; left: 15px; top: 12px; bottom: 12px;
                   width: 2px; background: var(--garis-kendali); }
.riwayat li { position: relative; padding-bottom: var(--r6); }
.riwayat li:last-child { padding-bottom: 0; }
.riwayat-tanda {
  position: absolute; left: -44px; top: 0; width: 32px; height: 32px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--kertas); border: 2px solid var(--tinta); color: var(--tinta);
}
.riwayat-tanda[data-keadaan="kini"] { background: var(--aksen); border-color: var(--tinta); }
.riwayat-tanda[data-keadaan="nanti"] { border-color: var(--redup); color: var(--redup); }
.riwayat-waktu { display: block; font-size: var(--t-kecil); color: var(--redup);
                 font-variant-numeric: tabular-nums; }
.riwayat h3 { font-size: 1.0625rem; margin-top: var(--r1); }
.riwayat p { color: var(--redup); font-size: var(--t-kecil); margin-top: var(--r1); }
.riwayat li[data-keadaan="nanti"] h3 { color: var(--redup); }

/* -----------------------------------------------------------------------------
   37. UNGGAH BERKAS — dihidupkan kembali untuk formulir minta tarif.
   Bordernya --garis-kendali (5,78: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: 600; 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); }
