﻿/* ============================================================
   Archivo  : trianon-brand.css
   Ruta     : Web.Principal/wwwroot/css/
   Modulo   : Branding / Layout
   Fase     : 8 - Views (capa de marca)
   Version  : V1.0 - 2026-08-20
   Sistema  : Hana_Trianon_Satelital
   ------------------------------------------------------------
   Capa de MARCA sobre Inspinia v5. Se carga DESPUES de
   app.min.css y solo redefine variables CSS del tema, por lo
   que NO requiere recompilar el SCSS con gulp/bun.
   El prefijo de variables del tema en esta build es --theme-.
   ============================================================ */

/* ── 1 · Tokens de marca Grupo Trianon ───────────────────── */
:root {
    --ts-navy-900: #0B2545;
    --ts-navy-800: #0E3160;
    --ts-navy-700: #123C71;
    --ts-navy:     #164A8A;
    --ts-blue-300: #4A7FC1;
    --ts-gold:     #E0AD0A;
    --ts-gold-300: #F5C542;
    --ts-ink:      #17202E;
    /* Rojo oficial de marca: unico rojo de toda la app (CTAs, indicador
       activo de menu, estados de peligro). No crear otro rojo aparte. */
    --brand:       #E4002B;
    --brand-tint:  #FBE1E6;
}

/* ── 2 · El logo del sistema respira mejor a 32px ─────────── */
:root {
    --theme-logo-lg-height: 32px;
    --theme-logo-sm-height: 30px;
}

/* ── 3 · Skin "gradient" recoloreado a la paleta Trianon ──── */
/*    Sidenav: navy profundo -> azul corporativo               */
html[data-menu-color='gradient'] {
    --theme-sidenav-bg:                 linear-gradient(160deg, #071A45 0%, #012462 58%, #023FA7 100%);
    --theme-sidenav-border-color:       transparent;
    --theme-sidenav-item-color:         #DCE8FF;
    --theme-sidenav-item-hover-color:   #FFFFFF;
    --theme-sidenav-item-hover-bg:      rgba(255, 255, 255, .10);
    --theme-sidenav-item-active-color:  #FFFFFF;
    --theme-sidenav-item-active-bg:     rgba(255, 255, 255, .14);
}

/*    Topbar: MISMA rampa de color que el sidenav (071A45 -> 012462 -> 023FA7),
      solo que horizontal en vez de diagonal, para que topbar y sidenav se
      lean como una sola superficie, no dos azules distintos que chocan
      en la esquina superior izquierda. Antes el topbar arrancaba en un
      celeste mas claro y en orden invertido: por eso se notaba "parchado".
      [TRIANON-BRAND 2026-09-21] unificado con el sidenav, pedido de UX. */
html[data-topbar-color='gradient'] {
    --theme-topbar-bg:                  linear-gradient(90deg, #071A45 0%, #012462 45%, #023FA7 100%);
    --theme-topbar-item-color:          #DCE8FF;
    --theme-topbar-item-hover-color:    #FFFFFF;
    --theme-topbar-search-bg:           rgba(255, 255, 255, .12);
    --theme-topbar-search-border:       rgba(255, 255, 255, .18);
}

/*    Filo dorado en el item activo del menu (el tema solo pinta
      el activo de primer nivel: .side-nav > .side-nav-item.active > a) */
html[data-menu-color='gradient'] .side-nav > .side-nav-item.active > a {
    box-shadow: inset 3px 0 0 0 var(--brand);
}

/*    El tema NO estiliza el enlace activo de segundo nivel, aunque
      el JS del sidebar le pone .active. Se marca en dorado.        */
html[data-menu-color='gradient'] .side-nav .collapse a.side-nav-link.active {
    color: #FFFFFF !important;
    font-weight: 600;
}

/*    Titulos de seccion del menu, en dorado tenue             */
html[data-menu-color='gradient'] .side-nav-title {
    color: rgba(220, 232, 255, .60);
    letter-spacing: .06em;
}

/* ── 4 · Bug del tema: con topbar "gradient" el logo que se
      mostraba era el oscuro (texto navy sobre fondo navy).    */
html[data-topbar-color='gradient'] .logo-topbar .logo-light { display: block; }
html[data-topbar-color='gradient'] .logo-topbar .logo-dark  { display: none;  }

/* ── 5 · Bloque de usuario del sidenav sobre el gradiente ─── */
/* Solo el bloque de datos del usuario (nombre/DNI/correo/empresa),
   nunca los items del dropdown (ej. 'Salir del Sistema') que tambien
   viven dentro de .sidenav-user y quedaban pintados invisibles. */
html[data-menu-color='gradient'] .sidenav-user span.fs-12:not(.ts-avatar) {
    color: rgba(255, 255, 255, .66);
}

html[data-menu-color='gradient'] .sidenav-user .sidenav-user-name {
    color: #FFFFFF;
}

html[data-menu-color='gradient'] .sidenav-user hr {
    border-color: rgba(255, 255, 255, .12);
}

/* ── 6 · Avatar de iniciales (0 requests, 0 imagenes) ─────── */
.ts-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--ts-gold-300) 0%, var(--ts-gold) 100%);
    color: var(--ts-navy-900);
    font-weight: 700;
    font-size: .82rem;
    line-height: 1;
    letter-spacing: .02em;
    text-transform: uppercase;
    text-decoration: none;
    user-select: none;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .20), 0 2px 6px rgba(11, 37, 69, .25);
}

.ts-avatar:hover { color: var(--ts-navy-900); }

/* Tamanos por contexto: no hace falta pasar parametros        */
.sidenav-user .ts-avatar { width: 46px; height: 46px; font-size: .95rem; }
.nav-user     .ts-avatar { width: 34px; height: 34px; font-size: .74rem; margin-inline-end: .5rem; }

/* Sobre fondo claro el anillo blanco no se ve: usa navy       */
html[data-topbar-color='light'] .nav-user .ts-avatar,
html[data-topbar-color='gray']  .nav-user .ts-avatar {
    box-shadow: 0 0 0 2px rgba(11, 37, 69, .12), 0 2px 6px rgba(11, 37, 69, .18);
}

/* ── 7 · Marca en el pie ─────────────────────────────────── */
.footer .ts-foot-brand { color: var(--ts-navy); font-weight: 600; }

/* ── 8 · Campos de solo lectura que SE VEAN de solo lectura ─
      Dos problemas encadenados, los dos medidos en esta build:

      (a) Bootstrap 5 saco [readonly] de la regla de :disabled, asi que un
          input readonly queda con fondo blanco, identico a uno editable.
          El usuario intenta escribir y no entiende por que no pasa nada.

      (b) La utilidad .bg-body-secondary NO sirve para grisarlo aqui: en
          esta build compila a rgba(var(--theme-secondary-bg-rgb),...) y
          --theme-secondary-bg vale #fff, o sea BLANCO. Y como las
          utilidades llevan !important, ponerla no solo no gris el campo:
          ademas BLOQUEA cualquier regla propia que intente pintarlo.

      Por eso los colores van LITERALES y sin utilidades de fondo.
      Caso concreto: "Moneda Local" en Empresas SAP, que la sincroniza SAP
      desde OADM.MainCurncy y el portal no debe poder tocar.               */
