/**
 * Cimientos de accesibilidad — Tema Tiendasisimo
 *
 * Se carga después del Tailwind compilado para poder ganarle en especificidad
 * sin tocar el build de Vite.
 *
 * Cubre:
 *   - Indicador de foco visible en todo el sitio (2.4.7 AA, 2.4.11 AA, 2.4.13 AAA)
 *   - Enlace de salto al contenido (2.4.1 A)
 *   - Texto solo para lectores de pantalla
 *   - Respeto de las preferencias del sistema operativo:
 *       prefers-reduced-motion (2.3.3 AAA)
 *       prefers-contrast       (1.4.6 / 1.4.11)
 *       forced-colors          (alto contraste de Windows)
 *   - Área táctil mínima (2.5.8 AA, 2.5.5 AAA)
 *   - Resistencia al espaciado de texto del usuario (1.4.12 AA)
 *
 * @package Tiendasisimo
 * @since 1.4.0
 */

:root {
	/* Anillo de foco. Dos colores para que se vea tanto sobre el morado del
	   header como sobre los fondos claros del cuerpo. */
	--a11y-focus-oscuro: #0b1120;
	--a11y-focus-claro: #ffd400;

	/* Área táctil mínima. 24px es el mínimo AA (2.5.8); 44px el AAA (2.5.5). */
	--a11y-objetivo-min: 44px;
}

/* ==========================================================================
   1. Foco visible
   ========================================================================== */

/**
 * Doble anillo: banda amarilla pegada al elemento y anillo oscuro por fuera.
 * Da contraste contra fondo claro y contra fondo oscuro con la misma regla, y
 * el grosor (3px) supera el perímetro de 2px que exige 2.4.13 (AAA).
 *
 * Se usa :where() para no subir la especificidad: cualquier regla del tema
 * puede seguir sobrescribiendo colores sin pelearse con esta.
 */
:where(a, button, input, select, textarea, summary, details, [tabindex], [role="button"], [role="link"], [role="option"], [role="tab"]):focus-visible {
	outline: 3px solid var(--a11y-focus-oscuro);
	outline-offset: 3px;
	box-shadow: 0 0 0 3px var(--a11y-focus-claro);
	border-radius: 3px;
}

/**
 * Respaldo para navegadores sin :focus-visible. Se anula en cuanto el
 * navegador demuestra que sí lo soporta, para no marcar el foco del ratón.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus {
	outline: 3px solid var(--a11y-focus-oscuro);
	outline-offset: 3px;
}

@supports selector(:focus-visible) {
	:where(a, button, input, select, textarea, summary, [tabindex]):focus:not(:focus-visible) {
		outline: none;
		box-shadow: none;
	}
}

/**
 * Defensa contra `focus:outline-none` de Tailwind. Esa utilidad tiene más
 * especificidad que la regla de arriba, así que se le gana explícitamente:
 * nada dentro del tema puede dejar a un usuario de teclado sin indicador.
 */
.focus\:outline-none:focus-visible,
[class*="outline-none"]:focus-visible {
	outline: 3px solid var(--a11y-focus-oscuro) !important;
	outline-offset: 3px !important;
	box-shadow: 0 0 0 3px var(--a11y-focus-claro) !important;
}

/**
 * 2.4.11 Foco no oculto: si en algún momento se añade una cabecera pegajosa,
 * este margen impide que tape el elemento enfocado al llegar con Tab.
 */
:where(a, button, input, select, textarea, [tabindex]) {
	scroll-margin-top: 6rem;
	scroll-margin-bottom: 3rem;
}

/* ==========================================================================
   2. Texto solo para lectores de pantalla
   ========================================================================== */

/**
 * Oculta visualmente sin sacar del árbol de accesibilidad. Se replica la
 * utilidad de Tailwind por si el purgado la elimina del build.
 */
.ts-sr-only {
	position: absolute !important;
	width: 1px !important;
	height: 1px !important;
	padding: 0 !important;
	margin: -1px !important;
	overflow: hidden !important;
	clip: rect(0, 0, 0, 0) !important;
	clip-path: inset(50%) !important;
	white-space: nowrap !important;
	border-width: 0 !important;
}

