/* Layout principal del portal del cliente y admin */

body.app {
    min-height: 100dvh;
    display: grid;
    grid-template-columns: 264px 1fr;
    grid-template-rows: 64px 1fr;
    grid-template-areas:
        "side topbar"
        "side main";
}

/* — Sidebar — */
.sidebar {
    grid-area: side;
    background: var(--color-surface);
    border-right: 1px solid var(--color-border);
    padding: var(--sp-5) var(--sp-3);
    display: flex; flex-direction: column;
    overflow-y: auto;
}
.sidebar .brand { padding: 6px var(--sp-3) var(--sp-6); }

.sidebar .group { margin-top: var(--sp-5); }
.sidebar .group .label-up { padding: 0 var(--sp-3) var(--sp-2); }

.sidebar a.nav {
    display: flex; align-items: center; gap: var(--sp-3);
    padding: 9px var(--sp-3);
    border-radius: var(--r-md);
    color: var(--color-text-muted);
    font-weight: 500;
    font-size: var(--fs-14);
    transition: background var(--t-fast), color var(--t-fast);
}
.sidebar a.nav .ic { color: var(--color-text-faint); width: 18px; height: 18px; }
.sidebar a.nav .count {
    margin-left: auto;
    background: var(--color-surface-2);
    color: var(--color-text-soft);
    border-radius: var(--r-pill);
    font-size: var(--fs-12);
    padding: 1px 8px;
    font-weight: 600;
}
.sidebar a.nav:hover { background: var(--color-surface-2); color: var(--color-text); }
.sidebar a.nav.active {
    background: var(--color-orbit-soft);
    color: var(--color-orbit-strong);
}
.sidebar a.nav.active .ic { color: var(--color-orbit); }

.tier-card {
    margin-top: auto;
    padding: var(--sp-4);
    border: 1px solid var(--color-border);
    border-radius: var(--r-md);
    background: var(--color-surface-2);
}
.tier-card .row { gap: var(--sp-2); margin-bottom: var(--sp-2); }
.tier-card p { font-size: var(--fs-13); color: var(--color-text-soft); margin: 0; }

/* — Topbar — */
.topbar {
    grid-area: topbar;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    padding: 0 var(--sp-6);
    display: flex; align-items: center; gap: var(--sp-4);
}
.topbar .search {
    flex: 1; max-width: 420px;
    position: relative;
}
.topbar .search .input {
    background: var(--color-surface-2);
    border-color: transparent;
    padding-left: 38px;
}
.topbar .search .kbd {
    position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
    font-family: var(--font-mono); font-size: var(--fs-12); color: var(--color-text-faint);
    border: 1px solid var(--color-border); padding: 1px 6px; border-radius: 4px;
    background: var(--color-surface);
}
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: var(--sp-3); }
.topbar .me {
    display: flex; align-items: center; gap: var(--sp-3);
    padding: 4px 8px 4px 4px; border-radius: var(--r-pill);
    cursor: pointer;
}
.topbar .me:hover { background: var(--color-surface-2); }
.topbar .me .avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--color-orbit-soft); color: var(--color-orbit-strong);
    display: grid; place-items: center; font-weight: 700; font-size: var(--fs-13);
}
.topbar .me .who { line-height: 1.1; }
.topbar .me .who .name { font-size: var(--fs-13); font-weight: 600; }
.topbar .me .who .org  { font-size: var(--fs-12); color: var(--color-text-soft); }

/* — Main — */
.main {
    grid-area: main;
    padding: var(--sp-7) var(--sp-7) var(--sp-9);
    overflow-y: auto;
}
.main > .container { max-width: 1200px; margin: 0 auto; }

.page-head { margin-bottom: var(--sp-6); }
.page-head .label-up { margin-bottom: var(--sp-2); }
.page-head h1 { font-size: var(--fs-30); }
.page-head p { color: var(--color-text-muted); margin-top: 6px; }