.form-control[readonly]:not(.form-control-plaintext),
.form-select[readonly]:not(.form-control-plaintext) {
    background-color: #EDF1F6;
    color: #55637A;
    cursor: default;
}

.form-control[readonly]:not(.form-control-plaintext):focus {
    background-color: #EDF1F6;
    border-color: #CBD4E0;
    box-shadow: none;
}

/* El addon del input-group acompaña el estado */
.input-group:has(> .form-control[readonly]:not(.form-control-plaintext)) > .input-group-text {
    background-color: #E3E9F1;
    color: #55637A;
}


/* ── 9 · Pantallas de autenticacion (_LayoutAuth.cshtml) ──────────────
   Unico lugar donde vive el CSS de Login/Registro/Recuperar/Restablecer/
   SegundoFactor/Configurar2FA/Consentimiento. Antes cada vista cargaba su
   propio .css (etrianon.css, etrianon-firma.css, registro-legal.css, etc.)
   y esos archivos se perdieron con el reemplazo del wwwroot v5. Se decidio
   NO recrearlos por separado: todo el bloque de auth entra aqui, en el
   maestro, para que exista una sola hoja que mantener. Ver Views/Account/*
   y Views/Shared/_LayoutAuth.cshtml para las clases que consume.
   ==================================================================== */

:root {
    --muted:       #6B7785;
    --ok:          #17803D;
    --ok-tint:     #E4F5EA;
    --font-display: inherit;
}

/* ── 9.1 · Layout partido: hero navy + panel de formulario ── */
.et-auth {
    display: flex;
    min-height: 100vh;
    background: #F4F6F9;
}

.et-auth-hero {
    flex: 0 0 42%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 24px;
    padding: 48px 56px;
    color: #FFFFFF;
    background: linear-gradient(155deg, var(--ts-navy-900) 0%, var(--ts-navy-700) 55%, var(--ts-navy) 100%);
}

.et-brand { display: flex; align-items: center; gap: 14px; }
.et-brand img { display: block; }

.et-eyebrow {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .68);
}

.et-auth-hero h1 {
    font-size: 34px;
    font-weight: 800;
    line-height: 1.18;
    margin: 0;
    max-width: 460px;
}

.et-auth-stats { display: flex; gap: 34px; }
.et-auth-stats b { display: block; font-size: 22px; font-weight: 800; line-height: 1.2; }
.et-auth-stats span { display: block; }

.et-auth-form {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 24px;
}

.et-auth-card { width: 100%; max-width: 420px; }

/* ── 9.2 · Campos ── */
.et-field { display: block; margin-bottom: 16px; }
.et-field > span {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ts-ink);
}

.et-input {
    width: 100%;
    padding: 12px 14px;
    font-size: 14.5px;
    color: var(--ts-ink);
    background: #EEF2F9;
    border: 1px solid #DCE3ED;
    border-radius: 10px;
    transition: border-color .15s, box-shadow .15s, background-color .15s;
}

.et-input:focus {
    outline: none;
    background: #FFFFFF;
    border-color: var(--ts-navy);
    box-shadow: 0 0 0 3px rgba(22, 74, 138, .14);
}

select.et-input { cursor: pointer; }

/* ── 9.3 · Contrasena con boton mostrar/ocultar (auth.js: .is-visible) ── */
.et-pwd-wrap { position: relative; }
.et-pwd-wrap .et-input { padding-right: 44px; }

.et-pwd-toggle {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: none;
    color: #8B96A6;
    cursor: pointer;
}
.et-pwd-toggle svg { width: 18px; height: 18px; }
.et-pwd-toggle .ico-eye-off { display: none; }
.et-pwd-toggle.is-visible .ico-eye { display: none; }
.et-pwd-toggle.is-visible .ico-eye-off { display: block; }

/* ── 9.4 · Enlaces y botones ── */
.et-link { color: var(--brand); font-weight: 600; font-size: 13.5px; text-decoration: none; }
.et-link:hover { text-decoration: underline; }

.et-btn {
    display: block;
    width: 100%;
    height: 48px;
    padding: 0 20px;
    font-size: 15px;
    font-weight: 700;
    color: #FFFFFF;
    text-align: center;
    background: var(--brand);
    border: none;
    border-radius: 10px;
    cursor: pointer;
    transition: background-color .15s;
}
.et-btn:hover { background: #C4001F; }
.et-btn:disabled { opacity: .55; cursor: not-allowed; }

.et-btn.ghost {
    color: var(--ts-navy-900);
    background: #FFFFFF;
    border: 1px solid #DCE3ED;
}
.et-btn.ghost:hover { background: #F4F6F9; }

.et-btn-outline {
    height: auto;
    padding: 14px 16px;
    color: var(--ts-navy-900);
    text-align: left;
    background: #FFFFFF;
    border: 1px solid #DCE3ED;
    border-radius: 10px;
}
.et-btn-outline:hover { border-color: var(--ts-navy); }

/* ── 9.5 · Indicador de pasos (Registro) ── */
.et-steps { display: flex; gap: 6px; }
.et-steps i {
    display: inline-block;
    width: 28px;
    height: 4px;
    font-style: normal;
    background: #DCE3ED;
    border-radius: 2px;
    transition: background-color .15s;
}
.et-steps i.on { background: var(--brand); }

/* ── 9.6 · Opciones de segundo factor (Configurar2FA) ── */
.et-2fa-opciones .et-btn-outline { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* ── 9.7 · Documentos legales con lectura obligatoria (Registro/Consentimiento) ── */
.et-doc-item {
    padding: 14px 16px;
    margin-bottom: 14px;
    background: #FFFFFF;
    border: 1px solid #DCE3ED;
    border-radius: 12px;
}
.et-doc-item.leido { border-color: var(--ok); background: var(--ok-tint); }

.et-doc-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}
.et-doc-nombre { font-size: 14px; font-weight: 600; color: var(--ts-ink); }

.et-doc-leer {
    flex: 0 0 auto;
    padding: 6px 14px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ts-navy);
    background: none;
    border: 1px solid var(--ts-navy);
    border-radius: 8px;
    cursor: pointer;
}
.et-doc-leer:hover { background: rgba(22, 74, 138, .08); }

.et-doc-check {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 13px;
    color: #475569;
}
.et-doc-check input { margin-top: 3px; pointer-events: none; }

.et-doc-estado { margin-top: 8px; font-size: 12px; color: var(--muted); }
.et-doc-item.leido .et-doc-estado { color: var(--ok); }

.et-doc-fin {
    margin-top: 18px;
    padding-top: 16px;
    font-size: 13px;
    color: var(--muted);
    text-align: center;
    border-top: 1px dashed #DCE3ED;
}

/* ── 9.7b · Tablas dentro del texto legal (Política de Privacidad: empresas
   del grupo, banco de datos/Oficial de Datos Personales, categorías de datos,
   finalidades con base jurídica, plazos de conservación, transferencias) ── */
.et-doc-tabla {
    width: 100%;
    border-collapse: collapse;
    margin: 10px 0 16px;
    font-size: 12.5px;
}
.et-doc-tabla th, .et-doc-tabla td {
    border: 1px solid #DCE3ED;
    padding: 7px 10px;
    text-align: left;
    vertical-align: top;
}
.et-doc-tabla thead th {
    background: #F4F6F9;
    font-weight: 700;
    color: var(--ts-ink);
}
/* Variante "ficha" (clave: valor) — proveedores de transferencias nacionales
   e internacionales: no tienen fila de encabezado real, la 1ra columna ES
   la etiqueta. */
.et-doc-tabla-kv td:first-child {
    width: 34%;
    font-weight: 600;
    color: var(--ts-ink);
    background: #FAFBFD;
}

/* ── 9.8 · Modal de documento (registro.js/consentimiento.js: .show) ── */
.et-modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1050;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(11, 37, 69, .55);
}
.et-modal-overlay.show { display: flex; }

