/* Sakelas Medika v2 — design system, tampilan "Kaca Ringan" (padat, tanpa blur). Sumber keputusan: DESIGN.md. */

/* Huruf di-host sendiri. font-display: optional: huruf yang belum siap saat halaman pertama digambar tidak ditukar di
   tengah tampilan, jadi huruf tidak berkedip/"ter-refresh" saat pindah menu. Berkas latin di-preload setiap layout
   (resources/views/partials/preload-huruf.blade.php) dan di-cache lama (public/.htaccess), jadi praktis selalu siap.
   Public Sans hanya bobot 400, 500, 700 (jangan memakai 600: browser akan memakai 700). */
@font-face { font-family: "Public Sans"; font-weight: 400; font-display: optional; src: url("../fonts/public-sans-latin-400-normal.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Public Sans"; font-weight: 400; font-display: optional; src: url("../fonts/public-sans-latin-ext-400-normal.woff2") format("woff2"); unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Public Sans"; font-weight: 500; font-display: optional; src: url("../fonts/public-sans-latin-500-normal.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Public Sans"; font-weight: 500; font-display: optional; src: url("../fonts/public-sans-latin-ext-500-normal.woff2") format("woff2"); unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Public Sans"; font-weight: 700; font-display: optional; src: url("../fonts/public-sans-latin-700-normal.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Public Sans"; font-weight: 700; font-display: optional; src: url("../fonts/public-sans-latin-ext-700-normal.woff2") format("woff2"); unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-display: optional; src: url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2"); unicode-range: U+0000-00FF; }
@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-display: optional; src: url("../fonts/ibm-plex-mono-latin-ext-400-normal.woff2") format("woff2"); unicode-range: U+0100-02AF; }

:root {
  /* Warna (DESIGN.md §3.1, kontras sudah dihitung) */
  --bg: #EEF2F8;              /* latar halaman abu kebiruan; kartu & panel putih padat di atasnya */
  --surface: #FFFFFF;
  --ink: #101828;
  --ink-2: #475467;           /* 6,6:1 di --bg */
  --muted: #5D6B7E;           /* 4,8:1 di --bg, 5,4:1 di putih */
  --border: #E1E6ED;          /* garis rambut dekoratif (kartu, panel); bukan batas kontrol */
  --border-strong: #65748A;   /* batas komponen (isian, tombol sekunder): 4,7:1 di putih, 4,1:1 di --bg */
  --samar: #65748A;           /* teks paling redup, HANYA di atas putih (nomor versi menu samping): 4,7:1 di putih */
  --border-hover: #4D5D74;
  --line: #E8ECF2;            /* garis rambut antar-baris daftar & tabel */
  --line-strong: #CBD4DF;     /* garis bawah kepala tabel/daftar, pemisah judul */
  --row-hover: #F4F7FC;       /* sorot baris & hover menu */
  --primary: #175CD3;         /* aksen produk: putih di atasnya 6,0:1. Klinik boleh menimpa --primary & --primary-hover. */
  --primary-hover: #1849A9;
  --on-primary: #FFFFFF;
  /* Turunan aksen. Nilai di sini cadangan untuk browser lama; di browser yang mendukung color-mix() dihitung dari
     --primary (lihat @supports di bawah), jadi ikut berubah bila klinik mengganti warna aksen. */
  --primary-soft: #EDF3FF;    /* latar pucat menu aktif */
  --primary-ink: var(--primary-hover);  /* teks aksen di atas --primary-soft (tetap >= 4,5:1 untuk warna klinik apa pun) */
  --focus-ring: rgba(23, 92, 211, .2);
  --link-line: currentColor;  /* garis bawah tautan */
  /* Kepala daftar, tabel, panel, dan legend form: pita warna klinik 16% + teks warna klinik 80% bercampur hitam, jadi
     kepala selalu beda warna dari isinya (teks >= 4,9:1 di pita untuk warna klinik apa pun yang lolos §3.2). Nilai di
     sini cadangan untuk browser tanpa color-mix(); --kepala-redup untuk teks kecil abu di pita. */
  --kepala-bg: #DCE7FA;
  --kepala-teks: var(--primary-hover);
  --kepala-redup: var(--ink-2);
  --kepala-garis: #9DB9EA;

  --danger: #B42318;  --danger-bg: #FEF0EE;  --danger-line: #F0B4AD;
  --warning: #8A4B00; --warning-bg: #FFF4E0; --warning-line: #E9C48C;
  --success: #1A6B3C; --success-bg: #E7F5EC; --success-line: #A9D3B9;
  --info: #4B3FB0;    --info-bg: #EFEDFB;    --info-line: #C4BEEC;   /* nila, agar tidak tertukar dengan biru aksen */

  /* Tipografi (§4) */
  --font: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --text-xs: 0.8125rem;
  --text-sm: 0.875rem;
  --text-md: 1rem;
  --text-lg: 1.125rem;
  --text-title: clamp(1.375rem, 1.1rem + 1vw, 1.75rem);
  --leading: 1.5;

  /* Jarak (§5): skala padat, sama di semua lebar */
  --s1: 4px; --s2: 6px; --s3: 10px; --s4: 12px; --s5: 16px; --s6: 20px; --s7: 32px;
  --page-pad: 12px;
  --gap-tap: 8px;             /* jarak antar target sentuh (tombol berderet) */

  --radius: 8px;              /* isian, tombol, kartu kecil */
  --radius-panel: 12px;       /* panel, daftar, tabel, strip angka */
  /* Kartu & panel "kaca padat": garis rambut + satu bayangan lembut, tanpa transparansi dan tanpa blur. */
  --bayang-panel: 0 0 0 1px rgba(16, 24, 40, .05), 0 8px 24px -12px rgba(16, 24, 40, .18);
  --tap: 44px;
  --sidebar-w: 240px;
  --rail-w: 100px;          /* label rail terpanjang "Laboratorium" (±82px di 13px) utuh satu baris */
  --bottom-nav-h: 56px;
  /* Tinggi bagian atas layar yang tertutup kerangka yang menempel (topbar di >= 640px, lihat "Kerangka aplikasi"):
     elemen lengket lain (kepala pasien, panel samping pemeriksaan) dan tujuan gulir (#id, fokus) dimulai di bawahnya. */
  --lengket-atas: 0px;

  /* Kepadatan (§5): diperkecil di mode padat desktop di bawah. */
  --topbar-h: 48px;
  --row-y: 6px;               /* padding atas/bawah baris daftar & kepala daftar */
  --cell-y: 6px;              /* padding atas/bawah sel tabel */
  --input-y: var(--s2);
  --input-x: var(--s3);
  --textarea-h: 72px;
  --field-gap: var(--s3);     /* jarak antar isian form */
  --panel-pad-y: var(--s4);
  --panel-pad-x: var(--s4);
  --panel-pad: var(--panel-pad-y) var(--panel-pad-x);
  --btn-kecil-h: var(--tap);  /* tombol kecil tetap >= 44px di layar sentuh */
  --btn-kecil-x: var(--s3);
  --stat-y: 8px;
  --alert-y: 8px;
  --empty-y: var(--s3);
  --nav-icon: 18px;

  /* Lebar kolom status (lihat "Kolom status dan aksi" di bawah): cukup untuk chip ±15 huruf ("Belum diperiksa").
     Lebar chip = teks (≈ 0,5 × --text-xs per huruf) + 14px padding & garis, jadi ditulis "N × --text-xs + 16px":
     ikut ukuran huruf chip (menyempit di mode padat) dan masih menyisakan ±6px. */
  --kolom-status: calc(var(--text-xs) * 8 + 16px);
}

@supports (color: color-mix(in srgb, red 50%, blue)) {
  :root {
    --primary-soft: color-mix(in srgb, var(--primary) 8%, #fff);
    --primary-ink: color-mix(in srgb, var(--primary) 88%, #000);
    --focus-ring: color-mix(in srgb, var(--primary) 20%, transparent);
    --link-line: color-mix(in srgb, var(--primary) 40%, transparent);
    --kepala-bg: color-mix(in srgb, var(--primary) 16%, #fff);
    --kepala-teks: color-mix(in srgb, var(--primary) 80%, #000);
    --kepala-garis: color-mix(in srgb, var(--primary) 45%, #fff);
  }
}

@media (min-width: 640px) { :root { --page-pad: 16px; --panel-pad-y: var(--s5); --panel-pad-x: var(--s5); } }
@media (max-width: 1023.98px) { :root { --text-title: 1.375rem; } }

/* Mode padat: hanya layar lebar dengan pointer halus (mouse). Huruf 13px, kontrol 32px, tombol kecil 26px, topbar 44px.
   Di layar sentuh (< 1024px atau pointer kasar) tombol, isian, menu, pilihan, dan tab tetap >= 44px. */
@media (min-width: 1024px) and (pointer: fine) {
  :root {
    --text-xs: 0.75rem;       /* 12px */
    --text-sm: 0.78125rem;    /* 12,5px */
    --text-md: 0.8125rem;     /* 13px */
    --text-lg: 0.9375rem;     /* 15px */
    --text-title: 1.25rem;    /* 20px */
    --leading: 1.45;
    --tap: 32px;
    --gap-tap: 6px;
    --sidebar-w: 200px;
    --page-pad: 20px;
    --topbar-h: 44px;
    --row-y: 5px;
    --cell-y: 4px;
    --input-y: 4px;
    --input-x: 8px;
    --textarea-h: 60px;
    --field-gap: 8px;
    --panel-pad-y: var(--s4);
    --panel-pad-x: var(--s5);
    --btn-kecil-h: 26px;
    --btn-kecil-x: 8px;
    --stat-y: 7px;
    --alert-y: 5px;
    --empty-y: 8px;
    --nav-icon: 16px;
  }
}

/* ---------- Dasar ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--text-md);
  line-height: var(--leading);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { line-height: 1.25; margin: 0; font-weight: 700; }
h1 { font-size: var(--text-title); letter-spacing: -0.015em; }
h2 { font-size: var(--text-lg); letter-spacing: -0.005em; }
h3 { font-size: var(--text-md); }
p { margin: 0; }
a { color: var(--primary); text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: var(--link-line); }
a:hover { color: var(--primary-hover); text-decoration-color: currentColor; }
/* Teks beraksen di isi halaman (tautan, remah, tab, pintasan saringan, tautan lipat) memakai --primary-ink: latar
   halaman (--bg) lebih gelap daripada putih, jadi warna klinik yang pas 4,5:1 di putih tetap terbaca. */
.main a:not(.btn), .main .btn--text, .tabs a[aria-current="page"], .toolbar__pintas .btn[aria-current="true"],
.disclosure > summary { color: var(--primary-ink); }
img { max-width: 100%; height: auto; }
/* IBM Plex Mono hanya dimuat bobot 400: kode di dalam judul/teks tebal tetap 400, tidak pernah tebal tiruan. */
.mono { font-family: var(--font-mono); font-size: 0.95em; font-weight: 400; }
.nowrap { white-space: nowrap; }
.muted { color: var(--muted); }
.small { font-size: var(--text-sm); }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

.skip-link {
  position: absolute; left: var(--s2); top: -100px; z-index: 100;
  background: var(--surface); color: var(--ink); padding: var(--s2) var(--s3);
  border: 2px solid var(--primary); border-radius: var(--radius);
}
.skip-link:focus { top: var(--s2); }

/* ---------- Pindah halaman ---------- */
/* Tanda pindah halaman (public/js/app.js, docs/UI-KIT.md "Pindah halaman"): bilah progres tipis tak tentu di atas layar
   dan isi diredupkan sedikit bila halaman berikutnya belum tiba setelah ±150 ms; menu tujuan langsung tampak aktif.
   Transisi antarhalaman (View Transitions) ada di public/css/transisi.css, hanya dimuat layout aplikasi. */
.muat-halaman {
  display: none; position: fixed; inset: 0 0 auto 0; z-index: 200; height: 3px; overflow: hidden; pointer-events: none;
  background: var(--primary-soft);
}
.muat-halaman[data-aktif] { display: block; }
.muat-halaman::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; background: var(--primary);
  animation: muat-halaman 1.1s ease-in-out infinite;
}
@keyframes muat-halaman { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
.main[aria-busy="true"] { opacity: 0.7; transition: opacity 120ms ease-out; }
.nav__link--dituju, .nav__link--dituju:hover { color: var(--primary-ink); background: var(--surface); box-shadow: var(--bayang-panel); }
/* Selama menu tujuan ditandai, menu halaman sekarang tidak lagi tampak aktif (hanya satu yang tampak dipilih). */
.nav__list:has(.nav__link--dituju) .nav__link[aria-current="page"]:not(.nav__link--dituju) {
  color: var(--ink-2); background: transparent; box-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  /* Tanpa gerakan: bilah penuh diam. */
  .muat-halaman::before { width: 100%; }
}
/* Menunggu layanan luar (tombol data-tunggu, public/js/app.js): teks status di bawah baris tombol selama kiriman berjalan. */
.tunggu-status { margin: var(--s2) 0 0; font-size: var(--text-sm); color: var(--ink-2); max-width: 60ch; }

/* ---------- Kerangka aplikasi ---------- */
.app { min-height: 100vh; min-height: 100dvh; }

.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: 0 var(--page-pad);
  background: var(--surface); border-bottom: 1px solid var(--border); box-shadow: 0 1px 0 rgba(16, 24, 40, .06);
  min-height: var(--topbar-h);
}
.topbar__clinic { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.topbar__clinic img { width: 32px; height: 32px; object-fit: contain; }
.topbar__name { font-weight: 700; font-size: var(--text-lg); letter-spacing: -0.01em; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar__user { display: none; align-items: center; gap: var(--s3); font-size: var(--text-sm); color: var(--ink-2); }

.nav { background: var(--surface); }
.nav__list { list-style: none; margin: 0; padding: 0; }
.nav__link {
  position: relative;
  display: flex; align-items: center; gap: var(--s3);
  min-height: var(--tap); padding: var(--s2) var(--s4);
  color: var(--ink-2); text-decoration: none; border-radius: var(--radius);
  font-weight: 500;
}
.nav__link:hover { background: var(--row-hover); color: var(--ink); }
.nav__link[aria-current="page"], .nav__link[aria-current="page"]:hover { color: var(--primary-ink); background: var(--surface); box-shadow: var(--bayang-panel); }
.nav__icon { width: 20px; height: 20px; flex: none; }
.nav__label { min-width: 0; overflow-wrap: anywhere; }
.nav__group { display: none; }
/* Jumlah pekerjaan menunggu (mis. resep, tagihan). Teks + warna, ada label untuk pembaca layar. */
.nav__badge {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--danger); color: #fff; font-size: 0.75rem; font-weight: 700; line-height: 20px; text-align: center;
}

.main { padding: var(--s4) var(--page-pad) var(--s7); max-width: 1280px; }

/* HP: navigasi bawah = 3 menu teratas + "Menu" (DESIGN.md §5, maks. 4 tujuan) */
@media (max-width: 639.98px) {
  .nav {
    position: fixed; inset: auto 0 0 0; z-index: 20;
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .nav__list { display: flex; }
  .nav__item { flex: 1 1 0; min-width: 0; }
  .nav__item--beyond-phone { display: none; }
  .nav__link {
    flex-direction: column; gap: 2px; justify-content: center;
    min-height: var(--bottom-nav-h); padding: var(--s1); border-radius: 0;
    font-size: var(--text-xs); text-align: center;
  }
  .nav__link[aria-current="page"], .nav__link[aria-current="page"]:hover,
  .nav__link--dituju, .nav__link--dituju:hover { background: transparent; box-shadow: inset 0 3px 0 var(--primary); }
  /* Label tidak dipenggal di tengah kata ("Pendafta/ran"): membungkus hanya di spasi ("Antrian / resep"). */
  .nav__label { overflow-wrap: normal; max-width: 100%; }
  .nav__badge { position: absolute; top: 4px; left: calc(50% + 6px); }
  .main { padding-bottom: calc(var(--bottom-nav-h) + var(--s6) + env(safe-area-inset-bottom)); }
}
/* HP sempit (< 360px, mis. 320px): setiap menu ±80px; huruf 12px dan padding 2px agar kata terpanjang di nav bawah
   ("Pendaftaran", ±68px) tetap utuh satu baris. */
@media (max-width: 359.98px) {
  .nav__link { padding-left: 2px; padding-right: 2px; font-size: 0.75rem; letter-spacing: -0.01em; }
}

/* Tablet: rail ikon + label = 5 menu teratas + "Menu". Rail cukup lebar agar label satu kata ("Pendaftaran") utuh.
   Kerangka tetap di tempat saat isi halaman digulir: topbar menempel di atas, menu samping setinggi sisa layar dengan
   gulirannya sendiri (daftar menu admin lebih tinggi dari layar; tanpa ini menu ikut tergulir bersama halaman dan menu
   terbawah baru terlihat di ujung halaman). Tinggi topbar tetap (--topbar-h) karena menu samping dan elemen lengket lain
   dimulai tepat di bawahnya. */
@media (min-width: 640px) {
  :root { --lengket-atas: var(--topbar-h); }
  html { scroll-padding-top: var(--lengket-atas); }
  .app { display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr); grid-template-rows: auto 1fr; }
  .topbar { grid-column: 1 / -1; position: sticky; top: 0; z-index: 16; height: var(--topbar-h); }
  .nav {
    position: sticky; top: var(--topbar-h); align-self: start;
    height: calc(100vh - var(--topbar-h)); height: calc(100dvh - var(--topbar-h));
    overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
    border-right: 1px solid var(--border); box-shadow: 1px 0 0 rgba(16, 24, 40, .04); padding: var(--s2) 6px;
  }
  .nav__list { display: grid; gap: var(--s1); }
  .nav__link { flex-direction: column; gap: 2px; padding: var(--s2) 2px; font-size: var(--text-xs); text-align: center; letter-spacing: -0.01em; }
  .nav__badge { position: absolute; top: 2px; right: 6px; }
}
@media (min-width: 640px) and (max-width: 1023.98px) {
  .nav__item--beyond-rail { display: none; }
}

/* Desktop: sidebar berlabel lengkap, dikelompokkan; baris menu rata tepi, garis aktif menempel di tepi kiri sidebar;
   akun di topbar. */
@media (min-width: 1024px) {
  .app { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); }
  .nav { padding: var(--s2) 8px; }
  .nav__link {
    flex-direction: row; gap: 10px; padding: var(--s1) var(--s4) var(--s1) 10px;
    font-size: var(--text-md); text-align: left; letter-spacing: normal;
  }
  .nav__link[aria-current="page"], .nav__link--dituju { font-weight: 700; }
  .nav__list:has(.nav__link--dituju) .nav__link[aria-current="page"]:not(.nav__link--dituju) { font-weight: 500; }
  .nav__icon { width: var(--nav-icon); height: var(--nav-icon); }
  .nav__badge { position: static; margin-left: auto; }
  .nav__group {
    display: block; margin: var(--s3) 10px 2px;
    font-size: var(--text-xs); font-weight: 700; color: var(--muted);
  }
  .nav__item--menu { display: none; }
  .topbar__user { display: flex; }
}

/* ---------- Halaman Menu ---------- */
.menu-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 160px), 1fr)); }
.menu-tile {
  display: flex; align-items: center; gap: var(--s3); min-height: 56px; padding: var(--s3) var(--s4);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); box-shadow: var(--bayang-panel);
  color: var(--ink); text-decoration: none; font-weight: 500;
}
.menu-tile:hover { border-color: var(--border-strong); background: var(--row-hover); color: var(--ink); }
.menu-tile__icon { width: 22px; height: 22px; color: var(--primary); }

/* ---------- Kepala halaman ---------- */
.page-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s2) var(--s4); margin-bottom: var(--s4); }
.page-head p { color: var(--ink-2); font-size: var(--text-sm); margin-top: 2px; }
/* Kode pendek di keterangan (No. RM, nomor antrian "UJI-UMUM-002") tidak terpenggal di tanda hubung. */
.page-head p .mono { white-space: nowrap; }
/* Chip status di kepala halaman (mis. akun "Aktif") sebaris dengan judul & keterangannya, bukan dengan remah di atasnya. */
.page-head > .chip { align-self: last baseline; }
/* Layar sempit dengan satu tombol: tombol sebaris dengan judul, remah di atas dan keterangan di bawah selebar kepala
   (hemat satu baris). grid-auto-flow dense menaruh tombol di baris judul, ada remah atau tidak. */