/* ==========================================================================
   3. Enlace de salto al contenido (2.4.1 A)
   ========================================================================== */

.ts-skip-link {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 100000;
	display: block;
	padding: 0.875rem 1.5rem;
	background: #ffffff;
	color: #513685;
	font-size: 1rem;
	font-weight: 700;
	text-decoration: underline;
	border: 3px solid #0b1120;
	border-radius: 0 0 0.5rem 0;

	/* Fuera de la pantalla hasta que recibe el foco. Se usa translate y no
	   display:none porque display:none lo sacaría del orden de tabulación. */
	transform: translateY(-120%);
	transition: transform 0.15s ease-in-out;
}

.ts-skip-link:focus {
	transform: translateY(0);
}

/* El contenedor de destino recibe foco por programa; no debe mostrar anillo. */
:where(main, #contenido):focus {
	outline: none;
}

/* ==========================================================================
   4. Área táctil mínima (2.5.8 AA / 2.5.5 AAA)
   ========================================================================== */

/**
 * Se agranda el área pulsable con un pseudo-elemento, sin tocar el tamaño
 * visible del control. Así se cumple sin alterar el diseño.
 */
.ts-objetivo-tactil {
	position: relative;
}

.ts-objetivo-tactil::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: var(--a11y-objetivo-min);
	height: var(--a11y-objetivo-min);
	transform: translate(-50%, -50%);
}

/**
 * Puntos del carrusel: medían 10×10 px. El punto visible no cambia; lo que
 * crece es la zona pulsable, con un pseudo-elemento centrado.
 *
 * La separación acompaña al tamaño del área para que dos puntos contiguos no
 * se solapen: si se solaparan, pulsar cerca del borde llevaría a la
 * diapositiva equivocada, que es peor que un objetivo pequeño.
 */
.swiper-pagination-bullet {
	position: relative;
	margin: 0 17px !important;
}

.swiper-pagination-bullet::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: var(--a11y-objetivo-min);
	height: var(--a11y-objetivo-min);
	transform: translate(-50%, -50%);
}

/**
 * En pantallas estrechas, siete puntos a 44 px ocupaban 308 de los 375 px
 * disponibles y dejaban al botón de pausa aplastado contra el borde.
 *
 * Se bajan a 34 px: sigue muy por encima del mínimo de 24×24 que exige
 * WCAG 2.5.8 (AA), aunque ya no alcanza los 44 px de 2.5.5 (AAA). Es un
 * intercambio consciente — la alternativa era que el control de pausa, que
 * cumple un criterio de nivel A, quedara inservible.
 */
@media (max-width: 640px) {
	:root {
		--a11y-objetivo-min: 34px;
	}

	.swiper-pagination-bullet {
		margin: 0 12px !important;
	}

	/* Los controles que no compiten por espacio conservan sus 44 px. */
	.ts-carrusel-pausa,
	.swiper-button-next,
	.swiper-button-prev,
	.ts-paginacion__btn {
		--a11y-objetivo-min: 44px;
	}
}

/* Flechas del carrusel a 44x44 reales. */
.swiper-button-next,
.swiper-button-prev {
	width: var(--a11y-objetivo-min);
	height: var(--a11y-objetivo-min);
}

/* ==========================================================================
   4bis. Control de pausa del carrusel (2.2.2 A)
   ========================================================================== */

/**
 * WCAG 2.2.2 exige poder detener cualquier movimiento automático que dure
 * más de cinco segundos. El botón lo crea scripts.js y se coloca sobre la
 * esquina del carrusel.
 */
