:root {
  color-scheme: light;

  /* Merek */
  --red: #b81f32;
  --red-dark: #8d1726;
  --gold: #d6a526;
  --green: #177a53;
  --blue: #1f6098;
  --violet: #6b4ea8;
  --amber: #9c6414;
  --danger: #b3261e;

  /* Teks, dari paling pekat ke paling redup */
  --ink-strong: #181c23;
  --ink: #20242c;
  --ink-label: #303743;
  --ink-soft: #414a56;
  --ink-table: #4f5968;
  --muted: #626b78;
  --muted-soft: #8a93a0;
  --ink-success: #15803d;
  --ink-warning: #b45309;

  /* Permukaan */
  --soft: #f5f7fb;
  --paper: #ffffff;
  --surface-tint: #fbfcfe;
  --surface-sunken: #f8fafc;
  --surface-hover: #fafcff;
  --header-bg: rgba(255, 255, 255, 0.94);
  --glass-bg: rgba(255, 255, 255, 0.78);
  --overlay: rgba(20, 28, 38, 0.48);

  /* Dua warna ini tidak pernah ikut tema. --on-accent adalah teks di atas
     isian pekat seperti tombol merah, dan --document-paper adalah kertas
     pratinjau surat serta halaman PDF, yang memang selalu putih. */
  --on-accent: #ffffff;
  --document-paper: #ffffff;

  /* Garis */
  --line: #d9dee7;
  --line-strong: rgba(32, 36, 44, 0.14);
  --line-soft: rgba(32, 36, 44, 0.1);
  --line-softer: rgba(32, 36, 44, 0.08);
  --field-border: #cbd2dc;
  --readonly-bg: rgba(32, 36, 44, 0.04);

  /* Aksen lembut, dipakai kartu dan lencana berstatus */
  --tint-blue: #f3f8fd;
  --tint-blue-strong: #e8f2fb;
  --tint-violet-strong: #efeafb;
  --tint-green: #eefaf5;
  --tint-green-strong: #e9f7f1;
  --tint-amber: #fff9e9;
  --tint-amber-strong: #fff1c7;
  --tint-red: #fdeceb;
  --tint-neutral: #edf1f6;
  --tint-neutral-strong: #e9edf2;

  /* Keadaan nonaktif */
  --disabled-bg: #e8ebef;
  --disabled-ink: #7b8490;
  --disabled-line: #d4dae2;

  /* Bagian yang memang gelap sejak semula */
  --footer-bg: #191919;
  --footer-ink: #f4f4f4;
  --footer-muted: #c8c8c8;
  --footer-line: #777777;
  --toast-bg: #24303b;

  /* Lapisan gradasi latar halaman dan hero. Nilainya dirancang untuk
     latar terang, jadi tema gelap wajib menimpanya. */
  --wash-gold: rgba(214, 165, 38, 0.16);
  --wash-red: rgba(184, 31, 50, 0.08);
  --hero-veil-a: rgba(255, 255, 255, 0.96);
  --hero-veil-b: rgba(255, 246, 246, 0.9);

  --shadow: 0 18px 45px rgba(20, 28, 38, 0.12);
  --bottom-nav-h: 58px;
}

/* ============================================================
   Tema gelap
   ============================================================
   Nilai ditulis sekali sebagai kumpulan token, lalu dipasang di dua tempat:
   lewat prefers-color-scheme untuk mengikuti pengaturan perangkat, dan lewat
   data-theme untuk pilihan manual petugas. Penjaga :not([data-theme="light"])
   memastikan pilihan terang manual tetap menang di perangkat bermode gelap. */

:root[data-theme="dark"] {
  color-scheme: dark;

  --red: #d9485e;
  --red-dark: #b81f32;
  --gold: #e0b53f;
  --green: #2ea77a;
  --blue: #5296dd;
  --violet: #a48ade;
  --amber: #d29a45;
  --danger: #e2635a;

  --ink-strong: #f3f5f9;
  --ink: #e4e8ee;
  --ink-label: #d0d6df;
  --ink-soft: #b6bec9;
  --ink-table: #a5aebb;
  --muted: #949daa;
  --muted-soft: #767f8c;
  --ink-success: #4ade80;
  --ink-warning: #fbbf24;

  --soft: #101319;
  --paper: #171b21;
  --surface-tint: #1b1f27;
  --surface-sunken: #1f242c;
  --surface-hover: #232833;
  --header-bg: rgba(16, 19, 25, 0.94);
  --glass-bg: rgba(255, 255, 255, 0.06);
  --overlay: rgba(0, 0, 0, 0.64);

  --line: #333b46;
  --line-strong: rgba(255, 255, 255, 0.15);
  --line-soft: rgba(255, 255, 255, 0.11);
  --line-softer: rgba(255, 255, 255, 0.07);
  --field-border: #3b4249;
  --readonly-bg: rgba(255, 255, 255, 0.05);

  --tint-blue: #16222f;
  --tint-blue-strong: #1b2c3e;
  --tint-violet-strong: #292140;
  --tint-green: #13251e;
  --tint-green-strong: #173128;
  --tint-amber: #2a2114;
  --tint-amber-strong: #3b2d15;
  --tint-red: #2e1918;
  --tint-neutral: #202631;
  --tint-neutral-strong: #262d39;

  --disabled-bg: #22262f;
  --disabled-ink: #6a7380;
  --disabled-line: #333b46;

  --footer-bg: #0c0e12;
  --footer-ink: #d7dae0;
  --footer-muted: #8c939d;
  --footer-line: #4a5059;
  --toast-bg: #2c3540;

  --wash-gold: rgba(224, 181, 63, 0.1);
  --wash-red: rgba(217, 72, 94, 0.13);
  --hero-veil-a: rgba(23, 27, 33, 0.9);
  --hero-veil-b: rgba(31, 24, 27, 0.86);

  --shadow: 0 18px 45px rgba(0, 0, 0, 0.5);
}

/* Cermin dari blok di atas untuk perangkat yang menyetel mode gelap di
   tingkat sistem. Isinya dibangkitkan dari :root[data-theme="dark"] agar
   keduanya tidak pernah melenceng; bila salah satu diubah, ubah keduanya. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --red: #d9485e;
    --red-dark: #b81f32;
    --gold: #e0b53f;
    --green: #2ea77a;
    --blue: #5296dd;
    --violet: #a48ade;
    --amber: #d29a45;
    --danger: #e2635a;

    --ink-strong: #f3f5f9;
    --ink: #e4e8ee;
    --ink-label: #d0d6df;
    --ink-soft: #b6bec9;
    --ink-table: #a5aebb;
    --muted: #949daa;
    --muted-soft: #767f8c;
    --ink-success: #4ade80;
    --ink-warning: #fbbf24;

    --soft: #101319;
    --paper: #171b21;
    --surface-tint: #1b1f27;
    --surface-sunken: #1f242c;
    --surface-hover: #232833;
    --header-bg: rgba(16, 19, 25, 0.94);
    --glass-bg: rgba(255, 255, 255, 0.06);
    --overlay: rgba(0, 0, 0, 0.64);

    --line: #333b46;
    --line-strong: rgba(255, 255, 255, 0.15);
    --line-soft: rgba(255, 255, 255, 0.11);
    --line-softer: rgba(255, 255, 255, 0.07);
    --field-border: #3b4249;
    --readonly-bg: rgba(255, 255, 255, 0.05);

    --tint-blue: #16222f;
    --tint-blue-strong: #1b2c3e;
    --tint-violet-strong: #292140;
    --tint-green: #13251e;
    --tint-green-strong: #173128;
    --tint-amber: #2a2114;
    --tint-amber-strong: #3b2d15;
    --tint-red: #2e1918;
    --tint-neutral: #202631;
    --tint-neutral-strong: #262d39;

    --disabled-bg: #22262f;
    --disabled-ink: #6a7380;
    --disabled-line: #333b46;

    --footer-bg: #0c0e12;
    --footer-ink: #d7dae0;
    --footer-muted: #8c939d;
    --footer-line: #4a5059;
    --toast-bg: #2c3540;

    --wash-gold: rgba(224, 181, 63, 0.1);
    --wash-red: rgba(217, 72, 94, 0.13);
    --hero-veil-a: rgba(23, 27, 33, 0.9);
    --hero-veil-b: rgba(31, 24, 27, 0.86);

    --shadow: 0 18px 45px rgba(0, 0, 0, 0.5);
  }
}

* {
  box-sizing: border-box;
}

html {
  min-width: 320px;
  /* Latar dipasang di <html>, bukan hanya di <body>. Ketika bilah alamat ponsel
     menyusut atau area gestur sistem ikut terhitung, sebagian peramban
     menggambar jalur tipis di bawah halaman memakai latar <html>; bila kosong,
     jalur itu tampil putih walau temanya gelap. */
  background: var(--soft);
  /* SIPIKO dipakai sebagai aplikasi layar penuh di ponsel, jadi cubit-perbesar
     dan ketuk-ganda dimatikan agar tata letak tidak pernah bergeser saat
     petugas menggulir daftar atau mengisi borang. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  color: var(--ink);
  font-family: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background:
    radial-gradient(circle at 12% 8%, var(--wash-gold), transparent 260px),
    linear-gradient(180deg, var(--wash-red), rgba(255, 255, 255, 0) 380px),
    var(--soft);
}

button,
input,
select,
textarea {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 200;
  padding: 10px 14px;
  color: var(--on-accent);
  background: var(--ink);
  border-radius: 7px;
  transform: translateY(-160%);
  transition: transform 160ms ease;
}

.skip-link:focus {
  transform: translateY(0);
}

a {
  color: inherit;
  text-decoration: none;
}

a:focus-visible,
button:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.28);
  outline-offset: 3px;
}

/*
 * Kerangka halaman disusun sebagai kolom fleksibel supaya footer selalu
 * menempel di dasar layar. Tanpa ini, halaman yang isinya pendek -- seperti
 * cek status atau halaman masuk -- menyisakan celah latar di bawah footer.
 */
.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  /* Satuan dinamis menghindari lompatan saat bilah alamat ponsel muncul. */
  min-height: 100dvh;
}

.app-shell > main {
  flex: 1 0 auto;
}

.app-shell > .site-footer {
  margin-top: auto;
}

.site-footer {
  color: var(--footer-ink);
  background: var(--footer-bg);
}

.footer-contact {
  padding: 28px clamp(18px, 6.4vw, 123px) 34px;
}

.footer-brand {
  display: block;
  width: min(100%, 240px);
  line-height: 0;
}

.footer-brand img {
  display: block;
  width: 100%;
  height: auto;
}

.footer-address {
  margin: 0;
  margin-top: 32px;
  font-size: 12px;
  line-height: 1.6;
}

.social-links {
  display: flex;
  gap: 14px;
  margin-top: 24px;
}

.social-link {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  color: var(--footer-muted);
  border: 1px solid var(--footer-line);
  border-radius: 50%;
  transition: color 180ms ease, border-color 180ms ease, background 180ms ease;
}

.social-link:hover,
.social-link:focus-visible {
  color: var(--on-accent);
  border-color: var(--on-accent);
  background: rgba(255, 255, 255, 0.08);
}

.social-link-disabled {
  cursor: default;
  opacity: 0.8;
}

.social-link-disabled:hover {
  color: var(--footer-muted);
  border-color: var(--footer-line);
  background: transparent;
}

.social-link svg {
  width: 17px;
  height: 17px;
  fill: currentColor;
}

.social-link svg rect,
.social-link svg circle {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}

.social-link svg circle:last-child {
  fill: currentColor;
  stroke: none;
}

.footer-copyright {
  display: flex;
  justify-content: center;
  gap: 10px;
  padding: 38px 18px 42px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 12px;
  line-height: 1.4;
  text-align: center;
}

.footer-copyright strong {
  font-weight: 800;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 12px clamp(18px, 4vw, 56px);
  border-bottom: 1px solid rgba(141, 23, 38, 0.14);
  background: var(--header-bg);
  backdrop-filter: blur(14px);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-width: 204px;
}

.brand-mark {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
}

.brand-mark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.brand strong,
.brand small {
  display: block;
  line-height: 1.12;
}

.brand small {
  margin-top: 3px;
  color: var(--muted);
  font-size: 12px;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}

.main-nav::-webkit-scrollbar {
  display: none;
}

.main-nav a {
  padding: 9px 12px;
  color: var(--muted);
  border-radius: 7px;
  white-space: nowrap;
}

.main-nav a:hover,
.main-nav a.active {
  color: var(--red-dark);
  background: rgba(184, 31, 50, 0.08);
}

main {
  outline: none;
}

.page {
  width: min(1160px, calc(100% - 36px));
  margin: 0 auto;
  padding: 34px 0 54px;
}

/*
 * Halaman publik sengaja sempit supaya nyaman dibaca. Dashboard admin justru
 * berisi tabel lebar, jadi ruang kosong di kiri dan kanan layar besar lebih
 * berguna dipakai daripada dibiarkan menganggur.
 */
.admin-page {
  width: min(1720px, calc(100% - 32px));
}

.info-page {
  max-width: 920px;
}

.info-page-head {
  display: grid;
  gap: 14px;
  margin-bottom: 26px;
}

.info-page-head h1 {
  max-width: 820px;
  font-size: clamp(38px, 6vw, 72px);
  line-height: 1.04;
}

.info-page-intro {
  max-width: 760px;
  margin: 0;
  color: var(--ink-soft);
  font-size: 18px;
  line-height: 1.65;
}

.info-document {
  display: grid;
  gap: 26px;
  padding: clamp(22px, 4vw, 42px);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(20, 28, 38, 0.06);
}

.info-document-compact {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.legal-modal-card {
  width: min(960px, 100%);
}

.legal-modal-body {
  padding-top: 0;
}

.legal-modal-body .info-document {
  padding: 22px 4px 4px;
}

.info-document section {
  display: grid;
  gap: 10px;
}

.info-document section + section {
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.info-document h2 {
  color: var(--ink);
  font-size: clamp(21px, 2.5vw, 28px);
}

.info-document p,
.info-document li {
  color: var(--ink-soft);
  line-height: 1.7;
}

.info-document p {
  margin: 0;
}

.info-document ul {
  display: grid;
  gap: 8px;
  margin: 0;
  padding-left: 22px;
}

.info-updated {
  color: var(--muted) !important;
  font-size: 13px;
}

.agreement-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 0 28px;
  font-size: 13px;
}

.agreement-links a {
  color: var(--blue);
  font-weight: 700;
}

.text-link {
  padding: 0;
  color: var(--blue);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  text-decoration: underline;
  background: transparent;
  border: 0;
  cursor: pointer;
}

.text-link:hover {
  color: var(--blue);
}

.public-hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line-softer);
  background:
    linear-gradient(115deg, var(--hero-veil-a), var(--hero-veil-b)),
    linear-gradient(90deg, rgba(184, 31, 50, 0.1), rgba(214, 165, 38, 0.08));
}