@media (max-width: 767.98px) {
  .page-head:has(> .btn:nth-child(2):last-child) {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-auto-flow: row dense; align-items: center; row-gap: 2px;
  }
  .page-head:has(> .btn:nth-child(2):last-child) > div:first-child { display: contents; }
  .page-head:has(> .btn:nth-child(2):last-child) > div:first-child > * { grid-column: 1 / -1; margin-top: 0; }
  .page-head:has(> .btn:nth-child(2):last-child) > div:first-child > :is(h1, .judul) { grid-column: 1; }
  .page-head:has(> .btn:nth-child(2):last-child) > .btn { grid-column: 2; }
}
/* Layar cukup lebar: judul & keterangan sebaris, dipisah garis rambut; remah (sebelum judul) tetap di baris sendiri. */
@media (min-width: 768px) {
  .page-head { align-items: center; }
  /* Blok judul mengisi ruang di samping tombol dan keterangannya membungkus di dalamnya; bila blok judul akan lebih
     sempit dari ±30rem, tombol turun ke bawah judul (tidak memeras keterangan). */
  .page-head > div:first-child { flex: 1 1 30rem; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--s3); }
  .page-head > div:first-child > :not(h1, .judul):not(h1 ~ *, .judul ~ *) { flex-basis: 100%; }
  /* Keterangan membungkus di sebelah judul (bukan turun ke baris sendiri) selama masih ada ruang ±14rem; keterangan
     kedua dan seterusnya (mis. periode laporan) di baris sendiri di bawahnya. */
  .page-head > div:first-child > :is(h1, .judul) + p { flex: 1 1 14rem; min-width: 0; margin-top: 0; padding-left: var(--s3); border-left: 1px solid var(--line-strong); line-height: 1.3; }
  .page-head > div:first-child > :is(h1, .judul) + p ~ * { flex-basis: 100%; }
}
.section { margin-top: var(--s6); }
.section > :is(h2, .judul) { margin-bottom: var(--s3); }

/* ---------- Kartu & panel ---------- */
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); padding: var(--panel-pad-y) var(--panel-pad-x); box-shadow: var(--bayang-panel); }

