/* EL ENSUEÑO — estilos base.
 * Layout: navbar + (sidebar pegado a la izquierda | contenido)
 * Theming: light por default, [data-bs-theme="dark"] sobreescribe tokens.
 *
 * Paleta agro: verde bosque (#166534) + dorado trigo (#F0B429).
 * El naranja quedó reservado para el estado "warning" y el teal para "info":
 * son semántica, no marca. Tipografía: Inter (cargada en base.html).
 */

/* ============================================================
 * 1. Design tokens
 * ============================================================ */
:root {
    /* Brand — verde + dorado */
    --pzf-primary: #166534;          /* verde bosque, 7.13:1 sobre blanco */
    --pzf-primary-hover: #0F4A26;
    --pzf-primary-rgb: 22, 101, 52;
    --pzf-primary-soft: rgba(22, 101, 52, .10);
    /* En claro el primario ya contrasta como texto; en oscuro diverge del
       relleno porque ningún verde sirve a la vez de fondo y de texto. */
    --pzf-primary-text: var(--pzf-primary);
    --pzf-primary-text-hover: var(--pzf-primary-hover);

    /* El teal dejó de ser color de marca. Sobrevive como 3ra serie de gráfico
       (charts.js): verde y dorado solos no alcanzan para 5 series. Para el
       tono semántico "info" usar --pzf-info, no esto. */
    --pzf-accent: #2DA4C4;
    --pzf-accent-rgb: 45, 164, 196;
    --pzf-accent-soft: rgba(45, 164, 196, .14);

    --pzf-gold: #F0B429;             /* dorado trigo */
    --pzf-gold-hover: #D89E14;
    --pzf-gold-rgb: 240, 180, 41;
    --pzf-gold-soft: rgba(240, 180, 41, .16);
    /* El dorado no admite texto blanco encima (1.86:1): va casi negro. */
    --pzf-on-gold: #241C05;
    /* Y como texto/icono sobre fondo claro necesita esta versión oscurecida. */
    --pzf-gold-text: #8A6206;

    --pzf-success: #15A36B;
    --pzf-success-rgb: 21, 163, 107;
    --pzf-warning: #E8763A;          /* naranja: atención/pendiente */
    --pzf-warning-rgb: 232, 118, 58;
    --pzf-danger:  #DC3545;
    --pzf-danger-rgb: 220, 53, 69;
    --pzf-info:    #2A8FA8;
    --pzf-info-rgb: 42, 143, 168;

    /* El naranja de --pzf-warning no llega a 4.5:1 sobre fondo claro: para
       texto e iconos va esta versión oscurecida. En oscuro se aclara. */
    --pzf-warning-text: #B4501C;
    /* Texto sobre un relleno de color (primary, danger, etc.) */
    --pzf-on-color: #FFFFFF;
    --pzf-on-warning: #2E1405;
    /* Relleno del tono "secondary" (gris Bootstrap), antes literal ×7. */
    --pzf-secondary-soft: var(--pzf-secondary-soft);

    /* Surfaces */
    --pzf-bg: #F5F8F4;
    --pzf-surface: #FFFFFF;
    --pzf-surface-2: #EBF1EA;
    --pzf-surface-alt: #FFFFFF;      /* sidebar */

    /* Text */
    --pzf-text: #26332B;
    --pzf-text-muted: #64748B;

    /* Borders */
    --pzf-border: #E2E8F0;
    --pzf-border-strong: #CBD5E1;

    /* Effects */
    --pzf-hover: rgba(22, 101, 52, .07);
    --pzf-focus-ring: 0 0 0 .2rem rgba(22, 101, 52, .24);
    --pzf-shadow-sm: 0 1px 2px rgba(15, 23, 42, .04), 0 1px 1px rgba(15, 23, 42, .03);
    --pzf-shadow:    0 4px 14px rgba(15, 23, 42, .07), 0 1px 3px rgba(15, 23, 42, .04);
    --pzf-shadow-lg: 0 18px 38px rgba(15, 23, 42, .11), 0 4px 10px rgba(15, 23, 42, .05);

    /* Geometry */
    --pzf-radius-sm: .4rem;
    --pzf-radius: .6rem;
    --pzf-radius-lg: .85rem;

    /* Easing */
    --pzf-ease: cubic-bezier(.4, 0, .2, 1);
    --pzf-ease-out: cubic-bezier(.16, 1, .3, 1);
    --pzf-ease-spring: cubic-bezier(.34, 1.56, .64, 1);

    /* Layout */
    --pzf-navbar-h: 52px;
    --pzf-sidebar-w: 240px;
    --pzf-sidebar-w-collapsed: 60px;
    --pzf-sidebar-current: var(--pzf-sidebar-w);
}

[data-bs-theme="dark"] {
    /* El verde bosque da 2.24:1 sobre superficie oscura: ilegible. Acá el
       relleno se aclara lo justo para sostener texto blanco (4.54:1) y el
       texto/link usa un verde bastante más claro. */
    --pzf-primary: #2F855A;
    --pzf-primary-hover: #37A06C;
    --pzf-primary-rgb: 47, 133, 90;
    --pzf-primary-text: #5DBE7D;
    --pzf-primary-text-hover: #85DDA8;

    --pzf-bg: #0F1512;
    --pzf-surface: #141A17;
    --pzf-surface-2: #1B231E;
    --pzf-surface-alt: #111713;

    --pzf-text: #E4EDE7;
    --pzf-text-muted: #93A69A;

    /* Con el primario verde, el verde esmeralda de "success" queda demasiado
       cerca en oscuro (1.40:1). Se corre a menta para que el badge de estado
       no se confunda con un botón de marca. */
    --pzf-success: #2DD4A7;
    --pzf-success-rgb: 45, 212, 167;

    /* Sobre fondo oscuro el naranja y el dorado ya contrastan de sobra. */
    --pzf-warning-text: #F0996B;
    --pzf-gold-text: #F0B429;

    --pzf-border: #2A3830;
    --pzf-border-strong: #3C5147;

    --pzf-hover: rgba(93, 190, 125, .15);
    --pzf-focus-ring: 0 0 0 .2rem rgba(93, 190, 125, .35);
    --pzf-primary-soft: rgba(93, 190, 125, .15);
    --pzf-shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
    --pzf-shadow:    0 4px 14px rgba(0, 0, 0, .45);
    --pzf-shadow-lg: 0 18px 38px rgba(0, 0, 0, .60);
}

/* ============================================================
 * 2. Reset / base
 * ============================================================ */
html, body { height: 100vh; }

body {
    background: var(--pzf-bg);
    color: var(--pzf-text);
    display: flex;
    flex-direction: column;
    overflow: hidden; /* el body no scrollea: navbar fija arriba, scroll va en .pzf-page-main */
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
                 Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

main { flex: 1 1 auto; min-height: 0; }

a { color: var(--pzf-primary-text); text-decoration: none; }
a:hover { color: var(--pzf-primary-text-hover); }

code, kbd {
    background: var(--pzf-surface-2);
    color: var(--pzf-text);
    border: 1px solid var(--pzf-border);
    border-radius: .25rem;
    padding: 0 .3rem;
    font-size: .875em;
}
/* Dentro de tablas, code se usa para valores numéricos —
 * no queremos el fondo gris de "código" ahí. */
.table code,
.pzf-table code {
    background: transparent;
    border: 0;
    padding: 0;
    color: inherit;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: inherit;
    font-variant-numeric: tabular-nums;
}
pre {
    background: var(--pzf-surface-2);
    color: var(--pzf-text);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius-sm);
    padding: .75rem 1rem;
    overflow-x: auto;
}

.text-muted { color: var(--pzf-text-muted) !important; }

/* Selección de texto con el azul de marca */
::selection { background: var(--pzf-primary-soft); color: var(--pzf-text); }

/* Scrollbars sutiles */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--pzf-border-strong);
    border-radius: 6px;
    border: 2px solid transparent;
    background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
    background: var(--pzf-text-muted);
    background-clip: padding-box;
}

/* ============================================================
 * 3. Topbar (navbar superior) — clase .pzf-topbar
 * Look: blanca, borde inferior, items grises con underline animado.
 * ============================================================ */
.navbar.pzf-topbar {
    background: var(--pzf-surface);
    border-bottom: 1px solid var(--pzf-border);
    box-shadow: var(--pzf-shadow-sm);
    min-height: var(--pzf-navbar-h);
    padding-top: .2rem;
    padding-bottom: .2rem;
}

.pzf-topbar .navbar-brand {
    display: inline-flex;
    align-items: center;
    gap: .65rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--pzf-text);
    padding: 0;
}
.pzf-topbar .navbar-brand:hover { color: var(--pzf-primary-text); }

.pzf-brand-mark {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: linear-gradient(135deg, var(--pzf-primary) 0%, var(--pzf-primary-hover) 45%, var(--pzf-gold) 115%);
    color: var(--pzf-on-color);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .95rem;
    box-shadow: 0 4px 10px rgba(var(--pzf-primary-rgb), .25);
    flex-shrink: 0;
}

/* Variante con logo: el PNG es circular con fondo transparente; un fondo blanco
   sutil mantiene el contraste del borde verde oscuro en tema oscuro. */
.pzf-brand-mark--img {
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 2px 6px rgba(var(--pzf-primary-rgb), .2);
    overflow: hidden;
}
.pzf-brand-mark--img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.pzf-topbar .nav-link {
    color: var(--pzf-text-muted);
    font-weight: 500;
    font-size: .88rem;
    padding: .4rem .75rem;
    border-radius: var(--pzf-radius-sm);
    position: relative;
    transition: color .15s var(--pzf-ease), background-color .15s var(--pzf-ease);
}
.pzf-topbar .nav-link:hover,
.pzf-topbar .nav-link:focus {
    color: var(--pzf-primary-text);
    background: var(--pzf-primary-soft);
}
.pzf-topbar .nav-link.active,
.pzf-topbar .nav-item.show > .nav-link {
    color: var(--pzf-primary-text);
}