.public-hero::before {
  position: absolute;
  inset: auto -80px -170px auto;
  width: 460px;
  height: 460px;
  content: "";
  background: rgba(184, 31, 50, 0.08);
  border: 1px solid rgba(184, 31, 50, 0.1);
  border-radius: 50%;
}

.public-hero::after {
  position: absolute;
  inset: -140px auto auto 44%;
  width: 360px;
  height: 360px;
  content: "";
  background: rgba(214, 165, 38, 0.12);
  border-radius: 50%;
}

.hero {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(260px, 0.75fr);
  gap: 42px;
  align-items: center;
  min-height: min(650px, calc(100vh - 70px));
  padding-top: 42px;
  padding-bottom: 42px;
}

.hero-copy {
  max-width: 760px;
}

.hero-visual {
  display: grid;
  min-height: 320px;
  place-items: center;
}

.hero-visual img {
  display: block;
  width: min(100%, 320px);
  height: auto;
  max-height: 430px;
  object-fit: contain;
  filter: drop-shadow(0 18px 18px rgba(20, 28, 38, 0.16));
}

.agency-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
  margin-bottom: 18px;
  padding: 8px 12px 8px 8px;
  color: var(--red-dark);
  font-size: 13px;
  font-weight: 800;
  background: var(--glass-bg);
  border: 1px solid rgba(184, 31, 50, 0.16);
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(20, 28, 38, 0.08);
}

.agency-badge img {
  width: 30px;
  height: 30px;
  object-fit: contain;
}

.eyebrow {
  margin: 0 0 12px;
  color: var(--red-dark);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0;
  text-transform: uppercase;
}

h1,
h2,
h3 {
  margin: 0;
  letter-spacing: 0;
}

h1 {
  max-width: 720px;
  color: var(--ink-strong);
  font-size: clamp(54px, 9vw, 104px);
  line-height: 0.98;
}

.hero-title {
  max-width: 360px;
  margin: 14px 0 20px;
}

.hero-title img {
  display: block;
  width: min(100%, 360px);
  height: auto;
}

h2 {
  font-size: clamp(26px, 3vw, 38px);
  line-height: 1.08;
}

h3 {
  font-size: 18px;
}

.lead {
  max-width: 680px;
  margin: 18px 0 0;
  color: var(--ink-soft);
  font-size: 18px;
  line-height: 1.65;
}

.hero-actions,
.toolbar,
.form-actions,
.status-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.hero-actions {
  margin-top: 28px;
}

/* Dibaca sekilas, bukan dipelajari: sebaris pendek di bawah tombol, dipisah
   titik tengah seperti keterangan pada rambu. */
.hero-requirements {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
}

.hero-requirements > span:not([aria-hidden]) {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.hero-requirements > span:not([aria-hidden])::before {
  content: "\2713";
  color: var(--green);
  font-size: 12px;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid transparent;
  border-radius: 7px;
  font-weight: 700;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease, transform 160ms ease;
}

.button:hover {
  transform: translateY(-1px);
}

.button.is-loading {
  cursor: wait;
  transform: none;
}

.button-spinner {
  width: 15px;
  height: 15px;
  margin-right: 8px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: button-spin 700ms linear infinite;
}

@keyframes button-spin {
  to { transform: rotate(360deg); }
}

.button.primary {
  color: var(--on-accent);
  background: linear-gradient(135deg, var(--red), var(--red-dark));
  box-shadow: 0 14px 28px rgba(184, 31, 50, 0.24);
}

.button.primary:hover {
  background: var(--red-dark);
}

/*
 * Tombol pendukung: maroon berisi dengan tulisan putih, sama seperti tombol
 * utama.
 *
 * Dulu berupa tombol bertepi dengan latar putih, dan tepinya yang setipis
 * 0,22 nyaris lenyap di atas latar hero yang sendirinya bersemu merah --
 * tombolnya terbaca seperti tulisan biasa.
 *
 * Bedanya dengan tombol utama tinggal permukaannya: yang utama bergradasi
 * dari merah terang ke merah tua, yang ini rata pada merah tuanya saja.
 * Cukup untuk membuat tombol utama tetap yang pertama tertangkap mata,
 * tanpa membuat keduanya terbaca sebagai dua jenis kontrol yang berbeda.
 */
.button.secondary {
  color: var(--on-accent);
  border-color: transparent;
  background: var(--red-dark);
}

.button.secondary:hover {
  background: var(--red);
}

.button.neutral {
  color: var(--ink);
  border-color: var(--line);
  background: var(--paper);
}

.button.danger {
  color: var(--on-accent);
  background: var(--danger);
}

.hero-panel {
  display: grid;
  gap: 14px;
  padding: 24px;
  background: var(--paper);
  border: 1px solid var(--line-softer);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

.form-intro {
  display: flex;
  align-items: center;
  gap: 14px;
}

.form-intro img {
  flex: 0 0 auto;
  width: 150px;
  height: auto;
  max-height: 70px;
  margin-left: auto;
  object-fit: contain;
}

.form-intro span {
  display: block;
  color: var(--muted);
  font-size: 13px;
}

.form-intro strong {
  display: block;
  margin-top: 3px;
  font-size: 18px;
}

.trust-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}

.trust-strip span {
  padding: 8px 10px;
  color: var(--ink-label);
  font-size: 13px;
  font-weight: 700;
  background: var(--glass-bg);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
}

.metric-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.metric,
.process-item,
.summary-tile,
.form-box,
.result-box,
.login-box,
.table-shell,
.admin-panel {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.metric {
  padding: 16px;
  background: linear-gradient(180deg, var(--paper), var(--surface-tint));
}

.metric span,
.summary-tile span {
  display: block;
  color: var(--muted);
  font-size: 13px;
}

.metric strong,
.summary-tile strong {
  display: block;
  margin-top: 6px;
  font-size: 28px;
  line-height: 1;
}

.section-band {
  margin-top: 0;
  padding: 42px 0 58px;
  border-top: 1px solid var(--line-softer);
}

.section-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 18px;
}

/*
 * Di layar sempit tombolnya turun ke barisnya sendiri dan selebar isi di
 * bawahnya, bukan menyusut sebesar tulisannya di ujung kanan.
 *
 * Aturan serupa sudah ada di bawah 620px lewat .button yang dibuat selebar
 * penuh, tetapi di antara 620px dan 720px -- tablet dan ponsel mendatar --
 * kepala halaman masih satu baris, sehingga judul dan tombol berebut ruang
 * dan tombolnya berdiri sendirian tidak sejajar dengan apa pun.
 */
@media (max-width: 720px) {
  .section-head {
    flex-wrap: wrap;
    gap: 14px;
  }

  .section-head > .button {
    width: 100%;
  }
}

.section-head p {
  max-width: 620px;
  margin: 8px 0 0;
  color: var(--muted);
  line-height: 1.6;
}

.process-grid,
.summary-grid {
  display: grid;
  /* Jumlah kartunya bertambah seiring status baru, jadi kolomnya dibiarkan
     menyesuaikan sendiri daripada dipatok empat -- kartu kelima yang terlempar
     sendirian ke baris baru terlihat seperti kekeliruan, bukan rancangan. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: 14px;
}

.process-item {
  padding: 18px;
  transition: transform 160ms ease, box-shadow 160ms ease;
}

.process-item:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(20, 28, 38, 0.08);
}

.process-item b {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  margin-bottom: 20px;
  color: var(--on-accent);
  background: linear-gradient(135deg, var(--red), var(--red-dark));
  border-radius: 50%;
}

.process-item p {
  margin: 10px 0 0;
  color: var(--muted);
  line-height: 1.55;
}

.form-layout,
.admin-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 22px;
  align-items: start;
}

.form-box,
.login-box,
.admin-panel {
  padding: 22px;
}

.public-form-layout {
  grid-template-columns: minmax(0, 1fr) 340px;
}

.public-form-layout .form-box {
  border-color: rgba(184, 31, 50, 0.14);
  box-shadow: 0 18px 45px rgba(20, 28, 38, 0.08);
}

.form-intro {
  margin-bottom: 20px;
  padding: 16px;
  background: linear-gradient(135deg, rgba(184, 31, 50, 0.07), rgba(214, 165, 38, 0.11));
  border: 1px solid rgba(184, 31, 50, 0.12);
  border-radius: 8px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.form-section-title {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-top: 2px;
  padding: 10px 0 2px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 8px;
}

.form-section-title span {
  display: grid;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  place-items: center;
  color: var(--on-accent);
  font-size: 13px;
  font-weight: 800;
  background: var(--red);
  border-radius: 50%;
}

.form-section-title strong,
.form-section-title small {
  display: block;
}

.form-section-title strong {
  font-size: 15px;
}

.form-section-title small {
  margin-top: 2px;
  color: var(--muted);
  line-height: 1.45;
}

.field {
  display: grid;
  gap: 7px;
  /*
   * Isi kolom dirapatkan ke atas. Tanpa ini, kolom yang punya keterangan bantu
   * memiliki satu baris lebih banyak daripada kolom di sebelahnya, dan sisa
   * ruang baris dibagi rata sehingga kotak isiannya tidak sejajar.
   */
  align-content: start;
}

.field.full,
.agreement-box.full,
.form-section-title.full,
.resource-grid.full {
  grid-column: 1 / -1;
}

.form-divider {
  grid-column: 1 / -1;
  height: 1px;
  margin: 2px 0;
  background: var(--line);
}

.resource-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 8px;
}

.resource-field {
  min-width: 0;
}

label {
  color: var(--ink-label);
  font-size: 14px;
  font-weight: 700;
}

input,
select,
textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  color: var(--ink);
  border: 1px solid var(--field-border);
  border-radius: 7px;
  background: var(--paper);
}

input[type="checkbox"] {
  width: 18px;
  height: 18px;
  min-height: 0;
  padding: 0;
  accent-color: var(--red);
}

textarea {
  min-height: 112px;
  resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
  outline: 3px solid rgba(31, 96, 152, 0.18);
  border-color: var(--blue);
}

.field-error {
  min-height: 18px;
  color: var(--danger);
  font-size: 13px;
}

.field-hint {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.agreement-box {
  display: grid;
  gap: 7px;
  padding: 14px;
  background: var(--tint-amber);
  border: 1px solid rgba(156, 100, 20, 0.2);
  border-radius: 8px;
}

.check-field {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  color: var(--ink-label);
  line-height: 1.45;
}

.button:disabled {
  color: var(--disabled-ink);
  background: var(--disabled-bg);
  border-color: var(--disabled-line);
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}

.request-actions {
  justify-content: flex-end;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.request-actions #submit-request {
  min-width: 228px;
  min-height: 54px;
  padding: 0 22px;
  border-radius: 10px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.01em;
}

.request-actions #submit-request:not(:disabled) {
  background: linear-gradient(135deg, #c5253d, var(--red-dark));
  box-shadow: 0 16px 30px rgba(184, 31, 50, 0.3), 0 0 0 4px rgba(184, 31, 50, 0.08);
}

.request-actions #submit-request:not(:disabled)::after {
  margin-left: 10px;
  content: "\2192";
  font-size: 20px;
  line-height: 1;
}

.request-actions #submit-request:not(:disabled):hover {
  background: linear-gradient(135deg, #d32a44, var(--red-dark));
  box-shadow: 0 18px 34px rgba(184, 31, 50, 0.36), 0 0 0 5px rgba(184, 31, 50, 0.1);
  transform: translateY(-2px);
}

.request-actions #submit-request:focus-visible {
  outline: 4px solid rgba(31, 96, 152, 0.28);
  outline-offset: 3px;
}

.help-box {
  display: grid;
  gap: 12px;
  padding: 18px;
  color: var(--ink-soft);
  background: var(--tint-amber);
  border: 1px solid rgba(156, 100, 20, 0.22);
  border-radius: 8px;
}

.public-help {
  position: sticky;
  top: 92px;
  align-self: start;
  overflow: hidden;
}

.help-box ul {
  margin: 0;
  padding-left: 20px;
  line-height: 1.65;
}

.result-box {
  display: grid;
  gap: 12px;
  margin-top: 18px;
  padding: 18px;
  border-color: rgba(23, 122, 83, 0.26);
  background: var(--tint-green);
}

.ticket {
  display: inline-block;
  width: fit-content;
  padding: 8px 10px;
  color: var(--green);
  font-weight: 800;
  background: var(--paper);
  border: 1px solid rgba(23, 122, 83, 0.28);
  border-radius: 7px;
}

.request-success-card {
  width: min(520px, 100%);
}

.request-success-body {
  display: grid;
  gap: 14px;
}

.success-reminder {
  margin: 0;
  color: var(--muted);
  line-height: 1.55;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 0 10px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
  background: var(--tint-neutral);
  border-radius: 6px;
}

.status-mark {
  display: inline-grid;
  width: 16px;
  height: 16px;
  place-items: center;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
}

.status-pill.green {
  color: var(--green);
  background: var(--tint-green-strong);
}

.status-pill.red {
  color: var(--danger);
  background: var(--tint-red);
}

.status-pill.blue {
  color: var(--blue);
  background: var(--tint-blue-strong);
}

.status-pill.amber {
  color: var(--amber);
  background: var(--tint-amber-strong);
}

.status-pill.violet {
  color: var(--violet);
  background: var(--tint-violet-strong);
}

/* Penanda kecil untuk isian yang boleh dikosongkan, supaya petugas tidak
   mengira formulirnya belum lengkap. */
.field-optional {
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  background: var(--tint-neutral-strong);
}

/* Penanda keterlambatan sengaja memakai warna bahaya, bukan sekadar kuning:
   barang yang belum kembali padahal tenggatnya lewat adalah satu-satunya
   keadaan di SIPIKO yang memburuk dengan sendirinya bila dibiarkan. */
.overdue-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 6px;
  padding: 3px 9px;
  border-radius: 6px;
  border: 1px solid currentColor;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--danger);
  background: var(--tint-red);
}

.my-request-marks {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
}

.summary-tile-alert {
  border-color: var(--danger);
  background: var(--tint-red);
}

.summary-tile-alert strong {
  color: var(--danger);
}

/* Tombol cetak berdiri di dalam langkah kerjanya, bukan di panel dokumen
   terpisah, supaya urutannya di layar sama dengan urutannya di meja loket. */
/* Aturan display pada .field dan blok ini mengalahkan [hidden] bawaan
   browser, jadi keduanya perlu penawarnya sendiri. */
.counterpart-other[hidden] {
  display: none;
}

.counterpart-other {
  display: grid;
  gap: 12px;
}

.field-choice {
  gap: 0;
}

.checkbox-line {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 13.5px;
  line-height: 1.5;
  cursor: pointer;
}

