/**
 * Caja rápida — hoja de estilo.
 *
 * Se busca que el cajero, que lleva meses con OpenPOS, no tenga que
 * reaprender nada: rejilla de productos a la izquierda, carrito a la
 * derecha, buscador arriba. Misma disposición, misma lógica de colores.
 *
 * Todo en unidades relativas y con `clamp()` para que funcione igual en el
 * monitor del mostrador y en la tablet. Por debajo de 900 px el carrito deja
 * de ser una columna y pasa a ser una hoja inferior: en una pantalla
 * estrecha, dos columnas dejan ambas inservibles.
 *
 * Sin dependencias, sin fuentes externas, sin imágenes. La hoja entera va
 * incrustada en la página para no gastar una petición de más.
 */

/*
 * La página de la caja NO se desplaza.
 *
 * La caja cubre el viewport con `position: fixed`, pero la página del tema
 * sigue debajo con su cabecera, su pie y su altura, y el navegador dibuja una
 * barra de desplazamiento que no lleva a ninguna parte —y que en una tablet se
 * arrastra sin querer, dejando la caja «bailando»—. Se bloquea solo en esta
 * página, mediante la clase que pone `SCP_Caja::clase_del_body()`.
 */
body.scp-caja-pantalla {
	overflow: hidden;
	height: 100%;
	overscroll-behavior: none;
}

/*
 * PANTALLA COMPLETA, y es imprescindible.
 *
 * Insertada como shortcode, la caja hereda la columna de contenido del tema
 * —unos 330 px— y queda inservible: las fichas se apilan en una tira estrecha
 * y el carrito no cabe. Un punto de venta necesita toda la pantalla, sin
 * cabecera ni menús del sitio compitiendo por el espacio.
 *
 * Se resuelve con `position: fixed` cubriendo el viewport, en vez de pelear
 * con los anchos del tema (que cambian de un tema a otro y de una plantilla a
 * otra). Así funciona igual da dónde se pegue el shortcode.
 */
.scp-caja {
	position: fixed;
	inset: 0;
	z-index: 99990;
	overflow: hidden;

	/*
	 * `inset: 0` no basta. Los temas de bloques ponen a los hijos del
	 * contenido un `max-width` (el ancho de columna) más `margin-inline:auto`,
	 * y eso encoge y centra hasta a un elemento fijo: se quedaba en 645 px
	 * centrados en vez de ocupar la pantalla. Hay que anular las tres cosas.
	 */
	max-width: none !important;
	width: auto !important;
	margin: 0 !important;
	min-height: 0 !important;

	--cj-fondo:    #f1f3f6;
	--cj-panel:    #ffffff;
	--cj-borde:    #dfe3e8;
	--cj-texto:    #1f2733;
	--cj-suave:    #6b7684;
	--cj-acento:   #0f766e;
	--cj-acento-2: #115e59;
	--cj-may:      #b91c1c;
	--cj-ok:       #15803d;
	--cj-radio:    10px;

	/* Menú lateral fijo + zona de trabajo, como OpenPOS. */
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 0;
	color: var(--cj-texto);
	font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	font-size: clamp(14px, 1.6vw, 16px);
	background: var(--cj-fondo);
	border-radius: 0;
	box-sizing: border-box;
}

.scp-caja *,
.scp-caja *::before,
.scp-caja *::after { box-sizing: inherit; }

/*
 * EL ATRIBUTO `hidden` TIENE QUE GANAR SIEMPRE.
 *
 * `hidden` funciona con la regla `[hidden]{display:none}` de la hoja del
 * navegador, que es la de MENOR prioridad: cualquier regla propia que declare
 * `display` la anula sin avisar. Aquí pasó con `.cj-desc { display:flex }` y
 * con `.cj-cifra { display:grid }`, y el resultado fue que la línea del
 * descuento NO SE OCULTABA aunque el descuento estuviera quitado —el elemento
 * tenía `hidden` puesto y aun así se veía—.
 *
 * Lección para las pruebas: comprobar `elemento.hidden` no vale, porque la
 * propiedad era `true` mientras en pantalla seguía visible. Hay que mirar
 * `getComputedStyle(...).display`.
 */
.scp-caja [hidden] { display: none !important; }

/* ---- Menú lateral ---- */

.cj-nav {
	display: flex;
	flex-direction: column;
	gap: 2px;
	width: clamp(74px, 8vw, 96px);
	padding: 8px 6px;
	background: var(--cj-acento-2);
	overflow-y: auto;
}

.cj-nav__b {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	padding: 12px 4px;
	border: 0;
	border-radius: 10px;
	background: transparent;
	color: #fff;
	font: inherit;
	font-size: .74em;
	font-weight: 700;
	line-height: 1.15;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}

.cj-nav__b svg { width: 26px; height: 26px; }
.cj-nav__b:hover { background: rgba(255, 255, 255, .16); }
.cj-nav__b--fin { margin-top: auto; }

/* ---- Zona de trabajo ---- */

.cj-principal {
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-width: 0;
	min-height: 0;
	padding: 10px;
}

/* ---- Barra superior ---- */

.cj-barra {
	display: flex;
	gap: 8px;
	align-items: center;
	flex-wrap: wrap;
}

.cj-buscar {
	flex: 1 1 240px;
	min-width: 0;
	padding: 12px 14px;
	font-size: 1em;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-panel);
	color: inherit;
}

.cj-buscar:focus {
	outline: 2px solid var(--cj-acento);
	outline-offset: -1px;
}

.cj-modo {
	flex: 0 0 auto;
	padding: 12px 18px;
	font-weight: 700;
	border: 0;
	border-radius: var(--cj-radio);
	background: var(--cj-acento);
	color: #fff;
	cursor: pointer;
}

/* ==================================================================
 * MODO MAYORISTA — la interfaz entera cambia de color
 *
 * No basta con teñir un botón: el cajero tiene que saber en qué lista está
 * con una ojeada, desde el otro lado del mostrador, sin leer nada. Se
 * reescriben las variables de color y el cambio recorre toda la pantalla
 * —fondo, paneles, bordes, acentos— de una sola vez.
 * ================================================================== */

.scp-caja.cj-mayorista {
	/* Rojo claro, no oscuro: se distingue de un vistazo pero se lee bien y
	   no cansa en una jornada entera delante de la pantalla. */
	--cj-fondo:    #fff1f1;
	--cj-panel:    #ffffff;
	--cj-borde:    #f5b5b5;
	--cj-texto:    #4a1010;
	--cj-suave:    #a35b5b;
	--cj-acento:   #c62828;
	--cj-acento-2: #8e1f1f;
	--cj-ok:       #b91c1c;
}

