/* ==========================================================================
   MapsID - dashboard
   Satu tema gelap, dirancang untuk dipakai lama di depan layar.
   ========================================================================== */

:root {
    --bg:            #0d1117;
    --bg-soft:       #131a24;
    --panel:         #161d29;
    --panel-2:       #1c2532;
    --border:        #232e3e;
    --border-soft:   #1b2431;

    --text:          #e6edf5;
    --text-dim:      #94a3b8;
    --text-faint:    #64748b;

    --accent:        #3b82f6;
    --accent-soft:   rgba(59, 130, 246, .14);
    --green:         #22c55e;
    --green-soft:    rgba(34, 197, 94, .14);
    --red:           #ef4444;
    --red-soft:      rgba(239, 68, 68, .14);
    --amber:         #f59e0b;
    --amber-soft:    rgba(245, 158, 11, .14);
    --violet:        #a78bfa;

    --radius:        12px;
    --radius-sm:     8px;
    --shadow:        0 4px 24px rgba(0, 0, 0, .35);
    --sidebar-w:     236px;
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    --mono: "SF Mono", "Cascadia Code", Consolas, monospace;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ------------------------------------------------------------------ layout */
.layout {
    display: grid;
    grid-template-columns: var(--sidebar-w) 1fr;
    min-height: 100vh;
}

.sidebar {
    background: var(--bg-soft);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.brand {
    padding: 20px 18px 16px;
    border-bottom: 1px solid var(--border-soft);
}

.brand-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 17px;
    font-weight: 650;
    letter-spacing: -.2px;
}

/* Logo ALGORITMAID: merah pada latar transparan, jadi tidak perlu kotak
   berwarna di belakangnya - cukup gambarnya sendiri. */
.brand-mark {
    width: 30px;
    height: 30px;
    object-fit: contain;
    flex-shrink: 0;
}

.brand-sub {
    margin-top: 3px;
    font-size: 11px;
    color: var(--text-faint);
    padding-left: 40px;
}

.nav {
    padding: 12px 10px;
    flex: 1;
    overflow-y: auto;
}

.nav-label {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: .8px;
    color: var(--text-faint);
    padding: 12px 8px 6px;
    font-weight: 600;
}

.nav a {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: var(--radius-sm);
    color: var(--text-dim);
    font-weight: 500;
    margin-bottom: 2px;
    transition: background .12s, color .12s;
}

.nav a:hover {
    background: var(--panel-2);
    color: var(--text);
    text-decoration: none;
}

.nav a.active {
    background: var(--accent-soft);
    color: #93c5fd;
}

.nav-icon { width: 17px; text-align: center; flex-shrink: 0; }

.sidebar-foot {
    border-top: 1px solid var(--border-soft);
    padding: 12px;
}

.user-chip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: var(--radius-sm);
    background: var(--panel);
}

.avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--accent), var(--violet));
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 12px;
    flex-shrink: 0;
    color: #fff;
}

.user-chip-info { min-width: 0; flex: 1; }
.user-chip-name {
    font-weight: 600;
    font-size: 12.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.user-chip-role { font-size: 10.5px; color: var(--text-faint); text-transform: capitalize; }

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 24px;
    border-bottom: 1px solid var(--border);
    background: rgba(13, 17, 23, .82);
    backdrop-filter: blur(10px);
    position: sticky;
    top: 0;
    z-index: 40;
}

.topbar h1 { margin: 0; font-size: 18px; font-weight: 650; letter-spacing: -.3px; }
.topbar-sub { font-size: 12px; color: var(--text-faint); margin-top: 1px; }
.topbar-actions { display: flex; align-items: center; gap: 8px; }

.content { padding: 22px 24px 40px; flex: 1; }
.content.flush { padding: 0; }

/* ------------------------------------------------------------------ pieces */
.panel {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}

.panel-head {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-soft);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.panel-title { font-weight: 620; font-size: 14px; }
.panel-body { padding: 16px; }

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: 12px;
    margin-bottom: 18px;
}

