/**
 * Estilos públicos.
 *
 * Deliberadamente neutros: heredan tipografía y color del tema para no
 * chocar con el diseño de la tienda.
 *
 * Los colores que la tienda puede cambiar desde Ajustes van por variable con
 * su valor actual como respaldo: sin configurar nada, el resultado es
 * exactamente el de siempre.
 */

.odr-bulk-table-wrap {
	margin: 1.25rem 0;
}

.odr-bulk-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.95em;
}

.odr-bulk-table caption {
	text-align: left;
	font-weight: 600;
	padding-bottom: 0.4rem;
}

.odr-bulk-table th,
.odr-bulk-table td {
	padding: 0.5rem 0.75rem;
	border: 1px solid currentColor;
	border-color: rgba( 0, 0, 0, 0.12 );
	text-align: left;
}

.odr-bulk-table thead th {
	background: var( --odr-table-head, rgba( 0, 0, 0, 0.04 ) );
	font-weight: 600;
}

.odr-savings th,
.odr-savings td {
	font-weight: 600;
}

.odr-badge-sale {
	white-space: nowrap;
}

/* --- Regalos automáticos ------------------------------------------------ */

/*
 * El regalo tiene que leerse como algo distinto de lo que se paga, sin
 * gritar: color propio en la etiqueta y el resto heredado del tema, que es
 * quien manda en la tipografía del carrito.
 *
 * La etiqueta va en su propia línea, encima del nombre. Al lado del nombre
 * competía por el ancho de la columna y empujaba los selectores fuera.
 */
