/* ============================================================================
   avisos.css — el sistema unico de avisos de PresuCosto
   ============================================================================

   Boceto 4 del lienzo "Sistema unico de avisos" ("Centro de avisos"), elegido
   por el dueno el 23-oct-2026. Hasta ese dia la app avisaba de 8 maneras
   distintas: 36 funciones de aviso flotante, 12 ventanas de confirmar y 373
   dialogos del navegador, con 6 juegos de colores, 7 radios y 11 capas
   (inventario en el mismo lienzo). Esta hoja es el UNICO dibujo:

     1. El aviso corto (.aviso), abajo a la derecha. Al cerrarse queda en la
        campana: nada se pierde.
     2. La ventana (.aviso-dialogo): confirmar antes de borrar y los avisos que
        deben detener al usuario. Lleva la banda de la app.
     3. La campana (#notifPanel), que pasa a ser el centro de avisos: lo que
        llega del servidor (guardado) y lo que se aviso en esta sesion.

   Los valores salen del contrato de la app (configuracion_contrato.css,
   docs/TEMA_MOVIL_ETAPA2.md): tinta #16202b, linea #e3e7ec, la banda
   #2c5a8f -> #0b2545 y los tintes de bien / atencion / mal / informacion.
   Sin !important; el JS solo pone y quita clases (static/js/components/avisos.js). */

:root {
    --av-tinta: #16202b;
    --av-tinta-2: #4d5b68;
    --av-tinta-3: #6b7a8b;
    --av-linea: #e3e7ec;
    --av-linea-suave: #eef2f6;
    --av-control: #cfd7e0;
    --av-fondo: #ffffff;
    --av-azul: #2c5a8f;
    --av-azul-hondo: #0b2545;
    --av-azul-suave: #eef4fb;
    --av-sombra: 0 12px 30px rgba(11, 37, 69, 0.18);
    --av-velo: rgba(11, 37, 69, 0.42);

    --av-exito-tinta: #1e7d46;
    --av-exito-suave: #e6f3ea;
    --av-error-tinta: #9d3220;
    --av-error-suave: #f7e9e5;
    --av-advertencia-tinta: #8a5c11;
    --av-advertencia-suave: #fef3e2;
    --av-info-tinta: #2c5a8f;
    --av-info-suave: #eef4fb;
    --av-cargando-tinta: #4d5b68;
    --av-cargando-suave: #eef2f6;

    /* Por encima de las ventanas viejas (modal_global va en 999999): un aviso
       que llega con una ventana abierta tiene que verse */
    --av-capa-avisos: 1000002;
    --av-capa-dialogo: 1000001;
}

/* ---------------------------------------------------------------------------
   1. El aviso corto
   --------------------------------------------------------------------------- */

/* La pila, abajo a la derecha, por encima de la barra flotante de Costo IA y
   WhatsApp (26 px de alto pegada al borde de abajo) */
.avisos {
    position: fixed;
    right: 16px;
    bottom: 48px;
    z-index: var(--av-capa-avisos);
    width: 340px;
    max-width: calc(100vw - 32px);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    pointer-events: none;
}

.aviso {
    box-sizing: border-box;
    padding: 10px 10px 10px 12px;
    display: flex;
    align-items: center;
    gap: 10px;
    border: 1px solid var(--av-linea);
    border-radius: 10px;
    background: var(--av-fondo);
    box-shadow: var(--av-sombra);
    color: var(--av-tinta);
    font-family: inherit;
    text-align: left;
    pointer-events: auto;
}

.aviso__icono {
    flex: none;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--av-info-suave);
    color: var(--av-info-tinta);
}

.aviso__icono svg {
    width: 16px;
    height: 16px;
}

.aviso__cuerpo {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
}

.aviso__titulo,
.aviso__mensaje {
    max-width: 100%;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow-wrap: anywhere;
}

.aviso__titulo {
    font-size: 13px;
    font-weight: 700;
    line-height: 1.35;
}