.checkbox-line input {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  accent-color: var(--red);
}

.handover-print {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--line-softer);
}

.handover-print .field-hint {
  flex: 1 1 220px;
  margin: 0;
}


/* --- Panel pemindaian di loket --- */

/* Tombol mengambang. Diletakkan di sudut kanan bawah, sejangkauan ibu jari,
   dan pada ponsel diangkat tepat di atas bilah navigasi dashboard supaya tidak
   menutupi tujuan mana pun di sana. */
.scan-launcher {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 55;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 20px;
  color: var(--on-accent);
  background: var(--red);
  border: 0;
  border-radius: 999px;
  box-shadow: 0 8px 24px rgba(184, 31, 50, 0.34);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.scan-launcher svg {
  width: 19px;
  height: 19px;
}

.scan-launcher:hover {
  background: var(--red-dark);
}

.scan-launcher:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
}

/* Pada ponsel pemindai sudah punya tempatnya sendiri di bilah bawah, jadi
   tombol mengambang ini hanya berlaku di layar lebar yang tidak punya bilah. */
@media (max-width: 620px) {
  .scan-launcher {
    display: none;
  }
}

/* Pemindai memenuhi layar seperti pemindai QR pada aplikasi perbankan: gambar
   kamera menjadi latar, sekelilingnya diredupkan, dan hanya satu kotak di
   tengah yang terang. Kotak itu tidak membatasi apa yang terbaca -- pustaka
   pemindainya tetap memeriksa seluruh gambar -- tetapi ia memberi tahu orang
   ke mana harus mengarahkan, dan itu jauh lebih cepat daripada menebak. */
.scan-modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: #000000;
}

.scan-panel {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000000;
}

.scan-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.scan-video[hidden] {
  display: none;
}

/* Bidang gelap di luar kotak dibuat dengan bayangan yang meluber ke segala
   arah, sehingga tidak perlu empat elemen penutup yang posisinya harus
   dihitung ulang setiap kali ukuran layar berubah. */
.scan-frame {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(74vw, 300px);
  aspect-ratio: 1;
  transform: translate(-50%, -55%);
  border-radius: 22px;
  box-shadow: 0 0 0 100vmax rgba(8, 10, 14, 0.62);
}

.scan-panel-mati .scan-frame {
  display: none;
}

.scan-corner {
  position: absolute;
  width: 34px;
  height: 34px;
  border: 4px solid #ffffff;
}

.scan-corner-tl {
  top: -2px;
  left: -2px;
  border-right: 0;
  border-bottom: 0;
  border-radius: 20px 0 0 0;
}

.scan-corner-tr {
  top: -2px;
  right: -2px;
  border-left: 0;
  border-bottom: 0;
  border-radius: 0 20px 0 0;
}

.scan-corner-bl {
  bottom: -2px;
  left: -2px;
  border-right: 0;
  border-top: 0;
  border-radius: 0 0 0 20px;
}

.scan-corner-br {
  bottom: -2px;
  right: -2px;
  border-left: 0;
  border-top: 0;
  border-radius: 0 0 20px 0;
}

.scan-top {
  position: absolute;
  inset: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: calc(env(safe-area-inset-top, 0px) + 16px) 16px 16px;
}

.scan-top h3 {
  margin: 0;
  color: #ffffff;
  font-size: 16px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.scan-close {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  color: #ffffff;
  background: rgba(255, 255, 255, 0.18);
  border: 0;
  border-radius: 999px;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
}

.scan-close:hover {
  background: rgba(255, 255, 255, 0.3);
}

.scan-state {
  display: none;
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(80vw, 330px);
  transform: translate(-50%, calc(-55% + min(37vw, 150px) + 22px));
  margin: 0;
  color: #ffffff;
  font-size: 13.5px;
  line-height: 1.6;
  text-align: center;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

.scan-panel-pesan .scan-state {
  display: block;
}

/* Tanpa gambar kamera tidak ada bingkai untuk dijadikan patokan, jadi
   keterangannya berdiri di tengah layar. */
.scan-panel-mati .scan-state {
  transform: translate(-50%, -50%);
}

.scan-bottom {
  position: absolute;
  inset: auto 0 0;
  padding: 16px;
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  background: linear-gradient(to top, rgba(8, 10, 14, 0.85), rgba(8, 10, 14, 0));
}

.scan-form {
  display: flex;
  gap: 8px;
}

.scan-form input {
  flex: 1 1 auto;
  min-width: 0;
  text-transform: uppercase;
}

.scan-form input::placeholder {
  text-transform: none;
}

.scan-form .button {
  flex: none;
  width: auto;
}

.scan-result {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
}

.scan-result-ok {
  color: var(--green);
  background: var(--tint-green-strong);
}

.scan-result-warning {
  color: var(--amber);
  background: var(--tint-amber-strong);
}

.scan-result-error {
  color: var(--danger);
  background: var(--tint-red);
}

/* --- Pemilih titik lokasi --- */

.location-picker {
  gap: 10px;
}

/* Alamat sering panjang, jadi kotaknya dibuat beberapa baris dan boleh
   ditinggikan sendiri oleh pemohon. Tanpa ini alamat lengkap hanya terlihat
   sepotong dan bagian yang terpotong justru bagian yang membedakan satu tempat
   dari tempat lain. */
#eventLocation {
  min-height: 68px;
  resize: vertical;
  line-height: 1.55;
}

/* Daftar saran menempel tepat di bawah kolom lokasi. Wadahnya tidak memakan
   tinggi sendiri supaya jarak antar kolom tidak berubah ketika daftarnya
   muncul dan hilang. */
.location-suggest-wrap {
  position: relative;
  gap: 0;
  min-height: 0;
}

.location-suggest {
  position: absolute;
  top: -6px;
  left: 0;
  right: 0;
  z-index: 20;
  max-height: 260px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 12px 30px rgba(20, 28, 38, 0.16);
}

.location-suggest[hidden] {
  display: none;
}

.location-suggest button {
  display: block;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  text-align: left;
  cursor: pointer;
}

.location-suggest button:hover,
.location-suggest button:focus-visible {
  background: var(--tint-neutral);
}

.location-map {
  /* Peta menjadi lapisan tersendiri. Leaflet menaruh ubin, penanda, dan
     kontrolnya pada z-index ratusan; tanpa kurungan ini angka-angka itu diadu
     langsung dengan bilah navigasi bawah (70) dan popup (80), dan petanya
     menang -- ia menutupi deretan ikon di bawah layar. Berkas gaya Leaflet
     dimuat saat peta dibuka, jadi ia selalu berada di urutan belakang dan tidak
     dapat dilawan hanya dengan menimpa z-index panel-panelnya. */
  position: relative;
  z-index: 0;
  height: 320px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.location-map[hidden] {
  display: none;
}

.location-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.location-actions[hidden] {
  display: none;
}

.location-actions .button {
  flex: 1 1 160px;
  width: auto;
}

.location-note {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.location-note:empty {
  display: none;
}

/* --- Jejak layanan --- */

/* Tepinya maroon dan berdenyut supaya terbaca sebagai sesuatu yang dapat
   ditekan. Denyutnya tidak berhenti ketika bagiannya dibentangkan: tepi yang
   tenang begitu dibuka membuat penandanya seakan lenyap, dan bagian ini
   justru perlu tetap terlihat sebagai satu blok tersendiri di bawah daftar
   pengajuan yang panjang. */
.service-trail {
  margin-top: 16px;
  border-color: var(--red-dark);
  animation: denyut-jejak-layanan 1.9s ease-in-out infinite;
}

.trail-warning {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--danger);
  background: var(--tint-red);
  font-size: 13px;
  line-height: 1.5;
}

.trail-tickets {
  display: grid;
  gap: 8px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

/* Isi Jejak layanan diberi jarak dari tepinya, sama seperti bagian lain di
   dalam tiket. Tanpa ini deretan barisnya menempel persis pada garis maroon,
   dan garis yang seharusnya membingkai justru terlihat tergores oleh isinya.
   Keterangan di atasnya sudah berbantalan lewat aturan .admin-section, jadi
   yang perlu disusulkan hanya ketiga bagian ini. */
.service-trail > .trail-warning,
.service-trail > .trail-tickets,
.service-trail > .pagination {
  margin-left: 14px;
  margin-right: 14px;
}

/* Barisnya sendiri yang menutup bagian ini ketika tiketnya belum cukup
   banyak untuk memunculkan navigasi halaman, jadi jaraknya ke garis bawah
   dipasang di sini. */
.service-trail > .trail-tickets {
  margin-bottom: 14px;
}

.service-trail > .pagination {
  margin-top: 0;
  margin-bottom: 14px;
}

.trail-ticket {
  border: 1px solid var(--line-soft);
  border-radius: 9px;
  background: var(--surface-sunken);
  overflow: hidden;
}

.trail-ticket.is-open {
  border-color: var(--line);
  background: var(--paper);
}

/* --- Penanda bagian Jejak layanan ---
   Bagian ini satu-satunya yang isinya tidak tertebak dari judulnya, dan
   paling mudah terlewat karena letaknya di bawah daftar pengajuan. Tepinya
   maroon dan berdenyut mengikuti cara yang sama dengan penanda kolom wajib
   yang masih kosong: lambat dan hanya berganti warna tepi, bukan kedipan
   cepat -- apa pun yang berkelip lebih dari tiga kali sedetik berisiko bagi
   penyandang fotosensitivitas. */
@keyframes denyut-jejak-layanan {
  0%, 100% {
    border-color: var(--red-dark);
    box-shadow: 0 0 0 0 rgba(184, 31, 50, 0);
  }
  50% {
    border-color: var(--red);
    box-shadow: 0 0 0 3px rgba(184, 31, 50, 0.15);
  }
}

@media (prefers-reduced-motion: reduce) {
  .service-trail {
    animation: none;
    border-color: var(--red);
  }
}

/*
 * Seluruh baris adalah tombolnya, bukan nomor tiketnya saja: sasaran tekan
 * selebar baris jauh lebih mudah dikenai jari di layar ponsel loket.
 */
.trail-ticket-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 11px 13px;
  text-align: left;
  border: 0;
  background: none;
  cursor: pointer;
}

.trail-ticket-head:hover {
  background: var(--surface-hover);
}

.trail-ticket-head:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.24);
  outline-offset: -3px;
}

.trail-ticket-head .status-pill {
  flex: none;
}

.trail-ticket-name {
  flex: 1 1 auto;
  min-width: 0;
}

.trail-ticket-name strong {
  display: block;
  font-size: 14px;
}

.trail-ticket-name > span {
  display: block;
  overflow: hidden;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.trail-ticket-meta {
  flex: none;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  text-align: right;
}

.trail-ticket-meta span {
  display: block;
}

.trail-ticket-caret {
  flex: none;
  width: 8px;
  height: 8px;
  margin-right: 3px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg) translate(-2px, -2px);
}

.trail-ticket.is-open .trail-ticket-caret {
  transform: rotate(225deg) translate(-2px, -2px);
}

.trail-ticket-body {
  padding: 0 13px 13px;
}

/*
 * Keempat peran ditaruh di atas urutan langkahnya, karena pertanyaan yang
 * membawa orang ke sini hampir selalu siapa, bukan kapan.
 */
.trail-roles {
  display: grid;
  gap: 8px 16px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  margin: 0 0 14px;
  padding: 11px 12px;
  border: 1px solid var(--line-softer);
  border-radius: 8px;
  background: var(--surface-sunken);
}

.trail-roles dt {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.trail-roles dd {
  margin: 2px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink);
}

.trail-roles dd span {
  display: block;
  font-size: 12px;
  color: var(--muted);
}

.trail-role-empty {
  color: var(--muted-soft);
}

.trail-steps {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.trail-steps li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-softer);
}

.trail-steps li:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.trail-steps .status-pill {
  flex: none;
  margin-top: 1px;
}

.trail-steps strong {
  display: block;
  font-size: 13.5px;
}

/*
 * Sengaja menyasar span di dalam blok teksnya saja, bukan semua span.
 * Lencana statusnya pun sebuah span, dan aturan ini dulu ikut mengenainya:
 * display: block mematikan inline-flex miliknya, sehingga align-items yang
 * menengahkan tulisannya tidak lagi berlaku dan tulisan itu naik menempel
 * ke sisi atas lencana.
 */
.trail-steps div span,
.trail-steps small {
  display: block;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.trail-steps small {
  margin-top: 2px;
  color: var(--ink-soft);
}

.trail-ticket-actions {
  margin-top: 13px;
}

/* Di layar sempit keterangan waktu turun ke baris sendiri agar nama pemohon
   tidak tergencet sampai tinggal beberapa huruf. */
@media (max-width: 560px) {
  .trail-ticket-head {
    flex-wrap: wrap;
  }

  .trail-ticket-name {
    flex-basis: calc(100% - 120px);
  }

  .trail-ticket-meta {
    flex-basis: 100%;
    text-align: left;
  }

  .trail-ticket-meta span {
    display: inline;
  }

  .trail-ticket-meta span + span::before {
    content: " \00b7 ";
  }
}

.admin-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 18px 0;
}

.admin-overview {
  display: grid;
  gap: 18px;
}

.overview-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.overview-stat-card {
  min-width: 0;
  padding: 16px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.overview-stat-card span,
.overview-stat-card small {
  display: block;
  color: var(--muted);
}

.overview-stat-card span {
  font-size: 13px;
  font-weight: 700;
}

.overview-stat-card strong {
  display: block;
  margin-top: 8px;
  color: var(--ink);
  font-size: 30px;
  line-height: 1;
}

.overview-stat-card small {
  margin-top: 8px;
  font-size: 12px;
}

.overview-stat-primary {
  border-color: rgba(31, 96, 152, 0.24);
  background: linear-gradient(145deg, var(--tint-blue), var(--paper));
}

.overview-stat-warning {
  border-color: rgba(156, 100, 20, 0.28);
  background: linear-gradient(145deg, var(--tint-amber), var(--paper));
}

.overview-stat-inventory {
  border-color: rgba(23, 122, 83, 0.24);
  background: linear-gradient(145deg, var(--tint-green), var(--paper));
}

.overview-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.overview-card {
  min-width: 0;
  padding: 18px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.overview-card-head {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.overview-card-head h3 {
  margin: 2px 0 0;
}

.overview-card-head .eyebrow {
  margin: 0;
}

.overview-card .status-pill {
  flex: 0 0 auto;
  color: var(--amber);
  background: var(--tint-amber-strong);
}

.overview-request-list,
.overview-activity-list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.overview-request-item,
.overview-activity-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}

.overview-request-item:last-child,
.overview-activity-item:last-child {
  border-bottom: 0;
}

.overview-request-item > div,
.overview-activity-item > div {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.overview-request-item strong,
.overview-request-item span,
.overview-activity-item strong,
.overview-activity-item span,
.overview-activity-item small {
  overflow-wrap: anywhere;
}

.overview-request-item span,
.overview-activity-item span,
.overview-activity-item small {
  color: var(--muted);
  font-size: 12px;
}

.overview-request-item .mini-button {
  flex: 0 0 auto;
}

.overview-activity-item {
  justify-content: start;
  align-items: start;
}

.activity-dot {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  margin-top: 5px;
  border: 3px solid rgba(31, 96, 152, 0.2);
  border-radius: 50%;
  background: var(--blue);
}

.overview-empty {
  display: grid;
  gap: 5px;
  padding: 16px 0 6px;
  color: var(--muted);
}

.overview-empty strong {
  color: var(--ink);
}

.overview-card-action {
  margin-top: 14px;
}

.inventory-percent {
  color: var(--green);
  font-size: 13px;
  font-weight: 800;
}

.inventory-percent.is-warning {
  color: var(--amber);
}

.inventory-meter {
  height: 10px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--tint-neutral-strong);
}

.inventory-meter span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--green), #35a878);
}

