/* css/avisos.css — cómo se ven los avisos de TODO el sistema LogiPaq.
   Los pinta js/ui/avisos.js (window.LogiAvisos). Los dos van juntos: si una
   página carga el JS sin este CSS los toasts salen con el estilo crudo de
   Shoelace.

   Todo Shoelace: <sl-alert> para los toasts y los bloques, <sl-dialog> para las
   confirmaciones y los formularios.

   Es autocontenido a propósito: define sus propios colores y no depende del CSS
   de ninguna página. Una página puede pisar los tokens de abajo si quiere otro
   color, pero no hace falta para que se vea bien. */

/* ── colores ──────────────────────────────────────────────────────────────
   Un token por tipo de aviso. Los lee `--acc`, que a su vez usan el borde
   superior del toast y el ícono. */

/* ── ANTES DE QUE SHOELACE CARGUE ─────────────────────────────────────────
   El autoloader registra cada componente recien cuando lo VE en el DOM y trae
   el modulo por red. Hasta entonces el navegador trata a `sl-dialog` como una
   etiqueta desconocida —un `display: inline` cualquiera— y PINTA SUS HIJOS: el
   contenido del modal aparece suelto al final de la pagina.

   `:not(:defined)` matchea solo mientras el elemento no esta registrado y deja
   de aplicar solo, sin JS ni una clase que alguien tenga que sacar. Va aca
   ademas de en css/ui/lp-modal.css porque avisos.css lo carga TODA la web
   —LogiAvisos es la norma del sistema— y lp-modal solo tres paginas. */
sl-dialog:not(:defined),
sl-drawer:not(:defined),
sl-alert:not(:defined) {
  display: none;
}

:root {
  --lp-avz-ok: #16a34a;
  --lp-avz-warn: #d97706;
  --lp-avz-err: #dc2626;
  --lp-avz-info: #007aff;
}

:root[data-theme="dark"],
.sl-theme-dark {
  --lp-avz-ok: #22c55e;
  --lp-avz-warn: #f59e0b;
  --lp-avz-err: #ef4444;
  --lp-avz-info: #4da3ff;
}

/* ── pila de toasts ────────────────────────────────────────────────────────
   Shoelace crea .sl-toast-stack solo; el módulo le agrega .lp-toasts para poder
   ubicarlo sin depender de qué otra cosa haya en la página. */

.sl-toast-stack.lp-toasts {
  /* ENCIMA DE TODO, sin excepción: de los modales de Bootstrap (1050), de los
     de Shoelace (1040), de SweetAlert2 (1060) y de los z-index a mano que hay
     repartidos por el sitio (llegan a 2147483000 en napse.css). Un aviso tapado
     por el modal que lo disparó no sirve de nada, y no hay nada que deba
     dibujarse arriba de un aviso. */
  z-index: 2147483647 !important;
  /* Abajo a la derecha: arriba tapa el navbar y la cabecera de los modales. */
  top: auto;
  bottom: 1rem;
  right: 1rem;
  width: min(26rem, calc(100vw - 2rem));
  /* El más nuevo queda abajo de todo, al lado del cursor. */
  display: flex;
  flex-direction: column;
}

.sl-toast-stack.lp-toasts sl-alert {
  margin-bottom: 0.6rem;
}

/* ── el toast ── */

.lp-toast::part(base) {
  border: 1px solid var(--sl-color-neutral-200);
  border-top: 3px solid var(--acc, var(--lp-avz-info));
  /* Arriba en escuadra: la línea de color de 3px se corta fea contra una esquina
     redondeada. Abajo sí, que es donde apoya. */
  border-radius: 0 0 12px 12px;
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.16), 0 2px 6px rgba(15, 23, 42, 0.06);
  backdrop-filter: blur(10px) saturate(140%);
  background: color-mix(in srgb, var(--sl-color-neutral-0) 96%, transparent);
}

