/* ============================================================================
   Juicy — Dashboard Design System · LIGHTBOX + DIALOG
   ----------------------------------------------------------------------------
   Figma: "Lightboxes" (1:2806). Tres piezas:
     Lightbox Main (1:2807)  Size = Small 480 | Medium 800 | Big 1100
     Dialog        (1:2829)  480×207 — la confirmación
     Overlay       (1:2840)  el velo + el Dialog centrado

     <div id="…" class="lightbox lightbox--sm destroy_on_close">
       <div class="lightbox__overlay" data-close-lightbox></div>
       <div class="lightbox__content">
         <div class="lightbox__header">
           <span class="lightbox__title">Editar producto</span>
           <span class="lightbox__close" data-close-lightbox><i class="fi fi-rr-cross"></i></span>
         </div>
         <div class="lightbox__body">…</div>
       </div>
     </div>

   `lightbox`, `lightbox_active` y `destroy_on_close` son CONTRATO CON EL JS
   (main.js abre/cierra y decide si lo destruye). Conservan su nombre, como el
   `bubble_wrapper` de ds/bubble.css: comportamiento y estilo dejan de compartir
   clase. El cierre lo dispara `[data-close-lightbox]`, un atributo — así que la
   clase quedó libre y `close_lightbox` pasa a ser `lightbox__close`.

   AQUÍ NO HAY SIDEBAR. `.lightbox` cubre su contenedor entero; el desplazamiento
   de 70px que el dashboard le mete para no tapar su barra lateral se queda en
   main.css, que es donde vive esa barra. El DS no sabe que existe — es el mismo
   contrato de portabilidad que hace que esto pueda viajar a Electron. Ver nota 1.
   ============================================================================ */

/* ---- Shell ---------------------------------------------------------------- */

.lightbox {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  /* Dónde empieza el área del modal. El DS no sabe que hay un sidebar: el HOST
     lo dice (el dashboard le cede 70px al suyo desde main.css, y sus modales
     bloqueantes lo devuelven a 0 redefiniendo esta variable). Ver nota 1.
     Es variable y no un valor por dos razones: el DS carga DESPUÉS de main.css,
     así que un `left:0` aquí le ganaría al offset del producto — y así el host
     no necesita pelear especificidad para decir algo que es suyo. */
  left: var(--lightbox-inset-start, 0px);
  width: calc(100% - var(--lightbox-inset-start, 0px));
  z-index: 99;

  opacity: 0;
  visibility: hidden;
  transition: opacity .5s, visibility .5s;
}

.lightbox.lightbox_active {
  opacity: 1;
  visibility: visible;
}

/* El velo. Charcoal al 70%, que es lo que mide el Figma (despejado del render:
   #22333B sobre blanco al 70% da exactamente el (101,113,118) que pinta).
   El producto lo tenía al 80% — y su diálogo, a un charcoal DISTINTO. Nota 4. */
.lightbox__overlay {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--brand-charcoal) 70%, transparent);
}

.lightbox__content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);

  width: calc(100% - 40px);
  max-width: 800px;                 /* Figma: Size=Medium. Es el default. */
  background: var(--surface-page);
  border-radius: var(--radius-md);
}

/* ---- Size ----------------------------------------------------------------- */

.lightbox--sm .lightbox__content {
  max-width: 480px;                 /* Figma: Size=Small */
}

/* Figma: Size=Medium. Coincide con el default de `.lightbox__content` (800), pero
   como clase EXPLÍCITA: un modal ancho (p.ej. el checkout horizontal) la pide por
   nombre en vez de depender del default. */
.lightbox--m .lightbox__content {
  max-width: 800px;
}

/* Figma: Size=Big. SIN consumidor hoy — se define porque el DS lo define, igual
   que el alert-banner. Ver nota 3. */
.lightbox--lg .lightbox__content {
  max-width: 1100px;
}

/* ---- Header ---------------------------------------------------------------- */

.lightbox__header {
  display: flex;
  align-items: center;
  justify-content: space-between;

  height: 55px;                     /* Figma. El producto tenía 50. */
  padding-left: 24px;
  background: var(--surface-sunken-light);   /* nota 5 */
  border-radius: var(--radius-md) var(--radius-md) 0 0;
}

/* Sin X que empujar a la derecha, el título va centrado. 9 lightboxes lo usan
   (los que no se cierran con la cruz sino con sus propios botones): antes lo
   pedían con `d-flex justify-content-center` a mano en cada uno. */
