/*
 Theme Name:     OV Child
 Theme URI:      https://portafolio.saludgo.org/
 Description:    Tema hijo de Divi para el portafolio. Anade los tipos de contenido
                 de Experiencia y Estudios, la ficha tecnica de los proyectos y sus
                 estilos.
 Author:         Guillermo Nieto
 Author URI:     https://portafolio.saludgo.org/
 Template:       Divi
 Version:        2.0.0
 Text Domain:    ov-child
 License:        GNU General Public License v2 or later
 License URI:    http://www.gnu.org/licenses/gpl-2.0.html
*/

/* =========================================================================
   Paleta tomada del diseno que ya existia en las paginas de Divi.
   ====================================================================== */
:root {
	--ovc-azul:      #0000ff;
	--ovc-violeta:   #461fef;
	--ovc-grafito:   #393e46;
	--ovc-humo:      #f5f8fa;
	--ovc-linea:     #e2e8f0;
}

/* =========================================================================
   Desbordamiento horizontal en movil

   El menu deslizante de Divi (.et_slide_in_menu_container) mide 320px y vive
   fuera de la pantalla, a la derecha. Nadie recorta ese sobrante, asi que en
   un movil de 390px el visitante podia arrastrar la pagina 780px hacia el
   lado y quedarse mirando un vacio. Medido: scrollX llegaba a 782.

   Se usa "clip" en vez de "hidden" porque hidden convierte el elemento en
   contenedor de scroll y rompe cualquier position:sticky que se anada
   despues; se deja hidden delante como respaldo para navegadores viejos.
   ====================================================================== */
html,
body {
	overflow-x: hidden;
	overflow-x: clip;
	max-width: 100%;
}

/* =========================================================================
   Experiencia y estudios  ([cv_experiencia] / [cv_estudios])
   ====================================================================== */
.ovc-cv {
	display: grid;
	gap: 40px 48px;
}

.ovc-cv--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.ovc-cv--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; }

.ovc-cv__item {
	position: relative;
	padding-left: 26px;
	border-left: 3px solid var(--ovc-linea);
}

/* El punto de la linea de tiempo. */
.ovc-cv__item::before {
	content: "";
	position: absolute;
	left: -9px;
	top: 6px;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background: var(--ovc-azul);
	box-shadow: 0 0 0 4px rgba(70, 31, 239, 0.18);
}

/* -------------------------------------------------------------------------
   Varias columnas: tarjetas en vez de línea de tiempo.

   La línea vertical y el punto tienen sentido en una sola columna, donde
   marcan una sucesión de fechas. Repartidos en dos o tres columnas se
   convierten en rayas sueltas que no significan nada, porque las entradas ya
   no van una detrás de otra en el tiempo. Para cursos y certificaciones
   funciona mejor una rejilla de tarjetas.
   ---------------------------------------------------------------------- */
.ovc-cv--cols-2 .ovc-cv__item,
.ovc-cv--cols-3 .ovc-cv__item {
	border-left: 0;
	padding: 22px 24px 24px;
	background: #fff;
	border: 1px solid var(--ovc-linea);
	border-radius: 14px;
	transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.ovc-cv--cols-2 .ovc-cv__item:hover,
.ovc-cv--cols-3 .ovc-cv__item:hover {
	transform: translateY(-4px);
	border-color: transparent;
	box-shadow: 0 16px 36px rgba(70, 31, 239, .15);
}

/* El punto de la línea de tiempo sobra dentro de una tarjeta. */
.ovc-cv--cols-2 .ovc-cv__item::before,
.ovc-cv--cols-3 .ovc-cv__item::before {
	content: none;
}

/* La insignia se sube al mismo renglón del título para ganar altura. */
.ovc-cv--cols-2 .ovc-cv__logo,
.ovc-cv--cols-3 .ovc-cv__logo {
	width: 52px;
	height: 52px;
	border-radius: 12px;
}

.ovc-cv--cols-2 .ovc-cv__item--con-imagen,
.ovc-cv--cols-3 .ovc-cv__item--con-imagen {
	grid-template-columns: 52px minmax(0, 1fr);
	gap: 14px;
}

/* El año, abajo del todo y alineado en todas las tarjetas. */
.ovc-cv--cols-2 .ovc-cv__datos,
.ovc-cv--cols-3 .ovc-cv__datos {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.ovc-cv--cols-2 .ovc-cv__periodo,
.ovc-cv--cols-3 .ovc-cv__periodo {
	margin-top: auto;
	padding-top: 10px;
	margin-bottom: 0;
}

/* Insignia o logo de la entidad, a la izquierda de cada entrada. */
.ovc-cv__item--con-imagen {
	display: grid;
	grid-template-columns: 64px minmax(0, 1fr);
	gap: 18px;
	align-items: start;
}

.ovc-cv__logo {
	width: 64px;
	height: 64px;
	border-radius: 14px;
	overflow: hidden;
	box-shadow: 0 6px 16px rgba(70, 31, 239, .22);
	background: var(--ovc-humo);
}

.ovc-cv__logo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.ovc-cv__datos { min-width: 0; }

/* -------------------------------------------------------------------------
   Las dos fotos que ilustran cada etapa.

   Se colocan a la derecha del texto, con la segunda montada sobre la primera
   y desplazada, que es el mismo recurso de sombra desplazada que ya usaba el
   diseño original de las páginas de Divi.
   ---------------------------------------------------------------------- */
.ovc-cv__item--con-fotos {
	grid-template-columns: 64px minmax(0, 1fr) clamp(200px, 26%, 300px);
	column-gap: 28px;
}

/* Sin insignia, pero con fotos. */
.ovc-cv__item--con-fotos:not(.ovc-cv__item--con-imagen) {
	display: grid;
	grid-template-columns: minmax(0, 1fr) clamp(200px, 26%, 300px);
	gap: 28px;
}

.ovc-cv__fotos {
	position: relative;
	align-self: start;
}

.ovc-cv__foto {
	position: relative;
	margin: 0;
	border-radius: 12px;
	background: var(--ovc-humo);
	/* Sombra en dos capas: una corta y marcada, otra larga y difusa. Una sola
	   sombra grande deja la foto flotando; dos la apoyan. */
	box-shadow: 0 2px 6px rgba(57, 62, 70, .14), 0 16px 38px rgba(57, 62, 70, .16);
	transition: transform .3s ease, box-shadow .3s ease;
}

.ovc-cv__foto img { border-radius: inherit; }

/* Al pasar el ratón la foto se levanta un poco: da vida sin ser un efecto
   llamativo. En móvil no hay hover, así que no molesta. */
.ovc-cv__foto:hover {
	transform: translateY(-4px);
	box-shadow: 0 4px 10px rgba(57, 62, 70, .16), 0 24px 50px rgba(70, 31, 239, .22);
}

/* --- Acabado "acento" -----------------------------------------------------
   Un bloque de color asomando por detrás, desplazado. Es el mismo recurso que
   ya usaba el diseño original del sitio (sombras azules desplazadas), pero
   limpio. El lado alterna en cada entrada, así la columna deja de parecer una
   pila de rectángulos iguales.
   ---------------------------------------------------------------------- */
.ovc-cv--marco-acento .ovc-cv__foto::before {
	content: "";
	position: absolute;
	inset: 14px -14px -14px 14px;
	border-radius: 12px;
	background: linear-gradient(135deg, var(--ovc-azul), var(--ovc-violeta));
	z-index: -1;
}

.ovc-cv--marco-acento .ovc-cv__item:nth-child(even) .ovc-cv__foto::before {
	inset: -14px 14px 14px -14px;
}

.ovc-cv--marco-acento .ovc-cv__foto {
	border: 4px solid #fff;
	isolation: isolate;
}

/* --- Acabado "tarjeta": marco blanco grueso, como una foto impresa. ----- */
.ovc-cv--marco-tarjeta .ovc-cv__foto {
	border: 10px solid #fff;
	border-bottom-width: 34px;
	border-radius: 4px;
	box-shadow: 0 3px 8px rgba(57, 62, 70, .18), 0 18px 40px rgba(57, 62, 70, .18);
}

/* --- Acabado "limpio": esquinas y sombra, nada más. -------------------- */
.ovc-cv--marco-limpio .ovc-cv__foto {
	box-shadow: 0 8px 24px rgba(57, 62, 70, .14);
}

.ovc-cv__foto img {
	display: block;
	width: 100%;
	height: auto;
	/*
	 * Cada foto conserva su propia proporción.
	 *
	 * Antes aquí había aspect-ratio: 3/2 con object-fit: cover, que recorta lo
	 * que sobra. Con las fotos apaisadas no se notaba, pero las verticales
	 * perdían la mitad de la altura: en las del Premio y el Talento Tech el
	 * recorte se comía la cara. Como solo hay una foto por entrada, no hay
	 * ninguna rejilla que alinear y las proporciones distintas no molestan.
	 *
	 * El tope de altura evita que un retrato muy alargado se coma la entrada.
	 */
	max-height: 560px;
	object-fit: contain;
	border-radius: 9px;
}

/* Con dos fotos sí conviene que midan lo mismo: van una encima de otra y una
   más alta que la otra desalinea el bloque. */
.ovc-cv__fotos--dos .ovc-cv__foto img,
.ovc-cv__fotos--superpuestas .ovc-cv__foto img {
	aspect-ratio: 3 / 2;
	object-fit: cover;
	max-height: none;
}

/* --- Variante "dos": las dos alineadas, mismo tamaño, sin solaparse. ------
   Es la que se lee mejor: bordes rectos arriba y abajo, así la lista de
   entradas queda alineada en vez de con los bordes dentados que deja el
   montaje. --------------------------------------------------------------- */
.ovc-cv__fotos--dos {
	display: grid;
	gap: 10px;
}

.ovc-cv__fotos--dos .ovc-cv__foto { width: 100%; }

/* --- Variante "una": una sola foto, más grande. -------------------------
   Al no tener que repartir el hueco entre dos, la columna se ensancha y la
   foto pasa de ~220px a ~380px: ahí ya se distingue qué se está haciendo en
   ella, que es el único motivo para ponerla. --------------------------- */
.ovc-cv__item--fotos-una {
	grid-template-columns: 64px minmax(0, 1fr) clamp(260px, 34%, 400px);
}

.ovc-cv__item--fotos-una:not(.ovc-cv__item--con-imagen) {
	grid-template-columns: minmax(0, 1fr) clamp(260px, 34%, 400px);
}

.ovc-cv__fotos--una .ovc-cv__foto {
	width: 100%;
}

/* --- Variante "superpuestas": el montaje desplazado del diseño antiguo. -- */
.ovc-cv__fotos--superpuestas.ovc-cv__fotos--2 .ovc-cv__foto--1 {
	width: 82%;
	outline: 5px solid var(--ovc-azul);
	outline-offset: -5px;
}

.ovc-cv__fotos--superpuestas.ovc-cv__fotos--2 .ovc-cv__foto--2 {
	width: 72%;
	margin: -18% 0 0 auto;
	position: relative;
	z-index: 2;
	border: 4px solid #fff;
}

.ovc-cv__titulo {
	font-size: 20px;
	font-weight: 600;
	line-height: 1.35;
	margin: 0 0 4px;
	color: var(--ovc-grafito);
}

.ovc-cv__titulo a { color: inherit; text-decoration: none; }
.ovc-cv__titulo a:hover { color: var(--ovc-violeta); }

.ovc-cv__sep { color: var(--ovc-linea); font-weight: 400; }
.ovc-cv__rol { color: var(--ovc-violeta); }

/* Institución que expide (estudios) o entidad que otorga (reconocimientos). */
.ovc-cv__entidad {
	font-size: 15px;
	color: var(--ovc-violeta);
	margin: 0 0 6px;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}

.ovc-cv__etiqueta {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: #7a8290;
	background: var(--ovc-humo);
	border: 1px solid var(--ovc-linea);
	border-radius: 999px;
	padding: 3px 10px;
}

.ovc-cv__periodo {
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: #7a8290;
	margin: 0 0 10px;
}

.ovc-cv__lugar { font-weight: 400; text-transform: none; letter-spacing: 0; }

.ovc-cv__texto  { text-align: justify; line-height: 1.8; }
.ovc-cv__texto p:last-child { margin-bottom: 0; }

.ovc-cv__soporte { margin: 10px 0 0; }
.ovc-cv__soporte a {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--ovc-violeta);
	text-decoration: none;
	border-bottom: 2px solid currentColor;
}

.ovc-vacio {
	padding: 16px 20px;
	border: 1px dashed var(--ovc-linea);
	color: #7a8290;
}

/* =========================================================================
   Página de un proyecto — maqueta propia (single-project.php)
   ====================================================================== */
.ovc-contenedor {
	width: 90%;
	max-width: 1080px;
	margin: 0 auto;
}

.ovc-proyecto-banda { padding: 130px 0 60px !important; }

.ovc-proyecto-single__cat {
	font-size: 12.5px;
	font-weight: 800;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--ovc-violeta);
	margin: 0 0 10px;
}

