/* 01 TOKENS - Base Data */
:root {
    --io-color-blue-500: #1E4E79; --io-color-blue-900: #1A3D54;
    --io-color-green-100: #F0FDF4; --io-color-green-500: #14532D;
    --io-color-gray-100: #F8FAFC; --io-color-gray-200: #E2E8F0;
    --io-color-gray-600: #475569; --io-color-gray-900: #1E293B;
    --io-color-red-100: #FEE2E2; --io-color-red-500: #991B1B;
    --io-color-white: #FFFFFF;
    --io-color-yellow-100: #FEF3C7; --io-color-yellow-500: #78350F;

    /* Warna baru — diambil dari logo Iuran Online (gradasi biru muda→hijau
       di ikon, "iuran" biru tua, "online" hijau). */
    --io-color-emerald-500: #16A34A;
    --io-color-emerald-600: #15803D;
    --io-color-sky-400:     #38BDF8;

    --io-color-secondary:    var(--io-color-emerald-500);
    --io-color-accent-light: var(--io-color-sky-400);
    --io-gradient-brand: linear-gradient(135deg, var(--io-color-blue-500) 0%, var(--io-color-emerald-500) 100%);

    --io-color-bg: var(--io-color-gray-100);
    --io-color-border: var(--io-color-gray-200);
    --io-color-danger: var(--io-color-red-500);
    --io-color-danger-bg: var(--io-color-red-100);
    --io-color-primary: var(--io-color-blue-500);
    --io-color-primary-dark: var(--io-color-blue-900);
    --io-color-success: var(--io-color-green-500);
    --io-color-success-bg: var(--io-color-green-100);
    --io-color-surface: var(--io-color-white);
    --io-color-text: var(--io-color-gray-900);
    --io-color-text-muted: var(--io-color-gray-600);
    --io-color-warning: var(--io-color-yellow-500);
    --io-color-warning-bg: var(--io-color-yellow-100);

    --io-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --io-space-1: 4px; --io-space-2: 8px; --io-space-3: 12px; --io-space-4: 16px; --io-space-6: 24px;
    --io-radius-2: 8px; --io-radius-3: 12px; --io-radius-round: 999px;
    --io-radius-4: 20px;
    --io-shadow-1: 0 1px 3px rgba(15,23,42,0.08);
    --io-weight-normal: 400; --io-weight-medium: 500; --io-weight-semibold: 600; --io-weight-bold: 700;
}

/* 02 TYPOGRAPHY */
.io-heading-xl { font-size: 24px; font-weight: var(--io-weight-bold); }
.io-heading-lg { font-size: 20px; font-weight: var(--io-weight-bold); }
.io-heading-md { font-size: 18px; font-weight: var(--io-weight-semibold); }
.io-body-md    { font-size: 14px; font-weight: var(--io-weight-normal); }
.io-caption    { font-size: 12px; font-weight: var(--io-weight-normal); }

/* 03 LAYOUT */
.io-page { width: 100%; background: var(--io-color-bg); }
.io-container { max-width: 1200px; margin: 0 auto; }
.io-stack { display: flex; flex-direction: column; }
.io-inline { display: flex; flex-direction: row; }
.io-actions { display: flex; flex-direction: column; }
@media (min-width: 640px) { .io-actions { flex-direction: row; } }
.io-grid { display: grid; }
@media (min-width: 768px) { .io-grid-2 { grid-template-columns: repeat(2, 1fr); } }

/* 04 COMPONENTS */
.io-card { background: var(--io-color-surface); border: 1px solid var(--io-color-border); border-radius: var(--io-radius-4); box-shadow: var(--io-shadow-1); }
a.io-card { text-decoration: none; color: inherit; display: block; transition: transform .15s ease, box-shadow .15s ease; }
a.io-card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(15,23,42,0.12); }

.io-hero { background: var(--io-gradient-brand); border-radius: var(--io-radius-4); }
.io-hero .io-caption,
.io-hero .io-heading-xl,
.io-hero .io-heading-lg,
.io-hero .io-heading-md { color: var(--io-color-white) !important; }

.io-btn { display: inline-flex; justify-content: center; align-items: center; padding: var(--io-space-2) var(--io-space-4); border-radius: var(--io-radius-2); font-weight: var(--io-weight-semibold); cursor: pointer; border: 1px solid transparent; box-shadow: 0 1px 2px rgba(15,23,42,0.08); transition: transform .15s ease, box-shadow .15s ease, opacity .15s ease; text-decoration: none; }
.io-btn:active { transform: scale(0.98); }
.io-btn.io-primary:hover { filter: brightness(1.06); box-shadow: 0 4px 14px rgba(22,163,74,0.25); }