/* Underline animado en items principales (no en dropdowns toggleados ni iconos) */
.pzf-topbar .nav-link:not(.dropdown-toggle):not(.pzf-icon-link)::after {
    content: "";
    position: absolute;
    left: .85rem;
    right: .85rem;
    bottom: .25rem;
    height: 2px;
    background: var(--pzf-primary);
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .25s var(--pzf-ease-out);
}
.pzf-topbar .nav-link:not(.dropdown-toggle):not(.pzf-icon-link):hover::after,
.pzf-topbar .nav-link:not(.dropdown-toggle):not(.pzf-icon-link).active::after {
    transform: scaleX(1);
}

.pzf-topbar .pzf-icon-btn {
    color: var(--pzf-text-muted);
    background: transparent;
    border: 0;
    padding: .35rem .55rem;
    border-radius: var(--pzf-radius-sm);
    transition: background .15s var(--pzf-ease), color .15s var(--pzf-ease);
    font-size: 1rem;
    line-height: 1;
}
.pzf-topbar .pzf-icon-btn:hover {
    color: var(--pzf-primary-text);
    background: var(--pzf-primary-soft);
}

.pzf-topbar .navbar-toggler {
    border-color: var(--pzf-border);
    color: var(--pzf-text-muted);
}
.pzf-topbar .navbar-toggler:focus {
    box-shadow: var(--pzf-focus-ring);
}
.pzf-topbar .navbar-toggler-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%2364748B' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* Campanita badge */
.pzf-topbar .badge.bg-danger {
    background: var(--pzf-gold) !important;
}

/* ============================================================
 * 4. Layout: main = sidebar (sticky, full-bleed) + contenido
 * ============================================================ */
main.pzf-main {
    display: block;
    padding: 0;
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

.pzf-page {
    display: grid;
    grid-template-columns: var(--pzf-sidebar-current) minmax(0, 1fr);
    gap: 0;
    height: 100%;
    min-height: 0;
    transition: grid-template-columns .2s var(--pzf-ease);
}

/* Cuando el bloque sidebar queda vacío (home, login), full-width */
.pzf-page:has(.pzf-page-sidebar:empty) {
    grid-template-columns: minmax(0, 1fr);
}

.pzf-page-sidebar {
    background: var(--pzf-surface-alt);
    border-right: 1px solid var(--pzf-border);
    box-shadow: var(--pzf-shadow-sm);
    padding: 1rem .75rem;
    height: 100%;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
}
.pzf-page-sidebar:empty { display: none; }

.pzf-page-main {
    min-width: 0;
    height: 100%;
    overflow-y: auto;
    padding: 1.1rem 1.35rem;
}

@media (max-width: 992px) {
    .pzf-page { grid-template-columns: minmax(0, 1fr); }
    .pzf-page-main { padding: 1rem .9rem; }

    .pzf-page-sidebar {
        position: fixed;
        top: var(--pzf-navbar-h);
        left: 0;
        bottom: 0;
        width: 280px;
        z-index: 1040;
        transform: translateX(-100%);
        transition: transform .25s var(--pzf-ease-out);
        box-shadow: var(--pzf-shadow-lg);
        height: auto;
    }
    [data-pzf-mobile-sidebar="open"] .pzf-page-sidebar { transform: translateX(0); }
    [data-pzf-mobile-sidebar="open"] body::after {
        content: "";
        position: fixed;
        inset: var(--pzf-navbar-h) 0 0 0;
        background: rgba(0, 0, 0, .4);
        backdrop-filter: blur(2px);
        z-index: 1039;
    }
}

/* ============================================================
 * 5. Sidebar tree
 * ============================================================ */
.pzf-tree { font-size: .85rem; }

.pzf-tree-header {
    font-weight: 700;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--pzf-text);
    padding: .2rem .5rem .6rem;
    border-bottom: 1px solid var(--pzf-border);
    margin-bottom: .4rem;
    display: flex;
    align-items: center;
    gap: .5rem;
    white-space: nowrap;
    overflow: hidden;
}
.pzf-tree-header i { color: var(--pzf-primary-text); }

.pzf-tree ul { list-style: none; padding-left: 0; margin: 0; }
.pzf-tree ul ul {
    padding-left: .5rem;
    border-left: 1px dashed var(--pzf-border-strong);
    margin-left: .75rem;
}
.pzf-tree li { margin: .1rem 0; }

.pzf-tree-group-label {
    display: block;
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--pzf-text);
    opacity: .55;
    padding: .55rem .5rem .2rem;
    font-weight: 700;
    white-space: nowrap;
}

.pzf-tree-leaf {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .4rem .65rem;
    border-radius: var(--pzf-radius-sm);
    color: var(--pzf-text);
    font-weight: 500;
    text-decoration: none;
    transition: background .15s var(--pzf-ease), color .15s var(--pzf-ease), transform .15s var(--pzf-ease);
    white-space: nowrap;
    position: relative;
}
.pzf-tree-leaf:hover {
    background: var(--pzf-hover);
    color: var(--pzf-primary-text);
    transform: translateX(2px);
}
.pzf-tree-leaf.active {
    background: var(--pzf-primary-soft);
    color: var(--pzf-primary-text);
    font-weight: 600;
}
/* Dot indicador a la derecha cuando está activo (microdetalle) */
.pzf-tree-leaf.active::after {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--pzf-primary);
    margin-left: auto;
    flex-shrink: 0;
}
.pzf-tree-leaf.active i { color: var(--pzf-primary-text); opacity: 1; }

.pzf-tree-leaf i {
    width: 1.1rem;
    text-align: center;
    opacity: .8;
    flex-shrink: 0;
    font-size: 1rem;
}

.pzf-tree-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- Sidebar colapsado (icon-only + hover-flyout) ---- */
@media (min-width: 992px) {
    [data-pzf-sidebar="collapsed"] {
        --pzf-sidebar-current: var(--pzf-sidebar-w-collapsed);
    }
    [data-pzf-sidebar="collapsed"] .pzf-page-sidebar {
        padding: 1rem .25rem;
        overflow: visible;
    }
    [data-pzf-sidebar="collapsed"] .pzf-tree-header {
        justify-content: center;
        padding: .25rem 0 .75rem;
    }
    [data-pzf-sidebar="collapsed"] .pzf-tree-header > span { display: none; }
    [data-pzf-sidebar="collapsed"] .pzf-tree-group-label { display: none; }
    [data-pzf-sidebar="collapsed"] .pzf-tree ul ul {
        padding-left: 0;
        border-left: 0;
        margin-left: 0;
    }
    [data-pzf-sidebar="collapsed"] .pzf-tree-leaf {
        justify-content: center;
        padding: .55rem .25rem;
        border-radius: var(--pzf-radius);
        margin: .15rem auto;
        width: 44px;
    }
    [data-pzf-sidebar="collapsed"] .pzf-tree-leaf.active {
        background: var(--pzf-primary);
        color: var(--pzf-on-color);
    }
    [data-pzf-sidebar="collapsed"] .pzf-tree-leaf.active::after { display: none; }
    [data-pzf-sidebar="collapsed"] .pzf-tree-leaf.active i { opacity: 1; color: var(--pzf-on-color); }
    [data-pzf-sidebar="collapsed"] .pzf-tree-label {
        position: absolute;
        left: calc(100% + .35rem);
        top: 50%;
        transform: translateY(-50%);
        background: var(--pzf-surface);
        color: var(--pzf-text);
        border: 1px solid var(--pzf-border);
        border-radius: var(--pzf-radius-sm);
        padding: .3rem .65rem;
        white-space: nowrap;
        box-shadow: var(--pzf-shadow);
        opacity: 0;
        pointer-events: none;
        transition: opacity .15s var(--pzf-ease);
        z-index: 50;
        font-weight: 500;
        flex: none;
        min-width: 0;
    }
    [data-pzf-sidebar="collapsed"] .pzf-tree-leaf:hover .pzf-tree-label {
        opacity: 1;
    }
}

/* ============================================================
 * 6. Widgets (.pzf-widget)
 * ============================================================ */
.pzf-widget {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    padding: .85rem 1rem;
    margin-bottom: .85rem;
    box-shadow: var(--pzf-shadow-sm);
    transition: box-shadow .2s var(--pzf-ease), border-color .2s var(--pzf-ease);
}
.pzf-widget-interactive:hover {
    border-color: var(--pzf-primary-soft);
    box-shadow: var(--pzf-shadow);
}

.pzf-widget-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: .65rem;
    gap: .5rem;
}

.pzf-widget-title {
    font-size: .98rem;
    font-weight: 600;
    margin: 0;
    color: var(--pzf-text);
    letter-spacing: -.01em;
}

.pzf-widget-body { min-height: 60px; }

.pzf-loading { opacity: .5; pointer-events: none; position: relative; }
.pzf-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 50 50'><circle cx='25' cy='25' r='20' fill='none' stroke='%23166534' stroke-width='4' stroke-dasharray='80' stroke-dashoffset='60'><animateTransform attributeName='transform' type='rotate' from='0 25 25' to='360 25 25' dur='1s' repeatCount='indefinite'/></circle></svg>") center / 32px no-repeat;
}

/* ============================================================
 * 7. Forms (inputs, selects)
 * ============================================================ */
.form-label {
    color: var(--pzf-text);
    font-weight: 500;
    font-size: .82rem;
    margin-bottom: .25rem;
}

.form-control,
.form-select {
    background-color: var(--pzf-surface);
    color: var(--pzf-text);
    border: 1px solid var(--pzf-border-strong);
    border-radius: var(--pzf-radius-sm);
    padding: .4rem .7rem;
    font-size: .875rem;
    transition: border-color .15s var(--pzf-ease), box-shadow .15s var(--pzf-ease), background-color .15s var(--pzf-ease);
}

.form-control::placeholder {
    color: var(--pzf-text-muted);
    opacity: .7;
}

.form-control:hover:not(:focus):not(:disabled):not([readonly]),
.form-select:hover:not(:focus):not(:disabled) {
    border-color: var(--pzf-primary);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--pzf-primary);
    background-color: var(--pzf-surface);
    color: var(--pzf-text);
    box-shadow: var(--pzf-focus-ring);
    outline: 0;
}

.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
    background-color: var(--pzf-surface-2);
    color: var(--pzf-text-muted);
    cursor: not-allowed;
    opacity: .85;
}