.ovc-proyecto-single__titulo {
	font-size: clamp(30px, 4vw, 46px);
	font-weight: 800;
	line-height: 1.15;
	letter-spacing: -1px;
	margin: 0;
	padding: 0;
	color: var(--ovc-grafito);
	max-width: 20ch;
}

.ovc-proyecto-single__titulo::after {
	content: "";
	display: block;
	width: 72px;
	height: 5px;
	margin-top: 18px;
	background: var(--ovc-azul);
	border-radius: 3px;
}

.ovc-proyecto-single__cuerpo { padding: 56px 0 80px; }

.ovc-proyecto-single__imagen {
	margin: 0 0 44px;
	border-radius: 14px;
	overflow: hidden;
	box-shadow: 0 2px 8px rgba(57, 62, 70, .12), 0 22px 50px rgba(57, 62, 70, .16);
}

.ovc-proyecto-single__imagen img {
	display: block;
	width: 100%;
	height: auto;
}

/* Dos columnas: la descripción manda, los datos acompañan. Es la misma
   estructura que tenían a mano los 11 proyectos antiguos. */
.ovc-proyecto-single__detalle {
	display: grid;
	grid-template-columns: minmax(0, 1fr) clamp(240px, 30%, 320px);
	gap: 48px;
	align-items: start;
}

.ovc-proyecto-single__sub {
	font-size: clamp(20px, 2.2vw, 26px);
	font-weight: 800;
	letter-spacing: 2px;
	text-transform: uppercase;
	margin: 0 0 6px;
	padding: 0;
	color: var(--ovc-grafito);
}

.ovc-proyecto-single__sub::after {
	content: "";
	display: block;
	width: 90px;
	height: 4px;
	margin: 14px 0 22px;
	background: var(--ovc-azul);
	border-radius: 3px;
}

.ovc-proyecto-single__texto {
	font-size: 17px;
	line-height: 1.85;
	color: #5c6472;
}

.ovc-proyecto-single__texto p:last-child { margin-bottom: 0; }

.ovc-proyecto-single__dato {
	padding: 14px 0;
	border-bottom: 1px solid var(--ovc-linea);
}

.ovc-proyecto-single__dato:first-child { padding-top: 0; }

.ovc-proyecto-single__dato span {
	display: block;
	font-size: 12px;
	font-weight: 800;
	letter-spacing: 1.4px;
	text-transform: uppercase;
	color: #7a8290;
	margin-bottom: 5px;
}

.ovc-proyecto-single__dato strong {
	font-size: 16px;
	font-weight: 600;
	color: var(--ovc-grafito);
}

.ovc-proyecto-single__tecs {
	list-style: none !important;
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin: 4px 0 0;
	padding: 0;
}

.ovc-proyecto-single__tecs li {
	list-style: none !important;
	background: var(--ovc-humo);
	border: 1px solid var(--ovc-linea);
	border-radius: 999px;
	padding: 4px 12px;
	font-size: 13px;
	color: var(--ovc-grafito);
}

.ovc-proyecto-single__tecs li::before { content: none !important; }

@media (max-width: 880px) {
	.ovc-proyecto-single__detalle { grid-template-columns: minmax(0, 1fr); gap: 32px; }
}

.ovc-proyecto-single__enlaces {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 32px 0 0;
}

.ovc-proyecto-single__nav {
	display: grid;
	/* Dos columnas: anterior a la izquierda y siguiente a la derecha. Antes
	   había una tercera en medio con un enlace al portafolio; el menú superior
	   ya lleva ahí, así que solo añadía ruido entre los dos proyectos. */
	grid-template-columns: 1fr 1fr;
	align-items: center;
	gap: 20px;
	margin-top: 56px;
	padding-top: 26px;
	border-top: 1px solid var(--ovc-linea);
}

.ovc-proyecto-single__anterior { text-align: left; }
.ovc-proyecto-single__siguiente { text-align: right; }

.ovc-proyecto-single__nav a {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 1.2px;
	text-transform: uppercase;
	color: var(--ovc-azul);
	text-decoration: none;
	line-height: 1.5;
}

.ovc-proyecto-single__nav a:hover { color: var(--ovc-violeta); }



@media (max-width: 700px) {
	.ovc-proyecto-single__nav { grid-template-columns: 1fr; text-align: center; gap: 14px; }
	.ovc-proyecto-single__anterior,
	.ovc-proyecto-single__siguiente { text-align: center; }
}

/* =========================================================================
   Página de un proyecto

   La imagen destacada se pinta con el módulo de título de Divi al 50% del
   ancho. Con las portadas generadas, que eran apaisadas, quedaba bien; con las
   capturas reales -muchas verticales, de móvil- ocupaba 500px de alto y
   empujaba el texto fuera de la pantalla. Se le pone un tope de altura y se
   deja que la imagen se ajuste dentro.
   ====================================================================== */
.single-project .et_pb_title_featured_container img {
	/*
	 * Los !important no son por pereza: Divi genera para ese módulo concreto
	 * la regla ".et_pb_post_title_1 .et_pb_title_featured_container img
	 * {max-height:none}", que tiene más especificidad que cualquier selector
	 * razonable y además cambia de número según el módulo. Medido en el
	 * navegador: sin esto, max-height salía "none" y la captura se pintaba a
	 * sus 501x766 naturales.
	 */
	max-height: 440px !important;
	width: auto !important;
	max-width: 100% !important;
	border-radius: 12px;
	box-shadow: 0 2px 6px rgba(57, 62, 70, .14), 0 16px 38px rgba(57, 62, 70, .16);
}

.single-project .et_pb_title_featured_container {
	text-align: center;
}

/* =========================================================================
   Ficha tecnica de proyecto  ([proyecto_ficha])
   ====================================================================== */
.ovc-ficha {
	background: var(--ovc-humo);
	border-radius: 10px;
	padding: 28px 32px;
	margin: 32px 0;
}

.ovc-ficha__titulo {
	font-size: 18px;
	font-weight: 700;
	letter-spacing: 3px;
	text-transform: uppercase;
	margin: 0 0 18px;
	color: var(--ovc-grafito);
}

.ovc-ficha__datos {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: 8px 20px;
	margin: 0 0 18px;
}

.ovc-ficha__datos dt {
	font-weight: 700;
	color: #7a8290;
	text-transform: uppercase;
	font-size: 13px;
	letter-spacing: 1px;
}

.ovc-ficha__datos dd { margin: 0; color: var(--ovc-grafito); }

.ovc-ficha__stack {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 18px;
	padding: 0;
}

.ovc-ficha__stack li {
	background: #fff;
	border: 1px solid var(--ovc-linea);
	border-radius: 999px;
	padding: 5px 14px;
	font-size: 14px;
	color: var(--ovc-grafito);
}

.ovc-ficha__enlaces { display: flex; flex-wrap: wrap; gap: 12px; margin: 0; }

.ovc-boton {
	display: inline-block;
	padding: 11px 26px;
	border: 2px solid var(--ovc-azul);
	border-radius: 100px;
	background: var(--ovc-azul);
	color: var(--ovc-humo);
	font-weight: 700;
	font-size: 14px;
	letter-spacing: 2px;
	text-transform: uppercase;
	text-decoration: none;
	transition: background .2s ease, color .2s ease, border-color .2s ease,
	            transform .2s ease, box-shadow .2s ease;
}

.ovc-boton--linea { background: transparent; color: var(--ovc-azul); }

/*
 * Mismo criterio que en los botones de la portada: la reaccion al raton solo
 * existe donde hay raton. En tactil, :hover se aplica al tocar y se queda
 * pegado hasta que se toca otra cosa, y un boton que se da la vuelta y se
 * queda asi parece un fallo.
 */
@media (hover: hover) {

	.ovc-boton:hover {
		background: var(--ovc-violeta);
		border-color: var(--ovc-violeta);
		color: var(--ovc-humo);
		transform: translateY(-2px);
		box-shadow: 0 10px 22px rgba(70, 31, 239, .28);
	}

	.ovc-boton--linea:hover {
		background: rgba(70, 31, 239, .09);
		border-color: var(--ovc-violeta);
		color: var(--ovc-violeta);
		transform: translateY(-2px);
		box-shadow: none;
	}
}