/* Judul panel (judul pertama, atau .judul / kepala bagian modul) di pita kepala selebar panel: beda warna dari isi. */
.panel > :is(h2, .judul, .resep__head, .panel-head, .ss-panel-head):not(.visually-hidden):first-child {
  margin: calc(-1 * var(--panel-pad-y)) calc(-1 * var(--panel-pad-x)) var(--panel-pad-y);
  padding: var(--s3) var(--panel-pad-x);
  background: var(--kepala-bg); color: var(--kepala-teks); --muted: var(--kepala-redup);
  border-bottom: 1px solid var(--kepala-garis); border-radius: calc(var(--radius-panel) - 1px) calc(var(--radius-panel) - 1px) 0 0;
}
.panel > :is(.judul, .resep__head, .panel-head, .ss-panel-head):first-child :is(h2, h3) { color: var(--kepala-teks); }
/* Panel form: judul sesudah token CSRF (input tersembunyi) juga dihitung judul pertama. */
.panel > input[type="hidden"]:first-child ~ :is(h2, .judul):not(.visually-hidden):nth-child(1 of :not(input[type="hidden"])) {
  margin: calc(-1 * var(--panel-pad-y)) calc(-1 * var(--panel-pad-x)) var(--panel-pad-y);
  padding: var(--s3) var(--panel-pad-x);
  background: var(--kepala-bg); color: var(--kepala-teks); --muted: var(--kepala-redup);
  border-bottom: 1px solid var(--kepala-garis); border-radius: calc(var(--radius-panel) - 1px) calc(var(--radius-panel) - 1px) 0 0;
}
/* Judul bagian di luar panel: bilah aksen 3px di kirinya (judul khusus pembaca layar tidak). */
.main :is(h2, h3):not(.visually-hidden, .panel *, summary *, .kartu *, .zona-bahaya *, .widget *, .empty *, .kosong *, .alert *, .cppt *, .menu-lain *, .petunjuk *, .resep-item *) {
  padding-left: var(--s3); box-shadow: inset 3px 0 0 var(--primary);
}

/* ---------- Judul + catatan (i) (x-catatan, DESIGN.md §6 "Catatan (i)") ---------- */
/* <div class="judul"><h2 id="…">Judul</h2><x-catatan untuk="…">…</x-catatan></div>: tombol (i) sebaris di kanan judul. */
.judul { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s2); row-gap: 2px; min-width: 0; }
.judul > :is(h1, h2, h3) { min-width: 0; }
.catatan { display: inline-flex; align-items: center; flex: none; vertical-align: middle; }
/* Lingkaran 20px yang terlihat; bidang sentuhnya setinggi --tap (44px di layar sentuh) tanpa menambah tinggi baris. */
.catatan__tombol {
  display: inline-grid; place-items: center; flex: none;
  width: var(--tap); height: var(--tap); margin: calc((var(--tap) - 22px) / -2);
  padding: 0; border: 0; border-radius: 50%; background: none; color: var(--ink-2); cursor: pointer;
}
.catatan__tombol:hover, .catatan__tombol:focus-visible, .catatan__tombol[data-terbuka] { color: var(--primary-ink); }
.catatan__tombol:focus-visible { outline-offset: -8px; }
.panel > :is(h2, .judul, .resep__head, .panel-head, .ss-panel-head):first-child .catatan__tombol { color: var(--kepala-teks); }
.catatan__ikon, .nav__icon.catatan__ikon { width: 20px; height: 20px; }
/* Isi catatan = popover (lapisan teratas, tidak terpotong wadah). Tanpa JS: di tengah layar (bawaan browser);
   dengan JS: di bawah tombol (atau di atasnya bila tidak muat), selalu di dalam layar (data-terletak). */
.catatan__isi {
  max-width: min(26rem, calc(100vw - 24px)); max-height: min(var(--catatan-maks-t, 60vh), 30rem); overflow: auto;
  padding: var(--s3) var(--s4); color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 0 0 1px rgba(16, 24, 40, .04), 0 12px 32px -12px rgba(16, 24, 40, .32);
  font: 400 var(--text-sm)/1.45 var(--font); letter-spacing: normal; text-align: left; white-space: normal; overflow-wrap: anywhere;
}
.catatan__isi[data-terletak] { inset: auto; margin: 0; top: var(--catatan-y, 0px); left: var(--catatan-x, 0px); }
.catatan__isi > * + * { margin-top: var(--s2); }
.catatan__isi :where(ul, ol) { margin: 0; padding-left: 1.2em; }
/* Browser tanpa Popover API: catatan tampil sebagai teks biasa di bawah judul, tanpa tombol. */
@supports not selector(:popover-open) {
  .catatan__tombol { display: none; }
  .catatan { display: block; flex-basis: 100%; }
  .catatan__isi { display: block; max-width: none; max-height: none; padding: 0; border: 0; box-shadow: none; background: none; color: var(--muted); }
}

/* ---------- Tombol ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: var(--tap); padding: 0 var(--s4);
  font: inherit; font-weight: 500; line-height: 1.2; text-decoration: none;
  border-radius: var(--radius); border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--ink); cursor: pointer;
}
.btn:hover { background: var(--row-hover); border-color: var(--border-hover); color: var(--ink); }
.btn--primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.btn--primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); color: var(--on-primary); }
.btn--text { border-color: transparent; background: transparent; color: var(--primary); padding: 0 var(--s2); }
.btn--text:hover { background: var(--row-hover); border-color: transparent; color: var(--primary-hover); }
.btn--block { width: 100%; }
/* Tombol nonaktif (mis. verifikasi dua langkah sedang dikunci): jelas tidak bisa ditekan, warna tidak berubah saat disorot. */
.btn:disabled, .btn:disabled:hover { opacity: 0.55; cursor: not-allowed; }
.btn--primary:disabled:hover { background: var(--primary); border-color: var(--primary); }
/* Form yang sedang dikirim (data-kirim-sekali, public/js/app.js): tombol kirim nonaktif sampai halaman berganti. */
form[data-terkirim] button:disabled { opacity: 0.6; cursor: progress; }

/* ---------- Form ---------- */
.field { display: grid; gap: 2px; margin-bottom: var(--field-gap); align-content: start; }
.field > label:not(.choice) { min-height: 1.5em; }
.field label { font-weight: 500; color: var(--ink-2); font-size: var(--text-sm); }
.input {
  width: 100%; min-height: var(--tap); padding: var(--input-y) var(--input-x);
  font: inherit; font-size: var(--text-md); color: var(--ink);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius);
}
.input:hover { border-color: var(--border-hover); }
.input:focus-visible { outline: 1px solid var(--primary); outline-offset: 0; border-color: var(--primary); box-shadow: 0 0 0 4px var(--focus-ring); }
.input::placeholder { color: var(--muted); }
/* Isian berkas (mis. logo klinik): tombol pilih berkas bawaan browser bergaya .btn. */
.input[type="file"] { padding: 3px; }
.input::file-selector-button {
  min-height: calc(var(--tap) - 8px); margin-right: var(--s3); padding: 0 var(--s4);
  font: inherit; font-weight: 500; color: var(--ink); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius); cursor: pointer;
}
.input::file-selector-button:hover { background: var(--row-hover); border-color: var(--border-hover); }
.input[aria-invalid="true"] { border-color: var(--danger); }
.input[aria-invalid="true"]:focus-visible { outline-color: var(--danger); box-shadow: 0 0 0 4px rgba(180, 35, 24, .16); }
.field__error { color: var(--danger); font-size: var(--text-sm); font-weight: 500; line-height: 1.35; }
.field__hint { color: var(--muted); font-size: var(--text-sm); line-height: 1.35; }

.search { display: flex; gap: var(--gap-tap); flex-wrap: wrap; }
.search .input { flex: 1 1 240px; }

/* ---------- Form berkelompok ---------- */
/* Form maksimal 2 kolom (DESIGN.md §5). Isian sejajar di atas: label tidak ikut meregang. */
.form { max-width: 880px; container: form / inline-size; }
/* Pesan di halaman form selebar form-nya. */
.main:has(> .form) > .alert, .main:has(> .form) > .empty { max-width: 880px; }
.form-grid { display: grid; gap: 0 var(--s5); grid-template-columns: minmax(0, 1fr); align-items: start; }
/* Jumlah kolom mengikuti lebar form (container query), bukan lebar layar. */
@container form (min-width: 520px) { .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Tanda vital: angka pendek, 2 kolom di form sempit, 4 kolom di form lebar. */
.form-grid--vitals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@container form (min-width: 640px) { .form-grid--vitals { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.form-grid__full { grid-column: 1 / -1; }
/* line-height: 1: tanda "wajib" (huruf lebih kecil) tidak pernah menambah tinggi baris label, juga bila bobot hurufnya
   belum siap dan tergambar dengan huruf cadangan, jadi isian sebaris tetap sejajar. */
.field__req { font-weight: 400; color: var(--muted); font-size: var(--text-xs); line-height: 1; margin-left: var(--s1); }
.fieldset { border: 1px solid var(--line-strong); border-radius: var(--radius); padding: var(--s4); margin: 0 0 var(--s4); min-width: 0; }
.fieldset .field:last-child, .fieldset .form-grid .field { margin-bottom: var(--s3); }
/* Judul bagian form: label berpita kepala (--kepala-*) yang duduk di garis fieldset. */
.fieldset legend {
  font-weight: 700; padding: 1px var(--s3); color: var(--kepala-teks);
  background: var(--kepala-bg); border: 1px solid var(--kepala-garis); border-radius: 6px;
}
/* Teks abu (--muted: "wajib", keterangan) di pita kepala memakai --kepala-redup agar tetap >= 4,5:1 di atas pita. */
.fieldset legend, .table thead, .data-list--cols .data-head { --muted: var(--kepala-redup); }
/* Keterangan abu-abu di legend (kode poli, spesialisasi) berbobot biasa seperti kode mono di sebelahnya; hanya
   nama/judulnya yang tebal. */
.fieldset legend .muted { font-weight: 400; }
textarea.input { min-height: var(--textarea-h); resize: vertical; }
select.input { appearance: auto; }
.choice-group { display: flex; flex-wrap: wrap; gap: var(--gap-tap) var(--s5); }
.choice { display: inline-flex; align-items: center; gap: var(--s2); min-height: var(--tap); cursor: pointer; }
.choice input { width: 20px; height: 20px; accent-color: var(--primary); margin: 0; }
.input-suffix { position: relative; }
.input-suffix .input { padding-right: 4.5rem; }
.input-suffix__unit { position: absolute; right: var(--s3); top: 50%; transform: translateY(-50%); color: var(--muted); font-size: var(--text-sm); pointer-events: none; }
.disclosure { margin-top: var(--s4); border-top: 1px solid var(--border); padding-top: var(--s3); }
.disclosure > summary { cursor: pointer; min-height: var(--tap); display: flex; align-items: center; font-weight: 500; color: var(--primary); }
.form-actions { display: flex; flex-wrap: wrap; gap: var(--gap-tap); margin-top: var(--s4); }
.btn--small { min-height: var(--btn-kecil-h); padding: 0 var(--btn-kecil-x); font-size: var(--text-sm); }
.row-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-tap); }

/* ---------- Pemeriksaan: ringkasan pasien + form SOAP ---------- */
.section-sm { margin-top: var(--s2); }
.exam { display: grid; gap: var(--s4); grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 1200px) {
  .exam { grid-template-columns: minmax(240px, 300px) minmax(0, 1fr); gap: var(--s5); }
  .exam__side { position: sticky; top: calc(var(--lengket-atas) + var(--s4)); }
}
.facts--stack { grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
.history { padding: var(--s3) 0; border-top: 1px solid var(--border); }
.history:first-of-type { margin-top: var(--s3); }
.history p + p { margin-top: var(--s1); }
.history__plan { white-space: pre-line; color: var(--ink-2); }

/* Rekam medis terkunci setelah "Selesai periksa" & amandemen (docs/UI-KIT.md "Rekam medis terkunci & amandemen") */
.exam__main > .form { max-width: none; }
.rm-terkunci__kepala { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--gap-tap) var(--s4); }
.rm-terkunci__keterangan { margin-top: var(--s2); color: var(--ink-2); }
.rm-isi { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s4); margin: var(--s4) 0 0; }
.rm-isi > div > dt { font-size: var(--text-sm); font-weight: 500; color: var(--ink-2); }
.rm-isi > div > dd { margin: var(--s1) 0 0; overflow-wrap: anywhere; }
.rm-isi__teks { white-space: pre-line; }
.rm-isi > div > .rm-isi__sumber { font-size: var(--text-sm); color: var(--muted); }
.rm-isi__angka { grid-template-columns: repeat(auto-fill, minmax(min(100%, 9rem), 1fr)); gap: var(--s2) var(--s5); }
.rm-isi__daftar { margin: 0; padding-left: 1.2em; }
.amandemen-alasan { margin-top: var(--s4); }
.amandemen-riwayat { margin-top: var(--s4); }
.amandemen-daftar { list-style: none; margin: var(--s4) 0 0; padding: 0; }
.amandemen + .amandemen { margin-top: var(--s5); padding-top: var(--s5); border-top: 1px solid var(--line-strong); }
.amandemen__kepala { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s3); align-items: baseline; }
.amandemen__kepala > span { color: var(--ink-2); font-size: var(--text-sm); }
.amandemen__alasan { margin: var(--s2) 0 var(--s3); overflow-wrap: anywhere; }
.amandemen__nilai { white-space: pre-line; overflow-wrap: anywhere; }
/* Rata atas: isian, sebelum, dan sesudah mulai di baris yang sama (.table td bawaannya rata tengah). */
.table.amandemen__tabel td { vertical-align: top; }
/* Isian bagian yang terkunci (<fieldset disabled> di panel modul): tetap terbaca, bukan pudar. */
.fieldset-terkunci { border: 0; padding: 0; margin: 0; min-width: 0; }
.fieldset-terkunci:disabled .input {
  color: var(--ink); -webkit-text-fill-color: var(--ink); background: var(--row-hover); opacity: 1; cursor: not-allowed;
}
.fieldset-terkunci:disabled .choice { cursor: not-allowed; }
.kunci-bagian { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-tap) var(--s4); margin: var(--s3) 0; }
.kunci-bagian__teks { flex: 1 1 18rem; color: var(--ink-2); font-size: var(--text-sm); margin: 0; }