.lp-toast::part(message) {
  /* Sin padding a la izquierda el texto queda pegado al ícono. */
  padding: 0.75rem 0.5rem 0.8rem 0.75rem;
}

/* El ícono va centrado en su columna, separado del borde y del texto. */
.lp-toast::part(icon) {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline-start: 0.9rem;
  font-size: 1.15rem;
  color: var(--acc, var(--lp-avz-info));
}

.lp-toast::part(close-button) {
  color: var(--sl-color-neutral-400);
}

.lp-toast::part(close-button):hover {
  color: var(--sl-color-neutral-700);
}

/* Un color por tipo. `--acc` lo leen el borde y el ícono. */
.lp-toast[variant="success"] { --acc: var(--lp-avz-ok); }
.lp-toast[variant="danger"]  { --acc: var(--lp-avz-err); }
.lp-toast[variant="warning"] { --acc: var(--lp-avz-warn); }
.lp-toast[variant="primary"] { --acc: var(--lp-avz-info); }
.lp-toast[variant="neutral"] { --acc: var(--sl-color-neutral-500); }

.lp-toast-tit {
  display: block;
  font-size: var(--sl-font-size-small);
  font-weight: var(--sl-font-weight-semibold);
  line-height: 1.25;
  color: var(--sl-color-neutral-900);
}

/* Chip chico bajo el mensaje: un dato de contexto (el nº de venta, el destino
   del mail) que no merece una línea entera. Lo usa AppNotifications.detail. */
.lp-toast-detalle {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  margin-top: 6px;
  padding: 2px 8px;
  border: 1px solid var(--sl-color-neutral-200);
  border-radius: 999px;
  background: var(--sl-color-neutral-100);
  color: var(--sl-color-neutral-600);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lp-toast-msg {
  margin-top: 2px;
  font-size: var(--sl-font-size-x-small);
  line-height: 1.4;
  color: var(--sl-color-neutral-600);
  /* Los mensajes de error traen saltos de línea (listas de conflictos, filas del
     Excel): se respetan sin tener que meter <br> a mano. */
  white-space: pre-line;
  overflow-wrap: anywhere;
}

@media (max-width: 640px) {
  .sl-toast-stack.lp-toasts {
    top: auto;
    bottom: 0.5rem;
    right: 0.5rem;
    left: 0.5rem;
    width: auto;
  }
}

/* ── toast de progreso ── */

.lp-toast--progreso sl-progress-bar {
  margin-top: 8px;
  --height: 4px;
  --indicator-color: var(--acc, var(--lp-avz-info));
  --track-color: var(--sl-color-neutral-200);
}

.lp-toast--progreso sl-spinner {
  font-size: 1.05rem;
  --indicator-color: var(--acc, var(--lp-avz-info));
  --track-width: 2px;
}

.lp-toast--progreso .lp-toast-msg {
  font-variant-numeric: tabular-nums;
}

/* ── diálogos (confirmación y formulario) ─────────────────────────────────
   Shoelace trae --sl-z-index-dialog en 800, y estos diálogos se abren DESDE
   adentro de otros modales: el navbar está en 1030, los modales de Bootstrap en
   1050, el de detalle de producteca en 1080 y el skin `napse-swal-container`
   —lo que estos diálogos vinieron a reemplazar— en 99999. Se pone arriba de
   todo eso.

   Van DOS declaraciones, y las dos hacen falta:

   1) `:root` es el piso para CUALQUIER sl-dialog de una página que cargue esta
      hoja. Sin él, los diálogos que arma otro módulo con su propia clase
      (`.lcu-dialog` de comentarios, `.erp-manual-dialog`, `.napse-nc-dialog`)
      se quedan con el default 800 de Shoelace y salen DEBAJO del navbar (1030)
      en las páginas que no cargan `css/ui/lp-modal.css`.

   2) `.lp-dialog` es la regla que de verdad resuelve el bug. `lp-modal.css`
      declara el mismo token en `:root` con 1040 y con la MISMA especificidad,
      así que entre los dos `:root` ganaba el que cargara último — y el orden
      del <head> es distinto en cada página: en napse/producteca/e3StoresOmni
      los diálogos de avisos caían a 1040, debajo de los modales de Bootstrap
      (1050). Declarado sobre el host, gana siempre: una custom property puesta
      en el elemento le gana a la heredada de `:root`, sin importar el orden de
      las hojas. */

:root {
  --sl-z-index-dialog: 999999;
}

.lp-dialog {
  --sl-z-index-dialog: 999999;
}

/* El fondo por defecto de Shoelace es muy suave y no trae blur: el diálogo no
   despega de la página. */
.lp-dialog::part(overlay) {
  background-color: rgba(15, 23, 42, 0.62);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}

.sl-theme-dark .lp-dialog::part(overlay),
:root[data-theme="dark"] .lp-dialog::part(overlay) {
  background-color: rgba(2, 6, 23, 0.72);
}

.lp-dialog::part(title) {
  font-size: var(--sl-font-size-large);
  font-weight: var(--sl-font-weight-semibold);
  padding-bottom: 0.4rem;
  /* Color explícito: sin esto hereda el de la página y en modo oscuro el título
     quedaba negro sobre el panel oscuro, o sea invisible. */
  color: var(--sl-color-neutral-900);
}

.lp-dialog::part(close-button) {
  color: var(--sl-color-neutral-600);
}

.lp-dialog::part(body) {
  padding-top: 0;
}

/* ── confirmación ── */

.lp-confirm {
  --width: min(480px, 92vw);
}

/* Crece con el contenido: son cortas y un alto fijo las deja con un hueco. */
.lp-confirm::part(panel) {
  height: auto;
  max-height: 86vh;
  border-radius: 14px;
}

.lp-confirm-cuerpo {
  display: flex;
  gap: var(--sl-spacing-medium);
  align-items: flex-start;
}

.lp-confirm-ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.35rem;
  background: color-mix(in srgb, var(--acc) 14%, transparent);
  color: var(--acc);
}