.ovc-boton:active,
.ovc-boton--linea:active { transform: translateY(1px); box-shadow: none; }

.ovc-boton:focus-visible,
.ovc-boton--linea:focus-visible {
	outline: 3px solid var(--ovc-violeta);
	outline-offset: 3px;
}

/* =========================================================================
   Aparición al desplazar

   La clase .ovc-revelar la pone el JavaScript, nunca el HTML ni este archivo.
   Si el script no llega a ejecutarse, estas reglas no se aplican a nada y el
   contenido se ve normal, en vez de quedarse invisible para siempre.
   ====================================================================== */
.ovc-revelar {
	opacity: 0;
	transform: translateY(22px);
	transition: opacity .55s ease, transform .55s cubic-bezier(.22, .61, .36, 1);
	/* Avisa al navegador de lo que va a cambiar para que lo prepare en su
	   propia capa; sin esto el desplazamiento da tirones en los moviles. */
	will-change: opacity, transform;
}

.ovc-revelar.ovc-visible {
	opacity: 1;
	transform: none;
	will-change: auto;
}

/* Variantes de entrada. La distancia es corta a proposito: un movimiento de
   veinte pixeles se lee como que la pagina responde; uno de cien se lee como
   que la pagina se esta montando delante de uno, y cansa al tercer bloque. */
.ovc-revelar--arriba { transform: translateY(26px); }
.ovc-revelar--izq    { transform: translateX(-28px); }
.ovc-revelar--der    { transform: translateX(28px); }
.ovc-revelar--zoom   { transform: translateY(20px) scale(.97); }

/* El subrayado azul se dibuja de izquierda a derecha en vez de aparecer. */
.ovc-revelar--raya {
	opacity: 1;
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform .7s cubic-bezier(.22, .61, .36, 1);
}

.ovc-revelar--raya.ovc-visible { transform: scaleX(1); }

/* =========================================================================
   Barra de progreso de lectura

   La crea el JavaScript y la pega arriba del todo. Tres pixeles, por encima
   de la cabecera fija de Divi (z-index 99999) y sin capturar el raton.
   ====================================================================== */
.ovc-progreso {
	position: fixed;
	top: 0; left: 0;
	width: 100%; height: 3px;
	z-index: 100000;
	background: linear-gradient(90deg, var(--ovc-azul), var(--ovc-violeta));
	transform: scaleX(0);
	transform-origin: left center;
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.ovc-progreso { display: none; }
}

/* Quien pide menos movimiento en su sistema lo ve todo de golpe. El script ya
   lo comprueba, pero esto cubre el instante entre que pinta y se ejecuta. */
@media (prefers-reduced-motion: reduce) {
	.ovc-revelar { opacity: 1; transform: none; transition: none; }
}

/* Los números no deben cambiar de ancho mientras suben: con cifras tabulares
   la tira de cifras no da saltos al animarse. */
.ovc-cifra__dato {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum";
}

/* =========================================================================
   Portada: bloque de presentación

   La tipografía va aquí y no en los ajustes del módulo de Divi. El contenido
   de la página se escribe directamente en la base de datos, sin pasar por el
   maquetador, y Divi solo genera el CSS de los módulos cuando guarda desde su
   propia interfaz: los tamaños puestos en el shortcode se quedaban sin efecto
   y el nombre salía a tamaño de párrafo.
   ====================================================================== */
.ovc-hero h1 {
	font-size: clamp(34px, 5vw, 56px);
	font-weight: 800;
	line-height: 1.08;
	letter-spacing: -1.5px;
	margin: 0 0 10px;
	color: var(--ovc-grafito);
	padding-bottom: 0;
}

.ovc-hero__rol {
	font-size: clamp(15px, 1.5vw, 19px);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--ovc-violeta);
	margin: 0 0 26px;
}

.ovc-hero p:not(.ovc-hero__rol) {
	font-size: 16.5px;
	line-height: 1.85;
	color: #5c6472;
	max-width: 44em;
}

.ovc-hero strong { color: var(--ovc-grafito); }

/* Los botones de Divi se apilan dentro de una columna; en la portada tienen
   que ir uno al lado del otro.

   La clase del módulo cae en el <a>, no en el div que lo envuelve, y es ese
   div el que es de bloque. Así que se marca la columna y desde ahí se alcanza
   el contenedor. */
.ovc-hero-col .et_pb_button_module_wrapper {
	display: inline-block;
	margin: 10px 14px 0 0;
}

@media (max-width: 480px) {
	.ovc-hero-col .et_pb_button_module_wrapper { display: block; margin-right: 0; }
	.ovc-hero-col .et_pb_button { display: block; text-align: center; }
}

/* -------------------------------------------------------------------------
   Botones.

   Los colores van aquí por el mismo motivo que la tipografía: Divi solo genera
   el CSS de sus módulos al guardar desde el maquetador, y los ajustes escritos
   en el shortcode no llegan a pintarse. Sin esto, el botón principal y el
   secundario salían idénticos.
   ---------------------------------------------------------------------- */
.et_pb_button.ovc-boton-primario,
.et_pb_button.ovc-boton-secundario {
	padding: 13px 30px !important;
	border-radius: 100px !important;
	border-width: 2px !important;
	font-size: 15px !important;
	font-weight: 700 !important;
	letter-spacing: 2px !important;
	text-transform: uppercase !important;
	transition: background .2s ease, color .2s ease, border-color .2s ease,
	            transform .2s ease, box-shadow .2s ease;
}

.et_pb_button.ovc-boton-primario {
	background: var(--ovc-azul) !important;
	border-color: var(--ovc-azul) !important;
	color: #fff !important;
}

.et_pb_button.ovc-boton-secundario {
	background: transparent !important;
	border-color: var(--ovc-azul) !important;
	color: var(--ovc-azul) !important;
}

/* En la banda azul del final, el primario se invierte. */
.ovc-cta .et_pb_button.ovc-boton-primario {
	background: #fff !important;
	border-color: #fff !important;
	color: var(--ovc-azul) !important;
}

/* -------------------------------------------------------------------------
   Reaccion al raton

   Toda la reaccion vive dentro de @media (hover: hover), y no es un capricho.
   En un movil o una tableta no hay puntero: al tocar un boton el navegador le
   aplica :hover y AHI SE QUEDA hasta que se toca otra cosa. Con un efecto que
   le da la vuelta al boton, el resultado es que despues de pulsar «Contactar»
   queda un rectangulo azul relleno en medio de la pagina, como si estuviera
   roto. Con esta consulta, en pantallas tactiles el efecto no existe y el
   boton se queda como estaba.

   Y el efecto en si cambia: antes cada boton se invertia entero -el de linea
   se rellenaba de azul, y el blanco de la banda se volvia transparente y
   desaparecia dentro de ella-. Ahora solo se matiza: se nota que responde,
   pero sigue siendo el mismo boton.
   ---------------------------------------------------------------------- */

@media (hover: hover) {

	.et_pb_button.ovc-boton-primario:hover {
		background: var(--ovc-violeta) !important;
		border-color: var(--ovc-violeta) !important;
		color: #fff !important;
	}

	/* El de linea se tine, no se rellena: conserva su caracter. */
	.et_pb_button.ovc-boton-secundario:hover {
		background: rgba(70, 31, 239, .09) !important;
		border-color: var(--ovc-violeta) !important;
		color: var(--ovc-violeta) !important;
	}

	/* El blanco sobre la banda azul se queda blanco; solo se levanta. */
	.ovc-cta .et_pb_button.ovc-boton-primario:hover {
		background: #fff !important;
		border-color: #fff !important;
		color: var(--ovc-azul) !important;
		box-shadow: 0 10px 26px rgba(0, 0, 0, .22);
	}

	.et_pb_button.ovc-boton-primario:hover,
	.et_pb_button.ovc-boton-secundario:hover { transform: translateY(-2px); }
}

/* -------------------------------------------------------------------------
   Pulsacion y foco

   El hundimiento al pulsar si vale en tactil: dura lo que dura el dedo encima
   y no se queda pegado.
   ---------------------------------------------------------------------- */

.et_pb_button.ovc-boton-primario:active,
.et_pb_button.ovc-boton-secundario:active {
	transform: translateY(1px) !important;
	box-shadow: none !important;
}

/*
 * Anillo de foco para quien navega con el teclado.
 *
 * Divi deja el outline en none, asi que al tabular no se veia donde estaba
 * uno. :focus-visible solo lo pinta cuando el navegador entiende que hace
 * falta -teclado si, raton no-, de modo que no reaparece el problema de que
 * el boton se quede marcado despues de pulsarlo.
 */
.et_pb_button.ovc-boton-primario:focus-visible,
.et_pb_button.ovc-boton-secundario:focus-visible {
	outline: 3px solid var(--ovc-violeta) !important;
	outline-offset: 3px;
}

.ovc-cta h2 { color: #fff; font-size: clamp(26px, 3vw, 36px); font-weight: 800; margin: 0 0 10px; }
.ovc-cta p  { color: rgba(255,255,255,.88); font-size: 18px; margin: 0; }

/* =========================================================================
   Cabecera de página y datos de contacto
   ====================================================================== */
/* Banda superior de las páginas interiores.

   El diseño original tenía un bloque azul ocupando el tercio izquierdo, justo
   donde va el logotipo. Con el logo en oscuro -que es lo que pide la portada,
   ahora clara- ahí quedaba ilegible. Se deja la banda clara en todas las
   páginas y el azul pasa a ser un acento bajo el título. */
.ovc-banda,
#seccion-cabezal {
	/* #seccion-cabezal es el identificador que llevan las bandas superiores
	   de Acerca y Portafolio, que vienen del diseño original y traen un
	   gradiente en línea de Divi 3. Se anula aquí para que las cinco páginas
	   tengan la misma cabecera y el logotipo oscuro se lea en todas. */
	background: var(--ovc-humo) !important;
	background-image: none !important;
	border-bottom: 1px solid var(--ovc-linea);
	/* La cabecera de Divi va superpuesta y mide unos 60px: sin ese margen
	   extra arriba, el título quedaba pegado al logotipo. */
	padding: 130px 0 70px !important;
}

/* La banda vieja mete el título en una columna de 2/3 con otra vacía delante;
   se recupera el ancho completo. */
#seccion-cabezal .et_pb_column { width: 100% !important; margin: 0 !important; }
#seccion-cabezal .et_pb_column:empty { display: none !important; }

#seccion-cabezal h1 {
	font-size: clamp(32px, 4.5vw, 48px);
	font-weight: 800;
	letter-spacing: -1px;
	color: var(--ovc-grafito);
	padding-bottom: 0;
	margin: 0;
}