/* ============================================================
   Hero asimétrico — dashboard cliente.
   Layout split 60/40 desktop, stack mobile. Sigue regla
   "ANTI-CENTER BIAS" del skill (LAYOUT_VARIANCE > 4).
   ============================================================ */
.hero-asym {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(280px, 1fr);
    gap: clamp(var(--sp-6), 4vw, var(--sp-9));
    align-items: end;
    padding: var(--sp-7) 0 var(--sp-9);
    margin-bottom: var(--sp-7);
    border-bottom: 1px solid var(--color-border);
    position: relative;
}
.hero-asym::before {
    /* Halo sutil — no neon, tono de marca difuminado */
    content: '';
    position: absolute;
    top: 0; right: 0;
    width: 320px; height: 220px;
    background: radial-gradient(circle at 70% 0%, var(--color-orbit-soft) 0%, transparent 65%);
    pointer-events: none;
    z-index: -1;
}
.hero-text { display: flex; flex-direction: column; gap: var(--sp-3); }
.hero-text .label-up { margin: 0; }
.hero-text h1 {
    margin: 0;
    /* clamp en base.css ya escala. Aquí solo refuerzo line-height tighter para hero. */
    line-height: 1;
    letter-spacing: -0.03em;
}
.hero-name {
    background: linear-gradient(120deg, var(--color-text) 0%, var(--color-orbit-strong) 100%);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}
.hero-lead {
    margin: 0;
    color: var(--color-text-muted);
    font-size: clamp(var(--fs-15), 1.4vw, var(--fs-18));
    max-width: 52ch;
    line-height: 1.5;
}
.hero-accent { color: var(--color-orbit-strong); font-weight: 700; }

.hero-stats {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sp-2);
    padding: var(--sp-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-xs);
}
.hero-stat {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: var(--sp-2) 0;
}
.hero-stat-divider {
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    padding: var(--sp-3) 0;
}
.hero-stat-label {
    font-size: var(--fs-12);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-soft);
    font-weight: 600;
}
.hero-stat-value {
    font-family: var(--font-display);
    font-size: var(--fs-30);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
}
.hero-stat-pulse {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--color-success);
    box-shadow: 0 0 0 0 rgba(34, 197, 94, .55);
    animation: pulseDot 2.4s var(--ease-out-soft) infinite;
}
.hero-stat-tier {
    font-family: var(--font-display);
    font-size: var(--fs-15);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 4px 12px;
    border-radius: var(--r-pill);
}
.hero-stat-tier.tier-bronze   { background: var(--tier-bronze-bg);   color: var(--tier-bronze-fg); }
.hero-stat-tier.tier-silver   { background: var(--tier-silver-bg);   color: var(--tier-silver-fg); }
.hero-stat-tier.tier-gold     { background: var(--tier-gold-bg);     color: var(--tier-gold-fg); }
.hero-stat-tier.tier-platinum { background: var(--tier-platinum-bg); color: var(--tier-platinum-fg); }

@media (max-width: 880px) {
    .hero-asym {
        grid-template-columns: 1fr;
        gap: var(--sp-6);
        padding: var(--sp-6) 0;
    }
    .hero-asym::before { display: none; }
}

/* — Tarjetas de categoría (dashboard A) — */
.cat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: var(--sp-4);
}
.cat-tile {
    display: flex; flex-direction: column; gap: var(--sp-3);
    padding: var(--sp-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    color: var(--color-text);
    transition: transform var(--t-fast), box-shadow var(--t-fast), border-color var(--t-fast);
    /* Stagger reveal: cada tile entra con un delay calculado por su posición.
       --i lo setea inline cada item en el EJS. */
    animation: tileEnter 540ms var(--ease-out-soft) both;
    animation-delay: calc(var(--i, 0) * 60ms);
}
.cat-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: var(--color-border-strong); }

/* Bento light — la primera tile ocupa 2 columnas en desktop,
   creando jerarquía visual sin abandonar la simetría operativa. */