.et-modal-box {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 640px;
    max-height: 85vh;
    overflow: hidden;
    background: #FFFFFF;
    border-radius: 14px;
}

.et-modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 20px;
    border-bottom: 1px solid #EEF1F6;
}
.et-modal-head h3 { margin: 0; font-size: 16px; font-weight: 700; }
.et-modal-head small { color: var(--muted); }

.et-modal-close {
    font-size: 22px;
    line-height: 1;
    color: #8B96A6;
    background: none;
    border: none;
    cursor: pointer;
}

.et-modal-body {
    padding: 18px 20px;
    overflow-y: auto;
    font-size: 13.5px;
    line-height: 1.65;
    color: #334155;
}

.et-modal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 20px;
    border-top: 1px solid #EEF1F6;
}
.et-modal-progress { font-size: 12px; color: var(--muted); }

/* ── 9.9 · Responsive: el hero se apila arriba en pantallas chicas ── */
@media (max-width: 900px) {
    .et-auth { flex-direction: column; }
    .et-auth-hero { flex: 0 0 auto; padding: 32px 24px; }
    .et-auth-hero h1 { font-size: 26px; }
    .et-auth-form { padding: 32px 20px; }
}

/* ── 10 · Select2 maestro (R8 2026-09-20): el plugin ahora carga desde
   _HeadCSS/_FooterScripts (global), no por pagina — una vista publica lo
   habia olvidado y el fallo fue mudo. Estos estilos van aqui por el mismo
   motivo: si vivieran en el <style> de una sola vista, la proxima pantalla
   con un combo largo vuelve a salir sin buscador ni salto de linea. Aplica
   a cualquier .select2-container del portal, tanto sobre .form-select
   (resto del portal) como sobre .et-input (pantallas de Account). ── */
.select2-container .select2-selection--single .select2-selection__rendered {
    white-space: normal !important;
    word-wrap: break-word;
    line-height: 1.4;
}
.select2-container--default .select2-selection--single {
    height: auto !important;
    min-height: 38px;
    display: flex;
    align-items: center;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
    height: 100%;
    top: 0;
}
.select2-results__option {
    white-space: normal;
    word-wrap: break-word;
    line-height: 1.35;
}

/* ── 10.1 · Select2 sobre .et-input (pantallas de Account: Registro, etc.) ── */
.et-field .select2-container { width: 100% !important; }
.et-field .select2-container .select2-selection--single {
    padding: 12px 14px;
    font-size: 14.5px;
    color: var(--ts-ink);
    background: #EEF2F9;
    border: 1px solid #DCE3ED;
    border-radius: 10px;
}
.et-field .select2-container--default .select2-selection--single .select2-selection__rendered {
    padding: 0;
}
.et-field .select2-container--default .select2-selection--single .select2-selection__arrow {
    right: 10px;
}
.et-field .select2-container--default.select2-container--focus .select2-selection--single,
.et-field .select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--ts-navy);
    box-shadow: 0 0 0 3px rgba(22, 74, 138, .14);
}


/* ── 10 · Componentes compartidos del portal (Dashboard, Ascensor,
   Documento, Historial, Presupuesto, Cuenta, Firmas, Programacion,
   Encuesta) ────────────────────────────────────────────────────────
   Mismo motivo que la seccion 9: estas clases "et-*" vivian en los CSS
   por-vista que se perdieron con el reemplazo del wwwroot (etrianon-
   inicio.css, etrianon-firma.css, etrianon-calendario.css). En vez de
   recrear un .css por pantalla, todo el sistema de componentes entra
   aqui, una sola vez. Ver wwwroot/js/consulta/*.js, cuenta.js,
   presupuesto.js y las vistas de cada modulo para el HTML exacto.
   ==================================================================== */

:root {
    --et-ink: var(--ts-ink);
    --et-danger: var(--brand);
}

.et-portal { padding-bottom: 28px; }

/* ── 10.1 · Titulos de pantalla (Documento/Historial/Presupuesto) ── */
.et-title { font-size: 22px; font-weight: 800; color: var(--ts-ink); margin: 0; }
.et-sub { font-size: 13.5px; color: var(--muted); margin: 2px 0 16px; }
.et-display { font-weight: 800; color: var(--ts-ink); }

/* ── 10.2 · Cajas de icono reutilizables ── */
.et-ico, .et-icon, .et-ico-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    font-size: 18px;
    border-radius: 10px;
}
.et-ico-lg { width: 52px; height: 52px; font-size: 22px; border-radius: 12px; }
.et-ico-brand { background: var(--brand-tint); color: var(--brand); }

/* ── 10.3 · Tarjetas KPI de Inicio/Documento (borde de color a la izquierda) ── */
.card-kpi.et-stat2 {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 18px;
    background: #FFFFFF;
    border: 1px solid #E7ECF3;
    border-left: 4px solid #CBD4E0;
    border-radius: 12px;
    transition: box-shadow .15s, transform .15s;
}
a.card-kpi.et-stat2:hover { box-shadow: 0 6px 18px rgba(15, 23, 42, .08); transform: translateY(-1px); }
.card-kpi.et-stat2 .ico {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; font-size: 20px; border-radius: 10px;
    flex-shrink: 0; background: #EEF2F9; color: #64748B;
}
.card-kpi.et-stat2 .tx { min-width: 0; }
.card-kpi.et-stat2 .label { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.card-kpi.et-stat2 .value { font-size: 22px; font-weight: 800; color: var(--ts-ink); line-height: 1.3; }
.card-kpi.et-stat2 .pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); margin-top: 2px; }
.card-kpi.et-stat2 .pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .55; }