#seccion-cabezal h1::after {
	content: "";
	display: block;
	width: 72px;
	height: 5px;
	margin-top: 16px;
	background: var(--ovc-azul);
	border-radius: 3px;
}

@media (max-width: 767px) {
	.ovc-banda,
	#seccion-cabezal { padding: 100px 0 46px !important; }
}

.ovc-cabecera h1::after {
	content: "";
	display: block;
	width: 72px;
	height: 5px;
	margin-top: 16px;
	background: var(--ovc-azul);
	border-radius: 3px;
}

.ovc-cabecera h1 {
	font-size: clamp(32px, 4.5vw, 48px);
	font-weight: 800;
	letter-spacing: -1px;
	margin: 0 0 8px;
	padding-bottom: 0;
	color: var(--ovc-grafito);
}

.ovc-cabecera p {
	font-size: 17px;
	color: #5c6472;
	margin: 0;
}

/* =========================================================================
   Cifras de la portada  ([ovc_cifras])
   ====================================================================== */
.ovc-cifras {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 1px;
	background: var(--ovc-linea);
	border: 1px solid var(--ovc-linea);
	border-radius: 14px;
	overflow: hidden;
}

.ovc-cifra {
	background: #fff;
	padding: 26px 18px;
	text-align: center;
}

.ovc-cifra__dato {
	display: block;
	font-size: 42px;
	font-weight: 800;
	line-height: 1.1;
	color: var(--ovc-azul);
	letter-spacing: -1px;
}

.ovc-cifra__texto {
	display: block;
	margin-top: 6px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 1.2px;
	text-transform: uppercase;
	color: #7a8290;
}

/* =========================================================================
   Servicios  ([ovc_servicios])
   ====================================================================== */
.ovc-servicios {
	display: grid;
	gap: 24px;
}

.ovc-servicios--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ovc-servicios--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ovc-servicios--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.ovc-servicio {
	position: relative;
	background: #fff;
	border: 1px solid var(--ovc-linea);
	border-radius: 16px;
	padding: 30px 30px 32px;
	overflow: hidden;
	transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.ovc-servicio:hover {
	transform: translateY(-5px);
	border-color: transparent;
	box-shadow: 0 18px 44px rgba(70, 31, 239, .16);
}

/* Número de orden, muy tenue, al fondo: da jerarquía sin robar atención. */
.ovc-servicio__numero {
	position: absolute;
	top: 12px;
	right: 22px;
	font-size: 62px;
	font-weight: 800;
	line-height: 1;
	color: var(--ovc-humo);
	pointer-events: none;
}

.ovc-servicio__marca {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 54px;
	height: 54px;
	border-radius: 14px;
	background: linear-gradient(135deg, var(--ovc-azul), var(--ovc-violeta));
	color: #fff;
	margin-bottom: 18px;
}

.ovc-servicio__icono { width: 26px; height: 26px; }

.ovc-servicio__titulo {
	position: relative;
	font-size: 20px;
	font-weight: 700;
	line-height: 1.3;
	margin: 0 0 10px;
	color: var(--ovc-grafito);
}

.ovc-servicio__texto {
	margin: 0 0 14px;
	line-height: 1.7;
	color: #5c6472;
}

.ovc-servicio__tecs {
	margin: 0;
	padding-top: 14px;
	border-top: 1px solid var(--ovc-linea);
	font-size: 13.5px;
	font-weight: 600;
	letter-spacing: .3px;
	color: var(--ovc-violeta);
}

.ovc-servicio__enlace {
	display: inline-block;
	margin-top: 16px;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--ovc-azul);
	text-decoration: none;
	border-bottom: 2px solid currentColor;
}

/* =========================================================================
   Aficiones  ([cv_aficiones])
   ====================================================================== */
.ovc-aficiones__titulo {
	font-size: 36px; font-weight: 700; letter-spacing: 4px;
	margin: 0 0 12px; color: var(--ovc-grafito);
}

.ovc-aficiones__raya {
	display: block; width: 150px; height: 5px;
	background: var(--ovc-azul); margin: 0 0 40px;
}

/*
 * Flex y no grid, a proposito. Las aficiones son las que sean: si quedan
 * cinco en una rejilla de cuatro, con grid la quinta se queda sola pegada al
 * margen izquierdo. Asi la ultima fila incompleta se centra sola, sea cual
 * sea el numero de fichas publicadas.
 */
.ovc-aficiones__rejilla {
	display: flex; flex-wrap: wrap; gap: 24px; justify-content: center;
}

.ovc-aficiones__rejilla > .ovc-aficion { flex: 0 1 auto; }

.ovc-aficiones--cols-2 > .ovc-aficion { width: calc((100% - 1 * 24px) / 2); }
.ovc-aficiones--cols-3 > .ovc-aficion { width: calc((100% - 2 * 24px) / 3); }
.ovc-aficiones--cols-4 > .ovc-aficion { width: calc((100% - 3 * 24px) / 4); }
.ovc-aficiones--cols-5 > .ovc-aficion { width: calc((100% - 4 * 24px) / 5); }

.ovc-aficion {
	background: #fff; border: 1px solid var(--ovc-linea);
	border-radius: 14px; padding: 26px 22px; text-align: center;
	transition: transform .25s ease, box-shadow .25s ease;
}

.ovc-aficion:hover { transform: translateY(-5px); box-shadow: 0 16px 34px rgba(70, 31, 239, .15); }

.ovc-aficion__marca {
	width: 66px; height: 66px; margin: 0 auto 14px; border-radius: 50%;
	background: linear-gradient(135deg, var(--ovc-azul), var(--ovc-violeta));
	display: flex; align-items: center; justify-content: center; overflow: hidden;
}