.ts-carrusel-pausa {
	position: absolute;
	right: 1rem;
	z-index: 20;

	/**
	 * El botón debe quedar SOBRE la imagen, no debajo.
	 *
	 * La paginación de este tema está forzada a `position: relative`, así que
	 * ocupa sitio en el flujo por debajo de las diapositivas y forma parte de
	 * la altura del contenedor. Anclar el botón a `bottom: 0` lo dejaba a la
	 * altura de los puntos, fuera de la fotografía.
	 *
	 * `--ts-carrusel-desfase` lo mide scripts.js: es la diferencia entre la
	 * altura del contenedor y la de las diapositivas. Restarla sube el botón
	 * hasta la esquina de la imagen, sea cual sea la altura de la paginación.
	 */
	bottom: calc(var(--ts-carrusel-desfase, 0px) + 1rem);

	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;

	background: rgba(255, 255, 255, 0.94);
	color: #513685;
	border: 2px solid #513685;
	border-radius: 9999px;
	cursor: pointer;

	transition: background-color 0.2s ease, color 0.2s ease;
}

.ts-carrusel-pausa:hover {
	background: #513685;
	color: #ffffff;
}

/* El icono se dibuja en CSS: dos barras para pausar, un triángulo para
   reanudar. Así no depende de ninguna librería de iconos. */
.ts-carrusel-pausa__icono {
	display: block;
	width: 14px;
	height: 16px;
	background: currentColor;

	/* Dos barras verticales. */
	clip-path: polygon(0 0, 36% 0, 36% 100%, 0 100%, 0 0, 64% 0, 100% 0, 100% 100%, 64% 100%, 64% 0);
}

.ts-carrusel-pausa.esta-en-pausa .ts-carrusel-pausa__icono {
	/* Triángulo de reproducción. */
	clip-path: polygon(0 0, 100% 50%, 0 100%);
}

/* El carrusel necesita ser el contexto de posicionamiento del botón. */
.swiper-hero,
.swiper-categories,
.swiper-featured {
	position: relative;
}

/**
 * Fila de controles: los puntos de paginación y el botón de pausa juntos.
 *
 * Es la colocación de los carruseles que muestran varias tarjetas a la vez
 * —el de categorías—, donde un botón flotante taparía la imagen y el título
 * de una de ellas. Aquí no pisa nada, ni en escritorio ni en móvil.
 */
.ts-carrusel-controles {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.75rem 1rem;
	margin-top: 1rem;

	/* Sin esto, en móvil el botón acaba pegado al borde de la pantalla. */
	padding-inline: 1rem;
}

.ts-carrusel-controles .swiper-pagination {
	margin-top: 0 !important;
	width: auto !important;
}

/* Dentro de la fila el botón deja de flotar y se coloca en el flujo. */
.ts-carrusel-controles .ts-carrusel-pausa {
	position: static;
	flex-shrink: 0;
	background: transparent;
	border-color: #513685;
}

.ts-carrusel-controles .ts-carrusel-pausa:hover {
	background: #513685;
	color: #ffffff;
}

@media (max-width: 640px) {
	.ts-carrusel-controles {
		gap: 0.75rem;
	}
}

/* ==========================================================================
   4ter. Paginación del buscador de tiendas
   ========================================================================== */

/**
 * Los estilos van aquí y no en clases de Tailwind porque utilidades como
 * `w-11` no están en el CSS que compila Vite, y usarlas dejaba los botones
 * en 8×32 px: apretados e imposibles de acertar con el dedo.
 *
 * Tamaño 44×44 (2.5.5 AAA), separación cómoda y salto de línea en pantallas
 * estrechas, donde catorce botones no caben en una fila.
 */
.ts-paginacion {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 0.5rem;
	margin-top: 2rem;
}

.ts-paginacion__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;

	/* Mínimo AAA de área táctil, y crece si el número tiene dos cifras. */
	min-width: 44px;
	height: 44px;
	padding-inline: 0.5rem;

	font-weight: 600;
	font-size: 1rem;
	line-height: 1;

	background-color: #ffffff;
	color: #3f3f46;
	border: 1px solid #d4d4d8;
	border-radius: 0.5rem;
	cursor: pointer;

	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.ts-paginacion__btn:hover {
	background-color: #f4f4f5;
	border-color: #a1a1aa;
	color: #18181b;
}

/**
 * La página actual no se distingue solo por el color (1.4.1): además del
 * fondo morado lleva `aria-current="page"`, que es lo que anuncia el lector
 * de pantalla, y un borde más marcado.
 */
