/* =============================================================
   ui/dialogo.css — La ventana. Un solo componente para todo.
   =============================================================
   Todo formulario del panel vive acá adentro. Antes eran bloques que se
   desplegaban dentro de la página, y eso en el teléfono se rompe.

   POR QUÉ `<dialog>` Y NO UN DIV PROPIO
   -------------------------------------
   Un `<dialog>` abierto con `showModal()` se pinta en el **top layer**, que es
   el único mecanismo que escapa a TODOS sus ancestros: ignora containing
   blocks, clipping, `overflow` y `z-index` de todo lo que esté arriba.

   Eso importa por una trampa concreta del CSS: `transform`, `filter`,
   `backdrop-filter`, `perspective`, `contain` y `will-change` **en cualquier
   ancestro** crean un containing block. Sus consecuencias:
     · un hijo `position: fixed` se ancla a ESE ancestro, no a la pantalla —
       tu overlay "de pantalla completa" queda del tamaño de una tarjeta;
     · en WebKit el elemento pasa a ser una capa compuesta, y un scroller que
       nace adentro puede no responder al dedo: se ve perfecto, pero no se
       mueve.
   Y lo traicionero es que **la propiedad culpable casi nunca está donde ves
   el síntoma**: una clase de tarjeta con blur rompe algo tres niveles abajo.

   El `<dialog>` no esquiva ese bug caso por caso: **elimina la familia entera
   por construcción**. Y de yapa vienen gratis y sin JavaScript el fondo
   inerte, Escape, el foco atrapado adentro y un `::backdrop` propio.

   Medido en Jeporavo el 04-ago-2026: hoy **ningún** overlay tiene un ancestro
   con esas propiedades, así que el bug no está activo. Esto es preventivo —
   y el `backdrop-filter` de `header.site` ya está ahí esperando.

   LAS 5 REGLAS QUE NO SE ROMPEN
   -----------------------------
   Cada una viene de un bug real. Romper una devuelve el problema:

   1. CERO `backdrop-filter` acá adentro. Fondo opaco.
   2. UN SOLO scroller vertical: el cuerpo. Y con `overflow-x` EXPLÍCITO —
      con solo `overflow-y` el spec fuerza el otro eje a `auto` y aparece un
      scroller horizontal invisible que se roba el gesto del dedo.
   3. NADA de bloquear el scroll del body a mano. `showModal()` ya deja el
      fondo inerte; `overscroll-behavior: contain` corta el encadenamiento.
      Los bloqueos manuales son de donde salieron los bugs de iOS.
   4. NADA de `translateZ` ni `will-change` "para acelerar": crean justo la
      capa compuesta que rompe el scroller.
   5. La confirmación de "tenés cambios sin guardar" va DENTRO del diálogo.
      Un overlay propio queda tapado e inerte debajo del top layer, y el
      usuario ve una pantalla congelada sin saber por qué.

   FORMA: en el teléfono es una hoja pegada abajo; en el escritorio, una
   ventana centrada. Es el MISMO componente — cambia solo con el breakpoint.
   ============================================================= */

/* ---------- El diálogo y su fondo ---------- */

.dlg {
  /* El `<dialog>` trae márgenes, padding y borde propios del navegador. */
  padding: 0;
  border: 0;
  /* Y también trae COLOR propio: la hoja del navegador le pone
     `color: CanvasText`, así que la ventana NO hereda el color del `body` —lo
     pisa—. Con `color-scheme: dark` en `:root` eso ya resuelve en claro, pero
     acá se declara igual y a propósito: si alguien saca esa línea, sin esto
     TODO el texto de TODAS las ventanas vuelve a ser negro sobre negro, en
     silencio. Es la cadena que se rompió el 14-ago-2026. */
  color: var(--text);
  background: transparent;
  margin: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
}

/* El diálogo ocupa la pantalla entera y UBICA la caja adentro con flex.
   Se probó primero con `margin: auto`, y no alcanza: un `<dialog>` es un
   elemento de bloque, así que `width: auto` se estira al ancho completo y la
   caja quedaba pegada a la izquierda en el escritorio. Con flex el centrado
   es explícito y el mismo mecanismo sirve para las dos formas: abajo en el
   teléfono, al medio en el escritorio.

   Va en `[open]` para no pisar el `display: none` que el navegador le pone
   al diálogo cerrado. */
.dlg[open] {
  display: flex;
  align-items: flex-end;      /* teléfono: hoja pegada abajo */
  justify-content: center;
}

.dlg::backdrop {
  /* Regla 1: oscurece, NO desenfoca. */
  background: rgba(0, 0, 0, 0.72);
}