.io-input { width: 100%; padding: var(--io-space-2) var(--io-space-3); border: 1px solid var(--io-color-border); border-radius: var(--io-radius-2); }
.io-badge { display: inline-flex; padding: var(--io-space-1) var(--io-space-2); border-radius: var(--io-radius-round); font-size: 12px; }
.io-divider { height: 1px; background-color: var(--io-color-border); width: 100%; }
.io-avatar { width: 40px; height: 40px; border-radius: var(--io-radius-round); background: var(--io-color-gray-200); }

/* 05 ANATOMY (Zero-Opinion) */
.io-head, .io-body, .io-foot, .io-media, .io-action, .io-meta, .io-aside, .io-extra {}

/* 06 UTILITIES */
.io-gap-4 { gap: var(--io-space-4); }
.io-items-center { align-items: center; }
.io-justify-between { justify-content: space-between; }
.io-w-full { width: 100%; }
.io-hidden { display: none; }
.io-gap-6 { gap: var(--io-space-6); }
.io-flex-1 { flex: 1; }

/* 07 SEMANTICS */
.io-primary { background: var(--io-gradient-brand); color: var(--io-color-white); }
.io-success { background: var(--io-color-success-bg); color: var(--io-color-success); }
.io-warning { background: var(--io-color-warning-bg); color: var(--io-color-warning); }
.io-danger  { background: var(--io-color-danger-bg); color: var(--io-color-danger); }
.io-btn-inverse { background: var(--io-color-surface); color: var(--io-color-primary); }
.io-btn-ghost { background: transparent; border: 1px solid rgba(255,255,255,.5); color: var(--io-color-white); }

.io-tabs { display: flex; gap: var(--io-space-4); border-bottom: 1px solid var(--io-color-border); overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }
.io-tabs a { padding: var(--io-space-2) var(--io-space-1); text-decoration: none; color: var(--io-color-text-muted); font-weight: var(--io-weight-semibold); font-size: 14px; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: 0.2s; flex-shrink: 0; }
.io-tabs a.active { color: var(--io-color-primary); border-bottom: 2px solid var(--io-color-primary); }

/* Base style tabel — SEBELUMNYA TIDAK PERNAH ADA sama sekali di file ini,
   walau class .io-table & .io-table-container dipakai luas di banyak
   halaman publik (Kartu IPL, Anggota KK, Dokumen). Akibatnya di semua
   halaman itu, tabel tidak pernah benar-benar bisa di-scroll horizontal
   di mobile — cuma "kebetulan" ke-cover kalau halamannya dalam konteks
   WooCommerce My Account (yang punya definisi scoped-nya sendiri di
   iuran-myaccount.css) atau IO Admin (io-admin.css) — tapi halaman
   publik berdiri sendiri seperti Kartu IPL sama sekali tidak ke-cover. */
.io-table-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin-top: var(--io-space-3);
}
.io-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 480px;
}
.io-table th, .io-table td {
    padding: 10px 12px;
    border: 1px solid var(--io-color-border);
    text-align: left;
}
.io-table thead { background: var(--io-color-bg); }
.io-block-header td {
    background: var(--io-color-bg);
    font-weight: var(--io-weight-bold);
    color: var(--io-color-text);
    border-top: 2px solid var(--io-color-border);
}

/* Highlight kolom bulan berjalan (Kartu IPL) */
.io-col-highlight {
    background: rgba(22, 163, 74, 0.08) !important;
    box-shadow: inset 0 0 0 1px rgba(22, 163, 74, 0.25);
}

/* Highlight baris rumah sendiri (Kartu IPL) — beda warna (biru) dari
   highlight kolom bulan (hijau) supaya tidak ketuker maksudnya. Kalau
   baris rumah sendiri KEBETULAN juga di kolom bulan berjalan, box-shadow
   biru di sini menang (dipasang belakangan di source order). */
.io-row-highlight td {
    background: rgba(30, 78, 121, 0.06) !important;
    font-weight: var(--io-weight-bold);
}
.io-row-highlight td.io-col-highlight {
    background: rgba(30, 78, 121, 0.14) !important;
}

/* Form filter (Tahun/Blok/dll) — dipakai di beberapa halaman (Kartu IPL,
   dll) tapi selama ini tidak pernah didefinisikan di sini, jadi elemennya
   cuma "ngambang" tanpa layout flex yang benar. */
.io-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--io-space-4);
    align-items: flex-end;
    background: var(--io-color-surface);
    border: 1px solid var(--io-color-border);
    border-radius: var(--io-radius-3);
    padding: var(--io-space-4);
}

