:root {
    --color-primary: #1D4ED8;
    --color-primary-dark: #1E3A8A;
    --color-success: #22C55E;
    --color-warning: #F59E0B;
    --color-danger: #EF4444;
    --color-gray: #6B7280;
    --color-bg: #F3F4F6;
    --color-white: #FFFFFF;
    --color-border: #E5E7EB;
    --font-base: 14px;
    --sidebar-width: 240px;
    --sidebar-width-collapsed: 56px;
}

* { box-sizing: border-box; }

/* ===== Skala tampilan halaman admin =====
   Seluruh CSS di file ini memakai ukuran piksel absolut, bukan rem, jadi tidak ada satu
   variabel font yang bisa memperkecil halaman -- padahal di layar laptop tampilannya
   kebesaran dan user berakhir menekan Ctrl+- di setiap halaman. Satu `zoom` di elemen root
   memperkecil SEMUANYA sekaligus (header, sidebar, tabel, grafik, modal) persis seperti page
   zoom browser, tanpa harus menyisir ratusan nilai px satu per satu.

   Hanya dipasang di .app-admin -- class di <html> milik app/Views/layouts/header.php. File
   ini dipakai juga oleh ESS dan halaman login yang punya <html> sendiri, dan ESS dibuka di
   layar HP, di mana teks 15% lebih kecil justru menyusahkan.

   --ui-zoom BUKAN sekadar dokumentasi: assets/js/app.js membacanya lewat Hris.uiZoom() untuk
   mengubah koordinat viewport (getBoundingClientRect/clientX -- keduanya sudah ikut terskala)
   kembali ke koordinat lokal sebelum ditulis ke style.left/style.width. Kalau angka di sini
   diubah, JS ikut menyesuaikan sendiri; kalau dihapus, JS jatuh ke 1 dan tetap benar. */
:root { --ui-zoom: 1; }
.app-admin { --ui-zoom: .85; zoom: var(--ui-zoom); }

/* Matikan penyesuaian ukuran teks otomatis milik browser mobile (Chrome/Samsung Internet
   "font boosting"): ia membesarkan font di sebagian perangkat tanpa membesarkan kotaknya,
   sehingga teks meluber dari tombol/kolom. Ini TIDAK mematikan setelan ukuran font milik
   pengguna di level sistem, hanya heuristik otomatis browser. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
    font-size: var(--font-base);
    background: var(--color-bg);
    color: #111827;
}

/* ===== Layout ===== */
.app-header {
    height: 60px;
    background: var(--color-white);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
}
.app-header .brand { font-weight: 700; color: var(--color-primary-dark); font-size: 18px; }
.header-title {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: #111827;
    max-width: 50%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: center;
}
.app-header .user-menu { display: flex; align-items: center; gap: 12px; }
.session-countdown {
    font-size: 12px;
    font-weight: 600;
    color: var(--color-gray);
    font-variant-numeric: tabular-nums;
    padding: 3px 8px;
    border-radius: 6px;
    background: #f3f4f6;
}
.session-countdown.session-countdown-warning {
    color: #b45309;
    background: #fef3c7;
}
.session-countdown.session-countdown-danger {
    color: #dc2626;
    background: #fee2e2;
}
.app-header .user-menu button {
    background: var(--color-danger); color: #fff; border: none;
    padding: 6px 14px; border-radius: 6px; cursor: pointer; font-size: 13px;
}
.app-header .user-menu a.btn { display: inline-block; text-decoration: none; }

/* ===== Sidebar (kiri) — sebelumnya top dropdown flyout, dikembalikan ke sidebar kiri
   sesuai permintaan. Interaksi accordion (klik expand/collapse), bukan lagi hover-flyout,
   karena sidebar kiri statis tidak butuh positioning fixed yang dihitung JS seperti nav
   horizontal sebelumnya. ===== */
.app-sidebar {
    position: fixed;
    top: 60px; left: 0; bottom: 0;
    width: var(--sidebar-width);
    background: var(--color-white);
    border-right: 1px solid var(--color-border);
    overflow-y: auto;
    padding: 4px 0 16px;
    z-index: 90;
}
.sidebar-nav { display: flex; flex-direction: column; }

.sidebar-link, .sidebar-group-toggle {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 7px 16px;
    color: #374151;
    text-decoration: none;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.3;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}
.sidebar-group-toggle { justify-content: space-between; }
.sidebar-group-toggle .sidebar-label { flex: 1; }
.sidebar-icon { font-size: 13px; width: 16px; text-align: center; flex-shrink: 0; }

.sidebar-link:hover, .sidebar-link.active,
.sidebar-group-toggle:hover, .sidebar-group-toggle.active {
    background: #EFF6FF;
    color: var(--color-primary);
    border-left-color: var(--color-primary);
}

.nav-caret {
    width: 0; height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    opacity: .6;
    transition: transform .15s ease;
    flex-shrink: 0;
}

/* Submenu dibuka KE SAMPING (kanan), bukan ke bawah — baik level 1 (langsung dari
   sidebar) maupun level 2 (nested, mis. Migration/Shift/Attendance). Posisi dihitung JS
   (lihat positionFlyout() di app.js) berdasar posisi tombol toggle-nya, sama seperti
   pola flyout yang dipakai top-nav sebelumnya, hanya arahnya sekarang ke kanan bukan
   ke bawah. */
.sidebar-submenu {
    display: none;
    position: fixed;
    min-width: 220px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 8px 20px rgba(17,24,39,.12);
    padding: 4px 0;
    z-index: 150;
}
.sidebar-group.open > .sidebar-submenu { display: block; }
.sidebar-submenu a {
    display: block;
    padding: 6px 16px;
    color: #374151;
    text-decoration: none;
    font-size: 13px;
    border-left: 3px solid transparent;
}
.sidebar-submenu a:hover, .sidebar-submenu a.active { background: #EFF6FF; color: var(--color-primary); border-left-color: var(--color-primary); }

/* ===== Nested (2nd level) — flyout lagi ke kanan dari flyout level 1 ===== */
.nav-subdropdown { position: relative; }
.nav-subdropdown-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: transparent;
    border: none;
    border-left: 3px solid transparent;
    padding: 6px 16px;
    color: #374151;
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}
.nav-subdropdown-toggle:hover,
.nav-subdropdown-toggle.active,
.nav-subdropdown.open > .nav-subdropdown-toggle {
    background: #EFF6FF;
    color: var(--color-primary);
    border-left-color: var(--color-primary);
}
.nav-caret-right {
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 5px solid currentColor;
    border-right: none;
    opacity: .6;
    flex-shrink: 0;
}

.nav-submenu {
    display: none;
    position: fixed;
    min-width: 200px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 8px 20px rgba(17,24,39,.12);
    padding: 4px 0;
    z-index: 160;
}
.nav-subdropdown.open > .nav-submenu { display: block; }

/* ===== Sidebar ciut (ikon saja) =====
   Class .sidebar-collapsed dipasang di <html> -- BUKAN di .app-sidebar -- supaya
   .content-area (yang bukan turunan sidebar) ikut menyesuaikan margin kirinya lewat
   selector yang sama, dan supaya guard sinkron di <head> bisa memasangnya sebelum
   halaman tergambar (lihat assets/js/sidebar-menu.js). Tanpa itu sidebar sempat tampil
   lebar lalu menciut di depan mata setiap kali pindah halaman.

   Submenu-nya TIDAK butuh aturan baru: flyout ke kanan + hover sudah jadi perilaku
   bawaan sidebar ini sejak dulu (positionSidebarFlyout() di app.js). Yang berubah cuma
   lebar sidebar dan label yang disembunyikan. */
.sidebar-collapsed .app-sidebar { width: var(--sidebar-width-collapsed); }
.sidebar-collapsed .content-area { margin-left: var(--sidebar-width-collapsed); }

/* Label & caret hilang, ikon dipusatkan. visibility tidak dipakai: elemennya harus
   benar-benar keluar dari alur supaya tombol tidak menyisakan lebar teks yang kosong. */
.sidebar-collapsed .sidebar-label,
.sidebar-collapsed .sidebar-nav .nav-caret { display: none; }
.sidebar-collapsed .sidebar-link,
.sidebar-collapsed .sidebar-group-toggle {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
    gap: 0;
}
.sidebar-collapsed .sidebar-collapse-toggle { justify-content: center; }
.sidebar-collapsed .sidebar-collapse-icon { transform: rotate(180deg); }

/* Judul grup ikut dibawa ke dalam flyout saat ciut -- tanpa ini yang terlihat cuma
   deretan item tanpa keterangan grupnya, dan ikon saja tidak cukup untuk membedakan
   mana Payroll mana Performance. Diisi sidebar-menu.js dari label tombolnya. */
.sidebar-flyout-title {
    display: none;
    padding: 6px 16px 7px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--color-border);
    font-size: 12px;
    font-weight: 700;
    color: var(--color-primary-dark);
}
.sidebar-collapsed .sidebar-flyout-title { display: block; }

