/* ---------------------------------------------------------------------------
   Tambahan khusus Whitelist Asset.

   app.css disalin apa adanya dari panel bio-amp dan sengaja tidak disentuh,
   supaya kalau berkas itu diperbarui di sana ia bisa ditimpa ke sini tanpa
   kehilangan apa pun. Semua yang hanya ada di aplikasi ini tinggal di berkas
   kedua ini — dimuat lewat <link> terpisah, persis seperti yang disarankan
   catatan di kepala app.css.

   Bahasa visualnya sama: timbul-tenggelam dari gradien dan bayangan, tanpa
   satu pun berkas gambar.
   --------------------------------------------------------------------------- */

/* ------------------------------------------------------- Daftar di dropzone */

/* Berkas yang sudah dipilih muncul di dalam kotaknya sendiri, bukan sebagai
   satu baris teks di bawahnya. Alasannya: setelah menjatuhkan lima berkas,
   yang ingin diperiksa orang adalah "apakah kelimanya benar" — dan itu tidak
   terjawab oleh tulisan "5 berkas".

   Kotaknya ikut berubah jadi permukaan terangkat saat berisi: cekungan
   menandakan wadah kosong yang menunggu diisi; begitu ada isinya, ia berhenti
   jadi undangan dan mulai jadi daftar. */
.dropzone.has-files {
  background-image: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
  border-style: solid;
  border-color: var(--border-soft);
  box-shadow: inset 0 1px 0 var(--bevel-top), var(--lift);
  padding: .75rem;
  align-items: stretch;
  gap: .5rem;
}

.droplist {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  width: 100%;
  text-align: left;
}

.droplist-item {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .3125rem .5rem;
  background-image: linear-gradient(180deg, var(--sunk) 0%, var(--surface-2) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--groove);
  font-size: .8571rem;
}

.droplist-item .icon { color: var(--text-muted); flex: none; }

/* Nama berkas yang memendek sendiri saat sempit. Tanpa min-width:0 flexbox
   menolak menyusutkan anak yang isinya panjang, dan ukuran berkas di kanan
   terdorong keluar kotak. */
.droplist-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--mono);
}

.droplist-size {
  flex: none;
  color: var(--text-muted);
  font-size: .8125rem;
  font-variant-numeric: tabular-nums;
}

/* Tombol buang per baris. Dibuat sebagai <button> di dalam <label> dropzone,
   jadi kliknya harus dihentikan sebelum menembus ke label — kalau tidak,
   membuang satu berkas malah ikut membuka dialog berkas. Penghentian itu ada
   di upload.js; di sini hanya bentuknya. */
.droplist-drop {
  flex: none;
  display: inline-flex;
  align-items: center;
  padding: .125rem .3125rem;
  background: none;
  border: 1px solid transparent;
  border-radius: 3px;
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
}

.droplist-drop:hover { color: var(--danger); border-color: var(--danger-border); }

/* Baris keterangan yang kosong tidak boleh menyisakan jarak. #drop-hint hanya
   berisi teks setelah ada berkas dipilih; tanpa aturan ini ia tetap memakan
   satu baris kosong di antara kotak dan isian IP. */
#drop-hint:empty { display: none; }

/* -------------------------------------------------------- Keterangan format */

/* Kaki panel unggah: rujukan yang dibaca sekali lalu diabaikan. Dipisahkan
   dari badan panel dengan torehan yang sama seperti .form-foot, supaya ia
   terbaca sebagai catatan kaki dan tidak bersaing dengan tombol Unggah. */
.formats {
  border-top: 1px solid var(--border-soft);
  box-shadow: inset 0 1px 0 var(--bevel-top);
}

/* Kolom kiri dipatok supaya ketiga barisnya sejajar. .kv membiarkan kolom
   pertama selebar isinya, dan di sini isinya berbeda-beda panjang. */
.formats .kv th {
  width: 7.5rem;
  padding-top: .45rem;
  color: var(--text);
  font-weight: 700;
  font-size: .8571rem;
}

.formats .kv td { padding: .3125rem 0 .625rem; }
.formats .kv tr:last-child td { padding-bottom: 0; }

.formats small { margin-top: .2rem; }