/* Un alert() viejo trae a veces dos o tres renglones (el numero del
   presupuesto, la lista de lo que falta): se respetan, hasta cuatro. */
.aviso__mensaje {
    font-size: 12px;
    line-height: 1.4;
    color: var(--av-tinta-2);
    white-space: pre-line;
    -webkit-line-clamp: 4;
}

.aviso__accion {
    margin: 1px 0 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--av-azul);
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.4;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.aviso__accion:hover {
    color: var(--av-azul-hondo);
    text-decoration: underline;
}

.aviso__cerrar {
    flex: none;
    width: 26px;
    height: 26px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--av-tinta-3);
    cursor: pointer;
}

.aviso__cerrar svg {
    width: 14px;
    height: 14px;
}

.aviso__cerrar:hover {
    background: var(--av-linea-suave);
    color: var(--av-tinta);
}

.aviso__cerrar:focus-visible,
.aviso__accion:focus-visible {
    outline: 2px solid var(--av-azul);
    outline-offset: 2px;
}

/* El tono va solo en el circulo del icono */
.aviso--exito .aviso__icono { background: var(--av-exito-suave); color: var(--av-exito-tinta); }
.aviso--error .aviso__icono { background: var(--av-error-suave); color: var(--av-error-tinta); }
.aviso--advertencia .aviso__icono { background: var(--av-advertencia-suave); color: var(--av-advertencia-tinta); }
.aviso--info .aviso__icono { background: var(--av-info-suave); color: var(--av-info-tinta); }
.aviso--cargando .aviso__icono { background: var(--av-cargando-suave); color: var(--av-cargando-tinta); }

.aviso--saliendo {
    opacity: 0;
    transition: opacity 0.18s ease-in;
}

@media (prefers-reduced-motion: no-preference) {
    .aviso {
        animation: aviso-entra 0.2s ease-out;
    }

    .aviso--saliendo {
        transform: translateY(6px);
        transition: opacity 0.18s ease-in, transform 0.18s ease-in;
    }

    .aviso--cargando .aviso__icono svg {
        animation: aviso-gira 0.9s linear infinite;
    }
}

@keyframes aviso-entra {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

@keyframes aviso-gira {
    to { transform: rotate(360deg); }
}

/* En el telefono la pila ocupa el ancho, abajo. "Ver en avisos" se apaga: la
   campana vive dentro del menu y abrirla desde el aviso no tiene sentido alli */
@media (max-width: 768px) {
    .avisos {
        left: 8px;
        right: 8px;
        bottom: calc(12px + env(safe-area-inset-bottom, 0px));
        width: auto;
        max-width: none;
    }

    .aviso__accion--centro {
        display: none;
    }
}

/* ---------------------------------------------------------------------------
   2. La ventana: confirmar y los avisos que detienen
   --------------------------------------------------------------------------- */

/* Centrada a mano: el centrado propio de <dialog> es margin:auto, y la
   limpieza global de margenes de la app lo anulaba (salia arriba a la izquierda) */
.aviso-dialogo {
    position: fixed;
    inset: 0;
    box-sizing: border-box;
    width: 430px;
    max-width: calc(100vw - 32px);
    height: fit-content;
    max-height: calc(100vh - 32px);
    margin: auto;
    padding: 0;
    overflow: hidden;
    border: 0;
    border-radius: 12px;
    background: var(--av-fondo);
    box-shadow: 0 18px 44px rgba(11, 37, 69, 0.28);
    color: var(--av-tinta);
    font-family: inherit;
}

.aviso-dialogo::backdrop {
    background: var(--av-velo);
}

.aviso-dialogo__banda {
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--av-azul-hondo) linear-gradient(90deg, var(--av-azul) 0%, var(--av-azul-hondo) 100%);
    color: #ffffff;
}

.aviso-dialogo__icono {
    flex: none;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.14);
}

.aviso-dialogo__icono svg {
    width: 17px;
    height: 17px;
}