.overview-warning {
  margin: 12px 0 0;
  padding: 10px 12px;
  color: var(--amber);
  font-size: 13px;
  line-height: 1.45;
  background: var(--tint-amber);
  border: 1px solid rgba(156, 100, 20, 0.2);
  border-radius: 7px;
}

.inventory-breakdown {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-top: 16px;
}

.inventory-breakdown div {
  min-width: 0;
  padding: 10px;
  background: var(--surface-sunken);
  border-radius: 7px;
}

.inventory-breakdown span,
.inventory-breakdown strong {
  display: block;
}

.inventory-breakdown span {
  color: var(--muted);
  font-size: 11px;
}

.inventory-breakdown strong {
  margin-top: 4px;
  font-size: 18px;
}

.overview-quick-links {
  display: grid;
  gap: 8px;
}

.overview-quick-links button {
  display: grid;
  gap: 4px;
  width: 100%;
  padding: 13px 14px;
  color: var(--ink);
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  cursor: pointer;
}

.overview-quick-links button:hover {
  border-color: rgba(184, 31, 50, 0.3);
  background: var(--tint-red);
}

.overview-quick-links button:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.24);
  outline-offset: 2px;
}

.overview-quick-links span {
  color: var(--muted);
  font-size: 12px;
}

.inventory-view {
  display: grid;
  gap: 18px;
}

.report-summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.report-summary-card {
  min-width: 0;
  padding: 16px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.report-summary-card span,
.report-summary-card small {
  display: block;
  color: var(--muted);
}

.report-summary-card span {
  font-size: 13px;
  font-weight: 700;
}

.report-summary-card strong {
  display: block;
  margin-top: 7px;
  font-size: 28px;
  line-height: 1;
}

.report-summary-card small {
  margin-top: 8px;
  font-size: 12px;
}

.report-summary-good {
  border-color: rgba(23, 122, 83, 0.24);
  background: linear-gradient(145deg, var(--tint-green), var(--paper));
}

.inventory-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(320px, 0.75fr);
  gap: 18px;
  align-items: start;
}

.inventory-panel {
  min-width: 0;
  padding: 18px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.inventory-form {
  min-width: 0;
}

.inventory-panel-head {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.inventory-panel-head .eyebrow {
  margin: 0;
}

.inventory-panel-head h3 {
  margin: 3px 0 0;
}

.inventory-stock-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.inventory-stock-card {
  min-width: 0;
  padding: 14px;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.inventory-stock-card.is-low {
  border-color: rgba(156, 100, 20, 0.35);
  background: var(--tint-amber);
}

.inventory-stock-head {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.inventory-stock-head > div {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.inventory-stock-head span {
  color: var(--muted);
  font-size: 12px;
}

.inventory-stock-head b {
  color: var(--green);
  font-size: 14px;
}

.inventory-stock-card.is-low .inventory-stock-head b {
  color: var(--amber);
}

.inventory-stock-breakdown {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 12px;
  color: var(--muted);
  font-size: 11px;
}

.inventory-stock-breakdown strong {
  color: var(--ink);
  font-size: 12px;
}

.inventory-low-label {
  display: inline-block;
  margin-top: 10px;
  color: var(--amber);
  font-size: 11px;
  font-weight: 800;
}

/* Kolom pendek dirata-tengahkan agar sejajar dengan kepala tabelnya. Kolom
   teks panjang tetap rata kiri, karena teks rata tengah sulit dipindai. */
.table-index,
.table-quantity,
.compact-table td[data-label="Status"],
.compact-table td[data-label="Detail"] {
  text-align: center;
}

/* Kepala kolom mengikuti perataan isinya. Sebelumnya seluruh kepala
   dirata-tengahkan sementara kolom teks rata kiri, sehingga judul kolom
   melayang tidak sejajar dengan angka maupun teks di bawahnya. */
th.table-index,
th.table-quantity {
  text-align: center;
}

/* Dipakai kepala kolom sekaligus selnya, untuk kolom pendek yang isinya bukan
   angka -- lencana status dan tombol. Satu kelas untuk keduanya menjaga judul
   dan isinya tidak pernah bergeser sendiri-sendiri. */
.is-centered {
  text-align: center;
}

/* Tabel petugas isinya pendek semua -- nama, peran, status, tanggal -- jadi
   seluruh kolomnya dirata-tengahkan dan terbaca sebagai satu blok yang rapi.
   Alasan menjaga kolom teks tetap rata kiri di tabel lain tidak berlaku di
   sini, karena tidak ada daftar panjang yang perlu ditelusuri mata. */
.admin-users-table th,
.admin-users-table td {
  text-align: center;
}

.admin-users-table td {
  vertical-align: middle;
}

.admin-users-table .admin-user-actions {
  justify-content: center;
}

.table-index {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Kolom No. tabel petugas diberi bidang maroon. Di layar lebar ia menjadi tepi
   kiri yang tegas, sehingga mata dapat menghitung baris tanpa menyusuri garis
   tabel yang tipis. Di ponsel gunanya lebih besar lagi: tiap baris di sana
   berubah menjadi kartu tersendiri, dan bidang ini menjadi kepala kartunya --
   penanda paling jelas bahwa satu data sudah selesai dan data berikutnya
   dimulai. */
.admin-users-table .table-index {
  color: var(--on-accent);
  font-weight: 700;
  background: var(--red-dark);
}

.table-quantity {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.table-quantity-note {
  color: var(--muted);
  font-size: 12px;
}

/*
 * Pilihan status di dalam baris dibuat sekecil mungkin supaya tabelnya tidak
 * melebar hanya karena satu kolom kontrol.
 */
.table-status-select {
  min-width: 0;
  max-width: 100%;
  min-height: 32px;
  padding: 0 8px;
  font-size: 13px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 7px;
  cursor: pointer;
}

/* Pilihan status ikut berwarna seperti lencananya, supaya keadaan pengajuan
   tetap terbaca sekilas walaupun kolomnya berupa kontrol. */
.table-status-select.green {
  color: var(--green);
  border-color: var(--green);
  background: var(--tint-green-strong);
}

.table-status-select.red {
  color: var(--danger);
  border-color: var(--danger);
  background: var(--tint-red);
}

.table-status-select.amber {
  color: var(--amber);
  border-color: var(--amber);
  background: var(--tint-amber-strong);
}

.table-status-select {
  font-weight: 700;
}

.table-status-select:disabled {
  cursor: progress;
  opacity: 0.6;
}

.handover-block {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}

.handover-block h4 {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.handover-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  align-items: start;
}

.handover-form {
  min-width: 0;
  padding: 14px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.handover-form-head {
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-soft);
}

.handover-row + .handover-row {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
}

.handover-row-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.handover-row-head span {
  color: var(--muted);
  font-size: 12px;
}

.handover-recap {
  margin-top: 14px;
}

.handover-summary {
  margin: 4px 0 0;
  color: var(--danger);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.5;
}

.handover-summary:empty {
  display: none;
}

.handover-form .form-actions {
  margin-top: 2px;
}

.photo-slot {
  min-width: 0;
  padding: 14px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.photo-slot-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.photo-slot-state {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

/*
 * Panggung berukuran tetap supaya kartu tidak melompat-lompat saat berganti
 * antara keadaan kosong, pratinjau kamera, dan hasil jepretan.
 */
.photo-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--tint-neutral);
  border: 1px solid var(--line-soft);
  border-radius: 7px;
}

.photo-preview,
.photo-shot {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * Fotonya sendiri yang jadi tombol, bukan tombol terpisah di sebelahnya:
 * menekan gambar untuk memperbesarnya sudah menjadi kebiasaan, dan bidang
 * tekannya seluas foto itu -- cukup lapang untuk jari di layar ponsel loket.
 */
.photo-shot-button {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}

.photo-shot-button:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.24);
  outline-offset: -3px;
}

.photo-lightbox {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(15, 22, 32, 0.72);
  overscroll-behavior: contain;
}

.photo-lightbox-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(960px, 100%);
  max-height: 100%;
  margin: 0;
  padding: 14px;
  border-radius: 12px;
  background: var(--paper);
  box-shadow: 0 24px 70px rgba(20, 28, 38, 0.32);
}

.photo-lightbox-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
}

.photo-lightbox-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
}

/* Halaman PDF di dalam pratinjau boleh setinggi panelnya, tidak dipatok
   480px seperti pratinjau kecil di kartu dokumen: di sinilah orang datang
   justru untuk membacanya. */
.photo-lightbox-panel .pdf-preview {
  max-height: none;
  min-height: 0;
}

/*
 * Berbeda dengan bingkai di kartu, di sini fotonya dimuat utuh: yang dicari
 * petugas justru bagian yang tadi terpangkas.
 */
.photo-lightbox-image {
  width: 100%;
  min-height: 0;
  object-fit: contain;
  border-radius: 8px;
  background: var(--tint-neutral);
}

.photo-empty {
  margin: 0;
  padding: 0 12px;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

.photo-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.photo-note {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.photo-note:empty {
  display: none;
}

.photo-note.is-invalid {
  color: var(--danger);
  font-weight: 700;
}

.return-condition {
  margin: 0 0 4px;
  padding: 14px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.return-condition legend {
  padding: 0 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.return-condition-row + .return-condition-row {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
}

.return-condition-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 12px 0 8px;
}

.return-condition-head span {
  color: var(--muted);
  font-size: 12px;
}

.return-condition-summary {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.return-condition-summary.is-invalid {
  color: var(--danger);
  font-weight: 700;
}

.inventory-form-group {
  margin: 0 0 16px;
  padding: 14px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.inventory-form-group-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line-soft);
}

.inventory-form-group-head h4 {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/*
 * Setiap .field sudah menyisakan 18px untuk baris pesan kesalahan, terisi atau
 * tidak. Tanpa memperhitungkan sisa ruang itu, tombol simpan terlihat
 * mengambang jauh di bawah kolom terakhir.
 */
.inventory-form-group .form-actions {
  margin-top: 2px;
}

.inventory-preview {
  margin: 12px 0 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

/* Baris ini hanya terisi saat sisa stok akan minus, jadi ruangnya tidak
   disisakan ketika angkanya sudah benar. */
.inventory-preview:empty {
  display: none;
}

.inventory-preview.is-invalid {
  color: var(--danger);
  font-weight: 700;
}

.inventory-help {
  margin: 16px 0 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.tab-button {
  min-height: 38px;
  padding: 0 12px;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--paper);
  cursor: pointer;
}

.tab-button.active {
  color: var(--red-dark);
  border-color: rgba(184, 31, 50, 0.32);
  background: rgba(184, 31, 50, 0.08);
}

.summary-tile {
  padding: 16px;
}

.summary-tile,
.overview-stat-card,
.overview-card,
.report-summary-card,
.inventory-panel,
.admin-request-filter {
  box-shadow: 0 8px 24px rgba(20, 28, 38, 0.05);
}

.admin-request-filter {
  margin-bottom: 16px;
  border-color: rgba(31, 96, 152, 0.16);
  background: linear-gradient(180deg, var(--paper), var(--surface-tint));
}

.admin-filter-actions {
  margin-top: 16px;
}

.filter-result-count {
  color: var(--muted);
  font-size: 13px;
}

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin: 14px 0 18px;
}

.pagination-summary {
  color: var(--muted);
  font-size: 13px;
}

.pagination-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
}

.pagination-button {
  min-width: 34px;
  min-height: 34px;
  padding: 6px 9px;
  color: var(--blue);
  font-size: 13px;
  font-weight: 700;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--paper);
  cursor: pointer;
}

.pagination-button:hover:not(:disabled),
.pagination-button.active {
  color: var(--on-accent);
  background: var(--blue);
  border-color: var(--blue);
}

.pagination-button:disabled {
  color: var(--muted-soft);
  background: var(--disabled-bg);
  cursor: not-allowed;
}

.pagination-edge {
  padding-inline: 10px;
}

.pagination-ellipsis {
  padding: 0 2px;
  color: var(--muted);
}

.table-shell {
  /* Jarak dari blok di atasnya dijadikan aturan, bukan ditempel satu per satu
     lewat atribut style. Cara lama membuat tab yang lupa menambahkannya --
     Laporan salah satunya -- tabelnya menempel pada kartu ringkasan. */
  margin-top: 16px;
  max-height: min(68vh, 720px);
  overflow: auto;
}

table {
  width: 100%;
  min-width: 760px;
  border-collapse: collapse;
}

.report-table {
  min-width: 980px;
}

.report-table th,
.report-table td {
  white-space: nowrap;
}

.report-table th {
  font-size: 11px;
}

.report-table td {
  font-size: 14px;
}

.report-table .report-activity-cell {
  width: 300px;
  max-width: 360px;
  white-space: normal;
  overflow-wrap: anywhere;
}

.report-activity-cell strong,
.report-activity-cell span {
  display: block;
}

.report-activity-cell span {
  margin-top: 3px;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.35;
}

.compact-table {
  min-width: 1080px;
}

th,
td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

td {
  font-size: 14px;
}

th {
  color: var(--ink-table);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-align: left;
  text-transform: uppercase;
  background: var(--surface-sunken);
  white-space: nowrap;
}

/*
 * Garis bawah kepala tabel digambar sebagai bayangan dalam, bukan border.
 * Dengan border-collapse: collapse, border milik sel yang position: sticky
 * ikut tergulung dan tidak pernah tergambar, sehingga garisnya putus.
 */
.compact-table thead th,
.report-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  box-shadow: inset 0 -1px 0 var(--line);
}

td {
  color: var(--ink-label);
}

tbody tr:hover td {
  background: var(--surface-hover);
}

tr.selected-row td {
  background: var(--tint-blue);
}

tr.selected-row td:first-child {
  box-shadow: inset 4px 0 0 var(--blue);
}

tr.needs-action td {
  background: var(--tint-amber);
}

tr.needs-action td:first-child {
  box-shadow: inset 4px 0 0 var(--amber);
}

tr.selected-row.needs-action td {
  background: var(--tint-blue);
}

tr.selected-row.needs-action td:first-child {
  box-shadow: inset 4px 0 0 var(--blue);
}

.priority-badge {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  margin-top: 6px;
  padding: 3px 7px;
  color: var(--amber);
  font-size: 11px;
  font-weight: 800;
  background: var(--tint-amber-strong);
  border: 1px solid rgba(156, 100, 20, 0.24);
  border-radius: 6px;
}

.clickable-row {
  cursor: pointer;
}

.clickable-row:hover td,
.clickable-row:focus td {
  background: var(--tint-blue);
}

.clickable-row:focus {
  outline: 3px solid rgba(31, 96, 152, 0.18);
  outline-offset: -3px;
}

.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
  max-width: 100%;
}

.mini-button {
  min-height: 32px;
  padding: 0 10px;
  color: var(--blue);
  border: 1px solid rgba(31, 96, 152, 0.24);
  border-radius: 7px;
  background: var(--paper);
  cursor: pointer;
}

.mini-button:hover {
  background: var(--tint-blue);
}

.mini-button:disabled {
  color: var(--muted-soft);
  border-color: var(--line);
  background: var(--disabled-bg);
  cursor: not-allowed;
  opacity: 0.9;
}

.admin-status-form .form-actions {
  position: sticky;
  bottom: -14px;
  z-index: 2;
  margin: 0 -14px -14px;
  padding: 12px 14px 14px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0), var(--paper) 35%);
}

.request-modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 20px;
  background: var(--overlay);
}