.sidebar-collapse-toggle {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 16px;
    margin-bottom: 2px;
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-gray);
    font-family: inherit;
    font-size: 12px;
    cursor: pointer;
    text-align: left;
}
.sidebar-collapse-toggle:hover { color: var(--color-primary); background: #EFF6FF; }
.sidebar-collapse-icon { font-size: 14px; width: 16px; text-align: center; flex-shrink: 0; transition: transform .15s ease; }

/* ===== Favorites / Sering Dibuka =====
   Sekarang SATU grup yang membuka flyout ke samping (kerangkanya di sidebar.php), bukan
   lagi deretan link di badan sidebar: favorit yang banyak dulu mendorong seluruh menu
   utama ke bawah, sampai fitur penghemat tempat ini justru yang paling boros tempat.
   Tampilannya karena itu mewarisi .sidebar-group/.sidebar-submenu apa adanya -- yang
   tersisa di sini cuma garis pemisah dari menu di bawahnya dan aturan kosong. */
.sidebar-favorites-group.is-empty { display: none; }
.sidebar-favorites-group { border-bottom: 1px solid var(--color-border); padding-bottom: 4px; margin-bottom: 4px; }
/* Label favorit dipotong dengan ellipsis, bukan dibungkus ke baris kedua: daftar ini
   dibaca sekilas, dan label panjang seperti "Overtime Payroll Gap Report" yang memakan
   tiga baris membuat flyout-nya jauh lebih tinggi daripada isinya. */
.sidebar-favorites-group .nav-item-row > a {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ===== Menu yang disembunyikan sendiri user (Profil -> Preferensi Menu) =====
   Class, bukan style.display seperti filter permission di sidebar.php: dua filter yang
   menulis properti inline yang sama akan saling menghapus. !important supaya menang atas
   style.display="" yang dipasang filter permission pada elemen yang sama. */
.menu-user-hidden { display: none !important; }

/* ===== Tombol bintang di tiap item submenu ===== */
.nav-item-row { display: flex; align-items: center; }
.nav-item-row > a { flex: 1; min-width: 0; }
.nav-fav-toggle {
    flex-shrink: 0;
    /* visibility, BUKAN display: tombolnya tetap memesan tempat walau belum terlihat,
       jadi teks menu tidak bergeser sedikit ke kiri tiap kali kursor lewat. */
    visibility: hidden;
    background: transparent;
    border: none;
    padding: 2px 10px 2px 4px;
    font-size: 14px;
    line-height: 1;
    color: #9CA3AF;
    cursor: pointer;
}
.nav-item-row:hover .nav-fav-toggle,
.nav-fav-toggle:focus-visible,
.nav-fav-toggle.is-favorite { visibility: visible; }
.nav-fav-toggle.is-favorite { color: #F59E0B; }
.nav-fav-toggle:hover { color: #F59E0B; }

.content-area {
    margin-left: var(--sidebar-width);
    margin-top: 60px;
    padding: 24px;
    min-height: calc(100vh - 60px);
}

/* ===== Tab workspace =====
   Baris tab di atas area konten (app/Views/layouts/tabstrip.php), diisi
   assets/js/tab-workspace.js. Ikut pola header & sidebar: position:fixed, jadi baris ini
   tetap terlihat saat halaman digulir -- satu-satunya penanda "halaman apa saja yang
   sedang saya buka" di dokumen yang tidak pernah dimuat ulang.

   z-index 80, SATU TINGKAT DI BAWAH sidebar (90): di layar kecil sidebar berubah jadi
   laci yang menutupi konten, dan laci itu harus lewat di ATAS baris tab. */
.workspace-tabs {
    position: fixed;
    top: 60px;
    left: var(--sidebar-width);
    right: 0;
    height: 40px;
    background: var(--color-white);
    border-bottom: 1px solid var(--color-border);
    z-index: 80;
    display: flex;
    align-items: stretch;
    overflow: hidden;
}
.workspace-tabs[hidden] { display: none; }
.sidebar-collapsed .workspace-tabs { left: var(--sidebar-width-collapsed); }

.workspace-tabs-strip {
    display: flex;
    align-items: stretch;
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}
.workspace-tabs-strip::-webkit-scrollbar { height: 4px; }
.workspace-tabs-strip::-webkit-scrollbar-thumb { background: #CBD5E1; border-radius: 2px; }

/* Bentuk chamfer: kedua sisi dipotong miring melebar ke bawah, seperti tab folder.
   clip-path (bukan border-radius) karena yang diminta sudut terpotong LURUS, bukan
   membulat. Bidang miringnya memakan 10px di tiap sisi atas, jadi padding kiri/kanan
   dinaikkan dari 12px ke 20px supaya ikon & label tidak menabrak bidang itu.

   Konsekuensi yang disengaja: border-right pemisah DIHAPUS -- clip-path memotong border
   juga, jadi yang tersisa cuma potongan garis miring yang terlihat seperti cacat render.
   Pemisahnya sekarang jarak 2px + warna latar tab non-aktif yang lebih gelap dari area
   konten. clip-path juga memotong hit-test, jadi klik di luar bentuk (segitiga antar tab)
   memang tidak mengenai tab mana pun -- tidak perlu pengaturan z-index tambahan. */
.workspace-tab {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 220px;
    padding: 0 20px;
    margin-right: 2px;
    border: 0;
    background: #EEF1F5;
    color: var(--color-gray);
    font-family: inherit;
    font-size: 13px;
    white-space: nowrap;
    cursor: pointer;
    clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 100%, 0 100%);
}
.workspace-tab:hover { background: #E2E8F0; color: #111827; }
.workspace-tab.active { background: var(--color-white); color: #111827; font-weight: 600; }

/* Ikon menu di kiri label, diambil dari ikon grup sidebar oleh tab-workspace.js.
   line-height:1 supaya emoji tidak menaikkan tinggi baris tab yang sudah dipatok 40px. */
.workspace-tab-icon {
    flex: 0 0 auto;
    font-size: 14px;
    line-height: 1;
}

/* Garis bawah penanda tab aktif. bottom:0 (bukan -1px) karena .workspace-tabs memakai
   overflow:hidden -- apa pun yang melewati tepi bawah akan terpotong tanpa jejak.
   Melebar penuh selebar SISI BAWAH tab (sisi terlebar dari bentuk chamfer), jadi tidak
   ikut terpotong clip-path. */
.workspace-tab.active::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--color-primary);
}

.workspace-tab-label { overflow: hidden; text-overflow: ellipsis; }

.workspace-tab-close {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    line-height: 15px;
    text-align: center;
    border-radius: 4px;
    color: #9CA3AF;
    font-size: 15px;
}
.workspace-tab-close:hover { background: #FEE2E2; color: var(--color-danger); }

/* Klik menu yang tabnya SUDAH terbuka tidak memuat apa pun -- tanpa penanda, layarnya
   tampak tidak bereaksi sama sekali. Tab yang bersangkutan berkedip sebentar. */
@keyframes workspace-tab-refocus {
    0%, 100% { background: var(--color-white); }
    35%      { background: #DBEAFE; }
}
.workspace-tab.is-refocus { animation: workspace-tab-refocus .6s ease; }

/* Halaman berikutnya sedang diambil. Sengaja setipis ini: perpindahan tab biasanya
   selesai dalam ratusan milidetik, dan indikator yang lebih besar justru berkedip. */
.workspace-tabs.is-loading::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--color-primary), transparent);
    animation: workspace-tab-loading 1s linear infinite;
}
@keyframes workspace-tab-loading {
    from { transform: translateX(-100%); }
    to   { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
    .workspace-tab.is-refocus { animation: none; background: #DBEAFE; }
    .workspace-tabs.is-loading::before { animation: none; }
}

/* Class dipasang sinkron di <head> (app/Views/layouts/header.php), bukan oleh JS `defer`,
   supaya konten tidak tersentak turun setelah halaman tergambar. Specificity-nya sengaja
   satu tingkat di atas .content-area polos supaya override mobile di bawah tidak
   mengembalikannya ke 60px. */
.has-workspace-tabs .content-area { margin-top: 100px; min-height: calc(100vh - 100px); }

.app-footer {
    margin-left: 240px;
    padding: 16px 24px;
    color: var(--color-gray);
    font-size: 12px;
    border-top: 1px solid var(--color-border);
}

.page-title { font-size: 20px; font-weight: 700; margin: 0 0 4px; }
/* Breadcrumb DISEMBUNYIKAN, bukan dihapus dari markup.
   Sejak baris tab workspace ada di atas area konten, jalur menu sudah terwakili dua kali:
   nama halaman ada di tab yang sedang aktif DAN di judul tengah header, ditambah menu yang
   tersorot di sidebar. Barisnya jadi pengulangan yang cuma memakan tinggi layar.

   Disembunyikan lewat satu aturan di sini karena markupnya tersebar di 80 view, sedangkan
   deploy ke produksi dilakukan upload manual per file -- menghapusnya satu-satu berarti 80
   berkas naik satu per satu, dan halaman yang belum kebagian akan tampil beda dari yang
   sudah. Kalau suatu saat breadcrumb dibutuhkan lagi, cukup hapus aturan ini.

   CATATAN: class ini juga dipakai baris sapaan "Selamat datang di HRIS" di
   app/Views/dashboard/index.php, jadi baris itu ikut hilang -- disengaja. Class .breadcrumb
   tidak dipakai satu pun halaman ESS, jadi ESS tidak terpengaruh sama sekali. */
.breadcrumb { display: none; }

/* ===== Fallback untuk halaman custom (non-generic-CRUD) — class ini dipakai luas di
   Attendance/Shift/Overtime/Payroll/Leave & Permission/Performance/Employee (Mutation,
   Promotion, Contract, Resignation, Retirement) tapi sebelumnya TIDAK PERNAH didefinisikan
   sama sekali, membuat halaman-halaman itu render nyaris tanpa styling: judul+tombol
   berantakan, tabel tanpa border/padding, modal detail persetujuan tidak ke-resize besar,
   dan "Approval Widget" (riwayat approval bertingkat) yang diwajibkan ui_guideline.md §3
   tampil sebagai teks polos tanpa bentuk timeline sama sekali. */
.page-header { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }

.data-table { width: 100%; border-collapse: collapse; background: var(--color-white); border: 1px solid var(--color-border); border-radius: 10px; }
.data-table th, .data-table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--color-border); font-size: 13px; }
.data-table th { background: #F9FAFB; color: #374151; font-weight: 600; }
.data-table tr:last-child td { border-bottom: none; }

.modal-box.modal-lg { width: 720px; max-width: 95vw; }

.form-hint { color: var(--color-gray); font-size: 12px; margin: -8px 0 12px; }

/* Approval Widget (timeline riwayat approval bertingkat) */
.approval-timeline { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 18px; }
.timeline-item {
    position: relative; padding: 10px 14px 10px 30px; background: #F9FAFB;
    border: 1px solid var(--color-border); border-radius: 8px; font-size: 13px;
}
.timeline-item::before {
    content: ''; position: absolute; left: 12px; top: 15px; width: 9px; height: 9px;
    border-radius: 50%; background: var(--color-gray);
}
.timeline-item.approved::before, .timeline-item.cleared::before { background: var(--color-success); }
.timeline-item.rejected::before { background: var(--color-danger); }
.timeline-item.pending::before { background: var(--color-warning); }
.timeline-item small { color: var(--color-gray); display: block; margin-top: 2px; }

/* ===== Card / Table ===== */
.card { background: var(--color-white); border: 1px solid var(--color-border); border-radius: 10px; padding: 20px; }
.card + .card { margin-top: 16px; }
.section-title { font-size: 15px; font-weight: 700; margin: 0; }

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px 18px;
    margin-bottom: 4px;
}

.form-section-title {
    font-size: 14px;
    font-weight: 700;
    color: #111827;
    margin: 24px 0 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--color-border);
}
.form-section-title:first-child { margin-top: 0; }
.required-mark { color: #dc2626; }
.form-actions-sticky {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
    position: sticky;
    bottom: 0;
    background: #fff;
}

.toggle-switch-label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-weight: 600;
    font-size: 14px;
    color: #111827;
}
.toggle-switch { position: relative; display: inline-block; width: 42px; height: 24px; flex-shrink: 0; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.toggle-switch-slider {
    position: absolute; inset: 0; background: #D1D5DB; border-radius: 999px;
    transition: background-color .15s ease;
}
.toggle-switch-slider::before {
    content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px;
    background: #fff; border-radius: 50%; transition: transform .15s ease;
    box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
.toggle-switch input:checked + .toggle-switch-slider { background: var(--color-primary); }
.toggle-switch input:checked + .toggle-switch-slider::before { transform: translateX(18px); }

.inline-add-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px dashed var(--color-border);
}
.inline-add-form .form-group { margin-bottom: 0; min-width: 160px; flex: 1; }
.inline-add-form button { flex-shrink: 0; }
.toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; gap: 12px; flex-wrap: wrap; }
.toolbar input[type="text"] {
    padding: 8px 12px; border: 1px solid var(--color-border); border-radius: 6px; min-width: 240px;
}
.toolbar-filters { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; }
.toolbar-filters select {
    padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 13px; background: #fff;
}
.btn {
    padding: 8px 16px; border-radius: 6px; border: none; cursor: pointer; font-size: 13px; font-weight: 600;
}
.btn-primary { background: var(--color-primary); color: #fff; }
.btn-primary:hover { background: var(--color-primary-dark); }
.btn-danger { background: var(--color-danger); color: #fff; }
.btn-secondary { background: #fff; border: 1px solid var(--color-border); color: #374151; }
.btn-sm { padding: 4px 10px; font-size: 12px; }
/* Tombol ikon (Edit/Hapus/Reset PIN/Reset Password di Master User) -- persegi, simbol
   di tengah, tooltip-nya pakai title= native (bukan .has-tooltip, itu untuk teks). */
.btn-icon { min-width: 30px; padding: 4px 8px; font-size: 14px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }

table { width: 100%; border-collapse: collapse; }
table th, table td {
    text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--color-border); font-size: 13px;
}
table th { background: #F9FAFB; color: #374151; font-weight: 600; }

/* Kolom tabel yang bisa di-resize manual (Hris.makeColumnsResizable(), pola Excel) --
   dipakai tabel preview lebar mis. Migrasi Data Karyawan (26 kolom). Selector dibatasi
   ke [data-resizable-init="1"] (flag yang di-set JS saat init) supaya TIDAK mempengaruhi
   tabel lain yang tidak pakai fitur ini. */
table[data-resizable-init="1"] th {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.col-resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    user-select: none;
    z-index: 2;
}
.col-resize-handle:hover,
body.col-resizing .col-resize-handle {
    background: #93C5FD;
}
body.col-resizing {
    cursor: col-resize;
    user-select: none;
}
/* Freeze kolom kiri (Hris.makeColumnsResizable(table, freezeCount), pola Excel Freeze
   Panes) -- kolom ke-1 s.d. ke-4 paling kiri "dibekukan" tetap terlihat saat tabel
   digeser ke kanan. Offset --freeze-left-N dihitung & di-update JS (lihat app.js),
   BUKAN nilai tetap, karena lebar tiap kolom bisa berubah kapan saja lewat resize
   manual. Cuma sampai kolom ke-4 -- cukup untuk kebutuhan saat ini (checkbox/#/No.
   Karyawan/Nama di Preview Migrasi Data Karyawan); tambah nth-child(5) dst kalau nanti
   ada tabel lain yang butuh membekukan lebih dari 4 kolom.
   Background WAJIB solid (bukan transparan) -- elemen sticky tanpa background akan
   "ditembus" oleh konten yang discroll di baliknya. */
table.frozen-cols th:nth-child(1), table.frozen-cols td:nth-child(1) { position: sticky; left: var(--freeze-left-1, 0); z-index: 3; }
table.frozen-cols th:nth-child(2), table.frozen-cols td:nth-child(2) { position: sticky; left: var(--freeze-left-2, 0); z-index: 3; }
table.frozen-cols th:nth-child(3), table.frozen-cols td:nth-child(3) { position: sticky; left: var(--freeze-left-3, 0); z-index: 3; }
table.frozen-cols th:nth-child(4), table.frozen-cols td:nth-child(4) { position: sticky; left: var(--freeze-left-4, 0); z-index: 3; }
table.frozen-cols td:nth-child(1),
table.frozen-cols td:nth-child(2),
table.frozen-cols td:nth-child(3),
table.frozen-cols td:nth-child(4) { background: #fff; }
table.frozen-cols th:nth-child(1),
table.frozen-cols th:nth-child(2),
table.frozen-cols th:nth-child(3),
table.frozen-cols th:nth-child(4) { background: #F9FAFB; z-index: 4; }
/* Garis pemisah tipis di pinggir kanan area beku -- penanda visual "mulai dari sini
   scroll", pola sama Excel. */
table.frozen-cols th:nth-child(4),
table.frozen-cols td:nth-child(4) {
    box-shadow: 2px 0 4px rgba(0, 0, 0, 0.08);
}
/* Card yang isinya tabel lebar (kolom di-resize bisa total melebihi lebar layar) perlu
   scroll horizontal sendiri di desktop -- .card baru punya overflow-x:auto bawaan di
   breakpoint mobile, jadi ditambah scoped ke card ini spesifik. */
#ei-preview-card {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.text-right { text-align: right; }
.text-muted { color: var(--color-gray); font-size: 12px; }
.actions-cell { display: flex; gap: 6px; justify-content: flex-end; }

.badge { padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; display: inline-block; }
.badge-active { background: #DCFCE7; color: #15803D; }
.badge-inactive { background: #FEE2E2; color: #B91C1C; }
.badge-locked { background: #F3F4F6; color: #4B5563; }
.badge-pending { background: #FEF3C7; color: #92400E; }

/* Warna badge generik dari Master Data > Status Absensi (attendance_status_references.
   badge_color) -- dipakai Rekap Attendance untuk kolom Status, TERPISAH dari .badge-active
   dkk di atas (yang maknanya "aktif/nonaktif", bukan warna sembarang). */
.badge-color-green { background: #DCFCE7; color: #15803D; }
.badge-color-yellow { background: #FEF3C7; color: #92400E; }
.badge-color-red { background: #FEE2E2; color: #B91C1C; }
.badge-color-blue { background: #DBEAFE; color: #1D4ED8; }
.badge-color-gray { background: #F3F4F6; color: #4B5563; }

/* Angka di dalam tabel yang bisa diklik untuk membuka rincian (drill-down) -- dibuat
   tampak seperti link biasa, tapi elemennya <button> supaya tetap bisa difokus keyboard
   dan tidak butuh href palsu. Dipakai Summary Report Absensi. */
.link-button {
    background: none; border: none; padding: 0; font: inherit; cursor: pointer;
    color: var(--color-primary); text-decoration: underline; text-underline-offset: 2px;
}
.link-button:hover { color: var(--color-primary-dark, #1E3A8A); }

.has-tooltip { border-bottom: 1px dotted var(--color-gray); cursor: help; }
.btn.has-tooltip { border-bottom: none; cursor: help; }

.pagination { display: flex; gap: 6px; justify-content: flex-end; margin-top: 14px; align-items: center; }
.pagination button {
    border: 1px solid var(--color-border); background: #fff; padding: 4px 10px; border-radius: 4px; cursor: pointer;
}
.pagination button.active { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
.pagination button:disabled { opacity: .4; cursor: not-allowed; }
.pagination .pagination-ellipsis { padding: 0 4px; color: var(--color-text-muted, #6b7280); }

/* ===== Modal ===== */
.modal-overlay {
    display: none; position: fixed; inset: 0; background: rgba(17,24,39,.5);
    align-items: center; justify-content: center; z-index: 200;
}
.modal-overlay.open { display: flex; }
.modal-box {
    background: #fff; border-radius: 10px; width: 480px; max-width: 92vw; max-height: 88vh; overflow-y: auto;
    padding: 20px 24px;
}
.modal-box h3 { margin-top: 0; }
.form-group { margin-bottom: 14px; }
.form-group label { display: block; font-weight: 600; margin-bottom: 4px; font-size: 13px; }
.form-group input, .form-group select, .form-group textarea {
    width: 100%; padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 6px; font-size: 13px;
}
/* Input readonly (mis. No. Karyawan yang auto-generate) — dibuat jelas secara visual
   bukan field yang bisa diketik, selain atribut HTML readonly itu sendiri. */
.form-group input[readonly] {
    background: #F3F4F6; color: #6B7280; cursor: not-allowed;
}
/* Dua field berdampingan dalam satu baris form (mis. Tanggal Mulai + Tanggal Selesai di
   Lokasi Absen Sementara). inline-block dipilih supaya wadah .form-group biasa TIDAK perlu
   diubah jadi flex/grid -- wadah itu dipakai belasan halaman master data, dan mengubahnya
   akan menggeser tata letak semuanya. Aman karena field dirender tanpa spasi antar elemen
   (master-data-crud.js join('')), jadi tidak ada celah inline-block yang menggeser lebar. */
.form-group-half { display: inline-block; width: calc(50% - 6px); vertical-align: top; }
.form-group-half + .form-group-half { margin-left: 12px; }

.form-error { color: var(--color-danger); font-size: 12px; margin-top: 4px; }
.field-hint { color: var(--color-gray); font-size: 12px; margin-top: 4px; }

/* ===== PIN Box (kotak per digit) ================================================
   Dipakai tiga tempat: gerbang PIN Payslip/Komponen Gaji (modal yang disuntik
   Hris.ensurePinUnlocked()), halaman Set PIN Gaji, dan modal PIN absen di Home ESS.
   Ditaruh di app.css dan bukan ess.css karena modal gerbang PIN dibangun dari app.js,
   yang juga dimuat halaman admin.

   Dua kotak terakhir bergaris putus-putus selama kosong: PIN aplikasi ini boleh 4-6
   digit, dan itu satu-satunya penanda visual bahwa dua kotak sisanya opsional.

   Selektornya sengaja `.pin-box .pin-cell` dan bukan `.pin-cell` saja: di halaman Set PIN
   kotak-kotak ini berada di dalam `.ess-form`, yang punya aturan `.ess-form input`
   (ess.css) dengan `width: 100%` + `font-size: 14px`. Aturan itu lebih spesifik daripada
   `.pin-cell` tunggal dan akan melebarkan tiap kotak sampai deretannya hilang. */
.pin-box { margin: 4px 0 2px; }
/* Label di atas kotak, dipakai modal PIN absen yang bisa menampilkan dua grup sekaligus
   (PIN baru + ulangi PIN) -- tanpa label keduanya tidak bisa dibedakan. */
.pin-box-label { display: block; font-size: 12px; color: #374151; margin: 12px 0 4px; text-align: center; }
.pin-box-cells { display: flex; gap: 8px; justify-content: center; }
.pin-box .pin-cell {
    width: 44px; height: 52px; box-sizing: border-box; font: inherit; font-size: 22px;
    font-weight: 600; font-variant-numeric: tabular-nums; text-align: center; padding: 0;
    border: 1px solid var(--color-border); border-radius: 10px; background: #fff; color: #111827;
}
.pin-box .pin-cell:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px #DBEAFE; }
.pin-box .pin-cell-opt:not(.is-filled) { border-style: dashed; border-color: #D1D5DB; background: #FAFAFA; }

.pin-box-reveal {
    display: flex; align-items: center; gap: 5px; margin: 10px auto 0;
    background: none; border: none; cursor: pointer; padding: 4px;
    font: inherit; font-size: 12px; color: var(--color-gray);
}
.pin-box-reveal:hover { color: #374151; }

/* Tombol modal yang sedang disabled sebelumnya tampak persis sama dengan yang aktif --
   tidak pernah kelihatan selama satu-satunya pemakaian disabled adalah jeda singkat saat
   menyimpan. Gerbang PIN membuatnya kelihatan: tombol "Buka" mati sampai 4 digit masuk,
   dan tanpa penanda ini user mengira tombolnya rusak. Sengaja disamakan dengan
   `.pagination button:disabled` yang sudah ada di file ini. */
.modal-box .btn:disabled { opacity: .45; cursor: not-allowed; }

/* Enam kotak 44px + gap 8px butuh 304px. Di layar sempit (iPhone SE dan sejenisnya)
   angka itu tidak muat di dalam padding kartu ESS, jadi kotaknya dikecilkan daripada
   dibiarkan turun ke baris kedua -- deretan terputus menghilangkan seluruh gunanya. */
@media (max-width: 360px) {
    .pin-box-cells { gap: 6px; }
    .pin-box .pin-cell { width: 38px; height: 46px; font-size: 19px; }
}

/* ===== Time Dial (pemilih jam lingkaran 24 jam) =================================
   SATU-SATUNYA bentuk isian jam di aplikasi ini: form Lembur (admin, ESS, Entri
   Departemen) dan Input Absen Manual. Dulu ada juga kelas .time-picker-24h (sepasang
   dropdown Jam/Menit dalam pil) yang disisakan khusus untuk Input Absen Manual --
   kelas itu sudah dihapus setelah halaman tersebut ikut memakai dial ini, jadi tidak
   ada lagi dua bentuk isian jam yang berbeda untuk pekerjaan yang sama.
   Markup & perilakunya di Hris.buildTimePickerHtml(), assets/js/app.js. */
.time-dial { display: inline-flex; }
.time-dial-pill {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 7px 14px; border: 1px solid var(--color-border); border-radius: 20px;
    background: var(--color-white); color: #111827;
    font: inherit; font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums;
    cursor: pointer; transition: border-color .14s, box-shadow .14s;
}
.time-dial-pill:hover { border-color: var(--color-primary); }
.time-dial-pill.is-open {
    border-color: var(--color-primary); box-shadow: 0 0 0 3px #DBEAFE;
}
.time-dial-pill:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.time-dial-value.is-empty { color: #9CA3AF; }
.time-dial-icon { color: var(--color-gray); flex-shrink: 0; }

/* Pasangan Jam Mulai / Jam Selesai berdampingan. Label & picker adalah item grid
   langsung (baris 1 dua label, baris 2 dua picker), bukan dua kolom pembungkus --
   dengan begitu aturan label form modal & .ess-form label tetap berlaku apa adanya.
   Row-gap 0 karena jarak vertikalnya sudah datang dari margin label. */
.time-range-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 12px;
    align-items: center;
}

/* Pasangan Tanggal Mulai / Tanggal Selesai berdampingan. SENGAJA beda dari
   .time-range-row di atas: tiap tanggal dibungkus <div> sendiri dan barisnya flex,
   supaya saat satu kolom disembunyikan (form Izin ESS: izin sehari cuma punya satu
   tanggal) kolom sisanya melar penuh -- grid 1fr 1fr akan menyisakan separuh baris
   kosong. Dipakai di .ess-form, yang selector field-nya descendant (.ess-form input),
   jadi div pembungkus tidak memutus style bawaannya. */
.date-range-row { display: flex; gap: 12px; }
.date-range-row > div { flex: 1 1 0; min-width: 0; }

/* Panel di-render ke <body> dengan position: fixed -- lihat catatan di app.js
   (pemakainya termasuk sel tabel yang overflow-nya memotong elemen menggantung). */
.time-dial-panel {
    position: fixed; z-index: 1200; width: 268px; box-sizing: border-box;
    background: #fff; border: 1px solid #E5E7EB; border-radius: 16px;
    box-shadow: 0 14px 38px rgba(17, 24, 39, .2); padding: 14px 14px 10px;
}
.time-dial-head { display: flex; align-items: center; gap: 4px; }
.time-dial-seg {
    font: inherit; font-size: 30px; font-weight: 600; font-variant-numeric: tabular-nums;
    line-height: 1; padding: 5px 9px; border: none; border-radius: 9px;
    background: transparent; color: #9CA3AF; cursor: pointer;
}
.time-dial-seg.is-active { background: #DBEAFE; color: var(--color-primary); }
.time-dial-colon { font-size: 26px; font-weight: 600; color: #9CA3AF; }
.time-dial-kb {
    margin-left: auto; width: 32px; height: 32px; display: grid; place-items: center;
    border: 1px solid var(--color-border); border-radius: 8px; background: #fff;
    color: var(--color-gray); cursor: pointer;
}
.time-dial-kb.is-active { border-color: var(--color-primary); color: var(--color-primary); background: #DBEAFE; }
.time-dial-hint { font-size: 11.5px; color: var(--color-gray); margin: 4px 0 8px; min-height: 16px; }

.time-dial-face { display: block; width: 100%; height: auto; touch-action: none; cursor: pointer; }
.time-dial-face .plate { fill: #F3F4F6; }
.time-dial-face .tick { stroke: #C7CDD6; }
.time-dial-face .tick-5 { stroke: #9AA3B0; }
.time-dial-face .hand { stroke: var(--color-primary); stroke-width: 2; }
.time-dial-face .hub, .time-dial-face .knob { fill: var(--color-primary); }
.time-dial-face .knob-dot { fill: #fff; }
.time-dial-face .num {
    fill: #111827; text-anchor: middle; dominant-baseline: central;
    font-variant-numeric: tabular-nums; pointer-events: none; user-select: none;
}
.time-dial-face .num.inner { fill: #6B7280; }
.time-dial-face .num.on { fill: #fff; font-weight: 600; }

.time-dial-keys {
    display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px;
    align-items: center; padding: 24px 4px;
}
.time-dial-keys input {
    width: 100%; box-sizing: border-box; font: inherit; font-size: 26px; font-weight: 600;
    font-variant-numeric: tabular-nums; text-align: center; padding: 12px 0;
    border: 1px solid var(--color-border); border-radius: 10px; background: #fff; color: #111827;
}
.time-dial-keys input:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px #DBEAFE; }
.time-dial-keys .sep { font-size: 24px; font-weight: 600; color: #9CA3AF; }
.time-dial-keys-note {
    grid-column: 1 / -1; font-size: 11.5px; color: var(--color-gray);
    text-align: center; margin: 0;
}

.time-dial-actions {
    display: flex; align-items: center; gap: 8px;
    margin-top: 6px; padding-top: 10px; border-top: 1px solid #E5E7EB;
}
.time-dial-actions .grow { flex: 1; }
.time-dial-actions button {
    font: inherit; font-size: 13px; font-weight: 600; padding: 8px 14px;
    border-radius: 8px; border: 1px solid transparent; cursor: pointer;
}
.time-dial-now { background: #fff; border-color: var(--color-border) !important; color: #374151; }
.time-dial-cancel { background: #fff; color: #6B7280; }
.time-dial-ok { background: var(--color-primary); color: #fff; }

/* Layar sempit (ESS & admin di HP): panel jadi sheet selebar layar yang menempel di
   dasar, bukan popover kecil yang menggantung -- jari perlu target sebesar mungkin,
   dan popover di dekat tepi layar sering tertutup keyboard virtual. */
@media (max-width: 640px) {
    .time-dial-panel {
        left: 0 !important; right: 0; top: auto !important; bottom: 0;
        width: 100%; border-radius: 18px 18px 0 0; border: none;
        padding-bottom: 16px; animation: time-dial-up .18s ease-out;
    }
}
@keyframes time-dial-up { from { transform: translateY(14px); opacity: .6; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .time-dial-panel { animation: none; }
}

.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

/* Form modal yang labelnya langsung anak <form> atau anak <div> pembungkus kondisional
   (BUKAN dibungkus .form-group) — pola lama dipakai banyak modal (Buat Pengumuman dan
   form Tambah lain yang serupa), bikin tampilannya mepet/tidak konsisten dibanding form
   yang sudah pakai .form-group. Ditambal generik di sini supaya tidak perlu ubah markup
   di setiap file satu-satu. */
.modal-box form > label,
.modal-box form > div:not(.form-group) > label {
    display: block;
    font-weight: 600;
    font-size: 13px;
    color: #111827;
    margin: 14px 0 5px;
}
.modal-box form > label:first-of-type { margin-top: 0; }
.modal-box form > input,
.modal-box form > select,
.modal-box form > textarea,
.modal-box form > div:not(.form-group) > input,
.modal-box form > div:not(.form-group) > select,
.modal-box form > div:not(.form-group) > textarea {
    width: 100%;
    padding: 9px 11px;
    border: 1px solid var(--color-border);
    border-radius: 7px;
    font-size: 13px;
    font-family: inherit;
    box-sizing: border-box;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.modal-box form input:focus,
.modal-box form select:focus,
.modal-box form textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(37,99,235,.12);
}
.modal-box form > textarea,
.modal-box form > div:not(.form-group) > textarea { resize: vertical; min-height: 84px; line-height: 1.5; }
.modal-box form select { cursor: pointer; }

/* Textarea "Alasan" pada form pengajuan (Lembur admin/ESS/Entri Departemen) tampil TANPA
   <label> di atasnya -- judulnya dipindah ke placeholder supaya form lebih pendek satu
   baris. margin-top menggantikan jarak yang tadinya diberi label, dan warna placeholder
   dibuat tipis supaya terbaca sebagai petunjuk, bukan teks yang sudah terisi. */
.reason-input { margin-top: 10px; }
.reason-input::placeholder { color: #9CA3AF; font-weight: 400; }

/* Searchable Select custom -- <select> disembunyikan, ditumpuk input teks + panel hasil
   pencarian. Dipakai reusable lewat assets/js/searchable-select.js (initSearchableSelect()).
   Styling input meniru persis .modal-box form > select supaya menyatu dengan field lain. */
.ssel-wrap { position: relative; width: 100%; }
.ssel-input {
    width: 100%; padding: 9px 11px; border: 1px solid var(--color-border); border-radius: 7px;
    font-size: 13px; font-family: inherit; box-sizing: border-box; cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.ssel-input:focus {
    outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(37,99,235,.12);
}
.ssel-panel {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 60;
    max-height: 220px; overflow-y: auto; background: #fff; border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0,0,0,.15); border: 1px solid var(--color-border);
}
.ssel-item { padding: 8px 12px; font-size: 13px; color: #111827; cursor: pointer; }
.ssel-item:hover { background: #f3f4f6; }
.ssel-empty { padding: 12px; font-size: 13px; color: var(--color-gray); text-align: center; }

/* Searchable select yang dipakai sebagai FILTER di toolbar (Rekap Attendance), bukan sebagai
   field di dalam form. `.ssel-wrap` aslinya block width:100% -- benar untuk form yang satu
   field per baris, tapi di toolbar ia memakan satu baris penuh sendiri dan mendorong filter
   lain ke bawah. Di sini dibuat inline-block selebar dropdown filter di sebelahnya. */
.table-toolbar .ssel-wrap,
.toolbar .ssel-wrap { display: inline-block; width: 220px; vertical-align: middle; flex: 0 0 auto; }
.table-toolbar .ssel-input,
.toolbar .ssel-input { padding: 8px 10px; font-size: 13px; }
/* Kotak pencarian searchable-select ADALAH <input type="text">, jadi ikut kena aturan
   `.toolbar input[type="text"] { min-width: 240px }` di atas -- input jadi lebih lebar
   daripada pembungkusnya (220px) dan meluber menimpa filter di sebelahnya (kejadian nyata:
   filter Karyawan menutupi filter tanggal di halaman Pengajuan Lembur). Pemilihnya sengaja
   3 tingkat supaya bobotnya mengalahkan aturan lama itu. */
.toolbar .ssel-wrap .ssel-input { min-width: 0; }

.target-scope-box {
    background: #F9FAFB;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 12px 14px;
    margin: -8px 0 14px;
}

/* ===== Toast ===== */
/* Realisasi terbaru: dipindah dari pojok kanan atas (dulu "right: 20px") ke TENGAH atas
   (left/right: 0 + align-items: center) -- posisi kanan atas sebelumnya sering menutupi
   tombol "+ Tambah/Ajukan ..." yang juga ada di pojok kanan atas (.page-header). Berlaku
   GLOBAL (elemen ini dipakai bersama oleh seluruh halaman lewat Hris.toast(), lihat
   assets/js/app.js), bukan cuma 1 halaman. */
#toast-container { position: fixed; top: 120px; left: 0; right: 0; z-index: 300; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.toast {
    padding: 10px 16px; border-radius: 8px; color: #fff; font-size: 13px; min-width: 220px;
    box-shadow: 0 4px 10px rgba(0,0,0,.12);
}
.toast-success { background: var(--color-success); }
.toast-error { background: var(--color-danger); }
/* Netral -- untuk pemberitahuan yang bukan sukses & bukan error, mis. "Absen dibatalkan."
   di ESS. Tanpa background sendiri, .toast cuma mewarisi color:#fff dan tulisannya jadi
   putih di atas transparan alias tak terbaca. */
.toast-info { background: var(--color-gray); }

/* ===== Dashboard ===== */
.dashboard-cards {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 16px;
}

/* Realisasi terbaru: KPI card sekarang berupa <a> (bukan <div>) supaya seluruh card
   bisa diklik langsung ke halaman terkait -- dibungkus dashboard-card-link supaya
   warna teks/underline bawaan link tidak "bocor", dan hover memberi affordance jelas
   bahwa card ini interaktif (bukan cuma dekorasi statis). */
.dashboard-card-link { text-decoration: none; display: block; color: inherit; }
.dashboard-card {
    padding: 14px 16px; border-radius: 10px; display: flex; flex-direction: column; gap: 4px;
    transition: transform .12s ease, box-shadow .12s ease; cursor: pointer; min-height: 92px;
    box-shadow: 0 1px 2px rgba(0,0,0,.06);
}
.dashboard-card:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,.14); }
.dashboard-card-icon { font-size: 18px; opacity: .9; }
.dashboard-card-value { font-size: 26px; font-weight: 800; line-height: 1.1; display: flex; align-items: baseline; gap: 6px; }
.dashboard-card-value .dashboard-card-delta { font-size: 12px; font-weight: 700; opacity: .85; }
.dashboard-card-label { font-size: 12px; font-weight: 600; opacity: .85; }
.dashboard-card-sub { font-size: 11px; opacity: .75; margin-top: auto; }

/* Palet warna per card -- meniru urutan warna di desain: card 1 (Total Employee) biru
   tua solid, 5 (Cuti Menunggu Approval) teal terang solid, 7 (Recruitment) teal gelap
   solid, 8 (Payroll) navy gelap solid; sisanya (2/3/4/6) putih/netral dengan aksen warna
   pada icon & value saja supaya tidak terlalu ramai. */
.dashboard-card--solid-blue { background: #1D4ED8; color: #fff; }
.dashboard-card--solid-blue .dashboard-card-label,
.dashboard-card--solid-blue .dashboard-card-sub,
.dashboard-card--solid-blue .dashboard-card-delta { color: #DBEAFE; opacity: 1; }

.dashboard-card--solid-teal { background: #14B8A6; color: #fff; }
.dashboard-card--solid-teal .dashboard-card-label,
.dashboard-card--solid-teal .dashboard-card-sub { color: #F0FDFA; opacity: 1; }

.dashboard-card--solid-teal-dark { background: #115E59; color: #fff; }
.dashboard-card--solid-teal-dark .dashboard-card-label,
.dashboard-card--solid-teal-dark .dashboard-card-sub { color: #CCFBF1; opacity: 1; }

.dashboard-card--solid-navy { background: #1E293B; color: #fff; }
.dashboard-card--solid-navy .dashboard-card-label,
.dashboard-card--solid-navy .dashboard-card-sub { color: #CBD5E1; opacity: 1; }

.dashboard-card--neutral { background: #fff; border: 1px solid var(--color-border); color: var(--color-text); }
.dashboard-card--neutral .dashboard-card-value { color: var(--color-primary-dark); }
.dashboard-card--accent-red .dashboard-card-value { color: #DC2626; }
.dashboard-card--accent-red .dashboard-card-icon { color: #DC2626; }

.dashboard-charts, .dashboard-widgets {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; margin-bottom: 20px;
}
.chart-title { font-size: 14px; margin: 0 0 12px; }

/* ===== Kepala kartu grafik (judul + badge angka ringkas) =====
   Dipakai BERSAMA oleh kartu Tren Attendance & Distribusi Usia. Keduanya sengaja memakai
   struktur yang sama (kepala -> baris keterangan -> area plot setinggi
   --chart-plot-height -> label sumbu X) supaya berbaris rata bersebelahan; sebelumnya
   line chart tingginya ikut melar mengikuti lebar kartu sementara grafik batang di
   sebelahnya tetap pendek, dan yang terlihat cuma ruang kosong sekartu penuh. */
:root { --chart-plot-height: 200px; }

.chart-card { display: flex; flex-direction: column; }
.chart-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; margin-bottom: 10px;
}
.chart-head .chart-title { margin: 0; font-size: 16px; }
/* Keterangan rentang di judul ("(20 Hari Kerja Terakhir)") -- bagian dari judul, tapi
   bukan namanya, jadi tidak ikut tebal. */
.chart-title-sub { font-weight: 400; font-size: 13px; color: var(--color-gray); }
.chart-badge {
    flex-shrink: 0; text-align: right; line-height: 1.25;
    border: 1px solid var(--color-border); border-radius: 8px; padding: 5px 10px;
    background: var(--color-white);
}
.chart-badge-label { display: block; font-size: 10px; color: var(--color-gray); }
.chart-badge-value { display: block; font-size: 16px; color: var(--color-primary-dark); }

/* ===== Line chart Tren Attendance (dashboard) =====
   SVG-nya digambar assets/js/dashboard.js dengan koordinat PIKSEL NYATA (viewBox = lebar
   container x tinggi tetap), jadi ukuran font & tebal garis di bawah ini benar-benar
   piksel layar -- tidak ada penskalaan yang membuat teks ikut melar. */
.line-chart-plot { position: relative; }
/* pan-y, bukan none: sentuhan horizontal tetap ditangkap untuk menggeser tooltip, tapi
   menggulung halaman dengan jari dari atas grafik tidak ikut terkunci. */
.line-chart-svg { display: block; width: 100%; touch-action: pan-y; }
.line-chart-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.line-chart-grid { stroke: #F1F2F4; stroke-width: 1; }
.line-chart-axis { stroke: var(--color-border); stroke-width: 1; }
.line-chart-axis-label { font-size: 11px; fill: var(--color-gray); }
.line-chart-crosshair { stroke: #9CA3AF; stroke-width: 1; stroke-dasharray: 3 3; }
.line-chart-focus-dot { stroke-width: 2.5; }

.line-chart-legend {
    display: flex; flex-wrap: wrap; gap: 4px 18px;
    margin-bottom: 6px; font-size: 12px; color: var(--color-text);
}
.line-chart-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.line-chart-legend-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }

/* Tooltip gabungan ketiga seri. pointer-events: none WAJIB -- kotaknya menutupi jalur
   kursor, dan tanpa ini setiap kali tooltip muncul di bawah kursor SVG langsung menerima
   pointerleave, jadi tooltipnya berkedip mati-hidup terus. */
.line-chart-tooltip {
    position: absolute; top: 34%; z-index: 5; pointer-events: none;
    display: flex; flex-direction: column; gap: 1px;
    transform: translateX(12px);
    background: var(--color-white); border: 1px solid var(--color-border);
    border-radius: 8px; box-shadow: 0 6px 18px rgba(17, 24, 39, .12);
    padding: 8px 10px; font-size: 12px; color: var(--color-text); white-space: nowrap;
}
.line-chart-tooltip.is-left { transform: translateX(calc(-100% - 12px)); }
.line-chart-tooltip-title { font-weight: 600; margin-bottom: 2px; }

/* ===== Distribusi Usia Karyawan (dashboard) =====
   Label sumbu X ditaruh di baris TERPISAH di luar area plot -- kalau ikut masuk ke dalam
   kolom batangnya, tinggi labelnya memakan area batang dan skala Y jadi meleset. Lebar
   gutter (28px) dipasang di .age-chart-plot supaya baris label X ikut bergeser sejauh
   yang sama dan tetap lurus di bawah batangnya. */
.age-chart { font-size: 11px; }
/* Judul sumbu Y. Sejajar gutter label angka, bukan di tengah kartu: pembacanya
   menyusurinya turun ke deretan angka di bawahnya. */
.age-chart-ylabel { color: var(--color-gray); margin-bottom: 4px; }
.age-chart-plot {
    position: relative; height: var(--chart-plot-height); margin-left: 28px;
    border-left: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border);
}
.age-chart-tick { position: absolute; left: 0; right: 0; border-top: 1px dashed #F1F2F4; }
.age-chart-tick span {
    position: absolute; right: 100%; bottom: -7px; width: 24px;
    padding-right: 6px; text-align: right; color: var(--color-gray);
}
.age-chart-cols { position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 8px; padding: 0 8px; }
.age-chart-col { flex: 1; min-width: 0; display: flex; justify-content: center; height: 100%; align-items: flex-end; }
/* Radius penuh di keempat sudut (bukan cuma atas) sesuai desain _desain/rev1.jpg.
   Dibatasi supaya batang pendek tidak berubah jadi kapsul: pada nilai kecil radius 10px
   memakan hampir seluruh tinggi batang dan angkanya jadi terlihat mengambang. */
.age-chart-bar {
    position: relative; width: 100%; min-height: 4px;
    background: #2F3468; border-radius: 10px;
}
.age-chart-value {
    position: absolute; left: 0; right: 0; top: 6px;
    text-align: center; font-weight: 600; font-size: 12px; color: #fff;
}
/* Batang terlalu pendek untuk memuat angkanya (termasuk rentang usia kosong) -- angkanya
   naik ke atas batang, warnanya ikut berubah karena latarnya bukan lagi warna batang. */
.age-chart-value--outside { top: auto; bottom: 100%; margin-bottom: 3px; color: var(--color-text); }
.age-chart-xaxis { display: flex; gap: 8px; padding: 6px 8px 0; margin-left: 28px; }
.age-chart-xlabel { flex: 1; min-width: 0; text-align: center; color: var(--color-gray); }
.age-chart-caption { margin-left: 28px; text-align: center; color: var(--color-gray); margin-top: 2px; }

.widget-list { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.widget-list li { padding: 8px 0; border-bottom: 1px solid var(--color-border); }
.widget-list li:last-child { border-bottom: none; }
.widget-list-empty { color: var(--color-gray); }

/* ===== Reports ===== */
.report-meta { font-size: 12px; color: var(--color-gray); margin: 10px 0; }

/* ===== Login ===== */
.login-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 24px;
    padding: 40px 20px;
    background:
        radial-gradient(circle at 85% 8%, rgba(255,255,255,0.10) 0%, transparent 45%),
        radial-gradient(circle at 6% 92%, rgba(255,255,255,0.08) 0%, transparent 40%),
        linear-gradient(135deg, #1E3A8A 0%, #2563EB 55%, #3B82F6 100%);
    position: relative;
    overflow: hidden;
}
/* ===== Skala kartu login =====
   Alasannya sama dengan .app-admin di atas: seluruh ukuran di file ini piksel absolut, dan di
   layar laptop halaman login terasa kebesaran sampai user menekan Ctrl+- tiap kali membukanya.

   Bedanya, zoom di sini dipasang di KARTU dan FOOTER-nya, bukan di <html>. .login-page memakai
   min-height:100vh untuk latar gradiennya; satuan viewport tidak diperlakukan sama oleh semua
   browser saat berada di dalam elemen ber-zoom, jadi latar itu berisiko berakhir 15% lebih
   pendek dari layar dan menyisakan pita putih di bawah kartu. Dengan zoom di kartu saja, latar
   tetap penuh satu layar sementara isinya mengecil serentak.

   Variabelnya sengaja BUKAN --ui-zoom: Hris.uiZoom() di assets/js/app.js membaca --ui-zoom dari
   <html> untuk mengoreksi koordinat viewport, dan di halaman ini <html> memang tidak di-zoom --
   memakai nama yang sama akan membuat JS mengoreksi koordinat yang sebenarnya tidak terskala. */
.login-page { --login-zoom: .85; }
.login-shell,
.login-footer { zoom: var(--login-zoom, 1); }

.login-shell {
    position: relative;
    z-index: 1;
    display: flex;
    width: 900px;
    max-width: 100%;
    min-height: 560px;
    background: #fff;
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 25px 60px rgba(0,0,0,.28);
}
/* Panel kanan dekoratif dihapus (permintaan) -- card sekarang 1 kolom saja, lebar
   disempitkan supaya tidak kelebaran kosong di layar besar. */
.login-shell--single {
    width: 460px;
    min-height: 0;
}
.login-left {
    flex: 1 1 52%;
    /* min-width:0 WAJIB. Flex item bawaannya min-width:auto, artinya ia TIDAK BOLEH menyusut
       di bawah min-content-nya sendiri -- dan min-content panel ini ditentukan elemen terlebar
       di dalamnya (dulu: logo SVG berlebar tetap 340px). Di HP 360px kartu cuma selebar 320px,
       jadi panelnya meluber ke kanan dan .login-shell{overflow:hidden} memotongnya: tepi kanan
       kolom username/password dan tombol Login hilang di balik tepi kartu. Diperparah
       autofocus di field username -- browser menggulir kotak overflow itu ke kanan untuk
       memperlihatkan field yang fokus, sehingga logo ikut terpotong di kiri dan seluruh isi
       tampak bergeser. Persis yang terlihat di _desain/kepotonglogin.jpeg. */
    min-width: 0;
    max-width: 100%;
    padding: 44px 48px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.login-shell--single .login-left { flex: 1 1 100%; }
.login-brand { text-align: center; margin-bottom: 1px; }
.login-logo-mark { display: block; margin: 0 auto 8px; width: 100%; max-width: 340px; height: auto; }
.login-title {
    text-align: center; font-size: 40px; font-weight: 800; color: #0F1F4D;
    margin: 4px 0 2px; letter-spacing: 1px;
}
.login-subtitle { text-align: center; color: #6B7280; font-size: 13px; margin: 0 0 16px; }
.login-divider { display: flex; justify-content: center; margin-bottom: 24px; }
.login-divider span {
    width: 90px; height: 1px; background: #CBD5E1; position: relative;
}
.login-divider span::after {
    content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 6px; height: 6px; border-radius: 50%; background: #2563EB;
}
.login-field { margin-bottom: 18px; }
.login-field label { display: block; font-size: 13px; font-weight: 600; color: #1F2937; margin-bottom: 6px; }
.login-input-wrap {
    position: relative; display: flex; align-items: center; min-width: 0;
    border: 1px solid #D1D5DB; border-radius: 8px; background: #fff;
    transition: border-color .15s, box-shadow .15s;
}
.login-input-wrap:focus-within { border-color: #2563EB; box-shadow: 0 0 0 3px rgba(37,99,235,.12); }
.login-input-icon { flex-shrink: 0; margin-left: 12px; color: #9CA3AF; }
.login-input-wrap input {
    flex: 1; min-width: 0; border: none; outline: none; padding: 12px 12px; font-size: 16px;
    border-radius: 8px; background: transparent;
    /* font-size WAJIB >= 16px -- di bawah itu Safari iOS (dan sebagian browser mobile
       lain) otomatis zoom-in saat field ini fokus, membuat tampilan tiba-tiba membesar
       dan sisi kanan halaman terlihat "terpotong" keluar layar. */
}
.login-toggle-password {
    background: none; border: none; cursor: pointer; color: #9CA3AF;
    display: flex; align-items: center; padding: 0 12px;
}
.login-toggle-password:hover { color: #6B7280; }
.login-submit-btn {
    width: 100%; padding: 13px; margin-top: 8px; border: none; border-radius: 9px;
    background: linear-gradient(135deg, #1E3A8A, #2563EB);
    color: #fff; font-weight: 700; font-size: 14px; letter-spacing: 1.5px;
    text-transform: uppercase; cursor: pointer; transition: opacity .15s;
    box-shadow: 0 8px 18px rgba(37,99,235,.35);
}
.login-submit-btn:hover { opacity: .92; }
.login-submit-btn:disabled { opacity: .6; cursor: not-allowed; }
.login-error {
    background: #FEE2E2; color: #B91C1C; padding: 9px 12px; border-radius: 6px;
    font-size: 13px; margin-bottom: 14px; display: none;
}

.login-footer {
    position: relative; z-index: 1; display: flex; flex-direction: column; gap: 2px;
    color: rgba(255,255,255,.85); font-size: 12px; text-align: center;
}

@media (max-width: 768px) {
    /* Di HP kartu login sudah memakai padding rapat dan lebarnya mengikuti layar -- mengecilkan
       15% lagi hanya membuat teks dan kolom input susah dibaca/ditekan. Keluhannya memang cuma
       di laptop/PC. */
    .login-page { --login-zoom: 1; }

    .login-shell { min-height: 0; }
    .login-left { padding: 36px 26px; }
    .login-title { font-size: 36px; }
}

/* HP sempit (360px ke bawah masih mayoritas di lapangan): padding dikurangi supaya kolom
   input punya ruang nyata, dan judul dikecilkan supaya tidak memaksa kartu melebar.
   Bersama min-width:0 di atas, ini membuat isi kartu selalu muat -- bukan sekadar
   "biasanya muat". */
@media (max-width: 400px) {
    .login-page { padding: 24px 12px; }
    .login-left { padding: 28px 18px; }
    .login-title { font-size: 30px; }
    .login-subtitle { font-size: 12px; }
    .login-divider { margin-bottom: 18px; }
    .login-field { margin-bottom: 14px; }
    .login-input-icon { margin-left: 10px; }
    .login-input-wrap input { padding: 11px 10px; }
    .login-toggle-password { padding: 0 10px; }
}

/* ===== Responsive (Tablet & Smartphone) ===== */
.sidebar-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 40px; height: 40px;
    background: transparent; border: none; cursor: pointer;
    flex-shrink: 0;
}
.sidebar-toggle span { display: block; width: 22px; height: 2px; background: #374151; border-radius: 2px; }

@media (max-width: 1024px) {
    .content-area { padding: 18px; }
    .form-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
}

@media (max-width: 768px) {
    /* Di bawah breakpoint ini halaman admin sudah pindah ke layout mobile (sidebar
       off-canvas, padding rapat) yang ukurannya memang sudah pas untuk layar sempit --
       mengecilkannya 15% lagi membuat teksnya tidak terbaca. Skala hanya untuk laptop
       ke atas, yang memang jadi keluhan awalnya. */
    .app-admin { --ui-zoom: 1; zoom: 1; }

    .app-header { padding: 0 12px; }
    .app-header .brand { font-size: 15px; }
    .app-header .user-menu span { display: none; }
    .header-title { font-size: 13px; max-width: 40%; }

    /* Sidebar jadi off-canvas (geser dari luar layar) di mobile, dibuka lewat tombol
       hamburger di header — bukan lagi push-content seperti desktop, supaya tidak makan
       lebar layar yang sempit. */
    .sidebar-toggle { display: flex; }
    .app-sidebar {
        width: 260px;
        transform: translateX(-100%);
        transition: transform .2s ease;
        box-shadow: 2px 0 16px rgba(17,24,39,.15);
    }
    .app-sidebar.open { transform: translateX(0); }

    /* Mode ciut (ikon saja) DIMATIKAN di layar kecil. Di sini sidebar sudah berupa laci
       yang muncul saat dipanggil dan menghilang lagi, jadi menciutkannya tidak melebarkan
       apa pun -- yang didapat cuma laci selebar 56px berisi ikon tanpa nama, dan tombol
       ciut/lebar yang tidak ada gunanya. Preferensi user-nya TIDAK dihapus: begitu
       halaman yang sama dibuka di layar lebar, sidebarnya ciut lagi seperti yang dia
       setel. */
    .sidebar-collapsed .app-sidebar { width: 260px; }
    .sidebar-collapsed .content-area { margin-left: 0; }
    .sidebar-collapsed .sidebar-label { display: revert; }
    .sidebar-collapsed .sidebar-nav .nav-caret { display: block; }
    .sidebar-collapsed .sidebar-flyout-title { display: none; }
    .sidebar-collapsed .sidebar-link,
    .sidebar-collapsed .sidebar-group-toggle { justify-content: flex-start; padding-left: 16px; padding-right: 16px; gap: 9px; }
    .sidebar-collapse-toggle { display: none; }

    .content-area { padding: 14px; margin-left: 0; margin-top: 60px; }
    .app-footer { margin-left: 0; }

    /* Sidebar sudah jadi laci yang keluar-masuk, jadi baris tab memakai lebar penuh --
       termasuk saat preferensi "sidebar ciut" milik user sedang aktif. */
    .workspace-tabs,
    .sidebar-collapsed .workspace-tabs { left: 0; }
    /* Di layar sempit bidang miring 10px + padding 20px memakan terlalu banyak dari
       lebar tab yang tinggal 150px -- label jadi tinggal beberapa huruf. Chamfer-nya
       dipangkas jadi 6px dan paddingnya ikut turun. */
    .workspace-tab {
        max-width: 150px;
        padding: 0 14px;
        clip-path: polygon(6px 0, calc(100% - 6px) 0, 100% 100%, 0 100%);
    }
    .page-title { font-size: 17px; }

    .card { padding: 14px; border-radius: 8px; }

    /* Card jadi scroll container horizontal untuk table di dalamnya, tanpa perlu
       menambahkan wrapper markup baru di tiap halaman View. */
    .card { overflow-x: auto; -webkit-overflow-scrolling: touch; }
    table { min-width: 560px; }

    /* Halaman custom pakai .data-table langsung tanpa wrapper .card, jadi perlu jadi
       scroll container sendiri di mobile (bukan mengandalkan overflow-x pada .card). */
    .data-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; }
    .page-header h1 { font-size: 17px; }

    /* Kolom Aksi (edit/nonaktifkan/dll) di-pin (sticky) ke sisi kanan viewport supaya
       selalu terlihat tanpa perlu scroll horizontal dan tidak melewati batas layar —
       tombol di dalamnya ditumpuk vertikal dalam lebar yang dibatasi. */
    table th:last-child, table td.actions-cell {
        position: sticky; right: 0; z-index: 2;
        background: var(--color-white);
        box-shadow: -6px 0 8px -6px rgba(17,24,39,.15);
    }
    .actions-cell {
        flex-direction: column; align-items: stretch; gap: 4px;
        width: 108px; max-width: 108px;
    }
    .actions-cell .btn { width: 100%; white-space: nowrap; }

    .toolbar { flex-direction: column; align-items: stretch; }
    .toolbar input[type="text"] { min-width: 0; width: 100%; }
    .toolbar-filters { flex-direction: column; }
    .toolbar-filters select { width: 100%; }
    .toolbar > div, .toolbar > button { width: 100%; }

    .form-grid { grid-template-columns: 1fr; gap: 12px; }

    .inline-add-form { flex-direction: column; align-items: stretch; }
    .inline-add-form .form-group { min-width: 0; width: 100%; }
    /* Layar sempit: field berdampingan kembali menumpuk selebar penuh -- dua input tanggal
       di lebar 50% masing-masing tidak terbaca di HP. */
    .form-group-half { display: block; width: 100%; }
    .form-group-half + .form-group-half { margin-left: 0; }
    .inline-add-form button { width: 100%; }

    .modal-box { width: 100%; max-width: 96vw; padding: 16px 16px; max-height: 92vh; }
    .modal-actions { flex-wrap: wrap; }
    .modal-actions button { flex: 1; min-width: 100px; }

    .dashboard-cards { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
    .dashboard-charts, .dashboard-widgets { grid-template-columns: 1fr; }

    #toast-container { left: 12px; right: 12px; top: 112px; }
    .toast { min-width: 0; width: 100%; }
}

@media (max-width: 480px) {
    .app-header .brand { font-size: 14px; }
    .header-title { display: none; }
    .page-title { font-size: 16px; }
    .content-area { padding: 10px; }
    .card { padding: 12px; }
    .btn { padding: 8px 12px; font-size: 12px; }
    .modal-box { padding: 14px; }

    .toolbar > button, .toolbar .btn { width: 100%; }
    .actions-cell { width: 92px; max-width: 92px; }
}

/* ===== Sidebar di layar sentuh: accordion + target sentuh yang bisa dijari =====
   Dua masalah nyata yang diperbaiki blok ini (perilaku desktop TIDAK tersentuh sama sekali,
   semuanya di dalam media query):

   1. Submenu melayang tidak muat. Di layar 360px, flyout min-width 220px tidak cukup ruang
      di sebelah kanan sidebar 260px, jadi positionSidebarFlyout() memundurkannya sampai
      MENIMPA menu induknya sendiri -- dan flyout tingkat 2 mendarat persis di atas tingkat 1.
      Hierarkinya jadi tidak terlihat sama sekali. Di sini submenu dikembalikan ke alur
      dokumen (accordion): terbuka ke bawah, di dalam panel sidebar, dengan indentasi yang
      menunjukkan tingkatnya.

   2. Target sentuh ~30px (padding 7px + font 12.5px). Panduan Android/iOS: 44-48px. Angka di
      bawah menghasilkan ~44px tanpa mengubah apa pun di desktop. */
@media (max-width: 768px) {
    .sidebar-group.open > .sidebar-submenu,
    .nav-subdropdown.open > .nav-submenu {
        position: static;   /* inline style top/left dari JS jadi tidak berlaku */
        min-width: 0;
        border: none;
        border-radius: 0;
        box-shadow: none;
        padding: 0;
        background: #F9FAFB;
    }

    .sidebar-link, .sidebar-group-toggle { padding: 12px 16px; font-size: 14px; }
    .sidebar-icon { font-size: 15px; width: 18px; }
    .sidebar-submenu a, .nav-subdropdown-toggle { padding: 12px 16px 12px 34px; font-size: 14px; }
    .nav-submenu a { padding-left: 50px; }
}

/* ==== Restriksi menu role HR Department ====
   Class .hr-restricted-menu ditambahkan ke <html> oleh header.php (guard sinkron di
   <head>, lihat coding_standard.md §9.13) khusus untuk role_name === 'HR Department'.
   Menyembunyikan grup sidebar Master Data/Payroll/Pengaturan yang ditandai
   [data-menu-group] di elemen masing-masing. (Tag "Payroll" dulu juga menyembunyikan
   card "Tren Payroll" di Dashboard; kartu itu sudah dihapus, tagnya kini murni sidebar.)
   "Entri Departemen" (Entri Cuti/Entri Lembur, milik role Admin Departemen) juga ikut
   disembunyikan -- HR Department punya menu Leave & Permission/Overtime penuh sendiri,
   jadi menu jalan-pintas entri departemen tidak relevan untuk role ini.
   Ini guard TAMPILAN saja -- proteksi data sesungguhnya ada di penghapusan
   role_permissions HR Department (lihat database/seeders). */
.hr-restricted-menu [data-menu-group="Master Data"],
.hr-restricted-menu [data-menu-group="Payroll"],
.hr-restricted-menu [data-menu-group="Pengaturan"],
.hr-restricted-menu [data-menu-group="Entri Departemen"] {
    display: none !important;
}

/* ==== Restriksi menu role Department Manager ====
   Class .dept-manager-restricted-menu ditambahkan ke <html> oleh header.php (guard
   sinkron di <head>) khusus role_name === 'Department Manager'. Menyembunyikan grup
   sidebar Master Data/Payroll/Pengaturan/Document Management/Reports + 3 card dashboard
   (Distribusi Usia Karyawan/Upcoming Contract Expiry/Upcoming Retirement, ditandai
   [data-menu-group="Dept Manager Dashboard"]).
   Card "Payroll Period Aktif" TIDAK bisa ditandai lewat CSS karena
   dirender dinamis oleh JS dari daftar key-value -- disembunyikan langsung di
   assets/js/dashboard.js berdasarkan role. Ini guard TAMPILAN saja -- proteksi data
   sesungguhnya (khusus Reports) ada di penghapusan role_permissions
   `report.view` Department Manager (lihat database/seeders). Master
   Data/Payroll/Pengaturan/Document Management sengaja TIDAK ikut dihapus permission-nya
   di backend untuk Dept Manager karena `department.view`/`division.view`/`position.view`
   dipakai dropdown di halaman lain yang tetap mereka pakai (Mutasi/Employee
   Profile/Shift) -- lihat catatan di seeder terkait. */
.dept-manager-restricted-menu [data-menu-group="Master Data"],
.dept-manager-restricted-menu [data-menu-group="Payroll"],
.dept-manager-restricted-menu [data-menu-group="Pengaturan"],
.dept-manager-restricted-menu [data-menu-group="Document Management"],
.dept-manager-restricted-menu [data-menu-group="Reports"],
.dept-manager-restricted-menu [data-menu-group="Dept Manager Dashboard"] {
    display: none !important;
}

/* ==== Restriksi menu role Admin Departemen ====
   Class .admin-departemen-restricted-menu ditambahkan ke <html> oleh header.php (guard
   sinkron di <head>) khusus role_name === 'Admin Departemen'. BEDA dari 2 blok di atas
   (yang menyembunyikan beberapa grup tertentu, sisanya tetap tampil): role ini
   didaftar-putih (whitelist) -- SEMUA grup disembunyikan KECUALI "Entri Departemen"
   (Entri Cuti/Entri Lembur), karena role ini murni jalan pintas entri+cetak, tidak
   relevan membuka menu admin lain sama sekali. Daftar judul grup di bawah HARUS
   disinkronkan manual kalau ada grup top-level baru ditambahkan ke
   MenuDefinition::tree() (tidak otomatis, karena CSS tidak bisa "kecuali selector
   ini" secara native untuk elemen dengan atribut dinamis seperti [data-menu-group]).
   Ini guard TAMPILAN saja -- proteksi data sesungguhnya lewat permission
   leave_entry.* dan overtime_entry.* (lihat database/admin_departemen_role.sql). */
.admin-departemen-restricted-menu [data-menu-group="Master Data"],
.admin-departemen-restricted-menu [data-menu-group="Recruitment"],
.admin-departemen-restricted-menu [data-menu-group="Employee"],
.admin-departemen-restricted-menu [data-menu-group="Time Management"],
.admin-departemen-restricted-menu [data-menu-group="Leave & Permission"],
.admin-departemen-restricted-menu [data-menu-group="Payroll"],
.admin-departemen-restricted-menu [data-menu-group="Performance"],
.admin-departemen-restricted-menu [data-menu-group="Training"],
.admin-departemen-restricted-menu [data-menu-group="Document Management"],
.admin-departemen-restricted-menu [data-menu-group="Pengaturan"],
.admin-departemen-restricted-menu [data-menu-group="Reports"],
.admin-departemen-restricted-menu [data-menu-group="Dept Manager Dashboard"] {
    display: none !important;
}

/* ==== Restriksi menu role Super Admin ====
   Hack lama (.super-admin-restricted-menu menyembunyikan SELURUH grup "Pengaturan" tanpa
   peduli permission asli) sudah diganti sistem permission_code per-menu (lihat
   database/103_add_permission_code_to_menu_items.sql, 104_gate_pengaturan_menu_by_permission.sql,
   dan filter render di app/Views/layouts/sidebar.php) -- tidak perlu rule CSS di sini lagi,
   tiap item Pengaturan tampil/sembunyi sendiri-sendiri mengikuti permission role tsb. */

/* ==== DIHAPUS: penyembunyi menu "Entri Departemen" untuk Super Admin & Sysadmin ====
   Rule .hide-department-entry-menu [data-menu-group="Entri Departemen"] { display:none }
   sudah dihapus bersama pemasang class-nya di header.php. Dulu menu itu disembunyikan
   karena halamannya memang selalu 403 untuk akun sistem (tidak tertaut employee -> tidak
   punya department_id). Sekarang kedua role itu SENGAJA didukung lewat dropdown
   "Departemen" (App\Helpers\DepartmentEntryScope + permission
   department_entry.all_departments), jadi menunya harus tampil dan visibilitasnya cukup
   diatur permission_code per item di Pengaturan Menu -- bukan aturan CSS berbasis nama
   role yang tidak bisa diubah admin dari UI. */

/* ==== Assign Permission — tabel matrix modul x aksi ====
   Menggantikan checklist vertikal per-kode-permission lama dengan tabel (modul jadi
   baris, aksi jadi kolom), sesuai desain yang diminta user. */
.permission-matrix-wrap {
    max-height: 55vh;
    overflow-y: auto;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
}
.permission-matrix { width: 100%; border-collapse: collapse; font-size: 13px; }
.permission-matrix th, .permission-matrix td {
    padding: 8px 10px;
    border-bottom: 1px solid #F3F4F6;
}
.permission-matrix thead th {
    position: sticky;
    top: 0;
    background: #F9FAFB;
    color: #374151;
    font-weight: 600;
    z-index: 1;
}
.permission-matrix tbody tr:hover { background: #FAFAFA; }
.permission-matrix input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: #2563EB;
    cursor: pointer;
}

/* ==== Halaman Hari Libur Nasional — navigasi panah Bulan/Tahun ====
   Class terpisah dari .toolbar generic supaya TIDAK ikut aturan
   `.toolbar { flex-direction: column }` di breakpoint mobile (lihat @media di atas) —
   navigasi panah ini harus tetap ringkas & sejajar horizontal, cuma diperkecil
   ukurannya di layar sempit, bukan ditumpuk vertikal selebar layar seperti toolbar
   form biasa (itu yang bikin tombol panah tampak tidak proporsional di HP sebelumnya). */
.holiday-nav {
    display: flex;
    width: 100%;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 20px;
    padding: 12px 0;
    text-align: center;
}
.holiday-nav-group {
    display: flex;
    align-items: center;
    gap: 6px;
}
.holiday-nav-btn {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    background: #F9FAFB;
    color: #374151;
    font-size: 14px;
    cursor: pointer;
}
.holiday-nav-btn:hover { background: #F3F4F6; }
.holiday-nav-btn:active { background: #E5E7EB; }
.holiday-nav-display {
    width: 110px;
    text-align: center;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    padding: 6px 4px;
    font-size: 14px;
    background: #fff;
    color: #111827;
}
.holiday-nav-display-year { width: 80px; }

@media (max-width: 480px) {
    /* Layar smartphone: tombol panah & kotak tampilan diperkecil proporsional (bukan
       melebar penuh seperti tombol form biasa), tetap sejajar horizontal per grup
       (Bulan tetap 1 baris, Tahun tetap 1 baris), grup Bulan & Tahun ditumpuk 2 baris. */
    .holiday-nav { gap: 8px; }
    .holiday-nav-group { gap: 4px; }
    .holiday-nav-btn { width: 26px; height: 26px; font-size: 12px; }
    .holiday-nav-display { width: 84px; font-size: 12px; padding: 5px 2px; }
    .holiday-nav-display-year { width: 64px; }
}

/* ==== Progress bar indeterminate — dipakai form Generate Kalender Shift ====
   Animasi "sedang berjalan" (bukan persentase real), karena backend Generate cuma
   1 request tunggal tanpa laporan progres bertahap dari server. */
.progress-bar-wrap { margin: 14px 0; }
.progress-bar-track {
    width: 100%;
    height: 8px;
    background: #E5E7EB;
    border-radius: 999px;
    overflow: hidden;
}
.progress-bar-fill {
    width: 40%;
    height: 100%;
    background: #2563EB;
    border-radius: 999px;
    animation: progress-bar-slide 1.1s ease-in-out infinite;
}
@keyframes progress-bar-slide {
    0%   { margin-left: -40%; }
    100% { margin-left: 100%; }
}
.progress-bar-label {
    margin: 6px 0 0;
    font-size: 12px;
    color: #6B7280;
    text-align: center;
}
/* Varian DETERMINATE — dipakai modal "Proses Absensi/Attendance", yang memang tahu sudah
   berapa hari selesai dari berapa hari total (frontend memproses per tanggal). Animasi
   geser dimatikan; lebar diisi inline oleh JS, jadi butuh margin-left netral supaya tidak
   mewarisi posisi keyframe milik varian indeterminate di atas. */
.progress-bar-fill--determinate {
    animation: none;
    margin-left: 0;
    width: 0;
    transition: width .18s ease-out;
}
.progress-bar-title {
    margin: 0 0 6px;
    font-size: 13px;
    font-weight: 600;
    text-align: center;
}

/* ==== Halaman Pengaturan Menu — tampilan tree ====
   Urutan diatur lewat tombol naik/turun, bukan input angka manual. */
.menu-tree-list {
    list-style: none;
    margin: 0;
    padding-left: 22px;
}
.menu-tree-list:first-child {
    padding-left: 0;
}
.menu-tree-item {
    margin: 2px 0;
}
.menu-tree-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    background: #F9FAFB;
    border: 1px solid #F3F4F6;
}
.menu-tree-caret {
    cursor: pointer;
    color: #6B7280;
    width: 14px;
    flex-shrink: 0;
    text-align: center;
    user-select: none;
}
.menu-tree-caret-leaf {
    cursor: default;
    color: #D1D5DB;
    font-size: 10px;
}
.menu-tree-default-label {
    flex-shrink: 0;
    min-width: 160px;
    color: #6B7280;
    font-size: 12px;
}
.menu-label-input {
    flex: 1;
    min-width: 120px;
    padding: 5px 8px;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    font-size: 13px;
}
.menu-url-input {
    flex: 1;
    min-width: 140px;
    padding: 5px 8px;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    font-size: 12px;
    color: #374151;
    font-family: monospace;
}
.menu-permission-input {
    flex: 0 1 160px;
    min-width: 110px;
    padding: 5px 8px;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    font-size: 12px;
    color: #374151;
    font-family: monospace;
}
.menu-tree-actions {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}
/* Node yang di-"Hapus" (hidden=1) -- tetap tampil di form supaya bisa dipulihkan,
   tapi ditandai visual jelas berbeda dari node aktif (redup + label "(Disembunyikan)"). */
.menu-tree-row--hidden {
    background: #FEF2F2;
    border-color: #FECACA;
    opacity: 0.7;
}
.menu-tree-hidden-tag {
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 700;
    color: #B91C1C;
    background: #FEE2E2;
    padding: 2px 8px;
    border-radius: 999px;
}
/* Tag "Kustom" -- pengganti .menu-tree-default-label untuk baris menu dinamis (tidak
   punya "nama asli kode" untuk ditampilkan sebagai referensi seperti node built-in). */
.menu-tree-custom-tag {
    flex-shrink: 0;
    min-width: 160px;
    font-size: 11px;
    font-weight: 700;
    color: #1D4ED8;
    background: #DBEAFE;
    padding: 2px 8px;
    border-radius: 999px;
    text-align: center;
}
/* Mini-form inline "+ Tambah" -- muncul tepat di bawah baris grup yang tombolnya
   diklik, sebelum daftar submenu-nya (kalau ada). */
.menu-tree-add-form {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0 4px 22px;
    padding: 8px;
    background: #F0F9FF;
    border: 1px dashed #BAE6FD;
    border-radius: 6px;
}
.menu-tree-add-form select,
.menu-tree-add-form input[type="text"] {
    padding: 5px 8px;
    border: 1px solid #D1D5DB;
    border-radius: 6px;
    font-size: 13px;
}
.menu-tree-add-form .add-form-label {
    flex: 1;
    min-width: 120px;
}
.menu-tree-add-form .add-form-url {
    flex: 1;
    min-width: 140px;
    font-family: monospace;
}
/* Biodata: Foto Profil (kiri, kolom sempit) + field utama (kanan, mengikuti .form-grid
   yang sudah ada) sebaris -- field lanjutan (Departemen dst) tetap full-width di bawah. */
.menu-tree-actions .btn[disabled] {
    opacity: 0.35;
    cursor: not-allowed;
}
/* Anggota Role: tiap baris user + tombol "-" (keluarkan) rata kanan. */
.role-member-list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 260px;
    overflow-y: auto;
}
.role-member-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 4px;
    border-bottom: 1px solid #F3F4F6;
}
.role-member-remove-btn {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1px solid #FCA5A5;
    background: #FEF2F2;
    color: #B91C1C;
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.role-member-remove-btn:hover {
    background: #FEE2E2;
}
.role-member-remove-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}
.biodata-photo-row {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
    align-items: flex-start;
}
.biodata-photo-col {
    flex: 0 0 150px;
    display: flex;
    flex-direction: column;
}
.biodata-photo-label {
    font-weight: 600;
    font-size: 13px;
    color: #1F2937;
    margin-bottom: 8px;
}
.biodata-fields-col {
    flex: 1 1 420px;
    min-width: 0;
}
@media (max-width: 640px) {
    .biodata-photo-row { flex-direction: column; }
    .biodata-photo-col { flex-basis: auto; }
}

/* ===== Employee List: foto bulat kecil + toggle List/Grid ===== */
.employee-photo-circle {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    background: #F3F4F6;
    border: 1px solid #E5E7EB;
    display: block;
}
.employee-photo-placeholder {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: #F3F4F6;
    border: 1px solid #E5E7EB;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #9CA3AF;
    font-size: 16px;
}
/* No. Karyawan sekarang jadi pintu masuk ke Detail (gantikan tombol Detail yang
   dihapus) -- diberi gaya link supaya jelas bisa diklik. */
.employee-number-link {
    color: #2563EB;
    font-weight: 600;
    text-decoration: none;
}
.employee-number-link:hover { text-decoration: underline; }
.view-toggle {
    display: flex;
    gap: 4px;
}
.view-toggle .btn.active {
    background: #2563EB;
    color: #fff;
    border-color: #2563EB;
}
.employee-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 14px;
    margin-top: 10px;
}
.employee-grid.hidden { display: none; }
#employeeTable.hidden { display: none; }
.employee-card {
    border: 1px solid #E5E7EB;
    border-radius: 10px;
    padding: 16px;
    text-align: center;
    background: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
}
.employee-card .employee-photo-circle,
.employee-card .employee-photo-placeholder {
    width: 72px;
    height: 72px;
    font-size: 30px;
}
.employee-card .employee-card-name {
    font-weight: 600;
    color: #111827;
    margin-top: 4px;
}
.employee-card .employee-card-meta {
    font-size: 12px;
    color: #6B7280;
}
.employee-card .employee-card-actions {
    display: flex;
    gap: 6px;
    margin-top: 8px;
}
@media (max-width: 768px) {
    .employee-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}

/* Kartu Delegasi Approval -- 1 kartu per penerima delegasi (HR Department/Super Admin),
   isinya daftar Approver Asli yang sedang diwakilinya + tombol tambah(+)/hapus(-). Dipakai
   assets/js/settings-approval-delegations.js -- menggantikan form tanggal manual, delegasi
   aktif selama approver asli masih ada di dalam kartu. */
.delegate-cards-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 16px; margin-top: 16px;
}
.delegate-card { display: flex; flex-direction: column; }
.delegate-card-header { display: flex; align-items: center; gap: 10px; }
.delegate-avatar {
    width: 40px; height: 40px; border-radius: 50%; background: #EFF6FF;
    display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0;
}
.delegate-card-name { font-weight: 600; color: #111827; font-size: 14px; }
.delegate-card-role { font-size: 12px; color: var(--color-gray); }
.delegate-add-btn { margin-left: auto; }
.delegate-approvers-list {
    margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--color-border);
    display: flex; flex-direction: column; gap: 6px; flex: 1;
}
.delegate-approver-chip {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    background: #F9FAFB; border: 1px solid var(--color-border); border-radius: 8px;
    padding: 6px 8px 6px 12px; font-size: 13px;
}
.delegate-approver-chip-info { display: flex; flex-direction: column; }
.delegate-approver-chip-module { font-size: 11px; color: var(--color-gray); }
.delegate-approver-chip-remove {
    border: none; background: #FEE2E2; color: #DC2626; width: 24px; height: 24px;
    border-radius: 50%; cursor: pointer; font-weight: 700; line-height: 1; flex-shrink: 0;
}
.delegate-approver-chip-remove:hover { background: #FCA5A5; }

/* Picker "Approver Asli" (searchable checkbox list + Pilih Semua) di modal Tambah
   Approver Asli -- dipakai assets/js/settings-approval-delegations.js. */
.approver-picker-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: 8px; font-size: 12px; color: var(--color-gray);
}
.approver-picker-select-all { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.approver-picker-list {
    max-height: 220px; overflow-y: auto; margin-top: 6px;
    border: 1px solid var(--color-border); border-radius: 8px;
}
.approver-picker-item {
    display: flex; align-items: center; gap: 8px; padding: 8px 10px;
    border-bottom: 1px solid var(--color-border); font-size: 13px; cursor: pointer;
}
.approver-picker-item:last-child { border-bottom: none; }
.approver-picker-item:hover { background: #F9FAFB; }
.approver-picker-item input[type="checkbox"] { flex-shrink: 0; }
.approver-picker-grade { font-size: 11px; color: var(--color-gray); }
.approver-picker-empty { padding: 14px; text-align: center; margin: 0; }
