/**
 * Configurador de cortes — aspecto.
 *
 * Solo lo específico del configurador: la tabla de cortes, el selector de
 * cantos y el dibujo del despiece. Todo lo demás (campos, botones, tarjetas,
 * avisos, precio) son componentes del tema, así que hereda tipografía, colores
 * y foco sin duplicar una línea.
 *
 * Consume los tokens del tema. Los valores de reserva permiten que el
 * configurador siga siendo legible si algún día se usa con otro tema, aunque el
 * resultado no sea el diseño de la casa.
 *
 * @package Configurador_Tableros
 */

.ct {
	display: grid;
	grid-template-columns: minmax(0, 1fr) var(--ml-configurador-resumen, 20rem);
	gap: var(--ml-space-5, 1.5rem);
	align-items: start;
}

@media (max-width: 900px) {

	.ct {
		grid-template-columns: minmax(0, 1fr);
	}
}

.ct__setup {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-5, 1.5rem);
	min-width: 0;
}

/*
 * El despiece va en la columna del formulario, no a ancho completo: el panel de
 * presupuesto queda fijo al hacer scroll y, si el dibujo pasara por debajo,
 * quedaría tapado justo cuando se está mirando.
 */
.ct__layout {
	grid-column: 1;
	min-width: 0;
}

@media (max-width: 900px) {

	.ct__layout {
		grid-column: 1 / -1;
	}
}

.ct.is-loading .ct__summary,
.ct.is-loading .ct__layout {
	opacity: 0.6;
	transition: opacity 120ms ease;
}

/* --- Pasos -------------------------------------------------------------- */

.ct__step-title {
	display: flex;
	align-items: center;
	gap: var(--ml-space-3, 0.75rem);
	margin: 0 0 var(--ml-space-4, 1rem);
	font-size: var(--ml-text-lg, 1.125rem);
}

/*
 * Los números de paso van en color de identidad, no en el de acción.
 *
 * Indican por dónde va el proceso; no se pulsan. En esta pantalla el color de
 * acción tiene un solo dueño —«Añadir al carrito»— y compartirlo con dos
 * adornos le resta la fuerza que necesita.
 */
/* --------------------------------------------------------------------------
   EL CONMUTADOR DE UNIDADES (cliente, 8/9/2026)

   Va en la cabecera del paso de las medidas, que es donde empiezan los números:
   quien lo necesita lo está mirando justo cuando va a teclear el primero.

   NO CAMBIA NINGÚN DATO. Lo que se envía, se cobra y se guarda sigue siendo el
   milímetro; esto solo decide cómo se escribe. Por eso puede vivir en un rincón
   del encabezado y no como un paso más.
   -------------------------------------------------------------------------- */

.ct__step-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--ml-space-2, 0.5rem) var(--ml-space-5, 1.5rem);
	margin-bottom: var(--ml-space-4, 1rem);
}

/* El aire de debajo lo pone la cabecera entera, no el título: con el margen en
   el `h2`, el conmutador quedaba una línea más abajo que el texto con el que se
   alinea. */
.ct__step-head > .ct__step-title {
	margin-bottom: 0;
}

.ct-units {
	margin: 0;
	padding: 0;
	border: 0;
}

/* El rótulo NO se esconde. Dos botones que dicen «cm» y «mm» sin nada delante se
   leen como un filtro de cualquier cosa; con «Unidades» al lado se entiende sin
   pulsarlos. Va en pequeño porque no es lo que se decide en este paso. */
.ct-units__title {
	float: left;
	padding: 0;
	margin-inline-end: var(--ml-space-2, 0.5rem);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-xs, 0.75rem);
	line-height: 1.9;
}

.ct-units__opts {
	display: flex;
	overflow: hidden;
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-sm, 4px);
}

.ct-units__opt {
	position: relative;
	display: block;
}

/* El radio nativo sigue debajo, solo sin su aspecto: es la misma técnica que los
   ejes del paso 1 y es lo que conserva el teclado y el lector de pantalla. No se
   usa `display: none`, que los sacaría del orden de tabulación. */