.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--pzf-danger);
}
.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    box-shadow: 0 0 0 .2rem rgba(var(--pzf-danger-rgb), .22);
}

.form-text { color: var(--pzf-text-muted); font-size: .8rem; }
.form-check-input { background-color: var(--pzf-surface); border-color: var(--pzf-border-strong); }
.form-check-input:checked { background-color: var(--pzf-primary); border-color: var(--pzf-primary); }
.form-check-input:focus { box-shadow: var(--pzf-focus-ring); border-color: var(--pzf-primary); }

/* input-group con botón portal "+" */
.input-group > .btn { border-color: var(--pzf-border-strong); }

/* Card header de secciones de form más prominente */
.card > .card-header {
    background: var(--pzf-surface-2);
    border-bottom: 1px solid var(--pzf-border);
    font-weight: 600;
}

[data-bs-theme="dark"] .form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23E6EDF5' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}

.invalid-feedback.pzf-server-error { display: block; }
.invalid-feedback { color: var(--pzf-danger); font-size: .8rem; }

/* ---- Tom Select: alinear a tokens EL ENSUEÑO ---- */
.ts-wrapper {
    padding: 0 !important;
}

/* Single: altura FIJA igual a .form-control para no empujar el layout
   cuando se escribe en el buscador o aparece la X de clear. */
.ts-wrapper.single .ts-control {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border-strong);
    border-radius: var(--pzf-radius-sm);
    padding: .4rem .7rem;
    box-shadow: none;
    height: calc(1.5em + .8rem + 2px);
    min-height: 0;
    color: var(--pzf-text);
    font-size: .875rem;
    flex-wrap: nowrap;
    overflow: hidden;
    transition: border-color .15s var(--pzf-ease), box-shadow .15s var(--pzf-ease);
}
.ts-wrapper.single .ts-control > input {
    flex: 1 1 auto;
    min-width: 0 !important;
    max-width: 100%;
    width: 100% !important;
}
.ts-wrapper.single .ts-control > .item {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Multi: altura crece con items pero acotada — scrollea internamente
   en vez de empujar el form hacia abajo sin límite. */
.ts-wrapper.multi .ts-control {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border-strong);
    border-radius: var(--pzf-radius-sm);
    padding: .25rem .45rem;
    box-shadow: none;
    min-height: calc(1.5em + .8rem + 2px);
    max-height: calc(3 * (1.5em + .8rem + 2px));
    overflow-y: auto;
    color: var(--pzf-text);
    font-size: .875rem;
    transition: border-color .15s var(--pzf-ease), box-shadow .15s var(--pzf-ease);
}
.ts-wrapper.single .ts-control:hover,
.ts-wrapper.multi .ts-control:hover { border-color: var(--pzf-primary); }
.ts-wrapper.focus .ts-control {
    border-color: var(--pzf-primary) !important;
    box-shadow: var(--pzf-focus-ring) !important;
}
.ts-wrapper.disabled .ts-control {
    background: var(--pzf-surface-2);
    color: var(--pzf-text-muted);
    opacity: .85;
}
.ts-wrapper.is-invalid .ts-control,
.ts-wrapper .ts-control.is-invalid { border-color: var(--pzf-danger) !important; }
.ts-wrapper .ts-control input,
.ts-wrapper .ts-control input::placeholder { color: var(--pzf-text); }
.ts-wrapper .ts-control input::placeholder { color: var(--pzf-text-muted); opacity: .7; }

.ts-dropdown {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border-strong);
    border-radius: var(--pzf-radius-sm);
    box-shadow: var(--pzf-shadow);
    color: var(--pzf-text);
    margin-top: .25rem;
}
/* El dropdown se monta en <body> (dropdownParent en PZF.enhanceSelects) para
   escapar del overflow del modal / .pzf-widget / .pzf-table-wrap: ahí tiene que
   pisar al modal (1055) y al sidebar (1040). */
body > .ts-dropdown { z-index: 1060; }

.ts-dropdown .option,
.ts-dropdown .create { color: var(--pzf-text); padding: .45rem .75rem; }
.ts-dropdown .option.active,
.ts-dropdown .active {
    background: var(--pzf-hover);
    color: var(--pzf-primary-text);
}
.ts-dropdown .option.selected {
    background: var(--pzf-primary-soft);
    color: var(--pzf-primary-text);
    font-weight: 600;
}
.ts-dropdown .no-results,
.ts-dropdown .optgroup-header { color: var(--pzf-text-muted); }

.ts-wrapper.multi .item {
    background: var(--pzf-primary-soft);
    color: var(--pzf-primary-text);
    border: 1px solid rgba(var(--pzf-primary-rgb), .25);
    border-radius: var(--pzf-radius-sm);
    padding: .1rem .5rem;
    margin: .1rem .25rem .1rem 0;
}
.ts-wrapper.plugin-clear_button .clear-button {
    color: var(--pzf-text-muted);
    opacity: .6;
}
.ts-wrapper.plugin-clear_button .clear-button:hover {
    color: var(--pzf-danger);
    opacity: 1;
}

/* ============================================================
 * 8. Tablas
 * ============================================================ */
.pzf-table-wrap {
    overflow-x: auto;
    border-radius: var(--pzf-radius-sm);
}

.pzf-table,
.table {
    width: 100%;
    margin-bottom: 0;
    color: var(--pzf-text);
    --bs-table-bg: transparent;
    --bs-table-color: var(--pzf-text);
    --bs-table-hover-color: var(--pzf-text);
    --bs-table-hover-bg: var(--pzf-hover);
    --bs-table-border-color: var(--pzf-border);
    --bs-table-striped-bg: var(--pzf-surface-2);
    --bs-table-striped-color: var(--pzf-text);
    font-variant-numeric: tabular-nums;
}

.pzf-table thead th,
.table thead th {
    background: var(--pzf-surface-2);
    color: var(--pzf-text-muted);
    font-size: .7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    border-bottom: 1px solid var(--pzf-border);
    padding: .5rem .75rem;
    position: sticky;
    top: 0;
    z-index: 1;
    white-space: nowrap;
}

.pzf-table tbody td,
.table tbody td {
    padding: .35rem .75rem;
    border-top: 1px solid var(--pzf-border);
    vertical-align: middle;
    font-size: .80rem;
    transition: background-color .12s var(--pzf-ease);
}

.pzf-table tbody tr:first-child td,
.table tbody tr:first-child td { border-top: 0; }

.pzf-table tbody tr,
.table tbody tr {
    transition: background-color .12s var(--pzf-ease);
}
.pzf-table tbody tr:hover,
.table tbody tr:hover { background: var(--pzf-hover); }

/* Fila a remover en delete: fade-out animado */
.pzf-table tbody tr.pzf-row-removing,
.table tbody tr.pzf-row-removing {
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity .18s var(--pzf-ease), transform .18s var(--pzf-ease);
}

/* Fade-in stagger genérico — el JS (PZF.utils.fadeInChildren) lo aplica
 * tanto a filas de tabla como a tarjetas, módulos, etc. */
.pzf-row-fade-in {
    opacity: 0;
    animation: pzf-fade-in .35s var(--pzf-ease-out) forwards;
}

.pzf-empty {
    color: var(--pzf-text-muted);
    text-align: center;
    padding: 1.5rem 1rem;
    font-style: italic;
    font-size: .88rem;
}

/* ============================================================
 * 9. Filtros (wrapper opcional para barras de filtros)
 * ============================================================ */
.pzf-filters {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    padding: .65rem .85rem;
    margin-bottom: .85rem;
    box-shadow: var(--pzf-shadow-sm);
}

/* botón "Filtros" — solo visible en mobile (lo inyecta pzf-list-mobile.js) */
.pzf-filters-toggle { display: none; }

@media (max-width: 767.98px) {
    .pzf-filters-toggle { display: inline-flex; align-items: center; gap: .35rem; }
    /* campos ocultos hasta abrir; el toggle agrega .pzf-filters-open */
    .pzf-filters > .row { display: none; }
    .pzf-filters.pzf-filters-open > .row { display: flex; }
}

/* ============================================================
 * 9c. Barra de flujo — pasos de un circuito repartido en pantallas
 *     (ej. Costo hora → Horas trabajadas → Absorción)
 * ============================================================ */
.pzf-flujo {
    display: flex;
    align-items: stretch;
    gap: .35rem;
    margin-bottom: .85rem;
}

.pzf-flujo-paso {
    flex: 1 1 0;
    display: block;
    padding: .5rem .75rem;
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    background: var(--pzf-surface);
    color: var(--pzf-text-muted);
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease;
}

a.pzf-flujo-paso:hover {
    background: var(--pzf-surface-2);
    border-color: var(--pzf-border-strong);
    color: var(--pzf-text-muted);
}

.pzf-flujo-paso.active {
    background: var(--pzf-primary-soft);
    border-color: var(--pzf-primary);
}

/* Sin permiso: se ve que el paso existe, pero no a dónde va. */
.pzf-flujo-paso.disabled { opacity: .45; }

.pzf-flujo-nombre {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .85rem;
    font-weight: 600;
    color: var(--pzf-text);
}

.pzf-flujo-paso.active .pzf-flujo-nombre { color: var(--pzf-primary-text); }

.pzf-flujo-num {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: var(--pzf-surface-2);
    color: var(--pzf-text-muted);
    font-size: .7rem;
    line-height: 1.15rem;
    text-align: center;
    font-weight: 700;
}

.pzf-flujo-paso.active .pzf-flujo-num {
    background: var(--pzf-primary);
    color: var(--pzf-on-color);
}

.pzf-flujo-desc {
    display: block;
    margin-top: .1rem;
    font-size: .74rem;
    line-height: 1.25;
    color: var(--pzf-text-muted);
}

@media (max-width: 575.98px) {
    .pzf-flujo { flex-wrap: wrap; gap: .25rem; }
    .pzf-flujo-paso { flex: 1 1 auto; padding: .35rem .5rem; }
    .pzf-flujo-desc { display: none; }
}

/* ============================================================
 * 9b. Tablas como cards apiladas en mobile
 *     (pzf-list-mobile.js inyecta data-label desde el thead)
 * ============================================================ */
