/* ============================================================================
   PRÉSTAMOS CACHO — Dark Premium
   Superficies azul-negras (nunca negro puro), dorado primario, teal/verde
   WhatsApp/azul SINPE como acentos de dominio. Space Grotesk para display y
   cifras, DM Sans para UI. Leitmotiv del sistema: cristal (blur) SOLO en topbar
   y en el fondo de los modales; el resto es superficie sobria con borde.
   ========================================================================= */

:root{
    /* ── Superficies ─────────────────────────────────────────────────────── */
    --bg:#0b0e14;--bg2:#0e1219;--card:#151a23;--card2:#1b2230;--inset:#10151f;

    /* ── Bordes ────────────────────────────────────────────────────────────
       --border separa (decorativo, no exige contraste).
       --border-input marca CONTROLES: exige ≥3:1 (WCAG 1.4.11). El valor
       pedido (#3a4557) daba 1.80:1 sobre --card, o sea rompía elBehavior T1;
       se sube a #5a6b80 → 3.20:1 sobre --card y 3.35:1 sobre --inset. */
    --border:#262e3d;--border-input:#5a6b80;

    /* ── Texto ────────────────────────────────────────────────────────────── */
    --fg:#f2f5f9;--muted:#9aa7ba;--accent:#f2f5f9;--accent2:#c8d2e0;

    /* ── Marca / acento primario (gold) ──────────────────────────────────── */
    --primary:#f0b429;--primary-2:#f59e0b;--on-primary:#1a1202;
    --primary-soft:rgba(240,180,41,.12);--primary-line:rgba(240,180,41,.35);

    /* ── Estados de dominio ───────────────────────────────────────────────── */
    --teal:#14b8a6;
    --whatsapp:#25d366;--on-whatsapp:#08281a;
    --sinpe:#3b82f6;--sinpe-fg:#60a5fa;
    --danger:#ef4444;--danger-fg:#f87171;
    /* --success es el verde de "al día / pagado / cerrado". --accent queda
       como alias porque js/ lo usa como color de éxito (ui.js, map.js,
       clients.js, loans.js, dashboard.js, reports.js, settings.js). */
    --success:#34d399;--success-2:#6ee7b7;--accent:var(--success);--accent2:var(--success-2);

    /* ── Tokens semánticos (conservados: los usa css y a11y) ─────────────── */
    --color-primary:#f2f5f9;--color-primary-contrast:#0b0e14;
    --color-focus:#f0b429;

    /* ── Elevación ──────────────────────────────────────────────────────────
       Escala corta y contenida: en superficies casi negras una sombra negra
       apenas se lee, así que la profundidad la da el borde + la línea de luz
       superior (inset 0 1px 0). Nada de sombras theatre. */
    --shadow-sm:0 1px 0 rgba(255,255,255,.03);
    --shadow-md:0 8px 24px rgba(0,0,0,.35);
    --shadow-lg:0 24px 64px rgba(0,0,0,.5);
    --shadow-gold:0 4px 14px rgba(240,180,41,.25);
    --edge-light:inset 0 1px 0 rgba(255,255,255,.03);

    /* ── Geometry ───────────────────────────────────────────────────────────
       --radius y --radius-sm se conservan como alias porque js/ los usa en
       estilos inline (reports.js, clients.js, loans.js). */
    --radius-sm:10px;--radius:14px;
    --radius-btn:10px;--radius-card:14px;--radius-modal:16px;--radius-pill:999px;

    /* ── Spacing scale ───────────────────────────────────────────────────── */
    --space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:24px;--space-6:32px;

    /* ── Type scale ──────────────────────────────────────────────────────── */
    --text-xs:12px;--text-sm:13px;--text-base:15px;--text-lg:18px;--text-xl:24px;--text-2xl:28px;
    --font-ui:'DM Sans',sans-serif;
    --font-display:'Space Grotesk',sans-serif;
}

/* ========== RESET & BASE ========== */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;overflow-x:hidden;width:100%;}
body{font-family:var(--font-ui);background:var(--bg);color:var(--fg);min-height:100vh;overflow-x:hidden;font-size:var(--text-base);line-height:1.5;letter-spacing:.01em;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}
h1,h2,h3,h4,h5{font-family:var(--font-display);line-height:1.2;letter-spacing:.01em;}
h1,h2{font-weight:700;}
h3,h4,h5{font-weight:600;}
button{cursor:pointer;font-family:var(--font-ui);border-radius:var(--radius-btn);}
input,select,textarea{font-family:var(--font-ui);}

/* Scrollbar discreto: la app es densa, la barra no debe competir con el dato. */
*{scrollbar-width:thin;scrollbar-color:#2b3547 transparent;}
::-webkit-scrollbar{width:8px;height:8px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:#2b3547;border-radius:99px;}
::-webkit-scrollbar-thumb:hover{background:var(--border-input);}
::selection{background:rgba(240,180,41,.85);color:var(--on-primary);}
::-moz-selection{background:rgba(240,180,41,.85);color:var(--on-primary);}

/* ========== TYPOGRAPHY ========== */
.text-muted{color:var(--muted);}.text-accent{color:var(--fg);}
.text-gold{color:var(--primary);}.text-danger{color:var(--danger-fg);}
.font-mono{font-family:var(--font-display),monospace;}
.fw-700{font-weight:700;}
/* Cifras: siempre Space Grotesk con ancho de dígito fijo — en columnas de
   montos y cuotas, un "1" que cambia de ancho hace imposible comparar de un
   vistazo. Es la decisión que más legitimacy le da a la pantalla. */
.kpi-val,.coll-kpi-val,.s-val,.cierre-val,.cls-stat-val,.d-value,
.cobro-amount-badge,.badge-code,.monto,.tabular{font-family:var(--font-display);font-variant-numeric:tabular-nums;}

/* ========== FORM CONTROLS ========== */
.input{width:100%;background:var(--inset);border:1.5px solid var(--border-input);border-radius:var(--radius-btn);padding:11px 14px;color:var(--fg);font-size:var(--text-base);letter-spacing:.01em;transition:border-color .16s,box-shadow .16s,background .16s;outline:none;appearance:none;}
.input:hover{border-color:#48566b;}
.input:focus{border-color:var(--color-focus);background:var(--bg2);box-shadow:0 0 0 3px rgba(240,180,41,.15);}
.input::placeholder{color:var(--muted);}
.input:disabled{opacity:.55;cursor:not-allowed;}
.input.error{border-color:var(--danger);box-shadow:0 0 0 3px rgba(239,68,68,.14);}
textarea.input{resize:vertical;min-height:80px;}
.input-icon{position:relative;}
.input-icon .icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:13px;pointer-events:none;}
.input-icon .input{padding-left:38px;}
select.input{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa7ba' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:36px;}
/* Labels en sentence-case: las MAYÚSCULAS gritan en una UI de alto densidad y
   además piorizan la lectura de la etiqueta (WCAG 1.4.8 la desaconseja). */
.form-group{margin-bottom:14px;}
.form-label{display:block;margin-bottom:6px;font-size:var(--text-sm);font-weight:500;color:var(--muted);}
.form-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;}
.field-error{font-size:12px;color:var(--danger-fg);margin-top:4px;display:none;}
.field-error.show{display:block;}
.form-actions{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-end;margin-top:22px;padding-top:18px;border-top:1px solid var(--border);}
.photo-upload-area{border:2px dashed var(--border-input);border-radius:var(--radius-btn);padding:16px;text-align:center;cursor:pointer;transition:border-color .16s,background .16s;position:relative;overflow:hidden;}
.photo-upload-area:hover{border-color:var(--primary);background:var(--primary-soft);}
.photo-upload-area input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;height:100%;}
.photo-preview{width:100%;max-height:160px;object-fit:cover;border-radius:var(--radius-sm);display:block;margin-top:10px;}
.photo-thumb{width:38px;height:38px;border-radius:8px;object-fit:cover;border:2px solid var(--border-input);cursor:pointer;}
.freq-select-btn{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:var(--radius-btn);border:1.5px solid var(--border-input);background:var(--inset);color:var(--muted);font-size:13px;font-weight:600;cursor:pointer;transition:all .16s;}
.freq-select-btn:hover{border-color:var(--muted);color:var(--fg);}
.freq-select-btn.active{border-color:var(--primary);background:var(--primary-soft);color:var(--primary);}
.freq-grid{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px;}
.pay-method-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:16px;}
.pay-method-btn{border:1.5px solid var(--border-input);border-radius:var(--radius-btn);padding:14px 10px;background:var(--inset);cursor:pointer;text-align:center;transition:all .16s;display:flex;flex-direction:column;align-items:center;gap:7px;}
.pay-method-btn:hover{border-color:var(--muted);}
.pay-method-btn i{font-size:22px;}
.pay-method-btn .pm-label{font-size:13px;font-weight:600;}
.pay-method-btn .pm-sub{font-size:11px;color:var(--muted);}
.pay-method-btn.selected{border-color:var(--primary);background:var(--primary-soft);}
.pay-method-btn.selected i,.pay-method-btn.selected .pm-label{color:var(--primary);}
.pay-method-btn.selected-sinpe{border-color:var(--sinpe);background:rgba(59,130,246,.12);}
.pay-method-btn.selected-sinpe i,.pay-method-btn.selected-sinpe .pm-label{color:var(--sinpe-fg);}