/* Deretan ekstensi. Chip <code> sudah bergaya cekung dari app.css; yang
   ditambahkan di sini hanya pembungkus yang bisa turun baris dengan rapi —
   satu baris koma sepanjang lima belas ekstensi tidak bisa dipindai mata. */
.extlist {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
}

.extlist code {
  font-size: .8125rem;
  padding: .1em .45em;
}

/* ----------------------------------------------------------------- URL akses */

/* Alamat unduh + tombol salin. Kotaknya readonly dan seluruh isinya terpilih
   saat diklik: alamat ini selalu disalin utuh, tidak pernah disunting
   sebagian. */
.urlrow { display: flex; gap: .5rem; align-items: stretch; }

.urlrow .input {
  font-family: var(--mono);
  font-size: .8571rem;
}

.urlrow .btn { flex: none; }

/* --------------------------------------------------------------- Fakta asset */

/* Deretan fakta pendek di halaman Kelola: pemilik, tipe, ukuran, hit, tanggal.

   Sebelumnya ini .kv — tabel dua kolom. Bentuk itu benar untuk pasangan
   label/keterangan yang keterangannya berupa kalimat, tapi salah di sini:
   kolom nilainya melar sampai tepi panel padahal isinya "6" atau "314.9 KB",
   jadi tiap baris menyisakan bidang kosong sepanjang setengah panel.

   Dijajar mendatar, lebar yang sama justru terpakai dan keenamnya bisa
   dipindai sekaligus, bukan dibaca menurun.

   Flex, BUKAN grid berkolom sama lebar. Itu percobaan pertama dan hasilnya
   salah: kolom yang sama lebar memaksa "hit: 6" memakan ruang selebar sebuah
   tanggal, sehingga yang keenam tidak kebagian dan turun ke baris bawah
   sendirian. Di sini tiap fakta berangkat dari lebar isinya sendiri
   (flex-basis auto), lalu sisa lebarnya dibagi rata (flex-grow) supaya
   barisnya tetap penuh sampai tepi. Kalau layarnya memang tidak cukup, ia
   turun baris — dan baris bawahnya pun ikut penuh, bukan menyisakan satu
   fakta yatim. */
.factgrid {
  display: flex;
  flex-wrap: wrap;
  gap: .875rem 1.5rem;
  margin: 0;
}

.factgrid > div { flex: 1 1 auto; }

.factgrid dt {
  display: flex;
  align-items: center;
  gap: .3rem;
  margin-bottom: .1rem;
  color: var(--text-muted);
  font-size: .8125rem;
}

.factgrid dt .icon { flex: none; }

/* break-word, bukan anywhere: yang terakhir ikut menurunkan lebar min-content
   sebuah fakta, jadi flex jadi lebih rela memampatkannya dan tanggal terbelah
   dua baris padahal barisnya masih muat. Ini hanya menolong kalau ada satu
   kata yang memang lebih panjang dari kotaknya — MIME panjang, misalnya. */
.factgrid dd {
  margin: 0;
  font-weight: 700;
  font-size: .9375rem;
  overflow-wrap: break-word;
}

/* ------------------------------------------------------------------ Pratinjau */

/* Gambar kecil di halaman kelola. Latarnya cekung supaya berkas dengan
   transparansi (PNG, WebP) tetap punya bidang yang terbaca di belakangnya. */
.preview {
  display: block;
  max-width: 100%;
  max-height: 16rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background-image: linear-gradient(180deg, var(--sunk) 0%, var(--surface-2) 100%);
  box-shadow: var(--groove);
  padding: .25rem;
}

/* ------------------------------------------------------------------- Widget */

/* Daftar pilihan bercentang: widget yang dipasang, lalu mode URL akses.
   Tiap baris jadi kartunya sendiri, bukan sekadar deretan centang, karena yang
   dibaca orang di sini bukan namanya melainkan keterangannya — penanda, posisi
   penyisipan, akibat memilih mode. Itu tiga baris teks per pilihan, dan tiga
   baris teks tanpa bidang yang membatasinya menyatu dengan tetangganya. */
.picklist {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.picklist-item {
  padding: .5rem .625rem;
  background-image: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--bevel-top);
}

/* Kartu mode URL adalah <label> — seluruh bidangnya bisa diklik. Kartu widget
   adalah <div> karena memuat <select> di dalamnya, jadi yang bisa diklik hanya
   labelnya. Penunjuk tangan hanya dipasang pada yang memang begitu. */