.lightbox__header--center {
  justify-content: center;
  padding-inline: 24px;
}

.lightbox__title {
  margin: 0;
  font-size: 16px;                  /* nota 6 */
  font-weight: 500;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-primary);
}

.lightbox__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;

  width: 55px;
  height: 55px;
  border-radius: 0 var(--radius-md) 0 0;
  color: var(--icon-field);
  cursor: pointer;
  transition: background .3s, color .3s;

  /* El cierre debería ser un `<button>` y no el `<span>` con el que nació: un span no se
     alcanza con Tab ni responde a Enter, así que el modal solo se cerraba con el ratón. Este
     reset es lo que permite las dos formas — sin él, un button sale con el borde y el fondo del
     navegador (medido en el front nuevo: un recuadro gris alrededor de la cruz). No cambia nada
     para los spans que ya existen. */
  appearance: none;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
}

.lightbox__close > i {
  font-size: 15px;
  line-height: 1;
}

.lightbox__close:hover {
  background: var(--surface-sunken);
  color: var(--text-primary);
}

.lightbox__body {
  padding: 25px;
  max-height: calc(100dvh - 150px);
  overflow: auto;
}

/* ---- Dialog ---------------------------------------------------------------- */

/* Figma: "Dialog" (1:2829), 480 de ancho. Es la confirmación destructiva, y NO
   es un `.lightbox__content` con otro nombre: no tiene header, ni X, ni cuerpo
   con scroll — es una tarjeta con título, mensaje y dos botones.
   Lo construyen main.js y pos.js (no las plantillas).

     <div id="…" class="lightbox lightbox--dialog destroy_on_close">
       <div class="lightbox__overlay" data-close-lightbox></div>
       <div class="dialog">
         <h3 class="dialog__title">Vaciar papelera</h3>
         <div class="dialog__body"><p>…</p></div>
         <div class="dialog__footer">
           <button class="btn btn--outline tone-neutral-lv2">Cancelar</button>
           <button class="btn tone-error">Vaciar</button>
         </div>
       </div>
     </div> */

.dialog {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);

  display: flex;
  flex-direction: column;
  gap: 16px;

  width: 480px;                     /* Figma. El producto tenía 380. */
  max-width: calc(100% - 40px);
  padding: 24px;
  background: var(--surface-page);
  border-radius: var(--radius-md);  /* el producto usaba 8 — fuera de escala */
  box-shadow: var(--shadow-lg);
}

.dialog__title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;                 /* nota 7 */
  line-height: 1.3;
  text-align: center;               /* Figma lo centra; el producto no. */
  color: var(--text-primary);
}

.dialog__body {
  font-size: 14px;
  line-height: 1.5;
  text-align: center;
  color: var(--text-secondary);
}

.dialog__body p        { margin: 0; }
.dialog__body p + p    { margin-top: 8px; }

.dialog__footer {
  display: flex;
  gap: 10px;
  justify-content: center;
  width: 100%;
}