/* Panel modul di bawah form pemeriksaan & widget beranda */
.exam-panel { margin-top: var(--s5); }
@media (min-width: 1200px) { .exam-panel { margin-left: calc(300px + var(--s5)); } }
.widgets { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); margin-bottom: var(--s4); }
/* Kartu widget Beranda (docs/UI-KIT.md "Panel & widget modul"): <section class="panel widget"> di .widget-deret. Kartu
   sebaris setinggi barisnya (stretch) dan tersusun flex kolom; tautan kaki (<p class="widget__kaki">, anak terakhir)
   didorong margin-top: auto ke dasar kartu, jadi tautan kaki kartu-kartu sebaris selalu sejajar berapa pun panjang isinya.
   Diukur tests/browser/layout-check.js ("tautan kaki tidak sejajar"). */
.widget-deret { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); align-items: stretch; }
.widget { display: flex; flex-direction: column; min-width: 0; }
.widget__kaki { margin-top: auto; padding-top: var(--s3); }
/* Beranda per peran: bagian dokter, pekerjaan utama modul, kartu widget, antrian terlipat, berjarak sama. */
.beranda > * + * { margin-top: var(--s6); }

/* ---------- UI kit bersama (lihat docs/UI-KIT.md) ---------- */
/* Tabel data padat (keuangan, stok, laporan): garis rambut, kepala tanpa isian, baris disorot. Selalu dibungkus .table-wrap
   agar tabel lebar bergulir di dalam wadahnya sendiri, bukan seluruh halaman. position: relative agar teks .visually-hidden
   (position: absolute) di dalam sel ikut terbatasi wadah ini dan tidak melebarkan halaman di HP. */
.table-wrap { position: relative; overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); box-shadow: var(--bayang-panel); }
.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.table th, .table td { padding: var(--cell-y) var(--s3); text-align: left; border-bottom: 1px solid var(--line); vertical-align: middle; line-height: 1.35; }
.table thead th { background: var(--kepala-bg); color: var(--kepala-teks); font-size: var(--text-xs); font-weight: 700; white-space: nowrap; border-bottom-color: var(--kepala-garis); }
.table tbody tr:hover td { background: var(--row-hover); }
.table tbody tr:last-child td { border-bottom: none; }
.table tfoot td { font-weight: 700; border-top: 1px solid var(--border-strong); border-bottom: none; }
.table .num, .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.table .num { font-weight: 500; }
/* Kode (No. kwitansi, batch, faktur, nomor antrian) tidak terpenggal di tanda hubung di layar lebar. Di HP & tablet boleh
   membungkus setelah tanda hubung agar kolom nama tidak tergencet. */
@media (min-width: 1024px) { .table td.mono { white-space: nowrap; } }
.table td.actions { white-space: nowrap; text-align: right; }
/* Keterangan kecil di bawah isi utama sel (mis. username · email · login terakhir di bawah nama), agar tabel cukup sedikit
   kolom untuk muat di tablet. Butir (<span>) dipisah "·" dari CSS seperti .data-row__meta: pemisah di awal baris yang
   membungkus jatuh di luar tepi kiri dan terpotong. Butir panjang tanpa spasi (username, email) boleh dipenggal. */
.table .sel-ket { --pisah: 0.71em; display: flex; flex-wrap: wrap; gap: 0 var(--pisah); overflow: hidden; margin-top: 2px; color: var(--ink-2); font-size: var(--text-sm); font-weight: 400; }
.table .sel-ket > * { position: relative; min-width: 0; margin-left: calc(-1 * var(--pisah)); padding-left: var(--pisah); overflow-wrap: anywhere; }
.table .sel-ket > *::before { content: "·"; position: absolute; left: 0; width: var(--pisah); text-align: center; color: var(--muted); }
/* HP: sel lebih rapat agar kolom Total lebih cepat terlihat tanpa menggulir. */
@media (max-width: 639.98px) {
  .table th, .table td { padding-left: 8px; padding-right: 8px; }
}

/* Baris filter/aksi di atas daftar: filter kiri, tombol utama kanan. */
.toolbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s3); margin-bottom: var(--s4); }
.toolbar .field { margin-bottom: 0; }
/* Isian cari di filter: lebar bawaan browser (±20 huruf) memotong petunjuknya ("Nama, No. RM, atau No. kwitansi"). */
.toolbar .field:has(.input[type="search"]) { flex: 1 1 16rem; max-width: 24rem; }
.toolbar__spacer { flex: 1 1 auto; }
/* Saringan daftar kerja (antrian Pendaftaran: Tanggal | Poli | Tampilkan | Hari ini, Kemarin; booking: Tanggal | Poli).
   Pintasan yang sedang tampil bergaris biru. HP: dua isian berbagi satu baris (nama poli panjang terpotong di dalam
   pilihannya), tombol di baris berikutnya. */
.toolbar__pintas { display: flex; flex-wrap: wrap; gap: var(--gap-tap); }
.toolbar__pintas .btn[aria-current="true"] { border-color: var(--primary); color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
@media (max-width: 639.98px) {
  .toolbar--saringan .field { flex: 1 1 8.5rem; min-width: 0; }
}

/* Tab navigasi antar-subhalaman modul (link biasa, bukan JS): garis bawah 2px. */
.tabs { display: flex; gap: var(--s5); box-shadow: inset 0 -1px 0 var(--border); margin-bottom: var(--s4); overflow-x: auto; }
.tabs a { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 2px; color: var(--ink-2); text-decoration: none; font-weight: 500; white-space: nowrap; border-bottom: 2px solid transparent; }
.tabs a:hover { color: var(--ink); border-bottom-color: var(--line-strong); }
.tabs a[aria-current="page"] { color: var(--primary); border-bottom-color: var(--primary); }
.tabs + .data-list { margin-top: 0; }
@media (max-width: 639.98px) {
  /* Tiga tab muat dalam satu layar HP tanpa digulir. */
  .tabs { gap: var(--s4); }
  .tabs a { font-size: 0.9375rem; }
}

/* Ringkasan total (tagihan, laporan). */
.summary { display: grid; gap: var(--s2); margin: 0; }
.summary > div { display: flex; justify-content: space-between; gap: var(--s4); }
.summary dt { color: var(--ink-2); }
.summary dd { margin: 0; font-variant-numeric: tabular-nums; }
.summary .summary__total { border-top: 1px solid var(--border-strong); padding-top: var(--s2); font-weight: 700; font-size: var(--text-lg); }

/* Angka ringkas (hanya data nyata dengan periode disebut). Kartu = grid tiga baris label / angka / catatan. Kartu berderet
   di grid (.widgets, ringkasan modul) memakai baris induk lewat subgrid, jadi label, angka, dan catatan sejajar antar-kartu
   walau label satu kartu membungkus dua baris; kartu yang diregangkan setinggi deretnya tidak meregangkan barisnya sendiri
   (angka tidak mengambang). Induk bukan grid (panel widget): grid-row & subgrid diabaikan, align-content: start.
   Kartu tidak boleh menjadi container (container-type memberi layout containment yang mematikan subgrid), jadi tata letak
   dipilih dari lebar induknya (container deret-angka): induk sempit 17,5-40rem (HP, panel) → satu kartu per baris,
   label + catatan kiri, angka kanan; induk lebih lebar → kartu berdampingan, angka di bawah label. */
:has(> .stat) { container: deret-angka / inline-size; }
.stat {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; align-content: start; column-gap: var(--s4);
  grid-row: span 3; grid-template-rows: subgrid; row-gap: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); padding: var(--stat-y) var(--s4);
}
.stat__label { grid-column: 1 / -1; color: var(--ink-2); font-size: var(--text-sm); font-weight: 500; line-height: 1.35; }
.stat__value { grid-column: 1 / -1; font-size: 1.25rem; font-weight: 700; line-height: 1.2; letter-spacing: -0.02em; margin-top: 2px; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
.stat__note { grid-column: 1 / -1; color: var(--muted); font-size: var(--text-xs); line-height: 1.35; }
/* Satu kartu per baris tidak butuh baris bersama: subgrid dilepas agar celah antarbaris induk tidak menambah ruang di kartu. */
@container deret-angka (min-width: 17.5rem) and (max-width: 39.999rem) {
  .stat { grid-column: 1 / -1; grid-row: auto; grid-template-rows: none; }
  .stat__label { grid-column: 1; grid-row: 1; }
  .stat__note { grid-column: 1; grid-row: 2; }
  .stat__value { grid-column: 2; grid-row: 1 / span 2; align-self: center; justify-self: end; margin-top: 0; }
}
/* Kartu angka berderet di .widgets: satu strip bergaris rambut (bayangan 1px kiri & atas; sel di tepi terpotong bingkai). */
.widgets:has(> .stat) {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); gap: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); overflow: hidden;
  box-shadow: var(--bayang-panel);
}
.widgets > .stat { border: 0; border-radius: 0; box-shadow: -1px 0 0 var(--border), 0 -1px 0 var(--border); }
/* Strip lebar (≥ 60rem: 3-4 sel ±280px, seperti acuan tema): angka di kanan sel, di tengah baris label + catatan. Baris
   subgrid dipakai bersama, jadi angka sel tanpa catatan tetap sejajar dengan sel yang bercatatan. */