/* ---------- Variante a pantalla completa ----------

   Para lo que NO es un formulario: el visor de fotos. Usa el mismo `<dialog>`
   —o sea el mismo top layer, el mismo Escape, el mismo fondo inerte— pero sin
   la caja de tres zonas, porque no hay nada que scrollear ni acciones que
   dejar fijas: la foto ocupa todo y se navega con las flechas.

   **No es un segundo componente.** Es el mismo elemento con las mismas cinco
   reglas; lo único que cambia es que no dibuja caja. Meter una foto a pantalla
   completa adentro de una tarjeta con encabezado sería pelearse con el diseño
   para ganar nada. */
.dlg.dlg-pleno {
  background: transparent;
}

.dlg.dlg-pleno[open] {
  /* Hereda el `display: flex` de `.dlg[open]` pero SIN el centrado: acá el
     contenido llena la pantalla en vez de quedar en una caja al medio.
     Se probó primero con `display: block` y fue peor: esta regla le gana en
     especificidad a la del consumidor, así que le pisaba su `flex-direction`
     y le desarmaba el layout en columna. La variante anula lo que sobra, no
     impone un display propio. */
  align-items: stretch;
  justify-content: stretch;
  flex-direction: column;
}

.dlg.dlg-pleno::backdrop {
  /* Más oscuro que un formulario: acá lo que importa es la foto. */
  background: rgba(0, 0, 0, 0.95);
}

/* ---------- Variante hoja lateral ----------

   Para lo que se pega a un costado y ocupa todo el alto: el carrito. En el
   teléfono llena la pantalla igual, porque el propio panel usa `width: 100%`
   y su `max-width` recién actúa cuando hay lugar.

   NACE DE UN BUG REAL (12-ago-2026), y el bug explica por qué esto tiene que
   ser una variante y no una regla del consumidor. El carrito se abría con
   `.dlg-pleno` —la de arriba, la del visor— y esa impone `flex-direction:
   column`. Con el eje principal en vertical, el `justify-content: flex-end`
   que el carrito declaraba en `style.css` dejó de controlar el costado: pasó a
   ser el eje CRUZADO. Resultado: en una pantalla de 1900px el panel quedaba de
   460px **pegado a la izquierda**, con el resto vacío. En el teléfono no se
   notaba —ocupa todo el ancho igual—, y por eso pasó la verificación de la
   Fase 4C, que se hizo a 320, 375 y 390.

   La lección quedó escrita en el PLAN: **a la verificación de un diálogo se le
   suma un ancho de escritorio.**

   `flex-direction: row` es lo que hace que `justify-content` vuelva a ser el
   costado. Es la línea que arregla el bug, no una formalidad. */
.dlg.dlg-lateral[open] {
  flex-direction: row;
  align-items: stretch;        /* alto completo */
  justify-content: flex-end;   /* pegada a la derecha */
}

/* ---------- La caja: header + cuerpo + pie ---------- */

.dlg-caja {
  display: flex;
  flex-direction: column;
  /* En el teléfono la hoja usa el ancho completo, SIEMPRE. Sin esto la caja
     toma el ancho de su contenido y queda una ventanita centrada: se descubrió
     con el diálogo de "Sitio e idiomas", cuyos campos son más angostos que los
     de los otros —que llenaban los 375 por casualidad y tapaban el defecto—.
     Verificar los cuatro fue lo que lo destapó. */
  width: 100%;
  /* Descontar la safe area, si no el borde de arriba queda bajo el notch.
     Y `100dvh` en vez de `100vh`: en móvil la barra del navegador aparece y
     desaparece, y con `vh` la caja queda cortada. */
  max-height: calc(100dvh - env(safe-area-inset-top, 0px) - 1rem);
  overflow: hidden;
  /* Regla 1: fondo OPACO. Nada de blur. */
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
  box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.6);
}

.dlg-header {
  /* No scrollea: el cuerpo es el único que lo hace. */
  flex-shrink: 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--line);
}

.dlg-titulo {
  font-family: 'Manrope', system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.3;
  margin: 0;
}

.dlg-subtitulo {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-3);
  font-weight: 400;
}

.dlg-cerrar {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px es el mínimo para tocar con el dedo sin errarle. */
  width: 44px;
  height: 44px;
  margin: -0.5rem -0.5rem -0.5rem 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
}

.dlg-cerrar:hover { background: var(--bg-3); color: var(--text); }

.dlg-cuerpo {
  /* Regla 2: ESTE es el único scroller vertical del diálogo.
     `min-height: 0` es obligatorio en una columna flex — sin eso el área no
     se puede encoger y el borde de arriba se recorta. */
  min-height: 0;
  flex: 1;
  overflow-y: auto;
  /* Regla 2, la parte que se olvida: `overflow-x` EXPLÍCITO. Con solo
     `overflow-y: auto` el spec fuerza el otro eje a `auto`, y aparece un
     scroller horizontal invisible que se queda con el gesto del dedo. */
  overflow-x: hidden;
  /* Regla 3: corta el scroll-chaining sin bloquear el body a mano. */
  overscroll-behavior: contain;
  padding: 1.25rem;
}

