/* ============================================================================
   Juicy — Dashboard Design System · POS (lado de productos)
   ----------------------------------------------------------------------------
   Figma: archivo NUEVO — "Juicy POS · Dashboard" (bgAIbrraHKNKn1VF7ZMHBQ),
   frame 2067:7337. OJO: se llama "POS · Cart Fill" pero RENDERIZA EL CARRITO
   VACÍO — el nombre miente. Es solo referencia VISUAL: los tokens de allá pueden
   no llamarse como los de aquí (dicho por el dueño), así que se compara el VALOR.

   Este archivo es la mitad IZQUIERDA: buscador, tabs, y la reja de productos.
   El carrito vive en `ds/cart.css`. La fase se partió así porque el Figma también:
   `Cart Header Search` + `Cart Grid Wrapper` de un lado, `Cart Header Actions` +
   `Cart Sidebar` del otro.

   Markup: templates/template-parts/blocks/pos.php

   Contrato con pos.js / main.js — NO renombrar: `pos_open` / `pos_closed`,
   `loading`, `show_results`, `active` (tab y grid), `outofstock`,
   `data-tabs-wrapper` / `data-tabs-header` / `data-show-tab`, `#pos_search`,
   `#pos_search_results`, `#pos_search_form`.
   ============================================================================ */

/* ---- Tokens ---------------------------------------------------------------- */
:root {
  /* El carril del carrito. Estaba a mano en tres sitios (450 de ancho, 470 =
     450+20 de margen, y el 20 suelto). Ver nota 1. */
  --pos-cart-width: 450px;
  --pos-cart-gap:   20px;
}

/* ---- Estructura ------------------------------------------------------------ */

.page-pos #dashboard_page_content {
  padding: 15px 30px 0 15px;
}

/* En la caja, el hueco del "título" no lleva un título: lleva los chips de la SESIÓN
   (sucursal, bloqueo, cierre) y lo que el vertical cuelgue ahí mismo —la mesa en curso,
   el botón del salón—. Van en FILA.
   Sin esto se APILABAN: cada uno es un bloque, así que el segundo caía a una segunda
   línea y se salía del header de 70px. Pasaba ya con la mesa en curso puesta. Con un
   solo hijo —POS y Espresso— no cambia nada. */
.page-pos #dashboard_title_wrapper {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* Sin caja abierta el POS se apaga: no es decoración, es el gate visual de que
   no se puede vender. Lo enciende `pos_open` desde el PHP. */
.pos_page_main_wrapper.pos_closed {
  opacity: 0.5;
  filter: grayscale(1);
}

.pos_page_main {
  width: calc(100% - (var(--pos-cart-width) + var(--pos-cart-gap)));
}

.pos_page_cart {
  width: var(--pos-cart-width);
  margin-left: var(--pos-cart-gap);
}

.pos_search_header,
.pos_product_archive {
  padding: 15px;
  background: var(--surface-page);
  border-radius: var(--radius-md);
  margin-bottom: 15px;
}

/* 205 = header del dashboard (70+15) + buscador (70+15) + respiro (35). Queda a
   mano: es aritmética de esta pantalla, no un token del sistema. */
.pos_product_archive,
.cart {
  height: calc(100dvh - 205px);
}

/* ---- Buscador -------------------------------------------------------------- */

/* El campo y el botón de alta al vuelo son HERMANOS, no padre e hijo. Ver nota 2. */
.pos_search_header_inner {
  display: flex;
  align-items: center;
  gap: 15px;
}

.pos_search_header_inner .field {
  flex: 1;
  min-width: 0;
}

#pos_search_results {
  position: absolute;
  width: 100%;
  bottom: 0;
  left: 0;
  background: var(--surface-page);
  z-index: 9;
  transform: translateY(100%);
  border: var(--stroke-thin) solid var(--neutral-100);
}

#pos_search_results:empty {
  display: none;
}

/* La ✕ de limpiar solo existe cuando hay resultados (`show_results` lo pone pos.js). */
.remove_results {
  display: none;
}

.show_results .remove_results {
  display: inline-flex;
}

.search_result {
  padding: 15px;
  gap: 15px;
  border-bottom: var(--stroke-thin) solid var(--border-default);
  cursor: pointer;
  transition: all 0.3s;
}

.search_result:last-child {
  border-bottom: none;
}

.search_result:hover {
  background: var(--border-default);
}