@media (max-width: 767.98px) {
    .pzf-table-wrap:has(.pzf-table-mobile) { overflow-x: visible; }

    .pzf-table-mobile thead,
    .pzf-table-mobile colgroup { display: none; }

    .pzf-table-mobile tbody { display: block; }

    .pzf-table-mobile tbody tr {
        display: block;
        background: var(--pzf-surface);
        border: 1px solid var(--pzf-border);
        border-radius: var(--pzf-radius-sm);
        box-shadow: var(--pzf-shadow-sm);
        margin-bottom: .55rem;
        padding: .35rem .8rem;
    }
    .pzf-table-mobile tbody tr:hover { background: var(--pzf-surface); }
    .pzf-table-mobile tbody tr:first-child td { border-top: 0; }

    .pzf-table-mobile tbody td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 1rem;
        border: 0 !important;
        border-top: 0 !important;
        padding: .3rem 0 !important;
        text-align: right;
        white-space: normal;
    }
    .pzf-table-mobile tbody td::before {
        content: attr(data-label);
        font-size: .66rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--pzf-text-muted);
        text-align: left;
        flex-shrink: 0;
    }
    /* celdas sin etiqueta o vacías (acciones, filas "cargando/sin datos") */
    .pzf-table-mobile tbody td:empty { display: none; }
    .pzf-table-mobile tbody td.pzf-empty,
    .pzf-table-mobile tbody td[colspan] {
        display: block;
        text-align: center;
    }
    .pzf-table-mobile tbody td.pzf-empty::before,
    .pzf-table-mobile tbody td[colspan]::before { content: none; }
}

/* ============================================================
 * 10. Botones
 * ============================================================ */
.btn {
    border-radius: var(--pzf-radius-sm);
    font-weight: 500;
    transition: transform .1s var(--pzf-ease), box-shadow .15s var(--pzf-ease), background-color .15s var(--pzf-ease), border-color .15s var(--pzf-ease), color .15s var(--pzf-ease);
}
.btn:focus,
.btn:focus-visible {
    box-shadow: var(--pzf-focus-ring);
}
.btn:active { transform: scale(.97); }

.btn-primary {
    background: var(--pzf-primary);
    border-color: var(--pzf-primary);
    color: var(--pzf-on-color);
}
.btn-primary:hover {
    background: var(--pzf-primary-hover);
    border-color: var(--pzf-primary-hover);
    color: var(--pzf-on-color);
}
.btn-primary:active { transform: scale(.97); }

.btn-outline-primary {
    color: var(--pzf-primary-text);
    border-color: var(--pzf-primary);
    background: transparent;
}
.btn-outline-primary:hover {
    background: var(--pzf-primary);
    color: var(--pzf-on-color);
}

.btn-link { color: var(--pzf-primary-text); }
.btn-link:hover { color: var(--pzf-primary-text-hover); }

/* Botón dorado: CTA destacado del producto (no para errores).
 * Lleva texto oscuro: sobre el dorado el blanco da 1.86:1. */
.btn-gold {
    background: var(--pzf-gold);
    border: 1px solid var(--pzf-gold);
    color: var(--pzf-on-gold);
}
.btn-gold:hover,
.btn-gold:focus {
    background: var(--pzf-gold-hover);
    border-color: var(--pzf-gold-hover);
    color: var(--pzf-on-gold);
}
.btn-outline-gold {
    background: transparent;
    border: 1px solid var(--pzf-gold);
    color: var(--pzf-gold-text);
}
.btn-outline-gold:hover,
.btn-outline-gold:focus {
    background: var(--pzf-gold);
    color: var(--pzf-on-gold);
}

/* ============================================================
 * 11. Badges suaves (override Bootstrap text-bg-*)
 * ============================================================ */
.badge {
    font-weight: 600;
    padding: .3em .6em;
    border-radius: 999px;
    font-size: .68rem;
    letter-spacing: .01em;
}

.badge.text-bg-primary {
    background-color: var(--pzf-primary-soft) !important;
    color: var(--pzf-primary-text) !important;
}
.badge.text-bg-success {
    background-color: rgba(var(--pzf-success-rgb), .14) !important;
    color: var(--pzf-success) !important;
}
.badge.text-bg-warning {
    background-color: rgba(var(--pzf-warning-rgb), .18) !important;
    color: var(--pzf-warning-text) !important;
}
.badge.text-bg-danger {
    background-color: rgba(var(--pzf-danger-rgb), .14) !important;
    color: var(--pzf-danger) !important;
}
.badge.text-bg-info {
    background-color: rgba(var(--pzf-info-rgb), .14) !important;
    color: var(--pzf-info) !important;
}
.badge.text-bg-secondary {
    background-color: var(--pzf-secondary-soft) !important;
    color: var(--pzf-text-muted) !important;
}
.badge.text-bg-gold {
    background-color: var(--pzf-gold-soft) !important;
    color: var(--pzf-gold-text) !important;
}

/* ============================================================
 * 12. Cards / modals / dropdowns / alerts (dark-mode aware)
 * ============================================================ */
.card {
    background: var(--pzf-surface);
    color: var(--pzf-text);
    border-color: var(--pzf-border);
}

.alert {
    border-radius: var(--pzf-radius);
    padding: .65rem .85rem;
    font-size: .88rem;
    margin-bottom: .75rem;
}

/* Breadcrumb default compacto — usado fuera del portal también */
.breadcrumb {
    margin-bottom: .65rem;
    font-size: .8rem;
}
.breadcrumb-item + .breadcrumb-item::before {
    color: var(--pzf-text-muted);
}
[data-bs-theme="dark"] .alert-info,
[data-bs-theme="dark"] .alert-primary {
    background-color: var(--pzf-primary-soft);
    border-color: rgba(var(--pzf-primary-rgb), .25);
    color: var(--pzf-primary-text);
}
[data-bs-theme="dark"] .alert-success {
    background-color: rgba(var(--pzf-success-rgb), .14);
    border-color: rgba(var(--pzf-success-rgb), .25);
    color: var(--pzf-success);
}
[data-bs-theme="dark"] .alert-warning {
    background-color: rgba(var(--pzf-warning-rgb), .14);
    border-color: rgba(var(--pzf-warning-rgb), .28);
    color: var(--pzf-warning-text);
}
[data-bs-theme="dark"] .alert-danger {
    background-color: rgba(var(--pzf-danger-rgb), .14);
    border-color: rgba(var(--pzf-danger-rgb), .28);
    color: #F08089;
}

/* Modales scrollables por default. */
.modal .modal-content {
    max-height: calc(100vh - 1rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    width: 100%;
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    box-shadow: var(--pzf-shadow-lg);
}
@media (min-width: 576px) {
    .modal .modal-content {
        max-height: calc(100vh - 3.5rem);
    }
}
.modal .modal-body {
    overflow-y: auto;
    min-height: 0;
    flex: 1 1 auto;
    padding: .85rem 1rem;
}
.modal .modal-header,
.modal .modal-footer {
    flex-shrink: 0;
    padding: .65rem 1rem;
}
.modal .modal-title {
    font-size: 1rem;
    font-weight: 600;
}
.modal .modal-content > form {
    display: contents;
}

/* Entrada animada del modal: fade + slide-up sutil */
.modal.fade .modal-dialog {
    transform: translateY(-12px);
    transition: transform .25s var(--pzf-ease-out), opacity .2s var(--pzf-ease);
}
.modal.show .modal-dialog {
    transform: translateY(0);
}

/* Backdrop con blur si el browser lo soporta */
.modal-backdrop.show { opacity: .55; }
@supports (backdrop-filter: blur(2px)) {
    .modal-backdrop.show { backdrop-filter: blur(2px); }
}

[data-bs-theme="dark"] .modal-content {
    background: var(--pzf-surface);
    color: var(--pzf-text);
    border-color: var(--pzf-border);
}
[data-bs-theme="dark"] .modal-header,
[data-bs-theme="dark"] .modal-footer { border-color: var(--pzf-border); }

.dropdown-menu {
    background: var(--pzf-surface);
    border-color: var(--pzf-border);
    box-shadow: var(--pzf-shadow);
    border-radius: var(--pzf-radius);
    padding: .35rem;
    animation: pzf-dropdown-in .15s var(--pzf-ease-out);
}
.dropdown-item {
    color: var(--pzf-text);
    border-radius: var(--pzf-radius-sm);
    padding: .45rem .65rem;
}
.dropdown-item:hover,
.dropdown-item:focus {
    background: var(--pzf-hover);
    color: var(--pzf-primary-text);
}
.dropdown-divider { border-color: var(--pzf-border); }
.dropdown-header { color: var(--pzf-text-muted); }

.pagination .page-link {
    color: var(--pzf-primary-text);
    background: var(--pzf-surface);
    border-color: var(--pzf-border);
    transition: background-color .12s var(--pzf-ease), color .12s var(--pzf-ease);
}
.pagination .page-link:hover {
    background: var(--pzf-hover);
    border-color: var(--pzf-border);
    color: var(--pzf-primary-text-hover);
}
.pagination .page-item.active .page-link {
    background: var(--pzf-primary);
    border-color: var(--pzf-primary);
    color: var(--pzf-on-color);
}
.pagination .page-item.disabled .page-link {
    background: var(--pzf-surface);
    color: var(--pzf-text-muted);
}

/* ============================================================
 * 13. KPI tiles
 * ============================================================ */
.pzf-kpi-tile {
    display: flex;
    align-items: center;
    gap: .7rem;
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-left: 3px solid var(--pzf-primary);
    border-radius: var(--pzf-radius);
    padding: .75rem .95rem;
    text-decoration: none;
    color: var(--pzf-text);
    height: 100%;
    box-shadow: var(--pzf-shadow-sm);
    transition: transform .2s var(--pzf-ease-out), box-shadow .2s var(--pzf-ease-out), border-color .2s var(--pzf-ease);
    position: relative;
    overflow: hidden;
}
.pzf-kpi-tile:hover {
    transform: translateY(-3px);
    box-shadow: var(--pzf-shadow-lg);
    color: var(--pzf-text);
}

.pzf-kpi-icon {
    width: 36px; height: 36px; flex-shrink: 0;
    border-radius: 10px;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.05rem;
    background: var(--pzf-primary-soft);
    color: var(--pzf-primary-text);
}
.pzf-kpi-body { min-width: 0; }
.pzf-kpi-value {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--pzf-text);
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}
.pzf-kpi-label {
    font-size: .7rem;
    color: var(--pzf-text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-top: .1rem;
    font-weight: 500;
}

.pzf-kpi-primary { border-left-color: var(--pzf-primary); }
.pzf-kpi-primary .pzf-kpi-icon { background: var(--pzf-primary-soft); color: var(--pzf-primary-text); }
.pzf-kpi-success { border-left-color: var(--pzf-success); }
.pzf-kpi-success .pzf-kpi-icon { background: rgba(var(--pzf-success-rgb), .12); color: var(--pzf-success); }
.pzf-kpi-warning { border-left-color: var(--pzf-warning); }
.pzf-kpi-warning .pzf-kpi-icon { background: rgba(var(--pzf-warning-rgb), .14); color: var(--pzf-warning-text); }
.pzf-kpi-danger { border-left-color: var(--pzf-danger); }
.pzf-kpi-danger .pzf-kpi-icon { background: rgba(var(--pzf-danger-rgb), .12); color: var(--pzf-danger); }
.pzf-kpi-info { border-left-color: var(--pzf-info); }
.pzf-kpi-info .pzf-kpi-icon { background: rgba(var(--pzf-info-rgb), .14); color: var(--pzf-info); }
.pzf-kpi-gold { border-left-color: var(--pzf-gold); }
.pzf-kpi-gold .pzf-kpi-icon { background: var(--pzf-gold-soft); color: var(--pzf-gold-text); }
.pzf-kpi-secondary { border-left-color: var(--pzf-border-strong); }
.pzf-kpi-secondary .pzf-kpi-icon { background: var(--pzf-secondary-soft); color: var(--pzf-text-muted); }

/* ============================================================
 * 14. Cards de módulo (home)
 * ============================================================ */
.pzf-modulo-card {
    display: flex;
    align-items: flex-start;
    gap: .8rem;
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    padding: .85rem 1rem;
    text-decoration: none;
    color: var(--pzf-text);
    height: 100%;
    box-shadow: var(--pzf-shadow-sm);
    transition: transform .2s var(--pzf-ease-out), box-shadow .2s var(--pzf-ease-out), border-color .2s var(--pzf-ease);
    position: relative;
}
.pzf-modulo-card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--pzf-radius);
    pointer-events: none;
    box-shadow: inset 0 0 0 0 var(--pzf-primary);
    transition: box-shadow .25s var(--pzf-ease);
}
.pzf-modulo-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--pzf-shadow-lg);
    border-color: rgba(var(--pzf-primary-rgb), .35);
    color: var(--pzf-text);
}

