/* ==========================================================================
   La Daurada Formularios — estilos de estructura/layout SOLAMENTE.
   Cero colores, tipografías o tamaños propios: todo vía las variables --mt-*
   que ya definen los dos temas (tema-daurada/mi-tema comparten el mismo
   design system, ver assets/css/variables.css de cada uno). Si algún día
   este plugin se usa en un sitio sin ese sistema, cada var() lleva un
   fallback razonable como segundo argumento.
   El botón de envío reutiliza el componente .mt-btn/.mt-btn--primary que ya
   existe en ambos temas -- este fichero NO define ningún botón propio.
   ========================================================================== */

.ldf-form {
	display: flex;
	flex-direction: column;
	gap: var(--mt-space-4, 1rem);
	max-width: 640px;
	font-family: var(--mt-font-body, sans-serif);
	color: var(--mt-color-text-body, #333333);
}

.ldf-field {
	display: flex;
	flex-direction: column;
	gap: var(--mt-space-2, 0.5rem);
}

.ldf-field label {
	font-size: var(--mt-font-size-sm, 0.875rem);
	/* `semibold` (600) y no `medium` (500): es el peso que usan las etiquetas
	   del checkout y las de la ficha del vale. Con 500, las de este conector
	   se veían más flojas que las de cualquier otro formulario. */
	font-weight: var(--mt-font-weight-semibold, 600);
	color: var(--mt-color-text-primary, #111111);
}

.ldf-required {
	color: var(--mt-color-error, #DC2626);
	margin-left: 0.15em;
}

.ldf-field input[type="text"],
.ldf-field input[type="email"],
.ldf-field input[type="tel"],
.ldf-field select,
.ldf-field textarea {
	font-family: inherit;
	font-size: var(--mt-font-size-base, 1rem);
	color: var(--mt-color-text-primary, #111111);
	background: var(--mt-color-bg-white, #ffffff);
	/* Fallback #767676 (no #e0e0e0): sobre fondo blanco da 4.54:1, por encima del 3:1 que
	   exige WCAG 1.4.11 para el contorno de un campo -- #e0e0e0 solo daba 1.32:1, casi
	   invisible (medido y reportado por otro equipo probando el plugin en un tema real). */
	border: var(--mt-border-width, 1px) var(--mt-border-style, solid) var(--mt-color-border, #767676);
	/* `md` (8px) y no `sm` (4px): es el radio que usa el checkout, que es el
	   formulario grande del sitio. Con `sm` los campos de contacto tenían la
	   esquina más viva que los del checkout, en dos páginas seguidas. */
	border-radius: var(--mt-radius-md, 8px);
	/* 12px arriba y abajo, 16px a los lados — lo mismo que el checkout. */
	padding: var(--mt-space-3, 0.75rem) var(--mt-space-4, 1rem);
	transition: var(--mt-transition-colors, border-color 0.2s ease);
}

/* 16px en móvil y 14px a partir de 768px, exactamente como el checkout.
 *
 * No es un adorno: por debajo de 16px, Safari en iOS hace ZOOM sobre el campo al
 * enfocarlo, y la página se queda descuadrada hasta que el visitante la aleja a
 * mano. Por eso el móvil se queda en `base` y solo el escritorio
 * —donde ese comportamiento no existe— baja a `sm`.
 *
 * Este conector tenía 16px fijos, así que en el escritorio sus campos eran un
 * punto más grandes que los del checkout. */
@media (min-width: 768px) {
	.ldf-field input[type="text"],
	.ldf-field input[type="email"],
	.ldf-field input[type="tel"],
	.ldf-field select,
	.ldf-field textarea {
		font-size: var(--mt-font-size-sm, 0.875rem);
	}
}

.ldf-field textarea {
	min-height: 8rem;
	resize: vertical;
}

.ldf-field select {
	appearance: auto;
}

/* Input de fichero: sin fondo/borde propios de .ldf-field (los navegadores ya dan su propio
   botón "Elegir fichero" con estilo del SO) -- solo tipografía/color heredados del tema. */
.ldf-field input[type="file"] {
	font-family: inherit;
	font-size: var(--mt-font-size-base, 1rem);
	color: var(--mt-color-text-primary, #111111);
}

.ldf-field__hint {
	margin: 0;
	font-size: var(--mt-font-size-xs, 0.75rem);
	color: var(--mt-color-text-secondary, #666666);
}

.ldf-field input:focus,
.ldf-field select:focus,
.ldf-field textarea:focus {
	outline: none;
	border-color: var(--mt-color-primary, #14B5C5);
	box-shadow: 0 0 0 3px var(--mt-color-focus-ring, rgba(20, 181, 197, 0.15));
}

.ldf-field input[aria-invalid="true"],
.ldf-field select[aria-invalid="true"],
.ldf-field textarea[aria-invalid="true"] {
	border-color: var(--mt-color-error, #DC2626);
}

/* El mensaje de error de un campo, con la misma pinta que en el resto del
   sitio: el círculo con la exclamación delante del texto.

   La icona sale de `--mt-icon-error`, que define el tema en variables.css —
   igual que ya se consumen de ahí los colores y los espaciados (ver la
   cabecera de includes/class-ldf-shortcode.php). Se lleva un SVG de reserva
   por si este connector acaba en un tema que no la declare: idéntico al del
   tema, pero aquí es la copia de emergencia, no la fuente.

   Antes no había icono. El tema sí lo ponía en el checkout y en los errores de
   MONEI, así que el mismo aviso salía de dos maneras según en qué formulario
   estuvieras. */
.ldf-error {
	display: flex;
	align-items: flex-start;
	gap: 4px;
	font-size: var(--mt-font-size-xs, 0.75rem);
	font-weight: var(--mt-font-weight-medium, 500);
	color: var(--mt-color-error, #DC2626);
	line-height: 1.4;
	min-height: 1em;
}

.ldf-error::before {
	content: '';
	flex-shrink: 0;
	display: inline-block;
	width: 12px;
	height: 12px;
	/* 0.2em y no 1px: la línea del mensaje mide 1,4em y el icono 12px, así que para
	   centrarlo hacen falta (16,8 - 12) / 2 = 2,4px con letra de 12px. Con 1px fijo
	   quedaba alto, y además no seguía el tamaño del texto si algún día cambia. */
	margin-top: 0.2em;
	/* `currentColor` y no el rojo: el icono tiene que seguir el color del TEXTO
	   del mensaje, no uno fijo. En el boletín del pie, el tema pasa ese texto a
	   blanco para que se lea sobre el azul de la franja — y con el rojo escrito
	   aquí salía el texto blanco y el icono rojo, que además contra ese azul
	   tampoco llegaba a contraste. Por omisión el texto ya es
	   `--mt-color-error`, así que en el resto de sitios no cambia nada. */
	background-color: currentColor;
	mask-image: var(--mt-icon-error, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E"));
	mask-size: contain;
	mask-repeat: no-repeat;
	-webkit-mask-image: var(--mt-icon-error, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='12'/%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'/%3E%3C/svg%3E"));
	-webkit-mask-size: contain;
	-webkit-mask-repeat: no-repeat;
}

/* Sin mensaje no hay icono, pero el hueco se queda reservado: así el
   formulario no pega un salto cuando aparece el primer error. Es la diferencia
   con el tema, que ahí sí oculta el elemento entero. */
.ldf-error:empty::before {
	content: none;
}

/* La casilla del consentimiento, cuando falta marcarla. En un checkbox nativo el
   `border-color` de la regla de arriba no se ve en la mayoría de navegadores, así que aquí
   se marca con `outline`, que sí pintan todos. No se usa `accent-color`: colorea la casilla
   SOLO cuando está marcada, que es justo el caso contrario al que hay que señalar. */
.ldf-consent input[type="checkbox"][aria-invalid="true"] {
	outline: 2px solid var(--mt-color-error, #DC2626);
	outline-offset: 2px;
}

/* El aviso del consentimiento empieza donde empieza la casilla, como CUALQUIER otro
   aviso del sitio.

   Antes iba sangrado hasta el texto de la etiqueta, con el argumento de que así se lee
   como parte de la frase que hay que aceptar. Dos motivos para deshacerlo:

   1. No lo conseguía. El sangrado empuja la fila entera, icono incluido, así que el
      TEXTO del aviso acababa 10px más a la derecha que el texto de la etiqueta. No
      quedaba alineado con nada.
   2. En el checkout, donde este mismo aviso lo pinta el tema, empezaba a la altura de
      la casilla. Dos formularios de la misma web decían lo mismo en dos sitios
      distintos, y el visitante no sabe que son dos programas.

   Ahora el icono forma columna con la casilla, que es lo que hacen los avisos del resto
   de campos con su propio campo. */
.ldf-consent .ldf-error {
	margin-top: var(--mt-space-1, 0.25rem);
}

.ldf-consent {
	font-size: var(--mt-font-size-sm, 0.875rem);
	color: var(--mt-color-text-secondary, #666666);
}

.ldf-consent label {
	display: flex;
	align-items: flex-start;
	/* 12px, los mismos que separan casilla y texto en las casillas del checkout
	   (.woocommerce-form__label-for-checkbox del tema). Aquí eran 8 y se notaba al
	   tener las dos delante. */
	gap: var(--mt-space-3, 0.75rem);
	font-weight: var(--mt-font-weight-regular, 400);
}

.ldf-consent input[type="checkbox"] {
	margin-top: 0.2em;
	flex-shrink: 0;
}

/* Las casillas no se estiran.
 *
 * Suena a perogrullada y por eso hacía falta escribirlo: el tema tenía en su
 * reset un `input, textarea { width: 100% }`, y esa regla también alcanza a un
 * checkbox. En la página de contacto la casilla del consentimiento pasaba a
 * medir los 346px de la columna y el texto que la acompaña quedaba aplastado
 * en 68px, desbordando la tarjeta. El reset del tema ya está arreglado, pero
 * este conector se pinta en dos sitios más (el checkout de WooCommerce y el
 * pie) y puede acabar en otro tema: no puede depender de que el reset de quien
 * lo aloje esté bien escrito.
 *
 * ⚠️ MEDIDA CONCRETA, NO `auto`. Aquí ponía `width: auto; height: auto`, con el
 * razonamiento de que la casilla la pinta el navegador y mide lo que mide. Eso
 * es cierto SOLO mientras nadie le quite el dibujo nativo: el tema la pinta con
 * `appearance: none` para poder darle el azul de la marca, y una casilla sin
 * dibujo nativo no tiene tamaño intrínseco -- con `height: auto` se quedaba en
 * 4 píxeles de alto, una rayita. Se veía en vivo el 2026-09-22.
 *
 * 18px es la medida del sistema de diseño de los dos temas. Un tema que quiera
 * otra la sobrescribe con más especificidad, como cualquier otra cosa de este
 * fichero. */
.ldf-form input[type="checkbox"],
.ldf-form input[type="radio"] {
	width: 18px;
	height: 18px;
	min-width: 18px;
	flex-shrink: 0;
}

/* El aviso de error, pegado al campo y no debajo del contador.
 *
 * En los campos con `maxlength` el tema inyecta un `.mt-char-counter` (su
 * main.js) justo detrás del `<textarea>`, o sea ENTRE el campo y el hueco del
 * error. El resultado era: campo, «0 / 5000», y el error una línea más abajo,
 * separado de lo que estaba señalando.
 *
 * `order` lo recoloca sin tocar el marcado, que lo pone el tema: el error
 * queda pegado al campo y el contador debajo. Al ser dos líneas distintas no
 * se pueden solapar, diga lo que diga el mensaje y mida lo que mida.
 *
 * Y sin mensaje no se reserva hueco cuando hay contador: si no, quedaba un
 * espacio en blanco entre el campo y el «0 / 5000». Es el mismo criterio que
 * ya sigue el conector de vales en su product-voucher.css. */
/* Con contador de caracteres, el aviso y el contador van en la MISMA línea: el aviso
   a la izquierda y el contador a la derecha, los dos justo debajo del campo, como dos
   columnas.
   
   Apilados uno sobre otro quedaba o bien el aviso lejos del campo (si iba debajo del
   contador) o bien el contador colgado al final (si iba debajo del aviso). Ninguno de
   los dos órdenes funcionaba, porque no son dos cosas seguidas: son dos notas del
   mismo campo.
   
   Hace falta rejilla y no flex porque el marcado no los tiene emparejados: el contador
   lo pone el tema (su main.js) detrás del <textarea>, y el aviso ya estaba. Con
   `grid-row: 3` en los dos, van a la misma fila diga lo que diga el orden del DOM.
   
   Las filas: 1 la etiqueta, 2 el campo, 3 el aviso y el contador. */
.ldf-field:has(.mt-char-counter) {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: baseline;
}

.ldf-field:has(.mt-char-counter) > label,
.ldf-field:has(.mt-char-counter) > textarea {
	grid-column: 1 / -1;
}

.ldf-field:has(.mt-char-counter) > .ldf-error {
	grid-column: 1;
	grid-row: 3;
	/* Sin mensaje no reserva altura: si no, quedaba un hueco entre el campo y el
	   contador. */
	min-height: 0;
}

.ldf-field:has(.mt-char-counter) > .mt-char-counter {
	grid-column: 2;
	grid-row: 3;
	/* El contador del tema lleva margen propio pensado para ir solo debajo del
	   campo; aquí lo coloca la rejilla. */
	margin-top: 0;
}

/* Sin contador, el aviso va justo detrás del campo y ya está. */
.ldf-field .ldf-error {
	order: 1;
}

.ldf-field .mt-char-counter {
	order: 2;
}

/* EL ÚLTIMO ELEMENTO DEL FORMULARIO NO DEJA AIRE DEBAJO.
   
   La franja de estado («Gracies! Hem rebut...») va después del botón y reserva altura
   aunque esté vacía, y el `gap` del formulario le añade otra. Entre las dos, debajo del
   botón había más espacio que encima del primer campo, y la tarjeta quedaba
   descentrada.
   
   El margen negativo cancela el `gap` cuando no hay mensaje. NO se oculta con
   `display: none` a propósito: es una región `aria-live`, y para que un lector de
   pantalla anuncie bien lo que aparece en ella, el elemento tiene que existir en el
   árbol de accesibilidad ANTES de que cambie el contenido. Si se oculta, algunos
   lectores no llegan a decirlo. */
.ldf-form__status:empty {
	min-height: 0;
	margin-top: calc(-1 * var(--mt-space-4, 1rem));
}

.ldf-consent a {
	color: var(--mt-color-primary-dark, var(--mt-color-primary, #14B5C5));
}

/* Checkbox SEGUNDO y opcional de alta a la newsletter -- separado visualmente del consentimiento
   RGPD obligatorio (.ldf-consent, arriba) con su propio espaciado, para que no se lean como la
   misma casilla. Mismo tamaño de fuente que el resto de campos (no el "secundario" de
   .ldf-consent): es una elección normal del formulario, no un aviso legal en letra pequeña. */
.ldf-newsletter-optin {
	margin-top: var(--mt-space-3, 0.75rem);
	padding-top: var(--mt-space-3, 0.75rem);
	border-top: var(--mt-border-width, 1px) var(--mt-border-style, solid) var(--mt-color-border, #767676);
}

.ldf-newsletter-optin label {
	display: flex;
	align-items: flex-start;
	gap: var(--mt-space-2, 0.5rem);
	font-weight: var(--mt-font-weight-regular, 400);
}

.ldf-newsletter-optin input[type="checkbox"] {
	margin-top: 0.2em;
	flex-shrink: 0;
}

.ldf-form__status {
	font-size: var(--mt-font-size-sm, 0.875rem);
	min-height: 1.2em;
}

.ldf-form__status[data-state="success"] {
	color: var(--mt-color-success, #15803D);
}

.ldf-form__status[data-state="error"] {
	color: var(--mt-color-error, #DC2626);
}

/* Páginas de confirmar el alta al boletín y de darse de baja ([ldf_newsletter_action]). El
   mismo `gap` que el formulario, para que el margen negativo de .ldf-form__status:empty siga
   cuadrando. Aquí el resultado es lo único que dice la página, así que va a tamaño normal. */
.ldf-newsletter-action {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--mt-space-4, 1rem);
}

.ldf-newsletter-action__intro {
	margin: 0;
}

.ldf-newsletter-action .ldf-form__status {
	font-size: inherit;
}

/* .mt-btn pone su propio `display`, que se impone al atributo `hidden` del navegador: sin esto,
   el botón se vería antes de que el JS encontrara un token. */
.ldf-newsletter-action button[hidden] {
	display: none;
}

/* Honeypot: oculto por CSS externo (nunca display:none inline en el HTML, para que un
   validador de accesibilidad/inspector rápido no lo confunda con "oculto por script"), y
   además marcado aria-hidden + tabindex=-1 en el propio markup. Fuera de la vista sin usar
   display:none (algunos bots evitan rellenar campos con display:none) y sin depender de
   posicionamiento off-screen que algunos lectores de pantalla siguen anunciando. */
.ldf-hp {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
}

/* El botón mientras se está enviando.

   Aquí había el espaciado del widget de Cloudflare Turnstile, que reservaba 72px en blanco
   encima del botón aunque no llegara a pintar nada. Se retiró el 2026-09-22 junto con el
   propio Turnstile.

   El giro va en un pseudoelemento y no en un SVG aparte para no tocar el marcado del botón,
   que lo pone el tema (.mt-btn). El `flex` del propio botón ya lo coloca al lado del texto.

   `prefers-reduced-motion` lo deja quieto: quien ha pedido que nada se mueva no quiere un
   disco girando, y el botón bloqueado más el texto «Enviant…» ya dicen lo que pasa. */
.ldf-form button[type="submit"].is-sending {
	cursor: progress;
}

.ldf-form button[type="submit"].is-sending::before {
	content: '';
	display: inline-block;
	width: 1em;
	height: 1em;
	margin-right: 0.5em;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	animation: ldf-spin 0.7s linear infinite;
	flex-shrink: 0;
}

@keyframes ldf-spin {
	to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
	.ldf-form button[type="submit"].is-sending::before {
		animation: none;
	}
}

/* ==========================================================================
   Campos del constructor de formularios (LDF_Custom_Forms).
   Todo lo de aquí abajo solo lo pinta un formulario creado desde el wp-admin:
   los del catálogo de código no llevan ninguna de estas clases ni estos tipos
   de campo, así que su aspecto no cambia.
   ========================================================================== */

/* Mismo aspecto que los campos de texto de arriba para los tipos que el
   catálogo de código no usaba. Se repite la regla en vez de ampliar el
   selector de arriba para no tocar nada de lo que ya estaba. */
.ldf-field input[type="number"],
.ldf-field input[type="url"] {
	font-family: inherit;
	font-size: var(--mt-font-size-base, 1rem);
	color: var(--mt-color-text-primary, #111111);
	background: var(--mt-color-bg-white, #ffffff);
	border: var(--mt-border-width, 1px) var(--mt-border-style, solid) var(--mt-color-border, #767676);
	border-radius: var(--mt-radius-md, 8px);
	padding: var(--mt-space-3, 0.75rem) var(--mt-space-4, 1rem);
	transition: var(--mt-transition-colors, border-color 0.2s ease);
}

@media (min-width: 768px) {
	.ldf-field input[type="number"],
	.ldf-field input[type="url"] {
		font-size: var(--mt-font-size-sm, 0.875rem);
	}
}

/* Dos columnas en el escritorio cuando algún campo es de «meitat». En el móvil
   todo sigue en una columna: la media pantalla de un móvil no da para un campo. */
@media (min-width: 640px) {
	.ldf-form--grid {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: var(--mt-space-4, 1rem);
	}

	.ldf-form--grid > * {
		grid-column: 1 / -1;
	}

	.ldf-form--grid > .ldf-field--half {
		grid-column: auto;
	}
}

/* Grupos de opciones (botones de opción y casillas): un <fieldset> sin el
   marco que le pone el navegador, con la pregunta en el <legend> igual que una
   etiqueta normal. */
.ldf-choices {
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
}

.ldf-choices legend {
	padding: 0;
	margin-bottom: var(--mt-space-2, 0.5rem);
	font-size: var(--mt-font-size-sm, 0.875rem);
	font-weight: var(--mt-font-weight-semibold, 600);
	color: var(--mt-color-text-primary, #111111);
}

.ldf-choices__list {
	display: flex;
	flex-direction: column;
	gap: var(--mt-space-2, 0.5rem);
}

/* La etiqueta de cada opción no es la del campo: peso normal, casilla a la
   izquierda y un objetivo táctil de al menos 24px de alto. */
.ldf-field .ldf-choice,
.ldf-field--acceptance label {
	display: flex;
	align-items: flex-start;
	gap: var(--mt-space-3, 0.75rem);
	min-height: 24px;
	font-weight: var(--mt-font-weight-regular, 400);
	color: var(--mt-color-text-body, #333333);
	cursor: pointer;
}

.ldf-choice input,
.ldf-field--acceptance input[type="checkbox"] {
	margin-top: 0.2em;
}

.ldf-choices[aria-invalid="true"] .ldf-choice input,
.ldf-choice input[aria-invalid="true"],
.ldf-field--acceptance input[type="checkbox"][aria-invalid="true"] {
	outline: 2px solid var(--mt-color-error, #DC2626);
	outline-offset: 2px;
}

.ldf-choice input:focus-visible,
.ldf-field--acceptance input[type="checkbox"]:focus-visible {
	outline: 2px solid var(--mt-color-primary, #14B5C5);
	outline-offset: 2px;
}