@container deret-angka (min-width: 60rem) {
  .widgets > .stat > .stat__label { grid-column: 1; grid-row: 1; }
  .widgets > .stat > .stat__note { grid-column: 1; grid-row: 2; }
  .widgets > .stat > .stat__value { grid-column: 2; grid-row: 1 / span 2; align-self: center; justify-self: end; margin-top: 0; }
}
/* HP: satu kolom (angka berderet rata kanan, mudah dibandingkan). */
@media (max-width: 639.98px) {
  .widgets, .widgets:has(> .stat), .widget-deret { grid-template-columns: minmax(0, 1fr); }
}

.btn--danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn--danger:hover { background: #8f1c13; border-color: #8f1c13; color: #fff; }
.text-danger { color: var(--danger); }
.text-success { color: var(--success); }
.stack > * + * { margin-top: var(--s3); }
.inline-form { display: inline; }

/* ---------- Pesan ---------- */
.alert { padding: var(--alert-y) var(--s4); border-radius: 10px; margin-bottom: var(--s4); border: 1px solid; }
.alert--info { color: var(--info); background: var(--info-bg); border-color: var(--info-line); }
.alert--success { color: var(--success); background: var(--success-bg); border-color: var(--success-line); }
.alert--danger { color: var(--danger); background: var(--danger-bg); border-color: var(--danger-line); }
.alert--warning { color: var(--warning); background: var(--warning-bg); border-color: var(--warning-line); }
/* Tombol di dalam pesan memakai warna pesan: garisnya kontras dengan latar pesan. */
.alert .btn { color: inherit; border-color: currentColor; background: var(--surface); }
.alert .btn:hover { background: var(--surface); text-decoration: underline; }
/* Pesan beraksi: tombol selalu di kanan teks; di layar sempit teks membungkus di kolomnya, tombol tidak turun ke baris sendiri. */
.alert:has(> .alert__aksi) { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s2) var(--s3); }

/* Status selalu teks + warna, tidak pernah warna saja. Persegi kecil bergaris tipis. */
.chip {
  display: inline-flex; align-items: center; padding: 1px 6px;
  border-radius: 6px; font-size: var(--text-xs); font-weight: 500; line-height: 1.4; white-space: nowrap;
  border: 1px solid currentColor;
}
.chip--waiting { color: var(--warning); background: var(--warning-bg); border-color: var(--warning-line); }
.chip--done { color: var(--success); background: var(--success-bg); border-color: var(--success-line); }
.chip--info { color: var(--info); background: var(--info-bg); border-color: var(--info-line); }
.chip--danger { color: var(--danger); background: var(--danger-bg); border-color: var(--danger-line); }
.chip--neutral { color: var(--ink-2); background: var(--row-hover); border-color: var(--line-strong); }

/* ---------- Keadaan kosong (§6) ---------- */
.empty { background: var(--surface); border: 1px dashed var(--border-strong); border-radius: var(--radius-panel); padding: var(--empty-y) var(--s4); }
.empty p + p { margin-top: 2px; }

/* ---------- Daftar data: tabel di layar lebar, kartu di HP ---------- */
.data-list { list-style: none; margin: 0; padding: 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-panel); box-shadow: var(--bayang-panel); line-height: 1.35; }
.data-list > li + li { border-top: 1px solid var(--line); }
.data-list > li:last-child { border-radius: 0 0 calc(var(--radius-panel) - 1px) calc(var(--radius-panel) - 1px); }
.data-list > li:not(.data-head):hover { background: var(--row-hover); }
/* Kepala kolom tersembunyi (layar sempit): baris pertama tidak perlu garis atas ganda. */
.data-list > .data-head + li { border-top: 0; }
.data-row { display: grid; gap: var(--s1) var(--s4); padding: var(--row-y) var(--s4); color: inherit; text-decoration: none; }
a.data-row:hover { color: inherit; }
.data-row__primary { font-weight: 500; }
.data-row__primary a { font-weight: 700; }
/* No. RM tidak pernah terpenggal dari dirinya sendiri. */
.data-row__primary .mono { white-space: nowrap; }
.data-row__meta { color: var(--ink-2); font-size: var(--text-sm); display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s3); }
.data-head { display: none; }
@media (max-width: 639.98px) {
  .data-row { padding: 8px var(--s4); }
}

@media (min-width: 900px) {
  .data-list--cols .data-head {
    display: grid; column-gap: var(--s3); padding: var(--row-y) var(--s4);
    font-size: var(--text-xs); color: var(--kepala-teks); font-weight: 700; background: var(--kepala-bg);
    border-bottom: 1px solid var(--kepala-garis); border-radius: calc(var(--radius-panel) - 1px) calc(var(--radius-panel) - 1px) 0 0;
  }
  .data-list--cols > .data-head + li { border-top: 0; }
  /* Jarak kolom kepala & baris harus sama agar kolom tetap sejajar. Semua teks sebaris berbagi satu garis dasar. */
  .data-list--cols .data-row,
  .data-list--cols .data-head { grid-template-columns: var(--cols); column-gap: var(--s3); }
  .data-list--cols .data-row { align-items: baseline; }
  .data-list--cols .data-row__meta { display: contents; }
}
/* Isi kolom keterangan yang kosong (.data-row__kosong, mis. Jaminan "–" di antrian): "–" hanya di tata letak tabel, di bawah
   kepala kolomnya. Di tata letak kartu (tanpa kepala kolom) tidak tampil, jadi keterangan tidak berakhir "· –" tanpa label.
   Daftar status-aksi dan kolom-banyak menyembunyikannya juga di rentang kartu masing-masing (blok di bawah). */
@media (max-width: 899.98px) {
  .data-row__meta > .data-row__kosong { display: none; }
}

/* Lebar kolom per jenis daftar (bukan inline style, agar lolos CSP). Lebar kolom hanya panjang tetap atau minmax(0, fr):
   setiap baris adalah grid sendiri, jadi kolom "auto" membuat baris tidak sejajar. */
.data-list--pilih-pasien { --cols: 8rem minmax(0, 2fr) 9rem 11rem 9rem; }
.data-list--pasien { --cols: 8rem minmax(0, 2fr) 9rem 11rem; }
.data-list--kunjungan { --cols: 8rem minmax(0, 1fr) minmax(0, 1fr) 9rem; }

/* Nomor antrian: Public Sans 700 (bobot yang dimuat) dengan angka tabular, bukan mono tebal tiruan.
   Nomor = "{kode poli}-{nnn}". Kolom nomor (--kolom-lead) muat 12 huruf utuh ("UJI-UMUM-002"), jadi format umum tidak
   pernah patah; kode poli yang lebih panjang lagi membungkus setelah tanda hubung, tidak menimpa kolom nama. */
.queue-no { font-family: var(--font); font-weight: 700; font-size: var(--text-md); letter-spacing: 0.01em; color: var(--ink); min-width: 2.5ch; overflow-wrap: anywhere; }

/* ---------- Kolom status dan aksi (docs/UI-KIT.md) ---------- */
/* Daftar kerja yang barisnya punya status dan tombol aksi (antrian, asesmen, farmasi, lab, kasir, booking, tiket, spesialis,
   kunjungan BPJS).
   Markup: ul.data-list.data-list--cols.data-list--status-aksi.data-list--<jenis>, baris
     .data-row > [kolom awal: nomor/jam] .data-row__primary .data-row__meta .row-status .row-aksi
   Status (chip + keterangan kecil .row-status__ket) dan tombol berada di wadah terpisah, jadi lebar chip tidak menggeser
   tombol. Setiap baris adalah grid sendiri, jadi semua lebar kolom tetap (bukan "auto"). Lebar per daftar di CSS modul:
   --kolom-lead (nomor/jam), --kolom-status, --kolom-aksi, dan --cols (urutan kolom desktop).
   - --kolom-lead: kelipatan --text-md. Nomor antrian tebal ≈ 0,63 × --text-md per huruf; bawaan 7,75 = 12 huruf utuh.
   - --kolom-status: "N × --text-xs + 16px" (lihat :root), N ≈ 0,55 × jumlah huruf chip terpanjang yang umum.
     Kolom status hanya untuk chip status (+ keterangan kecil); chip lain (alergi, BPJS) di kolom pasien.
   - --kolom-aksi: kelipatan --text-md agar ikut mengecil di mode padat; perkiraan per tombol kecil ≈ 0,5 × jumlah
     huruf + 1,4, per tombol biasa ≈ 0,55 × huruf + 2, ditambah 0,5 per jarak antar tombol. Ukur dengan label
     terpanjang di mode padat (13px) dan layar sentuh (16px): tombol tidak boleh turun ke baris kedua.
   - Desktop (>= 1024px): kolom berkepala; status lebar tetap, tombol rata kiri sehingga tombol pertama setiap baris sejajar.
     Layar sentuh 1024-1279px (huruf 16px, sidebar penuh) terlalu sempit untuk enam kolom: memakai tata letak tablet.
   - Tablet (768-1023px): nomor | nama + keterangan kecil di bawahnya | status | aksi; status & aksi tetap di kanan.
     Daftar yang kolom status + aksinya lebar (.data-list--aksi-lebar, --kolom-status + --kolom-aksi >= ±17 × --text-md:
     antrian, lab, kasir, booking, BPJS) di 768-899px: status di atas tombol, agar kolom nama tidak terjepit.
   - Tablet sempit (640-767px): nomor di atas nama (kolom nama lega); status di atas tombol di kolom kanan
     (--kolom-kanan, bawaan selebar kolom status atau aksi yang lebih lebar).
   - HP (< 640px): nomor + nama; keterangan; status lalu aksi. */
.data-list--status-aksi { --kolom-lead: calc(var(--text-md) * 7.75); --kolom-aksi: calc(var(--text-md) * 8); }
.row-status { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
.row-status .chip { white-space: normal; max-width: 100%; }  /* cadangan: chip yang lebih panjang dari kolomnya membungkus, tidak menimpa tombol */
.row-status:empty { display: none; }
.row-status__ket { color: var(--muted); font-size: var(--text-xs); line-height: 1.3; }
.row-status__ket:empty { display: none; }
.row-aksi { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-tap); min-width: 0; }
.row-aksi form { margin: 0; }