.pzf-modulo-icon {
    width: 40px; height: 40px; flex-shrink: 0;
    border-radius: var(--pzf-radius-sm);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.25rem;
    background: var(--pzf-primary-soft);
    color: var(--pzf-primary-text);
}
.pzf-modulo-body { min-width: 0; }
.pzf-modulo-title { font-weight: 600; font-size: .92rem; margin-bottom: .15rem; color: var(--pzf-text); letter-spacing: -.01em; }
.pzf-modulo-desc { font-size: .78rem; color: var(--pzf-text-muted); line-height: 1.4; }

.pzf-modulo-primary .pzf-modulo-icon { background: var(--pzf-primary-soft); color: var(--pzf-primary-text); }
.pzf-modulo-success .pzf-modulo-icon { background: rgba(var(--pzf-success-rgb), .12); color: var(--pzf-success); }
.pzf-modulo-warning .pzf-modulo-icon { background: rgba(var(--pzf-warning-rgb), .14); color: var(--pzf-warning-text); }
.pzf-modulo-danger  .pzf-modulo-icon { background: rgba(var(--pzf-danger-rgb), .12); color: var(--pzf-danger); }
.pzf-modulo-info    .pzf-modulo-icon { background: rgba(var(--pzf-info-rgb), .14); color: var(--pzf-info); }
.pzf-modulo-gold  .pzf-modulo-icon { background: var(--pzf-gold-soft); color: var(--pzf-gold-text); }
.pzf-modulo-secondary .pzf-modulo-icon { background: var(--pzf-secondary-soft); color: var(--pzf-text-muted); }

/* ============================================================
 * 15. Home header
 * ============================================================ */
.pzf-home-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

/* ============================================================
 * 16. Dashboards — section headers, charts, progress, deltas
 * ============================================================ */

.pzf-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .65rem;
    margin: .95rem 0 .55rem;
    flex-wrap: wrap;
}
.pzf-section-header:first-child { margin-top: 0; }
.pzf-section-header-title {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    font-size: .92rem;
    font-weight: 600;
    color: var(--pzf-text);
    margin: 0;
    letter-spacing: -.01em;
}
.pzf-section-header-title i {
    color: var(--pzf-primary-text);
    font-size: 1rem;
}
.pzf-section-header-meta {
    font-size: .76rem;
    color: var(--pzf-text-muted);
}

.pzf-chart {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    box-shadow: var(--pzf-shadow-sm);
    padding: .65rem .75rem;
    min-height: 220px;
    position: relative;
}
.pzf-chart-title {
    font-size: .78rem;
    font-weight: 600;
    color: var(--pzf-text);
    margin-bottom: .4rem;
}
.pzf-chart-canvas {
    width: 100%;
    height: 240px;
}

.pzf-progress {
    height: 6px;
    background: var(--pzf-primary-soft);
    border-radius: 999px;
    overflow: hidden;
    margin-top: .5rem;
}
.pzf-progress-bar {
    height: 100%;
    border-radius: 999px;
    background: var(--pzf-primary);
    transition: width .5s var(--pzf-ease-out);
}
.pzf-progress-primary .pzf-progress-bar { background: var(--pzf-primary); }
.pzf-progress-success .pzf-progress-bar { background: var(--pzf-success); }
.pzf-progress-warning .pzf-progress-bar { background: var(--pzf-warning); }
.pzf-progress-danger  .pzf-progress-bar { background: var(--pzf-danger); }
.pzf-progress-info    .pzf-progress-bar { background: var(--pzf-info); }
.pzf-progress-gold  .pzf-progress-bar { background: var(--pzf-gold); }

.pzf-stat-delta {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    font-size: .68rem;
    font-weight: 600;
    padding: .12rem .45rem;
    border-radius: 999px;
    line-height: 1;
}
.pzf-stat-delta-up {
    color: var(--pzf-success);
    background: rgba(var(--pzf-success-rgb), .12);
}
.pzf-stat-delta-down {
    color: var(--pzf-danger);
    background: rgba(var(--pzf-danger-rgb), .12);
}
.pzf-stat-delta-flat {
    color: var(--pzf-text-muted);
    background: var(--pzf-secondary-soft);
}

.pzf-kpi-tile.has-spark { align-items: stretch; }
.pzf-kpi-spark {
    width: 90px; height: 36px;
    margin-left: auto;
    align-self: center;
    flex-shrink: 0;
}

.pzf-timeline { list-style: none; padding: 0; margin: 0; }
.pzf-timeline-item {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    padding: .5rem .25rem;
    border-bottom: 1px solid var(--pzf-border);
}
.pzf-timeline-item:last-child { border-bottom: 0; }
.pzf-timeline-icon {
    width: 28px; height: 28px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--pzf-primary-soft);
    color: var(--pzf-primary-text);
    flex-shrink: 0;
    font-size: .85rem;
}
.pzf-timeline-icon.tone-success { background: rgba(var(--pzf-success-rgb), .12); color: var(--pzf-success); }
.pzf-timeline-icon.tone-warning { background: rgba(var(--pzf-warning-rgb), .14); color: var(--pzf-warning-text); }
.pzf-timeline-icon.tone-danger  { background: rgba(var(--pzf-danger-rgb), .12);  color: var(--pzf-danger); }
.pzf-timeline-icon.tone-info    { background: rgba(var(--pzf-info-rgb), .14);            color: var(--pzf-info); }
.pzf-timeline-icon.tone-gold  { background: var(--pzf-gold-soft);            color: var(--pzf-gold-text); }
.pzf-timeline-icon.tone-secondary { background: var(--pzf-secondary-soft); color: var(--pzf-text-muted); }
.pzf-timeline-body { min-width: 0; flex: 1; }
.pzf-timeline-title {
    font-size: .85rem;
    color: var(--pzf-text);
    line-height: 1.35;
}
.pzf-timeline-meta {
    font-size: .7rem;
    color: var(--pzf-text-muted);
    margin-top: .1rem;
}