.ovc-aficion__marca img { width: 100%; height: 100%; object-fit: cover; }
.ovc-aficion__emoji { font-size: 30px; line-height: 1; color: #fff; }

.ovc-aficion__titulo { font-size: 17px; font-weight: 700; margin: 0 0 6px; color: var(--ovc-grafito); }
.ovc-aficion__texto { font-size: 14.5px; line-height: 1.65; color: #6b7280; }
.ovc-aficion__texto p:last-child { margin-bottom: 0; }

/* =========================================================================
   Rejilla de proyectos  ([proyectos_destacados])
   ====================================================================== */
.ovc-proyectos__filtros {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 0 0 32px;
}

.ovc-filtro {
	appearance: none;
	border: 2px solid var(--ovc-linea);
	background: transparent;
	color: var(--ovc-grafito);
	border-radius: 999px;
	padding: 9px 20px;
	font: inherit;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	cursor: pointer;
	transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.ovc-filtro:hover { border-color: var(--ovc-violeta); color: var(--ovc-violeta); }

.ovc-filtro.is-activo {
	background: var(--ovc-azul);
	border-color: var(--ovc-azul);
	color: #fff;
}

.ovc-proyectos__rejilla {
	display: grid;
	gap: 28px;
}

.ovc-proyectos--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ovc-proyectos--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ovc-proyectos--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/*
 * El atributo [hidden] del navegador vale display:none, pero cualquier regla
 * del tema que fije display en el elemento le gana: Divi lleva en su reset un
 * "article { display: block }" y las tarjetas ocultadas por el filtro seguían
 * viéndose. Medido: al filtrar por Soporte quedaban 36 visibles y 0 ocultas.
 */
.ovc-proyecto[hidden] {
	display: none !important;
}

.ovc-proyecto {
	background: #fff;
	border: 1px solid var(--ovc-linea);
	border-radius: 14px;
	overflow: hidden;
	transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.ovc-proyecto:hover {
	transform: translateY(-6px);
	border-color: transparent;
	box-shadow: 0 18px 40px rgba(70, 31, 239, .18);
}

.ovc-proyecto__enlace {
	display: flex;
	flex-direction: column;
	height: 100%;
	text-decoration: none;
	color: inherit;
}

.ovc-proyecto__imagen {
	position: relative;
	aspect-ratio: 16 / 10;
	overflow: hidden;
	background: var(--ovc-humo);
	display: flex;
	align-items: center;
	justify-content: center;
}

.ovc-proyecto__imagen img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform .5s ease;
}

.ovc-proyecto:hover .ovc-proyecto__imagen img { transform: scale(1.05); }

/* Respaldo cuando el proyecto no tiene ni imagen ni portada generada. */
.ovc-proyecto__sinimagen {
	font-size: 44px;
	font-weight: 800;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: #fff;
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: linear-gradient(135deg, var(--ovc-azul), var(--ovc-violeta));
}

.ovc-proyecto__categoria {
	position: absolute;
	top: 14px;
	left: 14px;
	background: rgba(255, 255, 255, .92);
	color: var(--ovc-grafito);
	border-radius: 999px;
	padding: 5px 13px;
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 1.2px;
	text-transform: uppercase;
}

.ovc-proyecto__cuerpo {
	padding: 20px 22px 24px;
	display: flex;
	flex-direction: column;
	gap: 10px;
	flex: 1;
}

.ovc-proyecto__titulo {
	font-size: 19px;
	font-weight: 700;
	line-height: 1.35;
	margin: 0;
	color: var(--ovc-grafito);
}

.ovc-proyecto:hover .ovc-proyecto__titulo { color: var(--ovc-violeta); }

.ovc-proyecto__anio {
	margin: 0;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 1px;
	color: #7a8290;
}

/*
 * Divi pone viñeta a toda <li> dentro de un módulo de texto, y aquí las
 * etiquetas de tecnología salían con un punto delante. No basta con
 * list-style en la <ul>: hay que anularlo también en la <li>.
 */
.ovc-proyecto__tecs,
.ovc-proyecto__tecs li,
.ovc-ficha__stack,
.ovc-ficha__stack li {
	list-style: none !important;
}

.ovc-proyecto__tecs li::before,
.ovc-ficha__stack li::before,
.ovc-proyectos__filtros::before { content: none !important; }

.ovc-proyecto__tecs {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin: auto 0 0;
	padding: 0;
}

.ovc-proyecto__tecs li {
	background: var(--ovc-humo);
	border: 1px solid var(--ovc-linea);
	border-radius: 999px;
	padding: 4px 11px;
	font-size: 12.5px;
	color: var(--ovc-grafito);
}

.ovc-proyecto__mas { font-weight: 700; color: var(--ovc-violeta); }

/* =========================================================================
   Iconos sociales anadidos en includes/social_icons.php

   Codigos tomados de Divi (social_media_follow.css). LinkedIn esta en la
   fuente ETmodules; GitHub y WhatsApp estan en FontAwesome, por eso llevan
   ademas la clase et-pb-social-fa-icon en el marcado. Estas reglas hacen
   falta aqui porque el CSS del modulo Social Media Follow solo se carga si
   ese modulo aparece en la pagina, y estos iconos van en cabecera y pie.
   ====================================================================== */
.et-social-linkedin a.icon::before { content: "\E09D"; }

.et-pb-social-fa-icon a.icon::before { font-family: FontAwesome; }
.et-social-github   a.icon::before { content: "\F09B"; }
.et-social-whatsapp a.icon::before { content: "\F232"; }

/* =========================================================================
   Responsive
   ====================================================================== */
@media (max-width: 1100px) {
	.ovc-proyectos--cols-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 980px) {
	.ovc-cv--cols-2,
	.ovc-cv--cols-3 { grid-template-columns: 1fr; }

	/* Las fotos bajan y se ponen una al lado de otra, sin solaparse. */
	.ovc-cv__item--con-fotos { grid-template-columns: 64px minmax(0, 1fr); }
	.ovc-cv__item--con-fotos:not(.ovc-cv__item--con-imagen) { grid-template-columns: minmax(0, 1fr); }
	.ovc-cv__fotos {
		grid-column: 1 / -1;
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 14px;
		margin-top: 18px;
	}
	.ovc-cv__fotos--2 .ovc-cv__foto--1,
	.ovc-cv__fotos--2 .ovc-cv__foto--2 { width: 100%; margin: 0; border: 0; outline: 0; }
	.ovc-cv__fotos--dos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ovc-cv__fotos--una { grid-template-columns: minmax(0, 1fr); max-width: 420px; }
	.ovc-cv--marco-acento .ovc-cv__foto::before { inset: 9px -9px -9px 9px; }
	.ovc-cv--marco-acento .ovc-cv__item:nth-child(even) .ovc-cv__foto::before { inset: -9px 9px 9px -9px; }
	.ovc-proyectos--cols-3,
	.ovc-proyectos--cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 980px) {
	.ovc-aficiones--cols-3 > .ovc-aficion,
	.ovc-aficiones--cols-4 > .ovc-aficion,
	.ovc-aficiones--cols-5 > .ovc-aficion { width: calc((100% - 24px) / 2); }
}

@media (max-width: 980px) {
	.ovc-servicios--cols-3,
	.ovc-servicios--cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
	.ovc-proyectos__rejilla { grid-template-columns: 1fr !important; }
	.ovc-servicios { grid-template-columns: 1fr !important; }
	.ovc-cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ovc-cifra__dato { font-size: 34px; }
	.ovc-aficiones__rejilla > .ovc-aficion { width: 100% !important; }
	.ovc-aficiones__titulo { font-size: 26px; }
	.ovc-filtro { padding: 8px 15px; font-size: 12.5px; }
}

@media (max-width: 767px) {
	.ovc-cv { gap: 32px; }
	.ovc-cv__item--con-imagen { grid-template-columns: 48px minmax(0, 1fr); gap: 14px; }
	.ovc-cv__logo { width: 48px; height: 48px; border-radius: 11px; }
	.ovc-cv__titulo { font-size: 18px; }
	.ovc-ficha { padding: 22px 20px; }
	.ovc-ficha__datos { grid-template-columns: 1fr; gap: 2px; }
	.ovc-ficha__datos dd { margin-bottom: 10px; }
	.ovc-ficha__enlaces .ovc-boton { flex: 1 1 100%; text-align: center; }
}

/* =========================================================================
   Habilidades  ([cv_habilidades])

   Sustituyen a las barras de porcentaje. Sin numeros: lo que respalda cada
   competencia es la certificacion o el proyecto que ya aparece en la pagina,
   no una barra que se rellena sola.
   ====================================================================== */

.ovc-habilidades { margin: 0 0 10px; }

.ovc-habilidades__titulo {
	font-size: 36px; font-weight: 700; letter-spacing: 4px;
	margin: 0 0 12px; color: var(--ovc-grafito);
}

.ovc-habilidades__raya {
	display: block; width: 150px; height: 5px;
	background: var(--ovc-azul); margin: 0 0 40px;
}

.ovc-habilidades__rejilla { display: grid; gap: 24px; }

.ovc-habilidades--cols-1 { grid-template-columns: minmax(0, 1fr); }
.ovc-habilidades--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ovc-habilidades--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.ovc-hab {
	background: #fff; border: 1px solid var(--ovc-linea);
	border-radius: 14px; padding: 28px 24px;
	transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.ovc-hab:hover {
	transform: translateY(-5px);
	box-shadow: 0 16px 34px rgba(70, 31, 239, .14);
	border-color: rgba(70, 31, 239, .3);
}

.ovc-hab__marca {
	width: 52px; height: 52px; margin: 0 0 16px; border-radius: 13px;
	background: linear-gradient(135deg, var(--ovc-azul), var(--ovc-violeta));
	display: flex; align-items: center; justify-content: center;
	color: #fff;
}

.ovc-hab__icono { width: 26px; height: 26px; display: block; }

.ovc-hab__titulo {
	font-size: 17px; font-weight: 700; line-height: 1.35;
	margin: 0 0 14px; padding: 0; color: var(--ovc-grafito);
}

/* Se anula la vinneta y el margen que Divi pone a cualquier ul del contenido. */
.ovc-hab__items,
.ovc-hab__items li {
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
}

.ovc-hab__items::before,
.ovc-hab__items li::before { content: none !important; }

.ovc-hab__items {
	display: flex !important; flex-wrap: wrap; gap: 7px;
}

.ovc-hab__items li {
	font-size: 13px; font-weight: 600; line-height: 1.3;
	padding: 6px 11px !important;
	border-radius: 999px;
	background: rgba(70, 31, 239, .07);
	color: var(--ovc-azul);
}

.ovc-habilidades__blandas {
	margin: 34px 0 0; padding: 18px 22px;
	border-left: 4px solid var(--ovc-azul);
	background: #f5f8fa; border-radius: 0 10px 10px 0;
	font-size: 15px; line-height: 1.7; color: #4b5563;
}

.ovc-habilidades__blandas strong { color: var(--ovc-grafito); margin-right: 4px; }

@media (max-width: 980px) {
	.ovc-habilidades--cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 780px) {
	.ovc-habilidades__titulo { font-size: 28px; letter-spacing: 3px; }
	.ovc-habilidades__raya { width: 110px; margin-bottom: 28px; }
	.ovc-habilidades__rejilla { grid-template-columns: 1fr !important; }
}

/* =========================================================================
   Contacto  ([ovc_contacto] + formulario de Divi)

   La version anterior era una lista de texto con una linea gris debajo de
   cada dato, y el formulario salia con los campos grises planos que trae Divi
   de serie: cuatro rectangulos sin borde ni etiqueta visible. Aqui los datos
   pasan a ser tarjetas en las que se puede pulsar -el telefono marca, el
   correo abre el gestor, WhatsApp abre la conversacion- y el formulario se
   viste con el mismo lenguaje que el resto del sitio.
   ====================================================================== */

.ovc-contacto__titulo {
	font-size: clamp(28px, 3.4vw, 40px);
	font-weight: 800; letter-spacing: -.6px;
	margin: 0 0 12px; padding-bottom: 0;
	color: var(--ovc-grafito);
}

.ovc-contacto__bajada {
	font-size: 16.5px; line-height: 1.75;
	color: #5c6472; margin: 0 0 28px;
}

/* ---- Tarjetas de dato --------------------------------------------- */

.ovc-vcards { display: grid; gap: 12px; margin: 0 0 26px; }

.ovc-vcard {
	display: flex; align-items: center; gap: 15px;
	padding: 15px 18px;
	background: #fff;
	border: 1px solid var(--ovc-linea);
	border-radius: 13px;
	text-decoration: none !important;
	color: inherit;
	transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease;
}

a.ovc-vcard:hover {
	transform: translateX(5px);
	border-color: rgba(70, 31, 239, .35);
	box-shadow: 0 12px 26px rgba(70, 31, 239, .13);
}

.ovc-vcard__marca {
	flex: 0 0 auto;
	width: 44px; height: 44px; border-radius: 12px;
	display: flex; align-items: center; justify-content: center;
	background: rgba(70, 31, 239, .08);
	color: var(--ovc-azul);
	transition: background .22s ease, color .22s ease;
}

a.ovc-vcard:hover .ovc-vcard__marca {
	background: var(--ovc-azul); color: #fff;
}

.ovc-vcard__icono { width: 21px; height: 21px; display: block; }

.ovc-vcard__cuerpo { display: block; min-width: 0; }

.ovc-vcard__rotulo {
	display: block;
	font-size: 11.5px; font-weight: 700; letter-spacing: 1.4px;
	text-transform: uppercase; color: #7a8290; margin-bottom: 2px;
}

.ovc-vcard__valor {
	display: block;
	font-size: 16.5px; font-weight: 600; color: var(--ovc-grafito);
	word-break: break-word;
}

/* WhatsApp es el canal por el que de verdad escribe la gente aqui: se marca. */
.ovc-vcard--fuerte {
	background: linear-gradient(135deg, var(--ovc-azul), var(--ovc-violeta));
	border-color: transparent;
}

.ovc-vcard--fuerte .ovc-vcard__marca { background: rgba(255, 255, 255, .18); color: #fff; }
.ovc-vcard--fuerte .ovc-vcard__rotulo { color: rgba(255, 255, 255, .8); }
.ovc-vcard--fuerte .ovc-vcard__valor { color: #fff; }

a.ovc-vcard--fuerte:hover { box-shadow: 0 16px 34px rgba(70, 31, 239, .34); }
a.ovc-vcard--fuerte:hover .ovc-vcard__marca { background: rgba(255, 255, 255, .28); color: #fff; }

/* ---- Notas ---------------------------------------------------------- */

.ovc-contacto__notas,
.ovc-contacto__notas li { list-style: none !important; margin: 0; padding: 0; }
.ovc-contacto__notas li::before { content: none !important; }

.ovc-contacto__notas { display: grid; gap: 9px; }

.ovc-contacto__notas li {
	position: relative;
	padding-left: 26px !important;
	font-size: 14.5px; line-height: 1.6; color: #5c6472;
}

/* Palomita dibujada en CSS: no depende de ninguna fuente de iconos. */
.ovc-contacto__notas li::after {
	content: ''; position: absolute;
	left: 3px; top: 6px;
	width: 5px; height: 10px;
	border: solid var(--ovc-azul);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}

/* ---- Formulario de Divi --------------------------------------------- */

.ovc-formulario {
	background: #fff;
	border: 1px solid var(--ovc-linea);
	border-radius: 18px;
	padding: 34px 32px !important;
	box-shadow: 0 20px 50px rgba(23, 28, 43, .07);
}

.ovc-formulario .et_pb_contact_main_title {
	font-size: 20px; font-weight: 800; color: var(--ovc-grafito);
	margin-bottom: 18px;
}

.ovc-formulario .et_pb_contact_field { padding: 0 8px 16px !important; }

.ovc-formulario .et_pb_contact_field_options_title { display: none; }

.ovc-formulario input[type="text"],
.ovc-formulario input[type="email"],
.ovc-formulario textarea,
.ovc-formulario .et_pb_contact_field input,
.ovc-formulario .et_pb_contact_field textarea {
	width: 100%;
	background: #f7f9fc !important;
	border: 1.5px solid var(--ovc-linea) !important;
	border-radius: 11px !important;
	padding: 14px 16px !important;
	font-size: 15.5px !important;
	color: var(--ovc-grafito) !important;
	transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}

.ovc-formulario input::placeholder,
.ovc-formulario textarea::placeholder { color: #9aa2b1 !important; opacity: 1; }

.ovc-formulario input:focus,
.ovc-formulario textarea:focus {
	outline: none;
	background: #fff !important;
	border-color: var(--ovc-azul) !important;
	box-shadow: 0 0 0 4px rgba(70, 31, 239, .12);
}

.ovc-formulario textarea { min-height: 158px; resize: vertical; }

/* La suma anti-robots: Divi la deja minuscula y pegada al boton. */
.ovc-formulario .et_pb_contact_right {
	display: flex; align-items: center; gap: 10px;
	padding: 0 8px 16px !important; margin: 0;
	font-size: 15px; color: #5c6472;
}

.ovc-formulario .et_pb_contact_captcha_question { font-weight: 700; color: var(--ovc-grafito); }

.ovc-formulario input.et_pb_contact_captcha {
	width: 74px !important; text-align: center; padding: 12px 8px !important;
}

.ovc-formulario .et_contact_bottom_container {
	float: none !important;
	display: block; padding: 0 8px; margin-top: 4px;
}

.ovc-formulario .et_pb_contact_submit {
	display: block !important; width: 100% !important;
	padding: 15px 26px !important;
	background: var(--ovc-azul) !important;
	color: #fff !important;
	border: 0 !important; border-radius: 999px !important;
	font-size: 15px !important; font-weight: 700 !important;
	letter-spacing: 2.4px; text-transform: uppercase;
	cursor: pointer;
	transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}

.ovc-formulario .et_pb_contact_submit::after { display: none !important; }

.ovc-formulario .et_pb_contact_submit:hover {
	background: var(--ovc-violeta) !important;
	transform: translateY(-2px);
	box-shadow: 0 14px 30px rgba(70, 31, 239, .32);
}

.ovc-formulario .et_pb_contact_error_text,
.ovc-formulario .et-pb-contact-message p { font-size: 14.5px; }

@media (max-width: 780px) {
	.ovc-formulario { padding: 26px 20px !important; border-radius: 14px; }
	.ovc-vcard { padding: 13px 15px; }
	.ovc-vcard__valor { font-size: 15.5px; }
}

/* =========================================================================
   Contacto: acabado

   La tarjeta del formulario era blanca sobre fondo blanco y lo unico que la
   separaba era un borde de un pixel, que a un metro de la pantalla no se ve.
   Con la seccion en gris claro la tarjeta se despega y el bloque entero se
   lee como una pieza, no como texto suelto.
   ====================================================================== */

.ovc-seccion-contacto {
	background: linear-gradient(180deg, var(--ovc-humo) 0%, #eef2f7 100%);
}

.ovc-seccion-contacto .ovc-vcard {
	box-shadow: 0 1px 2px rgba(23, 28, 43, .04);
}

.ovc-seccion-contacto .ovc-formulario {
	box-shadow: 0 24px 60px rgba(23, 28, 43, .11);
	position: relative;
	overflow: hidden;
}

/* Filete de color arriba de la tarjeta: la ancla visualmente al resto. */
.ovc-seccion-contacto .ovc-formulario::before {
	content: '';
	position: absolute;
	top: 0; left: 0; right: 0;
	height: 4px;
	background: linear-gradient(90deg, var(--ovc-azul), var(--ovc-violeta));
}

/* El enlace de llamar, debajo de la tarjeta destacada. */
.ovc-vcard__segundo {
	display: inline-block;
	/* Hijo de la rejilla: sin esto se estira a todo el ancho y el subrayado
	   sale como una raya larga al lado de la palabra. */
	justify-self: start;
	margin: -4px 0 4px 62px;
	font-size: 13px; font-weight: 700;
	letter-spacing: .3px;
	color: var(--ovc-azul) !important;
	text-decoration: none !important;
	border-bottom: 1.5px solid rgba(70, 31, 239, .3);
	padding-bottom: 1px;
	transition: border-color .2s ease, color .2s ease;
}

.ovc-vcard__segundo:hover {
	color: var(--ovc-violeta) !important;
	border-color: var(--ovc-violeta);
}

/* La suma anti-robots: se le pone marco de campo para que no parezca que se
   ha colado ahi por error. */
.ovc-seccion-contacto .ovc-formulario .et_pb_contact_right {
	background: #f7f9fc;
	border: 1.5px solid var(--ovc-linea);
	border-radius: 11px;
	padding: 11px 16px !important;
	margin: 0 8px 16px !important;
	width: auto;
}

@media (max-width: 980px) {
	.ovc-vcard__segundo { margin-left: 0; }
}

/* =========================================================================
   Linea de tiempo: alternar el lado de la foto

   Las tres secciones de Acerca -reconocimientos, experiencia y educacion
   formal- usan la misma plantilla, y dentro de cada una las veinte entradas
   se repetian identicas: insignia a la izquierda, texto en medio, foto a la
   derecha. Veinte veces seguidas la pagina se lee como un listado de Excel.

   Alternando el lado en las pares, el ojo tiene que volver a encontrar la
   foto en cada entrada y la pagina deja de parecer la misma fila repetida.
   El orden del marcado no cambia -logo, texto, fotos-, asi que un lector de
   pantalla y la version impresa siguen leyendo en el orden logico.
   ====================================================================== */

@media (min-width: 981px) {

	/* Con insignia: foto | insignia | texto */
	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos.ovc-cv__item--con-imagen:nth-child(even) {
		grid-template-columns: clamp(200px, 26%, 300px) 64px minmax(0, 1fr);
	}

	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos.ovc-cv__item--con-imagen:nth-child(even) .ovc-cv__fotos { grid-column: 1; grid-row: 1; }

	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos.ovc-cv__item--con-imagen:nth-child(even) .ovc-cv__logo { grid-column: 2; grid-row: 1; }

	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos.ovc-cv__item--con-imagen:nth-child(even) .ovc-cv__datos { grid-column: 3; grid-row: 1; }

	/* Sin insignia: foto | texto */
	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos:not(.ovc-cv__item--con-imagen):nth-child(even) {
		grid-template-columns: clamp(200px, 26%, 300px) minmax(0, 1fr);
	}

	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos:not(.ovc-cv__item--con-imagen):nth-child(even) .ovc-cv__fotos { grid-column: 1; grid-row: 1; }

	.ovc-cv:not(.ovc-cv--cols-2):not(.ovc-cv--cols-3)
	.ovc-cv__item--con-fotos:not(.ovc-cv__item--con-imagen):nth-child(even) .ovc-cv__datos { grid-column: 2; grid-row: 1; }

	/* Y la entrada entra por el lado en el que esta su foto. */
	.ovc-cv__item:nth-child(even).ovc-revelar--izq { transform: translateX(28px); }
	.ovc-cv__item:nth-child(even).ovc-revelar--izq.ovc-visible { transform: none; }
}

/* =========================================================================
   Imagenes con vida

   Todas las imagenes del sitio estaban quietas: un rectangulo pegado al
   texto. Aqui reciben el mismo trato en todas partes -se acercan despacio
   bajo el raton, dentro de su marco, sin mover la maqueta-. El recorte lo
   hace el contenedor con overflow, asi que la imagen crece pero el hueco que
   ocupa en la pagina no cambia ni un pixel: sin esto, cada vez que el raton
   pasa por encima el texto de al lado daria un salto.
   ====================================================================== */

/*
 * El recorte NO se aplica a los marcos que llevan la sombra desplazada de
 * Divi: esa sombra la dibuja un div dentro del propio marco, y recortarlo la
 * hace desaparecer. Esos se quedan sin acercamiento, que es mejor que
 * quedarse sin la sombra azul que da caracter a las paginas antiguas.
 */
.ovc-cv__marco,
.ovc-proyecto__imagen,
.ovc-proyecto-single__imagen,
.et_pb_image .et_pb_image_wrap:not(.has-box-shadow-overlay),
.ovc-retrato .et_pb_image_wrap,
.et_pb_gallery_image {
	overflow: hidden;
}

.ovc-cv__marco img,
.ovc-proyecto__imagen img,
.ovc-proyecto-single__imagen img,
.et_pb_image .et_pb_image_wrap:not(.has-box-shadow-overlay) img,
.ovc-retrato .et_pb_image_wrap img,
.et_pb_gallery_image img {
	display: block;
	transition: transform .6s cubic-bezier(.22, .61, .36, 1), filter .6s ease;
	will-change: transform;
}

.ovc-cv__foto:hover .ovc-cv__marco img,
.ovc-proyecto:hover .ovc-proyecto__imagen img,
.ovc-proyecto-single__imagen:hover img,
.et_pb_image:hover .et_pb_image_wrap:not(.has-box-shadow-overlay) img,
.ovc-retrato:hover .et_pb_image_wrap img,
.et_pb_gallery_image:hover img {
	transform: scale(1.06);
}

/*
 * Brillo que cruza la foto al pasar por encima. Se dibuja con un pseudo
 * elemento y no con una imagen, asi que no cuesta ninguna descarga.
 */
.ovc-retrato .et_pb_image_wrap::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .34) 50%, transparent 62%);
	transform: translateX(-120%);
	transition: transform .9s cubic-bezier(.22, .61, .36, 1);
	pointer-events: none;
}

.ovc-retrato:hover .et_pb_image_wrap::after { transform: translateX(120%); }

.ovc-retrato .et_pb_image_wrap { position: relative; }

/* Quien pida menos movimiento no ve ninguno de estos efectos. */
@media (prefers-reduced-motion: reduce) {

	.ovc-cv__marco img,
	.ovc-proyecto__imagen img,
	.ovc-proyecto-single__imagen img,
	.et_pb_image .et_pb_image_wrap img,
	.et_pb_gallery_image img { transition: none; }

	.ovc-cv__foto:hover .ovc-cv__marco img,
	.ovc-proyecto:hover .ovc-proyecto__imagen img,
	.ovc-proyecto-single__imagen:hover img,
	.et_pb_image:hover .et_pb_image_wrap img,
	.et_pb_gallery_image:hover img { transform: none; }

	.ovc-retrato .et_pb_image_wrap::after { display: none; }
}

/* Frase de entrada de «Acerca»: una sola linea, grande, que dice a que se
   dedica uno. Antes el primer parrafo tenia el mismo tamano que los otros
   cuatro y no habia por donde empezar a leer. */
.ovc-lead {
	font-size: clamp(18px, 2vw, 22px) !important;
	font-weight: 600;
	line-height: 1.55 !important;
	color: var(--ovc-grafito);
	text-align: left !important;
	margin-bottom: 20px;
	padding-bottom: 0 !important;
}

/* =========================================================================
   Captcha propio  (includes/captcha.php)

   El de Divi salia como una suma suelta al lado del boton, con los dos
   sumandos escritos en el HTML. Este es un campo con su etiqueta, su marco y
   un boton para pedir otra pregunta, y la respuesta solo la sabe el servidor.
   ====================================================================== */

.ovc-captcha {
	margin: 0 8px 18px;
	padding: 16px 18px;
	background: #f7f9fc;
	border: 1.5px solid var(--ovc-linea);
	border-radius: 12px;
}

.ovc-captcha__etiqueta {
	display: block;
	font-size: 12.5px; font-weight: 700; letter-spacing: 1px;
	text-transform: uppercase; color: #7a8290;
	margin-bottom: 10px;
}

.ovc-captcha__fila {
	display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
}

.ovc-captcha__pregunta {
	font-size: 17px; font-weight: 700; color: var(--ovc-grafito);
	/* Ni se copia ni se arrastra: un poco mas de trabajo para un programa. */
	user-select: none;
}

.ovc-captcha__igual { font-size: 17px; font-weight: 700; color: #7a8290; }

.ovc-captcha__campo {
	width: 66px !important;
	text-align: center;
	padding: 11px 8px !important;
	background: #fff !important;
	border: 1.5px solid var(--ovc-linea) !important;
	border-radius: 10px !important;
	font-size: 16px !important; font-weight: 700 !important;
	color: var(--ovc-grafito) !important;
}

.ovc-captcha__campo:focus {
	outline: none;
	border-color: var(--ovc-azul) !important;
	box-shadow: 0 0 0 4px rgba(70, 31, 239, .12);
}

.ovc-captcha__otra {
	margin-left: auto;
	padding: 8px 15px;
	background: transparent;
	border: 1.5px solid var(--ovc-linea);
	border-radius: 999px;
	font-size: 12.5px; font-weight: 700; letter-spacing: 1px;
	text-transform: uppercase; color: #5c6472;
	cursor: pointer;
	transition: border-color .2s ease, color .2s ease, background .2s ease;
}

.ovc-captcha__otra:hover:not(:disabled) {
	border-color: var(--ovc-azul); color: var(--ovc-azul); background: #fff;
}

.ovc-captcha__otra:disabled { opacity: .5; cursor: default; }

.ovc-captcha__error {
	margin: 0 0 12px; padding: 10px 13px;
	background: #fdecec; border-left: 4px solid #d64545;
	border-radius: 0 8px 8px 0;
	font-size: 14px; color: #8c2d2d;
}

/* El contenedor que recorta la foto del curriculum al acercarse. Hereda las
   esquinas del figure para que el recorte siga su forma. */
.ovc-cv__marco {
	display: block;
	border-radius: inherit;
	overflow: hidden;
}

/* =========================================================================
   El retrato de «Acerca», con el mismo acabado que las demas fotos

   Era la unica foto del sitio que no hablaba el mismo idioma: esquinas
   redondeadas y una sombra gris, mientras las veinte del curriculum y las de
   los proyectos antiguos llevan un bloque de color asomando por detras. Una
   foto distinta a todas no se lee como una decision, se lee como un descuido.

   El bloque va como sombra solida y no como pseudo elemento a proposito: la
   sombra de un elemento NO la recorta su propio overflow, asi que el marco
   puede seguir recortando la imagen cuando se acerca bajo el raton -y el
   brillo que la cruza- sin perder el bloque de color.
   ====================================================================== */

.ovc-retrato .et_pb_image_wrap {
	border: 5px solid #fff;
	border-radius: 16px;
	box-shadow:
		18px 18px 0 0 var(--ovc-azul),
		0 3px 10px rgba(23, 28, 43, .12),
		0 22px 50px rgba(23, 28, 43, .16);
	transition: box-shadow .35s ease, transform .35s ease;
}

/* Al pasar por encima el bloque se acerca a la foto, como si se asentara. */
.ovc-retrato:hover .et_pb_image_wrap {
	box-shadow:
		10px 10px 0 0 var(--ovc-violeta),
		0 4px 14px rgba(23, 28, 43, .14),
		0 28px 60px rgba(23, 28, 43, .2);
	transform: translate(3px, 3px);
}

.ovc-retrato .et_pb_image_wrap img { border-radius: 11px; }

@media (max-width: 780px) {

	.ovc-retrato .et_pb_image_wrap {
		box-shadow:
			12px 12px 0 0 var(--ovc-azul),
			0 3px 10px rgba(23, 28, 43, .12),
			0 18px 40px rgba(23, 28, 43, .16);
	}
}

/* =========================================================================
   Contacto: correcciones

   El correo se partia en dos lineas -"...gmail.co" / "m"- porque la columna
   izquierda es estrecha y la direccion es larga. Se pinta un punto mas
   pequeno y se le permite encoger: es preferible leerlo entero en un tamano
   algo menor que verlo roto por la mitad.
   ====================================================================== */

.ovc-vcard--largo .ovc-vcard__valor {
	font-size: clamp(12.5px, 1.15vw, 16px);
	letter-spacing: -.1px;
	/* Si aun asi no cabe, que corte por donde sea antes que desbordar. */
	overflow-wrap: anywhere;
	word-break: normal;
}

/* El resto de valores no se parten nunca por la mitad de una palabra. */
.ovc-vcard__valor { word-break: normal; overflow-wrap: normal; }

/* --- El boton de copiar -------------------------------------------- */

button.ovc-vcard__segundo {
	background: transparent;
	border: 0;
	border-bottom: 1.5px solid rgba(70, 31, 239, .3);
	cursor: pointer;
	font-family: inherit;
	padding: 0 0 1px;
}

button.ovc-vcard__segundo.is-hecho {
	color: #1f8a4c !important;
	border-color: #1f8a4c;
}

/* =========================================================================
   Cabecera en movil y tableta: el logotipo en blanco

   Por debajo de 980 px la cabecera pasa a azul solido -asi la dejo configurada
   Divi- pero el logotipo seguia siendo la version oscura, que sobre azul no se
   lee. El sitio ya tiene la version en blanco preparada, asi que se cambia la
   imagen en ese tramo en vez de inventar un filtro de color: el archivo blanco
   esta dibujado para eso y conserva el detalle del icono.

   La ruta es relativa a esta hoja: asi sigue valiendo en local y en el
   servidor, sin depender del dominio.
   ====================================================================== */

@media (max-width: 980px) {

	#logo {
		content: url('../../uploads/2026/09/logo-gn-icono-blanco.png');
	}

	/* Las rayas del menu, tambien en blanco. */
	#main-header .mobile_menu_bar:before,
	#main-header .et_toggle_slide_menu:before { color: #fff !important; }
}

/* =========================================================================
   Capturas de aplicacion en las tarjetas

   Una captura de pantalla es alta y estrecha; la tarjeta del portafolio es
   apaisada. Recortandola por el centro -que es lo que hace object-fit: cover-
   se pierden la cabecera y el pie, que es donde se entiende de que va la
   pantalla. Estas se muestran enteras sobre un fondo suave.
   ====================================================================== */

/* En la tarjeta, encuadrada por arriba: asi se ve la cabecera de la pantalla
   y el arranque del contenido, que es donde se reconoce la aplicacion. Con
   «contain» la captura se encogia a una tira estrecha entre dos margenes. */
.ovc-proyecto__imagen img.ovc-animada {
	object-fit: cover;
	object-position: center top;
	background: #eef2f7;
}

/* En la ficha, entera y sin recortar. */
.ovc-proyecto-single__imagen img.ovc-animada {
	object-fit: contain;
	background: #eef2f7;
}

/* No se acercan bajo el raton: una imagen en movimiento que ademas crece
   marea, y al estar en «contain» el acercamiento la sacaria del marco. */
.ovc-proyecto:hover .ovc-proyecto__imagen img.ovc-animada,
.ovc-proyecto-single__imagen:hover img.ovc-animada {
	transform: none;
}

/* En la ficha del proyecto se ve entera y centrada, sin recorte. */
.ovc-proyecto-single__imagen img.ovc-animada {
	max-height: 720px;
	width: auto;
	margin: 0 auto;
}

/* =========================================================================
   Menu lateral

   Divi abre el panel encima de la pagina y no hace nada mas: el contenido
   sigue a la vista por debajo, medio tapado, y se puede seguir desplazando
   detras. Aqui se le pone el velo, el tamano y el acabado que se esperan de
   un panel lateral.
   ====================================================================== */

.ovc-velo {
	position: fixed;
	inset: 0;
	background: rgba(12, 16, 28, .55);
	backdrop-filter: blur(3px);
	-webkit-backdrop-filter: blur(3px);
	opacity: 0;
	visibility: hidden;
	transition: opacity .45s ease, visibility .45s ease;
	/* Justo por debajo del panel (999999) y por encima de todo lo demas. */
	z-index: 999998;
	cursor: pointer;
}

.ovc-velo.is-visible { opacity: 1; visibility: visible; }

/* --- El panel ------------------------------------------------------- */

.et_header_style_slide .et_slide_in_menu_container {
	width: 340px !important;
	max-width: 86% !important;
	background: linear-gradient(160deg, var(--ovc-azul) 0%, var(--ovc-violeta) 100%) !important;
	box-shadow: -18px 0 60px rgba(12, 16, 28, .35);
}

/* La franja de las redes, arriba. */
.et_slide_menu_top {
	background: rgba(0, 0, 0, .16) !important;
	padding: 26px 32px !important;
}

.et_slide_menu_top ul.et-social-icons { float: none !important; display: flex; gap: 18px; }
.et_slide_menu_top ul.et-social-icons li { margin: 0 !important; }
.et_slide_menu_top ul.et-social-icons a { color: rgba(255, 255, 255, .85); transition: color .2s ease; }
.et_slide_menu_top ul.et-social-icons a:hover { color: #fff; }

/* --- Los enlaces ---------------------------------------------------- */

.et_slide_in_menu_container #mobile_menu_slide { padding: 14px 0 40px !important; }

.et_slide_in_menu_container .et_mobile_menu li a {
	display: block;
	padding: 15px 32px !important;
	font-size: 15px !important;
	font-weight: 700 !important;
	letter-spacing: 1.6px;
	text-transform: uppercase;
	color: rgba(255, 255, 255, .88) !important;
	border-bottom: 0 !important;
	/* La barrita que aparece a la izquierda al pasar por encima. */
	border-left: 3px solid transparent;
	transition: color .2s ease, background .2s ease, border-color .2s ease, padding-left .2s ease;
}

.et_slide_in_menu_container .et_mobile_menu li a:hover {
	color: #fff !important;
	background: rgba(255, 255, 255, .1);
	border-left-color: #fff;
	padding-left: 38px !important;
}

/* La pagina en la que se esta, marcada. */
.et_slide_in_menu_container .et_mobile_menu li.current-menu-item > a,
.et_slide_in_menu_container .et_mobile_menu li.current_page_item > a {
	color: #fff !important;
	background: rgba(255, 255, 255, .14);
	border-left-color: #fff;
}

/* --- El aspa de cerrar ---------------------------------------------- */

.et_pb_slide_menu_active .et_toggle_slide_menu:after {
	color: #fff !important;
	text-shadow: 0 2px 10px rgba(12, 16, 28, .5);
}

@media (max-width: 480px) {
	.et_slide_in_menu_container .et_mobile_menu li a { padding: 14px 24px !important; font-size: 14.5px !important; }
	.et_slide_menu_top { padding: 22px 24px !important; }
}

/* Quien pida menos movimiento: el velo aparece sin desvanecido. */
@media (prefers-reduced-motion: reduce) {
	.ovc-velo { transition: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* =========================================================================
   Dos remates del menu lateral
   ====================================================================== */

/*
 * El aspa de cerrar por encima del velo.
 *
 * El velo cubre toda la pantalla, cabecera incluida, asi que el boton de
 * cerrar quedaba por debajo y se veia apagado. Se levanta solo el boton, no
 * la cabecera entera: si se levantara todo, el logotipo quedaria a plena luz
 * sobre la pagina oscurecida y el velo perderia su razon de ser.
 */
.et_pb_slide_menu_active .et_toggle_slide_menu {
	position: relative;
	z-index: 1000000;
}

.et_pb_slide_menu_active .et_toggle_slide_menu:after {
	color: #fff !important;
	text-shadow: 0 2px 12px rgba(12, 16, 28, .6);
}

/*
 * Icono de WhatsApp.
 *
 * Divi no trae ninguno: su clase et-pb-social-fa-icon cuenta con FontAwesome,
 * que en este sitio no se carga. El resultado era un hueco donde deberia estar
 * el icono. Se dibuja con un SVG incrustado y se pinta con mask, de modo que
 * toma el color del texto: blanco en el menu, y el que toque en el pie.
 */
.et-social-whatsapp a.icon:before {
	content: '';
	display: inline-block;
	width: 1em;
	height: 1em;
	vertical-align: -.12em;
	background-color: currentColor;
	-webkit-mask: var(--ovc-icono-whatsapp) center / contain no-repeat;
	mask: var(--ovc-icono-whatsapp) center / contain no-repeat;
}

:root {
	--ovc-icono-whatsapp: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M17.47 14.38c-.3-.15-1.76-.87-2.03-.97-.27-.1-.47-.15-.67.15-.2.3-.77.96-.94 1.16-.17.2-.35.22-.64.08-.3-.15-1.25-.46-2.38-1.47-.88-.79-1.48-1.75-1.65-2.05-.17-.3-.02-.46.13-.6.13-.13.3-.35.44-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.02-.52-.08-.15-.67-1.61-.92-2.2-.24-.58-.48-.5-.67-.51h-.57c-.2 0-.52.07-.79.37-.27.3-1.04 1.01-1.04 2.47s1.06 2.87 1.21 3.07c.15.2 2.1 3.2 5.08 4.49.71.3 1.26.49 1.69.63.71.22 1.36.19 1.87.12.57-.09 1.76-.72 2.01-1.41.25-.7.25-1.29.17-1.42-.07-.12-.27-.2-.57-.35z'/%3E%3Cpath fill='black' d='M12.04 2C6.58 2 2.13 6.45 2.13 11.91c0 1.75.46 3.45 1.32 4.95L2 22l5.25-1.38a9.86 9.86 0 0 0 4.79 1.22h.01c5.46 0 9.91-4.45 9.91-9.91 0-2.65-1.03-5.14-2.9-7.01A9.82 9.82 0 0 0 12.04 2zm0 18.15h-.01a8.2 8.2 0 0 1-4.19-1.15l-.3-.18-3.12.82.83-3.04-.2-.31a8.18 8.18 0 0 1-1.25-4.38c0-4.54 3.7-8.24 8.25-8.24 2.2 0 4.27.86 5.83 2.42a8.19 8.19 0 0 1 2.41 5.83c0 4.54-3.7 8.23-8.25 8.23z'/%3E%3C/svg%3E");
}

/* El boton de cerrar dentro del panel. */
.ovc-menu-cerrar {
	position: absolute;
	top: 20px;
	right: 22px;
	width: 38px;
	height: 38px;
	padding: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(255, 255, 255, .12);
	border: 0;
	border-radius: 50%;
	color: #fff;
	cursor: pointer;
	transition: background .2s ease, transform .2s ease;
}

.ovc-menu-cerrar:hover { background: rgba(255, 255, 255, .24); transform: rotate(90deg); }
.ovc-menu-cerrar svg { width: 19px; height: 19px; display: block; }

/* La franja de arriba pasa a ser el ancla del boton. */
.et_slide_menu_top { position: relative; }

/* El aspa de Divi sobra: queda tapada por el panel segun el ancho. */
.et_pb_slide_menu_active .et_toggle_slide_menu:after { opacity: 0 !important; }

/* =========================================================================
   Menu horizontal de la cabecera

   Sustituye al panel lateral. Las cinco secciones estan siempre a la vista en
   el ordenador, y en el movil se despliegan a todo el ancho por debajo de la
   cabecera, completas y sin recortes.
   ====================================================================== */

/* --- Escritorio ----------------------------------------------------- */

#top-menu li a {
	font-size: 13px !important;
	font-weight: 700 !important;
	letter-spacing: 1.4px;
	text-transform: uppercase;
	color: var(--ovc-grafito) !important;
	opacity: 1 !important;
	padding-bottom: 20px !important;
	position: relative;
	transition: color .2s ease;
}

#top-menu li a:hover { color: var(--ovc-azul) !important; opacity: 1 !important; }

/* La raya que marca la seccion en la que se esta y la que se sobrevuela. */
#top-menu li a:after {
	content: '';
	position: absolute;
	left: 0; right: 0; bottom: 12px;
	height: 2px;
	background: var(--ovc-azul);
	transform: scaleX(0);
	transform-origin: center;
	transition: transform .25s ease;
}

#top-menu li a:hover:after { transform: scaleX(1); }

#top-menu li.current-menu-item > a,
#top-menu li.current_page_item > a { color: var(--ovc-azul) !important; }

#top-menu li.current-menu-item > a:after,
#top-menu li.current_page_item > a:after { transform: scaleX(1); }

/* --- La franja superior con las redes -------------------------------- */

#top-header {
	background: linear-gradient(90deg, var(--ovc-azul), var(--ovc-violeta)) !important;
}

#top-header .et-social-icons { float: right; }
#top-header .et-social-icon a { color: rgba(255, 255, 255, .8); transition: color .2s ease; }
#top-header .et-social-icon a:hover { color: #fff; }

/* --- Movil: el desplegable, a todo el ancho -------------------------- */

@media (max-width: 980px) {

	/*
	 * Divi lo encierra dentro del contenedor central, asi que queda flotando
	 * con margenes a los lados. A pantalla completa se lee como parte de la
	 * cabecera y no como una caja suelta encima de la pagina.
	 */
	#main-header .et_mobile_menu {
		position: absolute;
		left: 50%;
		width: 100vw;
		margin-left: -50vw;
		padding: 8px 0 14px !important;
		border-top: 0 !important;
		background: linear-gradient(160deg, var(--ovc-azul) 0%, var(--ovc-violeta) 100%) !important;
		box-shadow: 0 22px 44px rgba(12, 16, 28, .28);
	}

	#main-header .et_mobile_menu li a {
		display: block;
		padding: 15px 8% !important;
		font-size: 14.5px !important;
		font-weight: 700 !important;
		letter-spacing: 1.4px;
		text-transform: uppercase;
		color: rgba(255, 255, 255, .9) !important;
		border-bottom: 0 !important;
		border-left: 3px solid transparent;
		transition: background .2s ease, color .2s ease, border-color .2s ease;
	}

	#main-header .et_mobile_menu li a:hover {
		background: rgba(255, 255, 255, .12);
		color: #fff !important;
		border-left-color: #fff;
	}

	#main-header .et_mobile_menu li.current-menu-item > a,
	#main-header .et_mobile_menu li.current_page_item > a {
		background: rgba(255, 255, 255, .16);
		color: #fff !important;
		border-left-color: #fff;
	}

	/* Las rayas del boton, en blanco sobre la cabecera azul. */
	#main-header .mobile_menu_bar:before { color: #fff !important; }
}

/* =========================================================================
   La cabecera, apilada en flujo normal

   Divi coloca #top-header y #main-header en posicion absoluta y separa el
   segundo con un «top: 33px» fijo, que es la altura que SUPONE para la franja
   superior. Basta con que esa franja crezca un poco -otro tamano de fuente,
   el zoom del navegador, un icono mas alto- para que la cabecera se le monte
   encima y corte el logotipo y el menu por la mitad.

   Apilandolos en flujo normal, cada uno ocupa lo que mide y el siguiente
   empieza donde acaba el anterior. No hay ninguna medida que mantener a mano
   y el problema no puede volver.
   ====================================================================== */

#top-header,
#main-header {
	position: relative !important;
	top: auto !important;
}

/* Sin la cabecera flotando encima, el contenido ya no necesita hueco. */
#page-container { padding-top: 0 !important; }

/* La franja superior: alto propio, sin depender de lo que suponga Divi. */
#top-header {
	padding: 7px 0;
	font-size: 13px;
	line-height: 1.4;
}

#top-header .container { padding-top: 0 !important; padding-bottom: 0 !important; }