@media (min-width: 980px) {
    .cat-grid { grid-template-columns: repeat(4, 1fr); }
    .cat-grid .cat-tile:first-child {
        grid-column: span 2;
        background: linear-gradient(135deg, var(--color-orbit-soft) 0%, var(--color-surface) 60%);
        border-color: var(--color-orbit-tint);
    }
    .cat-grid .cat-tile:first-child .ic-wrap { width: 56px; height: 56px; }
    .cat-grid .cat-tile:first-child .name { font-size: var(--fs-18); }
}

@keyframes tileEnter {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .cat-tile { animation: none; }
}
.cat-tile .ic-wrap {
    width: 44px; height: 44px; border-radius: var(--r-md);
    display: grid; place-items: center;
    background: var(--color-orbit-soft); color: var(--color-orbit);
}
.cat-tile .ic-wrap.alt-1 { background: #ede9fe; color: #6b3df0; }
.cat-tile .ic-wrap.alt-2 { background: #fef3c7; color: #b45309; }
.cat-tile .ic-wrap.alt-3 { background: #dcfce7; color: #15803d; }
.cat-tile .ic-wrap.alt-4 { background: #fde2e7; color: #be185d; }
.cat-tile .name { font-weight: 600; font-size: var(--fs-15); }
.cat-tile .count { color: var(--color-text-soft); font-size: var(--fs-13); }

/* — Featured (dashboard A) — */
.featured-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--sp-4);
}
.featured-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    overflow: hidden;
    display: flex; flex-direction: column;
    transition: transform var(--t-fast), box-shadow var(--t-fast);
    color: inherit;
    animation: tileEnter 540ms var(--ease-out-soft) both;
    animation-delay: calc(var(--i, 0) * 80ms + 200ms);
}
.featured-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }

/* Activity rows con stagger reveal */
.activity-row {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--color-border);
    animation: tileEnter 420ms var(--ease-out-soft) both;
    animation-delay: calc(var(--i, 0) * 50ms + 300ms);
}
.activity-row:last-child { border-bottom: 0; }
@media (prefers-reduced-motion: reduce) {
    .featured-card, .activity-row { animation: none; }
}
.featured-card .cover {
    aspect-ratio: 16 / 10;
    background:
      repeating-linear-gradient(135deg, #f1f5f9, #f1f5f9 8px, #f8fafc 8px, #f8fafc 16px);
    display: grid; place-items: center;
    color: var(--color-text-faint);
    font-size: var(--fs-13);
}
.featured-card .body { padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-2); }
.featured-card .meta { font-size: var(--fs-12); color: var(--color-text-soft); }

/* — Lista densa (dashboard B) — */
.section-head {
    display: flex; align-items: center; gap: var(--sp-2);
    margin: var(--sp-7) 0 var(--sp-3);
}
.section-head h2 { font-size: var(--fs-16); font-weight: 700; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.section-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-orbit); }

.row-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.row-item {
    display: flex; align-items: center; gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-md);
    transition: border-color var(--t-fast), box-shadow var(--t-fast);
    color: inherit;
}
.row-item:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-xs); }
.row-item .icon-tile {
    width: 36px; height: 36px; border-radius: var(--r-md);
    background: var(--color-orbit-soft); color: var(--color-orbit);
    display: grid; place-items: center; flex: 0 0 auto;
}
.row-item .ti { flex: 1; min-width: 0; }
.row-item .ti .title { font-weight: 600; font-size: var(--fs-14); }
.row-item .ti .meta  { font-size: var(--fs-12); color: var(--color-text-soft); }
.row-item .ti .title .badge { margin-left: var(--sp-2); }