/* ---------- KPI list (lista compacta de KPIs dentro de un .pzf-widget) ---------- */
.pzf-kpi-list { display: flex; flex-direction: column; }
.pzf-kpi-row {
    display: grid;
    grid-template-columns: 26px 1fr auto;
    align-items: center;
    gap: .65rem;
    padding: .5rem .2rem;
    border-top: 1px solid var(--pzf-border);
    transition: background-color .15s var(--pzf-ease);
}
.pzf-kpi-row:first-child { border-top: 0; }
.pzf-kpi-row:hover { background: var(--pzf-hover); }
.pzf-kpi-row-icon {
    width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    background: var(--pzf-secondary-soft);
    color: var(--pzf-text-muted);
    font-size: .8rem;
    flex-shrink: 0;
}
.pzf-kpi-row-label {
    font-size: .85rem;
    color: var(--pzf-text);
    line-height: 1.3;
    min-width: 0;
}
.pzf-kpi-row-label small {
    display: block;
    font-size: .7rem;
    color: var(--pzf-text-muted);
    margin-top: .08rem;
}
.pzf-kpi-row-value {
    font-size: .98rem;
    font-weight: 600;
    color: var(--pzf-text);
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.pzf-kpi-row.tone-primary .pzf-kpi-row-icon { background: var(--pzf-primary-soft); color: var(--pzf-primary-text); }
.pzf-kpi-row.tone-success .pzf-kpi-row-icon { background: rgba(var(--pzf-success-rgb), .12); color: var(--pzf-success); }
.pzf-kpi-row.tone-success .pzf-kpi-row-value { color: var(--pzf-success); }
.pzf-kpi-row.tone-warning .pzf-kpi-row-icon { background: rgba(var(--pzf-warning-rgb), .14); color: var(--pzf-warning-text); }
.pzf-kpi-row.tone-warning .pzf-kpi-row-value { color: var(--pzf-warning-text); }
.pzf-kpi-row.tone-danger  .pzf-kpi-row-icon { background: rgba(var(--pzf-danger-rgb), .12);  color: var(--pzf-danger); }
.pzf-kpi-row.tone-danger  .pzf-kpi-row-value { color: var(--pzf-danger); }
.pzf-kpi-row.tone-info    .pzf-kpi-row-icon { background: rgba(var(--pzf-info-rgb), .14);            color: var(--pzf-info); }
.pzf-kpi-row.tone-gold  .pzf-kpi-row-icon { background: var(--pzf-gold-soft);            color: var(--pzf-gold-text); }
.pzf-kpi-row.tone-gold  .pzf-kpi-row-value { color: var(--pzf-gold-text); }

.pzf-kpi-row-with-progress { grid-template-columns: 28px 1fr auto; }
.pzf-kpi-row-progress {
    grid-column: 1 / -1;
    margin-top: .45rem;
}

.pzf-widget-title-h {
    display: flex;
    align-items: center;
    gap: .45rem;
    font-size: .92rem;
    font-weight: 600;
    color: var(--pzf-text);
    margin: 0 0 .65rem 0;
    letter-spacing: -.01em;
}
.pzf-widget-title-h i { color: var(--pzf-primary-text); font-size: 1rem; }
.pzf-widget-title-h .pzf-widget-title-meta {
    margin-left: auto;
    font-size: .72rem;
    font-weight: 400;
    color: var(--pzf-text-muted);
}

.pzf-dashboard-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .85rem;
    flex-wrap: wrap;
    margin-bottom: .95rem;
}
.pzf-dashboard-header h1 {
    display: inline-flex; align-items: center; gap: .5rem;
    margin: 0;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -.02em;
}
.pzf-dashboard-header h1 i { color: var(--pzf-primary-text); }
.pzf-dashboard-header-meta {
    font-size: .76rem;
    color: var(--pzf-text-muted);
}

/* ============================================================
 * 17. Skeleton loaders (placeholders animados durante AJAX)
 * ============================================================ */
.pzf-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--pzf-surface-2);
    border-radius: var(--pzf-radius-sm);
    display: inline-block;
}
.pzf-skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(255, 255, 255, .55) 50%,
        transparent 100%);
    transform: translateX(-100%);
    animation: pzf-shimmer 1.4s infinite var(--pzf-ease);
}
[data-bs-theme="dark"] .pzf-skeleton::after {
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(255, 255, 255, .08) 50%,
        transparent 100%);
}
.pzf-skeleton-text {
    height: .8rem;
    width: 100%;
    border-radius: var(--pzf-radius-sm);
    margin: .25rem 0;
}
.pzf-skeleton-text.sm  { width: 35%; }
.pzf-skeleton-text.md  { width: 60%; }
.pzf-skeleton-text.lg  { width: 90%; }
.pzf-skeleton-circle {
    width: 32px;
    height: 32px;
    border-radius: 50%;
}
.pzf-skeleton-card {
    width: 100%;
    height: 120px;
    border-radius: var(--pzf-radius);
}
.pzf-skeleton-row td {
    border-top: 1px solid var(--pzf-border) !important;
    padding: .85rem !important;
}
.pzf-skeleton-row .pzf-skeleton {
    height: .9rem;
    width: 80%;
}

/* ============================================================
 * 18. Toasts (slide-down arriba a la derecha)
 * ============================================================ */
.pzf-toast-container {
    position: fixed;
    top: calc(var(--pzf-navbar-h) + .75rem);
    right: 1rem;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    pointer-events: none;
}
.pzf-toast {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-left: 4px solid var(--pzf-primary);
    border-radius: var(--pzf-radius);
    box-shadow: var(--pzf-shadow-lg);
    padding: .75rem 1rem .75rem .85rem;
    min-width: 260px;
    max-width: 380px;
    display: flex;
    align-items: flex-start;
    gap: .65rem;
    color: var(--pzf-text);
    font-size: .9rem;
    pointer-events: auto;
    animation: pzf-toast-in .3s var(--pzf-ease-out);
}
.pzf-toast.pzf-toast-out {
    animation: pzf-toast-out .25s var(--pzf-ease) forwards;
}
.pzf-toast-icon {
    flex-shrink: 0;
    font-size: 1.15rem;
    line-height: 1.2;
    color: var(--pzf-primary-text);
}
.pzf-toast-body { flex: 1; min-width: 0; }
.pzf-toast-close {
    background: transparent;
    border: 0;
    color: var(--pzf-text-muted);
    padding: 0 .25rem;
    cursor: pointer;
    line-height: 1;
    font-size: 1.1rem;
    transition: color .15s var(--pzf-ease);
}
.pzf-toast-close:hover { color: var(--pzf-text); }

.pzf-toast.tone-success { border-left-color: var(--pzf-success); }
.pzf-toast.tone-success .pzf-toast-icon { color: var(--pzf-success); }
.pzf-toast.tone-danger  { border-left-color: var(--pzf-danger); }
.pzf-toast.tone-danger  .pzf-toast-icon { color: var(--pzf-danger); }
.pzf-toast.tone-warning { border-left-color: var(--pzf-warning); }
.pzf-toast.tone-warning .pzf-toast-icon { color: var(--pzf-warning-text); }
.pzf-toast.tone-info    { border-left-color: var(--pzf-info); }
.pzf-toast.tone-info    .pzf-toast-icon { color: var(--pzf-info); }
.pzf-toast.tone-gold  { border-left-color: var(--pzf-gold); }
.pzf-toast.tone-gold  .pzf-toast-icon { color: var(--pzf-gold-text); }

/* ============================================================
 * 19. Animaciones globales
 * ============================================================ */
@keyframes pzf-fade-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes pzf-shimmer {
    100% { transform: translateX(100%); }
}

@keyframes pzf-dropdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

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

@keyframes pzf-toast-out {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(-12px); }
}

/* ============================================================
 * 20. Cuenta corriente (clientes / proveedores)
 *     Hero + display de saldo + tabla de movimientos.
 * ============================================================ */
.pzf-cc-hero {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    box-shadow: var(--pzf-shadow-sm);
    padding: 1rem 1.15rem;
    margin-bottom: .85rem;
    position: relative;
    overflow: hidden;
    display: grid;
    grid-template-columns: 1.2fr minmax(220px, .9fr);
    gap: 1.25rem;
    align-items: center;
}
.pzf-cc-hero::before {
    content: "";
    position: absolute;
    top: 0; left: 0;
    width: 5px;
    height: 100%;
    background: linear-gradient(180deg, var(--pzf-primary), var(--pzf-gold));
}
@media (max-width: 768px) {
    .pzf-cc-hero { grid-template-columns: 1fr; gap: 1.25rem; }
}

.pzf-cc-hero-info { min-width: 0; }
.pzf-cc-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--pzf-text-muted);
    margin-bottom: .25rem;
}
.pzf-cc-hero-eyebrow i { color: var(--pzf-primary-text); }
.pzf-cc-hero-title {
    font-size: 1.2rem;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--pzf-text);
    margin: 0 0 .25rem 0;
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: .45rem;
    flex-wrap: wrap;
}
.pzf-cc-hero-meta {
    color: var(--pzf-text-muted);
    font-size: .8rem;
    display: flex;
    gap: .85rem;
    flex-wrap: wrap;
    margin-top: .15rem;
}
.pzf-cc-hero-meta span {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}
.pzf-cc-hero-meta strong {
    color: var(--pzf-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Display de saldo principal */
.pzf-cc-saldo {
    background: var(--pzf-surface-2);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius-sm);
    padding: .8rem 1rem;
    text-align: right;
    position: relative;
}
.pzf-cc-saldo-label {
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--pzf-text-muted);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .3rem;
    margin-bottom: .25rem;
}
.pzf-cc-saldo-value {
    font-size: 1.65rem;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: var(--pzf-text);
}
.pzf-cc-saldo-currency {
    font-size: .92rem;
    font-weight: 600;
    color: var(--pzf-text-muted);
    margin-right: .3rem;
}

.pzf-cc-saldo.tone-debt {
    background: rgba(var(--pzf-danger-rgb), .07);
    border-color: rgba(var(--pzf-danger-rgb), .25);
}
.pzf-cc-saldo.tone-debt .pzf-cc-saldo-label { color: var(--pzf-danger); }
.pzf-cc-saldo.tone-debt .pzf-cc-saldo-value { color: var(--pzf-danger); }

.pzf-cc-saldo.tone-credit {
    background: rgba(var(--pzf-success-rgb), .07);
    border-color: rgba(var(--pzf-success-rgb), .25);
}
.pzf-cc-saldo.tone-credit .pzf-cc-saldo-label { color: var(--pzf-success); }
.pzf-cc-saldo.tone-credit .pzf-cc-saldo-value { color: var(--pzf-success); }

.pzf-cc-saldo.tone-zero {
    background: var(--pzf-surface-2);
}
.pzf-cc-saldo.tone-zero .pzf-cc-saldo-value { color: var(--pzf-text-muted); }

/* Toolbar de acciones */
.pzf-cc-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .65rem;
    flex-wrap: wrap;
    margin-bottom: .75rem;
}
.pzf-cc-toolbar-actions {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}
.pzf-cc-toolbar-filter {
    display: flex;
    align-items: center;
    gap: .5rem;
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    padding: .25rem .5rem .25rem .75rem;
    box-shadow: var(--pzf-shadow-sm);
}
.pzf-cc-toolbar-filter label {
    font-size: .78rem;
    color: var(--pzf-text-muted);
    margin: 0;
    white-space: nowrap;
}
.pzf-cc-toolbar-filter .form-control {
    border: 0;
    padding: .35rem .5rem;
    background: transparent;
    min-width: 120px;
    box-shadow: none;
    font-size: .85rem;
}
.pzf-cc-toolbar-filter .form-control:focus { box-shadow: none; }