.search_result_image {
  width: 50px;
  background: var(--surface-page);
  border-radius: var(--radius-md);
}

.search_result_image img {
  float: left;
  width: 50px;
  border-radius: var(--radius-md);
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
}

.search_result_name {
  font-size: 14px;
  font-weight: bold;
  color: var(--text-primary);
  text-transform: uppercase;
}

.search_result_sku {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: none;
}

.search_result_price {
  font-size: 16px;
  font-weight: bold;
  color: var(--text-muted);
}

/* ---- Barra de tabs --------------------------------------------------------- */

/* SUPERFICIE OSCURA. `--surface-raised` es el token del DS para esto — y
   semantics.css ya lo dice en su comentario: "oscuro: barra de tabs del POS".
   Igual que la caja del login, voltea SU tinta para que lo de encima se lea.
   Ver nota 3. */
.pos_products_nav {
  position: relative;
  display: flex;
  align-items: center;
  border-radius: 7px;
  background: var(--surface-raised);
  border: 3px solid var(--surface-raised);

  --text-primary: var(--neutral-white);
  color: var(--text-primary);
}

/* La tinta de los CONTROLES que van encima también se invierte. El chip `ghost`
   pinta su icono con `--tone-line` (icon-chip.css), no con `--text-primary`, así
   que voltear solo el texto dejaba el icono del tono por defecto — cian sobre la
   barra oscura. Lo cazó la foto, no la lectura: el CSS "se veía bien". Es la
   misma lección que el checkbox del login (F2f), calcada. */
.pos_products_nav .icon-chip {
  --tone-line: var(--neutral-white);
  --tone-fill: rgba(255, 255, 255, 0.15);
  --tone-fg:   var(--neutral-white);
}

.pos_closed .pos_categories_tabs {
  opacity: 0;
  pointer-events: none;
}

/* El desborde horizontal y el esconder su barra los pone `[data-hscroll]`
   (ds/utilities.css), que además la hace movible con la rueda y arrastrando.
   Aquí solo queda cómo ocupa su sitio en la barra. La `scrollbar-width: none`
   que vivía aquí solo escondía la barra en Firefox: en Chrome hacía falta el
   `::-webkit-scrollbar`, y de ahí venía la barra que se veía bajo los tabs. */
.pos_categories_tabs {
  flex: 1;
  min-width: 0;
}

.pos_tab {
  padding: 15px 20px;
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
  border-radius: var(--radius-md);
  white-space: nowrap;
}

/* El activo invierte: papel blanco, tinta oscura. Declara SU tinta junto a su
   papel, que es la regla que dejó F2f — si solo pusiera el fondo, heredaría el
   blanco de la barra y saldría blanco sobre blanco. */
.pos_tab.active {
  background: var(--neutral-white);
  color: var(--neutral-500);
}

/* El slot de acciones de la barra (hoy: ordenar). 44 en el Figma, que es lo que
   deja 30 de chip + 7 de aire a cada lado. */
.pos_products_nav_actions {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
}

/* El popover de orden vive DENTRO de la barra oscura, que invierte la tinta a
   blanca (`--text-primary: white`). Pero el bubble se pinta SOBRE el grid
   (blanco), así que hay que des-invertir o su texto sale blanco sobre blanco.
   Es el mismo gesto del par papel+tinta de `.pos_tab.active`. */
.pos_products_nav .bubble {
  --text-primary: var(--neutral-500);
  color: var(--neutral-500);
}

/* La opción de orden aplicada (persistida en localStorage `pos_sort`). */
.pos_sort_menu .bubble__item.is-active {
  color: var(--action-primary-default);
  font-weight: 600;
}

/* ---- La reja --------------------------------------------------------------- */

.pos_product_archives {
  height: calc(100% - 50px);
  overflow: auto;
  scrollbar-width: none;
}

/* El velo + el spinner de "cargando". `loading` lo pone pos.js. */
.pos_product_archive::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.95);
  z-index: 2;
  visibility: hidden;
  opacity: 0;
}

.pos_product_archive::after {
  content: '';
  position: absolute;
  top: calc(50% - 25px);
  left: calc(50% - 25px);
  width: var(--control-md);
  height: var(--control-md);
  border-width: 5px;
  border-style: solid;
  border-color: var(--neutral-500) var(--neutral-500) var(--neutral-500) transparent;
  border-radius: var(--radius-round);
  z-index: 3;
  animation: loadingRotate 1s infinite ease;
  visibility: hidden;
  opacity: 0;
}