.ts-paginacion__btn.is-actual,
.ts-paginacion__btn[aria-current="page"] {
	background-color: var(--color-isimo-purple, #513685);
	border-color: var(--color-isimo-purple, #513685);
	color: #ffffff;
	cursor: default;
}

.ts-paginacion__btn.is-actual:hover,
.ts-paginacion__btn[aria-current="page"]:hover {
	background-color: #3f2a68;
	border-color: #3f2a68;
	color: #ffffff;
}

@media (max-width: 480px) {
	.ts-paginacion {
		gap: 0.375rem;
	}

	.ts-paginacion__btn {
		min-width: 40px;
		height: 40px;
		font-size: 0.9375rem;
	}
}

/* ==========================================================================
   5. Preferencias del sistema — movimiento (2.3.3 AAA, 2.2.2 A)
   ========================================================================== */

/**
 * Si el usuario pidió menos movimiento en su sistema, se le obedece: nada de
 * animaciones, nada de desplazamiento suave. El autoplay del carrusel se
 * desactiva desde JavaScript leyendo esta misma media query.
 */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		transition-delay: 0ms !important;
		scroll-behavior: auto !important;
	}

	html {
		scroll-behavior: auto !important;
	}

	/* Animaciones propias del tema declaradas en style.css. */
	.float-animation,
	.pulse-slow,
	.gradient-animate {
		animation: none !important;
	}

	/* El efecto de escala al pasar por encima también es movimiento. */
	.swiper-pagination-bullet:hover {
		transform: none !important;
	}
}

/* ==========================================================================
   6. Preferencias del sistema — contraste
   ========================================================================== */

/**
 * Cuando el usuario pide más contraste, se refuerzan bordes y foco. Esto es
 * la alternativa correcta al típico botón de «alto contraste»: responde a lo
 * que la persona ya configuró en su sistema, sin pedirle que lo repita aquí.
 */
@media (prefers-contrast: more) {
	:root {
		--a11y-focus-claro: #ffffff;
	}

	:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
		outline-width: 4px;
	}

	/* Los enlaces dentro de párrafos dejan de depender solo del color. */
	.entry-content a,
	.prose a {
		text-decoration: underline;
		text-underline-offset: 2px;
	}

	input,
	select,
	textarea {
		border-width: 2px !important;
	}
}

/* ==========================================================================
   7. Modo de alto contraste de Windows (forced-colors)
   ========================================================================== */

/**
 * En modo de colores forzados el sistema reemplaza la paleta. Hay que
 * asegurarse de que los iconos SVG y los bordes no desaparezcan.
 */
@media (forced-colors: active) {
	:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
		outline: 3px solid CanvasText;
		outline-offset: 3px;
		box-shadow: none;
	}

	/* Los SVG dibujados con currentColor sobreviven; los que llevan fill fijo
	   se fuerzan al color de texto del sistema. */
	svg {
		forced-color-adjust: auto;
	}

	/* Los fondos de color que aportan significado se sustituyen por un borde
	   real, que sí se respeta en este modo. */
	.swiper-pagination-bullet {
		border: 1px solid CanvasText;
	}

	.swiper-pagination-bullet-active {
		background: Highlight !important;
		border-color: Highlight;
	}

	.ts-skip-link {
		border: 3px solid CanvasText;
	}
}

/* ==========================================================================
   8. Resistencia al espaciado de texto del usuario (1.4.12 AA)
   ========================================================================== */

/**
 * Quien tiene dislexia o baja visión suele aplicar su propia hoja de estilos
 * con más interlineado y más espacio entre letras. El sitio debe aguantarlo
 * sin cortar texto ni generar desplazamiento horizontal.
 *
 * La regla es: nada que contenga texto lleva altura fija.
 */
.ts-altura-flexible {
	height: auto !important;
	min-height: 0 !important;
}

/* El header tenía min-height: 234px, que impedía crecer al texto. */
header.bg-isimo-purple {
	min-height: 0;
}