@media (min-width: 1024px) {
  /* Status & aksi selalu di dua kolom terakhir, juga bila status kosong (tidak dirender). */
  .data-list--status-aksi .row-status { grid-column: -3 / -2; }
  .data-list--status-aksi .row-aksi { grid-column: -2 / -1; }
}
@media (max-width: 1023.98px), (max-width: 1279.98px) and (pointer: coarse) {
  /* Keterangan di bawah nama ("Poli · Dokter"): pemisah "·" ada di padding kiri setiap butir (selebar celah antar-butir,
     --pisah = lebar " · " di teks, jadi berjarak sama dengan "·" di dalam butir) dan butir digeser --pisah ke kiri, jadi isi
     butir tetap di tempatnya. Pemisah butir pertama di setiap baris
     jatuh di luar tepi kiri dan dipotong overflow: baris yang membungkus tidak pernah diawali "·". "·" di dalam satu
     butir (mis. "Poli&nbsp;· Dokter" di Blade) ditulis dengan spasi tak terputus di depannya karena alasan yang sama. */
  .data-list--status-aksi .data-row__meta { --pisah: 0.71em; display: flex; flex-wrap: wrap; gap: 0 var(--pisah); overflow: hidden; }
  .data-list--status-aksi .data-row__meta > * { position: relative; margin-left: calc(-1 * var(--pisah)); padding-left: var(--pisah); }
  .data-list--status-aksi .data-row__meta > *::before { content: "·"; position: absolute; left: 0; width: var(--pisah); text-align: center; color: var(--muted); }
  .data-list--status-aksi .data-row__meta > .data-row__kosong { display: none; }
}
@media (min-width: 640px) and (max-width: 1023.98px), (min-width: 1024px) and (max-width: 1279.98px) and (pointer: coarse) {
  .data-list--status-aksi > .data-head { display: none; }
  .data-list--status-aksi > .data-head + li { border-top: 0; }
  .data-list--status-aksi .data-row {
    grid-template-columns: var(--kolom-lead) minmax(0, 1fr) var(--kolom-status) var(--kolom-aksi);
    grid-template-areas: "lead isi status aksi" "lead meta status aksi";
    align-items: center; column-gap: var(--s3); row-gap: 2px;
  }
  .data-list--status-aksi .data-row > :first-child { grid-area: lead; }
  .data-list--status-aksi .data-row__primary { grid-area: isi; align-self: end; }
  .data-list--status-aksi .data-row__meta { grid-area: meta; align-self: start; }
  .data-list--status-aksi .row-status { grid-area: status; }
  .data-list--status-aksi .row-aksi { grid-area: aksi; }
}
/* Daftar dengan banyak kolom tetap (.data-list--kolom-banyak, mis. booking: jam, kode, status, dua tombol) juga terlalu sempit
   untuk enam kolom di mode padat 1024-1279px (mouse): kolom nama tinggal ±125px dan nama membungkus 3-6 baris. Daftar ini
   memakai tata letak tablet di rentang itu dengan pointer apa pun (aturan sama dengan dua blok di atas). */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  .data-list--kolom-banyak .data-row__meta { --pisah: 0.71em; display: flex; flex-wrap: wrap; gap: 0 var(--pisah); overflow: hidden; }
  .data-list--kolom-banyak .data-row__meta > * { position: relative; margin-left: calc(-1 * var(--pisah)); padding-left: var(--pisah); }
  .data-list--kolom-banyak .data-row__meta > *::before { content: "·"; position: absolute; left: 0; width: var(--pisah); text-align: center; color: var(--muted); }
  .data-list--kolom-banyak .data-row__meta > .data-row__kosong { display: none; }
  .data-list--kolom-banyak > .data-head { display: none; }
  .data-list--kolom-banyak > .data-head + li { border-top: 0; }
  .data-list--kolom-banyak .data-row {
    grid-template-columns: var(--kolom-lead) minmax(0, 1fr) var(--kolom-status) var(--kolom-aksi);
    grid-template-areas: "lead isi status aksi" "lead meta status aksi";
    align-items: center; column-gap: var(--s3); row-gap: 2px;
  }
  .data-list--kolom-banyak .data-row > :first-child { grid-area: lead; }
  .data-list--kolom-banyak .data-row__primary { grid-area: isi; align-self: end; }
  .data-list--kolom-banyak .data-row__meta { grid-area: meta; align-self: start; }
  .data-list--kolom-banyak .row-status { grid-area: status; }
  .data-list--kolom-banyak .row-aksi { grid-area: aksi; }
}
/* Status di atas tombol, keduanya di kolom kanan selebar kolom status atau aksi yang lebih lebar (daftar dengan
   --kolom-status fleksibel, mis. spesialis, mengisi --kolom-kanan). Status menempel ke tombol di bawahnya (seperti nama
   ke keterangannya), juga bila nama membungkus beberapa baris. */
@media (min-width: 768px) and (max-width: 899.98px) {
  .data-list--aksi-lebar .data-row {
    grid-template-columns: var(--kolom-lead) minmax(0, 1fr) var(--kolom-kanan, max(var(--kolom-status), var(--kolom-aksi)));
    grid-template-areas: "lead isi status" "lead meta aksi";
    row-gap: var(--s1);
  }
  .data-list--aksi-lebar .row-status { align-self: end; }
  .data-list--aksi-lebar .row-aksi { align-self: start; }
}
/* Tablet sempit: nomor/jam di baris sendiri di atas nama, jadi kolom nama tidak terjepit kolom nomor dan kolom kanan.
   Status yang lebih tinggi dari nomor + nama (mis. pesan gagal BPJS) menambah tinggi baris pertama (1fr), bukan baris nama:
   nomor, nama, dan keterangan tetap rapat. */
@media (min-width: 640px) and (max-width: 767.98px) {
  .data-list--status-aksi .data-row {
    grid-template-columns: minmax(0, 1fr) var(--kolom-kanan, max(var(--kolom-status), var(--kolom-aksi)));
    grid-template-rows: 1fr auto auto;
    grid-template-areas: "lead status" "isi status" "meta aksi";
  }
  .data-list--status-aksi .data-row > :first-child { align-self: end; }
  .data-list--status-aksi .row-status { align-self: end; }
  .data-list--status-aksi .row-aksi { align-self: start; }
}
@media (max-width: 639.98px) {
  .data-list--status-aksi .data-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) var(--s3); }
  .data-list--status-aksi .data-row__primary { flex: 1 1 0; min-width: 0; }
  .data-list--status-aksi .data-row__meta { flex-basis: 100%; }
}

/* Daftar antrian (Pendaftaran, Beranda dokter): No. | Pasien (RM · kode registrasi) | Poli | Dokter | Jaminan | Status |
   Periksa/Lihat RM, Panggil, Tiket (tanggal lain: Periksa/Lihat RM, Tagihan) (.data-list--aksi-lebar). Tujuh kolom: di
   1024-1279px tata letak tablet (.data-list--kolom-banyak), kecuali versi baca saja yang tanpa kolom aksi. */
.data-list--antrian { --kolom-aksi: calc(var(--text-md) * 15); --cols: var(--kolom-lead) minmax(0, 2.2fr) minmax(0, .9fr) minmax(0, .9fr) minmax(0, .75fr) var(--kolom-status) var(--kolom-aksi); }
/* Daftar baca saja (antrian terlipat di Beranda peran lain): kolom aksi kosong tidak memakan tempat. */
.data-list--baca { --kolom-aksi: 0px; }
/* Tanggal lain: paling banyak dua tombol kecil (Lihat RM/Periksa + Tagihan), kolom aksi lebih sempit. */
.data-list--antrian-lampau:not(.data-list--baca) { --kolom-aksi: calc(var(--text-md) * 11); }
/* Tanggal lain, dua tombol: tombol pertama ("Lihat RM" atau "Periksa") selebar label terpanjangnya ("Lihat RM" ≈ 4,16em
   Public Sans 500), jadi tombol Tagihan sejajar di semua baris. Keduanya tetap muat sebaris di --kolom-aksi di mode padat
   (±141 dari 143px) dan layar sentuh (±171 dari 176px). */
.data-list--antrian-lampau .row-aksi > .btn:first-child:not(:last-child) { min-width: calc(4.2em + 2 * var(--btn-kecil-x) + 2px); }
/* Baris kedua kolom pasien antrian: No. RM · kode registrasi (no_reg, mono). Masing-masing tidak terpenggal; bila tidak
   muat sebaris, kode registrasi turun utuh ke baris berikutnya. */
.antrian-kode { display: block; font-weight: 400; }
/* Nama pasien + penanda (mis. "Online"), partials/antrian-list: pembungkus tidak membungkus, nama di dalamnya membungkus
   seperti biasa. Di antara nama dan penanda hanya &nbsp; milik pembungkus, jadi penanda selalu menempel ke kata terakhir
   nama: nama panjang yang tidak muat bersama penanda membawa kata terakhirnya ke baris berikutnya, penanda tidak turun
   sendirian. (Spasi biasa di situ tetap dipenggal Chrome walau pembungkusnya nowrap.) */
.antrian-nama { white-space: nowrap; }
.antrian-nama > :not(.chip) { white-space: normal; }
.antrian-nama > .chip { margin-left: var(--s1); vertical-align: 1px; }

/* ---------- Pola halaman detail (docs/UI-KIT.md "Halaman detail", "Aksi") ---------- */
/* Komponen Blade: x-kepala, x-kepala-pasien, x-menu-lainnya, x-zona-bahaya, x-chip-alergi, x-stat, x-detail, x-kartu,
   x-tab-kerja/x-tab, x-kosong, x-info-lipat. Semua jalan tanpa JavaScript; app.js hanya menambah kenyamanan. */

/* Kepala halaman: remah | judul + chip, satu baris identitas | kelompok aksi di kanan (turun ke bawah judul bila sempit). */
.remah { margin-bottom: 2px; font-size: var(--text-sm); color: var(--ink-2); }
.kepala { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3) var(--s4); margin-bottom: var(--s4); }
.kepala__utama { flex: 1 1 24rem; min-width: 0; }
.kepala__judul { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s3); }
.kepala__judul h1 { min-width: 0; overflow-wrap: anywhere; }
.kepala__chip { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s2); min-width: 0; max-width: 100%; }
/* Butir identitas (<span>) dipisah "·" dari CSS, seperti .data-row__meta: pemisah di awal baris yang membungkus jatuh di
   luar tepi kiri dan terpotong, jadi baris tidak pernah diawali "·". */
.kepala__identitas {
  --pisah: 0.71em; display: flex; flex-wrap: wrap; gap: 0 var(--pisah); overflow: hidden;
  margin-top: 2px; color: var(--ink-2); font-size: var(--text-sm); line-height: 1.35;
}
.kepala__identitas > * { position: relative; margin-left: calc(-1 * var(--pisah)); padding-left: var(--pisah); }
.kepala__identitas > *::before { content: "·"; position: absolute; left: 0; width: var(--pisah); text-align: center; color: var(--muted); }
.kepala__identitas .mono { white-space: nowrap; }
.kepala__aksi { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-tap); }
.kepala__aksi form { margin: 0; }
/* Lengket (form panjang): tetap di atas saat menggulir, latar selebar isi halaman. Tingginya diukur app.js
   (--kepala-lengket-h) agar isian yang difokus dan tujuan tautan #id tidak tertutup kepala. */
.kepala--lengket {
  position: sticky; top: var(--lengket-atas); z-index: 15;
  margin-inline: calc(-1 * var(--page-pad)); padding: var(--s2) var(--page-pad);
  background: var(--bg); box-shadow: 0 1px 0 var(--border);
}
html:has(.kepala--lengket) { scroll-padding-top: calc(var(--lengket-atas) + var(--kepala-lengket-h, 7rem) + var(--s3)); }
/* HP: kepala lengket utuh memakan +-1/3 layar. Yang lengket hanya baris judul + chip (nama pasien & alergi tetap terlihat);
   identitas dan tombol ikut tergulir. display: contents menjadikan baris judul anak langsung .main, jadi bisa lengket
   sepanjang halaman tanpa menggandakan markup. */
@media (max-width: 639.98px) {
  .kepala--lengket, .kepala--lengket > .kepala__utama { display: contents; }
  .kepala--lengket .kepala__judul {
    position: sticky; top: 0; z-index: 15;
    margin-inline: calc(-1 * var(--page-pad)); padding: var(--s2) var(--page-pad);
    background: var(--bg); box-shadow: 0 1px 0 var(--border);
  }
  .kepala--lengket .kepala__identitas { margin-top: var(--s1); }
  .kepala--lengket > .kepala__aksi { position: relative; margin: var(--s3) 0 var(--s4); }
}

/* Chip alergi: berisi nama alergen, boleh membungkus (daftar alergen panjang), sedikit lebih besar dari chip status. */
.chip--alergi { white-space: normal; max-width: 100%; font-size: var(--text-sm); overflow-wrap: anywhere; }
.chip--alergi strong { font-weight: 700; }