.stat {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    position: relative;
    overflow: hidden;
}

.stat::after {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: var(--accent);
    opacity: .85;
}
.stat.is-green::after  { background: var(--green); }
.stat.is-red::after    { background: var(--red); }
.stat.is-amber::after  { background: var(--amber); }
.stat.is-violet::after { background: var(--violet); }

.stat-label {
    font-size: 11.5px;
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: .5px;
    font-weight: 600;
}

.stat-value {
    font-size: 27px;
    font-weight: 680;
    letter-spacing: -.8px;
    margin-top: 4px;
    font-variant-numeric: tabular-nums;
}

.stat-hint { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }

/* Perbandingan terhadap periode sebelumnya di kartu analitik. */
.stat-delta {
    font-size: 11.5px;
    font-weight: 620;
    margin-top: 3px;
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
}
.stat-delta.up   { color: #4ade80; }
.stat-delta.down { color: #f87171; }
.stat-delta .muted { font-weight: 500; }

/* Baris kunci-nilai di dalam panel (dipakai analitik & periode). */
.info-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
    font-size: 13px;
}
.info-row:last-child { border-bottom: none; }
.info-row .k { color: var(--text-dim); }
.info-row .v { font-weight: 600; text-align: right; }

/* Bar ketercapaian pembayaran per paket. */
.meter {
    height: 6px;
    border-radius: 99px;
    background: var(--panel-2);
    overflow: hidden;
}
.meter > i {
    display: block;
    height: 100%;
    border-radius: 99px;
    background: var(--green);
    transition: width .4s ease;
}

.progress {
    height: 5px;
    background: var(--panel-2);
    border-radius: 99px;
    overflow: hidden;
    margin-top: 9px;
}
.progress > i {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, var(--accent), var(--violet));
    border-radius: 99px;
    transition: width .5s ease;
}

