/**
 * Puente — Main CSS
 *
 * Component styles that are shared across all templates.
 * Design tokens live in style.css (the theme stylesheet).
 *
 * @package Puente
 */

/* ── Sticky header scroll state ───────────────────────────────────────────── */
.site-header.is-scrolled {
	box-shadow: var(--shadow-md);
}

/* ── Ambient orbs (compartido por home, pricing, blog, account) ──────────────
 * Gradientes muy difuminados que viven en el fondo de cualquier sección que
 * lleve `.home-orb-stage`. El nombre se mantiene por compatibilidad con la
 * primera implementación; ahora es global, no específico de la portada.
 *
 * Antes: `overflow: clip` recortaba los orbes en la frontera de cada
 * sección y producía un borde horizontal duro al cambiar de apartado.
 * Ahora dejamos que los orbes se extiendan VERTICALMENTE entre secciones
 * (overflow-y: visible) — la luz fluye sin corte. El recorte horizontal se
 * mantiene (overflow-x: clip) para que orbes con offsets negativos no
 * generen scroll lateral. */
.home-orb-stage {
	position: relative;
	isolation: isolate;
	overflow-x: clip;
	overflow-y: visible;
}

.home-orb {
	position: absolute;
	border-radius: 50%;
	filter: blur(80px);
	opacity: 0.45;
	pointer-events: none;
	z-index: -1;
	will-change: transform;
	/* Máscara radial fuerte: el orbe arranca a desvanecerse desde el centro
	   mismo y es totalmente transparente a la mitad de su bbox. Así, incluso
	   si una capa superior recorta el orbe, el borde visible ya es muy tenue
	   en lugar de aparecer como un semicírculo macizo. */
	-webkit-mask-image: radial-gradient(closest-side, #000 20%, transparent 90%);
	        mask-image: radial-gradient(closest-side, #000 20%, transparent 90%);
}

.home-orb--blue {
	width: 520px;
	height: 520px;
	background: radial-gradient(circle, rgba(45, 91, 255, 0.55) 0%, rgba(45, 91, 255, 0) 70%);
	top: -160px;
	left: -120px;
}

.home-orb--violet {
	width: 460px;
	height: 460px;
	background: radial-gradient(circle, rgba(91, 108, 255, 0.45) 0%, rgba(91, 108, 255, 0) 70%);
	top: 60px;
	right: -160px;
}

.home-orb--green {
	width: 380px;
	height: 380px;
	background: radial-gradient(circle, rgba(48, 209, 88, 0.35) 0%, rgba(48, 209, 88, 0) 70%);
	bottom: -180px;
	left: 30%;
}

.home-orb--soft {
	width: 320px;
	height: 320px;
	background: radial-gradient(circle, rgba(45, 91, 255, 0.25) 0%, rgba(45, 91, 255, 0) 70%);
	opacity: 0.5;
}

/* ── .reveal compartido (entrada suave on scroll) ──────────────────────────
 * Lo controla el JS de cada página (home.js, pricing.js, blog.js…). */
.reveal {
	opacity: 0;
	transform: translateY(16px);
	transition: opacity .6s ease, transform .6s ease;
	transition-delay: var(--reveal-delay, 0ms);
}

.reveal.is-visible {
	opacity: 1;
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.reveal { opacity: 1; transform: none; transition: none !important; }
}

/* ── Skip link ────────────────────────────────────────────────────────────── */
.skip-link:focus {
	position: fixed;
	top: var(--space-md);
	left: var(--space-md);
	z-index: 9999;
	background: var(--color-primary);
	color: #fff;
	padding: var(--space-sm) var(--space-lg);
	border-radius: var(--radius-md);
	font-weight: 600;
	text-decoration: none;
	clip: auto;
	width: auto;
	height: auto;
	overflow: visible;
	white-space: normal;
}

/* ── Search form ─────────────────────────────────────────────────────────── */
.search-form {
	display: flex;
	gap: var(--space-sm);
	max-width: 480px;
	margin-inline: auto;
}

.search-form .search-field {
	flex: 1;
	padding: 0.625rem var(--space-lg);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	font-size: var(--text-sm);
	background: var(--color-bg);
	color: var(--color-text);
	outline: none;
	transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.search-form .search-field:focus {
	border-color: var(--color-primary);
	box-shadow: 0 0 0 3px rgba(79,70,229,0.15);
}

.search-form .search-submit {
	padding: 0.625rem var(--space-lg);
	background: var(--color-primary);
	color: #fff;
	border: none;
	border-radius: var(--radius-md);
	font-weight: 600;
	font-size: var(--text-sm);
	cursor: pointer;
	transition: background-color var(--transition-fast);
}

.search-form .search-submit:hover {
	background: var(--color-primary-dark);
}

/* ── Breadcrumb ──────────────────────────────────────────────────────────── */
.breadcrumb a {
	color: var(--color-text-muted);
	text-decoration: none;
}

.breadcrumb a:hover {
	color: var(--color-primary);
}

/* ── WordPress core: captions, gallery ─────────────────────────────────── */
.wp-caption {
	max-width: 100%;
	margin-bottom: var(--space-md);
}

.wp-caption-text {
	font-size: var(--text-sm);
	color: var(--color-text-muted);
	text-align: center;
	margin-top: var(--space-xs);
}

.gallery {
	display: grid;
	gap: var(--space-sm);
}

.gallery-columns-2 { grid-template-columns: repeat(2, 1fr); }
.gallery-columns-3 { grid-template-columns: repeat(3, 1fr); }
.gallery-columns-4 { grid-template-columns: repeat(4, 1fr); }
.gallery-item img  { width: 100%; height: auto; border-radius: var(--radius-sm); }

/* ── WordPress widgets ────────────────────────────────────────────────────── */
.widget {
	margin-bottom: var(--space-2xl);
}

.widget__title {
	font-size: var(--text-base);
	font-weight: 700;
	margin-bottom: var(--space-md);
	padding-bottom: var(--space-sm);
	border-bottom: 2px solid var(--color-primary);
	display: inline-block;
}

.widget ul { padding-left: 0; list-style: none; }
.widget ul li { padding: var(--space-xs) 0; border-bottom: 1px solid var(--color-border); font-size: var(--text-sm); }
.widget ul li:last-child { border-bottom: none; }
.widget a { color: var(--color-text); text-decoration: none; }
.widget a:hover { color: var(--color-primary); }

/* ── Comments ─────────────────────────────────────────────────────────────── */
.comments-title {
	font-size: var(--text-2xl);
	margin-bottom: var(--space-xl);
}

.comment-list {
	list-style: none;
	padding: 0;
	margin: 0 0 var(--space-2xl);
}

.comment-body {
	padding: var(--space-xl);
	background: var(--color-surface);
	border-radius: var(--radius-xl);
	margin-bottom: var(--space-md);
}

.comment-meta {
	display: flex;
	align-items: center;
	gap: var(--space-md);
	margin-bottom: var(--space-md);
}

.comment-author .fn { font-weight: 700; font-size: var(--text-sm); }
.comment-metadata { font-size: var(--text-xs); color: var(--color-text-muted); }
.comment-content p { font-size: var(--text-sm); margin: 0; }

.reply a {
	font-size: var(--text-sm);
	font-weight: 600;
	color: var(--color-primary);
}

/* ── Comment form ─────────────────────────────────────────────────────────── */
.comment-reply-title {
	font-size: var(--text-2xl);
	margin-bottom: var(--space-xl);
}

.comment-form label {
	display: block;
	font-size: var(--text-sm);
	font-weight: 600;
	margin-bottom: var(--space-xs);
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
	width: 100%;
	padding: 0.625rem var(--space-md);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	font-size: var(--text-sm);
	font-family: var(--font-sans);
	background: var(--color-bg);
	color: var(--color-text);
	transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.comment-form input:focus,
.comment-form textarea:focus {
	outline: none;
	border-color: var(--color-primary);
	box-shadow: 0 0 0 3px rgba(79,70,229,0.15);
}

.comment-form textarea {
	min-height: 160px;
	resize: vertical;
}

.comment-form-comment,
.comment-form p {
	margin-bottom: var(--space-lg);
}

.comment-form .submit {
	background: var(--color-primary);
	color: #fff;
	border: none;
	padding: 0.75rem var(--space-2xl);
	border-radius: var(--radius-md);
	font-size: var(--text-sm);
	font-weight: 600;
	cursor: pointer;
	transition: background-color var(--transition-fast);
}

.comment-form .submit:hover {
	background: var(--color-primary-dark);
}

/* ── User placeholder indicators (visible until plugin is active) ─────────── */
.user-placeholder {
	opacity: 0.5;
	font-style: italic;
}

/* Plugin removes this class once real data is loaded */
.user-placeholder[data-loaded="true"] {
	opacity: 1;
	font-style: normal;
}

/* =========================================================
   THEME FAB — toggle modo claro / oscuro
   Botón flotante abajo-izquierda. Markup en footer.php
   (`<button class="theme-fab" id="theme-fab">…`). Lógica en main.js.
   Diseño paridad 1:1 con paginas-para-implementar/styles.css.
   ========================================================= */
.theme-fab {
	position: fixed;
	left: 20px;
	bottom: 20px;
	z-index: 90;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	height: 44px;
	padding: 0 16px 0 12px;
	background: var(--bg-primary);
	border: 1px solid var(--divider);
	border-radius: 999px;
	color: var(--text-primary);
	font: 600 13px / 1 var(--font);
	cursor: pointer;
	box-shadow: var(--shadow-card-hover);
	transition: background-color .15s ease, border-color .15s ease,
		color .15s ease, transform .15s ease, box-shadow .15s ease;
}

.theme-fab:hover {
	background: var(--bg-card);
	border-color: var(--text-secondary);
	color: var(--accent-blue);
	transform: translateY(-2px);
}

.theme-fab:active { transform: scale(.97); }

.theme-fab:focus-visible {
	outline: 2px solid var(--accent-blue);
	outline-offset: 2px;
}

/* En dark el icono toma el ámbar de marca para evocar el sol. */
[data-theme="dark"] .theme-fab { color: var(--color-warning, #F5A623); }
[data-theme="dark"] .theme-fab:hover { color: var(--accent-blue); }

/* Visibility crossfade entre los dos iconos (sol/luna) — cada icono
   representa la ACCIÓN que el click ejecutaría: luna en light (clic →
   pasar a dark), sol en dark (clic → volver a light).
   Importante: usamos !important porque algunas reglas globales del tema
   apuntan a `svg { display: block }` y ganarían especificidad sobre estas. */
.theme-fab__icon-sun,
.theme-fab__icon-moon { display: none !important; }
.theme-fab__icon-moon { display: block !important; }
[data-theme="dark"] .theme-fab__icon-moon { display: none !important; }
[data-theme="dark"] .theme-fab__icon-sun  { display: block !important; }

/* Label cambia según tema. Las strings se inyectan desde footer.php
   con data-action-from-* (i18n via puente_t en PHP, no en JS).
   En light se lee `data-action-from-light` (= lo que el click haría: ir a dark).
   En dark se lee `data-action-from-dark` (= lo que el click haría: ir a light). */
.theme-fab__label::before { content: attr(data-action-from-light); }
[data-theme="dark"] .theme-fab__label::before { content: attr(data-action-from-dark); }

/* En pantallas estrechas el FAB se vuelve circular para no estorbar. */
@media (max-width: 540px) {
	.theme-fab {
		padding: 0;
		width: 44px;
		justify-content: center;
	}
	.theme-fab__label { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	html, body, .theme-fab { transition: none; }
}

/* =========================================================
   AMBIENT BACKGROUND — dot-grid + cursor spotlight global.
   =========================================================
   Antes vivía sólo en home.css (sólo portada). Subido a main.css para que
   atraviese TODA la web — pricing, products, account, contact, páginas
   sueltas — y se haga visible cuando `body.puente-ambient` está presente.
   El blog (single posts, archive, search, listing) NO lleva la clase, así
   que mantiene su fondo plano para favorecer la lectura.

   Tres capas:
     1. html/body: el blanco se traslada a html para que el spotlight (z<0)
        sea visible debajo del body transparente.
     2. .home-dot-grid: malla gris muy tenue (z:-2) sobre todo el viewport.
        Se enriquece con una capa azul revelada por un mask que sigue al
        cursor (efecto "linterna").
     3. .home-cursor-bg: glow radial azul/violeta (z:-1) que sigue al cursor.

   `--cursor-x` / `--cursor-y` los setea initCursorBg() en main.js a cada
   frame; en touch o reduced-motion las capas dinámicas se ocultan.
*/

/* html siempre lleva el fondo de marca: cuando body es transparente (ambient)
   el spotlight z<0 se ve a través de body; cuando body es opaco (blog) tapa
   el html bg sin problema. Ponerlo incondicional evita depender de `:has()`. */
html { background-color: var(--bg-primary); }
body.puente-ambient { background-color: transparent; }

.home-dot-grid {
	position: fixed;
	inset: 0;
	pointer-events: none;
	z-index: -2;
	background-image: radial-gradient(circle, rgba(0, 0, 0, 0.06) 1px, transparent 1.5px);
	background-size: 24px 24px;
	background-position: 0 0;
}

.home-dot-grid::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: radial-gradient(circle, var(--accent-blue) 1.2px, transparent 1.5px);
	background-size: 24px 24px;
	background-position: 0 0;
	-webkit-mask-image: radial-gradient(
		circle 280px at var(--cursor-x, 50%) var(--cursor-y, 50%),
		black 0%,
		transparent 70%
	);
	        mask-image: radial-gradient(
		circle 280px at var(--cursor-x, 50%) var(--cursor-y, 50%),
		black 0%,
		transparent 70%
	);
	will-change: mask-image;
}

.home-cursor-bg {
	position: fixed;
	inset: 0;
	pointer-events: none;
	z-index: -1;
	background: radial-gradient(
		circle 380px at var(--cursor-x, 50%) var(--cursor-y, 50%),
		rgba(45, 91, 255, 0.10) 0%,
		rgba(91, 108, 255, 0.05) 35%,
		transparent 70%
	);
	will-change: background;
}

/* Dark mode: el grid de puntos pierde contraste; subimos algo la opacidad
   para que siga leyéndose contra el casi-negro del tema. */
[data-theme="dark"] .home-dot-grid {
	background-image: radial-gradient(circle, rgba(255, 255, 255, 0.08) 1px, transparent 1.5px);
}

/* Touch / hover-none y reduced-motion: ocultamos las capas dinámicas y
   dejamos sólo la malla estática (sigue siendo legible como "papel
   cuadriculado", evitamos parecer roto). */
@media (hover: none), (prefers-reduced-motion: reduce) {
	.home-cursor-bg,
	.home-dot-grid::after { display: none; }
}

/* — Pass-through: secciones FULL-WIDTH con fondo sólido tapan la capa
     fixed. Cuando ambient está activo, forzamos transparencia en las
     secciones marketing/producto para que la malla y el spotlight
     atraviesen toda la página. NO tocamos cards/paneles (.feature-card,
     .stat, .account-dash-hero, .pricing-trust-strip...) — siguen siendo
     "tarjetas" opacas flotando sobre el fondo común. */
body.puente-ambient .hero,
body.puente-ambient .showcase,
body.puente-ambient .cta-banner,
body.puente-ambient .features-section,
body.puente-ambient .social-proof {
	background: transparent;
	background-color: transparent;
}

/* Las plantillas de producto reparten un fondo `bg-card` por sección
   mediante inline-style (style="background:var(--bg-card)"). En modo
   ambient queremos que el dot-grid atraviese también esas secciones, así
   que sobreescribimos con `!important` (justificado: estamos pisando
   inline-style de forma intencionada y scoped al body class). */
body.puente-ambient .product-section[style*="background"] {
	background: transparent !important;
}