/* ========== BUTTONS ========== */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:10px 20px;border:1px solid transparent;border-radius:var(--radius-btn);font-size:var(--text-base);font-weight:600;letter-spacing:.01em;transition:background .16s,border-color .16s,color .16s,box-shadow .16s,transform .16s;white-space:nowrap;}
.btn:active{transform:scale(.97);}
.btn:disabled,.btn[disabled]{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none;}
/* Primario = el único elemento realmente "dorado" de la pantalla. */
.btn-primary{background:linear-gradient(135deg,#fbbf24,#f59e0b);color:var(--on-primary);box-shadow:var(--shadow-gold);}
.btn-primary:hover{box-shadow:0 6px 20px rgba(240,180,41,.34);transform:translateY(-1px);}
.btn-primary:active{transform:translateY(0) scale(.98);}
.btn-ghost{background:transparent;color:var(--muted);border:1.5px solid var(--border-input);}
.btn-ghost:hover{background:var(--card2);color:var(--fg);border-color:var(--muted);}
.btn-danger-soft{background:rgba(239,68,68,.12);color:var(--danger-fg);border:1.5px solid rgba(239,68,68,.32);}
.btn-danger-soft:hover{background:rgba(239,68,68,.2);border-color:rgba(239,68,68,.5);}
.btn-success-soft{background:rgba(52,211,153,.12);color:var(--success);border:1.5px solid rgba(52,211,153,.3);}
.btn-success-soft:hover{background:rgba(52,211,153,.2);border-color:rgba(52,211,153,.45);}
.btn-gold-soft{background:var(--primary-soft);color:var(--primary);border:1.5px solid var(--primary-line);}
.btn-gold-soft:hover{background:rgba(240,180,41,.2);border-color:rgba(240,180,41,.5);}
/* Gradiente rojo profundo: #ef4444 con texto blanco daba 3.76:1, por debajo
   de AA. El rango #dc2626→#b91c1c deja el texto blanco en 4.83:1 / 6.47:1. */
.btn-danger{background:linear-gradient(135deg,#dc2626,#b91c1c);color:#fff;border:none;}
.btn-danger:hover{box-shadow:0 6px 18px rgba(220,38,38,.32);transform:translateY(-1px);}
.btn-danger:active{transform:translateY(0) scale(.98);}
/* WhatsApp: verde de marca con texto oscuro (7.97:1). El blanco sobre #25d366
   daba 1.98:1 — ilegible. */
.btn-whatsapp{background:linear-gradient(135deg,#25d366,#12a15a);color:var(--on-whatsapp);border:none;}
.btn-whatsapp:hover{box-shadow:0 4px 14px rgba(37,211,102,.34);transform:translateY(-1px);}
.btn-whatsapp:active{transform:translateY(0) scale(.98);}
.btn-sm{padding:6px 13px;font-size:12px;}
.btn-icon{padding:8px;}
.btn-full{width:100%;}
.btn-close{width:32px;height:32px;border-radius:var(--radius-btn);background:var(--inset);border:1px solid var(--border);color:var(--muted);display:flex;align-items:center;justify-content:center;transition:all .16s;flex-shrink:0;}
.btn-close:hover{color:var(--fg);border-color:var(--border-input);background:var(--card2);}

/* ========== BADGES ========== */
/* Pills de tinte suave: el color lo da el fondo, la legibilidad el texto. */
.badge{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:var(--radius-pill);font-size:11px;font-weight:600;}
.badge-green{background:rgba(52,211,153,.14);color:var(--success);border:1px solid rgba(52,211,153,.3);}
.badge-gold{background:rgba(240,180,41,.14);color:var(--primary);border:1px solid var(--primary-line);}
.badge-red{background:rgba(239,68,68,.12);color:var(--danger-fg);border:1px solid rgba(239,68,68,.32);}
.badge-muted{background:rgba(255,255,255,.06);color:var(--muted);}
.badge-code{background:var(--inset);color:var(--fg);border:1px solid var(--border);font-family:var(--font-display);font-size:12px;padding:2px 9px;border-radius:var(--radius-sm);}
.badge-sinpe{background:rgba(59,130,246,.12);color:var(--sinpe-fg);border:1px solid rgba(59,130,246,.32);display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:var(--radius-pill);font-size:11px;font-weight:600;}
.badge-efectivo{background:rgba(255,255,255,.06);color:var(--fg);border:1px solid var(--border-input);display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:var(--radius-pill);font-size:11px;font-weight:600;}
.sync-badge{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 11px;border-radius:var(--radius-pill);background:rgba(52,211,153,.14);color:var(--success);border:1px solid rgba(52,211,153,.3);}
.sync-badge.syncing{background:rgba(240,180,41,.14);color:var(--primary);border-color:var(--primary-line);animation:syncPulse 1s ease infinite;}
.moroso-dias-badge{background:rgba(239,68,68,.18);color:#fecaca;border:1px solid rgba(239,68,68,.45);border-radius:var(--radius-pill);padding:2px 9px;font-size:11px;font-weight:700;}

/* ========== CARDS ========== */
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-card);box-shadow:var(--edge-light),var(--shadow-md);overflow:hidden;}
.card-header{padding:18px 22px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;}
.card-header h3{font-size:16px;font-weight:600;}
.stat-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-card);padding:20px 22px;box-shadow:var(--edge-light),var(--shadow-md);transition:transform .18s,border-color .18s,box-shadow .18s;}
.stat-card:hover{transform:translateY(-2px);border-color:var(--border-input);box-shadow:var(--edge-light),var(--shadow-lg);}
.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;}
.detail-item{background:var(--inset);border:1px solid var(--border);border-radius:var(--radius-btn);padding:13px;min-width:0;}
.detail-item .d-label{font-size:11px;color:var(--muted);margin-bottom:4px;}
.detail-item .d-value{font-size:15px;font-weight:600;overflow-wrap:break-word;}

/* ========== LOADING & LOGIN ========== */
#loadingScreen{position:fixed;inset:0;background:var(--bg);z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;}
.spinner{width:44px;height:44px;border:3px solid rgba(240,180,41,.2);border-top-color:var(--primary);border-radius:50%;animation:spin .8s linear infinite;}
#loginScreen{position:relative;isolation:isolate;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;background:var(--bg);}
/* El único momento memorable del sistema: un halo dorado detrás de la card de
   login. Se hace con ::before para no tocar el markup. */
#loginScreen::before{content:'';position:absolute;left:50%;top:50%;width:min(760px,130vw);height:min(560px,96vh);transform:translate(-50%,-50%);background:radial-gradient(ellipse at center,rgba(240,180,41,.15) 0%,rgba(240,180,41,.05) 45%,transparent 72%);pointer-events:none;z-index:0;}
.login-box{position:relative;z-index:1;width:100%;max-width:400px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius-modal);padding:44px 36px;box-shadow:var(--edge-light),var(--shadow-lg);overflow:hidden;}
.login-box::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#fbbf24,#f59e0b);}

/* ========== LAYOUT ========== */
#appScreen{display:none;}
.layout{display:flex;min-height:100vh;}
.sidebar{width:252px;background:var(--bg2);border-right:1px solid var(--border);display:flex;flex-direction:column;position:fixed;top:0;left:0;bottom:0;z-index:50;transition:transform .3s,visibility .3s;}
.sidebar-brand{padding:20px 18px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:11px;}
.brand-icon{width:36px;height:36px;border-radius:var(--radius-btn);flex-shrink:0;background:linear-gradient(135deg,#fbbf24,#f59e0b);display:flex;align-items:center;justify-content:center;}
.sidebar-nav{flex:1;padding:10px 8px;display:flex;flex-direction:column;gap:2px;overflow-y:auto;}
.sidebar-footer{padding:10px 8px;border-top:1px solid var(--border);}
.main{margin-left:252px;flex:1;min-width:0;display:flex;flex-direction:column;min-height:100vh;}
/* Cristal solo acá y en el overlay: el topbar flota sobre el contenido. */
.topbar{padding:16px 28px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;background:rgba(11,14,20,.8);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);position:sticky;top:0;z-index:40;}
#pgTitle{font-family:var(--font-display);font-size:22px;font-weight:700;line-height:1.2;letter-spacing:.01em;}
#pgSub{font-size:13px;}
.page-body{padding:28px;flex:1;}
#menuBtn{display:none;}

/* ========== TABLES ========== */
.table-wrap{overflow-x:auto;}
table{width:100%;border-collapse:collapse;}
thead th{padding:11px 18px;font-size:12px;font-weight:600;color:var(--muted);background:var(--bg2);text-align:left;white-space:nowrap;border-bottom:1px solid var(--border);}
tbody td{padding:13px 18px;font-size:14px;border-top:1px solid var(--border);vertical-align:middle;}
tbody tr:hover td{background:rgba(255,255,255,.03);}

/* ========== NAVIGATION ========== */
.nav-btn{position:relative;display:flex;align-items:center;gap:11px;width:100%;padding:11px 14px;border:none;background:none;color:var(--muted);font-size:14px;font-weight:500;border-radius:var(--radius-btn);text-align:left;transition:background .16s,color .16s;}
.nav-btn i{width:18px;text-align:center;font-size:15px;}
.nav-btn:hover{background:rgba(255,255,255,.04);color:var(--fg);}
.nav-btn.active{background:var(--primary-soft);color:var(--primary);font-weight:600;}
.nav-btn.active::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:22px;border-radius:0 3px 3px 0;background:var(--primary);}

/* ========== TABS ========== */
.tabs{display:flex;gap:3px;background:var(--bg2);border:1px solid var(--border);padding:4px;border-radius:var(--radius-card);margin-bottom:18px;}
.tab{flex:1;padding:9px 14px;border:1px solid transparent;background:none;color:var(--muted);font-size:13px;font-weight:600;border-radius:var(--radius-btn);display:flex;align-items:center;justify-content:center;gap:7px;transition:all .16s;}
.tab:hover{color:var(--fg);}
.tab.active{background:rgba(240,180,41,.14);color:var(--primary);border-color:var(--primary-line);}
.tab-count{font-size:11px;font-weight:600;padding:2px 8px;border-radius:var(--radius-pill);background:rgba(255,255,255,.07);color:var(--muted);}
.tab.active .tab-count{background:rgba(240,180,41,.2);color:var(--primary);}
.tab-content{display:none;}
.tab-content.active{display:block;}

/* ========== MODALS & OVERLAY ========== */
.overlay{position:fixed;inset:0;background:rgba(4,6,10,.6);z-index:100;display:flex;align-items:center;justify-content:center;padding:20px;opacity:0;pointer-events:none;transition:opacity .2s;}
@supports (backdrop-filter:blur(6px)) or (-webkit-backdrop-filter:blur(6px)){
    .overlay{backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);}
}
.overlay.open{opacity:1;pointer-events:all;}
.modal{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-modal);box-shadow:var(--edge-light),var(--shadow-lg);width:100%;min-width:0;max-width:580px;max-height:92vh;overflow-y:auto;overflow-x:hidden;transform:scale(.96) translateY(8px);transition:transform .2s;}
.overlay.open .modal{transform:scale(1) translateY(0);}
.modal-head{padding:22px 26px 16px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;background:var(--card);z-index:2;border-bottom:1px solid var(--border);}
.modal-head h3{font-size:18px;}
.modal-body{padding:22px 26px 28px;min-width:0;}
.overlay .modal.modal-lg{max-width:760px;}
@media(max-width:600px){.overlay .modal.modal-lg{max-width:100%;}}