.lp-confirm--warning { --acc: var(--lp-avz-warn); }
.lp-confirm--danger  { --acc: var(--lp-avz-err); }
.lp-confirm--primary { --acc: var(--lp-avz-info); }

.lp-confirm-txt {
  font-size: var(--sl-font-size-small);
  line-height: 1.5;
  color: var(--sl-color-neutral-700);
  /* Conflictos de códigos y errores de importación vienen como lista con saltos. */
  white-space: pre-line;
  overflow-wrap: anywhere;
  max-height: 46vh;
  overflow: auto;
}

/* ── formulario ── */

.lp-form-dialog {
  --width: min(560px, 92vw);
}

.lp-form-dialog::part(panel) {
  height: auto;
  max-height: 88vh;
  border-radius: 14px;
}

/* Campo obligatorio sin completar. */
.lp-campo-falta::part(base) {
  border-color: var(--sl-color-danger-500);
}

/* ── diálogo genérico (LogiAvisos.dialogo) ───────────────────────────────── */

.lp-dlg {
  --width: min(560px, 92vw);
}

.lp-dlg::part(panel) {
  height: auto;
  max-height: 88vh;
  border-radius: 14px;
}

.lp-dlg-cuerpo {
  font-size: var(--sl-font-size-small);
  line-height: 1.5;
  color: var(--sl-color-neutral-700);
}

/* Con ícono el texto va al costado; sin ícono ocupa todo el ancho. */
.lp-dlg-cuerpo--icono {
  display: flex;
  gap: var(--sl-spacing-medium);
  align-items: flex-start;
}

.lp-dlg-ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.35rem;
  background: color-mix(in srgb, var(--acc) 14%, transparent);
  color: var(--acc);
}

.lp-dlg-ico--success { --acc: var(--lp-avz-ok); }
.lp-dlg-ico--danger  { --acc: var(--lp-avz-err); }
.lp-dlg-ico--warning { --acc: var(--lp-avz-warn); }
.lp-dlg-ico--primary { --acc: var(--lp-avz-info); }