.ct-units__opt input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.ct-units__opt span {
	display: block;
	padding: 0.25rem var(--ml-space-3, 0.75rem);
	background: var(--ml-surface, #faf7f2);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-xs, 0.75rem);
	line-height: 1.6;
	cursor: pointer;
}

.ct-units__opt + .ct-units__opt span {
	border-inline-start: 1px solid var(--ml-border, #e5ded4);
}

.ct-units__opt input:checked + span {
	background: var(--ml-brand, #0e655e);
	color: var(--ml-text-on-brand, #ffffff);
	font-weight: var(--ml-weight-medium, 500);
}

.ct-units__opt input:focus-visible + span {
	box-shadow: var(--ml-focus-ring);
}

.ct__step-num {
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: var(--ml-radius-full, 999px);
	/* Como los números de la banda de pasos de la cabecera (1/10/2026):
	   petróleo oscuro con la cifra en ámbar. */
	background: var(--ml-surface-header, #123b38);
	color: var(--ml-accent-on-dark, #d9a85c);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: var(--ml-weight-bold, 700);
}

/* --- Elegir tablero: opciones a la vista ---------------------------------- */

/*
 * Botones, no desplegables.
 *
 * Un `<select>` esconde sus opciones hasta que se abre, así que el visitante no
 * ve que su elección acaba de cambiar lo que hay en los otros dos campos: hubo
 * que explicarlo con una frase, y esa frase era el síntoma. A la vista, lo que
 * no se fabrica se apaga delante de los ojos y no hace falta contarlo.
 *
 * El radio nativo sigue debajo —accesible con teclado y con lector de pantalla—
 * y solo se le quita el aspecto; lo que se ve es su etiqueta.
 */
.ct-choice {
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
}

.ct-choice__label {
	display: flex;
	flex-wrap: wrap;
	gap: var(--ml-space-1, 0.25rem) var(--ml-space-3);
	align-items: baseline;
	margin-bottom: var(--ml-space-2);
	padding: 0;
	color: var(--ml-text-muted);
	font-size: var(--ml-text-sm);
	font-weight: var(--ml-weight-medium);
}

/* El «¿cuál necesito?» del soporte. En el color de accion y sin subrayado
   permanente: acompana a la etiqueta y no debe competir con los botones de
   debajo, que es lo que hay que pulsar. */
.ct-choice__ayuda {
	color: var(--ml-brand);
	font-weight: var(--ml-weight-normal, 400);
	text-decoration: none;
}

/* En pantalla táctil, 44 px de alto para poder pulsarlo (4/10/2026). */
@media (pointer: coarse) {
	.ct-choice__ayuda {
		display: inline-flex;
		align-items: center;
		min-height: 2.75rem;
	}
}

.ct-choice__ayuda:hover,
.ct-choice__ayuda:focus-visible {
	text-decoration: underline;
}

.ct-choice__options {
	display: flex;
	flex-wrap: wrap;
	gap: var(--ml-space-2);
}

.ct-choice__option {
	position: relative;
	display: inline-flex;
}

/*
 * El radio no se oculta con `display:none` ni con `visibility:hidden`: eso lo
 * saca del recorrido del teclado. Se deja donde está, transparente y del tamaño
 * de la etiqueta, para que siga recibiendo el foco y el clic.
 */
.ct-choice__input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.ct-choice__text {
	display: inline-flex;
	align-items: center;
	gap: var(--ml-space-3);
	min-height: 2.5rem;
	padding: var(--ml-space-2) var(--ml-space-4);
	border: 1px solid var(--ml-border);
	border-radius: var(--ml-radius-sm);
	background: var(--ml-surface);
	color: var(--ml-text);
	font-size: var(--ml-text-sm);
	line-height: 1.2;
	transition: border-color var(--ml-transition), background-color var(--ml-transition);
}

.ct-choice__option:hover .ct-choice__text {
	border-color: var(--ml-brand);
}

/* --------------------------------------------------------------------------
   LA MUESTRA DEL DECORADO.

   Va DENTRO del botón y con su nombre al lado, no sola con un globo de ayuda:
   de los seis decorados dos son blancos y dos grises, así que como cuadritos
   sueltos serían indistinguibles. Y en un móvil no existe «pasar el ratón»:
   tocar para saber qué es equivale a elegirlo.

   Con el color en fila propia caben los dos: la imagen resuelve «cómo es» de un
   vistazo y el texto, «cuál es».
   -------------------------------------------------------------------------- */
.ct-choice__muestra {
	flex: 0 0 auto;

	/* Menos alta que ancha: es un trozo de tablero, no un icono. */
	width: 3rem;
	height: 2.25rem;
	border-radius: var(--ml-radius-sm, 4px);

	/* El borde interior evita que un decorado claro se funda con el fondo del
	   botón, que también lo es. */
	box-shadow: inset 0 0 0 1px rgb(0 0 0 / 12%);
	object-fit: cover;
}

.ct-choice__nombre {
	min-width: 0;
}

/* El color ocupa la fila entera: son seis o siete opciones con imagen, y
   apretadas en un tercio del ancho quedarían en una columna larguísima al lado
   de dos columnas casi vacías. */
.ct-choice--ancho {
	grid-column: 1 / -1;
}

.ct-choice--ancho .ct-choice__options {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}

.ct-choice--ancho .ct-choice__option,
.ct-choice--ancho .ct-choice__text {
	width: 100%;
}

.ct-choice--ancho .ct-choice__text {
	padding: var(--ml-space-2);
}

/* La descripción del decorado, plegable solo en el móvil (3/10/2026). */
.ct-decor__mas-boton {
	display: none;
}

@media ( max-width: 37.5rem ) {
	.ct-decor__mas-boton {
		display: list-item;
		color: var(--ml-brand-text, #0e655e);
		font-size: var(--ml-text-sm, 0.875rem);
		font-weight: var(--ml-weight-medium, 500);
		cursor: pointer;
	}
}

/* --------------------------------------------------------------------------
   EL PASO 1 EN ACORDEÓN (3/10/2026).
   Un apartado por eje; abierto el que toca, los hechos en una línea con
   «Cambiar» y los que vienen, cerrados y apagados.
   -------------------------------------------------------------------------- */
.ct-acordeon .ct__step--material .ct__fields {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-2, 0.5rem);
}

.ct-paso {
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-raised, #ffffff);
}

.ct-paso.is-abierto {
	border-color: var(--ml-brand, #0e655e);
	box-shadow: inset 0 0 0 1px var(--ml-brand, #0e655e);
}

.ct-paso__cab {
	display: flex;
	align-items: center;
	gap: var(--ml-space-3, 0.75rem);
	width: 100%;
	padding: var(--ml-space-3, 0.75rem) var(--ml-space-4, 1rem);
	border: 0;
	background: none;
	color: var(--ml-text, #2b2622);
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.ct-paso__cab:disabled {
	cursor: default;
}

.ct-paso__marca {
	display: grid;
	flex: none;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	/* De contorno: el círculo relleno es el de los pasos del configurador. */
	border: 2px solid var(--ml-brand, #0e655e);
	border-radius: var(--ml-radius-full, 999px);
	color: var(--ml-brand-text, #0e655e);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-paso__titulo {
	font-size: var(--ml-text-base, 1rem);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-paso__valor {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	color: var(--ml-text-muted, #666d72);
	/* Se corta con «…» antes de «Cambiar»: en un móvil, «Aglomerado» se
	   montaba encima del enlace (4/10/2026). */
	text-overflow: ellipsis;
	white-space: nowrap;
}

.ct-paso__accion {
	flex: none;
	color: var(--ml-brand-text, #0e655e);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: var(--ml-weight-medium, 500);
	text-decoration: underline;
}

.ct-paso.is-hecho .ct-paso__marca {
	background: var(--ml-brand, #0e655e);
	color: var(--ml-text-on-brand, #ffffff);
}

.ct-paso.is-futuro .ct-paso__cab {
	color: var(--ml-text-muted, #666d72);
}

.ct-paso.is-futuro .ct-paso__marca {
	border-color: var(--ml-border, #e5ded4);
	color: var(--ml-text-muted, #666d72);
}

.ct-paso__cuerpo {
	display: none;
	padding: 0 var(--ml-space-4, 1rem) var(--ml-space-4, 1rem);
}

.ct-paso.is-abierto .ct-paso__cuerpo {
	display: grid;
	gap: var(--ml-space-4, 1rem);
}

/* El título del eje ya lo dice la cabecera; queda solo su ayuda. */
.ct-paso .ct-choice[data-ct-choice] > .ct-choice__label {
	font-size: 0;
}

.ct-paso .ct-choice[data-ct-choice] > .ct-choice__label > * {
	font-size: var(--ml-text-sm, 0.875rem);
}

/* --------------------------------------------------------------------------
   LOS DECORADOS, SOLO CON SU FOTO (cliente, 3/10/2026).

   Tres por fila, la foto grande y sin texto; el nombre sale como globo al
   pasar el ratón o al llegar con el teclado. Sustituye a «muestra más nombre»
   del 6/9: con fotos reales de cada decorado ya se distinguen a la vista. El
   nombre sigue en el HTML (lo lee un lector de pantalla), y en el móvil, sin
   puntero, se lee en la ficha del decorado al elegirlo. Un decorado sin foto
   enseña el nombre dentro de la casilla.
   -------------------------------------------------------------------------- */
.ct-choice--muestras .ct-choice__options {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--ml-space-2);
}

.ct-choice--muestras .ct-choice__option,
.ct-choice--muestras .ct-choice__text {
	width: 100%;
}

.ct-choice--muestras .ct-choice__text {
	display: block;
	padding: 3px;
}

.ct-choice--muestras .ct-choice__muestra {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
}

.ct-choice--muestras .ct-choice__text:has(.ct-choice__muestra) .ct-choice__nombre {
	position: absolute;
	bottom: calc(100% + 6px);
	left: 50%;
	z-index: 5;
	width: max-content;
	max-width: 14rem;
	padding: var(--ml-space-1, 0.25rem) var(--ml-space-2, 0.5rem);
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface-header, #123b38);
	color: var(--ml-text-on-brand, #ffffff);
	font-size: var(--ml-text-xs, 0.75rem);
	font-weight: var(--ml-weight-medium, 500);
	text-align: center;
	opacity: 0;
	pointer-events: none;
	transform: translateX(-50%);
}

/* En pantallas sin puntero el globo no se ve nunca (no hay «pasar por
   encima»), pero su caja seguía ahí, transparente, y la del último decorado
   de la fila sobresalía 3 px de la pantalla (4/10/2026). Se recoge sin
   quitarlo: es el nombre del decorado para el lector de pantalla. */
@media (hover: none) {
	.ct-choice--muestras .ct-choice__text:has(.ct-choice__muestra) .ct-choice__nombre {
		left: 0;
		width: 1px;
		max-width: none;
		height: 1px;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		transform: none;
		white-space: nowrap;
	}
}

.ct-choice--muestras .ct-choice__option:hover .ct-choice__nombre,
.ct-choice--muestras .ct-choice__input:focus-visible + .ct-choice__text .ct-choice__nombre {
	opacity: 1;
}

.ct-choice--muestras .ct-choice__text:not(:has(.ct-choice__muestra)) {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	text-align: center;
}

.ct-choice__input:checked + .ct-choice__text {
	border-color: var(--ml-brand);
	box-shadow: inset 0 0 0 1px var(--ml-brand);
	font-weight: var(--ml-weight-medium);
}

.ct-choice__input:focus-visible + .ct-choice__text {
	box-shadow: var(--ml-focus-ring);
}

/*
 * Lo que no se fabrica con lo ya elegido. Apagado, no escondido: la gama sigue
 * a la vista —enseña lo que la casa trabaja— y quien buscaba algo que no está
 * no se queda dudando de si existe.
 */
.ct-choice__input:disabled {
	cursor: not-allowed;
}

.ct-choice__option.is-unavailable .ct-choice__text {
	border-style: dashed;
	color: var(--ml-text-muted);
	opacity: 0.5;
}

.ct-choice__option.is-unavailable:hover .ct-choice__text {
	border-color: var(--ml-border);
}

/*
 * `auto-fit` y no `auto-fill`: con el color en fila propia, los otros dos ejes
 * se reparten el ancho en vez de dejar una tercera columna fantasma.
 */
.ct__fields {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: var(--ml-space-4, 1rem) var(--ml-space-5, 1.5rem);
}

.ct__note {
	margin: var(--ml-space-4, 1rem) 0 0;
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-xs, 0.75rem);
}

/* La medida máxima, entre el título del paso 2 y la vista de la pieza. */
.ct__note--medidas {
	margin: 0 0 var(--ml-space-4, 1rem);
}

/* --------------------------------------------------------------------------
   LA FAMILIA: filtra la galería de decorados.

   No es un cuarto eje, así que tampoco se ve como los otros tres: son botones
   más pequeños y en una fila aparte, encima de los campos. Lo que decide qué
   se compra son los tres de abajo; esto solo acorta la lista.
   -------------------------------------------------------------------------- */

.ct-familias {
	/* A todo lo ancho del bloque de campos y encima del color, que es lo que
	   filtra. Fuera de `.ct__fields` caía al final del paso: la rejilla del
	   paso 1 coloca a sus hijos por posición y este no tenía la suya. */
	grid-column: 1 / -1;
	margin-bottom: 0;
}

/*
 * EN FILA Y AL TAMAÑO DEL TEXTO, no en la rejilla de los decorados.
 *
 * `ct-choice--ancho` le da a cada opción una celda de 13rem porque un decorado
 * lleva muestra y nombre largo. Un chip de familia es una palabra y un número:
 * a ese tamaño pesaría lo mismo que la elección de verdad, que está justo
 * debajo.
 */
.ct-familias .ct-choice__options {
	display: flex;
	flex-wrap: wrap;
	gap: var(--ml-space-2, 0.5rem);
}

.ct-familias .ct-choice__option,
.ct-familias .ct-choice__text {
	width: auto;
}

.ct-familias__opcion .ct-choice__text {
	padding-block: var(--ml-space-1, 0.25rem);
	font-size: var(--ml-text-sm, 0.875rem);
}

/*
 * EL DECORADO FILTRADO SE VA, no se apaga.
 *
 * Es lo contrario de lo que hacen el soporte y el grosor, y a propósito: allí
 * lo apagado significa «esto no se fabrica así» y hay que verlo; aquí significa
 * «esto es de otra familia», que no es una limitación sino lo que se acaba de
 * pedir. Dejarlo a la vista en gris diría que no existe, que es mentira.
 *
 * Con clase y no con `[hidden]`: la opción es un `flex` y en este proyecto
 * `display` le ha ganado al atributo tres veces.
 */
.ct-choice__option.is-filtered {
	display: none;
}

/*
 * Un eje desvelado (material, grosor) que aun no toca. Con `display` explicito
 * por lo de siempre: `[hidden]` solo no gana a una regla con `display`.
 */
.ct-choice[hidden] {
	display: none;
}


.ct__actions {
	margin-top: var(--ml-space-4, 1rem);
}

/* --- Tabla de cortes ---------------------------------------------------- */

.ct__table-wrap {
	overflow-x: auto;

	/*
	 * El aire alrededor no es decorativo: lo exige el scroll horizontal.
	 *
	 * `overflow-x: auto` recorta todo lo que sobresalga de este contenedor, y en
	 * CSS basta con que un eje sea `auto` para que el otro deje de ser
	 * `visible`. Aquí sobresalen dos cosas: la zona de pulsación de las casillas
	 * de canteado (arriba y abajo), y el anillo de foco de los campos, que es
	 * una sombra de 4 px. Sin este margen, la tabla aparecía con barra de scroll
	 * vertical estando vacía, y el anillo del primer campo se veía cortado por
	 * la izquierda.
	 *
	 * El relleno lateral se compensa con margen negativo para no robarle ancho a
	 * la tabla, que en móvil es justo lo que escasea. Los 24 px de la tarjeta
	 * dejan sitio de sobra.
	 */
	padding-block: 0.75rem;
	padding-inline: 0.5rem;
	margin-inline: -0.5rem;
}

.ct-cuts {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--ml-text-sm, 0.875rem);
}

.ct-cuts th {
	padding: 0 var(--ml-space-2, 0.5rem) var(--ml-space-2, 0.5rem);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-xs, 0.75rem);
	font-weight: 700;
	text-align: left;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	white-space: nowrap;
}

.ct-cuts td {
	padding: var(--ml-space-1, 0.25rem) var(--ml-space-2, 0.5rem);
	vertical-align: middle;
}

/*
 * La primera columna se alinea con el borde del bloque.
 *
 * Acotado a las filas de CORTE: la fila de mecanizados también tiene una
 * primera celda —la única, que ocupa todo el ancho— y esta regla le quitaba el
 * relleno izquierdo, con lo que sus tarjetas se pegaban al borde de la franja.
 */
.ct-cuts__row > td:first-child,
.ct-cuts th:first-child {
	padding-left: 0;
}

/* --------------------------------------------------------------------------
   EL NÚMERO DE LA PIEZA

   Los avisos hablan de «la pieza 3» —los del navegador y los del servidor— y
   hasta el 10/9/2026 ese número solo existía en el `aria-label`: quien
   escuchaba la página sabía cuál era y quien la miraba tenía que contar filas.

   Discreto a propósito: identifica, no compite con las medidas, que es lo que
   hay que leer.
   -------------------------------------------------------------------------- */
.ct-cuts th[data-col="num"],
.ct-cuts__num {
	width: 1%;
	white-space: nowrap;
	text-align: center;
}

.ct-cuts__num {
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
	font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   LA MEDIDA QUE NO VALE, SEÑALADA

   El número de la fila dice QUÉ pieza es; esto, en cuál de sus dos medidas
   está el problema. Sin ello, «el fondo de la pieza 3» obliga a buscar el
   campo a ojo. `aria-invalid` lo cuenta por su parte.
   -------------------------------------------------------------------------- */
.ct-cuts input.is-invalid,
.ct-cuts select.is-invalid,
.ct-upstand input.is-invalid {
	border-color: var(--ml-danger, #a32d2d);
	box-shadow: 0 0 0 1px var(--ml-danger, #a32d2d);
}

/*
 * EL CAMPO ES TAN ANCHO COMO EL NÚMERO QUE TIENE QUE ENSEÑAR (cliente, 7/9/2026)
 *
 * «Cant.» enseñaba el número **cortado por el borde del campo**. Medido: la
 * celda salía a 56 px y el campo a 40, de los que 16 son relleno y ~15 se los
 * lleva la ruleta del `input[type="number"]`; quedaban 9 px para las cifras.
 *
 * LA CAUSA NO ERA LA CANTIDAD, ERA EL RÓTULO. Aquí había un `width: 7rem` sobre
 * las tres primeras columnas que **no hacía nada**: comprobado anulándolo, las
 * columnas miden exactamente lo mismo con él y sin él. En una tabla automática,
 * la última columna pide el 100 % (ver arriba, y hace falta para que el dibujo
 * de cantos caiga bajo su cabecera), así que se queda con todo el sobrante y las
 * demás se encogen hasta su contenido mínimo. Y su contenido mínimo lo fijaba la
 * **cabecera**, que va con `white-space: nowrap`: 94 px «Ancho (mm)», 100 px
 * «Fondo (mm)» y 56 px «Cant.». O sea que el ancho de cada campo dependía de lo
 * largo que fuera el título de su columna, que es una coincidencia, no un
 * diseño: por eso solo se rompía en el más corto, y por eso variaba entre
 * navegadores y tipografías (el cliente lo vio en un ordenador y en un móvil).
 *
 * SE MIDE EN EL CAMPO, NO EN LA CELDA. Un `min-width` sobre el `td` tampoco
 * hace nada —comprobado: la celda sigue en 56 px—, porque la columna porcentual
 * vuelve a ganar. Puesto sobre el `input`, entra en el mínimo de la columna y sí
 * manda. Las cifras son las medidas de verdad: «5000» son 34,5 px de texto + 16
 * de relleno + 15 de ruleta + 2 de borde = 68; «200», 59.
 */
/* Y DESDE EL 8/9/2026 ESTOS DOS YA NO SON `type="number"`: con el conmutador de
   unidades hay que aceptar la coma decimal, y un campo numérico solo la admite
   si el idioma del navegador la usa. Así que de los 68 px medidos aquí abajo
   sobran los 15 de la ruleta — el mínimo se deja donde estaba, porque en
   milímetros el número sigue siendo de cuatro cifras y ahora en centímetros
   puede llevar coma («240,5»). */
.ct-cuts input[data-field="width"],
.ct-cuts input[data-field="height"] {
	min-width: 4.5rem;
}

.ct-cuts input[data-field="qty"] {
	min-width: 4rem;
}

/*
 * Y EL DESPLEGABLE DE LA VETA, que es el mismo fallo y se me escapó (8/9/2026).
 *
 * «Veta» es el rótulo más corto de la tabla, así que su columna se quedaba en
 * 50 px y el desplegable dentro en **34**: se leía «Se». Aquí hace falta más
 * sitio que en los números porque lo que distingue a las dos opciones está al
 * FINAL —«Sentido del ancho» y «Sentido del fondo» comparten los once primeros
 * caracteres—, y un recorte por el medio las volvería idénticas. Es el mismo
 * motivo por el que el listado de productos en móvil dejó de ser una rejilla.
 */
.ct-cuts select[data-field="grain"] {
	min-width: 10rem;
}

/*
 * Y SIN RULETA, que es quien se comía el sitio.
 *
 * El `input[type="number"]` reserva ~15 px dentro del campo para sus flechas.
 * En el de cantidad eso era **una cuarta parte** del ancho útil, y es la
 * diferencia entre que «2400» quepa o se corte en un teléfono de 360 px. A
 * cambio ofrece subir de uno en uno: en una medida de 2400 mm no sirve de nada,
 * y nadie ajusta milímetros a clics.
 *
 * No se pierde nada: las flechas del teclado siguen funcionando —`textfield`
 * solo quita los botones—, y iOS y Chrome de Android no las pintan nunca, así
 * que en un móvil de verdad esto ya era así.
 */
.ct-cuts input[type="number"] {
	appearance: textfield;
}

.ct-cuts input[type="number"]::-webkit-outer-spin-button,
.ct-cuts input[type="number"]::-webkit-inner-spin-button {
	appearance: none;
	margin: 0;
}

/*
 * EL SOBRANTE SE LO QUEDA LA ÚLTIMA COLUMNA, la de acciones.
 *
 * Una tabla al 100% reparte el ancho que le sobra entre las columnas sin medida,
 * y eso dejaba el dibujo de cantos —centrado en su celda— muy lejos de la
 * cabecera que lo nombra. Se veía poco mientras hubo una columna de veta en
 * medio; al desaparecer, la de cantos se llevó el doble de sobrante y el
 * descuadre se hizo evidente.
 *
 * Con la última al 100%, las demás se ciñen a su contenido: cada cosa cae bajo
 * su cabecera y deja de moverse cuando una columna se enseña o se oculta.
 */
.ct-cuts__row > td:last-child,
.ct-cuts th:last-child {
	width: 100%;
}

/* --- Cantos -------------------------------------------------------------- */

/* Las casillas de cada fila son el dato, no el control: se marcan en el bloque
   «Cantear» de la vista (lienzo.css). Por eso van ocultas. */
.ct-edges {
	display: none;
}

/* --------------------------------------------------------------------------
   EN MÓVIL LA FILA SE PARTE EN DOS LÍNEAS

   La fila entera no cabe a lo ancho de un teléfono, así que la tabla se
   desplazaba y el dibujo de cantos se quedaba fuera de la pantalla — con el
   canto corto derecho literalmente cortado por el borde. El cliente lo vio en
   su móvil el 6/9/2026 y propuso lo que se hace aquí: las medidas arriba y los
   cantos debajo, antes del botón de añadir.

   Encoger el dibujo se probó primero y no bastaba: cabía por poco y seguía
   pegado al borde, que es donde el pulgar tapa lo que hay que mirar.

   La tabla deja de pintarse como tabla, así que las cabeceras dejan de nombrar
   sus campos. Por eso cada uno lleva ya su `aria-label` desde el JavaScript
   —eso es lo que oye un lector de pantalla— y su `data-label`, que es lo que se
   ve. Sin las dos cosas, esto sería una rejilla de números sin nombre.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {

	/* Sin scroll horizontal: ya no hay nada que desplazar. */
	.ct__table-wrap {
		overflow-x: visible;
	}

	.ct-cuts thead {
		display: none;
	}

	.ct-cuts,
	.ct-cuts tbody,
	.ct-cuts__row,
	.ct-cuts__row > td {
		display: block;
	}

	/*
	 * Y LO OCULTO SIGUE OCULTO (cliente, 2/10/2026): el `display: block` de
	 * arriba gana al `[hidden]` del navegador, así que en el teléfono salían
	 * los cantos de una madera que no se cantea y la veta de un decorado sin
	 * veta —en el ordenador las celdas no llevan `display` y se ocultaban—.
	 */
	.ct-cuts__row > td[hidden] {
		display: none;
	}

	/* Cada corte, su propio bloque separado del siguiente. */
	/* La X tiene COLUMNA PROPIA, no `position: absolute`.
	   Colocada encima, se montaba sobre el campo de cantidad —medido: la X
	   ocupaba de 294 a 330 y el campo de 242 a 330—, así que tocar «quitar»
	   podía ser tocar el número. Reservándole columna, la rejilla se encarga. */
	.ct-cuts__row {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
		gap: var(--ml-space-3, 0.75rem);
		align-items: end;
		padding: var(--ml-space-4, 1rem) 0;
		border-top: 1px solid var(--ml-border, #e5ded4);
	}

	.ct-cuts__row:first-child {
		border-top: 0;
		padding-top: 0;
	}

	/* Anchos fijos fuera: aquí manda la rejilla. */
	.ct-cuts__row > td:last-child {
		width: auto;
	}

	/*
	 * Y el mínimo de los campos, también fuera.
	 *
	 * Arriba existe para que la columna no se encoja por debajo del número; aquí
	 * no hace falta, porque cada campo ocupa su columna entera. Y estorbaría: las
	 * tres son `minmax(0, 1fr)`, así que en un teléfono de 320 px se quedan en
	 * 50 px y un campo con 72 de mínimo se saldría de su celda.
	 */
	.ct-cuts select[data-field="grain"] {
		/* A línea completa: el mínimo de escritorio sobra y estorba. */
		min-width: 0;
		width: 100%;
	}

	.ct-cuts input[data-field="width"],
	.ct-cuts input[data-field="height"],
	.ct-cuts input[data-field="qty"] {
		min-width: 0;

		/*
		 * Y con menos relleno lateral, que aquí sí se nota: en un teléfono de
		 * 320 px cada columna se queda en 50 px y «2400» necesita 52 con el
		 * relleno de escritorio. Se puede recortar sin perder nada porque el
		 * rótulo va **encima** del campo, no dentro: no hay que dejarle sitio.
		 */
		padding-inline: var(--ml-space-1, 0.25rem);
	}

	.ct-cuts__row > td {
		padding: 0;
	}

	/* El nombre de la columna, encima de su campo. */
	/* Rótulos cortos y en una línea (4/10/2026): en mayúsculas y con la
	   unidad, «LARGO (CM)» ocupaba dos. */
	.ct-cuts__row > td[data-label]::before {
		content: attr(data-label);
		display: block;
		margin-bottom: var(--ml-space-1, 0.25rem);
		color: var(--ml-text-muted, #666d72);
		font-size: var(--ml-text-sm, 0.875rem);
		font-weight: 600;
		white-space: nowrap;
	}

	/*
	 * EL NÚMERO ENCABEZA EL BLOQUE, a la izquierda de la X.
	 *
	 * Apilada, la tabla deja de tener cabeceras, así que un «1» suelto no diría
	 * de qué es: aquí el rótulo va EN LÍNEA con la cifra —«PIEZA 1»— en vez de
	 * encima, que es como se pinta en las demás columnas.
	 *
	 * VA DESPUÉS DE LA REGLA DE ARRIBA A PROPÓSITO: las dos tienen la misma
	 * especificidad —`[data-label]` y `[data-col]` pesan igual—, así que decide
	 * el orden. Escrito antes, el `display: block` general ganaba y el rótulo
	 * salía en su propia línea.
	 */
	.ct-cuts__row > td[data-col="num"] {
		grid-column: 1 / 4;
		grid-row: 1;

		/* El `width: 1%` de escritorio encoge la celda dentro de su columna. */
		width: auto;
		align-self: center;
		text-align: left;
	}

	.ct-cuts__row > td[data-col="num"]::before {
		display: inline;
		margin-bottom: 0;
		margin-right: 0.3em;
		color: inherit;
		font-size: inherit;
		font-weight: inherit;
	}

	.ct-cuts__num {
		color: var(--ml-text, #2b2622);
		font-size: var(--ml-text-base, 1rem);
		font-weight: 700;
	}

	/* LA VISTA DE LA PIEZA, DETRÁS DE LA FILA Y MÁS BAJA (4/10/2026). Delante
	   medía 300 px y, sin medidas, era un recuadro casi vacío que llenaba la
	   pantalla: los campos quedaban fuera de la vista y parecía que no había
	   nada más. Ahora va después de las piezas y solo cuando hay algo que
	   dibujar. */
	.ct__step:has(> .ct-vista) {
		display: flex;
		flex-direction: column;
	}

	.ct__step > .ct-vista {
		order: 1;
		margin: var(--ml-space-4, 1rem) 0 0;
	}

	.ct__step:has(> .ct-vista) > .ct__actions {
		order: 2;
	}

	.ct__step > .ct-vista.is-vacia {
		display: none;
	}

	.ct__step > .ct-vista--fija {
		grid-template-rows: 2rem 10rem;
	}

	.ct__step > .ct-vista--fija .ct-vista__svg {
		max-height: 10rem;
	}

	/* Con el lienzo de huecos, el alto lo pone el lienzo. */
	.ct__step > .ct-vista--lienzo.ct-vista--fija {
		grid-template-rows: auto auto;
	}

	/* Veta, cantos y huecos: línea propia a todo lo ancho, debajo de las
	   medidas y antes del botón. Es lo que pidió el cliente y además es donde
	   caben: en la fila, el dibujo de cantos se salía de la pantalla y el canto
	   corto derecho quedaba cortado por el borde. */
	.ct-cuts__row > td[data-col="grain"],
	.ct-cuts__row > td[data-col="edges"],
	.ct-cuts__row > td[data-col="price"],
	.ct-cuts__row > td[data-col="machining"] {
		grid-column: 1 / -1;
	}

	/*
	 * La X va en la CUARTA columna, dicha entera.
	 *
	 * Con solo `grid-row: 1` se colocaba la primera de todas —CSS coloca antes
	 * los ítems con posición explícita que los automáticos— y se llevaba la
	 * columna 1, empujando las tres medidas a la derecha. Medido: la X salía en
	 * x 41-102 y el largo empezaba en 114.
	 */
	.ct-cuts__row > td:last-child {
		grid-column: 4 / 5;
		grid-row: 1;
	}
}

/* EN ENCIMERAS, LA VISTA CON EL LIENZO VA DETRÁS DE LAS PIEZAS Y DE «AÑADIR OTRA
   PIEZA» (5/10/2026), en todos los anchos: es el orden que la vista de las
   demás secciones ya tiene en el móvil, y aquí hace falta también en escritorio
   porque el lienzo, con su lista de huecos, mide casi una pantalla. */
.ct__step:has(> .ct-vista--lienzo) {
	display: flex;
	flex-direction: column;
}

.ct__step:has(> .ct-vista--lienzo) > .ct__actions {
	order: 1;
}

.ct__step > .ct-vista--lienzo {
	order: 2;
	margin: var(--ml-space-4, 1rem) 0 0;
}

/* --- Presupuesto --------------------------------------------------------- */

.ct__summary {
	position: sticky;
	/* La cabecera del tema es pegajosa y mide --ml-header-height (85 px) más su
	   borde. Con los 5rem (80 px) que había, la tarjeta se metía SEIS PÍXELES por
	   debajo y el arranque de su borde quedaba tapado al hacer scroll. Con
	   reserva a 0 para cuando no hay tema propio: sin cabecera pegajosa no hay
	   nada que esquivar. */
	top: calc(var(--ml-header-height, 0px) + var(--ml-space-3, 0.75rem));
}

.ct__summary-title {
	margin: 0 0 var(--ml-space-4, 1rem);
	font-size: var(--ml-text-xs, 0.75rem);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--ml-tracking-caps, 0.06em);
	color: var(--ml-text-muted, #666d72);
}

.ct__figures {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: var(--ml-space-2, 0.5rem) var(--ml-space-3, 0.75rem);
	margin: 0 0 var(--ml-space-4, 1rem);
	font-size: var(--ml-text-sm, 0.875rem);
}

.ct__figures dt {
	color: var(--ml-text-muted, #666d72);
}

.ct__figures dd {
	margin: 0;
	text-align: right;
	font-variant-numeric: tabular-nums;
}

.ct__total {
	display: block;
	margin: 0 0 var(--ml-space-4, 1rem);
	padding-top: var(--ml-space-4, 1rem);
	border-top: 1px solid var(--ml-border, #e5ded4);
	text-align: right;
}

.ct__notices {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-2, 0.5rem);
	margin-bottom: var(--ml-space-4, 1rem);
}

.ct__notices:empty {
	display: none;
}

.ct__pending {
	margin: var(--ml-space-3, 0.75rem) 0 0;
	color: var(--ml-text-subtle, #736a64);
	font-size: var(--ml-text-xs, 0.75rem);
	text-align: center;
}

/* --- Dibujo del despiece ------------------------------------------------- */

.ct__empty {
	margin: 0;
	padding: var(--ml-space-7, 3rem) var(--ml-space-4, 1rem);
	border: 1px dashed var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-lg, 12px);
	color: var(--ml-text-subtle, #736a64);
	text-align: center;
}

/*
 * Movimiento reducido.
 *
 * Esta hoja declara sus propias transiciones y trae valores de reserva para
 * funcionar fuera del tema, así que no puede dar por supuesto el reset global:
 * si el plugin se usa con otro tema, nadie más lo respetaría.
 */
@media (prefers-reduced-motion: reduce) {

	.ct__summary,
	.ct__layout {
		transition-duration: 0.01ms !important;
	}
}

/* --- Segunda vía: enviar el despiece ya dibujado ------------------------- */

/*
 * Va separada de los pasos 1 y 2 a propósito: no es la continuación del
 * configurador, es otro camino, y lleva a un sitio distinto (una solicitud que
 * revisa la tienda, no una compra). El aire de más y el borde punteado son lo
 * que dice «esto es una alternativa» sin necesidad de explicarlo.
 */
.ct-quote {
	margin-top: 2.5rem;
	border-style: dashed;
}

.ct-quote__title {
	margin: 0 0 0.5rem;
	font-size: var(--ml-text-lg, 1.125rem);
}

.ct-quote__lede {
	margin: 0 0 1.25rem;
	color: var(--ml-text-muted, #666d72);
	max-width: 60ch;
}

.ct-quote__form {
	display: grid;
	gap: 1rem;
}

.ct-quote__row {
	display: grid;
	gap: 1rem;
	grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

.ct-quote__field {
	display: grid;
	gap: 0.35rem;
	min-width: 0;
}

.ct-quote__hint {
	margin: 0;
	font-size: var(--ml-text-sm, 0.875rem);
	color: var(--ml-text-muted, #666d72);
}

.ct-quote button[type="submit"] {
	justify-self: start;
}

/*
 * Atajo a la vía alternativa, arriba del todo. Discreto: no debe competir con
 * el configurador, que es el camino principal, pero tiene que verse antes de
 * empezar a rellenar la tabla.
 */
.ct__alt-link {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 0.75rem;
	margin: 0 0 1rem;
	font-size: var(--ml-text-sm, 0.875rem);
	color: var(--ml-text-muted, #666d72);
}

/* Varios atajos en la misma línea, con un punto entre ellos; si no caben,
   se parten y el punto no se queda al principio de la línea. */
.ct__alt-link__item + .ct__alt-link__item::before {
	content: "·";
	margin-inline-end: 0.75rem;
}

/* --- Mecanizados ---------------------------------------------------------- */

/*
 * Los huecos de la pieza —fregadero, placa, orificios— se colocan en el lienzo
 * de la vista (lienzo.css), no en la fila: en la misma fila el ancho del
 * fregadero competiría con el de la encimera. En la fila queda el resumen.
 */
.ct-machining__toggle {
	white-space: nowrap;
}

.ct-machining__field {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ml-space-2, 0.5rem);
	font-size: var(--ml-text-sm, 0.875rem);
	color: var(--ml-text-muted, #666d72);
}

.ct-machining__field input {
	width: 6rem;
	flex: 0 0 auto;
}

/* --- Copetes -------------------------------------------------------------- */

/*
 * Una fila por copete, con sus tres medidas en línea. No es una tabla porque no
 * hay columnas que comparar: cada copete se lee entero de un vistazo.
 */
.ct-upstands {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-3, 0.75rem);
}

.ct-upstand {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--ml-space-3, 0.75rem);
	padding: var(--ml-space-3, 0.75rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
}

.ct-upstand__field {
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-start;
	gap: var(--ml-space-1, 0.25rem);
}

.ct-upstand__field input {
	width: 8rem;
}

.ct-upstand > button {
	margin-left: auto;
}

/* Lo que falta para poder comprar, no un adorno: el botón apagado sin
   explicación deja al cliente buscando qué ha hecho mal. */
.ct__pending--warning {
	color: var(--ml-warning-text, #8a5b1f);
	font-weight: var(--ml-weight-medium, 500);
}

/* «IVA incluido», debajo del total. Pequeño y en gris: es una aclaración, no un
   dato que compita con la cifra. */
.ct__total-tax {
	margin: calc(var(--ml-space-1, 0.25rem) * -1) 0 0;
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
}

.ct__total-tax[hidden] {
	display: none;
}

/* --------------------------------------------------------------------------
   EL DECORADO ELEGIDO: su nombre, su frase y sus características.

   Van los de la gama entera en el HTML y se enseña uno; por eso el `[hidden]`
   necesita regla propia, como en el lienzo: el `display` de aquí abajo gana al
   que el navegador aplica a [hidden].

   El hueco de la foto se reserva desde ya y no se pinta hasta que haya imagen
   (`:empty` sin fondo): así el bloque no cambia de forma cuando lleguen.
   -------------------------------------------------------------------------- */
.ct-decor[hidden],
.ct-decor [hidden] {
	display: none;
}

.ct-decor {
	margin-top: var(--ml-space-4, 1rem);
}

.ct-decor__ficha {
	display: grid;
	grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
	gap: var(--ml-space-4, 1rem);
	align-items: start;
	margin: 0;
	padding: var(--ml-space-4, 1rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface, #faf7f2);
}

/* AQUÍ HABÍA UNA REGLA QUE EXTENDÍA EL TEXTO A LAS DOS COLUMNAS cuando no había
   galería, y era correcta mientras la columna de la foto se quedaba vacía. Desde
   el 15/9/2026 no se queda: un decorado sin fotografía pinta ahí el aviso de que
   todavía no la hay, así que el texto se montaba encima. Se vio en encimeras,
   que es donde antes se notaba —su único material, el Krion, no tiene foto—.

   El texto se queda en su columna, y quien ocupa la primera es la galería o el
   aviso; siempre hay uno de los dos. */

.ct-decor__galeria {
	position: relative;
	display: grid;
	gap: var(--ml-space-2, 0.5rem);
	min-width: 0;
}

/* La lupa va SOBRE la foto y en su esquina, no debajo: encima se lee como «esta
   imagen se amplía» y debajo sería un botón más de la página. */
.ct-decor__lupa {
	position: absolute;
	z-index: 1;
	top: var(--ml-space-2, 0.5rem);
	right: var(--ml-space-2, 0.5rem);
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: 50%;
	background: var(--ml-surface-raised, #fff);
	color: var(--ml-text, #2b2622);
	cursor: pointer;
}

.ct-decor__lupa svg {
	width: 1.25rem;
	height: 1.25rem;
	fill: none;
	stroke: currentcolor;
	stroke-width: 1.75;
	stroke-linecap: round;
}

.ct-decor__lupa:hover {
	border-color: var(--ml-brand, #0e655e);
	color: var(--ml-brand, #0e655e);
}

.ct-decor__lupa:focus-visible {
	outline: 2px solid var(--ml-brand, #0e655e);
	outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   EL VISOR

   `<dialog>` nativo: el navegador ya atrapa el foco, cierra con Escape y
   devuelve el foco al botón que lo abrió. Aquí solo se le da tamaño y se
   destapa el fondo, que por omisión viene sin `::backdrop` visible.
   -------------------------------------------------------------------------- */
.ct-decor__visor {
	max-width: min(90vw, 60rem);
	max-height: 90vh;
	padding: 0;
	border: 0;
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-raised, #fff);
}

.ct-decor__visor::backdrop {
	background: rgba(0, 0, 0, 0.7);
}

.ct-decor__visor img {
	display: block;
	max-width: 100%;
	/* Descontando el alto del propio diálogo: sin esto una foto vertical se sale
	   por abajo en cuanto la pantalla es baja. */
	max-height: 90vh;
	height: auto;
}

.ct-decor__cerrar {
	position: absolute;
	top: var(--ml-space-2, 0.5rem);
	right: var(--ml-space-2, 0.5rem);
	display: grid;
	place-items: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: 50%;
	background: var(--ml-surface-raised, #fff);
	color: var(--ml-text, #2b2622);
	font-size: var(--ml-text-lg, 1.125rem);
	line-height: 1;
	cursor: pointer;
}

/* Anterior y siguiente en el visor (3/10/2026). */
.ct-decor__paso {
	position: absolute;
	top: 50%;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: 50%;
	background: var(--ml-surface-raised, #fff);
	color: var(--ml-text, #2b2622);
	font-size: 1.75rem;
	line-height: 1;
	cursor: pointer;
	transform: translateY(-50%);
}

.ct-decor__paso[hidden] {
	display: none;
}

.ct-decor__paso--ant {
	left: var(--ml-space-2, 0.5rem);
}

.ct-decor__paso--sig {
	right: var(--ml-space-2, 0.5rem);
}

.ct-decor__paso:focus-visible,
.ct-decor__cerrar:focus-visible {
	outline: 2px solid var(--ml-brand, #0e655e);
	outline-offset: 2px;
}

.ct-decor__foto {
	width: 100%;
	height: auto;
	aspect-ratio: 1;
	/* Toda la foto amplía, no solo la lupa (3/10/2026). */
	cursor: zoom-in;
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface-sunken, #f2ede5);
	object-fit: cover;
}

/* MINIATURAS DE TAMAÑO FIJO, EN UNA FILA QUE SE DESPLAZA.
   Repartirse el ancho a partes iguales parecía más limpio y no lo es: el
   cliente entrega una carpeta por decorado y no sabemos cuántas fotos trae, así
   que con dos salían dos sellos de media pantalla —en móvil, casi el alto
   entero— y con diez, diez uñas ilegibles. Con medida fija miden siempre lo
   mismo y lo que cambia es cuántas se ven.

   El relleno y el margen negativo NO son estética: `overflow-x` recorta lo que
   sobresale, y lo primero que sobresale es el anillo de foco. Sin esa holgura
   se ve cortado al llegar con el tabulador. */
.ct-decor__miniaturas {
	display: flex;
	gap: var(--ml-space-2, 0.5rem);
	margin: 0 calc(-1 * var(--ml-space-1, 0.25rem));
	padding: var(--ml-space-1, 0.25rem);
	overflow-x: auto;
	list-style: none;
}

.ct-decor__miniatura {
	display: block;
	flex: 0 0 auto;
	width: 3.5rem;
	padding: 0;
	border: 2px solid transparent;
	border-radius: var(--ml-radius-sm, 4px);
	background: none;
	cursor: pointer;
}

.ct-decor__miniatura img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1;
	border-radius: calc(var(--ml-radius-sm, 4px) - 1px);
	object-fit: cover;
}

.ct-decor__miniatura[aria-pressed="true"] {
	border-color: var(--ml-brand, #0e655e);
}

.ct-decor__miniatura:focus-visible {
	outline: 2px solid var(--ml-brand, #0e655e);
	outline-offset: 2px;
}

.ct-decor__texto {
	min-width: 0;
}

.ct-decor__nombre {
	margin: 0;
	font-size: var(--ml-text-base, 1rem);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-decor__slogan {
	margin: var(--ml-space-1, 0.25rem) 0 0;
	color: var(--ml-text-muted, #666d72);
}

/* EL HUECO DE UNA FOTO QUE NO HAY.

   No es un adorno: sin él, un decorado sin fotografía deja media pantalla en
   blanco a la izquierda de los selectores, y quien lo mira no sabe si falta la
   imagen o si la página ha fallado. Con el mismo cuadro que tendría la foto y
   una línea de texto, el hueco queda explicado.

   Se prefiere esto a enseñar una foto de ejemplo: los tableros apilados no son
   de este decorado y la muestra de color mide 160 px, así que a este tamaño se
   vería pixelada. Mejor decir que no hay. */
.ct-decor__sin-foto {
	display: grid;
	place-items: center;
	margin: 0;
	padding: var(--ml-space-4, 1rem);
	border: 1px dashed var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-sunken, #f2ede5);
	min-height: 8rem;
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
	text-align: center;
}

.ct-decor__puntos {
	margin: var(--ml-space-2, 0.5rem) 0 0;
	padding-left: var(--ml-space-4, 1rem);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
}

/* --------------------------------------------------------------------------
   PASO 1 A DOS COLUMNAS: LO QUE SE MIRA A UN LADO, LO QUE SE DECIDE AL OTRO.

   Apilados, la foto y los tres selectores compiten por el mismo espacio
   vertical: o la foto es un sello de 8 rem —y entonces no se ve la textura, que
   es literalmente lo que se está comprando— o empuja las opciones fuera de la
   pantalla. En dos columnas cabe una foto de verdad SIN alejar las decisiones.

   El texto del decorado va DEBAJO de la foto, no al lado: describe lo que se
   está mirando.

   Solo desde 60rem. Por debajo no hay ancho para dos columnas útiles y se
   vuelve a apilar, con la foto acotada para que no se coma la pantalla.
   -------------------------------------------------------------------------- */
@media (min-width: 60rem) {

	.ct__step--material {
		display: grid;
		grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
		column-gap: var(--ml-space-6, 2rem);
		align-items: start;
	}

	.ct__step--material > .ct__step-title {
		grid-column: 1 / -1;
	}

	/* LA GALERÍA Y EL TEXTO SE SEPARAN: la foto a la izquierda, el texto debajo
	   de los selectores. Juntos en la columna estrecha dejaban media página en
	   blanco a la derecha —los tres selectores ocupan un tercio del alto de la
	   foto— y las características quedaban en una columna de 24 rem partiendo
	   cada frase en tres líneas.

	   Se hace con `display: contents`, que saca los hijos al grid del paso sin
	   romper el `<figure>`/`<figcaption>`: la foto y su texto siguen siendo una
	   unidad para quien lee el HTML.

	   Va con `:where()` para NO subir la especificidad. Es la trampa que este
	   proyecto ya ha pisado dos veces: `display` gana a `[hidden]`, así que una
	   regla de display más específica que la de ocultar habría enseñado los seis
	   decorados a la vez. Con `:where()` la regla pesa lo que una clase y
	   `.ct-decor [hidden]` sigue mandando. */
	:where(.ct__step--material) > .ct-decor,
	:where(.ct__step--material) .ct-decor__ficha {
		display: contents;
	}

	/* Las filas se dicen a mano. En el DOM los selectores van antes que la ficha
	   —es el orden en el que se lee, y el que vale sin CSS—, así que el reparto
	   automático los pondría en la fila 2 y mandaría la foto a la 3. */
	/* La galería abarca las DOS filas de contenido. Ocupando solo la suya, esa
	   fila crecía hasta el alto de la foto y empujaba el texto por debajo de
	   ella: quedaba a media página de los selectores que describe, con un hueco
	   en medio. Abarcando ambas, cada fila mide lo suyo y el texto sube a donde
	   se está eligiendo. */
	.ct__step--material .ct-decor__galeria,
	.ct__step--material .ct-decor__sin-foto {
		grid-row: 2 / span 2;
		grid-column: 1;
		align-self: start;

		/* ACOMPAÑA AL SCROLL (cliente, 28/9/2026): con 27 decorados la lista
		   baja más que la foto, y al elegir uno de los de abajo había que volver
		   arriba para verlo. Pegajosa dentro de sus dos filas —la de los
		   selectores y la del texto—, así que se suelta al acabar el paso 1 y no
		   invade el 2. El `top` es el mismo que el del resumen: esquiva la
		   cabecera pegajosa del tema. */
		position: sticky;
		top: calc(var(--ml-header-height, 0px) + var(--ml-space-3, 0.75rem));
	}

	.ct__step--material > .ct__fields {
		grid-row: 2;
		grid-column: 2;
	}

	/* SIN FOTO, UNA SOLA COLUMNA (4/10/2026): antes de elegir nada, y sin foto
	   de arranque de la sección, la columna de la foto se quedaría vacía. */
	.ct__step--sin-foto.ct__step--material > .ct__fields,
	.ct__step--sin-foto.ct__step--material .ct-decor__texto {
		grid-column: 1 / -1;
	}

	/* Y las muestras, al doble por fila: a todo el ancho, tres por fila las
	   ponía al doble de tamaño. Así miden lo mismo que con la foto al lado. */
	.ct__step--sin-foto .ct-choice--muestras .ct-choice__options {
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	/* El aire de arriba lo pone esta regla y no el `gap` de la columna: el `gap`
	   es el mismo para las dos y aquí hace falta más, porque lo que queda encima
	   son botones con su propio marco. Pegado al último, el nombre del decorado
	   se leía como la etiqueta de ese botón. */
	.ct__step--material .ct-decor__texto {
		grid-row: 3;
		grid-column: 2;
		align-self: start;
		margin-top: var(--ml-space-6, 2rem);
	}
}

/* En una sola columna la foto deja de ser una miniatura al lado del texto y pasa
   a ser una banda encima. Cuadrada ocupaba casi una pantalla entera y empujaba
   fuera de la vista el nombre y las características, que es lo que se ha venido
   a leer: apaisada y con tope de alto cabe todo junto. */
@media (max-width: 40rem) {

	.ct-decor__ficha {
		grid-template-columns: minmax(0, 1fr);
	}

	.ct-decor__foto {
		max-height: 12rem;
		aspect-ratio: 16 / 9;
	}
}

/* --------------------------------------------------------------------------
   MECANIZADO (OPCIONAL): la casilla, con su importe a la derecha (21/9/2026).

   ES UNA TARJETA COMO LAS OPCIONES DEL PASO 1, no una casilla nativa (cliente,
   22/9/2026: «casi no se aprecia, y el cliente quiere que la gente no pase por
   alto esta parte»). El input queda transparente y del tamano de la tarjeta
   —sigue recibiendo el foco y el clic— y la casilla se dibuja: un cuadro de
   1,5 rem con el aspa en el color de accion al marcar. Marcada, la tarjeta
   entera cambia de borde y de fondo, que es lo que se ve desde lejos.

   El bloque del plano de debajo se ensena al marcarla; se oculta con clase y
   con `hidden`, porque en este proyecto `display` le ha ganado al atributo.
   -------------------------------------------------------------------------- */

.ct-mecanizado {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ml-space-3, 0.75rem) var(--ml-space-4, 1rem);
	padding: var(--ml-space-4, 1rem);
	border: 2px solid var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface, #faf7f2);
	cursor: pointer;
	transition: border-color 120ms ease, background-color 120ms ease;
}

.ct-mecanizado:hover {
	border-color: var(--ml-brand, #0e655e);
}

.ct-mecanizado:has(.ct-mecanizado__casilla:checked) {
	border-color: var(--ml-brand, #0e655e);
	background: var(--ml-brand-subtle, #e2f0ee);
}

.ct-mecanizado:has(.ct-mecanizado__casilla:focus-visible) {
	box-shadow: var(--ml-focus-ring);
}

/* El input de verdad: invisible, pero ocupa la tarjeta entera (foco y clic). */
.ct-mecanizado__casilla {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

/* La casilla dibujada. */
.ct-mecanizado__caja {
	flex: 0 0 auto;
	position: relative;
	width: 1.5rem;
	height: 1.5rem;
	border: 2px solid var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface, #faf7f2);
	transition: border-color 120ms ease, background-color 120ms ease;
}

.ct-mecanizado:hover .ct-mecanizado__caja {
	border-color: var(--ml-brand, #0e655e);
}

.ct-mecanizado__casilla:checked ~ .ct-mecanizado__caja {
	border-color: var(--ml-brand, #0e655e);
	background: var(--ml-brand, #0e655e);
}

/* El aspa: dos lados de un cuadrado girado, en blanco sobre el petroleo. */
.ct-mecanizado__caja::after {
	content: "";
	position: absolute;
	top: 0.1rem;
	left: 0.4rem;
	width: 0.4rem;
	height: 0.8rem;
	border: solid var(--ml-text-on-brand, #ffffff);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
	opacity: 0;
}

.ct-mecanizado__casilla:checked ~ .ct-mecanizado__caja::after {
	opacity: 1;
}

.ct-mecanizado__texto {
	flex: 1 1 14rem;
	font-size: var(--ml-text-base, 1rem);
	font-weight: var(--ml-weight-medium, 500);
	color: var(--ml-text, #2b2622);
}

.ct-plan {
	margin-top: var(--ml-space-4, 1rem);
}

.ct-plan[hidden],
.ct-plan.is-hidden {
	display: none;
}

/* --------------------------------------------------------------------------
   ARCHIVOS ADJUNTOS

   La lista existe porque un `<input type="file" multiple>` no acumula: al
   elegir un segundo archivo se pierde el primero, y el campo solo dice «2
   archivos», ni cuáles ni con qué quitarlos. La lista la mantiene el
   JavaScript; esto es cómo se ve.
   -------------------------------------------------------------------------- */

.ct-plan__lista {
	margin: var(--ml-space-2, 0.5rem) 0 0;
	padding: 0;
	list-style: none;
}

.ct-plan__lista:empty {
	display: none;
}

.ct-plan__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ml-space-2, 0.5rem);
	padding: var(--ml-space-1, 0.25rem) var(--ml-space-2, 0.5rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface, #faf7f2);
	font-size: var(--ml-text-sm, 0.875rem);
}

.ct-plan__item + .ct-plan__item {
	margin-top: var(--ml-space-1, 0.25rem);
}

/* El nombre puede ser largo y no debe empujar al botón fuera de la caja. */
.ct-plan__nombre {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.ct-plan__quitar {
	flex: 0 0 auto;
	width: 1.75rem;
	height: 1.75rem;
	padding: 0;
	border: 0;
	border-radius: var(--ml-radius-sm, 4px);
	background: none;
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-lg, 1.125rem);
	line-height: 1;
	cursor: pointer;
}

.ct-plan__quitar:hover {
	color: var(--ml-danger, #a32d2d);
}

.ct-plan__quitar:focus-visible {
	outline: 2px solid var(--ml-brand, #0e655e);
	outline-offset: 2px;
}

/* ==========================================================================
   Patas del escritorio (cliente, 27/9/2026)
   Un paso opcional: «Sin patas» y una tarjeta por modelo, en rejilla; al
   elegir uno aparece cuántas. El radio de verdad ocupa la tarjeta entera
   (foco y clic), como la casilla del mecanizado.
   ========================================================================== */

/* COMO EL PASO 1 (28/9/2026): la foto grande de la pata elegida a un lado y
   las opciones al otro; apiladas por debajo de 60rem, la foto encima. */
.ct-patas-paso {
	display: grid;
	gap: var(--ml-space-4, 1rem);
}

@media (min-width: 60rem) {
	.ct-patas-paso {
		grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
		column-gap: var(--ml-space-6, 2rem);
		align-items: start;
	}

	/* Y ACOMPAÑA AL SCROLL, como la del paso 1 (operador, 28/9/2026): la lista
	   de patas es más alta que la foto. Pegajosa dentro de su rejilla, así que
	   se suelta al acabar el paso y no invade el siguiente; el `top` es el del
	   paso 1, que esquiva la cabecera pegajosa del tema. */
	.ct-patas__vista {
		position: sticky;
		top: calc(var(--ml-header-height, 0px) + var(--ml-space-3, 0.75rem));
	}
}

.ct-patas__vista {
	min-width: 0;
}

/* Sin patas, o una pata sin fotos: un recuadro del tamaño de la foto. */
.ct-patas__vacia {
	display: grid;
	place-items: center;
	margin: 0;
	aspect-ratio: 1;
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-sunken, #f2ede5);
	color: var(--ml-text-muted, #666d72);
}

@media (max-width: 59.99rem) {
	.ct-patas__vacia {
		aspect-ratio: 4 / 3;
		max-height: 16rem;
	}
}

.ct-patas__vacia[hidden],
.ct-patas__galeria[hidden],
.ct-patas__vista[hidden] {
	display: none;
}

/* EN EL MÓVIL, DEBAJO DE LA OPCIÓN PULSADA (5/10/2026): el guion la mueve a la
   lista; ahí ocupa la fila entera y el recuadro «Sin patas» no hace falta. */
.ct-patas__vista.is-en-lista {
	grid-column: 1 / -1;
}

.ct-patas__vista.is-en-lista .ct-patas__vacia {
	display: none;
}

/* LA GALERÍA ES LA DEL DECORADO (5/10/2026); la foto de una pata se ve
   entera: es una pieza alta y estrecha, y recortada al cuadrado se perdía. */
.ct-patas__galeria .ct-decor__foto {
	object-fit: contain;
	/* Las fotos de las patas vienen sobre blanco: sin franjas grises al lado. */
	background: var(--ml-surface-raised, #ffffff);
}

.ct-patas__lado {
	display: grid;
	gap: var(--ml-space-4, 1rem);
	min-width: 0;
}

.ct-patas {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: var(--ml-space-3, 0.75rem);
	margin: 0;
	padding: 0;
	border: 0;
}

.ct-patas__opcion {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--ml-space-3, 0.75rem);
	padding: var(--ml-space-3, 0.75rem);
	border: 2px solid var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface, #faf7f2);
	cursor: pointer;
	transition: border-color 120ms ease, background-color 120ms ease;
}

.ct-patas__opcion:hover {
	border-color: var(--ml-brand, #0e655e);
}

.ct-patas__opcion:has(.ct-patas__input:checked) {
	border-color: var(--ml-brand, #0e655e);
	background: var(--ml-brand-subtle, #e2f0ee);
}

.ct-patas__opcion:has(.ct-patas__input:focus-visible) {
	box-shadow: var(--ml-focus-ring);
}

.ct-patas__input {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.ct-patas__foto {
	flex: 0 0 auto;
	width: 4rem;
	height: 4rem;
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface-sunken, #f2ede5);
	object-fit: contain;
}

/* «Sin patas»: un guion en el hueco de la foto. */
.ct-patas__foto--ninguna {
	display: grid;
	place-items: center;
}

.ct-patas__foto--ninguna::before {
	content: "";
	width: 1.25rem;
	height: 2px;
	background: var(--ml-text-muted, #666d72);
}

.ct-patas__texto {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	min-width: 0;
}

.ct-patas__nombre {
	font-weight: var(--ml-weight-bold, 700);
}

.ct-patas__detalle {
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
}

.ct-patas__precio {
	color: var(--ml-brand, #0e655e);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-patas__cuantas {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--ml-space-3, 0.75rem);
	margin-top: var(--ml-space-3, 0.75rem);
	padding: var(--ml-space-3, 0.75rem) var(--ml-space-4, 1rem);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-sunken, #f2ede5);
}

.ct-patas__cuantas[hidden] {
	display: none;
}

.ct-patas__cuantas-label {
	font-weight: var(--ml-weight-bold, 700);
}

.ct-patas__contador {
	display: inline-flex;
	align-items: center;
	border: 1px solid var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-surface, #faf7f2);
}

.ct-patas__paso {
	width: 2.75rem;
	height: 2.75rem;
	border: 0;
	background: transparent;
	color: var(--ml-brand, #0e655e);
	font-size: 1.25rem;
	cursor: pointer;
	touch-action: manipulation;
}

.ct-patas__numero {
	width: 3.5rem;
	border: 0;
	background: transparent;
	font: inherit;
	font-weight: var(--ml-weight-bold, 700);
	text-align: center;
	-moz-appearance: textfield;
	appearance: textfield;
}

.ct-patas__numero::-webkit-inner-spin-button,
.ct-patas__numero::-webkit-outer-spin-button {
	margin: 0;
	-webkit-appearance: none;
}

/*
 * EL PASO 0 DE BALDAS Y ESCRITORIOS: «Madera natural» o «Tableros» (cliente,
 * 28/9/2026). Dos tarjetas grandes con foto, que es lo unico que hay que decidir
 * al entrar; elegida la gama, se queda en una linea con el enlace a la otra.
 */
/*
 * LA ELECCIÓN ES LA PROTAGONISTA (operador, 29/9/2026): en la página de
 * Encimeras «competía» con las tarjetas de «Así de fácil» y la comparativa,
 * que explican pero no se eligen. Panel propio con filete de acción arriba y
 * sombra, la pregunta en tamaño de título y tarjetas más grandes.
 */
.ct-gamas {
	margin: 0 0 var(--ml-space-6, 2rem);
	padding: var(--ml-space-5, 1.5rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-top: 4px solid var(--ml-brand, #0e655e);
	border-radius: var(--ml-radius-lg, 12px);
	background: var(--ml-surface-raised, #ffffff);
	box-shadow: var(--ml-shadow-2, 0 2px 8px rgba(43, 38, 34, 0.10));
}

.ct-gamas__pregunta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--ml-space-1, 0.25rem) var(--ml-space-3, 0.75rem);
	margin: 0 0 var(--ml-space-4, 1rem);
	font-size: var(--ml-text-2xl, clamp(1.5rem, 1.3rem + 1vw, 2rem));
	font-weight: var(--ml-weight-bold, 700);
	line-height: 1.2;
}

/* Tarjetas de ancho fijo: caben cuatro en escritorio, y dos o tres no se
   estiran a lo ancho de la página. */
.ct-gamas__opciones {
	display: grid;
	grid-template-columns: repeat(auto-fill, 17rem);
	gap: var(--ml-space-4, 1rem);
}

@media (max-width: 40rem) {
	.ct-gamas {
		padding: var(--ml-space-4, 1rem);
	}

	.ct-gamas__opciones {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--ml-space-3, 0.75rem);
	}
}

.ct-gama {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-1, 0.25rem);
	overflow: hidden;
	padding: 0 0 var(--ml-space-4, 1rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-lg, 12px);
	background: var(--ml-surface-raised, #ffffff);
	color: var(--ml-text, #2b2622);
	text-decoration: none;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
	touch-action: manipulation;
}

.ct-gama:hover,
.ct-gama:focus-visible {
	border-color: var(--ml-brand, #0e655e);
	box-shadow: inset 0 0 0 1px var(--ml-brand, #0e655e);
}

.ct-gama__foto {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	margin-bottom: var(--ml-space-3, 0.75rem);
	object-fit: cover;
}

.ct-gama__foto--vacia {
	background: var(--ml-surface-sunken, #f2ede5);
}

.ct-gama__nombre {
	padding: 0 var(--ml-space-4, 1rem);
}

.ct-gama__nombre {
	font-size: var(--ml-text-xl, clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem));
	font-weight: var(--ml-weight-bold, 700);
}

/* Lo que se pulsa tiene que parecerlo: «Elegir →» abajo de cada tarjeta. */
.ct-gama__elegir {
	margin-top: auto;
	padding: var(--ml-space-2, 0.5rem) var(--ml-space-4, 1rem) 0;
	color: var(--ml-brand, #0e655e);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-gama:hover .ct-gama__elegir,
.ct-gama:focus-visible .ct-gama__elegir {
	text-decoration: underline;
}

/* Qué es cada material, en una frase: se lee antes de decidir. */
.ct-gama__texto {
	padding: 0 var(--ml-space-4, 1rem);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
	line-height: 1.45;
}

.ct-gamas__ayuda {
	margin-left: var(--ml-space-2, 0.5rem);
	color: var(--ml-brand, #0e655e);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: var(--ml-weight-normal, 400);
}

/* Cuánto hay para elegir, en el color de acción: es lo que invita a entrar. */
.ct-gama__dato {
	padding: 0 var(--ml-space-4, 1rem);
	color: var(--ml-brand, #0e655e);
	font-size: var(--ml-text-base, 1rem);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-gamas--elegida {
	padding: var(--ml-space-4, 1rem);
}

.ct-gamas--elegida .ct-gamas__pregunta {
	margin-bottom: var(--ml-space-3, 0.75rem);
	font-size: var(--ml-text-lg, 1.125rem);
}

.ct-gamas--elegida .ct-gamas__opciones {
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
	gap: var(--ml-space-2, 0.5rem);
}

.ct-gamas--elegida .ct-gama {
	flex-direction: row;
	align-items: center;
	gap: var(--ml-space-3, 0.75rem);
	padding: 0;
	border-radius: var(--ml-radius-md, 8px);
}

.ct-gamas--elegida .ct-gama__foto {
	flex: 0 0 4.5rem;
	width: 4.5rem;
	height: 3.5rem;
	aspect-ratio: auto;
	margin: 0;
}

.ct-gamas--elegida .ct-gama__nombre {
	min-width: 0;
	padding: 0 var(--ml-space-3, 0.75rem) 0 0;
	font-size: var(--ml-text-base, 1rem);
	hyphens: auto;
	overflow-wrap: break-word;
}

.ct-gamas--elegida .ct-gama[aria-current="true"] {
	border-color: var(--ml-brand, #0e655e);
	box-shadow: inset 0 0 0 1px var(--ml-brand, #0e655e);
	background: var(--ml-brand-subtle, #e2f0ee);
}

@media (max-width: 40rem) {
	.ct-gamas--elegida .ct-gamas__opciones {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.ct-gamas--elegida .ct-gama {
		gap: var(--ml-space-2, 0.5rem);
	}

	.ct-gamas--elegida .ct-gama__foto {
		flex-basis: 2rem;
		width: 2rem;
		height: 3rem;
	}

	.ct-gamas--elegida .ct-gama__nombre {
		padding-right: var(--ml-space-2, 0.5rem);
		font-size: var(--ml-text-sm, 0.875rem);
	}
}

@media (prefers-reduced-motion: reduce) {
	.ct-gama {
		transition: none;
	}
}

/* --------------------------------------------------------------------------
   EL TIPO DE MADERA EN TARJETAS, DENTRO DEL PASO 1 (4/10/2026).

   Las mismas piezas que la tarjeta del paso previo (`.ct-gama__*`), dentro del
   botón de opción: el radio sigue debajo para el teclado y el lector, y lo
   marcado se ve con el borde de acción como cualquier otra opción.
   -------------------------------------------------------------------------- */
.ct-choice--tarjetas .ct-choice__options {
	grid-template-columns: minmax(0, 1fr);
	gap: var(--ml-space-2, 0.5rem);
}

/* HORIZONTALES: foto a la izquierda y texto a la derecha. En la columna del
   paso 1 tres tarjetas verticales median más que la foto grande. */
.ct-choice--tarjetas .ct-choice__text {
	display: grid;
	grid-template-columns: 7rem minmax(0, 1fr);
	grid-auto-rows: min-content;
	align-content: center;
	column-gap: var(--ml-space-3, 0.75rem);
	row-gap: var(--ml-space-1, 0.25rem);
	min-height: 7rem;
	padding: 0 var(--ml-space-3, 0.75rem) 0 0;
	overflow: hidden;
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-raised, #ffffff);
	font-size: var(--ml-text-base, 1rem);
	line-height: 1.3;
	text-align: left;
}

.ct-choice--tarjetas .ct-gama__foto {
	grid-row: 1 / span 3;
	align-self: stretch;
	width: 100%;
	height: 100%;
	aspect-ratio: auto;
	margin: 0;
}

.ct-choice--tarjetas .ct-gama__nombre,
.ct-choice--tarjetas .ct-gama__texto,
.ct-choice--tarjetas .ct-gama__dato {
	grid-column: 2;
	padding: 0;
}

.ct-choice--tarjetas .ct-gama__nombre {
	padding-top: var(--ml-space-2, 0.5rem);
	font-size: var(--ml-text-lg, 1.125rem);
}

.ct-choice--tarjetas .ct-gama__texto {
	font-size: var(--ml-text-xs, 0.75rem);
}

.ct-choice--tarjetas .ct-gama__dato {
	padding-bottom: var(--ml-space-2, 0.5rem);
	font-size: var(--ml-text-sm, 0.875rem);
}