label.picklist-item,
.picklist-item .check { cursor: pointer; }

.picklist-item:hover { border-color: var(--text-muted); }

/* Pemilih letak di dalam kartu widget. Rata dengan teks di sebelah kotak
   centang, bukan dengan tepi kartu: ia keterangan lanjutan dari widget itu,
   bukan pilihan yang berdiri sendiri. */
.picklist-opt {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .375rem .5rem;
  margin-top: .5rem;
  padding-left: 1.5rem;
}

.picklist-opt > label {
  font-size: .8125rem;
  font-weight: 400;
  color: var(--text-muted);
  margin-bottom: 0;
}

/* .input dari app.css melebar penuh; di sini ia berbagi baris dengan labelnya. */
.picklist-opt .input {
  flex: 1 1 12rem;
  width: auto;
  min-width: 0;
  max-width: 22rem;
}

/* min-width:0 supaya keterangan panjang memendek di dalam kartunya, bukan
   mendorong kotak centang keluar. */
.picklist-body {
  flex: 1 1 auto;
  min-width: 0;
}

.picklist-name {
  display: block;
  font-weight: 700;
  font-size: .8571rem;
}

.picklist-body small { display: block; margin-top: .15rem; }
.picklist-body small.mono { font-family: var(--mono); font-size: .8125rem; }

/* Jarak sebelum judul kelompok kedua. Judulnya .form-section-title yang tidak
   punya margin atas sendiri — di tempat lain ia selalu jadi yang pertama. */
.picklist-gap { margin-top: 1rem; }

/* Keterangan penanda: terlipat, dibuka kalau dicari.

   app.css sudah punya dua bentuk <details>: baris pohon dan kepala panel, dua-duanya
   membuang segitiga bawaan dan menggambar caretnya sendiri. Yang ini tidak —
   segitiga bawaan peramban sudah cukup untuk satu baris kecil di kaki panel, dan
   menggambar caret sendiri di sini hanya menambah gaya untuk hal yang tidak
   dilihat orang. */
.formats > summary {
  cursor: pointer;
  list-style-position: inside;
}

.formats > summary:hover { color: var(--text); }
.formats[open] > summary { margin-bottom: .5rem; }

/* Tabel penanda memakai kaki panel .formats yang sama seperti keterangan
   format di halaman unggah, tapi isinya kolom kirinya <code>{{widget:slug}}</code>
   dan bukan satu kata. Lebar 7.5rem di .formats itu hanya usul; nowrap yang
   membuat tabelnya benar-benar memberi kolom itu ruang yang dibutuhkan. */
.formats .kv th code {
  font-size: .8125rem;
  padding: .1em .45em;
  white-space: nowrap;
}

/* --------------------------------------------------------------------- Aturan IP */

/* Daftar IP memakai lebar seadanya: kolom aturan cukup selebar teksnya,
   sisanya diberikan ke keterangan. Tanpa ini kolom aturan meregang sampai
   sepertiga tabel padahal isinya paling panjang 18 karakter. */
.table .ip-rule { width: 1%; white-space: nowrap; font-family: var(--mono); }

/* Kolom user agent. Isinya satu baris panjang tanpa spasi yang berguna, jadi
   ia harus dipatok dan dipendekkan — tanpa itu satu Mozilla/5.0 yang lengkap
   meregangkan tabelnya sampai kolom lain tidak terbaca.

   Dipakai bersama oleh tabel di halaman Kelola dan halaman Log. Sebelumnya
   keduanya memakai gaya sebaris dengan angka yang berbeda (16rem dan 15rem)
   padahal isinya kolom yang sama persis. */
.table .ua { max-width: 16rem; }

/* Baris yang menandai keadaan "belum ada IP sama sekali". Bukan flash —
   ini bukan hasil dari tindakan barusan, melainkan sifat asset yang berlaku
   terus sampai diperbaiki. */
.notice {
  display: flex;
  gap: .5rem;
  align-items: flex-start;
  padding: .625rem .75rem;
  background-image: linear-gradient(180deg, var(--warn-bg) 0%, var(--warn-bg-2) 100%);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--bevel-top);
  color: var(--warn);
}

.notice .icon { flex: none; margin-top: .15em; }
.notice b { color: var(--text); }
