/**
 * Lienzo de mecanizados: la encimera vista desde arriba, con sus huecos.
 *
 * Va en su propio fichero y no en configurador.css porque es una pieza
 * autónoma: se instancia una por fila y no comparte nada con la tabla de cortes
 * salvo el sitio donde se pinta.
 *
 * Los colores salen de los tokens del tema, con reserva para el caso de que el
 * plugin se use sin él. Las reservas son los valores REALES de tokens.css, y
 * eso ya no es una promesa escrita: lo comprueba
 * `ProyectoCoherenteTest::test_las_reservas_de_los_plugins_coinciden_con_los_tokens`,
 * porque esta misma cabecera afirmaba estar al día con dos que no lo estaban
 * —con el tema propio activo la reserva no se usa nunca, así que nada avisa—.
 */

/* Los `display` de aquí abajo ganan al `display: none` que el navegador aplica a
   [hidden], así que sin esta regla lo que se oculta desde JavaScript se sigue
   viendo: la paleta es flex y la lista de huecos es grid. */
.ct-lienzo[hidden],
.ct-lienzo [hidden] {
	display: none;
}

/* EL PLANO A TODO LO ANCHO, y los campos debajo.
   Una encimera es una tira muy alargada —2400 × 600 es cuatro a uno—, así que
   en media columna el dibujo se queda en una franja de tres centímetros donde
   no se distingue un fregadero de una placa. Es la pieza que hay que poder
   mirar; los campos se leen igual en una rejilla debajo. */
.ct-lienzo {
	display: grid;
	gap: var(--ml-space-4, 1rem);
	grid-template-columns: minmax(0, 1fr);
}

.ct-lienzo__paleta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--ml-space-2, 0.5rem);
}