/* ------------------------------------------------------------------ badges */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2.5px 8px;
    border-radius: 99px;
    font-size: 11px;
    font-weight: 620;
    text-transform: uppercase;
    letter-spacing: .3px;
    white-space: nowrap;
}
.badge::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.badge.online  { background: var(--green-soft);  color: #4ade80; }
.badge.offline { background: var(--red-soft);    color: #f87171; }
.badge.isolir  { background: var(--amber-soft);  color: #fbbf24; }
.badge.neutral { background: var(--panel-2);     color: var(--text-dim); }

.tag {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 6px;
    background: var(--panel-2);
    color: var(--text-dim);
    font-size: 11px;
    font-weight: 550;
}
/* Profile di router tidak sama dengan paket pelanggan - biasanya karena
   sedang diisolir/diblokir, tapi bisa juga tanda data tidak sinkron. */
.tag-warn { background: var(--amber-soft); color: #fbbf24; }

/* Status langganan dari comment MikroTik (bukan status koneksi). */
.badge.st-aktif   { background: var(--green-soft); color: #4ade80; }
.badge.st-waiting { background: var(--amber-soft); color: #fbbf24; }
.badge.st-psb     { background: rgba(99,102,241,.16); color: #a5b4fc; }
.badge.st-isolir  { background: var(--amber-soft); color: #fbbf24; }
.badge.st-blokir  { background: var(--red-soft);   color: #f87171; }
.badge.st-none    { background: var(--panel-2);    color: var(--text-dim); }

/* ------------------------------------------------------- chip filter jumlah */
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border-radius: 99px;
    border: 1px solid var(--border);
    background: var(--panel-2);
    color: var(--text-dim);
    font-size: 12.5px;
    font-weight: 560;
    font-family: inherit;
    cursor: pointer;
    transition: border-color .12s, background .12s, color .12s;
    white-space: nowrap;
}
.filter-chip b { font-variant-numeric: tabular-nums; color: var(--text); }
.filter-chip:hover { border-color: var(--accent); }
.filter-chip.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.filter-chip.active b { color: #fff; }

/* Titik warna kecil penanda arti tiap chip, hilang saat chip aktif. */
.filter-chip.online::before,
.filter-chip.offline::before,
.filter-chip.isolir::before,
.filter-chip.blokir::before {
    content: "";
    width: 7px; height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}
.filter-chip.online::before  { background: var(--green); }
.filter-chip.offline::before { background: var(--red); }
.filter-chip.isolir::before  { background: var(--amber); }
.filter-chip.blokir::before  { background: #a855f7; }

/* ----------------------------------------------------------------- buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 8px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--panel-2);
    color: var(--text);
    font-size: 13px;
    font-weight: 560;
    font-family: inherit;
    cursor: pointer;
    transition: filter .12s, background .12s, border-color .12s;
    white-space: nowrap;
}
.btn:hover:not(:disabled) { filter: brightness(1.18); text-decoration: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-green   { background: var(--green); border-color: var(--green); color: #04220f; }
.btn-danger  { background: var(--red-soft); border-color: rgba(239,68,68,.4); color: #fca5a5; }
.btn-ghost   { background: transparent; }
.btn-sm      { padding: 5px 10px; font-size: 12px; }
.btn-icon    { padding: 7px 9px; }

/* Tombol aksi ringkas di dalam baris tabel pelanggan. */
.btn-xs      { padding: 4px 8px; font-size: 11px; font-weight: 620; border-radius: 6px; }
.btn-wa      { background: var(--green-soft);       border-color: rgba(34,197,94,.4);  color: #4ade80; }
.btn-isolir  { background: var(--amber-soft);       border-color: rgba(245,158,11,.4); color: #fbbf24; }
.btn-blokir  { background: rgba(168,85,247,.16);    border-color: rgba(168,85,247,.4); color: #d8b4fe; }
.btn-aktif   { background: var(--green-soft);       border-color: rgba(34,197,94,.45); color: #4ade80; }
.btn-portal  { background: rgba(47,126,244,.16);    border-color: rgba(47,126,244,.45); color: #93c5fd; }

.act-cell { white-space: nowrap; }
.act-cell .btn { margin-right: 3px; }
.data td.center { text-align: center; }

/* ------------------------------------------------------------------ inputs */
.input, .select, .textarea {
    width: 100%;
    padding: 8px 11px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--bg-soft);
    color: var(--text);
    font-size: 13px;
    font-family: inherit;
    transition: border-color .12s, box-shadow .12s;
}
.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.input::placeholder, .textarea::placeholder { color: var(--text-faint); }
.textarea { resize: vertical; min-height: 60px; }
.select { cursor: pointer; }
.field { margin-bottom: 13px; }
.field label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-dim);
    margin-bottom: 5px;
}
.field-hint { font-size: 11.5px; color: var(--text-faint); margin-top: 4px; }

.toolbar {
    display: flex;
    gap: 9px;
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: 16px;
}
.toolbar .input, .toolbar .select { width: auto; min-width: 150px; }
.toolbar .grow { flex: 1; min-width: 220px; }

/* ------------------------------------------------------------------ tables */
.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--panel);
}

table.data { width: 100%; border-collapse: collapse; font-size: 13px; }

table.data th {
    text-align: left;
    padding: 11px 13px;
    background: var(--bg-soft);
    color: var(--text-dim);
    font-size: 11px;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: .5px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 2;
}

table.data td {
    padding: 11px 13px;
    border-bottom: 1px solid var(--border-soft);
    vertical-align: middle;
}
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: var(--panel-2); }
table.data tr.muted-row { opacity: .55; }

.cell-main { font-weight: 570; }
.cell-sub { font-size: 11.5px; color: var(--text-faint); margin-top: 1px; }
.mono { font-family: var(--mono); font-size: 12px; }

.empty {
    padding: 46px 20px;
    text-align: center;
    color: var(--text-faint);
}
.empty-icon { font-size: 30px; margin-bottom: 8px; opacity: .5; }

/* ------------------------------------------------------------------- misc */
.row { display: flex; gap: 10px; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.spacer { flex: 1; }
.muted { color: var(--text-faint); }
.dim { color: var(--text-dim); }
.nowrap { white-space: nowrap; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }

.thumb-row { display: flex; gap: 5px; align-items: center; }
.thumb {
    width: 38px;
    height: 38px;
    border-radius: 7px;
    object-fit: cover;
    border: 1px solid var(--border);
    cursor: pointer;
    transition: transform .12s;
    background: var(--panel-2);
}
.thumb:hover { transform: scale(1.08); }

.dot-live {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--green);
    box-shadow: 0 0 0 3px var(--green-soft);
    flex-shrink: 0;
}
.dot-live.stale { background: var(--amber); box-shadow: 0 0 0 3px var(--amber-soft); }
.dot-live.dead  { background: var(--red);   box-shadow: 0 0 0 3px var(--red-soft); }

.activity-item {
    display: flex;
    gap: 11px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-soft);
    font-size: 13px;
}
.activity-item:last-child { border-bottom: none; }
.activity-dot {
    width: 26px; height: 26px;
    border-radius: 8px;
    background: var(--panel-2);
    display: grid; place-items: center;
    font-size: 12px;
    flex-shrink: 0;
}
.activity-time { font-size: 11px; color: var(--text-faint); }

/* ------------------------------------------------------------------- login */
.login-page {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 20px;
    background:
        radial-gradient(900px 500px at 15% -10%, rgba(59,130,246,.13), transparent 60%),
        radial-gradient(800px 500px at 100% 110%, rgba(167,139,250,.11), transparent 60%),
        var(--bg);
}

.login-card {
    width: 100%;
    max-width: 372px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 30px 26px;
    box-shadow: var(--shadow);
}

.login-head { text-align: center; margin-bottom: 22px; }
.login-head .brand-logo { height: 62px; width: auto; display: block; margin: 0 auto 14px; }
.login-head h1 { margin: 0 0 4px; font-size: 21px; font-weight: 680; letter-spacing: -.4px; }
.login-head p { margin: 0; color: var(--text-faint); font-size: 13px; }
.login-note {
    margin: 18px 0 0;
    font-size: 12px;
    line-height: 1.6;
    color: var(--text-faint);
    text-align: center;
}

.alert {
    padding: 10px 13px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    margin-bottom: 14px;
    border: 1px solid transparent;
}
.alert-error { background: var(--red-soft); color: #fca5a5; border-color: rgba(239,68,68,.28); }
.alert-info  { background: var(--accent-soft); color: #93c5fd; border-color: rgba(59,130,246,.28); }
.alert-warn  { background: var(--amber-soft); color: #fbbf24; border-color: rgba(245,158,11,.28); }
/* Hijau untuk keadaan yang memang sudah benar - dipakai halaman Router
   MikroTik supaya "terhubung" tidak terbaca sekadar informasi biasa. */
.alert-ok    { background: var(--green-soft); color: #4ade80; border-color: rgba(34,197,94,.28); }
.alert-warn a { color: inherit; text-decoration: underline; }

/* -------------------------------------------------------------------- maps */
#map { width: 100%; height: 100%; background: var(--bg-soft); }
.map-shell { position: relative; height: calc(100vh - 61px); }

.map-overlay {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 500;
    background: rgba(22, 29, 41, .95);
    backdrop-filter: blur(10px);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 13px;
    width: 250px;
    box-shadow: var(--shadow);
    max-height: calc(100% - 28px);
    overflow-y: auto;
}
.map-overlay h3 { margin: 0 0 10px; font-size: 13px; font-weight: 650; }
.map-overlay .field { margin-bottom: 10px; }

.legend-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    padding: 3px 0;
    color: var(--text-dim);
}
.legend-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }

.marker-pin {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    border: 2.5px solid #fff;
    box-shadow: 0 1px 5px rgba(0, 0, 0, .55);
}
.marker-pin.online  { background: #22c55e; }
.marker-pin.offline { background: #ef4444; }
.marker-pin.isolir  { background: #f59e0b; }

/* ODP/ODC sengaja KOTAK, bukan bulat seperti rumah pelanggan. Di layar HP
   di bawah matahari beda warna saja gampang terlewat, dan salah mengira
   ODP sebagai rumah pelanggan berarti petugas mendatangi tempat yang
   keliru. Warnanya mengikuti nasib pelanggan di bawahnya:
   hijau ada yang online, merah semua mati, abu belum ada pelanggan. */
.marker-odp {
    width: 17px;
    height: 17px;
    border-radius: 4px;
    border: 2.5px solid #fff;
    box-shadow: 0 1px 5px rgba(0, 0, 0, .55);
}
.marker-odp.online  { background: #22c55e; }
.marker-odp.offline { background: #ef4444; }
.marker-odp.kosong  { background: #64748b; }

.legend-odp { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }

/* Info window Google Maps - nama kelasnya tidak didokumentasikan resmi
   (bisa berubah di versi API mendatang), tapi sudah stabil bertahun-tahun
   dan jadi cara umum menyamakan warnanya dengan tema gelap dashboard ini. */
.gm-style .gm-style-iw-c {
    background: var(--panel) !important;
    border: 1px solid var(--border) !important;
    border-radius: var(--radius) !important;
    box-shadow: var(--shadow) !important;
    padding: 0 !important;
}
.gm-style .gm-style-iw-d { overflow: auto !important; color: var(--text); }
.gm-style .gm-style-iw-t::after { background: var(--panel) !important; box-shadow: none !important; }
.gm-style .gm-ui-hover-effect { top: 4px !important; right: 4px !important; }
.gm-style .gm-ui-hover-effect > span { background-color: var(--text-dim) !important; }

.popup { padding: 13px; width: 236px; }
.popup h3 { margin: 0 0 3px; font-size: 14.5px; font-weight: 650; }
.popup .popup-user { font-size: 11.5px; color: var(--text-faint); margin-bottom: 9px; font-family: var(--mono); }
.popup-row {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding: 3.5px 0;
    font-size: 12.5px;
    border-bottom: 1px solid var(--border-soft);
}
.popup-row:last-of-type { border-bottom: none; }
.popup-row span:first-child { color: var(--text-faint); }
.popup-row span:last-child { text-align: right; font-weight: 550; }
.popup-actions { display: flex; gap: 6px; margin-top: 10px; }
.popup-actions .btn { flex: 1; }
.popup-photo {
    width: 100%;
    height: 128px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    margin-bottom: 9px;
    cursor: pointer;
    border: 1px solid var(--border);
}

/* ------------------------------------------------------------------ drawer */
.drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .58);
    backdrop-filter: blur(2px);
    z-index: 900;
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s;
}
.drawer-backdrop.open { opacity: 1; pointer-events: auto; }

.drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(440px, 100%);
    background: var(--panel);
    border-left: 1px solid var(--border);
    z-index: 901;
    transform: translateX(100%);
    transition: transform .22s cubic-bezier(.4, 0, .2, 1);
    display: flex;
    flex-direction: column;
}
.drawer.open { transform: translateX(0); }
.drawer-head {
    padding: 16px 18px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}
.drawer-head h2 { margin: 0; font-size: 16px; font-weight: 650; }
.drawer-body { padding: 18px; overflow-y: auto; flex: 1; }
.drawer-foot {
    padding: 13px 18px;
    border-top: 1px solid var(--border);
    display: flex;
    gap: 9px;
}
.drawer-foot .btn { flex: 1; }

.photo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
.photo-cell { position: relative; aspect-ratio: 1; }
.photo-cell img {
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    cursor: pointer;
}
.photo-del {
    position: absolute;
    top: 3px; right: 3px;
    width: 20px; height: 20px;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, .72);
    color: #fca5a5;
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    display: grid;
    place-items: center;
}
.photo-del:hover { background: var(--red); color: #fff; }

/* ------------------------------------------------------------------- toast */
.toast-host {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 1200;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}
.toast {
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    padding: 11px 15px;
    font-size: 13px;
    box-shadow: var(--shadow);
    animation: toast-in .2s ease;
    max-width: 330px;
    pointer-events: auto;
}
.toast.success { border-left-color: var(--green); }
.toast.error   { border-left-color: var(--red); }
.toast.warn    { border-left-color: var(--amber); }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.skeleton {
    background: linear-gradient(90deg, var(--panel-2) 25%, var(--border) 50%, var(--panel-2) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.3s infinite;
    border-radius: 5px;
    height: 12px;
}
@keyframes shimmer {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}

.spin { animation: spin 1s linear infinite; display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* -------------------------------------------------------------- responsive */
@media (max-width: 900px) {
    .layout { grid-template-columns: 1fr; }
    .sidebar {
        position: fixed;
        left: 0; top: 0; bottom: 0;
        width: var(--sidebar-w);
        z-index: 950;
        transform: translateX(-100%);
        transition: transform .22s cubic-bezier(.4, 0, .2, 1);
    }
    .sidebar.open { transform: translateX(0); }
    .menu-toggle { display: inline-flex !important; }
    .content { padding: 16px 14px 32px; }
    .topbar { padding: 13px 14px; }
    .map-overlay { width: calc(100% - 28px); max-height: 42%; }
    .map-shell { height: calc(100vh - 57px); }
}

.menu-toggle { display: none; }

@media (max-width: 560px) {
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .stat-value { font-size: 22px; }
    .toolbar .input, .toolbar .select, .toolbar .grow { width: 100%; min-width: 0; }
}

/* ------------------------------------------------- pemilih titik di peta */
/* Dipakai bersama halaman Tambah PPPoE dan dialog ubah data Pelanggan.
   Dialognya dibuat sendiri oleh js/mappicker.js, jadi tidak ada markup
   yang perlu diulang di kedua template. */
.picker-backdrop {
    position: fixed; inset: 0; z-index: 1200;
    background: rgba(3, 6, 12, .72);
    display: none; align-items: center; justify-content: center;
    padding: 20px;
}
.picker-backdrop.open { display: flex; }

.picker-box {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 14px; overflow: hidden;
    width: min(920px, 100%); max-height: 100%;
    display: flex; flex-direction: column;
}
.picker-head {
    display: flex; align-items: center; gap: 12px;
    padding: 14px 16px; border-bottom: 1px solid var(--border);
}
.picker-head h2 { margin: 0; font-size: 16px; font-weight: 650; }
.picker-head .cell-sub { margin-top: 2px; }
.picker-head > div:first-child { flex: 1; }

/* Tinggi dipatok, bukan mengikuti isi: Leaflet butuh kontainer yang sudah
   punya tinggi pasti saat dibuat, kalau tidak petanya keluar sebagai
   potongan abu-abu. */
.picker-map { height: min(60vh, 460px); width: 100%; background: var(--panel-2); }

.picker-foot {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 12px 16px; border-top: 1px solid var(--border);
}
.picker-foot .grow { flex: 1; min-width: 160px; }

@media (max-width: 560px) {
    .picker-backdrop { padding: 0; }
    .picker-box { border-radius: 0; height: 100%; }
    .picker-map { height: 100%; flex: 1; }
    .picker-foot .btn { flex: 1; }
}

/* Foto yang dipilih tapi BELUM terunggah - dipakai form Tambah PPPoE. */
.foto-pratinjau { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
.foto-pratinjau img {
    width: 72px; height: 72px; object-fit: cover;
    border-radius: 9px; border: 1px solid var(--border);
}