/* Halaman dikunci selama popup terbuka. overscroll-behavior menahan gulirannya
   di dalam popup, sedangkan overflow pada body mencegah halaman ikut bergerak
   pada peramban yang tetap meneruskan gulirannya. Keduanya diperlukan: yang
   satu saja tidak menutup seluruh peramban. */
html.modal-terbuka {
  overflow: hidden;
}

html.modal-terbuka body {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

.request-modal,
.card-modal,
.scan-modal {
  overscroll-behavior: contain;
}

.request-modal[hidden] {
  display: none;
}

.modal-card {
  width: min(880px, 100%);
  max-height: min(86vh, 820px);
  min-height: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  overflow-x: hidden;
  overflow: hidden;
  box-shadow: 0 24px 70px rgba(20, 28, 38, 0.22);
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-width: 0;
  padding: 0 0 12px;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

.modal-title-group {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.modal-title-group > span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.modal-title-group h3 {
  margin: 0;
  overflow-wrap: anywhere;
}

/* --- Dialog konfirmasi ---
   Menumpang gaya .request-modal, tetapi kartunya jauh lebih sempit karena
   isinya hanya satu pertanyaan. Tingginya dibiarkan mengikuti isi, tidak
   seperti .modal-card yang dipatok agar isi panjang dapat digulir. */
.confirm-card {
  width: min(460px, 100%);
  max-height: none;
  grid-template-rows: auto auto;
}

.confirm-body {
  display: grid;
  gap: 18px;
  padding-top: 16px;
}

.confirm-body p {
  margin: 0;
  color: var(--ink-soft);
  line-height: 1.6;
}

.confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* Di layar sempit tombol ditumpuk, dengan tombol setuju di atas agar berada
   dalam jangkauan ibu jari. */
@media (max-width: 480px) {
  .confirm-actions {
    flex-direction: column-reverse;
  }

  .confirm-actions .button {
    width: 100%;
  }
}

.modal-close {
  display: inline-grid;
  flex: 0 0 auto;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  color: var(--muted);
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
  border: 0;
  border-radius: 7px;
  background: transparent;
  cursor: pointer;
}

.modal-close:hover {
  color: var(--ink);
  background: var(--tint-neutral);
}

.modal-close:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.24);
  outline-offset: 2px;
}

.modal-body {
  min-width: 0;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  padding-top: 18px;
}

.admin-detail-body {
  display: grid;
  gap: 12px;
}

.request-quick-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.quick-summary-item {
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface-sunken);
}

.quick-summary-item > span:first-child {
  display: block;
  margin-bottom: 4px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.quick-summary-item strong {
  display: block;
  overflow-wrap: anywhere;
}

.quick-summary-status strong {
  min-height: 28px;
}

.admin-section {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
}

.admin-section > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding: 12px 14px;
  color: var(--ink);
  font-weight: 800;
  cursor: pointer;
  list-style: none;
}

.admin-section > summary::-webkit-details-marker {
  display: none;
}

.admin-section > summary::after {
  flex: 0 0 auto;
  color: var(--muted);
  content: "+";
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
}

.admin-section[open] > summary {
  border-bottom: 1px solid var(--line);
}

.admin-section[open] > summary::after {
  content: "\2212";
}

.admin-section > summary:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.24);
  outline-offset: -3px;
}

.section-summary {
  margin-left: auto;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  text-align: right;
}

/* --- Bagian pada halaman Pengaturan --- */

/* Dua blok yang berdiri sendiri, jadi diberi jarak. Sebelumnya keduanya
   bersinggungan dan garis di antaranya terbaca sebagai satu kotak yang
   terbagi, bukan sebagai dua bagian yang masing-masing dapat dibuka. */
.settings-section + .settings-section {
  margin-top: 14px;
}

.settings-section:first-of-type {
  margin-top: 18px;
}

/* Tepinya maroon dan berdenyut, persis seperti Jejak layanan -- termasuk
   alasannya: denyutnya TIDAK berhenti ketika bagiannya dibentangkan. Tepi yang
   tenang begitu dibuka membuat penandanya seakan lenyap, padahal bagian yang
   sedang terbuka justru yang paling perlu tetap terbaca sebagai satu blok
   tersendiri -- di sini, di antara borang panjang dan tabel petugas. */
.settings-section {
  border-color: var(--red-dark);
  animation: denyut-jejak-layanan 1.9s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .settings-section {
    animation: none;
    border-color: var(--red);
  }
}

.admin-section .detail-list,
.admin-section .detail-documents,
.admin-section .detail-trail,
.admin-status-form {
  margin: 0;
  padding: 14px;
}

/*
 * Anak langsung sebuah bagian yang tidak membawa bantalannya sendiri.
 *
 * Bantalan 14px di atas hanya diberikan kepada .detail-list dan kerabatnya,
 * sehingga keterangan dan kartu foto yang ditaruh langsung di dalam sebuah
 * bagian menempel pada garis tepinya -- bahkan menembusnya, karena kartunya
 * selebar penuh sedangkan bagiannya bergaris. Yang tampak lalu tidak sejajar
 * dengan judul bagiannya sendiri, yang memang sudah berbantalan sejak awal.
 *
 */
.admin-section > .field-hint {
  margin: 0;
  padding: 14px;
}

/*
 * Bantalan bawahnya dilepas hanya bila masih ada blok berbantalan di
 * bawahnya, sebab menjumlahkan keduanya membuat jaraknya menganga. Ketika
 * keterangan itu satu-satunya isi bagian -- seperti pada bagian yang sudah
 * terkunci -- bantalannya utuh, sehingga tulisannya duduk rata atas-bawah
 * dan tidak menempel ke garis bawah.
 */
.admin-section > .field-hint:not(:last-child) {
  padding-bottom: 0;
}

.admin-section > .handover-grid {
  padding: 14px;
}

.admin-section .detail-list {
  gap: 8px;
}

.admin-section .detail-list div:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.admin-status-form {
  display: grid;
  gap: 12px;
}

.admin-status-form .form-actions {
  position: sticky;
  bottom: -14px;
  z-index: 2;
  margin: 0 -14px -14px;
  padding: 12px 14px 14px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0), var(--paper) 35%);
}

.admin-section .detail-documents {
  display: grid;
  gap: 12px;
  border-top: 0;
}

/* Peran dan langkah dipakai bersama dengan Jejak layanan, jadi tidak ada
   gaya khusus di sini selain bantalannya. */
.detail-trail .trail-roles {
  margin-bottom: 14px;
}

.email-log-list {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 14px;
  list-style: none;
}

.email-log-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
}

.email-log-main {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.email-log-main div {
  display: grid;
  gap: 2px;
}

.email-log-main span,
.email-log-main small,
.email-log-main time,
.email-log-empty {
  color: var(--muted);
  overflow-wrap: anywhere;
}

.email-log-main time,
.email-log-main small {
  font-size: 12px;
}

.email-log-main p {
  margin: 2px 0 0;
  color: var(--ink-warning);
  font-size: 13px;
  font-weight: 600;
}

.email-log-main .email-retry-schedule {
  color: var(--muted);
  font-weight: 600;
}

.email-resend-button {
  flex: 0 0 auto;
}

.detail-list {
  display: grid;
  gap: 10px;
  margin: 18px 0;
}

.detail-list div {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.detail-list dt {
  color: var(--muted);
  font-weight: 700;
}

.detail-list dt::after {
  content: ":";
}

.detail-list dd {
  margin: 0;
  overflow-wrap: anywhere;
  color: var(--ink-label);
  font-weight: 600;
}

.detail-documents {
  display: grid;
  gap: 12px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.detail-documents h3 {
  margin: 0;
}

.attachment-card,
.document-card {
  display: grid;
  gap: 12px;
  min-width: 0;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface-tint);
}

.attachment-card-head,
.document-card {
  align-items: center;
}

.attachment-card-head,
.document-card {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
}

.attachment-card-head > div:first-child,
.document-card > div:first-child {
  display: grid;
  gap: 4px;
  min-width: 0;
  max-width: 100%;
  flex: 1 1 260px;
}

.attachment-card-head > div:first-child strong,
.document-card > div:first-child strong,
.attachment-card-head > div:first-child span,
.document-card > div:first-child span {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.attachment-card-head span,
.document-card span {
  color: var(--muted);
  font-size: 13px;
}

.attachment-preview-frame {
  width: 100%;
  min-height: 360px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--document-paper);
}

/*
 * Gambar lampiran dan scan tanda terima dapat ditekan untuk dibuka utuh,
 * sama seperti foto barang. Tombolnya tidak diberi tinggi tetap seperti
 * .photo-shot-button karena di sini gambarnya yang menentukan tinggi
 * kartunya, bukan sebaliknya.
 */
.attachment-preview-button {
  display: block;
  width: 100%;
  padding: 0;
  text-align: center;
  border: 0;
  background: none;
  cursor: zoom-in;
}

.attachment-preview-button:focus-visible {
  outline: 3px solid rgba(31, 96, 152, 0.24);
  outline-offset: 2px;
}

/*
 * Ditengahkan pada ukuran aslinya, bukan direntang selebar kartu.
 * width: 100% membuat pindaian kecil dipaksa membesar sampai buram, dan
 * surat yang aslinya tegak lurus jadi menempel ke tepi kiri kartu ketika
 * proporsinya tidak sama dengan wadahnya. Dengan margin otomatis, sekecil
 * atau sebesar apa pun berkasnya, letaknya selalu di tengah.
 */
.attachment-preview-image {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 460px;
  margin-left: auto;
  margin-right: auto;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--document-paper);
}

.pdf-preview {
  display: grid;
  justify-items: center;
  gap: 10px;
  max-height: 480px;
  overflow: auto;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--tint-neutral-strong);
}

/* Lembarnya selebar halaman yang digambar, bukan selebar kartunya, supaya
   yang terlihat memang menyerupai kertas -- bukan bidang putih lebar
   dengan halaman kecil menggantung di tengahnya. */
.pdf-preview-page {
  display: grid;
  justify-items: center;
  width: fit-content;
  max-width: 100%;
  gap: 6px;
  padding: 8px;
  background: var(--document-paper);
  box-shadow: 0 2px 8px rgba(20, 28, 38, 0.12);
}

.pdf-preview-page canvas {
  display: block;
  max-width: 100%;
  height: auto;
}

.pdf-preview-page-label {
  color: var(--muted);
  font-size: 11px;
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 14px 0;
}

.detail-item {
  padding: 12px;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: 7px;
}

.detail-item span {
  display: block;
  color: var(--muted);
  font-size: 12px;
}

.detail-item strong {
  display: block;
  margin-top: 4px;
  overflow-wrap: anywhere;
}

.status-timeline-wrap {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}

.status-timeline-wrap h3 {
  margin-bottom: 14px;
  color: var(--ink-label);
  font-size: 16px;
}

.status-timeline {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.timeline-step {
  position: relative;
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: 12px;
  min-height: 70px;
  padding-bottom: 18px;
}

.timeline-step:not(:last-child)::before {
  position: absolute;
  top: 30px;
  bottom: 0;
  left: 14px;
  width: 3px;
  content: "";
  background: var(--line);
  border-radius: 99px;
}

.timeline-marker {
  position: relative;
  z-index: 1;
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  color: var(--muted);
  font-size: 13px;
  font-weight: 800;
  background: var(--tint-neutral);
  border: 2px solid var(--line);
  border-radius: 50%;
}

.timeline-content {
  display: grid;
  align-content: start;
  gap: 3px;
  padding-top: 2px;
}

.timeline-content strong {
  color: var(--ink-label);
}

.timeline-content span,
.timeline-content small {
  color: var(--muted);
  line-height: 1.45;
}

.timeline-content small {
  display: block;
  overflow-wrap: anywhere;
}

.timeline-step.is-complete .timeline-marker {
  color: var(--green);
  background: var(--tint-green-strong);
  border-color: rgba(23, 122, 83, 0.32);
}

.timeline-step.is-complete:not(:last-child)::before {
  background: rgba(23, 122, 83, 0.45);
}

.timeline-step.is-current .timeline-marker {
  color: var(--on-accent);
  background: var(--blue);
  border-color: var(--blue);
  box-shadow: 0 0 0 5px rgba(31, 96, 152, 0.12);
}

.timeline-step.is-current .timeline-content strong {
  color: var(--blue);
}

.timeline-step.is-rejected .timeline-marker {
  color: var(--danger);
  background: var(--tint-red);
  border-color: rgba(179, 38, 30, 0.3);
}

.timeline-step.is-rejected.is-current .timeline-marker {
  color: var(--on-accent);
  background: var(--danger);
  border-color: var(--danger);
  box-shadow: 0 0 0 5px rgba(179, 38, 30, 0.12);
}

.timeline-step.is-rejected.is-current .timeline-content strong {
  color: var(--danger);
}

.empty-state {
  padding: 24px;
  color: var(--muted);
  text-align: center;
  overflow-wrap: anywhere;
}

.toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 100;
  max-width: min(420px, calc(100vw - 36px));
  padding: 13px 15px;
  color: var(--on-accent);
  background: var(--toast-bg);
  border-radius: 8px;
  box-shadow: var(--shadow);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 180ms ease, transform 180ms ease;
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}