.aviso-dialogo--exito .aviso-dialogo__icono { color: #7fd3a0; }
.aviso-dialogo--error .aviso-dialogo__icono { color: #f19a85; }
.aviso-dialogo--advertencia .aviso-dialogo__icono { color: #f2c46b; }
.aviso-dialogo--info .aviso-dialogo__icono { color: #8fc3ef; }
.aviso-dialogo--peligro .aviso-dialogo__icono { color: #f19a85; }

.aviso-dialogo__titulo {
    margin: 0;
    font-size: 16px;
    font-weight: 800;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.aviso-dialogo__cuerpo {
    padding: 18px 24px 24px;
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.aviso-dialogo__mensaje {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--av-tinta-2);
    white-space: pre-line;
    overflow-wrap: anywhere;
}

/* El dato que pide la ventana (lo que era prompt()): hundido, como todo
   campo de la app; el borde se vuelve azul al escribir y rojo si falta */
.aviso-dialogo__campo {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: -6px;
}

.aviso-dialogo__campo[hidden],
.aviso-dialogo__falta[hidden],
.aviso-dialogo__etiqueta:empty {
    display: none;
}

.aviso-dialogo__etiqueta {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--av-tinta-2);
}

.aviso-dialogo__entrada {
    box-sizing: border-box;
    width: 100%;
    min-height: 40px;
    padding: 0 12px;
    border: 1px solid var(--av-control);
    border-radius: 8px;
    background: #f7f9fb;
    color: var(--av-tinta);
    font: inherit;
    font-size: 14px;
}

.aviso-dialogo__entrada:focus {
    outline: none;
    border-color: var(--av-azul);
    background: var(--av-fondo);
    box-shadow: 0 0 0 3px rgba(44, 90, 143, 0.16);
}

.aviso-dialogo__entrada[aria-invalid="true"] {
    border-color: var(--av-error-tinta);
    box-shadow: 0 0 0 3px rgba(157, 50, 32, 0.12);
}

.aviso-dialogo__falta {
    font-size: 12px;
    line-height: 1.4;
    color: var(--av-error-tinta);
}

.aviso-dialogo__botones {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

/* Con un solo boton, centrado y del mismo ancho que uno de los dos */
.aviso-dialogo__botones--uno {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
}

.aviso-dialogo__botones--uno .aviso-dialogo__boton {
    width: calc(50% - 5px);
}

.aviso-dialogo__boton {
    min-height: 40px;
    padding: 0 14px;
    border: 1px solid var(--av-control);
    border-radius: 8px;
    background: var(--av-fondo);
    color: var(--av-tinta);
    font: inherit;
    font-size: 13.5px;
    font-weight: 700;
    cursor: pointer;
}

.aviso-dialogo__boton:hover {
    background: var(--av-linea-suave);
}

.aviso-dialogo__boton--principal {
    border-color: var(--av-azul);
    background: var(--av-azul);
    color: #ffffff;
}

.aviso-dialogo__boton--principal:hover {
    border-color: var(--av-azul-hondo);
    background: var(--av-azul-hondo);
}

.aviso-dialogo__boton--peligro {
    border-color: var(--av-error-tinta);
    background: var(--av-error-tinta);
    color: #ffffff;
}

.aviso-dialogo__boton--peligro:hover {
    border-color: #7f2819;
    background: #7f2819;
}

.aviso-dialogo__boton:focus-visible {
    outline: 2px solid var(--av-azul);
    outline-offset: 2px;
}

[hidden].aviso-dialogo__boton {
    display: none;
}

/* En el telefono, menos de 16 px en un campo hace que el navegador acerque
   la pantalla al tocarlo */
@media (max-width: 768px) {
    .aviso-dialogo__entrada {
        font-size: 16px;
    }
}

/* ---------------------------------------------------------------------------
   3. La campana: el centro de avisos
   --------------------------------------------------------------------------- */

/* El boton y su numero (vivian en el <style> de layout_sesion.html; van tal
   cual, solo cambian de casa) */
.notif-bell-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

#notifBell {
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px 8px;
    border-radius: 50%;
    color: #333;
    font-size: 18px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s;
    text-decoration: none;
}

#notifBell:hover { background: rgba(74, 144, 226, 0.1); }

#notifBadge {
    position: absolute;
    top: 2px;
    right: 2px;
    background: #dc2626;
    color: #fff;
    font-size: 10px;
    font-weight: 800;
    min-width: 16px;
    height: 16px;
    border-radius: 8px;
    text-align: center;
    line-height: 16px;
    padding: 0 3px;
    pointer-events: none;
}

#notifBadge.d-none { display: none; }

@keyframes notif-pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.3); }
    100% { transform: scale(1); }
}

#notifBadge.pulse { animation: notif-pulse 0.6s ease; }

/* Etiqueta "Notificaciones" del boton: solo en el menu del telefono */
.notif-bell-label {
    display: none;
}

/* El panel, con el dibujo del aviso */
#notifPanel {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    right: -10px;
    width: 380px;
    overflow: hidden;
    border: 1px solid var(--av-linea);
    border-radius: 10px;
    background: var(--av-fondo);
    box-shadow: 0 16px 40px rgba(11, 37, 69, 0.2);
    color: var(--av-tinta);
    z-index: 9999;
}