/* ============================================================================
   NOTAS

   1. EL DS NO SABE QUE HAY UN SIDEBAR. `.lightbox` traía `left:70px; width:
      calc(100% - 70px)` — o sea, el ancho de la barra lateral del dashboard
      metido dentro de un componente. Y como eso obligaba a des-hacerlo para los
      modales que SÍ tapan todo, había dos parches más (`.allblock_lightbox`,
      `.partialblock_lightbox`) cuyo trabajo era devolverlo a `left:0`.
      Aquí el componente cubre su contenedor y ya. El offset del sidebar se queda
      en main.css, junto al sidebar. Con eso, los dos parches se vuelven
      innecesarios en el DS (siguen en main.css mientras el sidebar viva ahí).

   2. LAS DOS PIEZAS SON DISTINTAS, y el producto ya lo sabía: su
      `.confirm_lightbox` decía en un comentario "Card centrada propia: NO usa el
      .lightbox_content con offset de sidebar". Correcto — pero la solución fue
      CLONAR: una tarjeta a mano, con sus propios botones, sus propios colores y
      su propio overlay. Aquí el Dialog es su propio componente y los botones son
      `.btn` del DS.

   3. TAMAÑOS. El Figma da Small 480 · Medium 800 · Big 1100. El producto tenía
      small 500, medium 600, default 800, big 1000 y full. Contado en el markup:
        small_lightbox   16 usos
        default (800)    el resto
        medium_lightbox   0   ← muerto
        big_lightbox      0   ← muerto
        full_lightbox     0   ← muerto
      O sea que el producto usaba DOS tamaños y tenía CINCO. El default (800)
      coincide exacto con el Medium del Figma; `small` baja de 500 a los 480 del
      Figma. `--lg` (1100) se define porque el DS lo define, sin consumidor.
      Los tres muertos no se migran: mueren.

   4. DOS OVERLAYS PARA UN VELO. El lightbox usaba `rgba(34,51,59,.8)` = el
      charcoal al 80%; el confirm, `rgba(15,24,29,.8)` = OTRO azul-negro que no
      es ningún primitivo. Y `.allblock`/`.partialblock` subían el primero a .95.
      El Figma tiene uno solo: charcoal al 70% (despejado del render por álgebra:
      34·0.7 + 255·0.3 = 101, y mide 101). Aquí hay uno.

   5. EL HEADER NO LLEVA BORDE. El producto le ponía `border-bottom: 1px solid
      #eaedf0` — un literal que no es ningún token, y el Figma no dibuja borde:
      bajo su header hay blanco puro (medido). Se va. El header sí conserva su
      fondo, que ya era `neutral-150` = `surface/sunken-light`.

   6. EL TÍTULO SE QUEDA EN 16, y no porque el Figma lo diga: porque no se puede
      leer de un render. Su cap-height mide 10, que con Montserrat da ~14 — pero
      ±1px de medición mueve esa cuenta a 15 o 16, y no hay variable que
      consultar. Misma regla que el padding del item del menú (ds/bubble.css
      nota 4): si solo se puede estimar, manda lo medido en el producto y se
      anota la duda. Pregunta abierta: ¿el título del lightbox es 14 o 16?

   7. `font-weight: 600` en el título del Dialog, transcrito — PERO el tema no
      carga el 600 de Montserrat (300;400;500;700;900), así que renderiza 700.
      Mismo hueco que en los totales del archive (ds/archive.css nota 6) y en el
      header de notificaciones. Van tres: vale la pena decidirlo de una vez.

   8. LOS ROLES DE LOS BOTONES ESTÁN AL REVÉS ENTRE EL FIGMA Y EL PRODUCTO, y
      aquí manda el producto:
        Figma:     CANCELAR outline ROJO · ACEPTAR relleno oscuro
        Producto:  CANCELAR outline neutro · CONFIRMAR relleno ROJO (is_danger)
      El rojo señala la acción DESTRUCTIVA, y la destructiva es la que confirma,
      no la que cancela. Ponerlo como el Figma haría que "Cancelar" — la salida
      segura — fuera lo que grita. Se conserva el producto y se anota el bug
      allá. (El `is_primary` del producto, para confirmaciones no destructivas,
      apuntaba a `--brand-500`, que tampoco es el primario del DS. Ahora es
      `tone-primary`.)

      CORRECCIÓN (F2f, 2026-07-17) — esta nota afirmó que `--brand-500` "NO
      EXISTE en ningún archivo del producto" y que caía a su fallback `--gw-200`
      (#3787D6). ES FALSO, y el cambio a `tone-primary` fue lo correcto por la
      razón equivocada. `--brand-500` SÍ existe y SÍ resuelve: vale **#2563eb**,
      lo define `[data-brand="pos"]` en `juicy-pos/wp-content/plugins/juicy-pos/
      assets/brand.css`, y el navegador lo confirma (`data-brand="pos"`, la hoja
      cargada, el valor computado). El error fue de método: grepeé `juicy-core`
      buscando `verticals/<vertical>/brand.css`, no lo encontré y concluí "no existe" —
      pero la capa de marca vive en el MÓDULO DEL VERTICAL, que es justo donde
      CLAUDE.md (regla 2) manda que viva. Buscar en un repo y concluir sobre
      cinco. `juicy-core/verticals/` sí existe, con un README y nada más, lo que
      reforzó la conclusión falsa.

      Lo que sí destapó buscarlo bien: hay DOS fuentes de marca que se
      contradicen. `brand.css` dice azul (#2563eb) y el preset del theme.json
      dice carmesí (`--wp--preset--color--custom-500` = #D62A49); donde se
      consulta el preset —el login lo hace— gana el carmesí y el azul del
      vertical no se ve nunca. Cuál manda es una decisión pendiente (§3.b);
      pertenece al modelo de marca (F2e), no aquí.
   ============================================================================ */