/* ========== TOAST ========== */
#toasts{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;gap:8px;}
.toast{background:rgba(20,26,38,.9);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid var(--border-input);border-radius:12px;padding:13px 18px;display:flex;align-items:center;gap:10px;font-size:13px;font-weight:500;box-shadow:var(--shadow-md);min-width:260px;max-width:360px;animation:toastIn .25s ease,toastOut .25s ease 2.75s forwards;}

/* ========== PROGRESS ========== */
.progress-bar{height:6px;background:rgba(255,255,255,.06);border-radius:var(--radius-pill);overflow:hidden;min-width:60px;}
.progress-fill{height:100%;border-radius:var(--radius-pill);transition:width .4s;}
.abono-bar{height:10px;background:rgba(255,255,255,.06);border-radius:var(--radius-pill);overflow:hidden;margin-top:6px;}
.abono-fill{height:100%;border-radius:var(--radius-pill);background:linear-gradient(90deg,#fbbf24,#f59e0b);}

/* ========== RATINGS ========== */
.stars{display:inline-flex;gap:2px;font-size:14px;}
.stars .star{color:var(--border-input);transition:color .2s;}
.stars .star.filled{color:var(--primary);}
.stars-sm{font-size:12px;}
.rating-label{font-size:11px;font-weight:600;margin-left:6px;}
.rating-5{color:var(--fg);}
.rating-4{color:var(--primary);}
.rating-3{color:var(--primary);}
.rating-2{color:#fb923c;}
.rating-1{color:var(--danger-fg);}

/* ========== MAP ========== */
.map-wrap{overflow:hidden;}
#mainMap{height:520px;}
#pickerMap{height:220px;}
.leaflet-container{background:var(--bg2)!important;}
.leaflet-popup-content-wrapper{background:var(--card)!important;color:var(--fg)!important;border:1px solid var(--border-input)!important;border-radius:var(--radius-btn)!important;box-shadow:var(--shadow-md)!important;}
.leaflet-popup-tip{background:var(--card)!important;}
.leaflet-popup-content{font-family:var(--font-ui)!important;font-size:13px!important;}

/* ========== ALERTS ========== */
.alert{padding:12px 16px;border-radius:var(--radius-btn);font-size:13px;display:flex;align-items:flex-start;gap:9px;margin-bottom:14px;}
.alert i{margin-top:1px;flex-shrink:0;}
.alert-info{background:rgba(20,26,38,.7);border:1px solid var(--border);color:var(--fg);}
.alert-warning{background:rgba(240,180,41,.08);border:1px solid rgba(240,180,41,.22);color:var(--primary);}
.alert-danger{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.28);color:var(--danger-fg);}
.alerta-moroso-strip{background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.3);border-radius:var(--radius-card);padding:14px 16px;margin-bottom:16px;}
.moroso-item{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid rgba(239,68,68,.14);}
.moroso-item:last-child{border-bottom:none;padding-bottom:0;}

/* ========== UTILITIES ========== */
.mt-4{margin-top:4px;}.mt-8{margin-top:8px;}.mt-16{margin-top:16px;}
.gap-6{gap:6px;}.flex-center{display:flex;align-items:center;}
.flex-between{display:flex;align-items:center;justify-content:space-between;}
.grid-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(185px,100%),1fr));gap:18px;margin-bottom:26px;}
.grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px;}
@media(max-width:900px){.grid-2{grid-template-columns:1fr;}}
.empty{text-align:center;padding:56px 20px;color:var(--muted);}
.empty i{font-size:40px;opacity:.25;display:block;margin-bottom:14px;}
.empty p{font-size:14px;}
.avatar{width:34px;height:34px;border-radius:var(--radius-btn);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;background:var(--card2);color:var(--fg);border:1px solid var(--border);}
.log-item{padding:10px 16px;border-bottom:1px solid var(--border);font-size:13px;}
.log-item:last-child{border-bottom:none;}
.pay-row{display:flex;align-items:center;justify-content:space-between;padding:11px 16px;font-size:13px;border-bottom:1px solid var(--border);transition:background .16s;gap:10px;flex-wrap:wrap;}
.pay-row:last-child{border-bottom:none;}
.pay-row:hover{background:rgba(255,255,255,.025);}