#notifPanel.show { display: block; }

.notif-panel-header {
    padding: 14px 16px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.notif-panel-header h4 {
    margin: 0;
    font-size: 15px;
    font-weight: 800;
    color: var(--av-tinta);
}

#btnMarkAllRead {
    padding: 2px 4px;
    border: 0;
    border-radius: 4px;
    background: none;
    color: var(--av-azul);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}

/* La letra de la app solo en escritorio. En el telefono la cabecera es la
   "equis" que cierra el panel (sesion_movil.js cierra al tocarla, salvo sobre
   este boton): con la letra de la app el boton medía 126 px en vez de 120 y el
   centro de la cabecera caia sobre el, asi que tocarla ya no cerraba (medido
   el 24-oct-2026 contra main). */
@media (min-width: 769px) {
    #btnMarkAllRead {
        font-family: inherit;
    }
}

#btnMarkAllRead:hover { text-decoration: underline; }

/* Sin leer / Todos: dos mitades iguales */
.notif-pestanas {
    margin: 10px 16px 0;
    padding: 3px;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 4px;
    border-radius: 8px;
    background: var(--av-linea-suave);
}

.notif-pestana {
    height: 30px;
    padding: 0 8px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--av-tinta-2);
    font: inherit;
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
}

.notif-pestana[aria-selected="true"] {
    background: var(--av-fondo);
    color: var(--av-tinta);
    box-shadow: 0 1px 2px rgba(11, 37, 69, 0.1);
}

.notif-pestana:focus-visible {
    outline: 2px solid var(--av-azul);
    outline-offset: 1px;
}

#notifList {
    max-height: 420px;
    margin-top: 6px;
    overflow-y: auto;
}

.notif-grupo {
    padding: 10px 16px 4px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--av-tinta-3);
}

.notif-item {
    padding: 10px 16px;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    border-top: 1px solid var(--av-linea-suave);
    transition: background 0.15s;
}

.notif-item.notif-clickable {
    cursor: pointer;
}

.notif-item.notif-clickable:hover {
    background: #f7f9fb;
}

/* El circulo del icono, con el tono del aviso */
.notif-icon {
    flex: none;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--av-info-suave);
    color: var(--av-info-tinta);
}

.notif-icon svg {
    width: 16px;
    height: 16px;
}