.pos_page_main_wrapper.loading .pos_product_archive::before,
.pos_page_main_wrapper.loading .pos_product_archive::after {
  visibility: visible;
  opacity: 1;
}

.pos_product_archive_grid_wrapper {
  display: none;
}

/* `block` y NO `inline-block`. Un inline-block se encoge a su contenido, así que
   la reja no tenía un ancho definido que llenar y `auto-fill` colapsaba a las
   columnas mínimas. Con las 6 fijas de antes daba igual —forzaban 6 pasara lo que
   pasara— y por eso el bug estaba dormido. Ver nota 4. */
.pos_product_archive_grid_wrapper.active {
  display: block;
}

/* La reja respira sola: `auto-fill` + un mínimo. Ver nota 4. */
.pos_product_archive_grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(135px, 1fr));
  gap: 20px;
  padding: 20px 10px;
}

/* ---- El producto ----------------------------------------------------------- */

.pos_product_item {
  cursor: pointer;
  transition: all 0.3s;
}

.pos_product_item:hover {
  background: var(--neutral-100);
  border-radius: var(--radius-md);
}

.pos_product_item_image {
  background: var(--surface-page);
  border-radius: var(--radius-md);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.pos_product_item_image img {
  float: left;
  width: 100%;
}

.product_title {
  text-transform: uppercase;
  font-size: 11px;
  font-weight: 500;
}

.product_price {
  font-weight: bold;
  font-size: 13px;
  margin-top: 4px;
}

/* ---- Agotado --------------------------------------------------------------- */

.pos_product_item.outofstock {
  text-decoration: line-through;
  pointer-events: none;
  color: var(--text-muted);
}

.outofstock .pos_product_item_image img {
  filter: grayscale(1);
  opacity: 0.5;
}

.outofstock_banner {
  position: absolute;
  top: 15px;
  right: -30px;
  width: 100%;
  height: 30px;
  line-height: 30px;
  font-size: 11px;
  color: var(--text-on-color);
  background: var(--neutral-300);
  text-transform: uppercase;
  transform: rotate(40deg);
  display: none;
}

.pos_product_item.outofstock .outofstock_banner {
  display: inline-block;
}

/* ---- Opciones de producto variable (dentro de su lightbox) ----------------- */

.attribute_label {
  text-align: center;
  display: block;
  margin-bottom: 15px;
  font-weight: 600;
  text-transform: uppercase;
}

.attribute_option_label input {
  display: none;
}

.cart_option {
  height: 60px;
  border: var(--stroke-thin) solid var(--neutral-300);
  color: var(--text-primary);
  border-radius: var(--radius-md);
  padding: 10px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s;
}

.cart_option:hover {
  background: var(--neutral-100);
}

.attribute_option_label input:checked + .cart_option {
  background: var(--neutral-300);
  color: var(--text-on-color);
}

/* ---- Los DOS lightboxes de la caja: buscar cupón y buscar cliente ----------
   Vienen de `main.css` (bloque "CUSTOMERS" y la barra de pestañas horizontal).
   La mudanza cierra un defecto MEDIDO — ver nota 5.
   -------------------------------------------------------------------------- */

/* La FILA de un resultado: un cupón en `posApplyCoupon`, un cliente en
   `searchCustomer`. Sus únicos emisores son esos dos lightboxes y el JS que los
   rellena (`gw_POS.php`, `gw_Coupon.php`, `pos.js`). */
.customer_result {
  padding: 15px;
  border-radius: 5px;
  background: var(--neutral-150);
  cursor: pointer;
  transition: all 0.3s;
}

.customer_result:hover {
  background: var(--neutral-200);
}

.customer_result_data .customer_name {
  text-transform: uppercase;
  font-size: 14px;
  font-weight: 500;
}

.customer_result_data .customer_email {
  font-size: 12px;
  opacity: 0.6;
}

.customer_result_actions .btn {
  font-size: 14px;
}

/* LA FILA DE ACCIONES DE LA CABECERA de la caja. Viene de `main.css`, donde una nota
   afirmaba que era "la barra de acciones de los archives": medido, su ÚNICO emisor en
   todo el producto es `gw_POS::posHeaderActions()`. Ver nota 5. */
.actions_list {
  gap: 5px;
}

/* La barra de pestañas HORIZONTAL. `ds/form.css` la dejó a propósito en
   `main.css` con esta nota: *"su único emisor en todo el producto es el lightbox
   de buscar cliente del POS … El POS es F4 y cruza con su propia familia"*. Es
   este cruce. Ningún formulario la pinta: `form_panel` usa `.sidebar_tab`. */
.tabs_header {
  background: var(--neutral-200);
  color: #fff;
  font-size: 12px;
  text-transform: uppercase;
}

.tab {
  position: relative;
  padding: 20px;
  cursor: pointer;
  color: var(--neutral-300);
}

.tab.active {
  background: #fff;
  color: var(--text-primary);
}

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

   1. EL CARRIL DEL CARRITO ESTABA EN TRES SITIOS Y NO CUADRABAN SOLOS:
      `.pos_page_cart{width:450px; margin-left:20px}` y
      `.pos_page_main{width:calc(100% - 470px)}`. El 470 era 450+20 calculado a
      mano — o sea que cambiar el ancho del carrito pedía acordarse de sumar. Ya
      no: `--pos-cart-width` y `--pos-cart-gap`, y el 470 se calcula solo.

   2. EL BOTÓN DE ALTA AL VUELO SALIÓ DEL CAMPO (decisión del dueño; el Figma lo
      pone en `On-fly Add Product`, 40x40, en x=815 con el input midiendo 790).
      Antes vivía DENTRO, en `.input_actions`, junto a la ✕ de limpiar. Y tenía
      sentido cuando el campo era un `<input>` pelón, pero desde F1 el campo es
      `.field > .field__control > .input`, y el DS dice que lo que va dentro del
      `.input` es una ACCIÓN DEL CAMPO (`Add Action`: limpiar lo escrito). Dar de
      alta un producto no es una acción del campo — es una acción de la pantalla
      que casualmente estaba pegada al campo. Fuera, es un hermano de 40 (el
      mismo `--control-md` del campo, por eso "igual que el field").
      La ✕ de limpiar resultados SÍ se queda dentro: esa sí es del campo.

   3. LA BARRA DE TABS ES LA SEGUNDA SUPERFICIE OSCURA DEL PRODUCTO, y aquí el
      token ya existía con el nombre puesto: `--surface-raised` (neutral/500), y
      su comentario en semantics.css dice literalmente "oscuro: barra de tabs del
      POS". O sea que el DS ya sabía de esta barra antes de que la barra lo
      supiera: pintaba `var(--neutral-500)` a pelo, el primitivo, teniendo su
      semántica a mano.
      Voltea la tinta igual que la caja del login (F2f). Van DOS consumidores del
      mismo patrón; a la tercera se promueve a `ds/` (regla 8). El tab activo es
      el caso interesante: invierte OTRA VEZ (papel blanco sobre barra oscura) y
      por eso declara su tinta junto a su papel — es exactamente la regla del par
      que dejó F2f, aplicada dos niveles seguidos.

   4. LA REJA YA NO CUENTA COLUMNAS. Había tres media queries con 6/5/4 columnas
      fijas — números que no se corresponden con nada salvo el ancho de pantalla
      del que los escribió. Ahora `auto-fill` + `minmax(135px, 1fr)`: la reja mete
      las que quepan. El 135 sale del Figma (146.8 de item con 844 de ancho útil
      = 5 columnas), redondeado para abajo para que a 1440 dé las mismas 5 que el
      diseño. Con el sidebar expandido a ≥1920 caben más, que es lo que se quiere.
      Es menos CSS y además responde al ancho REAL disponible, no al de la ventana
      — que no es lo mismo cuando el sidebar reserva 230 (ver ds/sidebar.css nota 4).

   5. LOS DOS LIGHTBOXES DE LA CAJA SALEN DE `main.css`, Y NO ES ORDEN: ES UN
      DEFECTO MEDIDO. El front nuevo NO importa `main.css` a propósito, así que
      todo lo que se quedó ahí no viste a React. Medido el 2026-08-07 con la caja
      abierta en los dos mundos (`e2e/espejo.mjs`, `/pos` vs `/app/pos`), sobre
      `#posApplyCoupon .customer_result`:

        PHP    background rgb(240,243,246) · border-radius 5px · padding 15px · alto 62
        REACT  background transparent      · border-radius 0px · padding  0px · alto 32

      …y con ellos `.customer_name` 14px→16 y `.customer_email` 12px→16. El dueño
      lo describió al revés —"los cupones salen en una caja gris que la caja vieja
      no tiene"—: la caja gris es la del DS y la que NO la tenía era React.

      Las pestañas (`.tabs_header`/`.tab`) van por lo mismo y con la misma prueba:
      son el modal de cliente, que en React salió SIN pestañas y sin el alta.

      La mudanza es INERTE para las pantallas de PHP: `ds/pos.css` se encola
      DESPUÉS de `main.css` (includes/bootstrap.php), ninguna hoja intermedia
      declara nada que case con estos selectores, y los valores son los mismos.
   ============================================================================ */

/* ---- La caja en VERTICAL: una sola columna, y se vende por el buscador ------ */

/**
 * MEDIDO el 2026-08-21: por debajo de **~565px de viewport** la rejilla de productos
 * (`.pos_page_main`) medía **0px de ancho** y la caja no se podía usar — ni buscar, ni tocar un
 * producto, ni cobrar. La causa es aritmética: el carrito pide `--pos-cart-width` FIJO y la
 * rejilla es `calc(100% - (450 + 20))`, que por debajo de ese umbral se clampa a cero mientras el
 * carrito se queda con todo el ancho.
 *
 * ⚠ **El umbral no es 375, y esa confusión es la trampa cara**: el celular más ancho del mercado
 * son 440px CSS, así que *"probarlo en un móvil más grande"* no arregla nada. **Ningún** teléfono
 * en vertical llegaba a mostrar un solo producto.
 *
 * El corte va en 768 —el mismo que ya usan `ds/header.css` y `ds/grid.css`— y no en el 565 medido:
 * entre ambos la rejilla existe pero mide menos de 200px y no pinta ni una columna decente, así
 * que apilar es mejor que estrujar. Por encima de 768 no cambia nada.
 *
 * **La rejilla se retira a propósito, no por no saber encajarla.** En un teléfono en vertical no
 * caben ni dos tarjetas por fila, y un catálogo de cientos de productos a una columna no se
 * navega: se busca. El buscador ya resuelve por nombre, SKU y código de barras —y es el mismo
 * camino que usa el escáner— así que en vertical **él es la caja**. Con la rejilla se va también
 * su barra de categorías, que sin rejilla que filtrar no tiene a qué apuntar.
 */
@media (max-width: 767.98px) {
  .pos_page_main_wrapper {
    flex-direction: column;
  }

  /* El orden vertical sale del DOM tal cual, sin reordenar: buscador → cliente y acciones →
     carrito. Es la secuencia con la que se cobra. */
  .pos_page_main,
  .pos_page_cart {
    width: 100%;
    margin-left: 0;
  }

  .pos_product_archive {
    display: none;
  }

  /**
   * El alto se recalcula porque el carrito ya no arranca arriba del todo: encima lleva el buscador
   * y la fila del cliente. Medido, empieza en `y=265`, así que el `calc(100dvh - 205px)` de dos
   * columnas se pasa de largo y lo saca de la pantalla.
   *
   * 280 = los 265 hasta donde empieza + 15 de respiro abajo. Es aritmética de esta pantalla, igual
   * que el 205 de arriba, y por eso va a mano y no como token.
   *
   * ⚠ **Aquí estuvo un `height: auto` y era un defecto**: sin alto acotado el carrito no scrollea,
   * y sin ancestro que scrolle el botón anclado deja de anclarse (ver el bloque de `ds/cart.css`).
   * Con el carrito lleno en un iPhone SE el botón se iba a `y=746` con la pantalla de 667.
   */
  .cart {
    height: calc(100dvh - 280px);
  }

  /**
   * ⚠ **LA LISTA DE RESULTADOS FLOTA SOBRE EL CARRITO, y en vertical eso importa.**
   *
   * `#pos_search_results` es `position: absolute` + `translateY(100%)` colgando del formulario, así
   * que no empuja el contenido: lo TAPA. En dos columnas caía sobre la rejilla y daba igual; aquí
   * cae sobre el cliente y el carrito, que es justo lo que hay que poder seguir viendo. Y sin tope
   * de alto, una búsqueda de dos letras cubre la pantalla entera sin dejar salida.
   *
   * Se le pone techo y scroll propio. El `z-index: 9` de la regla base ya la deja por encima del
   * carrito; lo que faltaba era el límite.
   */
  #pos_search_results {
    max-height: 60vh;
    overflow-y: auto;
  }

  /* Sin miniatura tampoco en los resultados (encargo del dueño), por lo mismo que en el renglón
     del carrito: en un teléfono el producto se reconoce por el nombre, y el hueco se lo queda el
     texto — que aquí carga además el SKU y el precio. */
  .search_result_image {
    display: none;
  }
}