/* Tabla de movimientos: tonos y signos por columna */
.pzf-cc-table td.pzf-cc-debe-cell  { color: var(--pzf-danger); font-weight: 500; }
.pzf-cc-table td.pzf-cc-haber-cell { color: var(--pzf-success); font-weight: 500; }
.pzf-cc-table td.pzf-cc-saldo-cell {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.pzf-cc-table td.pzf-cc-saldo-cell.is-debt   { color: var(--pzf-danger); }
.pzf-cc-table td.pzf-cc-saldo-cell.is-credit { color: var(--pzf-success); }
.pzf-cc-table td.pzf-cc-saldo-cell.is-zero   { color: var(--pzf-text-muted); }

.pzf-cc-table tfoot td {
    background: var(--pzf-surface-2);
    border-top: 2px solid var(--pzf-border-strong);
    padding: .75rem .85rem;
    font-weight: 600;
}

/* Badge por tipo de movimiento (tono según texto del tipo via JS o data-attr) */
.pzf-cc-tipo-badge {
    display: inline-block;
    padding: .25em .65em;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .01em;
    background: var(--pzf-secondary-soft);
    color: var(--pzf-text-muted);
    white-space: nowrap;
}
.pzf-cc-tipo-badge[data-tone="primary"] { background: var(--pzf-primary-soft); color: var(--pzf-primary-text); }
.pzf-cc-tipo-badge[data-tone="success"] { background: rgba(var(--pzf-success-rgb), .14); color: var(--pzf-success); }
.pzf-cc-tipo-badge[data-tone="danger"]  { background: rgba(var(--pzf-danger-rgb), .14);  color: var(--pzf-danger); }
.pzf-cc-tipo-badge[data-tone="warning"] { background: rgba(var(--pzf-warning-rgb), .18); color: var(--pzf-warning-text); }
.pzf-cc-tipo-badge[data-tone="info"]    { background: rgba(var(--pzf-info-rgb), .14); color: var(--pzf-info); }
.pzf-cc-tipo-badge[data-tone="gold"]  { background: var(--pzf-gold-soft); color: var(--pzf-gold-text); }

/* Empty state amigable */
.pzf-cc-empty {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--pzf-text-muted);
    font-size: .9rem;
}
.pzf-cc-empty i {
    font-size: 2rem;
    color: var(--pzf-border-strong);
    margin-bottom: .35rem;
    display: block;
}

/* ============================================================
 * 21. Overrides utilidades Bootstrap para alinear a la paleta.
 * Bootstrap usa --bs-primary internamente para .bg-primary, .text-primary, etc.
 * Lo redirigimos al token EL ENSUEÑO para evitar el azul Bootstrap default.
 * ============================================================ */
:root {
    --bs-primary: var(--pzf-primary);
    --bs-primary-rgb: var(--pzf-primary-rgb);
    --bs-link-color: var(--pzf-primary-text);
    --bs-link-hover-color: var(--pzf-primary-text-hover);
    --bs-body-color: var(--pzf-text);
    --bs-body-bg: var(--pzf-bg);
    --bs-border-color: var(--pzf-border);
    /* Sin esto los ~40 bg-warning de los templates usarían el #ffc107 stock
       de Bootstrap y el naranja de "atención" no se vería en pantalla. */
    --bs-warning: var(--pzf-warning);
    --bs-warning-rgb: var(--pzf-warning-rgb);
    --bs-success: var(--pzf-success);
    --bs-success-rgb: var(--pzf-success-rgb);
    --bs-info: var(--pzf-info);
    --bs-info-rgb: var(--pzf-info-rgb);
    --bs-danger: var(--pzf-danger);
    --bs-danger-rgb: var(--pzf-danger-rgb);
}

.bg-primary {
    background-color: var(--pzf-primary) !important;
}
.text-primary {
    color: var(--pzf-primary-text) !important;
}
.border-primary {
    border-color: var(--pzf-primary) !important;
}
.link-primary {
    color: var(--pzf-primary-text) !important;
}
.link-primary:hover,
.link-primary:focus {
    color: var(--pzf-primary-text-hover) !important;
}

.bg-warning {
    background-color: var(--pzf-warning) !important;
}
.text-warning {
    color: var(--pzf-warning-text) !important;
}
.border-warning {
    border-color: var(--pzf-warning) !important;
}
.text-success { color: var(--pzf-success) !important; }
.text-info    { color: var(--pzf-info) !important; }

/* Relleno naranja: el blanco encima da 2.96:1, va texto oscuro (5.81:1). */
.bg-warning,
.bg-warning * {
    color: var(--pzf-on-warning);
}
.btn-warning {
    background-color: var(--pzf-warning);
    border-color: var(--pzf-warning);
    color: var(--pzf-on-warning);
}
.btn-warning:hover,
.btn-warning:focus {
    background-color: var(--pzf-warning-text);
    border-color: var(--pzf-warning-text);
    color: var(--pzf-on-color);
}
.btn-outline-warning {
    color: var(--pzf-warning-text);
    border-color: var(--pzf-warning);
    background: transparent;
}
.btn-outline-warning:hover,
.btn-outline-warning:focus {
    background: var(--pzf-warning);
    color: var(--pzf-on-color);
}

/* Respeta usuarios que prefieren menos movimiento. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .pzf-skeleton::after { animation: none; }
}

/* ──────────────────────────────────────────────────────────────────────────
   Detalle de obra — navegación de pestañas en mobile
   Las ~16 pestañas envuelven en varias filas y se ven amontonadas. En mobile
   las convertimos en una sola fila horizontal scrolleable (swipe), con
   indicador inferior estilo "underline". (#obraTabs vive en obra_detalle.html)
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 767.98px) {
    #obraTabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;                 /* Firefox */
        border-bottom: 1px solid var(--pzf-border);
        gap: .15rem;
    }
    #obraTabs::-webkit-scrollbar { display: none; }   /* WebKit */
    #obraTabs .nav-item { flex: 0 0 auto; }
    #obraTabs .nav-link {
        white-space: nowrap;
        border: 0;
        border-bottom: 2px solid transparent;
        border-radius: 0;
        padding: .5rem .8rem;
        color: var(--pzf-text-muted);
        font-weight: 500;
    }
    #obraTabs .nav-link:hover { color: var(--pzf-primary-text); }
    #obraTabs .nav-link.active {
        color: var(--pzf-primary-text);
        background: transparent;
        border-bottom-color: var(--pzf-primary);
    }
}

/* ===========================================================================
   Carga rápida del home (F6)

   Todo con tokens `--pzf-*`, que ya cubren claro y oscuro: no hay un solo
   color literal acá. Ver docs/agro/07-carga-rapida-home.md.
   =========================================================================== */

.pzf-quick-bar {
    background: var(--pzf-surface);
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    padding: .85rem 1rem;
    box-shadow: var(--pzf-shadow);
}

.pzf-quick-bar-titulo {
    font-size: .78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--pzf-text-muted);
    margin-bottom: .6rem;
}

.pzf-quick-bar-acciones {
    display: grid;
    /* Los botones crecen hasta llenar la fila: en desktop entran los seis en
       una línea, en mobile caen a dos columnas sin que haya que tocar nada. */
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: .6rem;
}

.pzf-quick-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    padding: .85rem .5rem;
    border: 1px solid var(--pzf-border);
    border-radius: var(--pzf-radius);
    background: var(--pzf-surface-2);
    color: var(--pzf-text);
    font-size: .82rem;
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}

.pzf-quick-btn i {
    font-size: 1.45rem;
    line-height: 1;
}

.pzf-quick-btn:hover,
.pzf-quick-btn:focus-visible {
    color: var(--pzf-text);
    transform: translateY(-2px);
    box-shadow: var(--pzf-shadow);
}

/* El color del icono es lo único que distingue una acción de otra: el fondo
   queda neutro para que la barra no compita con los KPIs. */
.pzf-quick-primary i   { color: var(--pzf-primary-text); }
.pzf-quick-success i   { color: var(--pzf-success); }
.pzf-quick-warning i   { color: var(--pzf-warning-text, var(--pzf-warning)); }
.pzf-quick-info i      { color: var(--pzf-info); }
.pzf-quick-secondary i { color: var(--pzf-text-muted); }
.pzf-quick-danger i    { color: var(--pzf-danger); }

.pzf-quick-primary:hover   { border-color: var(--pzf-primary); }
.pzf-quick-success:hover   { border-color: var(--pzf-success); }
.pzf-quick-warning:hover   { border-color: var(--pzf-warning); }
.pzf-quick-info:hover      { border-color: var(--pzf-info); }
.pzf-quick-secondary:hover { border-color: var(--pzf-border-strong); }
.pzf-quick-danger:hover    { border-color: var(--pzf-danger); }

@media (prefers-reduced-motion: reduce) {
    .pzf-quick-btn { transition: none; }
    .pzf-quick-btn:hover { transform: none; }
}

/* ===========================================================================
   Ingesta por IA — marcado de lo que hay que revisar (F8)
   ---------------------------------------------------------------------------
   Un campo precargado por IA que el sistema no pudo resolver con certeza. El
   amarillo es señal de "mirá esto", no de error: el dato puede estar bien.
   Usa los tokens de warning, que ya están resueltos para claro y oscuro.
   =========================================================================== */
.pzf-ia-dudoso {
    background-color: rgba(var(--pzf-warning-rgb), .14);
    border-radius: var(--pzf-radius-sm, .375rem);
    box-shadow: inset 0 0 0 1px rgba(var(--pzf-warning-rgb), .45);
}

/* Dentro de una celda de tabla el fondo solo no se distingue del zebrado. */
td.pzf-ia-dudoso,
tr[data-lote-nuevo] td.pzf-ia-dudoso {
    box-shadow: inset 0 0 0 2px rgba(var(--pzf-warning-rgb), .5);
}

/* El marcado se saca al tocar el campo: si alguien ya lo revisó, dejarlo
   amarillo hace que el resto de las marcas pierdan sentido. */
.pzf-ia-dudoso:focus-within {
    background-color: transparent;
    box-shadow: none;
}