.dlg-pie {
  /* Siempre visible: las acciones no se pierden al scrollear. */
  flex-shrink: 0;
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
  padding: 1rem 1.25rem;
  /* La safe area de abajo, para que los botones no queden bajo la barra
     de gestos del teléfono. */
  padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  background: var(--bg-2);
}

/* 44px es el mínimo para tocar con el dedo sin errarle. Los `.btn` del panel
   miden 38, que alcanza con un mouse pero no en un teléfono — y estos son
   justo los botones que se aprietan con el pulgar. Se sube ACÁ y no en `.btn`
   global: cambiar el botón de todo el panel es otro trabajo, y este componente
   no tiene por qué arrastrarlo. */
.dlg-pie .btn {
  min-height: 44px;
}

/* En el teléfono los dos botones ocupan la mitad cada uno: más área para el
   dedo y sin decidir cuál queda más a mano. */
@media (max-width: 767px) {
  .dlg-pie .btn { flex: 1; justify-content: center; }
}

/* ---------- Regla 5: la confirmación vive ADENTRO ---------- */

.dlg-confirmar {
  display: none;
  padding: 1rem 1.25rem;
  border-top: 1px solid var(--line);
  background: var(--bg-3);
}

.dlg-caja.confirmando .dlg-confirmar { display: block; }
/* Mientras se confirma, el pie normal se esconde para no ofrecer dos
   juegos de botones a la vez. Se OCULTA, no se desmonta. */
.dlg-caja.confirmando .dlg-pie { display: none; }

.dlg-confirmar-texto {
  margin: 0 0 0.75rem;
  font-size: 14px;
  color: var(--text-2);
}

.dlg-confirmar-acciones {
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
}

/* ---------- La ventana de confirmar (lib/confirmar.js) ----------

   La caja angosta para un sí o no. Usa `.dlg-caja` entera —mismo fondo, mismo
   borde, misma hoja pegada abajo en el teléfono— y solo cambia el ancho en
   escritorio: 48rem para "¿borrás esto?" es una ventana enorme para dos
   renglones.

   El texto de la consecuencia va en gris y abajo, que es lo que un `confirm()`
   del navegador no puede hacer: ahí "Se publica directamente" queda con el
   mismo peso que la pregunta. */
.dlg-conf-detalle {
  margin: 0.5rem 0 0;
  color: var(--text-2);
  font-size: 14px;
  line-height: 1.5;
}

.dlg-conf-detalle[hidden] { display: none; }

/* Rojo solo cuando se pierde algo. Si todos los botones de confirmar fueran
   rojos, el rojo dejaría de querer decir nada. */
.btn.btn-peligro {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

/* ---------- Escritorio: ventana centrada ---------- */

@media (min-width: 768px) {
  /* Escritorio: ventana centrada, no hoja pegada abajo. */
  .dlg[open] { align-items: center; }

  .dlg-caja {
    width: min(48rem, calc(100vw - 3rem));
    max-height: calc(100dvh - 3rem);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  }

  /* DESPUÉS de `.dlg-caja` a propósito: las dos son (0,1,0), así que decide el
     orden. Puesta antes, la base le ganaría el ancho y la variante no haría
     nada — que es exactamente el bug que tuvo el carrito del 06 al 12-ago. */
  .dlg-caja--angosta { width: min(26rem, calc(100vw - 3rem)); }

  /* Los `.btn` del panel traen `flex: 1` de `style.css`, que en el pie los
     estira hasta ocupar todo el ancho. En el teléfono eso es deseable —más
     área para el dedo— pero en el escritorio deja dos botones enormes al
     lado de un formulario angosto. Acá vuelven a su tamaño natural. */
  .dlg-pie .btn { flex: 0 0 auto; }
}

/* ---------- Movimiento: poco, y respetando la preferencia ---------- */

@media (prefers-reduced-motion: no-preference) {
  /* Se anima SOLO la opacidad. Nada de `transform`, y no por gusto:
     al escribir esto se probó con `translateY(12px)` en el `from`, y en un
     entorno que no compone frames la animación **se quedó trabada en el
     primer fotograma**: la caja arrancaba 12px más abajo, y con ella el pie
     —los botones de guardar y cancelar— se iba fuera de la pantalla.

     La lección: **el layout no puede depender de que una animación termine.**
     Con `opacity` el peor caso es una caja que aparece de golpe; con
     `transform` el peor caso es una caja mal ubicada y botones inalcanzables.

     Y de paso cumple mejor la regla 4: cuanto menos `transform` haya acá,
     menos chance de crear la capa compuesta que rompe el scroller. */
  .dlg[open] .dlg-caja {
    animation: dlg-entrar 0.18s ease-out;
  }

  @keyframes dlg-entrar {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
}
