/* Gaya yang tidak bisa dinyatakan dengan utility Tailwind, atau yang lebih
 * baik ditulis sekali di sini daripada ditempel di setiap elemen.
 *
 * Tailwind tetap dipakai untuk tata letak. Yang ada di sini cuma tiga hal:
 * tipografi dasar, keadaan interaksi, dan hal-hal aksesibilitas yang wajib
 * berlaku menyeluruh dan tidak boleh bergantung pada kedisiplinan penulis
 * template.
 */

:root {
  /* Satu aksen saja. Hijau dicabut dari tombol export di T-410, karena empat
   * warna aksen yang bersaing membuat tampilan terasa tidak diputuskan.
   * Kuning dan merah bukan aksen: keduanya penanda keadaan, dan artinya
   * dijaga tetap satu. Kuning berarti peringatan, merah berarti kegagalan
   * atau data palsu. */
  --aksen: #1d4ed8;
  --aksen-gelap: #1e40af;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: 'Fira Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI',
    sans-serif;
  /* Angka tabular di seluruh halaman. Tanpa ini kolom angka tidak sejajar,
   * dan tabel angka yang tidak sejajar memaksa mata membaca digit per digit
   * alih-alih membandingkan panjangnya. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* Angka di sel data pakai Fira Code. Lebarnya benar-benar sama antar digit,
 * jadi perbandingan antar baris bisa dilakukan dengan melihat, bukan membaca. */
.angka {
  font-family: 'Fira Code', ui-monospace, 'SF Mono', monospace;
  font-variant-numeric: tabular-nums;
  font-size: 0.9em;
}

h1 {
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* Cincin fokus ditulis sekali di sini, bukan ditempel per elemen. Audit T-410
 * menemukan 38 kontrol di halaman Akun tanpa cincin fokus yang terlihat, dan
 * penyebabnya memang itu: ditempel satu-satu berarti ada yang terlewat. */
:focus-visible {
  outline: 2px solid var(--aksen);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Tautan lompat ke isi halaman. Tersembunyi sampai difokus, lalu muncul di kiri
 * atas. Wajib untuk yang menavigasi dengan papan tugas: tanpa ini, mencapai
 * tabel berarti melewati seluruh menu dan form dulu setiap kali. */
.lompat {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 50;
  background: #fff;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--aksen);
  border-radius: 0 0 0.25rem 0;
}

.lompat:focus {
  left: 0;
}

/* Pembungkus tabel yang bisa digeser ke samping.
 *
 * `position: relative` bukan hiasan dan jangan dihapus. Tanpa itu, keturunan
 * `position: absolute` di dalam tabel jatuh ke containing block viewport,
 * lolos dari pemotongan pembungkus ini, dan menarik area gulung seluruh
 * halaman selebar tabelnya.
 *
 * Itu persis T-422: satu label khusus pembaca layar selebar 1px di kolom
 * terakhir halaman Data membuat halamannya bisa digeser 600px ke samping,
 * sementara yang terlihat di sana cuma bidang kosong. Kolom kanan hilang dari
 * pandangan tanpa tanda apa pun bahwa ia ada.
 *
 * Ditulis sebagai kelas, bukan ditempel sebagai utility `relative` di sebelah
 * `overflow-x-auto` di tiap template, supaya alasannya ikut menempel pada
 * aturannya. `relative` yang berdiri sendiri terbaca seperti sisa yang lupa
 * dibuang, dan orang berikutnya akan menghapusnya karena tidak ada yang
 * kelihatan berubah setelahnya. */
.geser-x {
  overflow-x: auto;
  position: relative;
}

/* Judul tabel untuk pembaca layar. Tabel tanpa caption memaksa pembaca layar
 * menyebut "tabel" tanpa menyebut tabel apa. */
.hanya-pembaca-layar {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

/* Penyorotan baris saat hover. Di tabel 100 baris, mata kehilangan barisnya
 * saat bergerak ke kanan, dan ini yang mengembalikannya. */
tbody tr:hover {
  background-color: #f8fafc;
}

/* Penanda sedang memuat milik HTMX. Kelasnya disediakan HTMX sendiri; yang
 * kita atur cuma tampilannya. Tanpa ini, filter yang lambat terlihat seperti
 * halaman yang tidak merespons. */
.htmx-indicator {
  opacity: 0;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Bagian yang sedang ditukar diredupkan, jadi jelas isinya belum yang baru. */
.htmx-request table {
  opacity: 0.55;
}

button,
a,
input,
select,
summary,
table,
.htmx-indicator {
  transition-property: background-color, border-color, color, opacity;
  transition-duration: 180ms;
}

/* Tanda tanya kecil di sebelah judul kolom, dipasang di T-420. Tautan ke
 * daftar arti kolom di bawah tabel, bukan tooltip melayang. Alasannya ditulis
 * di partial/jelaskan.html: tooltip melayang terpotong pembungkus tabel yang
 * bisa digeser ke samping. */
.jelas-tanda {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem;
  height: 1rem;
  flex: none;
  line-height: 1;
  font-size: 0.7rem;
  font-weight: 400;
  border-radius: 9999px;
  border: 1px solid #cbd5e1;
  color: #64748b;
  background: #fff;
  text-decoration: none;
}

.jelas-tanda:hover {
  border-color: var(--aksen);
  color: var(--aksen);
}

/* Bagian yang baru saja dituju tautan itu disorot sebentar, supaya mata tahu
 * ke mana ia dibawa. Tanpa ini, melompat ke daftar yang sudah kelihatan di
 * layar terasa seperti tautan yang tidak melakukan apa-apa. */
:target > h3 {
  color: var(--aksen);
}

/* Dua tanda bahwa sesuatu sedang berjalan, dipasang di T-419. Keduanya hanya
 * dirender saat job benar-benar berjalan; yang menjaganya template, bukan CSS.
 *
 * Titik berdenyut di sebelah "Sedang berjalan". Job Instagram punya jendela
 * puluhan detik ketika tidak ada angka yang berubah sama sekali, dan halaman
 * yang terlihat diam membuat orang menekan tombol lagi atau menutup tab. */
.denyut {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 9999px;
  background-color: var(--aksen);
  animation: denyut 1.4s ease-in-out infinite;
}

@keyframes denyut {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.35;
    transform: scale(0.8);
  }
}

/* Bilah tanpa target, untuk tahap yang jumlah akhirnya memang tidak diketahui.
 * Instagram tidak memberi jumlah post total di jalur tanpa login, dan bilah
 * yang mengaku tahu persentasenya akan berbohong. Yang ini cuma menyatakan
 * bahwa sesuatu sedang berjalan. */
.bilah-tak-tentu {
  position: relative;
}

.bilah-tak-tentu::after {
  content: '';
  position: absolute;
  inset-block: 0;
  width: 35%;
  background-color: var(--aksen);
  border-radius: 9999px;
  animation: geser 1.6s ease-in-out infinite;
}

@keyframes geser {
  0% {
    left: -35%;
  }
  100% {
    left: 100%;
  }
}

/* Yang meminta gerakan dikurangi tidak mendapat transisi sama sekali. Ini
 * bukan preferensi gaya: gerakan bisa memicu pusing dan mual pada sebagian
 * orang. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }

  /* Aturan menyeluruh di atas menghentikan animasinya, tapi menghentikannya
   * saja tidak cukup di sini: bilah tak tentu akan berhenti di posisi akhir,
   * yaitu di luar kotaknya, dan hasilnya bilah kosong yang terbaca sebagai
   * nol persen. Jadi keadaan diamnya ditentukan sendiri. */
  .denyut {
    opacity: 1;
    transform: none;
  }

  .bilah-tak-tentu::after {
    left: 0;
    width: 100%;
    opacity: 0.35;
  }
}