@media (min-width: 1024px) {
	header.bg-isimo-purple {
		/* Se conserva la altura como mínimo deseable, no como techo. */
		min-height: 234px;
		height: auto;
	}
}

/* Las tarjetas de tienda fijaban 70px de alto para el título. */
.tienda-card h3 {
	min-height: 0;
	height: auto;
	padding-block: 0.75rem;
}

/**
 * Desplazamiento horizontal (1.4.10 AA).
 *
 * Aquí NO se usa `overflow-x: hidden` ni `clip` sobre el body. Ocultar el
 * desbordamiento no lo arregla: recorta el contenido que sobresale y lo deja
 * inalcanzable, que es exactamente la «pérdida de contenido» que el criterio
 * prohíbe. Hay que quitar la causa.
 *
 * Causa real medida en este tema: el correo de contacto del pie. Al aplicar el
 * espaciado de texto que exige 1.4.12, `servicioalcliente@tiendasisimo.com` no
 * cabía en 320 px, no tenía por dónde partirse, y empujaba toda la rejilla del
 * pie a 389 px.
 */

/* Las cadenas largas sin espacios —correos, URLs— deben poder partirse. */
a[href^="mailto:"],
a[href^="tel:"],
.entry-content a,
.prose a {
	overflow-wrap: anywhere;
}

/**
 * Un hijo de grid o flex tiene por defecto `min-width: auto`, lo que le impide
 * encogerse por debajo del ancho de su contenido. Es la causa habitual de los
 * desbordamientos que no se explican mirando el CSS.
 */
footer .grid > *,
.container > .grid > * {
	min-width: 0;
}

img,
video,
iframe,
table {
	max-width: 100%;
}

/* ==========================================================================
   8bis. Iconos sociales — contraste no textual (1.4.11 AA)
   ========================================================================== */

/**
 * Antes: icono blanco sobre el verde de marca = 1.79:1. El mínimo para un
 * icono que transmite significado es 3:1.
 *
 * Ahora: icono morado sobre verde = 5.31:1, y al pasar el cursor o recibir el
 * foco se invierte a blanco sobre morado = 9.47:1. Las dos combinaciones
 * cumplen, y el verde de marca se conserva.
 *
 * Va aquí y no como clases de Tailwind porque `hover:text-white` no está en
 * el CSS compilado por Vite y añadirla exigiría rehacer el build.
 */