/* ---- El marco de la caja: cabecera en flujo y respiro del contenido -------- */

/**
 * Ajustes del dueño (21-ago) para la pantalla de la caja **en móvil**, y sólo para ella: doble
 * puerta, la media query y `.page-pos`. El escritorio se queda **exactamente como estaba** — el
 * `padding` sobre todo, que medido le daba 15px más de ancho a la rejilla (695 → 710) y eso era
 * mover una pantalla que nadie pidió mover.
 *
 * `ds/header.css` pone `#dashboard_header` en `position: fixed` por debajo de 768px, con `top`,
 * `left` y un `width` calculado contra el riel de la barra. En la caja eso estorba: la cabecera se
 * despega del contenido y le roba sitio justo donde menos hay. Aquí vuelve al flujo — de ahí el
 * `inset: auto`, que deshace de una vez el `top`/`left` que trae de allá.
 */
@media (max-width: 767.98px) {
  .page-pos #dashboard_header {
    position: relative;
    width: 100%;
    inset: auto;
  }

  .page-pos #dashboard_page_content {
    padding: 15px;
  }
}

/* ---- El header de la caja en móvil: sólo las acciones ---------------------- */

/**
 * La píldora con el nombre de la sucursal se retira **sólo en móvil** (encargo del dueño, 21-ago):
 * ocupaba el ancho que necesitan los iconos de acción, y en un teléfono era la diferencia entre
 * verlos y no verlos. En escritorio se queda donde estaba.
 *
 * El dato no se pierde: sigue en el gate de "Abrir Caja" —que es donde se ELIGE— y en el corte.
 */