.hidden {
  display: none !important;
}

@media (max-width: 900px) {
  .site-header {
    align-items: start;
    flex-direction: column;
    gap: 12px;
  }

  .main-nav {
    width: 100%;
  }

  .hero,
  .form-layout,
  .admin-layout {
    grid-template-columns: 1fr;
  }

  .hero {
    min-height: auto;
  }

  .hero-visual {
    min-height: 240px;
  }

  .hero-visual img {
    width: min(100%, 260px);
    max-height: 330px;
  }

  .public-form-layout {
    grid-template-columns: 1fr;
  }

  /*
   * Syaratnya naik ke atas formulir.
   *
   * Di layar lebar kotak ini menempel di kolom kanan dan selalu terbaca
   * sambil mengisi. Begitu tata letaknya runtuh jadi satu kolom, ia jatuh ke
   * bawah formulir -- dan syarat yang baru terbaca sesudah seluruh kolom
   * diisi sudah kehilangan gunanya. Urutan tampilnya karena itu dibalik,
   * sementara urutan di dalam dokumen dibiarkan apa adanya supaya pembaca
   * layar tetap menemui formulirnya lebih dulu.
   */
  .public-help {
    position: static;
    order: -1;
  }

  .process-grid,
  .summary-grid,
  .report-summary-grid,
  .overview-stat-grid,
  .request-quick-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .overview-grid,
  .inventory-layout {
    grid-template-columns: 1fr;
  }

  .inventory-stock-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .main-nav {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 5px;
    width: 100%;
    padding: 4px;
    overflow: visible;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--soft);
  }

  .main-nav a {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 40px;
    padding: 8px 4px;
    font-size: clamp(11px, 3.4vw, 13px);
    line-height: 1.2;
    text-align: center;
  }

  /* Tautan layanan publik ditandai hidden oleh setActiveNav saat berada di
     area admin. Aturan .main-nav a di atas menimpa gaya bawaan peramban untuk
     [hidden], sehingga tanpa penawar ini tautan tersembunyi tetap tampil di
     header dashboard. */
  .main-nav a[hidden] {
    display: none;
  }

  .page {
    width: min(100% - 24px, 1160px);
    padding-top: 24px;
  }

  .brand {
    min-width: 0;
  }

  .brand-mark {
    width: 38px;
    height: 38px;
  }

  .agency-badge {
    align-items: flex-start;
    border-radius: 8px;
  }

  h1 {
    font-size: clamp(46px, 18vw, 76px);
  }

  .hero-title img {
    width: min(100%, 240px);
  }

  .form-grid,
  .resource-grid,
  .metric-row,
  .process-grid,
  .summary-grid,
  .detail-grid,
  .request-quick-summary,
  .overview-stat-grid,
  .report-summary-grid,
  .handover-grid,
  .inventory-stock-grid {
    grid-template-columns: 1fr;
  }

  .inventory-breakdown {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .detail-list div {
    grid-template-columns: 1fr;
    gap: 4px;
  }

  .table-shell {
    max-height: none;
    overflow: visible;
  }

  /* Berlaku untuk setiap tabel di dalam cangkang, bukan hanya yang berkelas.
     Aturan thead/tbody/tr/td di bawah sudah umum, jadi tabel tanpa kelas yang
     tertinggal di sini akan tetap dipaksa selebar min-width dan isinya
     melewati batas kartu. */
  .table-shell table {
    display: block;
    min-width: 0;
  }

  .table-shell table thead {
    display: none;
  }

  .table-shell table tbody {
    display: grid;
    gap: 12px;
  }

  .table-shell table tbody tr {
    display: grid;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--paper);
    box-shadow: 0 8px 20px rgba(20, 28, 38, 0.05);
  }

  /* Perataan tengah pada tampilan tabel dipakai agar kolom angka berbaris rapi
     di bawah judulnya. Begitu barisnya menjadi tumpukan label-dan-isi, kolom
     itu tidak ada lagi -- yang tersisa hanya daftar yang seharusnya rata kiri
     seluruhnya. Tanpa penawar ini, sebagian label menggantung di tengah dan
     sebagian rapat ke kiri pada baris yang sama. */
  .table-shell table tbody td {
    display: grid;
    grid-template-columns: minmax(108px, 38%) minmax(0, 1fr);
    gap: 10px;
    min-width: 0;
    padding: 11px 12px;
    white-space: normal;
  }

  /* Pemilihnya sengaja menyebut [data-label] agar cukup kuat mengalahkan
     aturan rata tengah pada kolom angka, yang pemilihnya juga memakai atribut
     itu. Media query sendiri tidak menambah kekuatan pemilih. */
  .table-shell table tbody td[data-label],
  .table-shell table tbody td[data-label]::before {
    text-align: left;
  }

  /* Label mengikuti gaya label lain di aplikasi ini: huruf besar merenggang,
     supaya terbaca sebagai keterangan kolom, bukan sebagai isi barisnya. */
  .table-shell table tbody td::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.5;
  }

  .table-shell table tbody td:last-child {
    border-bottom: 0;
  }

  /* Label kolom pada kartu petugas memakai warna redup yang lenyap di atas
     bidang maroon kepala kartunya. */
  .admin-users-table tbody td.table-index::before {
    color: rgba(255, 255, 255, 0.72);
  }

  /* Sel yang berdiri sendiri, misalnya baris "belum ada data", tidak punya
     pasangan label sehingga isinya boleh memakai seluruh lebar. */
  .table-shell table tbody td:only-child {
    display: block;
  }

  .table-shell table tbody td:only-child::before {
    content: none;
  }

  .table-shell table tbody .mini-button {
    justify-self: start;
  }

  .pagination {
    align-items: stretch;
    flex-direction: column;
  }

  .pagination-controls {
    justify-content: flex-start;
  }

  .email-log-item {
    flex-direction: column;
  }

  .email-resend-button {
    align-self: stretch;
  }

  .form-intro {
    align-items: flex-start;
    gap: 10px;
    padding: 12px;
  }

  .form-intro img {
    width: 98px;
    max-height: 46px;
  }

  .form-intro strong {
    font-size: 16px;
  }

  .section-head {
    align-items: start;
    flex-direction: column;
  }

  .button {
    width: 100%;
  }

  /*
   * Di ponsel footer menyusut menjadi sebaris ikon media sosial dan satu
   * baris hak cipta.
   *
   * Sebelumnya isinya menumpuk jadi satu kolom -- logo selebar 240px, alamat
   * dua baris, ikon, lalu blok hak cipta tiga baris -- sekitar 300 piksel di
   * kaki setiap halaman, padahal di bawahnya masih ada bilah navigasi tetap.
   * Yang benar-benar dicari orang dari ponsel adalah tautan media sosialnya;
   * alamat kantor dan logo tetap tersedia di layar lebar, tempat ruangnya
   * memang ada.
   */
  .footer-brand,
  .footer-address {
    display: none;
  }

  .footer-contact {
    display: flex;
    justify-content: center;
    padding: 16px 18px;
  }

  .social-links {
    margin-top: 0;
  }

  .footer-copyright {
    gap: 6px;
    padding: 0 18px 16px;
    border-top: 0;
    font-size: 11.5px;
  }

  /* Kalimat "Hak Cipta Dilindungi Undang-Undang" dilepas supaya barisnya
     tetap satu; tahun dan nama lembaganya sudah cukup sebagai pernyataan. */
  .footer-copyright span:last-child {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Akun organisasi peminjam --- */

/* Tautan halaman milik akun, sebelum pemisah. Tanpa tepi dan tanpa jarak
   tambahan, sehingga terbaca menyatu dengan tautan layanan publik di
   sebelahnya. */
.auth-nav-pages {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.auth-nav-pages:empty {
  display: none;
}

.auth-nav {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: 6px;
  padding-left: 10px;
  border-left: 1px solid var(--line-strong);
}

/* Nama dibiarkan membungkus ke baris kedua alih-alih dipotong ellipsis, agar
   petugas selalu dapat membaca sedang masuk sebagai siapa. Batas lebarnya
   menjaga tombol Keluar tetap berada di baris yang sama. */
.auth-nav-name {
  max-width: 240px;
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--red-dark);
  overflow-wrap: anywhere;
}

/* Sama persis dengan tombol Keluar di bilah akun: maroon berisi, tulisan
   putih. Tombol yang sama tidak boleh berganti rupa hanya karena dilihat dari
   header alih-alih dari bilah akun. */
.auth-nav-button {
  padding: 7px 13px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: var(--red-dark);
  color: var(--on-accent);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.auth-nav-button:hover {
  background: var(--red);
}

.auth-box {
  max-width: 460px;
  margin: 48px auto;
}

.auth-box .agreement-box {
  margin-top: 16px;
}

.auth-switch {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  font-size: 0.9rem;
  color: var(--muted);
  text-align: center;
}

.auth-switch a {
  font-weight: 600;
  color: var(--red-dark);
}

/* Kolom yang nilainya berasal dari akun tidak dapat disunting di formulir. */
.field input[readonly] {
  background: var(--readonly-bg);
  color: var(--muted);
  cursor: not-allowed;
}

/* Kolom tanggal yang belum boleh diisi karena kolom sebelumnya masih kosong.
   Dibedakan dari readonly dengan opasitas, agar terbaca sebagai "belum
   waktunya" dan bukan "tidak akan pernah bisa diubah". */
.field input:disabled {
  background: var(--readonly-bg);
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.65;
}

/* Kolom tanggal terkunci: latarnya diberikan pada lapisan teks, karena kolom
   aslinya sengaja transparan agar tulisan di bawahnya terlihat. */
.date-control input[type="date"]:disabled {
  background: transparent;
  opacity: 1;
}

.date-control input[type="date"]:disabled ~ .date-display {
  background: var(--readonly-bg);
}

/* Keterangan alasan kolom terkunci ditandai agar tidak terbaca sebagai galat.
   Peringatan biasa memakai --danger; ini sekadar urutan pengisian. */
/* :has() dipakai karena input tanggal kini bersarang di dalam .date-control,
   sehingga bukan lagi saudara dari .field-hint. */
.field:has(input:disabled) .field-hint {
  color: var(--muted-soft);
  font-style: italic;
}

/* --- Penanda kolom wajib yang masih kosong ---
   Tepinya berdenyut maroon agar pemohon langsung melihat apa yang tersisa
   tanpa harus menyusuri borang dari atas. Denyutnya lambat dan hanya berganti
   warna tepi, bukan kedipan cepat: apa pun yang berkelip lebih dari tiga kali
   sedetik berisiko bagi penyandang fotosensitivitas. */
@keyframes denyut-kolom-kosong {
  0%, 100% {
    border-color: var(--field-border);
    box-shadow: 0 0 0 0 rgba(184, 31, 50, 0);
  }
  50% {
    border-color: var(--red);
    box-shadow: 0 0 0 3px rgba(184, 31, 50, 0.15);
  }
}

/* Kolom yang sedang diketik tidak ikut berdenyut. Selama pemohon berada di
   dalamnya ia jelas tahu kolom itu kosong, dan denyut di bawah kursor hanya
   mengganggu. */
.field.is-blank input:not(:focus),
.field.is-blank select:not(:focus),
.field.is-blank textarea:not(:focus) {
  animation: denyut-kolom-kosong 1.9s ease-in-out infinite;
}

/* Kolom tanggal tidak perlu aturan sendiri. Yang dibuat transparan hanya warna
   teks dan latarnya, sedangkan tepinya tetap digambar input aslinya -- dan
   input itu berada di atas lapisan teks, sehingga aturan umum di atas sudah
   mengenai tepi yang benar. */

/* Sebagian orang merasa pusing oleh gerakan berulang, dan sebagian lagi
   mematikannya lewat pengaturan sistem. Penandanya tetap ada, hanya diam. */
@media (prefers-reduced-motion: reduce) {
  .field.is-blank input:not(:focus),
  .field.is-blank select:not(:focus),
  .field.is-blank textarea:not(:focus) {
    animation: none;
    border-color: var(--red);
  }
}

/* --- Kolom tanggal dengan bacaan lengkap ---
   Isi <input type="date"> digambar peramban menurut format bawaan sistem dan
   tidak dapat diatur dari halaman. Kolom aslinya karena itu dibuat transparan,
   lalu ditumpangi lapisan teks buatan sendiri. Kolom aslinya tetap berada di
   atas secara tumpukan agar seluruh klik dan sentuhan sampai kepadanya. */
.date-control {
  position: relative;
}

.date-control input[type="date"] {
  position: relative;
  z-index: 1;
  /* Warna dibuat transparan, bukan opacity: 0 pada elemennya, supaya cincin
     fokus dan garis tepi tetap tergambar oleh peramban seperti kolom lain. */
  color: transparent;
  background: transparent;
}

/* Ikon kalender bawaan disembunyikan karena lapisan teks sudah membawa ikon
   sendiri yang mengikuti warna tema. */
.date-control input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0;
  cursor: pointer;
}

.date-control input[type="date"]::-webkit-datetime-edit,
.date-control input[type="date"]::-webkit-date-and-time-value {
  color: transparent;
}

/* Lapisan teks menempati kotak yang sama persis dengan kolom aslinya. Nilai
   padding dan tinggi minimumnya menyalin aturan input di atas; bila salah satu
   berubah, keduanya harus ikut berubah. */
.date-display {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid transparent;
  border-radius: 7px;
  pointer-events: none;
}

.date-display svg {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--muted);
}

.date-display-text {
  overflow: hidden;
  color: var(--ink);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Sebelum tanggal dipilih, teksnya berperan sebagai placeholder. */
.date-display-text.is-empty {
  color: var(--muted-soft);
}

.date-control input[type="date"]:disabled ~ .date-display .date-display-text,
.date-control input[type="date"]:disabled ~ .date-display svg {
  color: var(--muted);
  opacity: 0.65;
}

@media (max-width: 720px) {
  .auth-nav {
    margin-left: 0;
    padding-left: 0;
    border-left: none;
  }

  .auth-nav-name {
    max-width: 150px;
  }

  .auth-box {
    margin: 24px auto;
  }
}

/* --- Label sisa stok pada kolom jumlah logistik --- */

.resource-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
  min-height: 22px;
}

.resource-head label {
  margin: 0;
}

.stock-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border: 1px solid rgba(21, 128, 61, 0.28);
  border-radius: 999px;
  background: rgba(34, 197, 94, 0.12);
  color: var(--ink-success);
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

/* Batas tercapai: pemohon perlu tahu kenapa angkanya berhenti bertambah. */
.stock-badge.is-max {
  border-color: rgba(180, 83, 9, 0.32);
  background: rgba(245, 158, 11, 0.16);
  color: var(--ink-warning);
}