/* ========== TARJETA VIRTUAL DE PRESTAMO ========== */
/* Documento imprimible: se mantiene la superficie clara a propósito, es un
   facsímil de papel que el cliente recibe. Los labels conservan MAYÚSCULAS. */
.tarjeta-prestamo{background:#fff;color:#111;border-radius:16px;padding:22px 20px;font-family:var(--font-ui);width:100%;box-shadow:0 6px 32px rgba(0,0,0,.25);box-sizing:border-box;}
.tarjeta-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px;gap:8px;flex-wrap:wrap;}
.tarjeta-num{font-size:12px;font-weight:700;color:#555;background:#f2f2f2;padding:3px 9px;border-radius:6px;}
.tarjeta-fecha-top{font-size:11px;color:#777;font-weight:600;}
.tarjeta-title{text-align:center;font-size:17px;font-weight:800;color:#111;letter-spacing:.5px;margin:10px 0 14px;padding:10px 0;border-top:2px solid #111;border-bottom:2px solid #111;}
.tarjeta-field{display:flex;flex-direction:column;margin-bottom:10px;}
.tarjeta-field label{font-size:10px;font-weight:700;text-transform:uppercase;color:#777;letter-spacing:.5px;margin-bottom:3px;}
.tarjeta-field span{font-size:14px;font-weight:600;color:#111;border-bottom:1.5px solid #ddd;padding-bottom:4px;word-break:break-word;}
.tarjeta-freq{display:flex;gap:8px;align-items:center;margin:10px 0 12px;flex-wrap:wrap;}
.tarjeta-freq>label{font-size:11px;font-weight:700;color:#555;flex-shrink:0;}
.tarjeta-freq-opts{display:flex;gap:10px;flex-wrap:wrap;}
.tarjeta-freq-item{display:flex;align-items:center;gap:5px;font-size:12px;font-weight:600;}
.tarjeta-freq-box{width:15px;height:15px;border:2px solid #111;border-radius:3px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;font-size:10px;}
.tarjeta-freq-box.checked{background:#111;color:#fff;}
.tarjeta-tabla-wrap{border:1px solid #ccc;border-radius:8px;overflow:auto;margin-top:6px;width:100%;}
.tarjeta-tabla{width:100%;border-collapse:collapse;min-width:560px;}
.tarjeta-tabla th{background:#111;color:#fff;font-size:10px;font-weight:700;text-transform:uppercase;padding:6px 8px;text-align:center;letter-spacing:.3px;white-space:nowrap;}
.tarjeta-tabla td{border:1px solid #e0e0e0;padding:6px 8px;font-size:12px;text-align:center;color:#111;white-space:nowrap;}
.tarjeta-tabla td.paid-row{background:#e8f8f5;color:#00897b;font-weight:700;}
.tarjeta-tabla td.incompleta-row{background:#ffeaea;color:#c0392b;font-weight:700;}
.tarjeta-tabla .half{width:50%;}
.tarjeta-pie{text-align:center;font-size:10px;color:#999;margin-top:12px;border-top:1px solid #e0e0e0;padding-top:8px;}

/* ========== ZONE CLIENT PANEL ========== */
#zoneClientPanel{position:fixed;top:0;right:0;bottom:0;width:480px;max-width:100vw;background:var(--card);border-left:1px solid var(--border);z-index:200;display:flex;flex-direction:column;transform:translateX(100%);transition:transform .3s cubic-bezier(.4,0,.2,1);box-shadow:-8px 0 32px rgba(0,0,0,.5);}
#zoneClientPanel.open{transform:translateX(0);}
.zcp-header{padding:18px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;background:var(--bg2);}
.zcp-body{flex:1;overflow-y:auto;padding:20px;}
.zcp-section{margin-bottom:20px;}
.zcp-section-title{font-size:11px;font-weight:600;color:var(--muted);margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid var(--border);}
.zcp-loan-card{background:var(--inset);border:1px solid var(--border);border-radius:var(--radius-btn);margin-bottom:10px;overflow:hidden;transition:border-color .16s;}
.zcp-loan-card:hover{border-color:var(--border-input);}
.zcp-loan-head{padding:13px 16px;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:10px;}
.zcp-loan-body{padding:0 16px 14px;display:none;}
.zcp-loan-body.open{display:block;}
.zcp-cuota-row{display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--border);gap:8px;flex-wrap:wrap;font-size:13px;}
.zcp-cuota-row:last-child{border-bottom:none;}
#zcpPanelOverlay{position:fixed;inset:0;background:rgba(4,6,10,.55);z-index:199;display:none;}
#zcpPanelOverlay.open{display:block;}
@media(max-width:520px){#zoneClientPanel{width:100vw;}}

/* ========== CIERRE DEL DIA ========== */
.cierre-modal{max-width:480px;}
.cierre-resumen{background:linear-gradient(135deg,var(--inset),var(--card2));border:1px solid var(--border);border-radius:var(--radius-card);padding:20px;margin-bottom:16px;}
.cierre-row{display:flex;justify-content:space-between;align-items:center;padding:10px 0;border-bottom:1px solid var(--border);}
.cierre-row:last-child{border-bottom:none;padding-bottom:0;}
.cierre-label{font-size:13px;color:var(--muted);font-weight:500;}
.cierre-val{font-size:16px;font-weight:600;}
.cierre-total{background:rgba(240,180,41,.08);border:1px solid rgba(240,180,41,.24);border-radius:var(--radius-btn);padding:14px;display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;}
.cierre-wa-btn{background:linear-gradient(135deg,#25d366,#12a15a);color:var(--on-whatsapp);border:none;border-radius:var(--radius-btn);padding:13px 20px;font-size:14px;font-weight:700;display:flex;align-items:center;gap:8px;cursor:pointer;width:100%;justify-content:center;transition:box-shadow .16s,transform .16s;}
.cierre-wa-btn:hover{box-shadow:0 4px 14px rgba(37,211,102,.34);transform:translateY(-1px);}

/* ========== COLLECTOR VIEW ========== */
.collector-hero{background:linear-gradient(135deg,rgba(240,180,41,.07) 0%,rgba(255,255,255,.02) 100%);border:1px solid rgba(240,180,41,.18);border-radius:var(--radius-modal);padding:22px 24px;margin-bottom:22px;position:relative;overflow:hidden;}
.collector-hero::before{content:'';position:absolute;right:-40px;top:-40px;width:150px;height:150px;border-radius:50%;background:radial-gradient(circle,rgba(240,180,41,.07),transparent 70%);}
.collector-hero::after{content:'';position:absolute;left:30%;bottom:-50px;width:130px;height:130px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.03),transparent 70%);}
.collector-hero-top{display:flex;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;gap:12px;position:relative;z-index:1;}
.collector-hero-money{background:var(--inset);border:1px solid var(--border-input);border-radius:var(--radius-btn);padding:12px 18px;text-align:right;}
.collector-progress{display:flex;align-items:center;gap:20px;margin-top:18px;padding-top:18px;border-top:1px solid var(--border);position:relative;z-index:1;}
.progress-ring-wrap{position:relative;width:64px;height:64px;flex-shrink:0;}
.progress-ring{transform:rotate(-90deg);}
.progress-ring-bg{fill:none;stroke:rgba(255,255,255,.08);stroke-width:5;}
.progress-ring-fill{fill:none;stroke:var(--success);stroke-width:5;stroke-linecap:round;transition:stroke-dashoffset .6s ease;}
.ring-center{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700;color:var(--fg);}
.coll-kpi-strip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-bottom:20px;}
.coll-kpi{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-card);padding:16px 18px;box-shadow:var(--edge-light),var(--shadow-md);cursor:pointer;transition:transform .18s,border-color .18s,box-shadow .18s;position:relative;overflow:hidden;}
.coll-kpi:hover{transform:translateY(-2px);border-color:var(--border-input);box-shadow:var(--edge-light),var(--shadow-lg);}
.coll-kpi-label{font-size:12px;font-weight:500;color:var(--muted);margin-bottom:8px;}
.coll-kpi-val{font-size:26px;font-weight:700;line-height:1;overflow-wrap:break-word;}
.coll-kpi-sub{font-size:11px;color:var(--muted);margin-top:5px;}
.coll-kpi.kpi-all{border-color:var(--border-input);}
.coll-kpi.kpi-today{border-color:rgba(240,180,41,.45);}
.coll-kpi.kpi-overdue{border-color:rgba(239,68,68,.45);}
.coll-kpi.kpi-all.active-kpi{border-color:var(--border-input);background:var(--card2);}
.coll-kpi.kpi-today.active-kpi{border-color:var(--primary);background:rgba(240,180,41,.08);}
.coll-kpi.kpi-overdue.active-kpi{border-color:var(--danger);background:rgba(239,68,68,.08);}
.collector-filter-bar{display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap;align-items:center;}
.filter-chip{padding:7px 14px;border-radius:var(--radius-pill);border:1.5px solid var(--border-input);background:var(--inset);color:var(--muted);font-size:13px;font-weight:600;cursor:pointer;transition:all .16s;display:flex;align-items:center;gap:6px;}
.filter-chip:hover{color:var(--fg);border-color:var(--muted);}
.filter-chip.active{border-color:var(--primary);background:rgba(240,180,41,.14);color:var(--primary);}
.filter-chip.active-red{border-color:rgba(239,68,68,.5);background:rgba(239,68,68,.12);color:var(--danger-fg);}
.cobro-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-card);box-shadow:var(--edge-light),var(--shadow-md);margin-bottom:14px;overflow:hidden;transition:border-color .18s,box-shadow .18s,transform .18s;animation:fadeUp .3s ease;}
.cobro-card:hover{border-color:var(--border-input);box-shadow:var(--edge-light),var(--shadow-lg);transform:translateY(-1px);}
.cobro-card.overdue{border-left:3px solid var(--danger);}
.cobro-card-head{padding:18px 20px;display:flex;align-items:flex-start;gap:14px;}
.cobro-avatar{width:52px;height:52px;border-radius:var(--radius-card);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:20px;}
.cobro-meta{display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap;}
.cobro-meta-item{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--muted);}
.cobro-actions{padding:14px 20px;border-top:1px solid var(--border);background:var(--inset);display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;}
.cobro-actions.three-col{grid-template-columns:auto minmax(0,1fr) minmax(0,1fr);}
.coll-btn-paid{background:linear-gradient(135deg,#fbbf24,#f59e0b);color:var(--on-primary);border:none;border-radius:var(--radius-btn);padding:13px 18px;font-size:14px;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;transition:all .16s;width:100%;}
.coll-btn-paid:hover{box-shadow:var(--shadow-gold);transform:translateY(-1px);}
.coll-btn-paid:active{transform:scale(.97);}
.coll-btn-nopaid{background:rgba(239,68,68,.12);color:var(--danger-fg);border:1.5px solid rgba(239,68,68,.32);border-radius:var(--radius-btn);padding:13px 18px;font-size:14px;font-weight:700;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;transition:all .16s;width:100%;}
.coll-btn-nopaid:hover{background:rgba(239,68,68,.2);border-color:rgba(239,68,68,.5);}
.coll-btn-nopaid:active{transform:scale(.97);}
.coll-btn-wa{background:#25d366;color:var(--on-whatsapp);border:none;border-radius:var(--radius-btn);padding:13px 14px;font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .16s;width:auto;}
.coll-btn-wa:hover{background:#1fbc5d;box-shadow:0 4px 12px rgba(37,211,102,.34);}
.cobro-amount-badge{display:inline-flex;align-items:center;background:var(--inset);border:1px solid var(--border);border-radius:var(--radius-btn);padding:5px 11px;font-weight:700;font-size:20px;}
.cobro-summary-bar{background:var(--card2);border:1px solid var(--border);border-radius:var(--radius-card);box-shadow:var(--edge-light);padding:16px 20px;margin-bottom:20px;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;}
.cobro-summary-item{min-width:0;}
.cobro-summary-item .s-label{font-size:10px;font-weight:500;color:var(--muted);margin-bottom:4px;}
.cobro-summary-item .s-val{font-size:18px;font-weight:600;overflow-wrap:break-word;}
.paid-today-row{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);gap:8px;animation:fadeUp .3s ease;}
.paid-today-row:last-child{border-bottom:none;}
.nopay-reason-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-bottom:12px;}
.nopay-reason-btn{border:1.5px solid var(--border-input);border-radius:var(--radius-btn);padding:11px 10px;background:var(--inset);cursor:pointer;text-align:center;font-size:13px;font-weight:600;color:var(--muted);transition:all .16s;display:flex;flex-direction:column;align-items:center;gap:5px;}
.nopay-reason-btn:hover{color:var(--fg);border-color:var(--muted);}
.nopay-reason-btn i{font-size:18px;}
.nopay-reason-btn.selected{border-color:var(--danger);background:rgba(239,68,68,.12);color:var(--danger-fg);}
.collectors-live{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;margin-bottom:20px;}
.collector-live-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-card);padding:14px 16px;position:relative;overflow:hidden;}
.collector-live-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#fbbf24,rgba(240,180,41,.15));}
.collector-live-name{font-size:14px;font-weight:600;margin-bottom:4px;}
.collector-live-zone{font-size:11px;color:var(--muted);margin-bottom:10px;}
.collector-live-stats{display:flex;gap:10px;}
.cls-stat{flex:1;min-width:0;text-align:center;background:var(--inset);border-radius:8px;padding:6px 4px;}
.cls-stat-val{font-size:15px;font-weight:700;overflow-wrap:break-word;}
.cls-stat-lbl{font-size:9px;color:var(--muted);font-weight:600;}
.cls-pct-bar{height:4px;background:rgba(255,255,255,.07);border-radius:var(--radius-pill);margin-top:8px;overflow:hidden;}
.cls-pct-fill{height:100%;background:linear-gradient(90deg,#fbbf24,#f59e0b);border-radius:var(--radius-pill);transition:width .4s;}

/* ========== DASHBOARD ========== */
.dash-kpi-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-bottom:24px;}
.kpi-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-card);box-shadow:var(--edge-light),var(--shadow-md);padding:20px 22px;position:relative;overflow:hidden;transition:transform .18s,box-shadow .18s,border-color .18s;cursor:default;}
/* Acento superior: 3px que codifica de qué va el KPI. Es la barra de progreso
   del dato, no decoración. */
.kpi-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--primary),rgba(240,180,41,.12));}
.kpi-card:hover{transform:translateY(-2px);border-color:var(--border-input);box-shadow:var(--edge-light),var(--shadow-lg);}
.kpi-card::after{content:'';position:absolute;inset:0;border-radius:var(--radius-card);opacity:0;transition:opacity .18s;pointer-events:none;}
.kpi-card .kpi-bg-icon{position:absolute;right:-10px;bottom:-10px;font-size:72px;opacity:.05;pointer-events:none;}
.kpi-card .kpi-label{font-size:12px;font-weight:500;color:var(--muted);margin-bottom:10px;}
.kpi-card .kpi-val{font-size:28px;font-weight:700;line-height:1.1;margin-bottom:5px;overflow-wrap:break-word;}
.kpi-card .kpi-sub{font-size:12px;color:var(--muted);}
.kpi-card.kpi-accent{border-color:var(--border-input);background:linear-gradient(135deg,rgba(255,255,255,.04) 0%,var(--card) 60%);}
.kpi-card.kpi-gold::before{background:linear-gradient(90deg,#fbbf24,rgba(240,180,41,.12));}
.kpi-card.kpi-gold{border-color:rgba(240,180,41,.3);background:linear-gradient(135deg,rgba(240,180,41,.07) 0%,var(--card) 60%);}
.kpi-card.kpi-blue::before{background:linear-gradient(90deg,var(--sinpe),rgba(59,130,246,.12));}
.kpi-card.kpi-blue{border-color:rgba(59,130,246,.3);background:linear-gradient(135deg,rgba(59,130,246,.07) 0%,var(--card) 60%);}
.kpi-card.kpi-purple::before{background:linear-gradient(90deg,#a78bfa,rgba(167,139,250,.12));}
.kpi-card.kpi-purple{border-color:rgba(167,139,250,.28);background:linear-gradient(135deg,rgba(167,139,250,.06) 0%,var(--card) 60%);}
.kpi-card.kpi-red::before{background:linear-gradient(90deg,var(--danger),rgba(239,68,68,.12));}
.kpi-card.kpi-red{border-color:rgba(239,68,68,.3);background:linear-gradient(135deg,rgba(239,68,68,.07) 0%,var(--card) 60%);}
.kpi-card.kpi-green::before{background:linear-gradient(90deg,var(--success),rgba(52,211,153,.12));}
.kpi-card.kpi-green{border-color:rgba(52,211,153,.3);background:linear-gradient(135deg,rgba(52,211,153,.07) 0%,var(--card) 60%);}
.dash-hero{background:linear-gradient(135deg,rgba(240,180,41,.06) 0%,rgba(255,255,255,.02) 50%,rgba(255,255,255,.01) 100%);border:1px solid rgba(240,180,41,.16);border-radius:var(--radius-modal);padding:24px 28px;margin-bottom:24px;position:relative;overflow:hidden;}
.dash-hero::before{content:'';position:absolute;right:-60px;top:-60px;width:200px;height:200px;border-radius:50%;background:radial-gradient(circle,rgba(240,180,41,.07),transparent 70%);}
.dash-hero::after{content:'';position:absolute;left:40%;bottom:-40px;width:160px;height:160px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.03),transparent 70%);}
.quick-actions{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:24px;}
.qa-btn{display:inline-flex;align-items:center;gap:7px;padding:9px 18px;border-radius:var(--radius-btn);font-size:13px;font-weight:600;border:1px solid transparent;cursor:pointer;transition:all .16s;}
.qa-btn:active{transform:scale(.96);}
.qa-primary{background:linear-gradient(135deg,#fbbf24,#f59e0b);color:var(--on-primary);}
.qa-primary:hover{box-shadow:var(--shadow-gold);transform:translateY(-1px);}
.qa-gold{background:rgba(240,180,41,.14);color:var(--primary);border:1.5px solid var(--primary-line);}
.qa-gold:hover{background:rgba(240,180,41,.22);border-color:rgba(240,180,41,.5);}
.qa-ghost{background:var(--card);color:var(--muted);border:1.5px solid var(--border-input);}
.qa-ghost:hover{color:var(--fg);border-color:var(--muted);}
.dash-section{display:grid;grid-template-columns:1.6fr 1fr;gap:18px;margin-bottom:18px;}
.dash-right-col{display:flex;flex-direction:column;gap:18px;}
.cobro-row{display:flex;align-items:center;justify-content:space-between;padding:11px 16px;border-bottom:1px solid var(--border);gap:8px;transition:background .16s;}
.cobro-row:last-child{border-bottom:none;}
.cobro-row:hover{background:rgba(255,255,255,.025);}
.cobro-row.overdue-row{border-left:3px solid var(--danger);background:rgba(239,68,68,.04);}
.cobro-row.overdue-row:hover{background:rgba(239,68,68,.07);}

/* ========== TUTORIAL ========== */
.tutorial-overlay{position:fixed;inset:0;background:rgba(4,6,10,.78);z-index:9999;display:flex;align-items:center;justify-content:center;padding:20px;}
.tutorial-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-modal);box-shadow:var(--edge-light),var(--shadow-lg);max-width:480px;width:100%;padding:32px 28px;position:relative;}
.tutorial-step{display:none;}
.tutorial-step.active{display:block;}
.tutorial-icon{width:64px;height:64px;border-radius:var(--radius-modal);background:linear-gradient(135deg,#fbbf24,#f59e0b);display:flex;align-items:center;justify-content:center;font-size:28px;margin:0 auto 16px;color:var(--on-primary);}
.tutorial-dots{display:flex;justify-content:center;gap:6px;margin:20px 0 0;}
.tutorial-dot{width:8px;height:8px;border-radius:50%;background:var(--border-input);transition:background .2s;}
.tutorial-dot.active{background:var(--primary);}
.tutorial-progress{height:3px;background:rgba(255,255,255,.07);border-radius:var(--radius-pill);margin-bottom:24px;overflow:hidden;}
.tutorial-progress-fill{height:100%;background:linear-gradient(90deg,#fbbf24,#f59e0b);border-radius:var(--radius-pill);transition:width .3s;}

/* ========== RESPONSIVE ========== */
/* Red de seguridad: cualquier grilla con estilo inline (las hay en varias
   páginas: resúmenes financieros, vistas previas, tarjetas de stats) no debe
   poder forzar overflow horizontal del modal o de la página — sin esto, un
   número/monto largo dentro de una celda de grid puede empujar todo el
   contenedor más ancho que la pantalla en vez de encogerse o hacer wrap. */
[style*="display:grid"]{min-width:0;max-width:100%;}
[style*="display:grid"]>*{min-width:0;overflow-wrap:break-word;}
img{max-width:100%;}

@media(max-width:900px){.dash-kpi-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media(max-width:900px){.dash-section{grid-template-columns:1fr;}}
@media(max-width:768px){
    .sidebar{transform:translateX(-100%);overflow-y:auto;visibility:hidden;}
    .sidebar.open{transform:translateX(0);box-shadow:8px 0 32px rgba(0,0,0,.5);visibility:visible;}
    .main{margin-left:0;}
    .page-body{padding:12px;}
    .topbar{padding:10px 12px;gap:8px;}
    .form-row{grid-template-columns:1fr;}
    .detail-grid{grid-template-columns:1fr;}
    #menuBtn{display:flex!important;}
    #todayDate{display:none!important;}
    #topbarUsername{font-size:12px!important;}
    .topbar-username-text{display:none!important;}
    #pgTitle{font-size:17px!important;}
    #pgSub{font-size:11px!important;}
    .coll-kpi-strip{grid-template-columns:repeat(3,minmax(0,1fr))!important;}
    .coll-kpi{padding:10px 10px!important;}
    .coll-kpi-val{font-size:20px!important;}
    .coll-kpi-label{font-size:9px!important;}
    .modal-head{padding:16px 18px 12px;}
    .modal-body{padding:16px 18px 20px;}
    [style*="grid-template-columns:1fr 1fr 1fr"]{grid-template-columns:repeat(2,minmax(0,1fr))!important;}

    /* Tablas → tarjetas apiladas: en pantallas angostas una tabla clásica obliga
       a deslizar de lado para ver columnas como Teléfono/Acciones sin ningún
       indicio visual de que hay más contenido. Cada <tr> pasa a comportarse como
       una tarjeta y cada <td> muestra su encabezado (data-label) arriba del valor. */
    .table-wrap{overflow-x:visible;}
    .table-wrap table,.table-wrap tbody,.table-wrap tr{display:block;width:100%;}
    .table-wrap thead{display:none;}
    .table-wrap tbody tr{border:1px solid var(--border);border-radius:var(--radius-card);margin-bottom:10px;padding:10px 14px;background:var(--inset);}
    .table-wrap tbody tr:last-child{margin-bottom:0;}
    .table-wrap tbody td{display:block;border-top:none;padding:7px 0;white-space:normal;text-align:left!important;}
    .table-wrap tbody td[data-label]::before{content:attr(data-label);display:block;font-size:10px;font-weight:600;color:var(--muted);margin-bottom:3px;}
    .table-wrap tbody td[data-label="Acciones"] > div{justify-content:flex-start!important;flex-wrap:wrap;}
}
@media(max-width:600px){.cobro-summary-bar{grid-template-columns:1fr 1fr;}}
/* El tamaño de .coll-kpi-val en ≤600px lo fija el bloque de 768px (su regla
   lleva !important). Acá solo se re-apila el strip: declarar el font-size acá
   era código muerto. */
@media(max-width:600px){.coll-kpi-strip{grid-template-columns:1fr;}}
@media(max-width:540px){.dash-kpi-grid{grid-template-columns:1fr 1fr;}}
@media(max-width:480px){
    .overlay{padding:8px;}
    .form-row,.pay-method-grid,.nopay-reason-grid,.grid-2,.detail-grid{grid-template-columns:1fr;}
    [style*="grid-template-columns:1fr 1fr"]{grid-template-columns:1fr!important;}
    .cobro-actions{grid-template-columns:1fr;}
    .cobro-actions.three-col{grid-template-columns:1fr;}
    .form-actions{justify-content:stretch;}
    .form-actions .btn{flex:1;}
}

/* ========== ACCESSIBILITY ========== */

/* Skip-link: visible solo al recibir foco (teclado) */
.skip-link{position:fixed;left:var(--space-2);top:var(--space-2);z-index:10001;background:var(--color-primary);color:var(--color-primary-contrast);padding:var(--space-2) var(--space-4);border-radius:var(--radius-sm);font-size:var(--text-sm);font-weight:700;transform:translateY(-400%);transition:transform .15s;box-shadow:0 4px 16px rgba(0,0,0,.5);}
.skip-link:focus{transform:translateY(0);}
#pageBody:focus{outline:none;}

/* Foco visible global: anillo gold sobre las superficies dark (contraste ≥7.3:1).
   Nunca eliminar el outline sin reemplazo en controles interactivos. */
:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px;}
.nav-btn:focus-visible,.tab:focus-visible,.input:focus-visible,.btn:focus-visible,
.filter-chip:focus-visible,.coll-kpi:focus-visible,.pay-method-btn:focus-visible,
.nopay-reason-btn:focus-visible,.freq-select-btn:focus-visible,.btn-close:focus-visible,
.qa-btn:focus-visible,.coll-btn-paid:focus-visible,.coll-btn-nopaid:focus-visible,
.coll-btn-wa:focus-visible,.cierre-wa-btn:focus-visible,.zcp-loan-head:focus-visible{
    outline:2px solid var(--color-focus);outline-offset:2px;}

/* Quienes pidan teclado en áreas no interactivas por defecto (divs clicables),
   reciben anillo gold propio y explícito (T4 completa tabindex+role en páginas). */
[role="button"]:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px;}

/* ========== MOTION ========== */
@media (prefers-reduced-motion: reduce){
    *,*::before,*::after{animation:none !important;transition-duration:0.01ms !important;scroll-behavior:auto !important;}
    html{scroll-behavior:auto;}
    /* Los hovers que levantan la superficie (translateY) se anulan: el cambio
       de estado tiene que verse al instante, sin desplazamiento. No se anula
       transform de forma global porque .sidebar y #zoneClientPanel la usan
       para posicionarse fuera de pantalla (rompería la navegación móvil). */
    .stat-card:hover,.coll-kpi:hover,.cobro-card:hover,.kpi-card:hover,
    .btn-primary:hover,.btn-danger:hover,.btn-whatsapp:hover,.cierre-wa-btn:hover,
    .coll-btn-paid:hover,.qa-primary:hover{transform:none;}
    .btn:active,.qa-btn:active,.coll-btn-paid:active,.coll-btn-nopaid:active,
    .btn-primary:active,.btn-danger:active,.btn-whatsapp:active{transform:none;}
    /* El halo dorado del login NO se oculta: es un gradiente estático, no
       movimiento. reduced-motion regula animación, no decoración. */
}

/* ========== ANIMATIONS ========== */
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes toastIn{from{opacity:0;transform:translateX(30px)}to{opacity:1;transform:translateX(0)}}
@keyframes toastOut{from{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(30px)}}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@keyframes syncPulse{0%,100%{opacity:1}50%{opacity:.5}}
.fade-up{animation:fadeUp .35s ease;}

/* T4a page polish */

/* Controles convertidos a role="button" (tarjetas KPI clicables de payments y
   futuros chips de T4b): puntero correcto y sin selección accidental de texto
   al hacer clic. El anillo gold de foco ya lo da [role="button"]:focus-visible. */
[role="button"]{cursor:pointer;user-select:none;-webkit-user-select:none;}

/* ════════════════════════════════════════════════════════════════════════
   T4b page polish — Accesibilidad (WCAG 2.1 AA)

   1) Contraste 1.4.11: los bordes de CONTROLES interactivos deben quedar
      ≥3:1 contra su fondo. --border (#262e3d) queda para separadores de
      layout/tablas; los controles pasan a --border-input (#5a6b80) o
      versiones más luminosas de su color identitario.
   2) Tab-order: el panel de zona cerrado (transformado fuera de pantalla)
      seguía dejando sus botones enfocables; se aplica el mismo mecanismo
      visibility que la sidebar móvil, con el cambio retrasado para no cortar
      la animación de salida.
   3) Anillos de foco para los nuevos role="button" de T4b.
   ════════════════════════════════════════════════════════════════════════ */

/* 1) Contraste de bordes de controles (1.4.11) */
.filter-chip,
.freq-select-btn,
.nopay-reason-btn,
.pay-method-btn{border-color:var(--border-input);}

/* KPIs de cobrador: el borde neutro tenue no llega a 3:1; se usa el token de
   borde de input o alfas ≥ .45 del color identitario. */
.coll-kpi.kpi-all{border-color:var(--border-input);}
.coll-kpi.kpi-today{border-color:rgba(240,180,41,.45);}
.coll-kpi.kpi-overdue{border-color:rgba(239,68,68,.45);}
.coll-kpi.kpi-all.active-kpi{border-color:var(--border-input);}
.coll-kpi.kpi-today.active-kpi{border-color:var(--primary);}
.coll-kpi.kpi-overdue.active-kpi{border-color:var(--danger);}

/* 2) Panel de zona cerrado fuera del tab-order (mismo patrón que .sidebar) */
#zoneClientPanel{transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .3s;visibility:hidden;}
#zoneClientPanel.open{transition:transform .3s cubic-bezier(.4,0,.2,1),visibility 0s;visibility:visible;}

/* 3) Anillos de foco de los nuevos controles T4b */
.collector-live-card:focus-visible,
.photo-upload-area:focus-visible{outline:2px solid var(--color-focus);outline-offset:2px;}
.tarjeta-tabla [role="button"]:focus-visible{outline:2px solid rgba(15,15,15,.7);outline-offset:1px;}

/* ============================================================================
   V3 PAGE POLISH — BLOQUE APPEND-ONLY
   No modifica ningún selector existente. Sólo agrega (a) el alias de
   compatibilidad que V1+V2 dejó sin propagar y (b) la tipografía interna de
   .stat-card, que el componente nunca declaró y por eso statCard() arrastraba
   inline en js/app/modal.js. Ver odd/tasks/frontend-visual-refresh.md.
   ========================================================================= */

/* (a) ALIAS DE COMPATIBILIDAD --gold.
   V1+V2 renombró este token a --primary en :root, pero js/ sigue consumiendo
   var(--gold) en 48 reglas (collector 16, dashboard 8, loans 6, payments 5,
   clients 3, reports 3, settings 3, history 1, map 1, collector-settings 1, y
   1 en js/utils/ui.js). Una custom property no definida hace que
   `color:var(--gold)` sea "invalid at computed-value time": la declaración se
   descarta y el texto HEREDA el color del padre. Por eso los montos y contadores
   dorados salían blancos o apagados en vez de dorados. Se restaura como alias
   --primary en lugar de editar 48 call-sites, y de paso repara el toast de
   js/utils/ui.js, que este pase no tiene permitido tocar sus aliases de color. */
:root{--gold:var(--primary);}

/* (b) TIPOGRAFÍA INTERNA DE .stat-card.
   .stat-card declara fondo, borde, radio, padding y sombra, pero NUNCA declaró la
   escala del label ni del valor. Estos dos rules Devuelven esa decisión al CSS.
   El label adopta la misma escala que .kpi-label y .coll-kpi-label (12px/500/
   muted); el valor adopta .kpi-val: Space Grotesk + tabular-nums, para que un
   "1" no cambie de ancho entre columnas de montos y las cuotas se comparen de un
   vistazo. El color del label y del valor lo sigue pasando statCard() inline,
   porque es dinámico (alert / estado). */
.stat-card-label{font-size:12px;font-weight:500;color:var(--muted);}
.stat-card-val{font-family:var(--font-display);font-variant-numeric:tabular-nums;font-size:var(--text-2xl);font-weight:700;line-height:1.1;}

/* ── V3 page polish — Login UX ─────────────────────────────────────────────
   Respuesta a "no sé qué poner": el login ahora explica qué credencial usar,
   habilita el gestor de contraseñas (autocomplete username/current-password) y
   cierra el loop si no tenés cuenta. La ayuda es aria-describedby del email. */
.login-help{font-size:13px;line-height:1.5;color:var(--muted);background:rgba(240,180,41,.06);border:1px solid rgba(240,180,41,.22);border-left:3px solid var(--primary);border-radius:10px;padding:10px 12px;margin:0 0 18px;}
.login-help strong{color:var(--primary);font-weight:600;}
.login-status{display:flex;align-items:center;justify-content:center;gap:6px;font-size:12px;padding:7px 12px;margin:0 0 16px;border-radius:999px;background:rgba(255,255,255,.03);border:1px solid var(--border);opacity:.9;}

/* ============================================================================
   V3 PAGE POLISH — SETTINGS
   Sólo reglas nuevas, sólo al final. Ninguna clase existente se renombra ni se
   redefine fuera de un scope de página. El trabajo real es este: sacar ~30
   estilos inline de js/pages/settings.js y js/pages/collector-settings.js y
   devolver la decisión de ritmo, color y tipografía al CSS.

   1) settings-card / settings-body / settings-actions — el ritmo vertical.
      La última card de admin era la única SIN `margin-bottom`: hoy las siete
      comparten la misma clase y el espaciado deja de ser un accident por card.
      `.settings-body` es flex-column: el `gap` es el mecanismo de ritmo y por
      eso se anula el `margin-bottom` de .form-group y de .alert dentro de él
      (si no, cada campo se aleja 12px + 14px del siguiente y la card crece).
   2) settings-head / settings-head-sub — título + qué hace la sección. El
      subtítulo no decora: contesta "¿esto qué me habilita?", que era
      justamente lo que faltaba. Hereda el `justify-content:space-between` de
      .card-header, así que el `<div>` de texto a la izquierda y el `<button>`
      de acción a la derecha no necesitan layout propio.
   3) settings-ico — el icono deja de flotar suelto con un color inline y pasa
      a un tile de 36px con el radio del sistema. Cinco variantes y ni una más:
      cada una mapea a un token de dominio que YA existe, así que el color
      sigue significando algo en vez de ser decoración. Contraste de cada
      texto de icono sobre su propio fondo: gold 7.5:1, whatsapp 7.1:1,
      blue 5.9:1, teal 5.9:1, danger 5.6:1 — todos ≥4.5:1 (WCAG 1.4.3).
   4) settings-hint — texto de apoyo de un campo, referenciado por
      aria-describedby. Contraste --muted sobre --card = 7.2:1.
   5) settings-kpi-grid — el KPI de mantenimiento iba en
      `style="grid-template-columns:repeat(4,1fr)"`, y 4 columnas fijas no
      ceden en mobile (a 375px cada celda quedaba de ~70px). Ahora 4 → 2 → 1
      por media query, con los mismos cortes que ya usa el archivo.
   6) settings-profile / settings-stat-* — identidad del cobrador y sus tres
      números de zona. `.stat-card` comparte `background:var(--card)` con la
      card que la contiene, así que anidada se leería como otra card igual;
      dentro de .settings-body se la pone en --inset, que es el mismo
      tratamiento que ya usa .detail-item para "dato dentro de una card".
   ========================================================================= */

.settings-card{margin-bottom:18px;}
.settings-body{padding:20px 22px;display:flex;flex-direction:column;gap:12px;}
.settings-body .form-group,
.settings-body .alert{margin-bottom:0;}
.settings-body .grid-stats{margin-bottom:0;}
.settings-actions{display:flex;flex-wrap:wrap;gap:10px;}

.settings-head{display:flex;align-items:center;gap:12px;min-width:0;}
.settings-head>div{min-width:0;}
.settings-head-sub{margin-top:2px;font-size:var(--text-sm);line-height:1.4;color:var(--muted);}

.settings-ico{
    width:36px;height:36px;flex-shrink:0;border-radius:var(--radius-btn);
    display:flex;align-items:center;justify-content:center;font-size:15px;
    background:var(--settings-ico-bg);color:var(--settings-ico-fg);
    border:1px solid var(--settings-ico-bd);
}
.settings-ico-gold{--settings-ico-bg:var(--primary-soft);--settings-ico-fg:var(--primary);--settings-ico-bd:var(--primary-line);}
.settings-ico-teal{--settings-ico-bg:rgba(20,184,166,.12);--settings-ico-fg:var(--teal);--settings-ico-bd:rgba(20,184,166,.32);}
.settings-ico-blue{--settings-ico-bg:rgba(59,130,246,.12);--settings-ico-fg:var(--sinpe-fg);--settings-ico-bd:rgba(59,130,246,.32);}
.settings-ico-danger{--settings-ico-bg:rgba(239,68,68,.12);--settings-ico-fg:var(--danger-fg);--settings-ico-bd:rgba(239,68,68,.32);}
.settings-ico-whatsapp{--settings-ico-bg:rgba(37,211,102,.12);--settings-ico-fg:var(--whatsapp);--settings-ico-bd:rgba(37,211,102,.32);}

.settings-hint{display:block;margin-top:6px;font-size:var(--text-xs);line-height:1.45;color:var(--muted);}

.settings-kpi-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;}
.settings-kpi-grid .kpi-card{padding:16px 18px;}
.settings-kpi-grid .kpi-val{font-size:24px;}

.settings-profile{display:flex;align-items:center;gap:14px;min-width:0;}
.settings-profile>.avatar{width:52px;height:52px;font-size:19px;}
.settings-profile-name{font-size:16px;font-weight:700;line-height:1.25;overflow-wrap:break-word;}
.settings-profile-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:6px;}
.settings-meta-label{font-size:var(--text-xs);font-weight:700;color:var(--muted);margin-bottom:5px;}

.settings-body .stat-card{background:var(--inset);}
/* .stat-card-label nunca declaró separación contra el valor: en las páginas que
   lo usan la caja del label y la del número se tocaban (medido: 0px de hueco).
   Acá se los separa con el token de 4px, y sólo en Settings: el componente se
   comparte con statCard() de js/app/modal.js y esa regla no es de este pase. */
.settings-body .stat-card-label{margin-bottom:var(--space-1);}
/* La variante verde necesita LA MISMA especificidad que la regla de inset que
   la antecede (0,2,0). Con (0,1,0) el `background` la perdedora y el stat de
   "Cobrado este mes" salía sin tinte: sólo le quedaba el borde verde. */
.settings-body .stat-card.settings-stat-green{border-color:rgba(52,211,153,.3);background:linear-gradient(135deg,rgba(52,211,153,.07) 0%,var(--inset) 60%);}
.settings-stat-green .stat-card-val{color:var(--success);}

@media(max-width:900px){.settings-kpi-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
@media(max-width:480px){.settings-kpi-grid{grid-template-columns:1fr;}}

/* V3 — stat-card gap (global): el label de .stat-card comparte componente con
   statCard() de js/app/modal.js, donde tampoco había separación contra el
   valor (medido 0px). Mismo token de 4px que el fix scoped de Settings. */
.stat-card-label{margin-bottom:var(--space-1);}