/* — KPI cards — */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--sp-4); }
.kpi {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    padding: var(--sp-5);
}
.kpi .label-up { margin-bottom: var(--sp-2); }
.kpi .value {
    font-family: var(--font-display);
    font-size: var(--fs-30);
    font-weight: 700;
    letter-spacing: -0.02em;
}
.kpi .delta {
    margin-left: var(--sp-2); font-size: var(--fs-12); font-weight: 600;
    padding: 2px 8px; border-radius: var(--r-pill);
    background: var(--color-success-soft); color: #166534;
}
.kpi .delta.down { background: var(--color-danger-soft); color: #991b1b; }

/* — Filter pills — */
.pill-group { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.pill {
    padding: 6px 14px;
    border-radius: var(--r-pill);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    font-size: var(--fs-13); font-weight: 600;
    color: var(--color-text-muted); cursor: pointer;
    text-decoration: none;
    transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast), transform var(--t-fast);
}
.pill:hover { border-color: var(--color-border-strong); }
.pill.active {
    background: var(--color-orbit-soft); color: var(--color-orbit-strong);
    border-color: var(--color-orbit-tint);
}

/* — FAB Harby — */
.fab {
    position: fixed; right: var(--sp-7); bottom: var(--sp-7);
    width: 56px; height: 56px;
    border-radius: 50%;
    background: var(--color-nebula);
    color: var(--color-text-inverse);
    display: grid; place-items: center;
    box-shadow: var(--shadow-md);
    cursor: pointer;
    transition: transform var(--t-fast);
}
.fab:hover { transform: scale(1.05); }
.fab:active { transform: scale(0.96); transition-duration: 80ms; }
.fab::after {
    content: ''; position: absolute; top: 4px; right: 4px;
    width: 10px; height: 10px; border-radius: 50%;
    background: var(--color-success); border: 2px solid var(--color-nebula);
    box-shadow: 0 0 0 0 rgba(34, 197, 94, .55);
    animation: pulseDot 2.4s var(--ease-out-soft) infinite;
}

/* Pulso continuo en status dots — micro-interacción "alive" del skill */
@keyframes pulseDot {
    0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, .55); }
    50%      { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
}

/* — Tactile feedback uniforme (skill design-taste-frontend) —
   Cada superficie clickeable se "hunde" 1px o se escala 0.98 al :active.
   Con la curva ease-out-soft se siente físico, no robótico. */
.pill:active,
.cat-tile:active,
.featured-card:active,
.row-item:active,
.cert-row:active {
    transform: translateY(1px) scale(0.995);
    transition-duration: 80ms;
}

/* — Tablas — */
table.table {
    width: 100%; border-collapse: separate; border-spacing: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    overflow: hidden;
    font-size: var(--fs-14);
}
table.table th, table.table td { padding: 12px var(--sp-4); text-align: left; vertical-align: middle; }
table.table thead th {
    background: var(--color-surface-2);
    font-weight: 600; color: var(--color-text-soft);
    text-transform: uppercase; letter-spacing: 0.05em; font-size: var(--fs-12);
    border-bottom: 1px solid var(--color-border);
}
table.table tbody tr { border-top: 1px solid var(--color-border); }
table.table tbody tr:first-child { border-top: 0; }
table.table tbody tr:hover { background: var(--color-surface-2); }
table.table .row-avatar {
    display: inline-flex; align-items: center; gap: var(--sp-2);
}
table.table .av {
    width: 28px; height: 28px; border-radius: 50%;
    background: var(--color-orbit-soft); color: var(--color-orbit-strong);
    display: grid; place-items: center; font-weight: 700; font-size: var(--fs-12);
}
table.table .actions { text-align: right; }