/* Menu "Lainnya" (<details>): tombol sekunder + daftar melayang. Aksi berbahaya paling bawah, dipisah garis, merah. */
.menu-lain { position: relative; display: inline-block; }
.menu-lain__tombol { list-style: none; user-select: none; }
.menu-lain__tombol::-webkit-details-marker { display: none; }
.menu-lain__tombol::after {
  content: ""; width: 0.4em; height: 0.4em; margin: -0.2em 0 0 var(--s1);
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
.menu-lain[open] > .menu-lain__tombol { background: var(--row-hover); border-color: var(--border-hover); }
.menu-lain[open] > .menu-lain__tombol::after { margin-top: 0.2em; transform: rotate(-135deg); }
.menu-lain__isi {
  position: absolute; z-index: 30; top: calc(100% + 4px); right: 0;
  width: max-content; min-width: 14rem; max-width: min(22rem, calc(100vw - 2 * var(--page-pad)));
  padding: var(--s1) 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 6px 20px rgba(16, 24, 40, .14);
}
.menu-lain__isi form { margin: 0; }
.menu-lain__isi :where(a, button) {
  display: flex; align-items: center; width: 100%; min-height: var(--tap); padding: var(--s1) var(--s4);
  font: inherit; font-size: var(--text-md); line-height: 1.3; text-align: left; text-decoration: none;
  color: var(--ink); background: none; border: 0; border-radius: 0; cursor: pointer;
}
.menu-lain__isi :where(a, button):hover { background: var(--row-hover); color: var(--ink); }
.menu-lain__isi :where(a, button):focus-visible { outline-offset: -2px; }
.menu-lain__bahaya:not(:first-child) { margin-top: var(--s1); padding-top: var(--s1); border-top: 1px solid var(--line-strong); }
.menu-lain__bahaya :where(a, button), .menu-lain__bahaya :where(a, button):hover { color: var(--danger); }
.menu-lain__bahaya :where(a, button):hover { background: var(--danger-bg); }
/* Kepala di layar sempit: daftar selebar kepala (tidak keluar dari tepi layar, di mana pun tombolnya berada). Kepala
   lengket sudah menjadi wadah daftar itu (position: sticky); position: relative di sini tidak boleh menimpanya, kalau
   tidak kepala berhenti lengket di 640-767 px. */
@media (max-width: 767.98px) {
  .kepala:not(.kepala--lengket) { position: relative; }
  .kepala .menu-lain { position: static; }
  .kepala .menu-lain__isi { left: 0; right: 0; width: auto; max-width: none; }
}
/* Kepala lengket 640-767 px melebar sampai tepi layar (latar penuh): daftar tetap sejajar isi halaman. */
@media (min-width: 640px) and (max-width: 767.98px) {
  .kepala--lengket .menu-lain__isi { left: var(--page-pad); right: var(--page-pad); }
}
/* Menu baris (x-menu-lainnya kecil, atau menu di dalam .table-wrap): wadah tabel bergulir ke samping, jadi daftar yang
   melayang absolut terpotong di dalamnya. app.js menandai menu ini data-melayang dan menaruh daftarnya position: fixed
   tepat di bawah (atau di atas) tombolnya, tetap di dalam layar. Tanpa JS daftar terbuka di dalam selnya sendiri
   (baris memanjang): semua aksi tetap terlihat dan bisa dipilih. */
.menu-lain--kecil:not([data-melayang]) > .menu-lain__isi { position: static; margin-top: var(--s1); box-shadow: none; }
.menu-lain[data-melayang] > .menu-lain__isi {
  position: fixed; top: var(--menu-y, 0); left: var(--menu-x, 0); right: auto;
  max-width: min(22rem, calc(100vw - 16px)); max-height: var(--menu-maks-t, none); overflow-y: auto;
}
/* Sebelum app.js menaruhnya (satu bingkai): tidak sempat tampil di tempat yang salah. */
.menu-lain[data-melayang][open]:not([data-terletak]) > .menu-lain__isi { visibility: hidden; }

/* Tombol berbahaya per baris: garis & teks merah di latar putih. Merah solid (btn--danger) hanya untuk tombol konfirmasi
   akhir dan aksi massal di halamannya sendiri. */
.btn--bahaya-garis { color: var(--danger); border-color: var(--danger); background: var(--surface); }
.btn--bahaya-garis:hover { color: #8f1c13; border-color: #8f1c13; background: var(--danger-bg); }

/* Zona bahaya: konfirmasi aksi berbahaya tingkat halaman, tampil saat dituju (#id) atau setelah validasi gagal. */
.zona-bahaya {
  max-width: 880px; margin-top: var(--s5); padding: var(--panel-pad);
  background: var(--surface); border: 1px solid var(--danger-line); border-left: 3px solid var(--danger); border-radius: var(--radius);
  scroll-margin-top: calc(var(--kepala-lengket-h, 0px) + var(--s4));
}
.zona-bahaya:not(:target):not(.zona-bahaya--terbuka), .zona-bahaya.zona-bahaya--tutup { display: none; }
.zona-bahaya__judul { font-size: var(--text-md); color: var(--danger); margin-bottom: var(--s2); }
.zona-bahaya__form > p { color: var(--ink-2); margin-bottom: var(--s3); max-width: 72ch; }
.zona-bahaya__form .form-actions { margin-top: var(--s3); }

/* Strip ringkasan: butir boleh menjadi tautan/saringan (a.stat), saringan aktif = aria-current. */
a.stat { color: inherit; text-decoration: none; }
a.stat:hover { background: var(--row-hover); color: inherit; }
a.stat:focus-visible { outline-offset: -2px; }
a.stat[aria-current="true"] { background: var(--primary-soft); }
a.stat[aria-current="true"] .stat__label { color: var(--primary-ink); }
.widgets > a.stat[aria-current="true"] { box-shadow: inset 0 -3px 0 var(--primary), -1px 0 0 var(--border), 0 -1px 0 var(--border); }

/* Detail dua kolom "kerja | rujukan": dua kolom mulai 1024 px dengan mouse (layar sentuh 1024-1279 px berhuruf 16px dan
   bersidebar penuh: tata letak tablet satu kolom, seperti daftar kerja). */
.detail { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s4); align-items: start; }
.detail__kerja { min-width: 0; }
.detail__kerja > .form { max-width: none; }
.detail__rujukan { display: grid; gap: var(--s3); align-content: start; min-width: 0; }
/* Satu kolom (tablet): kartu rujukan berdampingan bila muat, tidak memanjang selebar halaman. */
.detail__rujukan { grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); }
@media (min-width: 1024px) and (pointer: fine), (min-width: 1280px) {
  .detail { grid-template-columns: minmax(0, 1fr) clamp(20rem, 28vw, 22.5rem); gap: var(--s5); }
  .detail__rujukan { grid-template-columns: minmax(0, 1fr); }
}
.kartu { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--s3) var(--s4); min-width: 0; }
.kartu__kepala { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s2); }
.kartu__judul { font-size: var(--text-md); }
.kartu__aksi { font-size: var(--text-sm); }
.kartu dl { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--s1) var(--s3); margin: 0; font-size: var(--text-sm); line-height: 1.35; }
.kartu dl > div { display: contents; }
.kartu dt { color: var(--ink-2); }
.kartu dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }
.kartu > p + p, .kartu > dl + p, .kartu > p + dl { margin-top: var(--s2); }

/* Tab kerja berjumlah: tanpa JS bagian bertumpuk dengan judulnya; app.js membuat deretan tab dan menyembunyikan judul
   bagian (tetap dibaca pembaca layar). */
.tab-kerja__daftar { display: flex; gap: var(--s5); box-shadow: inset 0 -1px 0 var(--border); margin-bottom: var(--s4); overflow-x: auto; }
.tab-kerja__tab {
  display: inline-flex; align-items: center; gap: var(--s2); flex: none; min-height: var(--tap); padding: 0 2px;
  font: inherit; font-weight: 500; color: var(--ink-2); white-space: nowrap; cursor: pointer;
  background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 0;
}
.tab-kerja__tab:hover { color: var(--ink); border-bottom-color: var(--line-strong); }
.tab-kerja__tab:focus-visible { outline-offset: -2px; }
.tab-kerja__tab[aria-selected="true"] { color: var(--primary); border-bottom-color: var(--primary); }
.tab-kerja__jumlah {
  display: inline-block; min-width: 1.6em; padding: 0 5px; border-radius: 999px; border: 1px solid var(--line-strong);
  background: var(--row-hover); color: var(--ink-2); font-size: var(--text-xs); font-weight: 700; line-height: 1.4; text-align: center;
}
.tab-kerja__tab[aria-selected="true"] .tab-kerja__jumlah { background: var(--primary-soft); border-color: currentColor; color: var(--primary-ink); }
.tab-kerja__judul { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s3); }
.tab-kerja__panel + .tab-kerja__panel { margin-top: var(--s6); }
.tab-kerja__panel[hidden] { display: none; }
.tab-kerja--aktif .tab-kerja__panel + .tab-kerja__panel { margin-top: 0; }
.tab-kerja--aktif .tab-kerja__judul {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@media (max-width: 639.98px) { .tab-kerja__daftar { gap: var(--s4); } }

/* Kosong satu baris (subbagian, tab, panel, widget): kalimat + paling banyak satu aksi, tanpa kotak. */
.kosong { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); padding: var(--s1) 0; color: var(--ink-2); }
.kosong__teks { min-width: 0; }
.kosong__aksi { display: flex; flex-wrap: wrap; gap: var(--gap-tap); }
.kosong__aksi form { margin: 0; }
.kosong--tanpa-hak { color: var(--muted); font-size: var(--text-sm); }

/* Info lipat "Cara ...": tautan lipat kecil, isi dibatasi +-72 huruf per baris. */
.info-lipat { margin-top: var(--s3); font-size: var(--text-sm); }
.info-lipat > summary {
  display: inline-flex; align-items: center; gap: var(--s2); min-height: var(--tap);
  color: var(--primary); font-weight: 500; cursor: pointer; list-style: none;
}
.info-lipat > summary::-webkit-details-marker { display: none; }
.info-lipat > summary::before {
  content: ""; flex: none; width: 0.42em; height: 0.42em;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg);
}
.info-lipat[open] > summary::before { transform: rotate(45deg); }
.info-lipat > summary:hover { color: var(--primary-hover); text-decoration: underline; text-underline-offset: 3px; }
.info-lipat__isi { max-width: 72ch; padding: 0 0 var(--s2) calc(0.42em + var(--s2)); color: var(--ink-2); line-height: 1.45; }
.info-lipat__isi > * + * { margin-top: var(--s2); }
.info-lipat__isi ul, .info-lipat__isi ol { margin: 0; padding-left: 1.2em; }

/* Bagian lipat (x-bagian-lipat): baris lipat = panah + judul bagian (h2/h3) + ringkasan jumlah + "Tampilkan" di kanan.
   Seluruh baris adalah tombol lipat (summary, >= --tap); isi tampil saat dibuka. */
.bagian-lipat > summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s3);
  min-height: var(--tap); cursor: pointer; list-style: none;
}
.bagian-lipat > summary::-webkit-details-marker { display: none; }
.bagian-lipat > summary::before {
  content: ""; flex: none; width: 0.45em; height: 0.45em; margin: 0 2px;
  border-right: 2px solid var(--ink-2); border-bottom: 2px solid var(--ink-2); transform: rotate(-45deg);
}
.bagian-lipat[open] > summary::before { transform: rotate(45deg); }
.bagian-lipat__judul { min-width: 0; }
.bagian-lipat__ringkas { min-width: 0; color: var(--ink-2); font-size: var(--text-sm); }
.bagian-lipat__aksi { margin-left: auto; color: var(--primary); font-weight: 500; font-size: var(--text-sm); }
.bagian-lipat > summary:hover .bagian-lipat__aksi { color: var(--primary-hover); text-decoration: underline; text-underline-offset: 3px; }
.bagian-lipat__tutup, .bagian-lipat[open] .bagian-lipat__buka { display: none; }
.bagian-lipat[open] .bagian-lipat__tutup { display: inline; }
.bagian-lipat__isi > :first-child { margin-top: var(--s2); }