.notif-item--exito .notif-icon { background: var(--av-exito-suave); color: var(--av-exito-tinta); }
.notif-item--error .notif-icon { background: var(--av-error-suave); color: var(--av-error-tinta); }
.notif-item--advertencia .notif-icon { background: var(--av-advertencia-suave); color: var(--av-advertencia-tinta); }
.notif-item--info .notif-icon { background: var(--av-info-suave); color: var(--av-info-tinta); }
.notif-item--cargando .notif-icon { background: var(--av-cargando-suave); color: var(--av-cargando-tinta); }

.notif-content {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.notif-title {
    font-size: 13px;
    font-weight: 700;
    line-height: 1.35;
    color: var(--av-tinta);
    overflow-wrap: anywhere;
}

.notif-message {
    font-size: 12px;
    line-height: 1.4;
    color: var(--av-tinta-2);
    white-space: pre-line;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.notif-time {
    margin-top: 1px;
    font-size: 11px;
    color: var(--av-tinta-3);
}

.notif-time .notif-accion {
    padding: 0;
    border: 0;
    background: none;
    color: var(--av-azul);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

/* El punto azul de "sin leer" */
.notif-punto {
    flex: none;
    width: 8px;
    height: 8px;
    margin-top: 6px;
    border-radius: 50%;
    background: transparent;
}

.notif-item.notif-unread .notif-punto {
    background: #3498db;
}

.notif-actions {
    flex: none;
    display: flex;
    gap: 2px;
}

.btn-notif-read,
.btn-notif-delete {
    width: 24px;
    height: 24px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--av-tinta-3);
    cursor: pointer;
}

.btn-notif-read svg,
.btn-notif-delete svg {
    width: 13px;
    height: 13px;
}

.btn-notif-read:hover { background: var(--av-exito-suave); color: var(--av-exito-tinta); }
.btn-notif-delete:hover { background: var(--av-error-suave); color: var(--av-error-tinta); }

.notif-empty {
    padding: 28px 16px 32px;
    text-align: center;
    color: var(--av-tinta-3);
    font-size: 13px;
}

@media (max-width: 768px) {
    /* La campana es una fila mas del menu hamburguesa */
    .notif-bell-wrap {
        width: 100%;
    }

    #notifBell {
        width: 100%;
        min-height: 44px;
        border-radius: 8px;
        gap: 8px;
        font-size: var(--font-base, 14px);
        font-weight: 500;
        color: #334155;
    }

    .notif-bell-label {
        display: inline;
    }

    #notifBadge {
        top: 50%;
        right: 12px;
        transform: translateY(-50%);
    }

    /* Hoja fija bajo el header: position:fixed escapa del overflow del menu */
    #notifPanel {
        position: fixed;
        top: 70px;
        left: 10px;
        right: 10px;
        width: auto;
        max-height: calc(100vh - 90px);
        max-height: calc(100dvh - 90px);
        overflow-y: auto;
    }
}

/* ---------------------------------------------------------------------------
   3b. El aviso fijo en la pagina (templates/components/avisos_en_pagina.html):
   los mensajes del servidor junto al formulario (iniciar sesion, registro...).
   El mismo dibujo que el aviso corto, sin flotar y sin cerrarse solo.
   --------------------------------------------------------------------------- */

.avisos-en-pagina {
    margin: 0 0 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.aviso--en-pagina {
    width: 100%;
    box-shadow: none;
}

.aviso--en-pagina .aviso__titulo {
    display: block;
    overflow: visible;
    font-weight: 600;
}

.aviso--en-pagina .aviso__titulo a {
    color: var(--av-azul);
    font-weight: 700;
}

/* La tienda: el ancho de su columna de pago */
.avisos-en-pagina--checkout {
    max-width: 680px;
    margin: 16px auto;
    padding: 0 20px;
    box-sizing: border-box;
}

/* ---------------------------------------------------------------------------
   4. El mensaje dentro de un formulario (debajo del campo)
   --------------------------------------------------------------------------- */

.aviso-campo {
    margin-top: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--av-error-tinta);
}

.aviso-campo svg {
    flex: none;
    width: 14px;
    height: 14px;
}