.scp-caja.cj-mayorista .cj-nav    { background: #c62828; }
.scp-caja.cj-mayorista .cj-estado--ok { background: #fde2e2; color: #8e1f1f; }
.scp-caja.cj-mayorista .cj-ficha  { border-left-color: #e05252; }

/* Salida al menú: en pantalla completa el menú del sitio queda tapado, así
   que la caja tiene que ofrecer su propia puerta de vuelta. */
.cj-salir {
	flex: 0 0 auto;
	padding: 12px 16px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-panel);
	color: var(--cj-suave);
	font: inherit;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
}

.cj-salir:hover { color: var(--cj-texto); }

.cj-estado {
	flex: 0 0 auto;
	font-size: .82em;
	font-weight: 600;
	padding: 6px 10px;
	border-radius: 999px;
	background: #e5e7eb;
	color: var(--cj-suave);
	white-space: nowrap;
}

.cj-estado--ok      { background: #dcfce7; color: var(--cj-ok); }
.cj-estado--espera  { background: #fef3c7; color: #92400e; }
.cj-estado--offline { background: #fee2e2; color: var(--cj-may); }

/* ---- Quién tiene la caja abierta, y cómo está la red ----
 *
 * Arriba a la derecha, junto al buscador. Con varias cajas y turnos que se
 * cruzan, lo que hace falta ver de un vistazo es el NOMBRE; el estado de la
 * red cabe en un icono, que además se distingue desde lejos mejor que la
 * palabra «En línea» que había antes. El texto no se pierde: va en `title`
 * y en `aria-label`. */

.cj-sesion {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
}

/* El nombre es un <button> desde la 2.19 (abre la tarjeta del cajero, como
   la foto), pero se ve como el texto de siempre: sin borde ni fondo. El
   recorte con «…» va en el <span> de dentro. */
.cj-quien {
	display: inline-flex;
	align-items: center;
	min-width: 0;
	max-width: 22ch;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	font: inherit;
	font-size: .9em;
	font-weight: 700;
	line-height: 1.25;
	color: var(--cj-texto);
	text-align: left;
	text-transform: uppercase;
	letter-spacing: .3px;
	cursor: default;
}

.cj-quien__n {
	display: block;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* La miniatura del cajero (v2.18), donde antes iba el icono de señal. Es un
   botón: el módulo de bienvenida la usa para volver a enseñar la tarjeta. */
.cj-avatar {
	position: relative;
	flex: 0 0 auto;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: inherit;
	font: inherit;
	line-height: 0;
	cursor: default;
}

.cj-avatar.es-abre { cursor: pointer; }
.cj-avatar:focus-visible { outline: 2px solid var(--cj-acento); outline-offset: 2px; }

.cj-avatar__foto {
	display: block;
	width: 100%;
	height: 100%;
	overflow: hidden;
	border-radius: 50%;
	background: var(--cj-borde);
	box-shadow: 0 0 0 2px var(--cj-panel), 0 1px 4px rgba(15, 23, 42, .25);
}

.cj-avatar__foto > img,
.cj-avatar__foto > svg {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Sin conexión la foto se apaga un poco: de un vistazo se ve que algo va mal. */
.cj-avatar.es-offline .cj-avatar__foto { filter: grayscale(.85); opacity: .75; }

/* La insignia de la conexión, sobre la esquina de la foto. Sin número es un
   puntito; con ventas o cambios por subir lleva la cifra. */
.cj-conex {
	position: absolute;
	right: -3px;
	bottom: -2px;
	min-width: 13px;
	height: 13px;
	padding: 0;
	border-radius: 999px;
	background: #94a3b8;
	box-shadow: 0 0 0 2px var(--cj-fondo);
	color: #fff;
	font-size: 10.5px;
	font-weight: 800;
	line-height: 13px;
	text-align: center;
	white-space: nowrap;
	pointer-events: none;
}

.cj-conex.con-numero { min-width: 18px; height: 18px; padding: 0 4px; line-height: 18px; right: -6px; bottom: -4px; }
.cj-conex.es-ok      { background: #22c55e; }
.cj-conex.es-espera  { background: #f59e0b; color: #422006; }
.cj-conex.es-offline { background: #64748b; }

/* Sin conexión la insignia late despacio: es el único aviso de que las
   ventas se están quedando en el navegador. */
.cj-conex.es-offline { animation: cj-latir 1.8s ease-in-out infinite; }

@keyframes cj-latir { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

@media (prefers-reduced-motion: reduce) {
	.cj-conex.es-offline { animation: none; }
}

/* En pantalla estrecha el nombre estorba más de lo que ayuda: la foto se
   queda, el nombre se recorta a lo que quepa. */
@media (max-width: 560px) {
	.cj-quien { max-width: 10ch; }
	.cj-avatar { width: 34px; height: 34px; }
}

/* En el móvil el buscador va solo en la primera fila (entero, para escribir
   cómodo) y debajo el buzón a la izquierda y quien cobra a la derecha. */
@media (max-width: 480px) {
	.cj-barra .cj-buscar { flex-basis: 100%; }
	.cj-sesion { margin-left: auto; }
	.cj-quien { max-width: 16ch; }
}

/* ---- Cuerpo: rejilla + carrito ---- */

.cj-cuerpo {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
	gap: 10px;
	/* min-height:0 es lo que permite que los hijos con scroll funcionen
	   dentro de un contenedor flexible; sin esto la lista desborda. */
	min-height: 0;
	flex: 1 1 auto;
}

/* DOS COLUMNAS FIJAS, no `auto-fill`.
   Con auto-fill, en un monitor ancho salían cinco o seis columnas y encontrar
   un producto se volvía un barrido con la vista. Dos columnas dejan el nombre
   completo legible y la búsqueda va por el teclado, no por el ojo. */
.cj-lista {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 8px;
	align-content: start;
	overflow-y: auto;
	/* La altura la marca el contenedor, que ya ocupa la pantalla. Fijarla en
	   vh dejaba un hueco muerto abajo en monitores altos. */
	max-height: 100%;
	padding-right: 4px;
	min-height: 0;
}

.cj-ficha {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 10px;
	width: 100%;
	text-align: left;
	padding: 12px 14px;
	border: 1px solid var(--cj-borde);
	border-left: 3px solid var(--cj-acento);
	border-radius: var(--cj-radio);
	background: var(--cj-panel);
	color: inherit;
	font: inherit;
	cursor: pointer;
	transition: transform .06s ease, box-shadow .12s ease;
}

.cj-ficha:hover  { box-shadow: 0 2px 10px rgba(15, 23, 42, .10); }
.cj-ficha:active { transform: scale(.985); }

.scp-caja.cj-mayorista .cj-ficha { border-left-color: var(--cj-may); }

.cj-ficha__n {
	font-weight: 600;
	line-height: 1.25;
	/* Dos líneas como máximo: los nombres largos no pueden descuadrar la
	   rejilla ni empujar el precio fuera de la ficha. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.cj-ficha__p {
	flex: 0 0 auto;
	font-weight: 700;
	white-space: nowrap;
	color: var(--cj-acento-2);
}

.scp-caja.cj-mayorista .cj-ficha__p { color: var(--cj-may); }

/* El precio de la otra lista, tachado y en gris CLARO: está de referencia,
   no compite con el que se va a cobrar. */
.cj-normal {
	display: block;
	font-size: .8em;
	font-weight: 600;
	color: #9aa5b1;
	text-decoration: line-through;
	text-decoration-thickness: 2px;
}

/* Sin tarifa en la lista de mayorista: el precio sale en 0 y la ficha se
   apaga, para que se vea que a ese producto le falta precio. */
.cj-ficha--sintarifa { opacity: .7; }
.cj-ficha--sintarifa .cj-ficha__p { color: var(--cj-suave); }

.cj-ficha--agotado {
	opacity: .55;
	border-left-color: var(--cj-suave);
}

/* Venta sencilla y Crear producto: siempre al principio, y con aspecto
   distinto para que no se confundan con un producto del catálogo. */
.cj-ficha--sencilla {
	border-style: dashed;
	border-left-width: 3px;
	border-left-style: solid;
	background: transparent;
	color: var(--cj-acento);
	font-weight: 700;
}

.cj-ficha--sencilla .cj-ficha__p { font-size: 1.4em; line-height: 1; }

/* ---- Carrito ---- */

.cj-carro {
	display: flex;
	flex-direction: column;
	min-height: 0;
	background: var(--cj-panel);
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	overflow: hidden;
}

/* ==================================================================
 * PESTAÑAS DE VENTA
 *
 * Varias ventas abiertas a la vez, encima del carrito. Cuando en el
 * mostrador se juntan dos clientes, el segundo no puede esperar a que el
 * primero decida: se abre otra pestaña y se atiende.
 *
 * Van ARRIBA del carrito y no en el menú lateral porque pertenecen al
 * carrito: cambiar de pestaña cambia lo que hay debajo, y el ojo tiene que
 * ver las dos cosas juntas.
 * ================================================================== */

.cj-pes {
	flex: 0 0 auto;
	display: flex;
	gap: 4px;
	padding: 6px 6px 0;
	overflow-x: auto;
	/* Que la tira se desplace sola en vez de estrujar las pestañas hasta que
	   no se lea ninguna: es el mismo error que aplastaba la lista de pedidos. */
	scrollbar-width: thin;
}

.cj-pes__b {
	flex: 0 0 auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: 2px 6px;
	max-width: 46%;
	padding: 7px 10px;
	border: 1px solid var(--cj-borde);
	border-bottom: 0;
	border-radius: 8px 8px 0 0;
	background: var(--cj-fondo);
	color: var(--cj-suave);
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.cj-pes__b:hover { color: var(--cj-texto); }

.cj-pes__b.esta-activa {
	background: var(--cj-panel);
	color: var(--cj-texto);
	border-color: var(--cj-acento);
	box-shadow: inset 0 3px 0 var(--cj-acento);
}

/* Una venta en lista mayorista se marca aunque no sea la que se está
   mirando: es lo que evita cobrarle a un cliente el precio del otro. */
.cj-pes__b.es-may { border-color: var(--cj-may); }
.cj-pes__b.es-may .cj-pes__t::after {
	content: " · MAY";
	color: var(--cj-may);
	font-size: .85em;
}

.cj-pes__t {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .86em;
	font-weight: 700;
}

.cj-pes__s {
	grid-column: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: .74em;
	opacity: .8;
}

.cj-pes__x {
	grid-row: 1 / span 2;
	grid-column: 2;
	padding: 0 4px;
	border-radius: 6px;
	font-size: 1.1em;
	line-height: 1;
	opacity: .55;
}

.cj-pes__x:hover { background: #fee2e2; color: var(--cj-may); opacity: 1; }

.cj-pes__mas {
	flex: 0 0 auto;
	align-self: stretch;
	padding: 0 14px;
	border: 1px dashed var(--cj-borde);
	border-bottom: 0;
	border-radius: 8px 8px 0 0;
	background: transparent;
	color: var(--cj-acento);
	font: inherit;
	font-size: 1.25em;
	font-weight: 700;
	line-height: 1;
	cursor: pointer;
}

.cj-pes__mas:hover { background: var(--cj-fondo); }

.cj-carro__lineas {
	flex: 1 1 auto;
	overflow-y: auto;
	min-height: 120px;
	padding: 8px;
	border-top: 1px solid var(--cj-borde);
}

/* La línea entera es el botón: se toca y se abre el editor de cantidad y
   precio. Antes llevaba +/− incrustados, pero en una tablet se pulsaban sin
   querer al deslizar la lista y robaban ancho a cada fila. */
.cj-linea {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	grid-template-areas: "nombre total quitar" "unit total quitar";
	align-items: center;
	gap: 2px 8px;
	padding: 10px 4px 10px 6px;
	border-bottom: 1px solid var(--cj-borde);
	cursor: pointer;
	border-radius: 8px;
}

.cj-linea:hover { background: var(--cj-fondo); }
.cj-linea__n {
	grid-area: nombre;
	font-size: 1.02em;
	font-weight: 700;
	line-height: 1.25;
}
.cj-linea__u { grid-area: unit; }
.cj-linea__t { grid-area: total; }

/* Quitar del carrito: discreto hasta que se necesita. Gris apagado, y solo
   se tiñe de rojo al pasar por encima, para que no compita con los datos. */
.cj-quita {
	grid-area: quitar;
	width: 30px;
	height: 30px;
	border: 0;
	border-radius: 8px;
	background: transparent;
	color: var(--cj-suave);
	font-size: 1.25em;
	line-height: 1;
	opacity: .5;
	cursor: pointer;
	transition: opacity .12s ease, background .12s ease;
}

.cj-linea:hover .cj-quita { opacity: 1; }
.cj-quita:hover { background: rgba(185, 28, 28, .12); color: var(--cj-may); opacity: 1; }

/* Etiquetas de renglón: de qué lista salió, o si es una venta suelta. */
.cj-etiq {
	display: inline-block;
	margin-left: 4px;
	padding: 0 5px;
	border-radius: 4px;
	background: var(--cj-may);
	color: #fff;
	font-size: .74em;
	font-weight: 700;
	letter-spacing: .3px;
	vertical-align: 1px;
}

.cj-etiq--man { background: var(--cj-suave); }
.scp-caja.cj-mayorista .cj-etiq { background: #fecaca; color: #7f1d1d; }

.cj-linea:last-child { border-bottom: 0; }

.cj-linea__n {
	font-size: .9em;
	line-height: 1.2;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.cj-linea__u {
	font-size: .92em;
	font-weight: 600;
	color: var(--cj-suave);
	white-space: nowrap;
}

.cj-linea__t { font-weight: 800; font-size: 1.06em; white-space: nowrap; }

/* Línea con el precio cambiado a mano: se marca para que quien cuadre la
   caja lo vea sin tener que abrir el pedido. */
.cj-linea--tocada .cj-linea__u { color: var(--cj-may); font-weight: 700; }
.cj-marca { color: var(--cj-may); }

.cj-carro__pie {
	border-top: 1px solid var(--cj-borde);
	padding: 10px;
	display: grid;
	gap: 8px;
	background: var(--cj-panel);
}

.cj-total {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	font-size: 1.05em;
}

.cj-total strong { font-size: 1.5em; }

/* Subtotal: la cifra de la que se parte cuando hay descuento. En gris y
   pequeña, porque la que se cobra es la de abajo. */
.cj-sub {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	font-size: .92em;
	color: var(--cj-suave);
}

.cj-cobrar {
	padding: 15px;
	border: 0;
	border-radius: var(--cj-radio);
	background: var(--cj-ok);
	color: #fff;
	font-size: 1.05em;
	font-weight: 700;
	cursor: pointer;
}

.cj-cobrar:disabled { background: #cbd5e1; cursor: not-allowed; }

.cj-vaciar {
	padding: 9px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: transparent;
	color: var(--cj-suave);
	cursor: pointer;
}

.cj-vacio {
	padding: 22px 12px;
	text-align: center;
	color: var(--cj-suave);
}

/* ---- Aviso flotante ---- */

.cj-aviso {
	position: fixed;
	left: 50%;
	bottom: 22px;
	transform: translateX(-50%);
	z-index: 9999;
	max-width: min(92vw, 460px);
	padding: 12px 18px;
	border-radius: 999px;
	background: #1f2937;
	color: #fff;
	font-weight: 600;
	box-shadow: 0 6px 24px rgba(0, 0, 0, .25);
}

.cj-aviso--ok     { background: var(--cj-ok); }
.cj-aviso--error  { background: var(--cj-may); }
.cj-aviso--espera { background: #b45309; }

/* ---- Diálogo de cobro ---- */

.cj-modal-fondo {
	position: fixed;
	inset: 0;
	z-index: 10000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
	background: rgba(15, 23, 42, .55);
}

.cj-modal {
	width: min(94vw, 420px);
	grid-template-columns: minmax(0, 1fr);
	max-height: 92vh;
	overflow-y: auto;
	background: var(--cj-panel);
	border-radius: 14px;
	padding: 18px;
	display: grid;
	gap: 12px;
	align-content: start;
	box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}

.cj-modal__t { margin: 0; font-size: 1.2em; line-height: 1.25; }

/* Los campos del modal heredaban el alto de la caja y se estiraban al alto
   de la fila del grid, quedando desalineados entre sí. */
.cj-modal .cj-campo input { width: 100%; }
.cj-modal .cj-campo { align-content: start; }

/* Atajos con los billetes de siempre: la mayoría de los cobros se resuelven
   con un toque, sin teclear nada. */
.cj-rapidos { display: flex; flex-wrap: wrap; gap: 6px; }

.cj-rapido {
	flex: 1 1 auto;
	padding: 10px 8px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	color: inherit;
	font-weight: 700;
	white-space: nowrap;
	cursor: pointer;
}

.cj-rapido:hover { border-color: var(--cj-acento); color: var(--cj-acento); }

.cj-campo { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; font-size: .9em; }

.cj-campo input {
	padding: 14px;
	font-size: 1.25em;
	font-weight: 700;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	color: inherit;
}

.cj-cambio {
	margin: 0;
	min-height: 1.4em;
	font-size: 1.15em;
	font-weight: 700;
	color: var(--cj-ok);
}

.cj-cambio--falta { color: var(--cj-may); }

.cj-modal__pie { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,2fr); gap: 8px; }
.cj-modal__pie3 { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr) minmax(0,1.4fr); gap: 8px; }
.cj-modal--cobro { width: min(94vw, 460px); }
/* El modal de cobro coge el foco al pulsar en una zona vacía (para que Enter
   confirme); no hace falta pintarle un marco por eso. */
.cj-modal--cobro:focus { outline: none; }

/* El importe manda: es lo que el cajero dice en voz alta y lo que el cliente
   comprueba. Tiene que leerse desde lejos y sin buscarlo. */
.cj-cifra {
	display: grid;
	gap: 2px;
	padding: 12px 14px;
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	text-align: center;
}

.cj-cifra__r { font-size: .82em; font-weight: 600; color: var(--cj-suave); text-transform: uppercase; letter-spacing: .5px; }
.cj-cifra__v { font-size: 2.1em; font-weight: 800; line-height: 1.1; }
.cj-cifra--cambio { background: #dcfce7; }
.cj-cifra--cambio .cj-cifra__r { color: #166534; }
.cj-cifra--cambio .cj-cifra__v { color: #15803d; }
.cj-cifra--falta { background: #fee2e2; }
.cj-cifra--falta .cj-cifra__r,
.cj-cifra--falta .cj-cifra__v { color: var(--cj-may); }

.cj-cobrar--grande { padding: 18px; font-size: 1.15em; }

.cj-check { display: flex; align-items: center; gap: 8px; font-weight: 600; cursor: pointer; }
.cj-check input { width: 20px; height: 20px; }

/* ---- Pedidos ---- */

.cj-pedidos { max-height: 52vh; overflow-y: auto; display: grid; gap: 6px; }

.cj-ped {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	align-items: center;
	gap: 10px;
	padding: 10px 12px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
}

.cj-ped__d b { font-size: 1.02em; }
.cj-ped__m { display: block; font-size: .82em; color: var(--cj-suave); }
.cj-ped__t { font-weight: 800; white-space: nowrap; }
.cj-modal__sub { margin: -6px 0 0; font-size: .88em; color: var(--cj-suave); }
.cj-modal--ancho { width: min(94vw, 560px); }

.cj-quitar {
	padding: 12px;
	border: 1px solid var(--cj-may);
	border-radius: var(--cj-radio);
	background: transparent;
	color: var(--cj-may);
	font-weight: 600;
	cursor: pointer;
}

/* ---- Editor de línea: cantidad y precio ---- */

.cj-edit { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 10px; }

.cj-paso { display: grid; grid-template-columns: auto minmax(0,1fr) auto; gap: 6px; }

.cj-paso button {
	width: 44px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	color: inherit;
	font-size: 1.3em;
	line-height: 1;
	cursor: pointer;
}

.cj-paso input { text-align: center; }

/* ---- Resultados de búsqueda dentro de un modal ---- */

.cj-result { max-height: 34vh; overflow-y: auto; display: grid; gap: 4px; }

.cj-res {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 10px;
	width: 100%;
	text-align: left;
	padding: 11px 12px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	color: inherit;
	font: inherit;
	cursor: pointer;
}

.cj-res:hover { background: var(--cj-panel); border-color: var(--cj-acento); }
.cj-res__n { min-width: 0; }
.cj-res__p { font-weight: 700; white-space: nowrap; }

.cj-elegido {
	padding: 10px;
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	display: grid;
	gap: 8px;
}

.cj-elegido__n { font-weight: 700; }
.cj-elegido__m { font-size: .86em; color: var(--cj-suave); }
.cj-oculto { display: none !important; }

/* ---- Botones auxiliares de la barra ---- */

.cj-aux {
	flex: 0 0 auto;
	padding: 12px 14px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-panel);
	color: var(--cj-texto);
	font: inherit;
	font-weight: 600;
	cursor: pointer;
}

.cj-aux:hover { border-color: var(--cj-acento); color: var(--cj-acento); }

.scp-caja__cargando {
	padding: 40px;
	text-align: center;
	color: var(--cj-suave);
}

/* ==================================================================
 * Pantalla estrecha
 *
 * Dos columnas en una tablet vertical dejan las dos inservibles, así que
 * el carrito pasa abajo y la rejilla se queda con todo el ancho.
 * ================================================================== */

@media (max-width: 900px) {
	.scp-caja { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; }
	.cj-nav {
		order: 2;
		flex-direction: row;
		width: auto;
		overflow-x: auto;
		padding: 4px;
	}
	.cj-nav__b { flex: 1 0 auto; padding: 8px 10px; font-size: .7em; }
	.cj-nav__b svg { width: 22px; height: 22px; }
	.cj-nav__b--fin { margin-top: 0; }
	.cj-principal { order: 1; padding: 8px; }
	.cj-cuerpo {
		grid-template-columns: 1fr;
	}
	/* Una sola columna: en un móvil, dos dejan el nombre ilegible. */
	.cj-lista {
		grid-template-columns: 1fr;
		max-height: 46vh;
	}
	.cj-carro__lineas { max-height: 30vh; }
	.cj-carro {
		position: sticky;
		bottom: 0;
	}
}

@media (max-width: 560px) {
	.scp-caja { padding: 8px; font-size: 15px; }
	.cj-lista { grid-template-columns: 1fr; }
	.cj-ficha { padding: 14px; }
	.cj-modo, .cj-buscar { padding: 13px 14px; }
	/* El dedo necesita más superficie que el ratón. */
	.cj-cobrar { padding: 17px; }
	/* En una pantalla estrecha, cantidad y precio no caben en dos columnas. */
	.cj-edit { grid-template-columns: minmax(0,1fr); }
	.cj-modal__pie3 { grid-template-columns: minmax(0,1fr) minmax(0,1fr); }
	.cj-modal__pie3 [data-cj="ok"] { grid-column: 1 / -1; }
}

/* ---- Modo oscuro ---- */

@media (prefers-color-scheme: dark) {
	.scp-caja {
		--cj-fondo: #0f172a;
		--cj-panel: #1e293b;
		--cj-borde: #334155;
		--cj-texto: #e2e8f0;
		--cj-suave: #94a3b8;
		--cj-acento: #14b8a6;
		--cj-acento-2: #5eead4;
	}
	.cj-estado { background: #334155; }
	.cj-linea__qty button { background: #0f172a; }
	.cj-aviso { background: #0b1220; }
}

/* ==================================================================
 * AÑADIDOS v2.6
 * ================================================================== */

/* ---- Títulos de modal: mayúscula, centrados y con separador ---- */

.cj-modal__t {
	margin: 0 0 2px;
	padding-bottom: 10px;
	border-bottom: 2px solid var(--cj-borde);
	font-size: 1.1em;
	font-weight: 800;
	letter-spacing: .6px;
	text-align: center;
	text-transform: uppercase;
}

.cj-modal__sub { text-align: center; }

/* ---- Interruptor (código de barras) ---- */

.cj-toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 10px 12px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	font-weight: 600;
}

.cj-sw {
	flex: 0 0 auto;
	width: 52px;
	height: 30px;
	padding: 3px;
	border: 0;
	border-radius: 999px;
	background: #cbd5e1;
	cursor: pointer;
	transition: background .15s ease;
}

.cj-sw__b {
	display: block;
	width: 24px;
	height: 24px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
	transition: transform .15s ease;
}

.cj-sw[aria-checked="true"] { background: var(--cj-acento); }
.cj-sw[aria-checked="true"] .cj-sw__b { transform: translateX(22px); }

/* ---- Los dos listados, uno al lado del otro ---- */

.cj-dos { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 10px; }

/* Cada lista con su color, para no equivocarse de campo. */
.cj-campo--normal span { color: var(--cj-acento); font-weight: 700; }
.cj-campo--may span    { color: var(--cj-may);    font-weight: 700; }
.cj-campo--may input   { border-color: #f2c2c2; }

/* ---- Fichas con y sin tarifa en mayorista ----
   Las que SÍ tienen precio destacan en blanco fuerte; las que no, se apagan
   sobre el fondo. Es lo que permite ver de un vistazo qué falta por tarifar. */

.scp-caja.cj-mayorista .cj-ficha {
	background: #fff;
	border-color: #e8b4b4;
	box-shadow: 0 1px 4px rgba(140, 30, 30, .10);
}

.scp-caja.cj-mayorista .cj-ficha--sintarifa {
	background: transparent;
	border-style: dashed;
	box-shadow: none;
	opacity: .62;
}

/* ---- Pantalla de pedidos, con acordeón ---- */

.cj-pantalla {
	position: absolute;
	inset: 0;
	z-index: 5;
	display: flex;
	flex-direction: column;
	background: var(--cj-fondo);
}

.cj-pantalla__cab {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 10px;
	border-bottom: 2px solid var(--cj-borde);
}

.cj-pantalla__t {
	flex: 1 1 auto;
	margin: 0;
	font-size: 1.05em;
	font-weight: 800;
	letter-spacing: .6px;
	text-transform: uppercase;
}

/*
 * LA LISTA DE PEDIDOS SE DESPLAZA; LAS FILAS NO SE ENCOGEN.
 *
 * `grid-auto-rows: max-content` no es adorno: sin él, con 31 pedidos las filas
 * se aplastaban de 47 px a 20 y el texto quedaba cortado por la mitad, una
 * encima de otra, sin barra de desplazamiento.
 *
 * El porqué es el gemelo vertical de la trampa del `min-width: auto`. Una
 * fila lleva `overflow: hidden`, y eso hace que su tamaño mínimo automático
 * pase a ser CERO. Cuando el contenido no cabe en una rejilla de altura fija,
 * las pistas `auto` pueden encogerse hasta ese mínimo — o sea, hasta nada—, y
 * el navegador prefiere apretarlas antes que desbordar. Con `max-content` la
 * pista se queda con la altura de su contenido, el conjunto desborda como debe
 * y `overflow-y: auto` hace su trabajo.
 *
 * `align-content: start` NO evitaba esto: se comprobó midiendo, y con él
 * puesto las filas seguían en 20 px.
 */
.cj-pantalla__cuerpo {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	padding: 10px;
	display: grid;
	gap: 6px;
	grid-auto-rows: max-content;
	align-content: start;
}

.cj-fila { border: 1px solid var(--cj-borde); border-radius: var(--cj-radio); background: var(--cj-panel); overflow: hidden; }
.cj-fila.esta-abierta { border-color: var(--cj-acento); }

.cj-fila__cab {
	display: grid;
	/* Nº · datos · insignias… · total. La columna elástica es la de los
	   datos: es la única que puede recortarse sin perder una cifra.
	   Las insignias NO tienen un número fijo —origen y lista siempre; TRANSF.
	   y la de Alegra solo a veces—, así que no se cuentan columnas: todo va en
	   UNA fila y cada hijo de más abre su columna a la derecha. Con cinco
	   columnas fijas, la sexta (Alegra) bajaba sola a otra línea. */
	grid-template-columns: auto minmax(0, 1fr);
	grid-auto-flow: column;
	grid-auto-columns: auto;
	align-items: center;
	gap: 12px;
	width: 100%;
	padding: 12px 14px;
	border: 0;
	background: transparent;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.cj-fila__cab:hover { background: var(--cj-fondo); }
.cj-fila__n { font-weight: 800; }
.cj-fila__m { font-size: .86em; color: var(--cj-suave); }
.cj-fila__t { font-weight: 800; white-space: nowrap; }

.cj-fila__e {
	padding: 2px 8px;
	border-radius: 999px;
	background: #e2e8f0;
	color: var(--cj-suave);
	font-size: .72em;
	font-weight: 800;
	letter-spacing: .4px;
}

.cj-fila__e.es-may { background: #fde2e2; color: var(--cj-may); }

/* Procedencia de la venta: esta caja, la registradora vieja o la web. */
.cj-fila__o {
	padding: 2px 8px;
	border-radius: 999px;
	font-size: .72em;
	font-weight: 800;
	letter-spacing: .4px;
	background: #e2e8f0;
	color: var(--cj-suave);
}

.cj-fila__o.es-caja { background: #dcfce7; color: #15803d; }
.cj-fila__o.es-pos  { background: #e0f2fe; color: #075985; }
.cj-fila__o.es-web  { background: #fef3c7; color: #92400e; }

/* Pagada por transferencia: ese dinero no está en el cajón. */
.cj-fila__p {
	padding: 2px 8px;
	border-radius: 999px;
	font-size: .72em;
	font-weight: 800;
	letter-spacing: .4px;
	white-space: nowrap;
	background: #ede9fe;
	color: #5b21b6;
}

.cj-det { padding: 0 14px 12px; border-top: 1px dashed var(--cj-borde); }
.cj-det__tabla { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: .92em; }
.cj-det__tabla th { text-align: left; padding: 6px 4px; border-bottom: 1px solid var(--cj-borde); font-size: .86em; color: var(--cj-suave); text-transform: uppercase; letter-spacing: .4px; }
.cj-det__tabla td { padding: 6px 4px; border-bottom: 1px solid var(--cj-borde); }
.cj-det__q, .cj-det__u, .cj-det__t { text-align: center; white-space: nowrap; }
.cj-det__tabla th:not(:first-child) { text-align: center; }
.cj-det__u b { color: var(--cj-may); font-size: .8em; }
.cj-det__imp { width: 100%; padding: 12px; }

.cj-aux--grande { padding: 18px 14px; font-size: 1.05em; }

/* La zona de trabajo necesita ser el marco de la pantalla de pedidos. */
.cj-principal { position: relative; }

@media (max-width: 560px) {
	.cj-dos { grid-template-columns: minmax(0,1fr); }
	/*
	 * En el móvil no caben en una fila. Tres renglones, con cualquier número
	 * de insignias: «#número … total» arriba, los datos debajo y las
	 * insignias al final, en las líneas que hagan falta. Con flex y `order`
	 * porque el orden de los hijos lo fija el HTML (y Alegra mete la suya
	 * antes del total). Todo hijo es insignia salvo que se diga otra cosa:
	 * así una insignia nueva de un módulo cae sola en su renglón.
	 */
	.cj-fila__cab { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
	.cj-fila__cab > * { order: 3; }
	.cj-fila__cab > .cj-fila__n { order: 0; }
	.cj-fila__cab > .cj-fila__t { order: 1; margin-left: auto; }
	.cj-fila__cab > .cj-fila__m { order: 2; flex: 1 1 100%; }
	.cj-modal__pie3 { grid-template-columns: minmax(0,1fr); }
}

/* ---- Descuento ---- */

.cj-desc {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	font-size: .92em;
	font-weight: 700;
	color: var(--cj-may);
}

.cj-tipos { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 8px; }

.cj-tipo {
	padding: 12px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
	color: inherit;
	font: inherit;
	font-weight: 700;
	cursor: pointer;
}

.cj-tipo.is-sel {
	background: var(--cj-acento);
	border-color: var(--cj-acento);
	color: #fff;
}

/* ---- Filtro de fechas en pedidos ---- */

.cj-fechas {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	margin-left: auto;
}

.cj-fechas label {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-size: .84em;
	font-weight: 600;
	color: var(--cj-suave);
}

.cj-fechas input {
	padding: 8px 10px;
	border: 1px solid var(--cj-borde);
	border-radius: 8px;
	background: var(--cj-panel);
	color: inherit;
	font: inherit;
	font-size: .92em;
}

.cj-resumen {
	padding: 8px 12px;
	margin: 0 10px;
	border-radius: var(--cj-radio);
	background: var(--cj-panel);
	border: 1px solid var(--cj-borde);
	font-weight: 700;
	text-align: center;
}

@media (max-width: 760px) {
	.cj-pantalla__cab { flex-wrap: wrap; }
	.cj-fechas { margin-left: 0; width: 100%; }
	.cj-fechas label { flex: 1 1 auto; }
	.cj-fechas input { width: 100%; }
}

/* ==================================================================
 * PANTALLA DE PIN
 *
 * Ocupa el viewport igual que la caja: instalada como aplicación no hay
 * barra de direcciones ni menú del sitio, así que esto es lo único que el
 * cajero ve al abrir sin sesión.
 * ================================================================== */

.scp-caja-login {
	position: fixed;
	inset: 0;
	z-index: 99990;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
	background: #0f172a;

	/* Mismos anuladores que la caja: los temas de bloques encogen y centran
	   a los hijos del contenido, incluso a un elemento fijo. */
	max-width: none !important;
	width: auto !important;
	margin: 0 !important;

	font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	box-sizing: border-box;
}

.scp-caja-login * { box-sizing: border-box; }

.cjl {
	width: min(92vw, 380px);
	display: grid;
	/*
	 * `minmax(0, 1fr)` y no `1fr` a secas.
	 *
	 * Los hijos de un grid llevan `min-width: auto`, o sea que NO se encogen
	 * por debajo de su ancho intrínseco. Un `<input>` sin atributo `size` pide
	 * unos 20 caracteres, y con esta fuente grande y el espaciado de letras
	 * eso son 485 px: la columna se estiraba a ese ancho y el campo, el título
	 * y el botón SE SALÍAN de la tarjeta de 380 px por la derecha.
	 */
	grid-template-columns: minmax(0, 1fr);
	gap: 14px;
	padding: 28px 24px;
	border-radius: 16px;
	background: #fff;
	box-shadow: 0 20px 60px rgba(0, 0, 0, .45);
	text-align: center;
}

.cjl__t { margin: 0; font-size: 1.35em; font-weight: 800; color: #1f2733; line-height: 1.2; }
.cjl__s { margin: -8px 0 4px; font-size: .95em; font-weight: 600; color: #6b7684; letter-spacing: .4px; text-transform: uppercase; }

.cjl__e {
	margin: 0;
	padding: 10px 12px;
	border-radius: 10px;
	background: #e0f2fe;
	color: #075985;
	font-weight: 600;
	font-size: .92em;
}

.cjl__e.es-malo { background: #fee2e2; color: #b91c1c; }

.cjl__c { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; text-align: left; min-width: 0; }
.cjl__c span { font-size: .86em; font-weight: 700; color: #6b7684; }

.cjl__c input {
	width: 100%;
	min-width: 0;
	padding: 16px;
	border: 1px solid #dfe3e8;
	border-radius: 10px;
	background: #f1f3f6;
	color: #1f2733;
	font: inherit;
	font-size: 1.6em;
	font-weight: 800;
	letter-spacing: .35em;
	text-align: center;
}

.cjl__c input:focus { outline: 2px solid #0f766e; outline-offset: -1px; }

.cjl__b {
	padding: 16px;
	border: 0;
	border-radius: 10px;
	background: #15803d;
	color: #fff;
	font: inherit;
	font-size: 1.05em;
	font-weight: 800;
	letter-spacing: .6px;
	cursor: pointer;
}

.cjl__b:hover { background: #166534; }
.cjl__b:disabled,
.cjl__c input:disabled {
	background: #e5e7eb;
	color: #9ca3af;
	cursor: not-allowed;
}
.cjl__b:disabled { box-shadow: none; }

/* ------------------------------------------------------------------
 * FONDO ANIMADO
 *
 * Tres manchas de color que se desplazan despacio detrás de la tarjeta.
 *
 * Solo se animan `transform` y nada más. Es la única propiedad (junto a
 * `opacity`) que el navegador puede mover sin rehacer el diseño ni volver a
 * pintar: lo resuelve la tarjeta gráfica con la capa ya dibujada. Animar
 * `left`, `width` o un `filter: blur()` obligaría a recalcular en cada
 * fotograma, y esto corre en la tablet del mostrador mientras el cajero
 * escribe.
 *
 * El desenfoque va en el propio degradado —un borde suave hasta
 * transparente— en vez de con `filter: blur()`, que es caro de verdad.
 *
 * Las manchas quedan DEBAJO de la tarjeta (`z-index`) y fuera del alcance
 * del ratón (`pointer-events: none`): son decoración, no deben estorbar a
 * quien intenta tocar el campo.
 * ------------------------------------------------------------------ */

.cjl-fondo {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
}

.cjl-fondo span {
	position: absolute;
	display: block;
	border-radius: 50%;
	/* Tamaño atado al lado mayor: en móvil no se ven tres bolas diminutas. */
	width: max(52vw, 52vh);
	height: max(52vw, 52vh);
	will-change: transform;
}

.cjl-fondo__a {
	top: -18%;
	left: -12%;
	background: radial-gradient(circle at 50% 50%, rgba(13, 148, 136, .55), rgba(13, 148, 136, 0) 68%);
	animation: cjl-vagar-a 19s ease-in-out infinite;
}

.cjl-fondo__b {
	right: -16%;
	bottom: -20%;
	background: radial-gradient(circle at 50% 50%, rgba(29, 78, 216, .5), rgba(29, 78, 216, 0) 68%);
	animation: cjl-vagar-b 23s ease-in-out infinite;
}

.cjl-fondo__c {
	top: 28%;
	right: 6%;
	width: max(34vw, 34vh);
	height: max(34vw, 34vh);
	background: radial-gradient(circle at 50% 50%, rgba(21, 128, 61, .42), rgba(21, 128, 61, 0) 70%);
	animation: cjl-vagar-c 27s ease-in-out infinite;
}

@keyframes cjl-vagar-a {
	0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
	50%      { transform: translate3d(14%, 10%, 0) scale(1.12); }
}
@keyframes cjl-vagar-b {
	0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
	50%      { transform: translate3d(-12%, -9%, 0) scale(1.08); }
}
@keyframes cjl-vagar-c {
	0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
	50%      { transform: translate3d(-9%, 12%, 0) scale(.9); }
}

/* La tarjeta, por encima del fondo. */
.scp-caja-login .cjl { position: relative; z-index: 1; }

/*
 * Quien pida menos animación, menos animación: se queda el color, se va el
 * movimiento. Hay quien se marea con esto, y no vale la pena discutirlo por
 * una pantalla de PIN.
 */
@media (prefers-reduced-motion: reduce) {
	.cjl-fondo span { animation: none; }
}

/* ==================================================================
 * BLINDAJE CONTRA DESBORDES
 *
 * Los hijos de un grid o un flex llevan `min-width: auto`: NO se encogen por
 * debajo de su ancho intrínseco. Y un `<input>` sin atributo `size` pide unos
 * 20 caracteres, que con una fuente grande son cientos de píxeles. El
 * resultado es que el campo estira su columna y se sale del contenedor,
 * arrastrando con él a los hermanos.
 *
 * Pasó en la pantalla de PIN: tarjeta de 380 px con el campo, el título y el
 * botón midiendo 485 y saliéndose por la derecha. Aquí se cierra para todos
 * los contenedores de la caja, para que no vuelva a aparecer al cambiar una
 * fuente o añadir un campo.
 * ================================================================== */

.scp-caja .cj-modal > *,
.scp-caja .cj-campo > *,
.scp-caja .cj-edit > *,
.scp-caja .cj-dos > *,
.scp-caja .cj-paso > *,
.scp-caja .cj-elegido > *,
.scp-caja .cj-barra > *,
.scp-caja .cj-fechas > *,
.scp-caja .cj-res > *,
.scp-caja .cj-linea > *,
.scp-caja .cj-fila__cab > *,
.scp-caja .cj-pantalla__cab > * { min-width: 0; }

/* Los campos ocupan su columna y no imponen su ancho intrínseco. */
.scp-caja input,
.scp-caja select { max-width: 100%; }

/* ==================================================================
 * PAGO MIXTO Y TRANSFERENCIAS EN EL COBRO (v2.17.0)
 *
 * Tres formas de pago en vez de dos. En Mixto aparece «Por transferencia»
 * y la parte en efectivo, que es sobre la que se calcula el cambio. Con
 * Transferencia o Mixto, la lista de las transferencias que ya llegaron por
 * ese valor, para elegir una (opcional).
 * ================================================================== */

.cj-tipos--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.cj-mixto {
	display: grid;
	grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
	align-items: end;
	gap: 8px 10px;
	padding: 10px 12px 12px;
	border: 1px solid #ddd6fe;
	border-radius: var(--cj-radio);
	background: #f5f3ff;
}

.cj-mixto .cj-campo--transf > span { color: #5b21b6; font-weight: 800; }
.cj-mixto .cj-campo--transf input { background: var(--cj-panel); border-color: #c4b5fd; }
.cj-mixto .cj-campo--transf input.es-mal { border-color: var(--cj-may); box-shadow: 0 0 0 3px rgba(185, 28, 28, .18); }

.cj-mixto__ef {
	display: grid;
	gap: 2px;
	padding: 8px 10px;
	border-radius: var(--cj-radio);
	background: #dcfce7;
	text-align: right;
}

.cj-mixto__ef span { font-size: .78em; font-weight: 800; letter-spacing: .4px; text-transform: uppercase; color: #166534; }
.cj-mixto__ef strong { font-size: 1.35em; font-weight: 900; line-height: 1.15; color: #15803d; font-variant-numeric: tabular-nums; white-space: nowrap; }

.cj-mixto__error {
	grid-column: 1 / -1;
	margin: 0;
	padding: 8px 10px;
	border-radius: 8px;
	background: #fee2e2;
	color: var(--cj-may);
	font-size: .88em;
	font-weight: 700;
	line-height: 1.35;
}

/* Transferencias que ya llegaron por ese valor. */
.cj-cand {
	display: grid;
	gap: 8px;
	padding: 10px 12px 12px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-fondo);
}

.cj-cand__cab { display: flex; align-items: center; gap: 8px; }
.cj-cand__t { flex: 1 1 auto; min-width: 0; font-size: .8em; font-weight: 800; letter-spacing: .4px; text-transform: uppercase; color: var(--cj-suave); }

.cj-cand__spin {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	border: 2.5px solid var(--cj-borde);
	border-top-color: var(--cj-acento);
	animation: cj-girar .75s linear infinite;
}

@keyframes cj-girar { to { transform: rotate(360deg); } }

.cj-cand__lista { display: grid; gap: 6px; max-height: 30vh; overflow-y: auto; }
.cj-cand__lista:empty { display: none; }

.cj-cand__i {
	display: grid;
	grid-template-columns: 22px minmax(0, 1fr) auto;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 10px 12px;
	border: 1px solid var(--cj-borde);
	border-radius: var(--cj-radio);
	background: var(--cj-panel);
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.cj-cand__i:hover { border-color: var(--cj-acento); }
.cj-cand__i.is-sel { border-color: var(--cj-acento); box-shadow: 0 0 0 2px var(--cj-acento) inset; }

.cj-cand__marca {
	width: 20px;
	height: 20px;
	border: 2px solid var(--cj-borde);
	border-radius: 50%;
	background: var(--cj-panel);
}

.cj-cand__i.is-sel .cj-cand__marca {
	border-color: var(--cj-acento);
	background: var(--cj-acento);
	box-shadow: inset 0 0 0 3px var(--cj-panel);
}

.cj-cand__d { display: grid; gap: 1px; min-width: 0; }
.cj-cand__v { font-size: 1.05em; font-weight: 900; font-variant-numeric: tabular-nums; }
.cj-cand__q { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .84em; font-weight: 600; color: var(--cj-suave); text-transform: uppercase; }
.cj-cand__h { display: grid; justify-items: end; gap: 1px; font-size: .86em; font-weight: 700; white-space: nowrap; }
.cj-cand__h small { font-size: .82em; font-weight: 600; color: var(--cj-suave); }

.cj-cand__nota { margin: 0; font-size: .84em; line-height: 1.35; color: var(--cj-suave); }
.cj-cand__nota.es-ok { color: var(--cj-ok); font-weight: 700; }

/* Pedidos: la insignia del mixto y su reparto en el detalle. */
.cj-fila__p--mixto { background: #e0e7ff; color: #3730a3; }
.cj-det__pago { margin: 0 0 8px; font-size: .9em; font-weight: 700; color: var(--cj-suave); }

@media (max-width: 560px) {
	.cj-mixto { grid-template-columns: minmax(0, 1fr); }
	.cj-mixto__ef { display: flex; align-items: baseline; justify-content: space-between; }
	.cj-tipos--3 .cj-tipo { padding: 12px 4px; }
}

@media (prefers-color-scheme: dark) {
	.cj-mixto { background: #1e1b3a; border-color: #4c1d95; }
	.cj-mixto .cj-campo--transf > span { color: #c4b5fd; }
	.cj-mixto .cj-campo--transf input { border-color: #6d28d9; }
	.cj-mixto__ef { background: #0f2f1d; }
	.cj-mixto__ef span { color: #86efac; }
	.cj-mixto__ef strong { color: #4ade80; }
	.cj-mixto__error { background: #3b1114; color: #fca5a5; }
	.cj-fila__p--mixto { background: #312e81; color: #c7d2fe; }
}

@media (prefers-reduced-motion: reduce) {
	.cj-cand__spin { animation-duration: 1.6s; }
}

.scp-caja .cj-mixto > *,
.scp-caja .cj-cand__i > * { min-width: 0; }

/* ==================================================================
 * v3.3.0 — Piezas de formulario compartidas (crear producto, SAMIT)
 * ================================================================== */

.cj-modal--crear { width: min(94vw, 480px); }

/* Grupo con título pequeño (IVA, cantidad…). */
.cj-grupo { display: grid; gap: 8px; }
.cj-grupo__t { font-size: .9em; font-weight: 600; }
.cj-grupo__t small { font-weight: 400; color: var(--cj-suave); }
.cj-grupo--fila { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }

/* Botones de opción («chips»): uno elegido a la vez. */
.cj-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.cj-chip {
	flex: 1 1 auto; min-width: 72px; padding: 10px 12px;
	border: 1.5px solid var(--cj-borde); border-radius: 999px;
	background: var(--cj-panel); color: var(--cj-texto);
	font: inherit; font-size: .9em; font-weight: 700; cursor: pointer;
	transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.cj-chip:hover { border-color: var(--cj-acento); }
.cj-chip[aria-checked="true"] { background: var(--cj-acento); border-color: var(--cj-acento); color: #fff; }
.cj-chip small { font-weight: 600; opacity: .75; }
.cj-chip:focus-visible, .cj-paso__b:focus-visible { outline: 2px solid var(--cj-acento); outline-offset: 2px; }

/* Cantidad con − / +. */
.cj-paso { display: inline-flex; align-items: stretch; border: 1px solid var(--cj-borde); border-radius: var(--cj-radio); overflow: hidden; background: var(--cj-fondo); }
.cj-paso__b { width: 46px; border: 0; background: var(--cj-panel); color: var(--cj-texto); font-size: 1.4em; font-weight: 700; cursor: pointer; }
.cj-paso__b:hover { background: var(--cj-fondo); color: var(--cj-acento); }
.cj-paso input { width: 64px; padding: 10px 4px; border: 0; border-left: 1px solid var(--cj-borde); border-right: 1px solid var(--cj-borde); background: var(--cj-fondo); color: inherit; font-size: 1.2em; font-weight: 700; text-align: center; }

/* Atajos de teclado en los botones (se ocultan en pantallas táctiles). */
.scp-caja kbd {
	display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 5px;
	background: rgba(0, 0, 0, .12); font: 600 .72em/1.5 system-ui, sans-serif; vertical-align: middle;
}
.cj-cobrar kbd { background: rgba(255, 255, 255, .22); }
@media (pointer: coarse) { .scp-caja kbd { display: none; } }
