/* Movimiento de SIGS.

   Que el sistema se sienta continuo y moderno: al cambiar de módulo el menú y
   la barra superior se quedan quietos y solo cambia lo de adentro; las
   tarjetas, tablas y barras aparecen con suavidad; y al apretar un botón hay
   respuesta inmediata (barra de carga arriba, botón con indicador).

   No cambia tamaños ni disposición: solo agrega movimiento y un poco más de
   contraste. Las animaciones usan las propiedades individuales translate y
   scale (no transform) para no pisar el transform que ponen Bootstrap y
   Popper en menús y ventanas. Todo se apaga con «reducir movimiento» del
   sistema. */

:root {
    --sigs-curva: cubic-bezier(.2, .7, .2, 1);
    --sigs-rapido: .16s;
    --sigs-normal: .45s;

    /* Un poco más de contraste que antes: texto secundario más oscuro (de
       5,9:1 a cerca de 7:1 sobre blanco), bordes y sombras algo más marcados
       para que cada tarjeta se distinga del fondo. */
    --sigs-texto-muted: #4b5563;
    --sigs-borde: #d6dde8;
    --sigs-sombra-sm: 0 1px 3px rgba(15, 23, 42, .09), 0 1px 2px rgba(15, 23, 42, .05);
}

body { color: #161b27; }
.text-muted { color: var(--sigs-texto-muted) !important; }

/* Contorno de foco visible y del color de la marca. */
:focus-visible {
    outline: 2px solid var(--sigs-acento, #2563eb);
    outline-offset: 2px;
    border-radius: 6px;
}
.form-control:focus-visible, .form-select:focus-visible { outline-offset: 0; }

/* ── Pulido: lo más diminuto, legible; los estados, con colores claros ─────
   No se agranda la letra del sistema: solo se sube lo que estaba por debajo
   de lo legible (insignias de 9,5 px, encabezados de tabla de 9,8 px,
   botones chicos de 10,7 px). */
.badge { font-size: .75rem; letter-spacing: 0; }
.badge.globo, .noti-icon-badge { font-size: .7rem; }
.table > thead > tr > th { font-size: .75rem; letter-spacing: .04em; color: #374151; }
.btn-sm { font-size: .8125rem; }

/* Estados con la misma lógica en todo el sistema: azul = en marcha, verde =
   bien, ámbar = atención, rojo = problema, gris = neutro o en espera. El
   «secundario» del tema es un rosado que se leía como error (un «Cotizado»
   o un «Borrador» no lo son): pasa a gris. Los textos de cada color se
   oscurecen para que se lean sobre su fondo suave. */
.badge.bg-primary-subtle   { background-color: #e3ecff !important; color: #1d4ed8 !important; }
.badge.bg-success-subtle   { background-color: #dcf5e6 !important; color: #166534 !important; }
.badge.bg-warning-subtle   { background-color: #fdeccd !important; color: #8a4b08 !important; }
.badge.bg-danger-subtle    { background-color: #fde2e2 !important; color: #b42318 !important; }
.badge.bg-info-subtle      { background-color: #dff3fa !important; color: #0b6580 !important; }
.badge.bg-secondary-subtle { background-color: #e9edf3 !important; color: #475569 !important; }

/* Resumen plegable de Cotizaciones: la línea que lo abre. */
.resumen-cot__detalle > summary {
    cursor: pointer;
    list-style: none;
    font-size: .9rem;
    color: var(--sigs-texto-muted);
}
.resumen-cot__detalle > summary::-webkit-details-marker { display: none; }
.resumen-cot__detalle > summary strong { color: #161b27; }
.resumen-cot__detalle > summary::before { content: '＋ '; color: var(--sigs-acento, #2563eb); }
.resumen-cot__detalle[open] > summary::before { content: '－ '; }
.resumen-cot__detalle[open] > summary { margin-bottom: .5rem; }

/* «Ver las otras N» de Para revisar hoy: un enlace discreto bajo la lista. */
.revisar-resto > summary {
    cursor: pointer;
    list-style: none;
    border-top: 1px solid var(--sigs-borde);
    font-weight: 500;
}
.revisar-resto > summary::-webkit-details-marker { display: none; }
.revisar-resto > summary::before { content: '＋ '; }
.revisar-resto[open] > summary::before { content: '－ '; }
.revisar-resto > summary:hover { background: var(--sigs-acento-suave, #eef4ff); }

/* ── Respuesta al tacto ─────────────────────────────────────────────────── */
.btn,
.dropdown-item,
.nav-link,
.page-link,
#sidebar-menu #side-menu > li > a {
    transition: background-color .18s ease, border-color .18s ease, color .18s ease,
        box-shadow .18s ease, translate var(--sigs-rapido) ease, scale var(--sigs-rapido) ease;
}
.btn:hover:not(:disabled):not(.disabled) { translate: 0 -1px; box-shadow: var(--sigs-sombra-sm); }
.btn:active:not(:disabled):not(.disabled) { translate: 0 0; scale: .98; box-shadow: none; }

#sidebar-menu #side-menu > li > a span { transition: translate .2s var(--sigs-curva); display: inline-block; }
#sidebar-menu #side-menu > li > a:hover span { translate: 3px 0; }

.card { transition: box-shadow .2s ease, translate .2s var(--sigs-curva), border-color .2s ease; }
a.card:hover,
.card:has(> .card-body.py-3):hover {
    translate: 0 -2px;
    box-shadow: var(--sigs-sombra-md);
}

.table > tbody > tr { transition: background-color .15s ease; }
.table-hover > tbody > tr:hover > * { transition: background-color .15s ease; }

/* Al marcar algo (un chip, una casilla, una opción): un salto corto de resorte
   para que se note que quedó. La clase la pone movimiento.js solo cuando la
   persona marca: lo que ya viene marcado al abrir no se mueve. */
@keyframes sigs-marca {
    40% { scale: 1.08; }
}
.sigs-marcado { animation: sigs-marca .26s cubic-bezier(.34, 1.56, .64, 1); }
.form-check-input { transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease, background-position .15s ease; }

/* ── Entrada de cada pantalla ─────────────────────────────────────────────
   Lo que está debajo de la cabecera sube y aparece en escalera, de arriba a
   abajo. backwards: antes de empezar se ve el primer fotograma y al terminar
   no queda nada aplicado (nada de transform residual). */
@keyframes sigs-subir {
    from { opacity: 0; translate: 0 14px; }
    to   { opacity: 1; translate: 0 0; }
}
@keyframes sigs-aparecer {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes sigs-bajar {
    from { opacity: 0; translate: 0 -10px; }
    to   { opacity: 1; translate: 0 0; }
}
@keyframes sigs-menu {
    from { opacity: 0; translate: 0 -6px; scale: .98; }
    to   { opacity: 1; translate: 0 0; scale: 1; }
}
@keyframes sigs-crecer {
    from { scale: 0 1; }
    to   { scale: 1 1; }
}
@keyframes sigs-girar {
    to { rotate: 360deg; }
}

/* Solo lo que ya está en la página al cargar. Los paneles flotantes (el
   menú de obras y los paneles de la cuadrilla), ventanas y avisos se
   muestran quitando `hidden`: con la animación volvían a entrar cada vez,
   invisibles un momento y deslizándose después de soltar a alguien. */
.content > .container-fluid > :not(.row):not(.alert):not(script):not(style):not(.lt-flotante):not([hidden]):not(.modal):not(dialog):not(.toast-container),
.content > .container-fluid > .row > * {
    animation: sigs-subir var(--sigs-normal) var(--sigs-curva) backwards;
}
.content > .container-fluid > :nth-child(2),
.content > .container-fluid > .row > :nth-child(2) { animation-delay: .06s; }
.content > .container-fluid > :nth-child(3),
.content > .container-fluid > .row > :nth-child(3) { animation-delay: .12s; }
.content > .container-fluid > :nth-child(4),
.content > .container-fluid > .row > :nth-child(4) { animation-delay: .18s; }
.content > .container-fluid > :nth-child(5),
.content > .container-fluid > .row > :nth-child(5) { animation-delay: .24s; }
.content > .container-fluid > :nth-child(n+6),
.content > .container-fluid > .row > :nth-child(n+6) { animation-delay: .3s; }

/* Las filas de las tablas aparecen una tras otra (las primeras 14; más allá
   de eso ya está todo a la vista y esperar sería molesto). */
.table > tbody > tr { animation: sigs-aparecer .4s ease backwards; }
.table > tbody > tr:nth-child(1)  { animation-delay: .10s; }
.table > tbody > tr:nth-child(2)  { animation-delay: .13s; }
.table > tbody > tr:nth-child(3)  { animation-delay: .16s; }
.table > tbody > tr:nth-child(4)  { animation-delay: .19s; }
.table > tbody > tr:nth-child(5)  { animation-delay: .22s; }
.table > tbody > tr:nth-child(6)  { animation-delay: .25s; }
.table > tbody > tr:nth-child(7)  { animation-delay: .28s; }
.table > tbody > tr:nth-child(8)  { animation-delay: .31s; }
.table > tbody > tr:nth-child(9)  { animation-delay: .34s; }
.table > tbody > tr:nth-child(10) { animation-delay: .37s; }
.table > tbody > tr:nth-child(n+11) { animation-delay: .4s; }
/* En listas largas (cientos de movimientos) animar cada fila no aporta nada y
   pesa: más allá de las primeras 24 aparecen de una vez. */
.table > tbody > tr:nth-child(n+25) { animation: none; }

/* Barras de avance y de uso: crecen desde cero. */
.progress-bar { transform-origin: left center; animation: sigs-crecer .9s .15s var(--sigs-curva) backwards; }

/* Barras de gráficos y de uso del presupuesto: las del Resumen suben desde la
   base, las de avance y de uso crecen desde la izquierda. Cada una entra un
   poco después de la anterior, así se lee de izquierda a derecha. */
@keyframes sigs-subir-barra {
    from { scale: 1 0; }
    to   { scale: 1 1; }
}
.resumen-barra { transform-origin: bottom center; animation: sigs-subir-barra .7s .25s var(--sigs-curva) backwards; }
.resumen-barras__mes:nth-child(2) .resumen-barra { animation-delay: .32s; }
.resumen-barras__mes:nth-child(3) .resumen-barra { animation-delay: .39s; }
.resumen-barras__mes:nth-child(4) .resumen-barra { animation-delay: .46s; }
.resumen-barras__mes:nth-child(5) .resumen-barra { animation-delay: .53s; }
.resumen-barras__mes:nth-child(n+6) .resumen-barra { animation-delay: .6s; }
.barra-presupuesto > span,
.resumen-obras__barra,
.resumen-apilada__parte { transform-origin: left center; animation: sigs-crecer .9s .25s var(--sigs-curva) backwards; }

/* La campana y los globos del menú «laten» un par de veces al abrir la
   pantalla: avisan que hay algo pendiente sin quedarse parpadeando. */
@keyframes sigs-latido {
    0%, 100% { scale: 1; }
    45%      { scale: 1.3; }
}
.noti-icon-badge,
#sidebar-menu .globo { animation: sigs-latido 1.1s ease-in-out .9s 2; }

/* Filas de las tablas: al pasar el mouse se marca la fila con una barra de
   color a la izquierda, para no perderse en tablas anchas. */
.table-sigs > tbody > tr > td:first-child,
.table-hover > tbody > tr > td:first-child { transition: box-shadow .18s ease; }
.table-sigs > tbody > tr:hover > td:first-child,
.table-hover > tbody > tr:hover > td:first-child { box-shadow: inset 3px 0 0 var(--sigs-acento, #2563eb); }

/* «Más opciones» y los demás desplegables: el contenido baja suavemente en
   vez de aparecer de golpe. */
details[open] > :not(summary) { animation: sigs-bajar .28s var(--sigs-curva); }

/* Ventanas emergentes: entran con un leve zoom además del fundido. */
.modal .modal-dialog { scale: .96; transition: scale .25s var(--sigs-curva), transform .3s ease-out; }
.modal.show .modal-dialog { scale: 1; }

/* Los enlaces a un ancla (#lista) se deslizan en vez de saltar. */
html { scroll-behavior: smooth; }

/* Avisos y menús desplegables. */
.alert { animation: sigs-bajar .4s var(--sigs-curva) backwards; }
.dropdown-menu.show { animation: sigs-menu var(--sigs-rapido) ease-out; }
.toast.show { animation: sigs-bajar .3s var(--sigs-curva); }

/* ── Cambio de módulo (el navegador anima la transición entre páginas) ────
   El menú y la barra superior no se mueven: solo cambia lo que está
   dentro. En navegadores sin soporte, la entrada de arriba cumple el papel. */
@view-transition { navigation: auto; }

.app-sidebar-menu { view-transition-name: sigs-menu; }
.topbar-custom { view-transition-name: sigs-barra; }

::view-transition-old(sigs-menu),
::view-transition-new(sigs-menu) { animation: none; mix-blend-mode: normal; }

::view-transition-old(root) { animation: sigs-aparecer .12s ease reverse both; }
::view-transition-new(root) { animation: sigs-aparecer .2s ease both; }

/* La barra se queda en su sitio: solo se funden el título y los botones. */
::view-transition-group(sigs-barra),
::view-transition-old(sigs-barra),
::view-transition-new(sigs-barra) { animation-duration: .2s; }

/* La raya de la pestaña y el marco de la cuenta viajan de una a otra; la
   barra de la revisión crece. Las dos imágenes son iguales: basta la nueva. */
::view-transition-group(sigs-pestana),
::view-transition-group(sigs-cuenta),
::view-transition-group(sigs-avance) {
    animation-duration: .36s;
    animation-timing-function: cubic-bezier(.22, 1, .36, 1);
}
::view-transition-old(sigs-pestana),
::view-transition-old(sigs-cuenta),
::view-transition-old(sigs-avance) { display: none; }
::view-transition-new(sigs-pestana),
::view-transition-new(sigs-cuenta),
::view-transition-new(sigs-avance) { animation: none; width: 100%; height: 100%; }

/* Con sentido: lo nuevo entra desde donde está su pestaña (transiciones.js). */
@keyframes sigs-sale-izquierda { to { opacity: 0; translate: -24px 0; } }
@keyframes sigs-sale-derecha { to { opacity: 0; translate: 24px 0; } }
@keyframes sigs-entra-derecha { from { opacity: 0; translate: 24px 0; } }
@keyframes sigs-entra-izquierda { from { opacity: 0; translate: -24px 0; } }

html:active-view-transition-type(adelante)::view-transition-old(root) { animation: sigs-sale-izquierda .14s ease both; }
html:active-view-transition-type(adelante)::view-transition-new(root) { animation: sigs-entra-derecha .28s var(--sigs-curva) both; }
html:active-view-transition-type(atras)::view-transition-old(root) { animation: sigs-sale-derecha .14s ease both; }
html:active-view-transition-type(atras)::view-transition-new(root) { animation: sigs-entra-izquierda .28s var(--sigs-curva) both; }

/* Si todo el contenido ya se desliza, las tarjetas no suben además. */
html:active-view-transition-type(adelante, atras) .content > .container-fluid > *,
html:active-view-transition-type(adelante, atras) .content > .container-fluid > .row > * {
    animation: none !important;
}

/* El fondo que asoma mientras el contenido se desliza. */
html { background-color: var(--sigs-fondo); }

/* ── Barra de carga arriba y botones que están enviando ───────────────────
   La pone movimiento.js al hacer clic en un enlace o enviar un formulario:
   así, aunque el servidor tarde, se ve que el sistema está trabajando. */
#sigs-carga {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 3px;
    z-index: 2000;
    background: linear-gradient(90deg, var(--sigs-acento, #2563eb), #6aa0ff);
    transform-origin: left center;
    scale: 0 1;
    opacity: 0;
    pointer-events: none;
    transition: scale .25s ease-out, opacity .25s ease;
    box-shadow: 0 0 8px rgba(37, 99, 235, .55);
}
#sigs-carga.activa { opacity: 1; }

form[data-enviando] button[type="submit"],
form[data-enviando] input[type="submit"] { pointer-events: none; opacity: .85; }
form[data-enviando] button[type="submit"]::after {
    content: '';
    display: inline-block;
    width: 1em; height: 1em;
    margin-left: .55em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    vertical-align: -.15em;
    animation: sigs-girar .7s linear infinite;
}

/* ── Quien prefiere menos movimiento ───────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    @view-transition { navigation: none; }
}