.ct-lienzo__dibujo {
	min-width: 0;
	padding: var(--ml-space-3, 0.75rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-raised, #ffffff);
}

.ct-lienzo__svg {
	display: block;
	width: 100%;
	height: auto;
	/* Sin esto, un arrastre sobre el dibujo hace desplazarse la página en un
	   móvil y el hueco no llega a moverse. */
	touch-action: none;
}

.ct-lienzo__pieza {
	fill: var(--ml-surface-sunken, #f2ede5);
	stroke: var(--ml-text, #2b2622);
	stroke-width: 4;
}

/* La banda prohibida se ve desde el principio: una regla que solo aparece
   cuando la incumples se vive como un fallo de la web, no como una norma. */
.ct-lienzo__margen {
	pointer-events: none;
	opacity: 0.55;
}

.ct-lienzo__raya {
	stroke: var(--ml-border-strong, #c9c0b4);
	stroke-width: 6;
}

.ct-lienzo__hueco {
	fill: var(--ml-surface-raised, #ffffff);
	stroke: var(--ml-brand, #0e655e);
	stroke-width: 6;
	cursor: grab;
}

.ct-lienzo__hueco:focus-visible {
	outline: none;
	stroke-width: 12;
}

.ct-lienzo__hueco--sel {
	fill: var(--ml-brand-subtle, #e2f0ee);
	stroke-width: 10;
}

.ct-lienzo__hueco--mal {
	stroke: var(--ml-danger, #a32d2d);
	fill: var(--ml-danger-subtle, #fcebeb);
}

/* El eje del imán: mientras un orificio está pegado al centro de un fregadero.
   En el OCRE de acento y no en el color de acción: por ese mismo eje pasa la
   cota vertical del hueco seleccionado, que ya es petróleo y fina, y las dos
   se fundían. Es lo que hace cualquier programa de diseño con sus guías
   magnéticas —un color que no usa para nada más— y aquí es un trazo, no una
   superficie. Por encima de los huecos y sin recibir el puntero, que sigue
   arrastrando lo de debajo. */
.ct-lienzo__guia {
	pointer-events: none;
}

.ct-lienzo__iman {
	stroke: var(--ml-accent, #b0762a);
	stroke-width: 7;
	stroke-dasharray: 18 12;
	stroke-linecap: round;
}

.ct-lienzo__medida {
	fill: var(--ml-text-muted, #666d72);
}

.ct-lienzo__cotas {
	/* Se rehacen enteras en cada movimiento, así que no pueden recibir eventos:
	   el nodo bajo el puntero desaparecería a media interacción. */
	pointer-events: none;
}

.ct-lienzo__cota {
	stroke: var(--ml-brand, #0e655e);
	stroke-width: 3;
}

.ct-lienzo__cota-texto {
	fill: var(--ml-brand, #0e655e);
	paint-order: stroke;
	stroke: var(--ml-surface-sunken, #f2ede5);
	stroke-width: 8;
}

.ct-lienzo__huecos {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: var(--ml-space-3, 0.75rem);
	align-items: start;
}

.ct-lienzo__item {
	padding: var(--ml-space-3, 0.75rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface, #faf7f2);
}

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

.ct-lienzo__item-head {
	display: flex;
	align-items: center;
	gap: var(--ml-space-2, 0.5rem);
	margin-bottom: var(--ml-space-2, 0.5rem);
}

.ct-lienzo__item-nombre {
	flex: 1 1 auto;
	margin: 0;
	font-weight: var(--ml-weight-medium, 500);
}

.ct-lienzo__campos {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--ml-space-2, 0.5rem);
}

.ct-lienzo__campo {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-1, 0.25rem);
	font-size: var(--ml-text-xs, 0.75rem);
	color: var(--ml-text-muted, #666d72);
}

.ct-lienzo__campo input {
	width: 100%;
}

.ct-lienzo__avisos {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-1, 0.25rem);
}

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

.ct-lienzo__aviso {
	padding: var(--ml-space-2, 0.5rem) var(--ml-space-3, 0.75rem);
	border-radius: var(--ml-radius-sm, 4px);
	background: var(--ml-danger-subtle, #fcebeb);
	color: var(--ml-danger, #a32d2d);
	font-size: var(--ml-text-sm, 0.875rem);
}

/* La nota que explica que los huecos se repiten en todas las piezas de la fila.
   Va sobre el lienzo porque es una condición de lo que se está dibujando, no un
   consejo suelto. */
.ct-note {
	margin: 0 0 var(--ml-space-3, 0.75rem);
	font-size: var(--ml-text-sm, 0.875rem);
	color: var(--ml-text-muted, #666d72);
}

/* El aviso que ocupa el sitio del lienzo mientras la pieza no tiene medidas.
   Se le da el aire del dibujo que va a sustituir, para que se lea como «aquí
   irá algo» y no como un error. */
.ct-lienzo__vacio {
	margin: 0;
	padding: var(--ml-space-5, 1.5rem);
	border: 1px dashed var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-raised, #ffffff);
	color: var(--ml-text-muted, #666d72);
	text-align: center;
}

/* --------------------------------------------------------------------------
 * La vista de la pieza (3/10/2026): el mismo dibujo que el lienzo, de solo
 * lectura, encima de la tabla de medidas en las secciones sin huecos. Usa las
 * clases del lienzo para la pieza y las cotas; aquí solo va lo suyo.
 * ------------------------------------------------------------------------ */

.ct-vista {
	margin: 0 0 var(--ml-space-4, 1rem);
	padding: var(--ml-space-3, 0.75rem);
	border: 1px solid var(--ml-border, #e5ded4);
	border-radius: var(--ml-radius-md, 8px);
	background: var(--ml-surface-raised, #ffffff);
}

/* `display` propio anula el `hidden` del navegador. */
.ct-vista[hidden] {
	display: none;
}

.ct-vista__titulo {
	margin: 0 0 var(--ml-space-2, 0.5rem);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: var(--ml-weight-medium, 500);
}

/* Tope de alto: una pieza estrecha y larga no puede empujar la tabla fuera
   de la pantalla. El SVG mantiene su proporción dentro de la caja. */
.ct-vista__svg {
	max-height: 15rem;
	/* No se arrastra nada aquí: que el dedo pueda desplazar la página. */
	touch-action: auto;
}

.ct-vista__veta line {
	stroke: var(--ml-text, #2b2622);
	stroke-opacity: 0.22;
	stroke-width: 3;
}

.ct-vista__cantos line {
	stroke: var(--ml-brand, #0e655e);
	stroke-linecap: butt;
}

/* --------------------------------------------------------------------------
   LA VISTA DE LA PIEZA (3/10/2026), con hueco
   fijo —no aparece ni desaparece, así la tabla no salta— y un aviso cuando
   aún no hay medidas. La pieza se cambia pulsando su fila.
   -------------------------------------------------------------------------- */
.ct-vista--fija {
	position: relative;
	display: grid;
	grid-template-columns: 1fr auto;
	grid-template-rows: 2rem 15rem;
	align-items: center;
	column-gap: var(--ml-space-3, 0.75rem);
}

.ct-vista--fija .ct-vista__titulo {
	margin: 0;
	color: var(--ml-text, #2b2622);
	font-weight: var(--ml-weight-bold, 700);
}

.ct-vista--fija > svg,
.ct-vista--fija > .ct-vista__vacia {
	grid-column: 1 / -1;
	grid-row: 2;
	justify-self: center;
}

.ct-vista--fija .ct-vista__svg {
	max-width: 100%;
	max-height: 15rem;
}

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

.ct-vista.is-vacia .ct-vista__vacia {
	display: block;
}

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

/* EN ENCIMERAS LA VISTA LLEVA EL LIENZO DE HUECOS (5/10/2026): el mismo hueco
   fijo, el mismo título y el mismo aviso sin medidas, y dentro el lienzo de la
   pieza activa. Va DETRÁS de la tabla y de «Añadir otra pieza» (configurador.css):
   con la lista de huecos mide más que la vista de las otras secciones y,
   encima, dejaba las piezas fuera de la pantalla. Detrás no empuja nada, así
   que mide lo que mida el lienzo. */
.ct-vista--lienzo.ct-vista--fija {
	grid-template-rows: auto auto;
	row-gap: var(--ml-space-3, 0.75rem);
}

.ct-vista--lienzo > .ct-vista__lienzo {
	display: grid;
	grid-column: 1 / -1;
	grid-row: 2;
	align-self: start;
	gap: var(--ml-space-3, 0.75rem);
	min-width: 0;
}

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

/* La vista ya es el marco: dentro, el dibujo sin un segundo recuadro. */
.ct-vista__lienzo .ct-lienzo__dibujo {
	padding: 0;
	border: 0;
}

.ct-vista__lienzo > .ct-note {
	margin: 0;
}


/* La fila que se está viendo, resaltada en la tabla. */
.ct-cuts__row.is-activa > td {
	background: var(--ml-brand-subtle, #e2f0ee);
}

.ct-cuts__row.is-activa > td:first-child {
	box-shadow: inset 3px 0 0 var(--ml-brand, #0e655e);
}

/* En el móvil la fila se apila en bloque: se resalta el bloque entero. */
@media ( max-width: 37.5rem ) {
	/* Aire para la barra, en todas las filas: así cambiar de pieza no mueve
	   nada de sitio. */
	.ct-acordeon .ct-cuts__row {
		padding-inline: var(--ml-space-3, 0.75rem);
	}

	.ct-cuts__row.is-activa {
		border-radius: var(--ml-radius-sm, 4px);
		background: var(--ml-brand-subtle, #e2f0ee);
		box-shadow: inset 3px 0 0 var(--ml-brand, #0e655e);
	}

	.ct-cuts__row.is-activa > td,
	.ct-cuts__row.is-activa > td:first-child {
		background: transparent;
		box-shadow: none;
	}
}

/* LOS CANTOS (3/10/2026): casillas con su precio en el bloque «Cantear», junto
   al dibujo de la pieza activa; los lados del dibujo también se pulsan. En la
   fila de la tabla, un resumen. */
.ct-vista__guia {
	stroke: var(--ml-border-strong, #c9c0b4);
	pointer-events: none;
}

.ct-vista__lado {
	stroke: transparent;
	cursor: pointer;
	outline: none;
}

.ct-vista__lado:hover,
.ct-vista__lado:focus-visible {
	stroke: var(--ml-brand, #0e655e);
	stroke-opacity: 0.25;
}

/* El bloque de cantos, junto al dibujo de la pieza activa. */
.ct-vista__cantos {
	display: flex;
	flex-direction: column;
	gap: var(--ml-space-2, 0.5rem);
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	font-size: var(--ml-text-sm, 0.875rem);
}

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

.ct-vista__cantos-titulo {
	margin-bottom: var(--ml-space-1, 0.25rem);
	padding: 0;
	font-weight: var(--ml-weight-bold, 700);
}

/* Escritorio: el dibujo a la izquierda y los cantos a la derecha. */
@media ( min-width: 37.5rem ) {
	.ct-vista--fija.con-cantos {
		grid-template-columns: minmax(0, 1fr) 14rem;
	}

	.ct-vista--fija.con-cantos > svg,
	.ct-vista--fija.con-cantos > .ct-vista__vacia {
		grid-column: 1;
	}

	.ct-vista--fija.con-cantos > .ct-vista__cantos {
		grid-column: 2;
		grid-row: 2;
		align-self: center;
	}

}

/* Móvil: «Cantear» dentro de la pieza activa, en lugar de su resumen. */
.ct-vista__cantos.is-en-fila {
	margin-top: var(--ml-space-1, 0.25rem);
}

.ct-cuts__row [data-col="edges"]:has(.ct-vista__cantos.is-en-fila:not([hidden])) .ct-edges__resumen {
	display: none;
}

.ct-vista__cantos.is-en-fila .ct-vista__cantos-titulo {
	/* La celda ya lleva el rótulo «Cantos». */
	display: none;
}

.ct-cantos__casilla {
	display: flex;
	align-items: flex-start;
	gap: var(--ml-space-2, 0.5rem);
	line-height: 1.3;
	cursor: pointer;
}

.ct-cantos__casilla input {
	flex: none;
	margin-top: 0.1em;
}

.ct-cantos__precio {
	white-space: nowrap;
}

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


.ct-cantos__precio {
	color: var(--ml-brand-text, #0e655e);
	font-weight: var(--ml-weight-medium, 500);
}

/* La pieza que no puede ir al carrito: un icono de alerta junto a su número
   (3/10/2026). */
.ct-cuts__aviso {
	display: inline-grid;
	place-items: center;
	width: 1.15rem;
	height: 1.15rem;
	margin-left: var(--ml-space-1, 0.25rem);
	border-radius: var(--ml-radius-full, 999px);
	background: var(--ml-danger, #a32d2d);
	color: var(--ml-text-on-brand, #ffffff);
	font-size: 0.75rem;
	font-weight: var(--ml-weight-bold, 700);
	line-height: 1;
	vertical-align: middle;
}

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


/* Baldas y escritorios: se dice que van canteadas por los cuatro lados. */
.ct-vista__nota {
	grid-column: 1 / -1;
	margin: var(--ml-space-2, 0.5rem) 0 0;
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
	text-align: center;
}

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

/* El precio de cada pieza y el botón de duplicarla. */
.ct-cuts__precio {
	color: var(--ml-text, #2b2622);
	font-weight: var(--ml-weight-medium, 500);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

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

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

/* La barra del móvil: el total y el botón, siempre a mano. */
.ct-barra {
	display: none;
}

@media ( max-width: 56.25rem ) {
	.ct-barra {
		position: fixed;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 30;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--ml-space-3, 0.75rem);
		padding: var(--ml-space-3, 0.75rem) var(--ml-space-4, 1rem);
		padding-bottom: calc(var(--ml-space-3, 0.75rem) + env(safe-area-inset-bottom, 0px));
		border-top: 1px solid var(--ml-border, #e5ded4);
		background: var(--ml-surface-raised, #ffffff);
		box-shadow: 0 -4px 16px rgb(0 0 0 / 8%);
		transition: transform 160ms ease;
	}

	.ct-barra.is-oculta {
		transform: translateY(110%);
	}

	.ct-barra__total {
		margin: 0;
		font-size: var(--ml-text-xl, clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem));
		font-weight: var(--ml-weight-bold, 700);
		font-variant-numeric: tabular-nums;
	}

	/* Que la barra no tape el final de la página. */
	.ct {
		padding-bottom: 5rem;
	}
}

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

/*
 * EL DIBUJO DE UN TABLERO DESPIEZADO (10/10/2026). Lo pinta
 * `ConfiguradorTablerosLienzo.tablero()`, que usan el despiece del configurador
 * y el corte a medida del canal profesional; por eso vive aquí, con su guion.
 */
.ct-board {
	margin: 0 0 var(--ml-space-5, 1.5rem);
}

.ct-board__caption {
	margin-bottom: var(--ml-space-2, 0.5rem);
	color: var(--ml-text-muted, #666d72);
	font-size: var(--ml-text-sm, 0.875rem);
	font-weight: 500;
}

.ct-board__svg {
	display: block;
	width: 100%;
	height: auto;
	border: 1px solid var(--ml-border-strong, #c9c0b4);
	border-radius: var(--ml-radius-sm, 4px);
}

.ct-board__sheet {
	fill: var(--ml-surface-sunken, #f2ede5);
}

.ct-piece {
	stroke: var(--ml-surface-raised, #ffffff);
	stroke-width: 4;
}

/*
 * Un color por línea de corte, para poder seguir a simple vista qué pieza
 * corresponde a qué medida pedida. Tonos apagados: el dibujo informa, no
 * decora.
 */
.ct-piece--0 { fill: #c79a6a; }
.ct-piece--1 { fill: #7fa3a6; }
.ct-piece--2 { fill: #a98bb0; }
.ct-piece--3 { fill: #9db06f; }
.ct-piece--4 { fill: #cf9a8e; }
.ct-piece--5 { fill: #8296bd; }
.ct-piece--6 { fill: #c2b477; }
.ct-piece--7 { fill: #a98d78; }

.ct-piece__label {
	fill: #2b2722;
	font-family: var(--ml-font-sans, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
	text-anchor: middle;
	dominant-baseline: middle;
	pointer-events: none;
}