/* — Sidebar/main — modo Admin con chrome morado — */
body.admin .topbar {
    background: linear-gradient(135deg, #3d1d8a 0%, var(--color-titan) 100%);
    color: var(--color-text-inverse);
    border-bottom: 0;
    padding-left: var(--sp-7);
}
body.admin .topbar .crumbs { font-weight: 600; font-size: var(--fs-14); }
body.admin .topbar .crumbs span.sep { color: rgba(255,255,255,.4); margin: 0 8px; }
body.admin .topbar .crumbs strong { color: #ffffff; }
body.admin .topbar .me .avatar { background: rgba(255,255,255,.18); color: #ffffff; }
body.admin .topbar .me .who .name, body.admin .topbar .me .who .org { color: rgba(255,255,255,.85); }

body.admin .sidebar {
    background: #1c1235;
    border-right-color: rgba(255,255,255,.08);
}
body.admin .sidebar a.nav { color: rgba(255,255,255,.7); }
body.admin .sidebar a.nav .ic { color: rgba(255,255,255,.45); }
body.admin .sidebar a.nav:hover { background: rgba(255,255,255,.06); color: #ffffff; }
body.admin .sidebar a.nav.active { background: var(--color-titan); color: #ffffff; }
body.admin .sidebar a.nav.active .ic { color: #ffffff; }
body.admin .sidebar .brand .one { color: #b69eff; }
body.admin .sidebar .brand .client { color: rgba(255,255,255,.7); }

/* — Hamburguesa: oculta en desktop — */
.menu-toggle {
    display: none;
    background: transparent; border: 0; padding: 8px;
    border-radius: var(--r-md); cursor: pointer;
    color: var(--color-text); margin-right: var(--sp-2);
}
.menu-toggle:hover { background: var(--color-surface-2); }
body.admin .menu-toggle { color: rgba(255,255,255,.85); }
body.admin .menu-toggle:hover { background: rgba(255,255,255,.08); }

/* Backdrop del drawer móvil */
.sidebar-backdrop {
    display: none;
    position: fixed; inset: 0;
    background: rgba(15, 29, 61, .55);
    z-index: 90;
    backdrop-filter: blur(2px);
}

/* — Tablet / desktop angosto: sidebar pasa a drawer + layouts apilados — */
@media (max-width: 1024px) {
    body.app {
        grid-template-columns: 1fr;
        grid-template-rows: 64px 1fr;
        grid-template-areas: "topbar" "main";
    }
    .sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        width: 280px; max-width: 86vw;
        z-index: 100;
        transform: translateX(-100%);
        transition: transform .22s ease;
        box-shadow: 0 0 24px rgba(15,29,61,.18);
    }
    body.sidebar-open .sidebar { transform: translateX(0); }
    body.sidebar-open .sidebar-backdrop { display: block; }
    .menu-toggle { display: inline-flex; align-items: center; justify-content: center; }

    /* Inline grids `1fr 1fr` / `repeat(3, 1fr)` (user-detail, settings) — stack. */
    .main [style*="grid-template-columns: 1fr 1fr"],
    .main [style*="grid-template-columns:1fr 1fr"] {
        grid-template-columns: 1fr !important;
    }
    .main [style*="grid-template-columns: repeat(3, 1fr)"],
    .main [style*="grid-template-columns:repeat(3, 1fr)"],
    .main [style*="grid-template-columns:repeat(3,1fr)"] {
        grid-template-columns: 1fr 1fr !important;
    }

    /* Botones en .row no overflowean — envuelven. */
    .main .row { flex-wrap: wrap; }

    /* Tablas con scroll horizontal nativo, manteniendo layout de tabla por dentro. */
    table.table {
        display: block;
        overflow-x: auto;
        max-width: 100%;
        -webkit-overflow-scrolling: touch;
    }
    table.table > thead, table.table > tbody { display: table; min-width: 100%; }
    table.table > thead > tr, table.table > tbody > tr { display: table-row; }
    table.table > thead > tr > th,
    table.table > tbody > tr > td {
        display: table-cell;
        white-space: nowrap;
    }
}

/* — Layout grid 1.6fr / 1fr usado en dashboard y otros — */
.dash-split {
    display: grid;
    grid-template-columns: 1.6fr 1fr;
    gap: var(--sp-6);
}
.dash-split-narrow { grid-template-columns: 320px 1fr; gap: var(--sp-7); }
@media (max-width: 900px) {
    .dash-split,
    .dash-split-narrow { grid-template-columns: 1fr; gap: var(--sp-5); }
}

/* — Móvil ajustado: padding más compacto y tipografía más razonable — */
@media (max-width: 720px) {
    .topbar { padding: 0 var(--sp-3); gap: var(--sp-2); }
    body.admin .topbar { padding-left: var(--sp-3); }
    body.admin .topbar .crumbs {
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        flex: 1; min-width: 0; font-size: var(--fs-13);
    }
    .topbar .right { gap: var(--sp-2); }
    .topbar .me .who { display: none; }
    .topbar .search { max-width: none; }
    .main { padding: var(--sp-5) var(--sp-4) var(--sp-7); }
    .page-head h1 { font-size: var(--fs-24); }
    .featured-grid { grid-template-columns: 1fr; }
    .cat-grid { grid-template-columns: repeat(2, 1fr); gap: var(--sp-3); }

    /* Tablas (scroll horizontal ya activo desde 1024px); apretar padding. */
    table.table > thead > tr > th,
    table.table > tbody > tr > td { padding: 10px var(--sp-3); }

    /* Cards y grids dentro de cards: no encajonar tan apretado. */
    .card { padding: var(--sp-4); }
}

/* ── Certificados de distribuidor ────────────────────────────────────── */
.cert-list { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
.cert-row {
    display: flex; align-items: flex-start; gap: var(--sp-3);
    padding: var(--sp-3); border: 1px solid var(--color-border);
    border-radius: var(--r-md); background: #fff;
}
.cert-row .badge.dot.success { background: var(--color-success-soft); color: #166534; border: 1px solid rgba(34,197,94,.3); }
.cert-row .badge.dot.warn    { background: var(--color-warn-soft);    color: #92400e; border: 1px solid rgba(245,158,11,.3); }
.cert-row .badge.dot.danger  { background: var(--color-danger-soft);  color: #991b1b; border: 1px solid rgba(239,68,68,.3); }

/* ── Modal genérico ──────────────────────────────────────────────────── */
.modal-backdrop {
    position: fixed; inset: 0; z-index: 9000;
    background: rgba(15, 29, 61, .55);
    display: flex; align-items: center; justify-content: center;
    padding: var(--sp-4);
    backdrop-filter: blur(2px);
    animation: modalFadeIn .15s ease-out;
}
.modal-backdrop[hidden] { display: none; }
.modal-card {
    background: var(--color-surface);
    border-radius: var(--r-lg, 14px);
    box-shadow: 0 20px 60px rgba(15, 29, 61, .35);
    width: 100%; max-width: 620px;
    max-height: calc(100dvh - 64px);
    overflow-y: auto;
    animation: modalSlideIn .2s ease-out;
}
.modal-head {
    display: flex; justify-content: space-between; align-items: flex-start;
    gap: var(--sp-4);
    padding: var(--sp-5) var(--sp-5) var(--sp-3);
    border-bottom: 1px solid var(--color-border);
}
.modal-head h3 { margin: 0; font-size: var(--fs-18, 1.125rem); font-weight: 600; color: var(--color-text); }
.modal-close {
    background: transparent; border: 0; cursor: pointer;
    width: 32px; height: 32px; border-radius: 8px;
    font-size: 22px; line-height: 1; color: var(--color-text-soft);
    display: grid; place-items: center;
}
.modal-close:hover { background: var(--color-surface-2); color: var(--color-text); }
.modal-actions {
    display: flex; justify-content: flex-end; gap: var(--sp-2);
    padding: var(--sp-4) var(--sp-5) var(--sp-5);
    border-top: 1px solid var(--color-border);
    background: var(--color-surface-2);
    border-radius: 0 0 var(--r-lg, 14px) var(--r-lg, 14px);
}

/* Form dentro del modal de certificado */
.cert-modal-form { padding: var(--sp-5); }
.cert-modal-form .form-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4);
}
.cert-modal-form .field { display: flex; flex-direction: column; gap: 6px; }
.cert-modal-form .field.full { grid-column: 1 / -1; }
.cert-modal-form .label-up {
    font-size: var(--fs-12); font-weight: 600;
    color: var(--color-text-soft); text-transform: uppercase;
    letter-spacing: .04em;
}
.cert-modal-form input[type=text],
.cert-modal-form input[type=date],
.cert-modal-form input:not([type]),
.cert-modal-form textarea {
    width: 100%; padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--r-sm, 8px);
    background: #fff; font: inherit; color: var(--color-text);
    transition: border-color .15s, box-shadow .15s;
}
.cert-modal-form input:focus,
.cert-modal-form textarea:focus {
    outline: 0;
    border-color: var(--color-orbit);
    box-shadow: 0 0 0 3px var(--color-orbit-tint);
}
.cert-modal-form textarea { resize: vertical; min-height: 64px; }

.cert-modal-form .file-field input[type=file] {
    padding: 10px 12px;
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--r-sm, 8px);
    background: var(--color-surface-2);
    cursor: pointer;
}
.cert-modal-form .file-field input[type=file]:hover {
    border-color: var(--color-orbit);
    background: var(--color-orbit-soft);
}
.cert-modal-form .file-hint {
    font-size: var(--fs-12); color: var(--color-text-faint);
    margin-top: 2px;
}

@keyframes modalFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalSlideIn {
    from { opacity: 0; transform: translateY(8px) scale(.98); }
    to   { opacity: 1; transform: translateY(0)   scale(1); }
}

@media (max-width: 600px) {
    .cert-modal-form .form-grid { grid-template-columns: 1fr; }
    .modal-card { max-height: 100dvh; border-radius: 0; }
}

/* ============================================================
   Empty states — mandatorios según design-taste-frontend skill.
   No mostrar tabla / lista vacía sin guiar al usuario.
   ============================================================ */
.empty-state {
    display: grid;
    place-items: center;
    text-align: center;
    padding: clamp(var(--sp-7), 6vw, var(--sp-10)) var(--sp-6);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--r-lg);
    background:
        radial-gradient(circle at 50% 0%, var(--color-orbit-soft) 0%, transparent 55%),
        var(--color-surface);
    color: var(--color-text-muted);
}
.empty-state .empty-icon {
    width: 56px; height: 56px;
    border-radius: 50%;
    display: grid; place-items: center;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-orbit);
    margin-bottom: var(--sp-4);
    box-shadow: var(--shadow-xs);
}
.empty-state h3 {
    font-family: var(--font-display);
    font-size: var(--fs-18);
    color: var(--color-text);
    margin: 0 0 var(--sp-2);
    letter-spacing: -0.01em;
}
.empty-state p {
    max-width: 52ch;
    margin: 0 0 var(--sp-5);
    color: var(--color-text-soft);
    font-size: var(--fs-14);
    line-height: 1.55;
}
.empty-state .empty-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; justify-content: center; }

/* Variante in-table: cuando es un colspan="N" dentro de tbody, queremos
   borrarle el border-radius y los borders de la celda y dejar respirar */
.empty-state.in-table {
    border: none;
    background: transparent;
    border-radius: 0;
    padding: var(--sp-9) var(--sp-4);
}

/* ============================================================
   Skeleton loader — placeholders con shimmer suave.
   Úsalo en <span class="skel skel-line"></span> mientras carga.
   ============================================================ */
.skel {
    display: inline-block;
    background: linear-gradient(
        90deg,
        var(--color-surface-2) 0%,
        var(--color-border) 40%,
        var(--color-surface-2) 80%
    );
    background-size: 200% 100%;
    animation: skelShimmer 1.6s var(--ease-out-soft) infinite;
    border-radius: var(--r-sm);
    color: transparent;
    user-select: none;
}
.skel-line   { width: 100%; height: 12px; }
.skel-title  { width: 60%;  height: 18px; }
.skel-block  { width: 100%; height: 80px; border-radius: var(--r-md); display: block; }
.skel-circle { width: 36px; height: 36px; border-radius: 50%; }
@keyframes skelShimmer {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
    .skel { animation: none; opacity: 0.7; }
    .fab::after { animation: none; }
}