/* Tabel ringkas (3-5 kolom): selebar isinya (maks. +-48rem), angka tidak jauh dari labelnya. */
.table-wrap:has(> .table--ringkas) { max-width: 48rem; }
/* Tabel isian: isian di dalam sel, satuan/petunjuk sekali di kepala kolom, total berjalan di tfoot. */
.table--isian td { vertical-align: baseline; }
/* Isian di sel selebar angkanya (bukan seluruh kolom); di kolom angka (td.num) rata kanan. */
.table--isian td > .input { display: block; width: 100%; min-width: 5rem; max-width: 9rem; }
.table--isian td.num > .input { margin-left: auto; }
.table--isian .input[inputmode="decimal"], .table--isian .input[inputmode="numeric"] { text-align: right; }
.table--isian .field__error { margin-top: 2px; white-space: normal; }
/* Tablet: kolom aksi tabel lengket di kanan saat tabel digulir ke samping (<th class="actions"> + td.actions). Kolom lengket
   menutupi kolom di bawahnya selama tabel belum digulir, jadi tabel kartu dirancang muat di 640 px (sedikit kolom, keterangan
   di .sel-ket) agar chip status tidak tertutup (dicek tests/browser/layout-check.js); kepala kolom boleh dua baris. */
@media (min-width: 640px) and (max-width: 1023.98px) {
  .table--kartu :is(th, td).actions { position: sticky; right: 0; background: var(--surface); box-shadow: -1px 0 0 var(--line); }
  .table--kartu thead th { white-space: normal; }
}
/* HP: setiap baris tabel kartu/isian menjadi kartu; label diambil dari td[data-label]; sel pertama = judul kartu. */
@media (max-width: 639.98px) {
  .table-wrap:has(> .table--kartu), .table-wrap:has(> .table--isian) { background: none; border: 0; overflow: visible; }
  .table--kartu, .table--isian, .table--kartu tbody, .table--isian tbody, .table--kartu tfoot, .table--isian tfoot { display: block; }
  .table--kartu thead, .table--isian thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0;
  }
  .table--kartu tr, .table--isian tr {
    display: block; padding: var(--s2) var(--s4); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  }
  .table--kartu tr + tr, .table--isian tr + tr, .table--kartu tbody + tfoot, .table--isian tbody + tfoot { margin-top: var(--s2); }
  .table--kartu tbody tr:hover td, .table--isian tbody tr:hover td { background: none; }
  .table--kartu td, .table--isian td {
    display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3);
    padding: 3px 0; border: 0; text-align: right; white-space: normal;
  }
  .table--kartu td::before, .table--isian td::before {
    content: attr(data-label); flex: none; max-width: 45%; text-align: left; color: var(--ink-2); font-size: var(--text-xs); font-weight: 500;
  }
  .table--kartu td:first-child, .table--isian td:first-child { display: block; text-align: left; font-weight: 700; font-size: var(--text-md); }
  .table--kartu td:first-child::before, .table--isian td:first-child::before,
  .table--kartu td.actions::before, .table--isian td.actions::before,
  .table--kartu td:not([data-label])::before, .table--isian td:not([data-label])::before { content: none; }
  .table--kartu td.actions, .table--isian td.actions { justify-content: flex-start; flex-wrap: wrap; gap: var(--gap-tap); padding-top: var(--s2); text-align: left; }
  .table--kartu td:empty, .table--isian td:empty { display: none; }
  /* Teks panjang (<td class="sel-teks" data-label="...">): label di atas, teks rata kiri selebar kartu. */
  .table--kartu td.sel-teks { display: block; text-align: left; }
  .table--kartu td.sel-teks::before { display: block; max-width: none; margin-bottom: 2px; }
  /* Isian: label di atas isian selebar kartu. */
  .table--isian td:has(.input) { display: grid; justify-content: stretch; gap: 2px; text-align: left; }
  .table--isian td:has(.input)::before { max-width: none; }
  .table--isian td > .input { width: 100%; max-width: none; }
}

/* ---------- Detail pasien ---------- */
.facts { display: grid; gap: var(--s3) var(--s5); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); margin: 0; }
.facts dt { font-size: var(--text-sm); color: var(--ink-2); }
.facts dd { margin: 0; font-weight: 500; overflow-wrap: anywhere; }
.facts > .facts__penuh { grid-column: 1 / -1; }
.allergy { margin-bottom: var(--s4); }

/* ---------- Paginasi ---------- */
.pager { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); margin-top: var(--s4); flex-wrap: wrap; }

/* ---------- Halaman login ---------- */
.auth { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: var(--s5) var(--page-pad); }
.auth__box { width: 100%; max-width: 400px; }
.auth__brand { margin-bottom: var(--s5); }
.auth__brand p { color: var(--ink-2); margin-top: var(--s1); }
.auth__footer { margin-top: var(--s5); color: var(--muted); font-size: var(--text-sm); }
.auth__footer > p + p { margin-top: var(--s2); }
/* Verifikasi dua langkah: username yang baru diketik, lalu aksi teks di bawah form (teksnya rata dengan tepi form). */
.auth__akun { font-size: var(--text-sm); overflow-wrap: anywhere; }
.auth__aksi { display: flex; flex-wrap: wrap; gap: 0 var(--s3); margin: var(--s3) calc(-1 * var(--s2)) 0; }
.auth__aksi form { margin: 0; }

/* ---------- Akun saya & verifikasi dua langkah ---------- */
/* Nama akun di topbar = tautan ke Akun saya (satu-satunya jalan ke sana di desktop selain spanduk): warna teks topbar
   dengan garis bawah tipis, lebih tegas saat disorot/aktif. Satu baris (nama panjang dipotong "…"): tinggi topbar tetap. */
.topbar__akun {
  display: inline-block; max-width: min(48ch, 40vw); min-height: var(--tap); line-height: var(--tap); vertical-align: middle;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: inherit;
  text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px;
}
.topbar__akun:hover, .topbar__akun[aria-current="page"] { color: var(--ink); text-decoration-color: currentColor; }
/* Halaman Akun saya: satu lebar isi, selebar form (880px). */
.akun { max-width: 880px; }
.akun-judul { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s3); }
.akun-catatan { margin-top: var(--s4); }
/* Bagian form 2FA yang dituju fragmen setelah ditolak (#dua-langkah, #ganti-hp, ...): tidak menempel di tepi atas layar. */
.akun [data-fokus-galat] { scroll-margin-top: var(--s3); }
/* Halaman aktivasi: tiga langkah bernomor di judulnya (bukan nomor daftar), selebar form. */
.langkah-aktivasi { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); max-width: 880px; }
/* Kode QR: SVG hitam di atas putih dengan zona tenang sendiri, tetap putih di tema apa pun (terbaca kamera HP). */
.qr-kode { display: block; width: min(100%, 240px); height: auto; margin-top: var(--s3); background: #fff; border: 1px solid var(--border); border-radius: var(--radius); }
/* Kunci teks: kelompok 4 huruf (dipisah spasi agar mudah diketik ulang), boleh membungkus di antara kelompok. */
.kunci-rahasia {
  margin-top: var(--s2); padding: var(--s3) var(--s4);
  background: var(--row-hover); border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-size: var(--text-lg); word-spacing: .25em; overflow-wrap: anywhere; user-select: all;
}
.akun-otpauth { margin-left: calc(-1 * var(--s2)); text-align: left; }
/* Tautan ke aplikasi autentikator: di HP paling atas langkah 2 (halaman dibuka di HP yang sama dengan aplikasinya, kode QR
   tidak bisa dipindai), di layar lebar di bawah kode QR & kunci. */
.akun-otpauth-hp { display: none; }
@media (max-width: 639.98px) {
  .akun-otpauth-hp { display: block; }
  .akun-otpauth-lebar { display: none; }
}
/* Kode pemulihan: dua kolom (1-5 | 6-10) bila muat, satu kolom di HP; huruf mono besar agar tidak salah baca. */
.kode-pemulihan { max-width: 880px; }
.kode-pemulihan__daftar { margin: 0; padding-left: 2.25em; columns: 2 12rem; column-gap: var(--s7); font-size: var(--text-lg); line-height: 1.9; }
@media print {
  .kode-pemulihan { border-color: #000; }
  .main > .alert { color: #000; background: #fff; border-color: #000; }
  /* Pesan "berhasil" layout tidak ikut tercetak bersama kode. */
  .main:has(.kode-pemulihan) > .alert--success { display: none; }
}

/* ---------- Petunjuk & nomor versi ---------- */
/* Tautan "Petunjuk" di topbar (desktop): gaya sama dengan nama akun di sebelahnya, target sentuh setinggi --tap. */
.topbar__petunjuk {
  display: inline-block; min-height: var(--tap); line-height: var(--tap); white-space: nowrap; color: inherit;
  text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px;
}
.topbar__petunjuk:hover, .topbar__petunjuk[aria-current="page"] { color: var(--ink); text-decoration-color: currentColor; }
/* Isi petunjuk: pintasan ke setiap tahap alur (membungkus di HP), lalu kartu per menu (dua kolom di layar lebar). */
.petunjuk-isi__daftar { list-style: none; margin: 0 0 var(--s2); padding: 0; display: flex; flex-wrap: wrap; gap: 0 var(--s4); }
.petunjuk-isi__daftar a { display: inline-flex; align-items: center; min-height: var(--tap); }
.petunjuk-kelompok { scroll-margin-top: var(--s3); }
.petunjuk-grid { display: grid; gap: var(--s3); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .petunjuk-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.petunjuk { display: flex; flex-direction: column; gap: var(--s2); }
.petunjuk h3 { margin: 0; font-size: var(--text-md); }
.petunjuk__langkah { margin: 0; padding-left: 1.4em; display: grid; gap: var(--s1); max-width: 70ch; }
.petunjuk__catatan { margin: 0; max-width: 70ch; }
.petunjuk__kaki { margin: auto 0 0; }
.petunjuk__kaki a { display: inline-flex; align-items: center; min-height: var(--tap); }
/* Nomor versi: kecil & redup, tidak mengganggu isi (Menu, Akun saya, Petunjuk; kaki menu samping desktop). */
.versi-aplikasi { font-size: var(--text-xs); color: var(--muted); overflow-wrap: anywhere; }
.nav__versi { display: none; }
@media (min-width: 1024px) {
  /* Paling redup yang masih lolos kontras teks 4,5:1 di latar putih menu samping; 11px, di bawah --text-xs. */
  .nav__versi { display: block; margin: var(--s4) 10px var(--s2); font-size: 0.6875rem; color: var(--samar); }
}

/* ---------- Halaman error ---------- */
.error-page { max-width: 560px; }
.error-page .actions { margin-top: var(--s5); display: flex; gap: var(--gap-tap); flex-wrap: wrap; }

/* ---------- Cetak (§6) ---------- */
@media print {
  body { background: #fff; color: #000; }
  .nav, .topbar, .skip-link, .no-print, .pager, .search, .catatan__tombol { display: none !important; }
  .app { display: block; }
  .main { padding: 0; max-width: none; }
  .panel, .data-list { border-color: #000; }
  .panel, .data-list, .table-wrap, .widgets, .menu-tile { box-shadow: none; }
  a { color: #000; text-decoration: none; }
}