.card-kpi.et-stat2.danger { border-left-color: var(--brand); }
.card-kpi.et-stat2.danger .ico { background: var(--brand-tint); color: var(--brand); }
.card-kpi.et-stat2.brand { border-left-color: var(--ts-navy); }
.card-kpi.et-stat2.brand .ico { background: #E7EEF8; color: var(--ts-navy); }
.card-kpi.et-stat2.warn { border-left-color: #E0A100; }
.card-kpi.et-stat2.warn .ico { background: #FCF1D8; color: #B4790A; }
.card-kpi.et-stat2.ok { border-left-color: var(--ok); }
.card-kpi.et-stat2.ok .ico { background: var(--ok-tint); color: var(--ok); }

/* .et-card / .et-stat2 tambien se usan solos (Documento), sin .card-kpi */
.et-card { border: 1px solid #E7ECF3; border-radius: 12px; background: #FFFFFF; }
.et-card-pad { padding: 16px; }
.et-card.et-stat2 { display: flex; align-items: center; gap: 14px; padding: 16px; border-left-width: 4px; }
.et-card.et-stat2.danger { border-left-color: var(--brand); }
.et-card.et-stat2.warn { border-left-color: #E0A100; }
/* Documento V4.1 · KPI por moneda: una línea por moneda (S/ · USD) */
.et-kpi-mon { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.et-kpi-mon .amt { white-space: nowrap; }
.et-kpi-mon .cnt { font-size: 12px; font-weight: 600; color: var(--muted, #64748B); }

/* ── 10.4 · Chips de filtro (Ascensor/Documento/Historial) ── */
.et-chip-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.et-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 14px; font-size: 13px; font-weight: 600; color: #475569;
    background: #FFFFFF; border: 1px solid #DCE3ED; border-radius: 999px;
    cursor: pointer; transition: background-color .15s, color .15s;
}
.et-chip .n { padding: 1px 7px; font-size: 11.5px; font-weight: 700; color: #64748B; background: #EEF2F9; border-radius: 999px; }
.et-chip:hover { border-color: var(--ts-navy); }
.et-chip.active { background: var(--ts-navy); border-color: var(--ts-navy); color: #FFFFFF; }
.et-chip.active .n { background: rgba(255, 255, 255, .22); color: #FFFFFF; }

/* ── 10.5 · Pildoras y badges de estado (Cuenta/Documento/Historial/Presupuesto) ── */
.et-pill { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 12.5px; font-weight: 600; border-radius: 999px; }
.et-pill-vacio { background: #F1F4F8; color: var(--muted); }
.et-pill-ok { background: var(--ok-tint); color: var(--ok); }

.et-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; font-size: 12px; font-weight: 700; border-radius: 999px; }
.et-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.et-badge-ok { background: var(--ok-tint); color: var(--ok); }
.et-badge-warn { background: #FCF1D8; color: #B4790A; }
.et-badge-danger { background: var(--brand-tint); color: var(--brand); }
.et-badge-info { background: #E3EEFB; color: #1D6FB8; }

/* ── 10.6 · Botones pequenos reutilizables (Documento/Historial/Presupuesto).
   Selector compuesto (.et-btn.et-btn-sm) a proposito: pesa mas que el
   .et-btn de la seccion 9 (48px, ancho completo) sin depender del orden
   en el archivo. */
.et-btn.et-btn-sm {
    display: inline-flex; align-items: center; gap: 6px;
    width: auto; height: 34px; padding: 0 14px; font-size: 13px; border-radius: 8px;
    background: var(--brand); color: #FFFFFF;
}
.et-btn.et-btn-soft { background: var(--brand-tint); color: var(--brand); }
.et-btn.et-btn-soft:hover { background: #F6CBD3; }
.et-btn.et-btn-ghost { background: #FFFFFF; color: #475569; border: 1px solid #DCE3ED; }
.et-btn.et-btn-ghost:hover { background: #F4F6F9; }

/* ── 10.7 · Fila "numero + subtitulo" de listas (Documento/Historial) ── */
.et-doc-nro { font-weight: 700; font-size: 13.5px; color: var(--ts-ink); }
.et-doc-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ── 10.8 · Anexos adjuntos (Documento/Historial) ── */
.et-anexo-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; margin-bottom: 8px; border: 1px solid #E7ECF3; border-radius: 8px; }
.et-anexo-ico { display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; flex-shrink: 0; font-size: 16px; color: #64748B; background: #EEF2F9; border-radius: 8px; }
.et-anexo-ico.pdf { background: #FBE1E1; color: #C0392B; }
.et-anexo-ico.img { background: #E3EEFB; color: #1D6FB8; }

/* ── 10.9 · Cabecera de pestana (Cuenta) ── */
.et-tab-head { margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px solid #EEF1F6; font-weight: 700; font-size: 15px; color: var(--ts-ink); }

/* ── 10.10 · Firma digital (Cuenta/Firmas) ── */
.et-firma-panel { padding: 16px; background: #F9FAFC; border: 1px dashed #DCE3ED; border-radius: 12px; }
.et-pad-wrap {
    position: relative;
    overflow: hidden;
    background: #FFFFFF;
    background-image: repeating-linear-gradient(to bottom, transparent, transparent 27px, #E7ECF3 28px);
    border: 2px dashed #C7D0DC;
    border-radius: 10px;
    transition: border-color .15s, background-color .15s;
}
.et-pad-wrap canvas { display: block; width: 100%; touch-action: none; position: relative; z-index: 1; }
.et-pad-vacio { background-color: #F9FAFC; }
.et-pad-vacio::before {
    content: "Dibuja tu firma aqui";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-style: italic;
    color: var(--muted);
    pointer-events: none;
    z-index: 0;
}
.et-pad-dirty { border-color: var(--ts-navy); border-style: solid; background-color: #FFFFFF; }
.et-pad-dirty::before { content: none; }
.et-firma-acciones { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; }
.et-firma-botones { display: flex; gap: 8px; }
.et-firma-hint { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.et-ver-doc-leido { color: var(--ts-navy); font-weight: 600; text-decoration: underline; }

/* ── 10.11 · Calificacion por estrellas (Encuesta) ── */
.et-stars { display: flex; gap: 4px; font-size: 28px; color: #DCE3ED; cursor: pointer; }
.et-stars i { font-style: normal; transition: color .1s; }
.et-stars i.on { color: #E0AD0A; }

/* ── 10.12 · Linea de tiempo (Dashboard: proximos servicios) ── */
.et-tl { position: relative; }
.et-tl-item { position: relative; padding: 10px 0 10px 22px; border-left: 2px solid #E7ECF3; }
.et-tl-item:last-child { border-color: transparent; padding-bottom: 0; }
.et-tl-dot { position: absolute; top: 14px; left: -6px; width: 10px; height: 10px; background: #CBD4E0; border-radius: 50%; }
.et-tl-dot.next { background: var(--ts-navy); box-shadow: 0 0 0 4px rgba(22, 74, 138, .15); }

/* ── 10.13 · Calendario propio (Programacion) ── */
.et-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.et-cal-dow { padding-bottom: 6px; font-size: 11px; font-weight: 700; text-align: center; text-transform: uppercase; color: var(--muted); }
.et-cal-cell { min-height: 92px; padding: 6px; background: #FFFFFF; border: 1px solid #E7ECF3; border-radius: 8px; }
.et-cal-cell.empty { background: transparent; border-color: transparent; }
.et-cal-cell.hoy { border-color: var(--ts-navy); box-shadow: inset 0 0 0 1px var(--ts-navy); }
.et-cal-num { margin-bottom: 4px; font-size: 12.5px; font-weight: 700; color: var(--ts-ink); }
.et-cal-ev {
    overflow: hidden;
    margin-bottom: 3px;
    padding: 2px 6px;
    font-size: 10.5px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
    border: 1px solid transparent;
    border-radius: 5px;
}

/* ── 10.14 · Tarjeta de ascensor: eje de pisos simulado (Dashboard) ── */
/* .et-shaft/.flr V1 (barras planas) retirados: ver SS22 -- ahora es una cabina animada. */
.et-piso-num { display: flex; align-items: baseline; gap: 2px; font-size: 26px; font-weight: 800; color: var(--ts-ink); line-height: 1; }
.et-piso-num small { font-size: 14px; font-weight: 600; color: var(--muted); }
.et-dir { margin-left: 2px; font-size: 13px; }
.et-dir.up { color: var(--ts-navy); }
.et-dir.down { color: var(--ts-navy); }
.et-piso-lbl { display: flex; align-items: center; gap: 8px; margin-top: 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.et-sim-tag { padding: 2px 8px; font-size: 10px; font-weight: 700; text-transform: uppercase; color: #B4790A; background: #FCF1D8; border-radius: 999px; }

/* ── 10.15 · Estado vacio (sin equipos/sin resultados) ── */
.et-empty { padding: 48px 24px; text-align: center; color: var(--muted); }
.et-empty .ico { display: flex; align-items: center; justify-content: center; width: 56px; height: 56px; margin: 0 auto 14px; font-size: 24px; color: #94A3B8; background: #EEF2F9; border-radius: 50%; }
.et-empty .t { margin-bottom: 6px; font-weight: 700; color: var(--ts-ink); }
.et-empty .s { max-width: 360px; margin: 0 auto; font-size: 13px; }

/* ── 11 · Iconografia con volumen (badges 3D) ──────────────────────
   [TRIANON-BRAND 2026-09-21] Los pictogramas planos de Tabler dentro
   de .ico/.et-ico-lg (linea monocroma sobre caja de color solido) se
   veian sin vida. Se reemplazan por una insignia SVG inline con
   gradiente de 3 tonos + brillo superior + sombra propia — MISMA
   paleta de marca (navy/rojo/dorado/verde), cero CDN, cero imagen
   rasterizada. La clase .ico-3d anula el fondo plano de .ico/.et-ico-lg
   para que se vea solo la insignia SVG con su propia profundidad. ── */
.ico-3d {
    background: none !important;
    box-shadow: none !important;
}
.ico-3d svg {
    display: block;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 3px 6px rgba(15, 23, 42, .22));
}

/* ── 12 · Visor de anexos (VisorAnexo / visor_anexo.js) ────────────
   [TRIANON-BRAND 2026-09-21] Este componente NO tenia CSS propio en
   ningun archivo: el modal de PDF/imagen se veia con el spinner
   generico de Bootstrap y nada mas mientras cargaba. Es el mismo
   patron "cadena de pasos con estado" que ya usa el portal para todo
   proceso de mas de un paso (descarga -> render), pero en vivo: barra
   de progreso real (bytes descargados / Content-Length cuando el
   servidor lo manda) + esqueletos de pagina con "shimmer" que se
   reemplazan por el canvas real a medida que PDF.js termina cada
   pagina, en vez de una pantalla muda hasta que todo termina. ── */

.visor-anexo-estado {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 56px 24px;
    text-align: center;
}

.visor-anexo-ico-wrap { position: relative; width: 64px; height: 64px; }

.visor-anexo-ico-wrap svg {
    display: block;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 4px 10px rgba(15, 23, 42, .22));
}

/* anillo pulsante detras de la insignia, sugiere actividad sin ser un spinner generico */
.visor-anexo-ico-wrap::before {
    content: "";
    position: absolute;
    inset: -8px;
    border-radius: 18px;
    background: radial-gradient(closest-side, rgba(22, 74, 138, .18), transparent 72%);
    animation: et-pulso 1.6s ease-in-out infinite;
}

@keyframes et-pulso {
    0%, 100% { transform: scale(.92); opacity: .55; }
    50%      { transform: scale(1.08); opacity: 1; }
}

.visor-anexo-texto { font-weight: 700; color: var(--ts-ink); font-size: 14.5px; }
.visor-anexo-subtexto { font-size: 12.5px; color: var(--muted); min-height: 16px; }

/* ── Barra de progreso (descarga y render comparten el mismo componente) ── */
.visor-anexo-barra {
    position: relative;
    width: 100%;
    max-width: 320px;
    height: 8px;
    background: #E7ECF3;
    border-radius: 999px;
    overflow: hidden;
}

.visor-anexo-barra-fill {
    position: absolute;
    inset: 0 auto 0 0;
    width: 0%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--ts-navy) 0%, #4A7FC1 60%, var(--ts-gold) 100%);
    transition: width .25s ease-out;
}

/* Modo indeterminado: sin Content-Length no se sabe el %, se anima un bloque corriendo */
.visor-anexo-barra.indeterminado .visor-anexo-barra-fill {
    width: 40% !important;
    animation: et-barra-corre 1.1s ease-in-out infinite;
}

@keyframes et-barra-corre {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}

/* ── Pasos del visor (Descargando -> Renderizando), mismo lenguaje que
   el resto del portal usa para resultados de procesos multi-paso ── */
.visor-anexo-pasos { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.visor-anexo-pasos .paso { display: flex; align-items: center; gap: 5px; opacity: .45; }
.visor-anexo-pasos .paso.activo { opacity: 1; color: var(--ts-navy); }
.visor-anexo-pasos .paso.hecho { opacity: 1; color: var(--ok); }
.visor-anexo-pasos .sep { opacity: .35; }

/* ── Esqueletos de pagina (uno por cada pagina del PDF, se reemplazan
   por su <canvas> real apenas PDF.js termina de pintarla) ── */
.visor-anexo-pagina-skeleton {
    position: relative;
    width: 100%;
    max-width: 760px;
    margin: 0 auto 18px;
    aspect-ratio: var(--et-ar, 0.77);
    border-radius: 6px;
    overflow: hidden;
    background: #EEF2F9;
    box-shadow: 0 2px 10px rgba(15, 23, 42, .08);
}

.visor-anexo-pagina-skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .75) 50%, transparent 70%);
    background-size: 220% 100%;
    animation: et-shimmer 1.35s ease-in-out infinite;
}

.visor-anexo-pagina-num {
    position: absolute;
    bottom: 8px;
    right: 10px;
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 700;
    color: var(--muted);
    background: rgba(255, 255, 255, .85);
    border-radius: 999px;
}

@keyframes et-shimmer {
    0%   { background-position: 130% 0; }
    100% { background-position: -30% 0; }
}

#visor-anexo-body canvas { display: block; max-width: 100%; height: auto; margin: 0 auto 18px; border-radius: 6px; box-shadow: 0 2px 10px rgba(15, 23, 42, .1); }

.visor-anexo-aviso {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    margin-bottom: 14px;
    font-size: 13.5px;
    color: #8A5A00;
    background: #FCF1D8;
    border: 1px solid #F0DBA0;
    border-radius: 10px;
}

/* ── 13 · Iconos del menu lateral (sprite SVG local con volumen) ───
   [TRIANON-BRAND 2026-09-21] _NavNode.cshtml ya soportaba un modo
   "SVG Sprite" (IconSprite que arranca con "/") ademas del modo Tabler,
   pero no existia ningun sprite: appsettings.Menu.json usaba "ti ti-*"
   en los 23 items. Se creo wwwroot/images/icons-3d/sprite.svg (insignias
   con gradiente navy/dorado + brillo, mismo lenguaje que los KPIs de
   Inicio) y se re-apunto el JSON del menu a el. Cero cambio de codigo:
   el partial ya sabia renderizar <svg><use>. */
.side-nav .menu-icon .sa-icon {
    filter: drop-shadow(0 1.5px 3px rgba(0, 0, 0, .35));
    border-radius: 6px;
}

/* Sidebar colapsado a solo-iconos: la insignia se agranda un poco para
   que siga leyendose como marca y no como un cuadrito perdido. */
html[data-sidenav-size='condensed'] .menu-icon .sa-icon,
html[data-sidenav-size='compact'] .menu-icon .sa-icon {
    width: 1.375rem;
    height: 1.375rem;
}

/* ── 14 · Botones circulares de accion (icon buttons) con volumen ──
   [TRIANON-BRAND 2026-09-21] Todo boton "btn-icon rounded-circle" del
   portal (ayuda, ficha tecnica, y CUALQUIER boton de fila ver/editar/
   eliminar de cada datatable que se construya de aqui en adelante,
   segun el molde documentado en la skill de frontend) pasa de circulo
   plano gris a insignia con relieve real: gradiente suave + brillo
   interior + sombra que responde al hover. Es CSS del componente
   compartido: no hay que tocar cada vista ni cada datatable nueva,
   heredan esto solo por usar la clase ya estandar del sistema. ── */
.btn.btn-icon.rounded-circle {
    position: relative;
    background: linear-gradient(150deg, #F6F8FC 0%, #E3E9F1 100%);
    border-color: rgba(11, 37, 69, .08);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .06), inset 0 1px 0 rgba(255, 255, 255, .9), 0 3px 8px rgba(15, 23, 42, .10);
    color: var(--ts-navy);
    transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.btn.btn-icon.rounded-circle:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(15, 23, 42, .08), inset 0 1px 0 rgba(255, 255, 255, .9), 0 7px 16px rgba(15, 23, 42, .18);
}
.btn.btn-icon.rounded-circle:active { transform: translateY(0); box-shadow: inset 0 1px 3px rgba(15,23,42,.18); }

/* Tono segun la intencion que ya trae el icono (text-danger/success/warning/
   primary): mismo patron de "leer la clase existente", cero HTML nuevo. */
.btn.btn-icon.rounded-circle:has(.text-danger)  { background: linear-gradient(150deg, #FFE3E8 0%, #FBC6CF 100%); color: var(--brand); }
.btn.btn-icon.rounded-circle:has(.text-success) { background: linear-gradient(150deg, #DFF6E8 0%, #BEEBD0 100%); color: var(--ok); }
.btn.btn-icon.rounded-circle:has(.text-warning) { background: linear-gradient(150deg, #FDF1D3 0%, #FBE1A0 100%); color: #B4790A; }
.btn.btn-icon.rounded-circle:has(.text-primary) { background: linear-gradient(150deg, #E7EEF8 0%, #C9D9EF 100%); color: var(--ts-navy); }

/* ── 15 · Botones de chrome sobre superficie navy (topbar/sidebar) ──
   Mismo criterio de volumen, pero "vidrio esmerilado" en vez de
   gradiente claro, porque estan sobre el fondo oscuro de marca. */
.sidenav-toggle-button.btn,
.topnav-toggle-button,
.topbar-link {
    transition: background-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.topbar-item .topbar-link {
    border-radius: 10px;
}
.topbar-item .topbar-link:hover {
    background: rgba(255, 255, 255, .12);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
}
.sidenav-toggle-button.btn.btn-primary {
    background: linear-gradient(150deg, rgba(255,255,255,.22) 0%, rgba(255,255,255,.06) 100%);
    border-color: rgba(255, 255, 255, .22);
    box-shadow: 0 2px 6px rgba(2, 12, 30, .35), inset 0 1px 0 rgba(255, 255, 255, .25);
}
.sidenav-toggle-button.btn.btn-primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(2, 12, 30, .4), inset 0 1px 0 rgba(255, 255, 255, .3);
}

/* ── 16 · KPI ".ico" tambien fuera de .card-kpi (Documento/Facturas) ──
   [TRIANON-BRAND 2026-09-21] SS10.3 solo definia el gradiente/tamano
   del icono para ".card-kpi.et-stat2 .ico". Documento/Index.cshtml usa
   el mismo componente pero SIN la clase .card-kpi (".et-card.et-stat2"),
   asi que su icono caia al genero ".et-ico" sin tono ni tamano fijo —
   el "Saldo pendiente"/"Saldo Vencido" de Facturas electronicas se veian
   deformes. Se iguala el mismo tratamiento embebido (gradiente + brillo
   + sombra) para AMBAS variantes del componente. */
.et-card.et-stat2 .ico {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; font-size: 20px; border-radius: 10px;
    flex-shrink: 0; background: linear-gradient(150deg, #EEF2F9 0%, #DCE3ED 100%); color: #64748B;
    box-shadow: 0 2px 6px rgba(15, 23, 42, .12), inset 0 1px 0 rgba(255, 255, 255, .6);
}
.card-kpi.et-stat2 .ico,
.et-card.et-stat2 .ico {
    box-shadow: 0 2px 6px rgba(15, 23, 42, .14), inset 0 1px 0 rgba(255, 255, 255, .55);
}
.card-kpi.et-stat2.danger .ico, .et-card.et-stat2.danger .ico { background: linear-gradient(150deg, #FFE3E8 0%, #FBC6CF 100%); color: var(--brand); }
.card-kpi.et-stat2.brand  .ico, .et-card.et-stat2.brand  .ico { background: linear-gradient(150deg, #E7EEF8 0%, #C9D9EF 100%); color: var(--ts-navy); }
.card-kpi.et-stat2.warn   .ico, .et-card.et-stat2.warn   .ico { background: linear-gradient(150deg, #FDF1D3 0%, #FBE1A0 100%); color: #B4790A; }
.card-kpi.et-stat2.ok     .ico, .et-card.et-stat2.ok     .ico { background: linear-gradient(150deg, #DFF6E8 0%, #BEEBD0 100%); color: var(--ok); }
/* .ico-3d (badges SVG propias, como en Inicio) siguen anulando el fondo de esta seccion */
.ico-3d { background: none !important; box-shadow: none !important; }

/* ── 17 · Botones "et-btn*" con volumen (Ver/Descargar en Historial,
   Documento, Presupuesto, Cuenta, Firmas, Programacion, Encuesta) ──
   Mismo criterio que los rounded-circle: gradiente + sombra + hover
   con elevacion, sobre la clase compartida que ya usan todos esos
   modulos — no hay que tocar cada JS. */
.et-btn.et-btn-sm {
    box-shadow: 0 2px 5px rgba(228, 0, 43, .28), inset 0 1px 0 rgba(255, 255, 255, .25);
    border: none;
    transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.et-btn.et-btn-sm:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(228, 0, 43, .34), inset 0 1px 0 rgba(255, 255, 255, .3); color: #FFFFFF; }
.et-btn.et-btn-soft { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 1px 3px rgba(228, 0, 43, .10); }
.et-btn.et-btn-soft:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5), 0 3px 8px rgba(228, 0, 43, .18); }
.et-btn.et-btn-ghost:hover { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(15, 23, 42, .12); }

/* ── 18 · Insignias de archivo/anexo con volumen (et-anexo-ico) ──── */
.et-anexo-ico {
    background: linear-gradient(150deg, #EEF2F9 0%, #DCE3ED 100%);
    box-shadow: 0 2px 5px rgba(15, 23, 42, .14), inset 0 1px 0 rgba(255, 255, 255, .6);
}
.et-anexo-ico.pdf { background: linear-gradient(150deg, #FFD9DE 0%, #F6AAB4 100%); color: #A80019; }
.et-anexo-ico.img { background: linear-gradient(150deg, #D3E6FB 0%, #A8CCF3 100%); color: #0E4E8C; }

/* ── 19 · Cualquier boton pequeno solido (btn-info/danger/primary/
   success/warning) con volumen — cubre catalogos genericos como
   Tipo_Documento (btn-editar/btn-eliminar) sin tocar su JS. */
.btn.btn-sm.btn-info, .btn.btn-sm.btn-danger, .btn.btn-sm.btn-primary,
.btn.btn-sm.btn-success, .btn.btn-sm.btn-warning {
    border: none;
    box-shadow: 0 2px 6px rgba(15, 23, 42, .2), inset 0 1px 0 rgba(255, 255, 255, .3), inset 0 -2px 3px rgba(0, 0, 0, .1);
    transition: transform .15s ease, box-shadow .15s ease;
}
.btn.btn-sm.btn-info:hover, .btn.btn-sm.btn-danger:hover, .btn.btn-sm.btn-primary:hover,
.btn.btn-sm.btn-success:hover, .btn.btn-sm.btn-warning:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(15, 23, 42, .28), inset 0 1px 0 rgba(255, 255, 255, .35), inset 0 -2px 3px rgba(0, 0, 0, .12);
}

/* ── 20 · Boton "Descargar" y cabecera del visor de anexos ───────
   Antes: btn-outline-secondary generico, sin marca. Se sube el
   mismo lenguaje 3D (gradiente navy) sin tocar visor_anexo.js: el
   boton es un <a id="visor-anexo-descargar"> fijo en el DOM. */
#visor-anexo-descargar.btn {
    display: inline-flex; align-items: center; gap: 6px;
    color: #FFFFFF;
    background: linear-gradient(150deg, #4A7FC1 0%, #164A8A 100%);
    border: none;
    box-shadow: 0 2px 6px rgba(11, 37, 69, .35), inset 0 1px 0 rgba(255, 255, 255, .25);
    transition: transform .15s ease, box-shadow .15s ease;
}
#visor-anexo-descargar.btn:hover {
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(11, 37, 69, .42), inset 0 1px 0 rgba(255, 255, 255, .3);
}

/* ── 21 · Tarjetas de anexo con miniatura real (AnexosPreview) ─────
   [TRIANON-BRAND 2026-09-21] La fila plana ".et-anexo-item" (icono +
   nombre + boton "Ver") dejaba un hueco en blanco enorme a la derecha
   en el modal de Anexos (Documento/Historial/Presupuesto): no habia
   nada que ocupara ese espacio. Se reemplaza por una grilla de tarjetas
   con miniatura RENDERIZADA (imagen real o 1ra pagina del PDF via
   PDF.js, generada por wwwroot/js/shared/anexos_preview.js) — ya no es
   layout vacio, es contenido. #anexos-lista es el mismo id en las tres
   vistas: una sola regla cubre las tres. */
#anexos-lista {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
    gap: 14px;
}

.et-anexo-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #FFFFFF;
    border: 1px solid #E7ECF3;
    border-radius: 12px;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .06);
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.et-anexo-card:hover, .et-anexo-card:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 8px 18px rgba(15, 23, 42, .14);
    border-color: #C9D9EF;
    outline: none;
}

.et-anexo-thumb {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 0.86;
    background: #EEF2F9;
    overflow: hidden;
}
.et-anexo-thumb canvas,
.et-anexo-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #FFFFFF;
    display: block;
}
.et-anexo-thumb-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    font-size: 22px;
    border-radius: 10px;
    color: #A80019;
    background: linear-gradient(150deg, #FFD9DE 0%, #F6AAB4 100%);
    box-shadow: 0 2px 6px rgba(15, 23, 42, .14), inset 0 1px 0 rgba(255, 255, 255, .6);
}
/* Mientras carga: shimmer sobre el fondo, el icono de respaldo se ve detras */
.et-anexo-thumb-skel::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .8) 50%, transparent 70%);
    background-size: 220% 100%;
    animation: et-shimmer 1.35s ease-in-out infinite;
}

.et-anexo-card-body { padding: 8px 10px 2px; min-width: 0; }
.et-anexo-card-body .nombre { font-size: 12.5px; font-weight: 700; color: var(--ts-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.et-anexo-card-body .meta { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }

.et-anexo-card .et-btn.et-btn-sm { margin: 8px 10px 10px; justify-content: center; }

/* ── 22 · Ascensor: cabina animada real (sube/baja) ─────────────────
   [TRIANON-BRAND 2026-09-21] Pedido explicito: el icono de ascensor
   era generico (ti-elevator) y el "piso actual" era una pila de barras
   planas que solo cambiaba de color -- no se veia un ascensor. La
   simulacion (setInterval en ascensor.js/dashboard.js) YA elegia piso
   destino y avanzaba de a uno con pausas reales; lo que faltaba era la
   parte visual. Ahora hay una CABINA que desliza de verdad dentro del
   riel (transition en "top", easing tipo ascensor), con puertas,
   brillo y sombra propia, y un breve efecto de "en movimiento" (glow +
   ligero squash/stretch) mientras cambia de piso -- generado por
   wwwroot/js/shared/elevator_shaft.js, un solo lugar para las dos
   pantallas que lo usan (Ascensor/Index y Dashboard). ── */
.et-shaft2 {
    position: relative;
    width: 30px;
    height: 84px;
    flex-shrink: 0;
    padding: 9px 0;
    background: linear-gradient(180deg, #E7ECF3 0%, #F4F6F9 50%, #E7ECF3 100%);
    border-radius: 6px;
    box-shadow: inset 0 2px 4px rgba(15, 23, 42, .12), inset 0 -2px 4px rgba(15, 23, 42, .08);
    overflow: hidden;
}
/* riel central: la guia por la que "corre" la cabina */
.et-shaft2::before {
    content: "";
    position: absolute;
    top: 6px; bottom: 6px; left: 50%;
    width: 2px;
    margin-left: -1px;
    background: repeating-linear-gradient(180deg, #C7D0DC 0 3px, transparent 3px 6px);
}
.et-shaft2 .et-piso-tick {
    position: absolute;
    left: 4px; right: 4px;
    height: 1px;
    background: rgba(15, 23, 42, .08);
}

.et-cabina {
    position: absolute;
    left: 50%;
    width: 20px;
    height: 15px;
    margin-left: -10px;
    border-radius: 3px;
    background: linear-gradient(160deg, #8FE0AC 0%, #17803D 55%, #0B4D24 100%);
    box-shadow: 0 2px 5px rgba(15, 23, 42, .35), inset 0 1px 0 rgba(255, 255, 255, .4);
    transition: top .85s cubic-bezier(.45, 0, .2, 1), transform .3s ease, box-shadow .3s ease;
}
/* puertas: linea central de la cabina */
.et-cabina::after {
    content: "";
    position: absolute;
    top: 2px; bottom: 2px; left: 50%;
    width: 1px;
    margin-left: -0.5px;
    background: rgba(11, 37, 69, .35);
}
.et-cabina.bg-warning { background: linear-gradient(160deg, #FBE199 0%, #E0A100 55%, #9C7205 100%); }
.et-cabina.bg-danger  { background: linear-gradient(160deg, #FFA6B2 0%, #E4002B 55%, #970018 100%); }
.et-cabina.bg-secondary { background: linear-gradient(160deg, #CBD4E0 0%, #8A96A6 55%, #55637A 100%); }

/* "en movimiento": leve respiracion vertical + resplandor, se agrega
   por unos ms cada vez que la cabina cambia de piso -- sugiere avance
   real, no solo un salto de posicion. */
.et-cabina.en-movimiento {
    transform: scaleY(1.12);
    box-shadow: 0 3px 10px rgba(23, 128, 61, .5), inset 0 1px 0 rgba(255, 255, 255, .5);
}
.et-cabina.bg-warning.en-movimiento { box-shadow: 0 3px 10px rgba(224, 161, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .5); }
.et-cabina.bg-danger.en-movimiento  { box-shadow: 0 3px 10px rgba(228, 0, 43, .5), inset 0 1px 0 rgba(255, 255, 255, .5); }

/* flecha de direccion sobre la propia cabina, ademas del ".et-dir" de texto */
.et-cabina .et-cabina-dir {
    position: absolute;
    top: -11px; left: 50%;
    transform: translateX(-50%);
    font-size: 9px;
    line-height: 1;
    color: var(--ts-navy);
    opacity: 0;
    transition: opacity .2s ease;
}
.et-cabina.en-movimiento .et-cabina-dir { opacity: 1; }

/* ── Insignia de ascensor (reemplaza ti-elevator generico) ── */
.et-ico.et-ico-ascensor { background: none; }
.et-ico.et-ico-ascensor svg { width: 100%; height: 100%; filter: drop-shadow(0 2px 4px rgba(15, 23, 42, .25)); }

/* ── 23. Tarjeta de Contrato compacta (Edificios y Contratos) ── */
.et-contrato-card {
    border: 1px solid rgba(15, 23, 42, .08);
    border-radius: 12px;
    box-shadow: 0 2px 6px rgba(15, 23, 42, .06);
    transition: transform .18s ease, box-shadow .18s ease;
}
.et-contrato-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 18px rgba(15, 23, 42, .12);
}
.et-contrato-head {
    padding: 10px 14px;
    background: linear-gradient(135deg, var(--ts-navy-800, #164A8A), var(--ts-navy-900, #0B2545));
    color: #fff;
}
.et-contrato-nro {
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .02em;
    opacity: .78;
    text-transform: uppercase;
    line-height: 1.2;
}
.et-contrato-edificio {
    font-size: 14px;
    font-weight: 700;
    line-height: 1.25;
    margin-top: 1px;
}
.et-contrato-head .badge {
    font-size: 10px;
    font-weight: 600;
    padding: .3em .55em;
    flex-shrink: 0;
}
.et-contrato-body {
    padding: 10px 14px 12px;
}
.et-contrato-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--muted, #8a94a6);
    line-height: 1.2;
    margin-bottom: 1px;
}
.et-contrato-valor {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--ts-ink, #1f2937);
    line-height: 1.3;
    word-break: break-word;
}
.et-contrato-ejecutivo {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dashed rgba(15, 23, 42, .1);
}
.et-contrato-ejecutivo img,
.et-contrato-ejecutivo .avatar-title {
    flex-shrink: 0;
}