@media (max-width: 767.98px) {
  .header_salepoint {
    display: none;
  }
}

/* ============================================================================
   EL PREMIO DE LEALTAD.

   Vive DENTRO de la fila del cliente —de quien es el premio— y no como un banner
   encima. El banner ocupaba alto propio en la pantalla que menos tiene y empujaba
   el carrito hacia abajo; además decía qué premio había y no de dónde salía. La
   explicación y el botón están ahora en el lightbox, que abre esta marca.

   Sigue siendo la fila del CLIENTE y no el pie de los descuentos, porque canjear
   es una decisión que se toma al elegir a quién se le vende, no al cobrar: entre
   los descuentos, un cajero con prisa no lo ve hasta que ya cobró.
   ========================================================================== */

/* LA FORMA LA PONE EL DS: `icon-chip icon-chip--sm icon-chip--round tone-secondary`.
   Aquí sólo queda la separación de la fila — cualquier otra cosa sería redefinir
   un componente que ya existe, y el DS se llena de copias así.

   SÓLO EL ICONO, y no icono + «Premio»: con el texto la fila se quedaba sin ancho
   y el nombre del cliente se partía en dos líneas (medido con «Facturable
   Testing»), que es justo el descuadre que este cambio venía a evitar. El resto de
   acciones de la fila también son sólo icono; el nombre del premio lo dice el
   `title`, y el porqué, el lightbox. */
.pos_cart_premio_marca {
	margin-left: var(--space-2, 8px);
}

/* ---- El cuerpo del lightbox ------------------------------------------------ */

.premio_lightbox__premio {
	display: flex;
	align-items: center;
	gap: var(--space-2, 8px);
	margin: 0 0 var(--space-3, 12px);
	font-size: 1.125rem;
	font-weight: 600;
	color: var(--text-primary);
}

.premio_lightbox__premio i {
	color: var(--text-brand);
}

.premio_lightbox__porque {
	margin: 0 0 var(--space-2, 8px);
	font-size: 0.9375rem;
	color: var(--text-primary);
}

/* Lo de «no se gasta hasta cobrar» es lo que quita el miedo a pulsar, pero es
   letra pequeña: no debe competir con el premio. */
.premio_lightbox__detalle {
	margin: 0 0 var(--space-4, 16px);
	font-size: 0.8125rem;
	color: var(--text-secondary);
}

/* CENTRADOS: el modal es estrecho y sólo tiene dos botones; alineados a la derecha
   dejaban un hueco muerto a la izquierda que no separaba nada. */
.premio_lightbox__acciones {
	gap: var(--space-2, 8px);
}