.odr-gift-badge {
	display: block;
	width: fit-content;
	margin: 0 0 0.25em;
	padding: 0.1em 0.5em;
	border-radius: 3px;
	background: var( --odr-accent, #2e7d32 );
	color: var( --odr-accent-text, #fff );
	font-size: 0.7em;
	font-weight: 700;
	line-height: 1.7;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	white-space: nowrap;
}

/*
 * El nombre va en línea, no en bloque.
 *
 * cart.php concatena un `&nbsp;` al nombre cuando la línea no tiene enlace —y
 * la del regalo no lo tiene—. Es texto pelado dentro de la celda: no hay
 * filtro de PHP que lo alcance ni elemento propio al que apuntar desde aquí.
 * Con el nombre en bloque, ese espacio caía detrás en una línea propia y
 * abría un hueco entre el producto y el aviso de que falta elegir.
 *
 * En línea el espacio se queda pegado al nombre, que es donde no se ve. Y no
 * hace falta que el nombre sea bloque para que el aviso baje: quien va en
 * bloque es el selector, que ya lo es.
 */
.odr-gift-name {
	display: inline;
}

.odr-gift-free {
	color: var( --odr-accent, #2e7d32 );
	font-weight: 600;
	white-space: nowrap;
}

/* El precio unitario del regalo no repite «Gratis»: basta un guion. */
.odr-gift-dash {
	opacity: 0.45;
}

.odr-gift-qty {
	display: inline-block;
	opacity: 0.6;
	white-space: nowrap;
}

/*
 * El bloque de elección, bajo el nombre.
 *
 * Ya no encierra un formulario: los desplegables se fueron al modal, así que
 * aquí solo queda decir qué falta y dar la puerta para resolverlo. Sin marco
 * ni fondo —un recuadro dentro de la celda peleaba con el borde de la propia
 * tabla y hacía que la fila del regalo pareciera un panel pegado encima—.
 * Lo que separa esto del nombre es el aire y el color del aviso, no una caja.
 */
.odr-gift-chooser {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5em 0.75em;
	max-width: 100%;
	margin: 0.45em 0 0;
	padding: 0;
	border: 0;
	background: none;
	box-sizing: border-box;
}

/*
 * Muchos temas resetean <form> dentro de .woocommerce table, y esa regla gana
 * por especificidad a una clase suelta: dos regalos iguales salían distintos.
 * Repetir la clase sube la especificidad sin llegar a !important.
 */
.odr-gift-chooser.odr-gift-chooser {
	margin: 0.45em 0 0;
	padding: 0;
	border: 0;
	background: none;
}

.odr-gift-chooser__field {
	display: flex;
	flex-direction: column;
	gap: 0.3em;
	margin: 0;
	width: 100%;
}

/*
 * Las etiquetas son rótulos, no titulares: en versalitas pequeñas se leen de
 * un vistazo y dejan que el peso visual se lo lleve el desplegable, que es
 * donde hay que decidir.
 */
.odr-gift-chooser__label {
	font-size: 0.72em;
	font-weight: 600;
	line-height: 1.4;
	opacity: 0.6;
	text-align: left;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/*
 * Todos los desplegables miden lo mismo y ocupan el ancho: con anchos
 * distintos por el largo de cada opción, la columna quedaba en zigzag.
 */
.odr-gift-chooser__select {
	display: block;
	width: 100%;
	max-width: 100%;
	min-height: 44px;
	margin: 0;
	padding: 0.55em 2.4em 0.55em 0.8em;
	border: 1px solid rgba( 0, 0, 0, 0.12 );
	border-radius: 8px;
	/*
	 * Relleno gris claro en vez de blanco sobre blanco.
	 *
	 * Con el fondo del modal blanco, lo unico que dibujaba el campo era su
	 * borde, asi que para que se viera habia que subirle el contraste al
	 * borde, y un borde oscuro alrededor de un campo vacio ya se lee como un
	 * aviso. Con el relleno el campo se ve solo y el borde puede ser casi
	 * invisible: se distingue por la forma, no por una linea de color.
	 */
	background-color: rgba( 0, 0, 0, 0.03 );
	color: inherit;
	font-size: 0.9em;
	font-family: inherit;
	line-height: 1.4;
	height: auto;
	box-sizing: border-box;
	/*
	 * La flecha va dibujada aquí y no la pone el navegador.
	 *
	 * La nativa es un bloque gris con su propio relieve que no se parece a
	 * nada más del modal: al lado de las tarjetas y del botón verde, los dos
	 * desplegables eran lo único que seguía teniendo aspecto de formulario de
	 * sistema. Con appearance:none la caja es nuestra y la flecha es una
	 * marca fina, del mismo gris que el texto.
	 */
	appearance: none;
	-webkit-appearance: none;
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23333' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 0.7em center;
	background-size: 16px 16px;
	cursor: pointer;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.odr-gift-chooser__select:hover {
	border-color: rgba( 0, 0, 0, 0.22 );
	background-color: rgba( 0, 0, 0, 0.05 );
}

/*
 * El foco, en gris oscuro y no en el color de la tienda.
 *
 * En verde se confundia con la tarjeta elegida, que usa ese mismo verde para
 * decir «esto es lo que te llevas»: al tabular parecia que el desplegable
 * quedaba seleccionado igual que el regalo. Un borde oscuro y fino dice donde
 * esta el cursor sin significar nada mas.
 */
.odr-gift-chooser__select:focus-visible {
	border-color: rgba( 0, 0, 0, 0.55 );
	outline: 1px solid rgba( 0, 0, 0, 0.55 );
	outline-offset: 0;
	background-color: #fff;
}

/*
 * Mientras dice «Elige…» el texto va en gris: es un hueco por rellenar, no un
 * valor ya decidido. La marca la pone el propio campo pendiente, que es quien
 * sabe si se ha elegido algo —los select no son required, asi que :invalid no
 * casaria nunca—, y se quita en cuanto hay valor.
 */
.odr-gift-chooser__field.is-missing .odr-gift-chooser__select {
	color: rgba( 0, 0, 0, 0.5 );
}

/* Las opciones desplegadas se leen siempre en negro, aunque el campo este gris. */
.odr-gift-chooser__select option {
	color: initial;
}

/*
 * Lo que falta por elegir no se marca en rojo.
 *
 * El rojo es para lo que esta mal, y un campo que nadie ha tocado todavia no
 * esta mal: al abrir el modal, con los dos desplegables vacios, la pantalla
 * salia con dos avisos rojos antes de que el cliente hubiera hecho nada. Lo
 * que falta ya se dice en gris con el «Elige…», y si se intenta guardar sin
 * elegir, el aviso de arriba lo explica con palabras.
 */

/*
 * Ya elegido: no queda recuadro ni desplegables, solo el botón de volver a
 * elegir. Lo decidido se lee en el nombre de la línea.
 *
 * El botón va DEBAJO del nombre, no a su lado. Al lado empujaba el nombre
 * hacia la izquierda y, en cuanto el producto tenía un nombre largo, partía
 * la línea y dejaba el botón descolgado a media altura. Debajo ocupa su
 * propio renglón y la columna se lee de arriba abajo: etiqueta, regalo,
 * cambiarlo. Es además donde está el botón cuando aún falta elegir, así que
 * no se mueve de sitio al pasar de un estado al otro.
 */
.odr-gift-chooser.odr-gift-chooser.is-chosen {
	display: flex;
	align-items: flex-start;
	/*
	 * En su propio renglón, no al lado del nombre.
	 *
	 * `display: flex` por sí solo no bastaba: el nombre va en línea —tiene que
	 * ir, para tragarse el `&nbsp;` que cart.php le pega detrás—, así que el
	 * botón se colocaba a su derecha y, con un nombre largo, la línea se
	 * partía y el botón quedaba descolgado. `clear` no sirve aquí porque nada
	 * flota: lo que hace bajar el bloque es ocupar el ancho entero.
	 */
	width: 100%;
	max-width: none;
	margin: 0.4em 0 0;
	padding: 0;
	border: 0;
	background: none;
}

/*
 * Reiniciar es una salida, no una acción principal: discreta, pero un botón.
 *
 * Antes era un SVG suelto al 50 % de opacidad, sin marco y sin texto. Colgaba
 * bajo el nombre como si fuera decoración —o un icono de «cargando»— y no
 * habia forma de saber que se podia pulsar ni que hacia sin dejar el raton
 * encima esperando el title. Ahora lleva marco, texto visible y el area de
 * pulsacion que pide un dedo.
 */
.odr-gift-reset {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.4em;
	min-height: 28px;
	margin: 0;
	padding: 0.3em 0.7em;
	border: 1px solid rgba( 0, 0, 0, 0.2 );
	border-radius: 4px;
	background: transparent;
	color: inherit;
	font-size: 0.78em;
	font-weight: 600;
	line-height: 1.3;
	text-decoration: none;
	opacity: 0.75;
	cursor: pointer;
	transition: opacity 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}

.odr-gift-reset:hover,
.odr-gift-reset:focus-visible {
	border-color: currentColor;
	background: rgba( 0, 0, 0, 0.04 );
	opacity: 1;
}

/* El foco de teclado nunca se hereda del tema: aquí se ve siempre. */
.odr-gift-reset:focus-visible {
	outline: 2px solid #2271b1;
	outline-offset: 1px;
}

.odr-gift-reset__icon {
	display: block;
	flex: none;
}

/*
 * El texto se cae solo en pantallas muy estrechas. Ahi el icono se queda solo,
 * pero conserva marco y tamaño, que es lo que lo hace reconocible como boton.
 *
 * El corte estaba en 480px, pensando en la columna estrecha de la tabla de
 * escritorio; pero en movil WooCommerce apila la tabla y la celda pasa a
 * ocupar el ancho entero, asi que a 390px se escondia un texto que cabia de
 * sobra y quedaba un boton con un icono suelto que no dice que hace.
 */
@media ( max-width: 360px ) {
	.odr-gift-reset__text {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		overflow: hidden;
		clip: rect( 0, 0, 0, 0 );
		white-space: nowrap;
		border: 0;
	}

	.odr-gift-reset {
		gap: 0;
		padding: 0.3em 0.45em;
	}
}

/*
 * Falta elegir: solo el botón, debajo del nombre del regalo.
 *
 * El botón arranca del mismo margen que el nombre, que es lo que lo ata a
 * este producto y no al de al lado.
 *
 * Sin marco ni fondo: en una celda de tabla cualquier caja compite con los
 * bordes que ya dibuja el tema, y la fila del regalo acababa pareciendo un
 * panel pegado encima.
 */
.odr-gift-chooser.odr-gift-chooser.is-pending {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.5em;
	border: 0;
	background: none;
}

/*
 * El formulario ocupa su propia línea, siempre.
 *
 * Muchos temas dejan el <form> de la celda en `display: inline` o lo meten en
 * un contenedor flex junto al nombre, y entonces el botón se sube a la misma
 * línea: el nombre del regalo y el botón quedaban lado a lado, apretados
 * contra el ancho de la columna. `width: 100%` y el salto de línea lo bajan
 * sin depender de lo que haga el tema con el nombre.
 */
/*
 * La caja que envuelve el nombre y el botón.
 *
 * Existe por los temas que ponen la celda del producto en `display: flex` o
 * `grid`: ahí cada hijo directo es un ítem que se coloca en su propia columna,
 * así que el nombre y el botón salían lado a lado por mucho que el formulario
 * fuera un bloque —y `flex-basis: 100%` solo lo arregla si el padre trae
 * `flex-wrap`, que no es lo normal—. Envueltos, la celda ve UN solo ítem y
 * dentro de él manda esta columna.
 *
 * El `width: 100%` es para el caso contrario: una celda flex reparte el ancho
 * entre sus ítems y esta caja se quedaría estrecha, partiendo el nombre en
 * una palabra por línea.
 */
.odr-gift-cell {
	/*
	 * Bloque, NO flex.
	 *
	 * En flex, el `&nbsp;` que cart.php pega detrás del nombre —lo concatena
	 * él, fuera de nuestro filtro, cuando la línea no tiene enlace, y la del
	 * regalo no lo tiene— deja de ser un espacio y pasa a ser un ítem más de
	 * la columna, con su propia línea de alto: por eso salía un hueco entre el
	 * nombre y el botón. En flujo de bloques ese espacio se queda pegado al
	 * final del nombre, que es donde no ocupa nada.
	 *
	 * Apilar no hace falta pedirlo: el badge y el formulario ya son bloques y
	 * el nombre es inline, así que caen uno debajo de otro solos.
	 */
	display: block;
	flex: 1 1 100%;
	grid-column: 1 / -1;
	width: 100%;
	min-width: 0;
	/*
	 * Debajo de «Producto:», no a su lado.
	 *
	 * En movil WooCommerce apila la tabla y le pone a cada celda su rotulo con
	 * `content: attr( data-title )` flotado a la izquierda. Nuestra etiqueta
	 * «Regalo gratis» es un bloque, y un bloque no aparta a un flotante: se
	 * metia debajo y las dos se pisaban, que es lo que se veia en la fila del
	 * regalo. Con `clear` la celda entera empieza bajo el rotulo.
	 */
	clear: both;
	/*
	 * Y alineada a la izquierda, aunque el tema alinee la celda a la derecha.
	 *
	 * En la tabla apilada los valores van a la derecha, contra su rotulo. Eso
	 * vale para un precio —dos palabras— pero aqui dentro hay tres cosas
	 * apiladas: la etiqueta, el nombre y el boton. La etiqueta y el boton se
	 * ajustan a su contenido y quedaban a la izquierda, mientras el nombre se
	 * iba al borde derecho: las tres piezas de un mismo regalo, cada una por
	 * su lado. Todas a la izquierda se leen como un bloque.
	 */
	text-align: left;
}

.odr-gift-chooser.odr-gift-chooser {
	width: 100%;
}

/*
 * Mientras la elección viaja al servidor.
 *
 * Ya no hay recarga, así que sin esto no pasa nada visible entre pulsar
 * «Agregar regalo» y ver la fila cambiada: en una conexión lenta parece que el
 * botón no ha respondido y se pulsa otra vez.
 */
.odr-gift-cell.is-busy {
	opacity: 0.55;
	pointer-events: none;
}

/*
 * El botón que abre el modal.
 *
 * Es un <a> con ancla, no un <button>: sin JS lleva al diálogo, que sigue
 * siendo un formulario visible más abajo. Con JS el click se intercepta.
 *
 * Va en el color de la tienda y no en el rojo del aviso: la acción no es el
 * problema, es lo que lo resuelve. Y sólido, no fantasma, porque es lo único
 * que hay que pulsar en toda esa fila.
 */
.odr-gift-choose {
	display: inline-flex;
	align-items: center;
	gap: 0.45em;
	min-height: 34px;
	padding: 0.45em 0.95em;
	border: 0;
	border-radius: 5px;
	background: transparent;
	box-shadow: inset 0 0 0 1.5px var( --odr-accent, #2e7d32 );
	color: var( --odr-accent, #2e7d32 );
	font-size: 0.82em;
	font-weight: 600;
	line-height: 1.3;
	white-space: nowrap;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

/*
 * El subrayado del tema, fuera.
 *
 * Es un <a>, así que casi cualquier tema le pinta un subrayado —y algunos en
 * el color del enlace—, y sobre un botón eso se lee como un enlace roto
 * dentro de una caja. El color se repite en cada estado porque el `:visited`
 * del tema, si no, lo tiñe de morado en cuanto se ha abierto una vez.
 */
.odr-gift-choose,
.odr-gift-choose:link,
.odr-gift-choose:visited,
.odr-gift-choose:hover,
.odr-gift-choose:focus,
.odr-gift-choose:active {
	color: var( --odr-accent, #2e7d32 );
	text-decoration: none;
}

/*
 * Contorno y no relleno: encima está el badge de «regalo gratis», sólido y en
 * ese mismo color. Dos bloques macizos del mismo verde, uno bajo el otro,
 * hacían ver dos etiquetas en vez de una etiqueta y un botón. El contorno
 * comparte el color de la tienda pero se lee como algo que se pulsa.
 */
.odr-gift-choose:hover,
.odr-gift-choose:focus-visible {
	/* Gris para quien no tenga color-mix: el contorno ya lleva el color. */
	background: rgba( 0, 0, 0, 0.05 );
	background: color-mix( in srgb, var( --odr-accent, #2e7d32 ) 10%, transparent );
}

.odr-gift-choose:focus-visible {
	outline: 2px solid var( --odr-accent, #2e7d32 );
	outline-offset: 2px;
}

.odr-gift-icon {
	display: block;
	flex: none;
	opacity: 0.9;
}

/*
 * El diálogo.
 *
 * Sin JS —o sin <dialog> en el navegador— queda como un bloque normal debajo
 * del botón: se ve, se rellena y se envía. Es el estado por defecto, y el JS
 * lo esconde marcando el <html>. Al revés (oculto por defecto) un navegador
 * sin JS dejaba al cliente sin forma de elegir su regalo.
 */
.odr-gift-modal {
	display: block;
	width: 100%;
	max-width: 22em;
	margin: 0.6em 0 0;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
}

.odr-gift-js .odr-gift-modal:not( [open] ) {
	display: none;
}

.odr-gift-js .odr-gift-modal[open] {
	position: fixed;
	inset: 0;
	width: min( 46em, calc( 100vw - 2rem ) );
	max-width: none;
	max-height: calc( 100vh - 2rem );
	margin: auto;
	overflow: visible;
}

.odr-gift-modal::backdrop {
	background: rgba( 17, 20, 24, 0.55 );
}

/*
 * La caja.
 *
 * Cabecera en el color de la tienda con el lazo: nada más abrirse se sabe que
 * esto va del regalo y no de un formulario más del carrito. El resto, blanco
 * y tranquilo, que es donde hay que decidir.
 */
.odr-gift-modal__box {
	position: relative;
	display: flex;
	flex-direction: column;
	max-height: calc( 100vh - 2rem );
	overflow: hidden;
	border-radius: 10px;
	background: #fff;
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.22 );
	text-align: left;
	outline: 0;
	/*
	 * El interlineado lo fija la caja, no el tema.
	 *
	 * El titulo y la frase son <p>, y hay temas que les ponen line-height 1.7
	 * y margenes de 1.5em: la cabecera crecia por su cuenta, el aspa —que mide
	 * lo que mide— se quedaba arriba descolgada del texto, y entre la linea de
	 * la cabecera y la primera tarjeta salia una franja vacia.
	 */
	line-height: 1.4;
}

/*
 * La cabecera: una barra de alto fijo con el lazo, el título y el aspa.
 *
 * Antes el alto lo decidía el padding del título mientras el aspa media 44px
 * por su cuenta, así que ninguna de las dos cuadraba con la otra: el aspa se
 * salía por arriba y el título quedaba descentrado respecto a ella. Ahora la
 * barra manda —alto propio y todo centrado dentro— y el aspa se coloca sobre
 * ella ocupando ese mismo alto.
 */
.odr-gift-modal__title {
	display: flex;
	flex: none;
	align-items: center;
	gap: 0.55em;
	box-sizing: border-box;
	height: 52px;
	margin: 0 !important;
	padding: 0 52px 0 1.15em;
	border-bottom: 1px solid rgba( 0, 0, 0, 0.09 );
	background: #fff;
	color: inherit;
	font-size: 1.02em;
	font-weight: 700;
	line-height: 1.2;
}

/* El lazo se queda con el color de la tienda; el título, con el del texto. */
.odr-gift-modal__title .odr-gift-icon {
	color: var( --odr-accent, #2e7d32 );
}

/* El lazo no se estira ni se encoge con el título. */
.odr-gift-modal__title .odr-gift-icon {
	flex: none;
	opacity: 0.9;
}

.odr-gift-modal__title > span {
	min-width: 0;
}

/*
 * La frase que explica por qué se abrió el modal.
 *
 * Sin ella el diálogo aparece solo al cargar el carrito y quien no recuerde
 * la promoción ve una parrilla de productos sin saber qué se le está
 * ofreciendo ni por qué le interrumpe.
 */
.odr-gift-modal__lead {
	flex: none;
	padding: 0.95em 1.15em 0;
	font-size: 0.9em;
	line-height: 1.45;
	opacity: 0.75;
	margin: 0 !important;
	text-align: center;
}

.odr-gift-modal__fields {
	display: flex;
	flex-direction: column;
	gap: 1.1em;
	padding: 0.85em 1.15em 1.15em;
	overflow-y: auto;
	min-height: 0;
}

/*
 * Los regalos posibles, en parrilla de fotos.
 *
 * Un desplegable obligaba a leer nombres de siete palabras casi idénticos
 * para separar dos frascos que en la foto se distinguen sin leer nada. Las
 * columnas se calculan solas: en el ancho del modal caben tres o cuatro, y en
 * móvil bajan a dos sin media queries.
 */
.odr-gift-cards {
	display: grid;
	/*
	 * «auto-fit» y no «auto-fill»: con dos regalos en un modal ancho,
	 * auto-fill reservaba tambien las columnas vacias que cabrian y dejaba
	 * las dos tarjetas apretadas contra el borde izquierdo, con el hueco
	 * sobrante a la derecha. Con auto-fit las columnas de mas se colapsan y
	 * lo que hay queda centrado.
	 */
	grid-template-columns: repeat( auto-fit, minmax( 190px, 220px ) );
	justify-content: center;
	gap: 0.9em;
}

/*
 * Cada tarjeta es un <label> con su radio dentro: se pulsa entera, no solo el
 * cuadrito. En una parrilla de fotos, apuntar a un control de 16px es lo que
 * convierte una elección de un gesto en tres intentos.
 */
.odr-gift-card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.4em;
	margin: 0;
	padding: 0.6em 0.6em 0.85em;
	border: 1px solid rgba( 0, 0, 0, 0.12 );
	border-radius: 8px;
	background: #fff;
	text-align: center;
	cursor: pointer;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.odr-gift-card:hover {
	border-color: rgba( 0, 0, 0, 0.28 );
}

/*
 * El radio no se ve, pero sigue estando.
 *
 * En una parrilla de fotos el circulito de la esquina no aporta nada: la
 * tarjeta entera ya es el control, se pulsa donde se mire, y lo que dice cual
 * esta elegida es el marco de color. Dibujar ademas el radio deja dos marcas
 * de seleccion para una sola eleccion, y encima la del navegador —azul— peleaba
 * con el verde de la tienda.
 *
 * Se esconde con la tecnica de siempre, no con display:none: asi sigue en el
 * recorrido del tabulador y el lector de pantalla lo sigue anunciando como el
 * grupo de radios que es, que es justo lo que hace falta para elegir sin raton.
 */
.odr-gift-card__input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	overflow: hidden;
	clip: rect( 0 0 0 0 );
	clip-path: inset( 50% );
	white-space: nowrap;
}

/*
 * El alto lo manda la caja, no la imagen.
 *
 * Ponérselo a la <img> no funciona: WooCommerce trae `.woocommerce img {
 * height: auto }` con la misma especificidad que cualquier selector nuestro de
 * elemento, y su hoja se carga después de la nuestra, así que gana ella y la
 * foto se quedaba del tamaño de un icono. Muchos temas añaden encima su propio
 * `height: auto !important`, que no hay especificidad que lo tumbe.
 *
 * Con la caja midiendo y la imagen limitada por `max-height`, el `height:auto`
 * del tema deja de ser un problema y pasa a ser justo lo que queremos: la foto
 * conserva su proporción y se ajusta dentro. Nadie pelea con nadie.
 */
.odr-gift-card__media {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 175px;
}

/* La foto manda el alto de la tarjeta: todas iguales, sin recortar el frasco. */
/*
 * La foto es lo que se compara, así que se lleva el sitio.
 *
 * Con miniaturas de cien píxeles dentro de una tarjeta con aire alrededor, dos
 * frascos del mismo laboratorio eran indistinguibles y había que leerse los
 * nombres igual que en el desplegable que quitamos: la parrilla dejaba de
 * servir para lo que está.
 *
 * La clase repetida sube la especificidad por encima del `.woocommerce img`
 * de WooCommerce sin llegar al !important, igual que se hace más arriba con
 * el formulario.
 */
.odr-gift-card.odr-gift-card .odr-gift-card__media img {
	display: block;
	width: auto;
	max-width: 100%;
	height: auto;
	max-height: 100%;
	margin: 0;
	object-fit: contain;
}

/*
 * El nombre se corta a tres líneas: los nombres de colección se van a seis y
 * dejaban tarjetas del doble de alto que sus vecinas en la misma fila.
 */
.odr-gift-card__name {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 0.86em;
	font-weight: 600;
	line-height: 1.35;
}

/* El SKU es dato de referencia, no titular: va debajo y en gris. */
.odr-gift-card__sku {
	font-size: 0.72em;
	line-height: 1.3;
	opacity: 0.6;
}

/*
 * La elegida se marca con el color de la tienda. Se pinta por :has() y también
 * por la clase que pone el JS, para los navegadores sin :has().
 */
.odr-gift-card.is-selected,
.odr-gift-card:has( .odr-gift-card__input:checked ) {
	border-color: var( --odr-accent, #2e7d32 );
	box-shadow: inset 0 0 0 2px var( --odr-accent, #2e7d32 );
}

/*
 * La elegida lleva ademas su palomita.
 *
 * Sin el radio a la vista, lo unico que distinguia la tarjeta elegida era un
 * marco de color, y un marco de color es tambien lo que hacen el hover y el
 * foco: en una parrilla de fotos las tres cosas se confundian. La palomita
 * solo aparece en la elegida, asi que no hay con que confundirla; y no depende
 * del color para leerse, que es lo que hace falta para quien no distingue el
 * verde del gris.
 */
.odr-gift-card.is-selected::after,
.odr-gift-card:has( .odr-gift-card__input:checked )::after {
	position: absolute;
	top: 0.5em;
	right: 0.5em;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: var( --odr-accent, #2e7d32 ) url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E" ) no-repeat center;
	background-size: 13px 13px;
	content: '';
}

/*
 * El foco del teclado se ve en la tarjeta entera: el radio esta escondido, asi
 * que sin esto quien se mueve con el tabulador no ve donde esta.
 *
 * El azul del foco no se parece al verde de la seleccion a proposito: son dos
 * cosas distintas —donde estoy y que he elegido— y con el mismo color, al
 * recorrer la parrilla con el teclado, parece que se va eligiendo todo a su
 * paso.
 */
.odr-gift-card:has( .odr-gift-card__input:focus-visible ) {
	outline: 2px solid #2271b1;
	outline-offset: 2px;
}

/* Respaldo para navegadores sin :has(): el foco se pinta sobre el radio. */
@supports not selector( :has( * ) ) {
	.odr-gift-card__input:focus-visible {
		position: static;
		width: auto;
		height: auto;
		margin: 0;
		clip: auto;
		clip-path: none;
		outline: 2px solid #2271b1;
	}
}

.odr-gift-chooser__attrs {
	display: flex;
	flex-direction: column;
	gap: 0.85em;
}

/*
 * Los desplegables no se estiran a lo ancho del modal.
 *
 * Con la parrilla de tarjetas el diálogo mide bastante más que antes, y un
 * «Talla» de tres opciones ocupando cuarenta y seis eme se lee como un campo
 * de texto libre. Acotados a una columna se ven como lo que son: lo último
 * que queda por decidir, después de la foto.
 */
.odr-gift-chooser__attrs--stack .odr-gift-chooser__field {
	max-width: 22em;
	/*
	 * Centrados bajo la parrilla: pegados al borde izquierdo se leian como si
	 * pertenecieran a otra caja distinta de las tarjetas de arriba.
	 */
	margin-inline: auto;
}

/*
 * Los grupos de los regalos no elegidos van con [hidden], que muchos temas
 * pisan al declarar display en el selector de elemento.
 */
.odr-gift-chooser__attrs[hidden] {
	display: none;
}

/*
 * Las acciones, con línea y fondo propios: cierran la caja y dejan claro que
 * ahí abajo está lo que confirma, no otro campo más.
 */
.odr-gift-modal__actions {
	display: flex;
	flex: none;
	justify-content: flex-end;
	gap: 0.6em;
	padding: 1em 1.4em;
	border-top: 1px solid rgba( 0, 0, 0, 0.09 );
	background: rgba( 0, 0, 0, 0.02 );
}

/*
 * «Después» cierra sin elegir: el regalo sigue pendiente y el pago sigue
 * bloqueado, así que va en gris y sin peso. Existe porque un modal que se abre
 * solo y no deja salir es una trampa, no una promoción.
 */
.odr-gift-modal__later {
	flex: 0 0 auto;
	min-height: 42px;
	padding: 0.55em 1.1em;
	border: 1px solid rgba( 0, 0, 0, 0.15 );
	border-radius: 5px;
	background: #fff;
	color: inherit;
	font-size: 0.88em;
	font-weight: 500;
	line-height: 1.3;
	cursor: pointer;
}

.odr-gift-modal__later:hover {
	background: rgba( 0, 0, 0, 0.04 );
}

.odr-gift-modal__later:focus-visible {
	outline: 2px solid #2271b1;
	outline-offset: 2px;
}

.odr-gift-modal__save {
	flex: 0 0 auto;
	min-height: 42px;
	padding: 0.55em 1.6em;
	border: 0;
	border-radius: 5px;
	background: var( --odr-accent, #2e7d32 );
	color: var( --odr-accent-text, #fff );
	font-size: 0.88em;
	font-weight: 600;
	line-height: 1.3;
	cursor: pointer;
	transition: filter 0.15s ease;
}

.odr-gift-modal__save:hover {
	filter: brightness( 0.92 );
}

.odr-gift-modal__save:focus-visible {
	outline: 2px solid #2271b1;
	outline-offset: 2px;
}

/*
 * El aspa de cerrar, sobre la cabecera.
 *
 * Sustituye al «Cancelar» que había junto a Guardar: dos salidas para lo
 * mismo, y una de ellas pegada al botón que confirma, que es donde peor cae.
 * Arriba a la derecha es donde se busca para cerrar, y deja la barra de abajo
 * con una sola cosa que hacer.
 *
 * Solo aparece con JS: sin él el diálogo no es modal —es un bloque más de la
 * página— y no hay nada que cerrar.
 */
.odr-gift-modal__x {
	position: absolute;
	top: 0;
	right: 0;
	display: none;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	/*
	 * Cuadra con la cabecera porque mide lo mismo que ella. Antes eran dos
	 * altos distintos (56px fijos contra un minimo que crecia) y el aspa
	 * quedaba por encima de la linea del titulo.
	 */
	width: 52px;
	height: 52px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	color: inherit;
	line-height: 0;
	opacity: 0.5;
	cursor: pointer;
	transition: opacity 0.15s ease;
}

/* Los temas le meten min-height y padding a todo <button> del contenido. */
.odr-gift-modal__x:hover {
	background: none;
}

.odr-gift-modal__x svg {
	display: block;
}

.odr-gift-js .odr-gift-modal__x {
	display: flex;
}

.odr-gift-modal__x:hover,
.odr-gift-modal__x:focus-visible {
	opacity: 1;
}

.odr-gift-modal__x:focus-visible {
	outline: 2px solid #2271b1;
	outline-offset: -6px;
}

.odr-gift-modal__hint {
	margin: 0;
	padding: 0 1.15em 1.15em;
	font-size: 0.78em;
	line-height: 1.45;
	opacity: 0.7;
}

/* En móvil el diálogo se pega abajo, que es donde llega el pulgar. */
/*
 * En la tabla apilada, el bloque del regalo va a la derecha.
 *
 * Ahi WooCommerce pone el rotulo de cada celda a la izquierda y su valor a la
 * derecha —«Precio: —», «Subtotal: Gratis»—, asi que la fila del regalo era la
 * unica que rompia esa columna: el rotulo «Producto:» a un lado y todo su
 * contenido debajo pegado al otro. Alineado a la derecha, el regalo se lee en
 * la misma columna que el resto de valores de su fila.
 *
 * No basta con `text-align`: la etiqueta y los botones se ajustan a su
 * contenido y son cajas de bloque, asi que quien los mueve es el margen
 * automatico, y el contenedor del boton es flex, asi que a ese lo mueve
 * `justify-content`.
 */
@media ( max-width: 600px ) {
	.odr-gift-cell {
		text-align: right;
	}

	.odr-gift-badge {
		margin-right: 0;
		margin-left: auto;
	}

	.odr-gift-chooser {
		justify-content: flex-end;
	}

	/*
	 * El pendiente es una columna, asi que quien lo alinea a lo ancho es
	 * `align-items` y no `justify-content`. La clase repetida iguala la
	 * especificidad de la regla que lo pone a la izquierda mas arriba.
	 */
	.odr-gift-chooser.odr-gift-chooser.is-pending {
		align-items: flex-end;
	}

	.odr-gift-reset {
		margin-left: auto;
	}
}

@media ( max-width: 600px ) {
	.odr-gift-js .odr-gift-modal[open] {
		/*
		 * Centrado, no pegado abajo.
		 *
		 * Estaba anclado al borde inferior para caer bajo el pulgar, pero con
		 * el modal del regalo eso lo dejaba colgando del fondo de la pantalla
		 * y tocando los dos bordes laterales: se leia como una hoja a medio
		 * subir, no como una caja. «inset: 0» con «margin: auto» lo centra en
		 * los dos ejes, y el margen deja ver la pagina por los lados, que es
		 * lo que hace que se entienda como algo que esta por encima.
		 */
		inset: 0;
		width: auto;
		max-width: none;
		max-height: calc( 100vh - 2rem );
		margin: auto 0.75rem;
		box-sizing: border-box;
	}

	.odr-gift-modal__box {
		max-height: calc( 100vh - 2rem );
		border-radius: 12px;
	}

	/* Dos por fila: a 150px de mínimo entraba una sola y la foto se disparaba. */
	.odr-gift-cards {
		grid-template-columns: repeat( 2, 1fr );
		gap: 0.6em;
	}

	.odr-gift-card__media {
		height: 130px;
	}

	.odr-gift-modal__title {
		padding-right: 48px;
		padding-left: 1em;
	}

	.odr-gift-modal__x {
		width: 48px;
	}

	.odr-gift-modal__lead,
	.odr-gift-modal__fields {
		padding-right: 1em;
		padding-left: 1em;
	}

	.odr-gift-modal__actions {
		padding: 0.85em 1em;
	}

	/* En el pie estrecho los dos botones se reparten el ancho. */
	.odr-gift-modal__later,
	.odr-gift-modal__save {
		flex: 1 1 auto;
	}
}

/*
 * El aviso que ocupa el sitio del botón de pagar.
 *
 * Mientras falte elegir el regalo, el botón no lleva a ninguna parte: el
 * checkout rechazaría el carrito y devolvería al cliente aquí. En su lugar va
 * este aviso, que dice por qué no se puede seguir y deja la respuesta a la
 * vista, unas filas más arriba.
 */
.odr-gift-block {
	margin: 0;
	padding: 0.9em 1em;
	border: 1px solid rgba( 214, 54, 56, 0.35 );
	border-radius: 5px;
	background: rgba( 214, 54, 56, 0.06 );
	color: inherit;
	font-size: 0.88em;
	line-height: 1.45;
	text-align: center;
}