/* Stok kosong: kolomnya tetap ada, tetapi jelas tidak dapat diisi. */
.stock-badge.is-empty {
  border-color: rgba(100, 106, 118, 0.28);
  background: rgba(100, 106, 118, 0.1);
  color: var(--muted);
}

@media (max-width: 720px) {
  .resource-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .stock-badge {
    font-size: 11px;
    padding: 2px 8px;
  }
}

/* --- Halaman pengajuan milik akun peminjam --- */

.auth-nav-link {
  padding: 7px 10px;
  border-radius: 7px;
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 600;
  white-space: nowrap;
}

.auth-nav-link:hover {
  color: var(--red-dark);
  background: rgba(184, 31, 50, 0.08);
}

.my-request-list {
  display: grid;
  gap: 14px;
}

.my-request-card {
  padding: 18px 20px;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
}

.my-request-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line-softer);
}

.my-request-head .ticket {
  display: block;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--red-dark);
}

.my-request-date {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 12px;
}

.my-request-detail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 20px;
  margin: 14px 0 0;
}

.my-request-detail dt {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

.my-request-detail dd {
  margin: 2px 0 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-label);
}

/* Tiga momen peminjaman berdiri sebagai barisnya sendiri, dipisahkan garis
   tipis dari rincian kegiatan, supaya urutan waktunya terbaca sekali lihat. */
.my-request-moments {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--line-softer);
}

/* Tanggal yang belum terjadi ditulis berbeda dari yang sudah, supaya rencana
   tidak pernah terbaca sebagai kejadian. */
.moment-plan {
  font-weight: 500;
  color: var(--muted);
}

/* Rincian dilipat supaya satu kartu tidak menghabiskan seluruh layar ponsel.
   Yang tetap terlihat hanyalah yang dibutuhkan sekali lihat: nomor tiket,
   keadaannya, dan tombol membuka kartu. */
.my-request-more {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-softer);
}

/*
 * Berupa baris yang jelas dapat ditekan, bukan tulisan abu-abu bertanda panah
 * kecil. Sebagai teks polos di tengah kartu, ia terbaca sebagai keterangan --
 * dan rincian yang ada di baliknya tidak pernah dibuka orang karena tidak ada
 * yang memberi tahu bahwa ia dapat dibuka.
 */
.my-request-more > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 9px 12px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--surface-sunken);
  border: 1px solid var(--line-soft);
  border-radius: 7px;
}

.my-request-more > summary:hover {
  color: var(--ink);
  background: var(--surface-hover);
  border-color: var(--line);
}

/* Ketika terbentang, barisnya diberi jarak dari isi yang baru muncul supaya
   keduanya tidak terbaca sebagai satu blok. */
.my-request-more[open] > summary {
  margin-bottom: 4px;
}

.my-request-more > summary::-webkit-details-marker {
  display: none;
}

.my-request-more > summary::after {
  content: "\25BE";
  font-size: 11px;
  transition: transform 0.15s ease;
}

.my-request-more[open] > summary::after {
  transform: rotate(180deg);
}

.my-request-more > summary:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 4px;
}

.my-request-more .my-request-detail {
  margin-top: 12px;
}

.my-request-note {
  margin: 14px 0 0;
  padding: 10px 12px;
  background: rgba(245, 158, 11, 0.1);
  border-radius: 7px;
  font-size: 13px;
  line-height: 1.5;
}

.my-request-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line-softer);
}

/* Kartu tidak langsung terpampang; yang tampil hanya ajakan membukanya. */
.digital-card-teaser {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
  padding: 14px 16px;
  background: var(--tint-neutral);
  border: 1px solid var(--line-softer);
  border-radius: 12px;
}

.digital-card-teaser strong {
  display: block;
  font-size: 14px;
}

.digital-card-teaser span {
  display: block;
  max-width: 46ch;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* Dua tombol berdampingan, tidak menumpuk. Aturan umum .button { width: 100% }
   untuk ponsel harus dikembalikan di sini, kalau tidak masing-masing tombol
   memakan satu baris penuh dan kartunya kembali memanjang. */
.digital-card-actions {
  display: flex;
  flex-wrap: nowrap;
  /* Tumbuh mengisi sisa baris, dan mengambil satu baris penuh begitu ajakan di
     sebelahnya terdorong turun -- sehingga kedua tombol selalu terentang dari
     tepi kiri sampai tepi kanan, bukan menggerombol di kiri. */
  flex: 1 1 260px;
  gap: 8px;
}

.digital-card-actions .button {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  white-space: nowrap;
}

/* Popup kartu. Latarnya putih tetap, tidak mengikuti tema gelap, karena
   pemindai membaca modul gelap di atas terang. */
.card-modal {
  position: fixed;
  inset: 0;
  /* Sejajar dengan popup lain (80), karenanya di atas bilah navigasi bawah
     (70). Dengan angka di bawah bilah, ikon-ikon bilah tetap tergambar di atas
     latar gelap popup. */
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(12, 15, 20, 0.6);
}

.card-modal-panel {
  width: min(420px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  background: #ffffff;
  color: #181c23;
}

.card-modal-body {
  display: grid;
  justify-items: center;
  gap: 14px;
  padding: 20px 20px 24px;
  text-align: center;
}

.card-modal-qr {
  width: min(300px, 76vw);
  height: auto;
  aspect-ratio: 1;
  image-rendering: pixelated;
}

.card-modal-hint {
  margin: 0;
  max-width: 40ch;
  font-size: 13px;
  line-height: 1.5;
  color: #4f5968;
}

.card-modal-detail {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  width: 100%;
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid #e5e8ee;
}

.card-modal-detail dt {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #626b78;
}

.card-modal-detail dd {
  margin: 2px 0 0;
  font-size: 14px;
  font-weight: 600;
}


@media (max-width: 720px) {
  .my-request-card {
    padding: 16px;
  }

  .my-request-actions .button {
    width: 100%;
  }
}

/* --- Pengelolaan petugas --- */

.admin-user-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.admin-user-actions .button {
  padding: 7px 12px;
  font-size: 12.5px;
}

.admin-self-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: 6px;
  background: rgba(184, 31, 50, 0.1);
  color: var(--red-dark);
  font-size: 11px;
  font-weight: 700;
}

tr.is-disabled td {
  opacity: 0.6;
}

/* Nama petugas pada riwayat pengajuan. */
#admin-user-form {
  margin-top: 18px;
}

/* Borang pengaturan: satu isian per baris. Isinya alamat panjang yang lebih
   mudah diperiksa bila tidak dipepet berdampingan. */
.admin-settings-form {
  display: grid;
  gap: 14px;
  padding: 14px;
}

.admin-settings-form .form-actions {
  margin-top: 4px;
}

/* Penanda petugas yang belum mengganti kata sandi sementaranya. */
.admin-pending-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 6px;
  background: rgba(245, 158, 11, 0.16);
  color: var(--ink-warning);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

/* Alamat email petugas, ditampilkan di bawah nama penggunanya. */
.admin-email {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 12px;
  word-break: break-all;
}

/* Penanda wewenang petugas. */
.role-pill {
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid rgba(100, 106, 118, 0.28);
  border-radius: 6px;
  background: rgba(100, 106, 118, 0.08);
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}

.role-pill.is-manager {
  border-color: rgba(31, 96, 152, 0.32);
  background: rgba(31, 96, 152, 0.12);
  color: var(--blue);
}

/* Baris keterangan hasil filter pengajuan, tanpa tombol terapkan. */
.admin-filter-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-softer);
}

/*
 * Tombol reset filter: ringkas, dan berlatar sendiri.
 *
 * Kelabu batu -- bukan putih, bukan maroon. Berdampingan dengan Ekspor yang
 * maroon, keduanya langsung terbaca sebagai dua hal berbeda; dan karena
 * latarnya berisi, ia tidak pernah tampak seperti tombol yang sedang mati.
 *
 * Warnanya dipatok, tidak mengambil token netral yang ada: hampir semua
 * token netral membalik terang-gelap mengikuti tema, sedangkan tombol ini
 * perlu tetap gelap di kedua tema agar tulisan putihnya selalu terbaca.
 */
.filter-reset {
  padding: 8px 16px;
  color: #ffffff;
  background: #4f5968;
  border-color: transparent;
  font-size: 13px;
}

.filter-reset:hover {
  color: #ffffff;
  background: #3f4855;
}

/* Tombol pada baris aksi filter laporan. */
.report-filter-buttons {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/*
 * Di ponsel keduanya bertumpuk, masing-masing selebar penuh.
 *
 * Lebarnya sama dengan isian tanggal di atasnya, sehingga seluruh baris
 * penyaring terbaca sebagai satu kolom yang rapi -- bukan dua tombol pendek
 * yang mengambang di tepi berlawanan. Yang membedakan keduanya warnanya,
 * bukan letaknya: Ekspor maroon sebagai tindakan utama, Reset netral sebagai
 * jalan kembali.
 */
@media (max-width: 620px) {
  .report-filter-buttons {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
}

/* ============================================================
   Ajakan memasang SIPIKO di layar utama
   ============================================================
   z-index 72 menempatkannya tepat di atas bilah navigasi bawah (70) namun
   tetap di bawah lapisan modal (80). */

.install-banner {
  position: fixed;
  right: 14px;
  bottom: 18px;
  left: 14px;
  z-index: 72;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 480px;
  margin: 0 auto;
  /* Ruang kanan disediakan untuk tombol tutup yang dipasang mutlak di sudut. */
  padding: 12px 42px 12px 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
}

.install-banner[hidden] {
  display: none;
}

.install-banner-icon {
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: 9px;
  border: 1px solid var(--line);
  object-fit: contain;
}

.install-banner-text {
  display: grid;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

/* Nama instansi atau petunjuk panjang tidak boleh melebarkan banner. */
.install-banner-text strong,
.install-banner-text small {
  overflow-wrap: anywhere;
}

.install-banner-text small {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.35;
}

.install-banner .button {
  flex: none;
  padding: 9px 16px;
  font-size: 13px;
}

.install-banner .button[hidden] {
  display: none;
}

.install-banner-close {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 26px;
  height: 26px;
  padding: 0;
  color: var(--muted);
  background: none;
  border: 0;
  border-radius: 6px;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
}

.install-banner-close:hover {
  color: var(--ink);
  background: var(--soft);
}

/* Selama ajakan pasang terlihat, notifikasi naik ke atasnya. Tingginya diukur
   di app.js dan disiarkan lewat --install-banner-h, karena banner berganti
   tinggi mengikuti lebar layar dan panjang petunjuk. Peramban tanpa dukungan
   :has() hanya melewati aturan ini; keduanya tetap terbaca karena toast berada
   di lapisan yang lebih tinggi. */
body:has(#install-banner:not([hidden])) .toast {
  bottom: calc(var(--install-banner-h, 0px) + 28px);
}

@media (max-width: 620px) {
  /* Digeser ke atas bilah navigasi bawah agar keduanya tidak bertumpuk. */
  .install-banner {
    bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px) + 10px);
    flex-wrap: wrap;
    align-items: flex-start;
    padding-right: 14px;
  }

  .install-banner-text {
    padding-right: 28px;
  }

  /* Di layar sempit, ikon, teks, dan tombol tutup sudah menghabiskan satu
     baris penuh. Tombol Pasang diturunkan ke baris sendiri lewat urutan flex,
     bukan lewat kisi, supaya baris itu ikut hilang tanpa menyisakan jarak
     kosong ketika tombol disembunyikan pada perangkat iOS. */
  .install-banner .button {
    order: 4;
    flex: 1 0 100%;
    min-height: 42px;
  }

  .install-banner-icon {
    width: 38px;
    height: 38px;
  }

  body:has(#install-banner:not([hidden])) .toast {
    bottom: calc(
      var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px)
      + var(--install-banner-h, 0px) + 22px
    );
  }
}

/* ============================================================
   Lonceng pengajuan baru (dashboard admin)
   ============================================================ */

/* Tab perlu menjadi kotak lentur agar lencana duduk sebaris dengan labelnya. */
.tab-button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.tab-badge {
  display: inline-grid;
  place-items: center;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  color: var(--on-accent);
  background: var(--red);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.tab-badge[hidden] {
  display: none;
}

/* Lencana keterlambatan dibedakan bentuknya, bukan hanya warnanya, karena
   keduanya berdiri bersebelahan dan sebagian petugas sulit membedakan merah
   dari merah tua. Garis tepi terang membuatnya terbaca sebagai lencana kedua,
   bukan sebagai angka lanjutan dari lencana di sebelahnya. */
.tab-badge-overdue {
  margin-left: 4px;
  color: var(--danger);
  background: var(--paper);
  box-shadow: inset 0 0 0 1.5px currentColor;
}

/* Notifikasi yang sedang dimatikan sendiri dibuat lebih redup. Aturannya
   menyasar penandanya, bukan kelas rupanya, supaya tetap berlaku ke mana pun
   sakelarnya kelak dipindahkan. */
[data-notify-enable][data-push-on="0"] {
  opacity: 0.6;
}

/* Cek status kini hanya meminta nomor tiket, jadi isiannya memakai satu
   lajur penuh alih-alih setengah kisi dua kolom. */
#status-form .form-grid {
  grid-template-columns: 1fr;
}

/* Panel akun pada halaman "Pengajuan saya". Di layar lebar kendali yang sama
   sudah tersedia di header, jadi panel ini disembunyikan. */