.io-tab-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    margin-left: 5px;
    border-radius: var(--io-radius-round);
    background: var(--io-color-danger);
    color: var(--io-color-white);
    font-size: 11px;
    font-weight: var(--io-weight-bold);
    line-height: 1;
    vertical-align: middle;
}

/* 08 STATES */
.is-loading   { cursor: wait; pointer-events: none; }
.is-disabled  { opacity: 0.6; pointer-events: none; }

/* 09 CARD SPACING (fix: konten mepet border) */
.io-head, .io-body, .io-foot { padding: var(--io-space-4); }

/* 10 RESPONSIVE CARD GRID (1 mobile / 2 tablet / 3-4 desktop) */
.io-grid-cards { grid-template-columns: 1fr; }
@media (min-width: 640px) {
    .io-grid-cards { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
}

/* 11 BULK BUYING (Beli Massal) */
.cb-pilih-wrap { display: none; }
.iuran-beli.mode-active .cb-pilih-wrap { display: block; }

.io-sticky-bar {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 999;
    background: var(--io-color-surface);
    border-top: 1px solid var(--io-color-border);
    border-radius: var(--io-radius-3) var(--io-radius-3) 0 0;
    box-shadow: 0 -4px 16px rgba(15,23,42,0.15);
    padding: var(--io-space-4);
}

/* 12 iOS "ADD TO HOME SCREEN" BANNER */
.io-ios-banner {
    display: none;
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 12px;
    z-index: 998;
    background: var(--io-color-surface);
    border: 1px solid var(--io-color-border);
    border-radius: var(--io-radius-3);
    box-shadow: 0 -4px 16px rgba(15,23,42,0.15);
    padding: var(--io-space-3) var(--io-space-4);
    align-items: center;
    gap: var(--io-space-3);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .2s ease, transform .2s ease;
}
.io-ios-banner.is-visible {
    display: flex;
    opacity: 1;
    transform: translateY(0);
}
.io-ios-banner-icon { font-size: 22px; line-height: 1; flex-shrink: 0; }
.io-ios-banner-text { flex: 1; font-size: 13px; line-height: 1.4; color: var(--io-color-text); }
.io-ios-banner-close {
    background: none;
    border: none;
    font-size: 20px;
    line-height: 1;
    color: var(--io-color-text-muted);
    cursor: pointer;
    padding: 4px 8px;
    flex-shrink: 0;
}

/* 13 ANDROID/DESKTOP "INSTALL APP" BANNER (via beforeinstallprompt) */
.io-install-banner {
    display: none;
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 12px;
    z-index: 998;
    background: var(--io-color-surface);
    border: 1px solid var(--io-color-border);
    border-radius: var(--io-radius-3);
    box-shadow: 0 -4px 16px rgba(15,23,42,0.15);
    padding: var(--io-space-3) var(--io-space-4);
    align-items: center;
    gap: var(--io-space-3);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .2s ease, transform .2s ease;
}
.io-install-banner.is-visible {
    display: flex;
    opacity: 1;
    transform: translateY(0);
}
.io-install-banner-icon { font-size: 22px; line-height: 1; flex-shrink: 0; }
.io-install-banner-text { flex: 1; font-size: 13px; line-height: 1.4; color: var(--io-color-text); }
.io-install-banner-btn {
    flex-shrink: 0;
    padding: var(--io-space-2) var(--io-space-4);
    border-radius: var(--io-radius-2);
    border: none;
    background: var(--io-color-primary);
    color: var(--io-color-white);
    font-weight: var(--io-weight-semibold);
    font-size: 13px;
    cursor: pointer;
}
/* 14 IO BERITA WIDGET */
.io-berita-cat-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--io-color-bg);
    padding: var(--io-space-3) var(--io-space-4);
    border-radius: var(--io-radius-2);
}
.io-berita-cat-header a {
    color: var(--io-color-primary);
    text-decoration: none;
    font-weight: var(--io-weight-semibold);
    font-size: 13px;
    flex-shrink: 0;
}

.io-berita-items {
    display: flex;
    flex-direction: column;
    gap: var(--io-space-4);
    margin-top: var(--io-space-3);
}
.io-berita-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: var(--io-space-3);
    text-decoration: none;
    color: inherit;
}
.io-berita-thumb {
    width: 56px;
    height: 56px;
    flex-shrink: 0;
    border-radius: var(--io-radius-2);
    background-color: var(--io-color-gray-200);
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
}
.io-berita-title {
    font-size: 14px;
    font-weight: var(--io-weight-medium);
    line-height: 1.4;
}

@media (min-width: 768px) {
    .io-berita-items {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: var(--io-space-4);
    }
    .io-berita-item {
        flex-direction: column;
        align-items: stretch;
    }
    .io-berita-thumb {
        width: 100%;
        height: 120px;
    }
    .io-berita-title {
        margin-top: var(--io-space-1);
    }
}