.ts-social-icono {
	background-color: var(--color-isimo-green, #93d50a);
	color: var(--color-isimo-purple, #513685);
	transition: background-color 0.2s ease, color 0.2s ease;
}

a:hover .ts-social-icono,
a:focus-visible .ts-social-icono {
	background-color: var(--color-isimo-purple, #513685);
	color: #ffffff;
}

/* ==========================================================================
   8ter. Texto sobre fotografía (1.4.3 AA)
   ========================================================================== */

/**
 * Poner texto blanco encima de una foto es apostar a que ningún píxel claro
 * caiga detrás de una letra. El velo degradado quita la apuesta: el texto
 * siempre cae sobre morado oscuro y la imagen sigue viéndose a la derecha.
 *
 * Contraste garantizado: blanco sobre #3d2865 al 88% = 11.4:1.
 */
.ts-sobre-imagen {
	position: relative;
	/* La altura fija de 622px impedía que el texto creciera (1.4.4). */
	min-height: 622px;
	height: auto;
}

.ts-sobre-imagen::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: linear-gradient(
		100deg,
		rgba(45, 28, 78, 0.94) 0%,
		rgba(45, 28, 78, 0.88) 38%,
		rgba(45, 28, 78, 0.45) 62%,
		rgba(45, 28, 78, 0.15) 100%
	);
}

/* En móvil no hay columna libre: el velo cubre por igual. */
@media (max-width: 1023px) {
	.ts-sobre-imagen::before {
		background: rgba(45, 28, 78, 0.9);
	}

	.ts-sobre-imagen {
		min-height: 0;
	}
}

.ts-sobre-imagen__contenido {
	position: relative;
	z-index: 1;
}

/* ==========================================================================
   8quater. Banners con texto real (1.4.5 AA)
   ========================================================================== */

/**
 * La fotografía queda de fondo y el texto va encima como HTML de verdad.
 * A diferencia del texto incrustado en el JPEG, este se lee con lector de
 * pantalla, se agranda con el zoom, se traduce y lo indexa Google.
 */
.ts-banner {
	position: relative;
	border-radius: 2rem;
	overflow: hidden;
}

.ts-banner__texto {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 0.75rem;

	padding: clamp(1.25rem, 5vw, 3.5rem);

	/* Velo que garantiza el contraste del texto pase lo que pase detrás. */
	background: linear-gradient(
		90deg,
		rgba(45, 28, 78, 0.92) 0%,
		rgba(45, 28, 78, 0.75) 45%,
		rgba(45, 28, 78, 0) 85%
	);
	color: #ffffff;
}

.ts-banner__titulo {
	/* Escala con el ancho pero sigue respondiendo al zoom de texto, porque el
	   mínimo y el máximo van en rem y no en px. */
	font-size: clamp(1.5rem, 4vw, 3.25rem);
	font-weight: 800;
	line-height: 1.1;
	max-width: 18ch;
}

.ts-banner__subtitulo {
	font-size: clamp(1rem, 1.8vw, 1.5rem);
	max-width: 30ch;
}

.ts-banner__boton {
	align-self: flex-start;
	margin-top: 0.5rem;
	padding: 0.75rem 1.75rem;

	/* Área táctil por encima del mínimo AAA. */
	min-height: 44px;
	display: inline-flex;
	align-items: center;

	background: #f4e500;
	color: #513685; /* 7.24:1 sobre el amarillo: cumple incluso AAA. */
	font-weight: 700;
	border-radius: 0.5rem;
	text-decoration: none;
}

.ts-banner__boton:hover {
	background: #ffffff;
}

@media (max-width: 767px) {
	.ts-banner__texto {
		/* En móvil no hay columna libre a la derecha. */
		background: rgba(45, 28, 78, 0.82);
	}
}

/* ==========================================================================
   8quinquies. Contenido sin barra lateral
   ========================================================================== */

/**
 * Al quitar la barra lateral de las entradas, el contenido pasa a ocupar todo
 * el ancho. Se le pone un techo porque una línea de texto muy larga es difícil
 * de seguir: al saltar de renglón se pierde el sitio. Es la recomendación de
 * 1.4.8 (AAA) y una de las ayudas de lectura que más se nota.
 */
.ts-contenido-unico {
	width: 100%;
	max-width: 72rem;
	margin-inline: auto;
}

/* ==========================================================================
   9. Ayudas de legibilidad (COGA)
   ========================================================================== */

/**
 * Longitud de línea acotada y espaciado cómodo en los bloques de texto
 * corrido. Mejora comprensión lectora y cumple parte de 1.4.8 (AAA).
 */
.entry-content,
.prose {
	line-height: 1.6;
}

.entry-content p,
.prose p {
	max-width: 80ch;
}

/* Nunca justificar: los ríos de espacio en blanco dificultan la lectura a
   personas con dislexia (1.4.8 AAA). */
.entry-content,
.prose,
.entry-content p,
.prose p {
	text-align: left;
}

/* ==========================================================================
   10. Utilidades varias
   ========================================================================== */

/**
 * Mayúsculas de presentación.
 *
 * Antes se aplicaban con strtoupper() en PHP, lo que hacía llegar el texto ya
 * en caja alta al árbol de accesibilidad: algunos lectores de pantalla lo
 * interpretan como siglas y lo deletrean («B, O, G, O, T, A»). Además, la caja
 * alta sostenida es más difícil de leer con dislexia, porque desaparece la
 * silueta de la palabra.
 *
 * Con CSS el efecto visual es idéntico y el texto real sigue siendo «Bogotá».
 */
.ts-mayusculas {
	text-transform: uppercase;
}

/* Los emojis decorativos no deben leerse; se ocultan del árbol con
   aria-hidden en el marcado y se mantiene su espacio aquí. */
.ts-emoji {
	font-style: normal;
	speak: none;
}