/* El pie del form de orden: el importe facturable es el número que la persona
   está tratando de obtener, así que acompaña el scroll en vez de quedar al
   final. La clase se usaba desde F3 pero nunca se había estilado — el total
   quedaba tres pantallas más abajo. */
.pzf-ot-footer {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: var(--pzf-surface);
    border-top: 1px solid var(--pzf-border);
    box-shadow: 0 -4px 12px rgba(0, 0, 0, .08);
    padding: .75rem 0;
    margin-top: 1rem;
}


/* ===========================================================================
   Carga de orden de trabajo en el celular (F9 — riesgo R5)
   ---------------------------------------------------------------------------
   La orden se carga en el campo, parado al lado de la máquina. Si eso no
   funciona en un teléfono, el modelo queda vacío y ningún reporte sirve.

   Los tres formsets son tablas de 4 a 8 columnas: en un celular obligan a un
   scroll horizontal por fila, que es la forma más segura de que alguien cargue
   las hectáreas en la columna del rinde. En mobile se apilan como fichas
   "etiqueta → campo", con el mismo criterio que `pzf-list-mobile.js` usa para
   los listados — pero acá sin JS, porque las filas las clona `ot_form.js` y un
   observer se perdería las nuevas.
   =========================================================================== */
@media (max-width: 767.98px) {
    .pzf-ot-form .pzf-table-wrap { overflow-x: visible; }

    .pzf-ot-form table.pzf-table thead,
    .pzf-ot-form table.pzf-table tfoot {
        display: none;
    }

    .pzf-ot-form table.pzf-table,
    .pzf-ot-form table.pzf-table tbody,
    .pzf-ot-form table.pzf-table tr,
    .pzf-ot-form table.pzf-table td {
        display: block;
        width: 100%;
    }

    .pzf-ot-form table.pzf-table tr.pzf-formset-row {
        border: 1px solid var(--pzf-border);
        border-radius: var(--pzf-radius);
        background: var(--pzf-surface);
        padding: .75rem;
        margin-bottom: .75rem;
    }

    .pzf-ot-form table.pzf-table td {
        border: 0;
        padding: .25rem 0;
    }

    .pzf-ot-form table.pzf-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: .72rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--pzf-text-muted);
        margin-bottom: .15rem;
    }

    /* Las reglas de toque salieron de acá a `.pzf-touch` (abajo), porque las
       necesita también el modal de carga rápida. El form de OT la hereda. */

    /* En mobile el pie ocupa el ancho completo y los botones se agrandan. */
    .pzf-ot-footer .btn { min-height: 2.75rem; }
}


/* ===========================================================================
   .pzf-touch — pantallas que se usan con el dedo
   ---------------------------------------------------------------------------
   Dos reglas, y la primera no es estética: **por debajo de 16px iOS hace zoom
   al enfocar un input**, y después la página queda corrida. En un modal a
   pantalla completa eso descoloca todo.

   La segunda es el objetivo de toque de 44px, que es lo que hace falta para
   acertarle con guantes o con las manos sucias.

   Nació scopeada al form de orden de trabajo (F9); la carga rápida mobile la
   necesita igual, así que se promovió a una clase propia.
   =========================================================================== */
@media (max-width: 767.98px) {
    .pzf-touch .form-control,
    .pzf-touch .form-select,
    .pzf-touch .ts-control,
    .pzf-ot-form .form-control,
    .pzf-ot-form .form-select,
    .pzf-ot-form .ts-control {
        font-size: 16px;
        min-height: 2.75rem;
    }

    .pzf-touch .btn,
    .pzf-ot-form .btn { min-height: 2.75rem; }

    .pzf-touch input[type="checkbox"],
    .pzf-ot-form input[type="checkbox"] {
        width: 1.35rem;
        height: 1.35rem;
    }
}


/* ===========================================================================
   Carga rápida: botón flotante y selector de tipo
   =========================================================================== */

/* El botón que hace que esto esté "desde el inicio" en toda pantalla.
   `env(safe-area-inset-bottom)` no es opcional: con `viewport-fit=cover` en el
   viewport (ya está en el `<head>`), sin él el botón queda debajo de la barra
   de gestos del iPhone y no se puede tocar. */
.pzf-fab {
    position: fixed;
    right: calc(1rem + env(safe-area-inset-right, 0px));
    bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    z-index: 1040;              /* debajo del modal (1055), encima del resto */
    width: 3.5rem;
    height: 3.5rem;
    border: 0;
    border-radius: 50%;
    background: var(--pzf-primary);
    color: var(--pzf-on-color);
    font-size: 1.5rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 6px 18px rgba(var(--pzf-primary-rgb), .45);
    transition: transform .15s ease, background-color .15s ease;
}

.pzf-fab:hover,
.pzf-fab:focus-visible {
    background: var(--pzf-primary-hover, var(--pzf-primary));
    transform: scale(1.06);
    color: var(--pzf-on-color);
}

.pzf-fab:active { transform: scale(.96); }

/* Con el modal abierto el botón sólo estorba. */
body.modal-open .pzf-fab { display: none; }

/* En escritorio el acceso vive en la navbar: un botón flotante taparía
   contenido y nadie lo buscaría ahí. */
@media (min-width: 768px) {
    .pzf-fab { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .pzf-fab { transition: none; }
    .pzf-fab:hover, .pzf-fab:focus-visible, .pzf-fab:active { transform: none; }
}

/* Los tiles del paso 1. Reusa `.pzf-quick-btn` y sus variantes de color, que
   ya están verificadas en tema claro y oscuro; acá sólo se define la grilla. */
.pzf-rapido-tiles,
.pzf-rapido-subtiles {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: .75rem;
}

.pzf-rapido-tiles .pzf-quick-btn,
.pzf-rapido-subtiles .pzf-quick-btn {
    position: relative;
    flex-direction: column;
    justify-content: center;
    text-align: center;
    gap: .4rem;
    min-height: 6rem;
    padding: 1rem .75rem;
}

.pzf-rapido-tiles .pzf-quick-btn i:first-child,
.pzf-rapido-subtiles .pzf-quick-btn i:first-child {
    font-size: 1.75rem;
}

/* La flecha que avisa que el tile despliega más opciones en vez de abrir. */
.pzf-rapido-tile-mas {
    position: absolute;
    top: .5rem;
    right: .5rem;
    font-size: .8rem;
    opacity: .5;
}

@media (min-width: 576px) {
    .pzf-rapido-tiles,
    .pzf-rapido-subtiles { grid-template-columns: repeat(3, 1fr); }
}


/* ===========================================================================
   Ayuda contextual: botón flotante y contenido del modal
   =========================================================================== */

/* Clase propia y no `.pzf-fab` por dos motivos: aquél se esconde en escritorio
   (su acceso vive en la navbar) y la ayuda tiene que estar en los dos lados, y
   además comparten esquina. El reparto queda así:

       escritorio   carga rápida oculta  ·  ayuda abajo a la derecha
       mobile       carga rápida abajo   ·  ayuda apilada encima

   `env(safe-area-inset-*)` no es opcional: el viewport usa `viewport-fit=cover`
   y sin él el botón queda debajo de la barra de gestos del iPhone. */
.pzf-fab-ayuda {
    position: fixed;
    right: calc(1rem + env(safe-area-inset-right, 0px));
    bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    z-index: 1040;              /* mismo escalón que .pzf-fab: bajo el modal (1055) */
    width: 3.5rem;
    height: 3.5rem;
    padding: 0;
    border: 1px solid var(--pzf-border);
    border-radius: 50%;
    /* Superficie neutra a propósito: el verde lleno es del botón de carga
       rápida, que es la acción primaria. La ayuda no compite con él. */
    background: var(--pzf-surface);
    color: var(--pzf-text-muted);
    font-size: 1.35rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--pzf-shadow);
    transition: transform .15s ease, background-color .15s ease, color .15s ease;
}

.pzf-fab-ayuda:hover,
.pzf-fab-ayuda:focus-visible {
    background: var(--pzf-primary);
    border-color: var(--pzf-primary);
    color: var(--pzf-on-color);
    transform: scale(1.06);
}

.pzf-fab-ayuda:focus-visible {
    outline: 2px solid var(--pzf-focus-ring);
    outline-offset: 2px;
}

.pzf-fab-ayuda:active { transform: scale(.96); }

/* Con un modal abierto el botón sólo estorba — mismo criterio que .pzf-fab. */
body.modal-open .pzf-fab-ayuda { display: none; }

@media (max-width: 767.98px) {
    /* Apilado sobre el FAB de carga rápida (1rem + 3.5rem de alto + aire). */
    .pzf-fab-ayuda {
        bottom: calc(5.5rem + env(safe-area-inset-bottom, 0px));
        width: 3rem;
        height: 3rem;
        font-size: 1.15rem;
    }

    /* Con dos botones apilados en la esquina, sin este colchón la última fila
       de la tabla y la paginación quedan tapadas al llegar al fondo. */
    .pzf-page-main { padding-bottom: 5rem; }
}

@media (prefers-reduced-motion: reduce) {
    .pzf-fab-ayuda { transition: none; }
    .pzf-fab-ayuda:hover,
    .pzf-fab-ayuda:focus-visible,
    .pzf-fab-ayuda:active { transform: none; }
}

/* ---------- Contenido del modal ---------- */
.pzf-ayuda-seccion {
    font-size: .8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--pzf-text-muted);
    margin-top: 1rem;
    margin-bottom: .5rem;
}

.pzf-ayuda-seccion:first-child { margin-top: 0; }

.pzf-ayuda-pasos { padding-left: 1.25rem; margin-bottom: 0; }
.pzf-ayuda-pasos li { margin-bottom: .5rem; }

.pzf-ayuda-tips { list-style: none; padding-left: 0; margin-bottom: 0; }

.pzf-ayuda-tips li {
    display: flex;
    gap: .5rem;
    align-items: baseline;
    margin-bottom: .5rem;
    color: var(--pzf-text-muted);
}

/* Dorado *como texto* va con el token de texto: `--pzf-gold` es relleno y
   sobre fondo claro no llega al contraste mínimo. */
.pzf-ayuda-tips .bi-lightbulb {
    color: var(--pzf-gold-text);
    flex-shrink: 0;
}