/* 15 EMERGENCY FLOATING BUTTON (pojok kiri bawah, link ke Page /emergency) */
.io-emergency-fab {
    position: fixed;
    left: 16px;
    bottom: 16px;
    z-index: 996;
    width: 52px;
    height: 52px;
    border-radius: var(--io-radius-round);
    background: var(--io-color-danger);
    color: var(--io-color-white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    text-decoration: none;
    box-shadow: 0 4px 14px rgba(0,0,0,.25);
    transition: transform .15s ease;
}
.io-emergency-fab:hover { transform: scale(1.06); }

/* 16 TABEL RESPONSIVE-STACK (jadi kartu bertumpuk di layar sempit,
   dipakai untuk tabel dengan banyak kolom seperti Anggota Keluarga KK) */
@media (max-width: 600px) {
    .io-table-responsive-stack thead { display: none; }
    .io-table-responsive-stack,
    .io-table-responsive-stack tbody,
    .io-table-responsive-stack tr,
    .io-table-responsive-stack td {
        display: block;
        width: 100%;
    }
    .io-table-responsive-stack { min-width: 0; }
    .io-table-responsive-stack tr {
        margin-bottom: 12px;
        border: 1px solid var(--io-color-border);
        border-radius: var(--io-radius-2);
        padding: 4px 12px;
    }
    .io-table-responsive-stack td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
        padding: 8px 0;
        border: none;
        border-bottom: 1px solid var(--io-color-border);
        text-align: right;
    }
    .io-table-responsive-stack td:last-child { border-bottom: none; }
    .io-table-responsive-stack td::before {
        content: attr(data-label);
        font-weight: var(--io-weight-semibold);
        color: var(--io-color-text-muted);
        text-align: left;
        flex-shrink: 0;
    }
}

/* 17 /BELI: TOMBOL & BADGE HIERARKI VISUAL */
.io-btn-outline {
    background: transparent;
    border: 1.5px solid var(--io-color-primary);
    color: var(--io-color-primary);
}
.io-btn-outline:hover { background: rgba(30,78,121,0.06); }

/* Disalin dari io-admin.css — supaya halaman publik yang perlu konsisten
   sama gaya tombol Laporan admin (misal Kartu IPL) tidak perlu load
   io-admin.css sekalian (berisiko bentrok definisi .io-filter-bar dobel). */
.io-btn-detail { background: #2563eb; color: #fff; }
.io-btn-detail:hover { background: #1d4ed8; }

.io-neutral { background: var(--io-color-gray-100); color: var(--io-color-text-muted); }

.io-card.is-selected {
    border-color: var(--io-color-primary);
    box-shadow: 0 0 0 1px var(--io-color-primary);
}

/* 18 DASHBOARD: CARD HEADER TINT & CHEVRON */
.io-card-head-tint {
    background: rgba(30, 78, 121, 0.05);
    border-radius: var(--io-radius-4) var(--io-radius-4) 0 0;
}
.io-card-chevron {
    font-size: 20px;
    font-weight: var(--io-weight-bold);
    color: var(--io-color-primary);
    line-height: 1;
    flex-shrink: 0;
}

/* Fix kontras teks "Menu" (toggle mobile bawaan tema Kadence) yang hampir
   tidak kelihatan saat non-aktif — theme-level element, bukan markup
   plugin kita, jadi diperbaiki lewat override CSS di sini. */
.menu-toggle-label,
.menu-toggle-icon {
    color: var(--io-color-text) !important;
}

/* Tabel bawaan WooCommerce (order-pay, checkout review, dll) sering
   terpotong di mobile karena tidak ada wrapper scroll — WC render tabel
   ini langsung tanpa container, beda dari tabel kita sendiri yang sudah
   dibungkus io-table-container. Trik CSS murni: cukup jadikan <table>
   itu sendiri jadi container scroll, JANGAN ubah display thead/tbody/tr
   di dalamnya (itu bisa merusak struktur kolom malah). */
.woocommerce-checkout-review-order-table,
table.shop_table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}

/* Spinner loading global — dipakai iuran-ux-helpers.js di semua tombol
   aksi. Pakai currentColor supaya otomatis cocok warna teks tombol
   apapun (primary gradient putih, outline biru, dst) tanpa perlu diatur
   manual per tombol. */
.iuran-spinner {
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-right: 7px;
    vertical-align: -2px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    opacity: 0.85;
    animation: iuran-spin 0.65s linear infinite;
}
@keyframes iuran-spin {
    to { transform: rotate(360deg); }
}