.lp-dlg-html {
  flex: 1 1 auto;
  min-width: 0;
}

/* El markup que trae quien llama puede venir de una página con otro CSS: se le
   fija lo mínimo para que no salga descalzado. */
.lp-dlg-html > :first-child { margin-top: 0; }
.lp-dlg-html > :last-child { margin-bottom: 0; }

.lp-dlg-html input:not([type="checkbox"]):not([type="radio"]),
.lp-dlg-html select,
.lp-dlg-html textarea {
  width: 100%;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--sl-color-neutral-300);
  border-radius: 8px;
  background: var(--sl-color-neutral-0);
  color: var(--sl-color-neutral-800);
  font-size: var(--sl-font-size-small);
}

.lp-dlg-html input:focus,
.lp-dlg-html select:focus,
.lp-dlg-html textarea:focus {
  outline: none;
  border-color: var(--lp-avz-info);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--lp-avz-info) 22%, transparent);
}

/* El error de validación: aparece abajo del cuerpo y frena el cierre. */
.lp-dlg-error {
  margin-top: 0.75rem;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
  border-left: 3px solid var(--lp-avz-err);
  background: color-mix(in srgb, var(--lp-avz-err) 10%, transparent);
  color: var(--lp-avz-err);
  font-size: var(--sl-font-size-x-small);
  line-height: 1.4;
}

.lp-dlg-error[hidden] {
  display: none;
}

.lp-dlg-barra {
  margin-top: 0.75rem;
  --height: 4px;
  --indicator-color: var(--lp-avz-info);
  --track-color: var(--sl-color-neutral-200);
}

/* ── aviso fijo, en la página ── */

.lp-aviso-bloque::part(base) {
  border-radius: 12px;
}

/* ── modo oscuro sin Shoelace ──────────────────────────────────────────────
   El sitio marca el tema con `data-theme`; Shoelace lo lee de la clase
   `sl-theme-dark`. Si la página no las sincroniza, los avisos salen en claro
   sobre una página oscura y no se leen.

   Acá se redefinen SOLO los tokens que usan los avisos, y SOLO sobre los
   elementos de este módulo: las custom properties bajan al shadow DOM de
   Shoelace, así que alcanza y no se le toca el tema a nadie más. */

:root[data-theme="dark"] .lp-toast,
:root[data-theme="dark"] .lp-dialog,
:root[data-theme="dark"] .lp-aviso-bloque {
  color-scheme: dark;

  --sl-color-neutral-0: #18181b;
  --sl-color-neutral-100: #303034;
  --sl-color-neutral-200: #3f3f46;
  --sl-color-neutral-300: #52525b;
  --sl-color-neutral-400: #71717a;
  --sl-color-neutral-500: #a1a1aa;
  --sl-color-neutral-600: #d4d4d8;
  --sl-color-neutral-700: #e4e4e7;
  --sl-color-neutral-800: #f4f4f5;
  --sl-color-neutral-900: #fafafa;
  --sl-color-danger-500: #ef4444;
}

/* ── Piezas que agrega js/ui/swalCompat.js ────────────────────────────────
   El shim de SweetAlert2 sobre LogiAvisos necesita tres cosas que el diálogo
   normal no arma: el `footer` de Swal, el spinner de `showLoading()` y el
   renglón de `showValidationMessage()`. */
.lp-dialogo-pie {
  margin-top: 0.9rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--sl-color-neutral-200);
  color: var(--sl-color-neutral-500);
}

.lp-dialogo-cargando {
  display: flex;
  justify-content: center;
  padding: 1rem 0 0.25rem;
  font-size: 2rem;
}

.lp-dialogo-error {
  margin-top: 0.6rem;
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
  background: var(--e3-err-bg, #fee2e2);
  color: var(--e3-err-fg, #b91c1c);
  font-size: 0.875rem;
}

.lp-dialogo-error[hidden] {
  display: none;
}