.account-bar {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
  padding: 12px 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.account-bar-identity {
  display: grid;
  gap: 1px;
  min-width: 0;
}


.account-bar-label {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.account-bar-identity strong,
.account-bar-identity small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-bar-identity small {
  color: var(--muted);
  font-size: 12px;
}

/* Bilah admin hanya berisi identitas, tanpa tombol, sehingga teksnya boleh
   memakai seluruh lebar dan membungkus alih-alih dipotong. */
.account-bar-admin {
  margin-top: 4px;
}

.account-bar-admin .account-bar-identity strong,
.account-bar-admin .account-bar-identity small {
  white-space: normal;
  overflow: visible;
  overflow-wrap: anywhere;
}

/* Pada ponsel ada aturan umum .button { width: 100% }. Tombol Keluar di sini
   berdiri berdampingan dengan identitas akun, jadi lebarnya harus dikembalikan
   ke ukuran isinya -- tanpa ini tombolnya memakan seluruh baris dan menghimpit
   nama organisasi sampai selebar nol. */
.account-bar .button {
  flex: none;
  width: auto;
  padding: 8px 16px;
  font-size: 13px;
}

/* ============================================================
   Bilah navigasi bawah (khusus ponsel)
   ============================================================
   Satu markup dipakai bersama nav atas; di layar lebar bilah ini
   disembunyikan sepenuhnya. z-index 70 sengaja di bawah
   .request-modal (80) supaya bilah tidak menembus lapisan modal. */

/* Bilah TIDAK melayang. Ia berdiri di luar .app-shell sebagai baris terakhir
   badan halaman -- sejajar dengan kotak yang bergulir, bukan menumpang di
   atasnya. Alasannya ditulis lengkap pada blok tata letak ponsel di bawah.

   position: relative hanya menyalakan z-index; ia tidak menggeser bilah ke mana
   pun. z-index 70 menjaga bilah tetap di atas unsur melayang berlapis rendah
   seperti tombol pindai mengambang (55), namun sengaja di bawah lapisan popup
   (80) supaya bilah tidak menembus popup yang sedang terbuka. */
.bottom-nav {
  position: relative;
  z-index: 70;
  display: none;
  /* Kolom dibuat mengalir, bukan dipatok empat, karena bilah dashboard berisi
     lima tautan dan yang kelima disembunyikan bagi petugas biasa. Dengan kolom
     tetap, tautan tersembunyi itu menyisakan satu kolom kosong. */
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  height: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--paper);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 18px rgba(20, 28, 38, 0.08);
}

@media (max-width: 620px) {
  .bottom-nav {
    display: grid;
    /* Sebagai anak flex badan halaman, bilah tidak boleh ikut menyusut ketika
       isi halaman panjang. */
    flex: 0 0 auto;
  }

  .bottom-nav a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    color: var(--muted);
    font-size: clamp(10px, 3vw, 11.5px);
    font-weight: 500;
    line-height: 1.1;
  }

  .bottom-nav svg {
    width: 22px;
    height: 22px;
    flex: none;
  }

  /* Tombol pindai berdiri di tengah bilah sebagai lingkaran yang menyembul ke
     atas. Bentuknya sengaja berbeda dari tetangganya karena perannya memang
     berbeda: yang lain memindahkan halaman, yang ini mengerjakan sesuatu.
     Menonjol begitu juga membuatnya paling mudah dijangkau ibu jari, dan itu
     tombol yang paling sering ditekan sepanjang hari di loket. */
  .bottom-nav-scan {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 3px;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--red);
    font-family: inherit;
    font-size: clamp(10px, 3vw, 11.5px);
    font-weight: 700;
    line-height: 1.1;
    cursor: pointer;
  }

  .bottom-nav-scan svg {
    box-sizing: content-box;
    width: 24px;
    height: 24px;
    margin-top: -24px;
    padding: 12px;
    color: #ffffff;
    background: var(--red);
    border: 4px solid var(--paper);
    border-radius: 999px;
    box-shadow: 0 6px 16px rgba(184, 31, 50, 0.36);
  }

  .bottom-nav-scan:active svg {
    background: var(--red-dark);
  }

.bottom-nav a.active {
    color: var(--red);
  }

  .bottom-nav a.active svg {
    stroke-width: 2.1;
  }

  /* Papan ketik ponsel menutupi sebagian layar; bilah disembunyikan
     selama pengguna mengisi isian agar tidak menimpa tombol kirim. */
  body.is-typing .bottom-nav {
    display: none;
  }

  /* ---------- halaman diam, kotak isinya yang bergulir ----------

     Sebelumnya bilah bawah melayang (position: fixed) dan seluruh halaman
     bergulir di belakangnya. Susunan itu menuntut peramban menggambar ulang
     bilah pada setiap bingkai gulir, dan di tengah gulir cepat ia tertinggal --
     tulisan halaman sekilas terlihat menembus bilah. Menambal lapisannya tidak
     menolong: peta membuatnya lebih parah lagi, karena Leaflet menaruh ubinnya
     pada lapisan yang jauh lebih tinggi daripada angka apa pun yang masuk akal
     dipasang pada bilah, sehingga peta menutupi deretan ikon begitu halaman
     digulir.

     Sekarang badan halaman dikunci setinggi layar dan tidak bergulir sama
     sekali. Yang bergulir hanya .app-shell, dan bilah duduk di bawahnya sebagai
     saudara, bukan sebagai lapisan di atasnya. Tidak ada lagi isi halaman yang
     pernah lewat di belakang bilah -- cacatnya hilang karena keadaannya tidak
     mungkin lagi terjadi, bukan karena ditambal. overflow pada .app-shell
     sekaligus memangkas peta: ia tidak dapat lagi tergambar di luar kotak isi.

     Susunan ini menyalin halaman panduan, tempat cacat yang sama sudah
     diselesaikan dengan cara yang sama. */
  html,
  body {
    /* Satuan dinamis, bukan 100% atau 100vh. Karena halaman tidak lagi
       bergulir, bilah alamat ponsel tidak pernah menyusut sendiri: layar yang
       benar-benar terlihat adalah yang paling pendek, dan hanya dvh yang
       mengikutinya. Dengan vh, bilah navigasi bawah terdorong ke luar layar
       setinggi bilah alamat. Baris 100% dipertahankan untuk peramban lama yang
       belum mengenal dvh. */
    height: 100%;
    height: 100dvh;
  }

  body {
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  .app-shell {
    /* min-height: 100dvh dari aturan pokok wajib dilepas. Sebagai anak flex
       yang tingginya sudah ditentukan sisa ruang, batas itu justru memaksa
       kerangka lebih tinggi daripada layar -- dan gulirnya balik lagi ke
       halaman, persis yang sedang dihindari. */
    min-height: 0;
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Bilah dashboard menonjolkan tombol Pindai sebagai lingkaran yang menyembul
     ke atas bilah. Tanpa ruang tambahan, baris terakhir halaman berhenti tepat
     di bawah lingkaran itu dan mengintip di kiri-kanannya. */
  body:has(.bottom-nav-admin:not([hidden])) .app-shell {
    padding-bottom: 30px;
  }

  /* Popup mengunci kotak isi, bukan badan halaman. Cara layar lebar -- memaku
     body dengan position: fixed lalu menggesernya ke atas sejauh posisi gulir
     -- akan mencabut body dari susunan flex ini dan menggeser bilah keluar
     layar. Di sini cukup mematikan guliran kotak isinya; posisi gulirnya
     tersimpan sendiri di kotak itu dan kembali utuh saat popup ditutup. */
  html.modal-terbuka body {
    position: static;
  }

  html.modal-terbuka .app-shell {
    overflow: hidden;
  }

  /* Notifikasi digeser ke atas bilah. */
  .toast {
    right: 12px;
    left: 12px;
    bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px) + 12px);
    max-width: none;
  }

  /* Seluruh navigasi publik pindah ke bilah bawah, termasuk kendali akun:
     masuk dan keluar dijangkau lewat tab Akun. Header di ponsel menyisakan
     logo saja. Area admin dikecualikan karena tidak punya bilah bawah dan
     tombol keluar petugas hanya tersedia di header. */
  .site-header {
    flex-direction: row;
    align-items: center;
    gap: 12px;
  }

  .main-nav {
    display: none;
  }


  /* Identitas akun dan tombol keluar hanya perlu tampil di ponsel. */
  .account-bar {
    display: flex;
  }

  /* Nama petugas dan tombol Keluar keduanya diserahkan ke .account-bar-admin
     yang punya lebar penuh. Header ponsel terlalu sempit untuk memuat
     keduanya berdampingan dengan ikon-ikon di sebelah kiri. */
  .auth-nav-name {
    display: none;
  }
}

/* ============================================================
   Tombol pengalih tema
   ============================================================ */

.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  margin-left: auto;
  padding: 0;
  color: var(--muted);
  background: none;
  border: 1px solid var(--line);
  border-radius: 9px;
  cursor: pointer;
  transition: color 160ms ease, border-color 160ms ease, background 160ms ease;
}

.theme-toggle:hover {
  color: var(--red-dark);
  border-color: var(--red);
  background: rgba(184, 31, 50, 0.08);
}

.theme-toggle .theme-icon {
  width: 19px;
  height: 19px;
  grid-area: 1 / 1;
}

/* Lonceng memakai bentuk serta ukuran yang sama dengan pengalih tema di
   sebelahnya, hanya tanpa margin otomatis -- yang mendorong keduanya ke kanan
   cukup dikerjakan oleh pengalih tema. */

.notify-bell[hidden] {
  display: none;
}

.notify-bell {
  margin-left: 8px;
}

.theme-toggle .head-icon {
  width: 19px;
  height: 19px;
  grid-area: 1 / 1;
}

/* Lonceng utuh saat menyala, lonceng tercoret saat mati. Keadaannya dibedakan
   bentuk, bukan warna saja, agar tetap terbaca oleh yang sulit membedakan
   warna maupun pada layar yang silau. */
.notify-bell .bell-icon-off {
  display: none;
}

.notify-bell[data-push-on="0"] .bell-icon-off {
  display: block;
}

.notify-bell[data-push-on="0"] .bell-icon-on {
  display: none;
}

.notify-bell[data-notify-state="granted"][data-push-on="1"] {
  color: var(--green);
  border-color: rgba(23, 122, 83, 0.35);
}

/* Ikon menunjukkan tema tujuan, bukan tema yang sedang berlaku: saat terang
   tampil bulan (ketuk untuk menggelapkan), saat gelap tampil matahari. */
.theme-toggle .theme-icon-sun {
  display: none;
}

.theme-toggle[data-effective="dark"] .theme-icon-sun {
  display: block;
}

.theme-toggle[data-effective="dark"] .theme-icon-moon {
  display: none;
}

/* Header memakai margin-left auto pada nav; dengan tombol tema di antaranya,
   pendorongnya dipindah ke tombol supaya keduanya tetap merapat ke kanan. */
.site-header .main-nav {
  margin-left: 0;
}

/* ============================================================
   Penyesuaian khusus tema gelap
   ============================================================
   Sebagian besar tampilan sudah ikut berubah lewat token. Yang tersisa di
   sini adalah bagian yang menyandarkan diri pada warna terang secara tersirat. */


/* Maskot dan logo berupa gambar bergaris hitam tanpa latar. Di tema gelap
   garis hitamnya lenyap, jadi diberi bayangan tipis agar bentuknya kembali
   terbaca tanpa harus menyediakan berkas gambar versi kedua. */
:root[data-theme="dark"] .hero-visual img,
:root[data-theme="dark"] .brand-mark img {
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.55))
    drop-shadow(0 18px 18px rgba(0, 0, 0, 0.45));
}

/* Pratinjau surat dan halaman PDF tetap berkertas putih, jadi teks di dalam
   bingkainya tidak boleh mewarisi warna terang milik tema gelap. */
:root[data-theme="dark"] .attachment-preview-frame,
:root[data-theme="dark"] .attachment-preview-image,
:root[data-theme="dark"] .pdf-preview-page {
  color: #20242c;
}

/* Hasil pencarian yang tidak ketemu. Warnanya dulu ditulis langsung pada
   atribut style di app.js, sehingga tidak ikut berubah saat tema gelap. */
.result-box.is-not-found {
  color: var(--ink);
  background: var(--tint-red);
  border-color: rgba(179, 38, 30, 0.26);
}


/* Ajakan pasang yang sudah berubah menjadi konfirmasi terpasang. */
.install-banner.is-installed {
  border-color: rgba(23, 122, 83, 0.4);
}

.install-banner.is-installed .install-banner-text strong {
  color: var(--ink-success);
}


/* ============================================================
   Bilah bawah dashboard
   ============================================================ */

/* Kedua bilah bawah disembunyikan lewat atribut hidden. Aturan ini diperlukan
   karena display: grid pada .bottom-nav menimpa gaya bawaan peramban untuk
   [hidden], sehingga tanpa ini bilah yang tidak berlaku tetap tampil. */
.bottom-nav[hidden],
.bottom-nav a[hidden] {
  display: none;
}

/* Lencana jumlah pengajuan baru, menempel di pojok ikon. */
.bottom-nav a {
  position: relative;
}

.bottom-nav-badge {
  position: absolute;
  top: 4px;
  left: 50%;
  min-width: 17px;
  height: 17px;
  margin-left: 4px;
  padding: 0 4px;
  color: var(--on-accent);
  background: var(--red);
  border: 2px solid var(--paper);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  line-height: 13px;
  text-align: center;
}

.bottom-nav-badge[hidden] {
  display: none;
}

@media (max-width: 620px) {
  /* Tab dashboard pindah ke bilah bawah. Tombol izin notifikasi tetap tinggal
     di barisnya, karena tidak punya tempat di bilah bawah dan tetap perlu
     dijangkau petugas dari ponsel. */
  .admin-tabs .tab-button {
    display: none;
  }

  .admin-tabs {
    margin: 12px 0 6px;
  }

}


/* Tautan peta memakai rupa tombol kecil yang sama dengan tombol lain di
   rincian. Ia sebuah tautan, bukan tombol, karena memang berpindah ke
   alamat lain -- menekan tahan untuk menyalin atau membuka di tab baru
   tetap bekerja seperti yang orang harapkan dari tautan. */
.map-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: fit-content;
  text-decoration: none;
}

.map-link span {
  font-size: 12px;
  line-height: 1;
}

/* Koordinat di detail pengajuan: angkanya perlu terbaca dan mudah disalin,
   tetapi tidak boleh menyaingi tautan petanya yang lebih sering dipakai. */
.detail-coordinate {
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Masuk lewat Google.
   Tombolnya sengaja tidak memakai lambang resmi Google yang dimuat dari server
   mereka: Content-Security-Policy SIPIKO hanya mengizinkan gambar dari sumber
   sendiri, dan menambahkan pengecualian demi satu ikon tidak sepadan. Huruf G
   berwarna sudah cukup dikenali, dan tidak menambah satu pun permintaan ke luar. */
.auth-alternative {
  margin-top: 18px;
}

.auth-divider {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  color: var(--muted);
  font-size: 12px;
}

.auth-divider::before,
.auth-divider::after {
  content: "";
  height: 1px;
  background: var(--line-soft);
}

.google-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
}

.google-mark {
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
  /* Empat warna Google diringkas menjadi gradasi pada hurufnya sendiri. */
  background: linear-gradient(90deg, #4285f4 0%, #ea4335 35%, #fbbc05 70%, #34a853 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.auth-notice {
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid rgba(23, 122, 83, 0.26);
  border-radius: 8px;
  background: var(--tint-green);
  font-size: 13px;
  line-height: 1.45;
}

/* Tautan yang berdampingan dengan tombol utamanya, dipakai "Lupa kata sandi?"
   di sebelah tombol Masuk. Didorong ke ujung kanan agar ruang kosong di baris
   tombol terpakai, dan yang mencarinya menemukannya persis di tempat ia
   menyadari sandinya terlupa -- bukan setelah menggulung melewati dua garis
   pemisah di bawahnya. Pada layar sempit ia turun sendiri karena barisnya
   memang sudah membungkus. */
.form-actions-link {
  margin-left: auto;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--red-dark);
  text-decoration: none;
}

.form-actions-link:hover,
.form-actions-link:focus-visible {
  text-decoration: underline;
}
