/* Deltas de CSS que necesitan los patrones de bloques.
   No modifica profiles.css: solo añade lo que el marcado de Gutenberg requiere. */

/* Numeración de secciones. Sustituye al <span>01</span> que escribía PHP.
   Guarda de convivencia retirada en el cutover de perfiles: la plantilla PHP
   legada ya no existe, así que no puede haber doble numeración.
   Al ser un contador CSS los números se recalculan solos si el usuario
   reordena, duplica o elimina secciones desde el editor. */
.profile-page,
.profile-blocks {
	counter-reset: pp-section;
}

.profile-section-marker::before {
	counter-increment: pp-section;
	content: counter(pp-section, decimal-leading-zero) / "";
	margin-right: .9rem;
	color: var(--wp--preset--color--primary, #f16824);
	font-family: var(--wp--preset--font-family--mono, monospace);
}

/* El ' / ""' es el texto alternativo de content: deja el número visible pero
   silencioso para lectores de pantalla. Es numeración decorativa, y el h3
   siguiente ya dice lo que importa. */

/* Numeración de especialidades. Misma lógica que arriba. */
.profile-specialties {
	counter-reset: pp-specialty;
}

.profile-specialty::before {
	counter-increment: pp-specialty;
	content: counter(pp-specialty, decimal-leading-zero) / "";
	color: #ad4e1e;
	font: .6rem/1.5 var(--wp--preset--font-family--mono, monospace);
}

/* ─────────────────────────────────────────────────────────────────────────
   HERO DE PERFIL
   ───────────────────────────────────────────────────────────────────────── */

/* La señal decorativa. En el PHP era
   <div class="profile-signal"><span></span><i></i><i></i><i></i></div>:
   un div vacío con cuatro hijos también vacíos. Como bloque es un
   wp:separator, que es lo que realmente es —una línea horizontal— y además
   se ve y se entiende en el editor.

   Los pseudo-elementos van acotados a hr. Ya no hace falta como guarda de
   convivencia —el marcado legado se retiró en el cutover— pero se conserva:
   el bloque ES un wp:separator, así que el prefijo describe la realidad y
   protege si alguien cambia el separador por otro bloque.

   El <hr> aporta la línea (ya la pinta .profile-signal), ::before el punto
   y ::after los tres cuadrados como capas de background. Se comprobó que
   ninguna de las cinco marcas declara animation ni transition, así que las
   capas son equivalentes a los elementos que sustituyen. */
hr.profile-signal {
	border: 0;
	margin: 0;
	padding: 0;
}

/* El punto. Copia literal de la regla .profile-signal span, box-shadow incluido. */
hr.profile-signal::before {
	content: "";
	position: absolute;
	right: 12%;
	top: -4px;
	width: 9px;
	height: 9px;
	background: var(--orange);
	border-radius: 50%;
	box-shadow: 0 0 18px rgba(241, 104, 36, .65);
}

/* Los tres cuadrados. El SVG lleva fill="none", así que el interior es
   transparente de verdad y deja ver el degradado del hero por debajo.

   Sobre las posiciones: background-position alinea el p% de la imagen con
   el p% de la caja, mientras que left:p% no descuenta el ancho del elemento.
   La diferencia es exactamente p × 7px, constante e independiente del ancho
   del contenedor, así que se compensa sumándola. */
hr.profile-signal::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: -3px;
	height: 7px;
	background-repeat: no-repeat;
	background-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='7'%3E%3Crect x='.5' y='.5' width='6' height='6' fill='none' stroke='%23f16824'/%3E%3C/svg%3E"),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='7'%3E%3Crect x='.5' y='.5' width='6' height='6' fill='none' stroke='%23f16824'/%3E%3C/svg%3E"),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='7'%3E%3Crect x='.5' y='.5' width='6' height='6' fill='none' stroke='%23f16824'/%3E%3C/svg%3E");
	background-position:
		calc(17% + 1.19px) 0,
		calc(58% + 4.06px) 0,
		calc(86% + 6.02px) 0;
}

/* El PHP apagaba el resplandor del punto en movimiento reducido
   (.profile-signal span{box-shadow:none}). Mismo trato al pseudo-elemento. */
@media (prefers-reduced-motion: reduce) {
	hr.profile-signal::before {
		box-shadow: none;
	}
}

/* El enlace del hero era hijo directo de .profile-hero-copy. Como bloque va
   dentro de un wp:paragraph, que aporta el margen 1em del navegador. Se anula
   desde una clase explícita en el propio párrafo, no desde un selector
   estructural. */
.profile-text-link-row {
	margin: 0;
}

/* Márgenes que trae el bloque de imagen de core y que el marcado original
   no tenía, porque eran <div> y <figure> escritos a mano.

   El pie: .wp-block-image :where(figcaption){margin-bottom:1em;margin-top:.5em}.
   Aunque está posicionado en absoluto el margen sí desplaza la caja: a
   font-size .58rem, 1em son 9.28px, justo lo que subía.

   La figura del proyecto: 1em al pie de .wp-block-image, es decir 16px de más
   por tarjeta. El retrato del hero no lo sufría porque .profile-portrait ya
   declara margin:0 en el tema; .profile-project-image no tenía equivalente. */
.profile-portrait figcaption {
	margin: 0;
}

.profile-project-image {
	margin: 0;
}


/* ─────────────────────────────────────────────────────────────────────────
   TRABAJO SELECCIONADO
   ───────────────────────────────────────────────────────────────────────── */

/* Numeración de proyectos. Sustituye al <span>01</span> del PHP, con la misma
   lógica que las especialidades: al ser un contador, duplicar o reordenar una
   tarjeta renumera el resto solo. Silencioso para lectores de pantalla. */
.profile-project-grid {
	counter-reset: pp-project;
}

.profile-project-meta::before {
	counter-increment: pp-project;
	content: counter(pp-project, decimal-leading-zero) / "";
	color: var(--wp--preset--color--primary, #f16824);
	font: .62rem/1.5 var(--wp--preset--font-family--mono, monospace);
}

/* ─────────────────────────────────────────────────────────────────────────
   EXPERIENCIA
   ───────────────────────────────────────────────────────────────────────── */

/* Numeración de entradas. Sin este ::before la rejilla de tres columnas
   (48px / título / roles) pierde su primer elemento y todo el contenido se
   recoloca una columna a la izquierda: no es un detalle cosmético.

   Aquí no hace falta guarda :not(:has(> span)) porque la clase
   .profile-experience solo existe en el marcado de bloques; el <article> de
   la plantilla PHP no la lleva, así que no puede haber doble numeración. */
.profile-ledger-list {
	counter-reset: pp-experience;
}

.profile-experience::before {
	counter-increment: pp-experience;
	content: counter(pp-experience, decimal-leading-zero) / "";
	color: #ad4e1e;
	font: .6rem/1.5 var(--wp--preset--font-family--mono, monospace);
}

/* El marcador de sección del ledger. En el PHP era un <div>, así que
   .profile-ledger>div lo alcanzaba y recibía la animación de entrada junto al
   bloque principal. Como bloque es un <p> y deja de coincidir, así que se le
   devuelve la animación desde su propia clase. */
@supports (animation-timeline: view()) {
	.profile-ledger > .profile-section-marker {
		animation: profile-reveal linear both;
		animation-timeline: view();
		animation-range: entry 8% cover 32%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.profile-ledger > .profile-section-marker {
		opacity: 1 !important;
		transform: none !important;
	}
}

/* ─────────────────────────────────────────────────────────────────────────
   MEDIA SERVER ARCHITECT
   ───────────────────────────────────────────────────────────────────────── */

/* `.profile-training > div:last-child > p:not(.profile-eyebrow)` también
   alcanza al párrafo que envuelve el enlace, que en el PHP era un <a> suelto.
   Sin esto el enlace hereda #9b9a94 en vez del blanco del tema.
   Se contrarresta con la misma especificidad (0,3,2); patterns.css carga
   después de profiles.css, así que gana el desempate por orden. */
.profile-training > div:last-child > p.profile-text-link-row {
	color: inherit;
	max-width: none;
	font-size: inherit;
}

/* Igual que en el ledger: `.profile-training > div` alcanzaba al marcador
   cuando era un <div>. Como bloque es un <p> y pierde la animación. */
@supports (animation-timeline: view()) {
	.profile-training > .profile-section-marker {
		animation: profile-reveal linear both;
		animation-timeline: view();
		animation-range: entry 8% cover 32%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.profile-training > .profile-section-marker {
		opacity: 1 !important;
		transform: none !important;
	}
}

/* ─────────────────────────────────────────────────────────────────────────
   CIERRE DE PERFIL
   ───────────────────────────────────────────────────────────────────────── */

/* La rejilla decorativa. En el PHP era <div class="profile-cta-grid"> vacío.
   `.profile-cta` no usa ningún pseudo-elemento, así que ::before queda libre:
   la decoración se dibuja ahí y desaparece el div vacío del marcado.
   Al ir en position:absolute no cuenta como ítem del flex del contenedor.

   Guarda de convivencia retirada en el cutover de perfiles. */
.profile-cta::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image:
		linear-gradient(rgba(255, 255, 255, .04) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255, 255, 255, .04) 1px, transparent 1px);
	background-size: 48px 48px;
	-webkit-mask-image: radial-gradient(circle, #000, transparent 68%);
	mask-image: radial-gradient(circle, #000, transparent 68%);
}

/* `.profile-cta > *` daba la animación de entrada al div de la rejilla.
   Como pseudo-elemento ya no lo alcanza, así que se le declara aquí. */
@supports (animation-timeline: view()) {
	.profile-cta::before {
		animation: profile-reveal linear both;
		animation-timeline: view();
		animation-range: entry 8% cover 32%;
	}
}

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

/* `.profile-cta > p:not(.profile-eyebrow)` alcanza al párrafo que envuelve el
   botón, que en el PHP era un <a> suelto: le metía 2.5rem de margen inferior
   y un ancho máximo que no tenía. Misma especificidad (0,1,2) más la clase. */
.profile-cta > p.profile-cta-action {
	max-width: none;
	margin: 0;
}

/* ═════════════════════════════════════════════════════════════════════════
   PORTADA
   ═════════════════════════════════════════════════════════════════════════ */

/* Numeración de secciones de portada. En el SPA de React el marcador ya es un
   <p class="section-marker"> con un <span>01</span> dentro, así que el cambio
   es el mismo que en los perfiles: el span pasa a contador.

   El reset va en body porque la portada no tiene un envoltorio propio
   equivalente a .profile-page. Ninguna otra parte del sitio usa .section-marker
   (los perfiles usan .profile-section-marker), así que no hay interferencia. */
body {
	counter-reset: pp-home-section;
}

/* Ojo: a diferencia del marcador de los perfiles, `.section-marker span` de
   site.css NO declara monospace — hereda la Arial del cuerpo. Copiar la regla
   de los perfiles metía un desfase de 1px y un cambio de tipografía. */
.section-marker::before {
	counter-increment: pp-home-section;
	content: counter(pp-home-section, decimal-leading-zero) / "";
	margin-right: .9rem;
	color: var(--wp--preset--color--primary, #f16824);
}

/* ── Para quién es ──────────────────────────────────────────────────────── */

/* La columna de valores era <span> + tres <strong> sueltos dentro de un flex.
   Como bloques, cada uno va dentro de su propio <p>, que aporta el margen del
   navegador y desajustaría el gap de 1rem del contenedor. */
.audience-values > p {
	margin: 0;
	/* El <strong> era el ítem del flex y medía 18px de alto (.75rem x 1.5).
	   Envuelto en un <p> que hereda los 16px del cuerpo pasaría a 24px y
	   descuadraría el gap. Se le da el tamaño del <strong> que contiene. */
	font-size: .75rem;
	line-height: 1.5;
}

/* El <span>Built around</span> pasa a ser un párrafo con clase propia, así que
   deja de coincidir con `.audience-values span`. Mismos valores. */
.audience-values .audience-values-label {
	color: var(--faint);
	letter-spacing: .13em;
	text-transform: uppercase;
	font: .62rem/1 monospace;
}


/* ── Cierre y contacto ──────────────────────────────────────────────────── */

/* La rejilla decorativa era <div class="completion-grid"> con cuatro <span>
   dentro. Ambos pseudo-elementos de .completion-scene estaban libres:
   ::before lleva la rejilla y ::after los cuatro puntos.

   Los puntos van como capas de background con un SVG que incluye
   feGaussianBlur: el desenfoque de box-shadow se define como una gaussiana de
   desviación típica blur/2, así que stdDeviation='9' reproduce los 18px del
   original en vez de aproximarlos con un degradado.

   La máscara va en los dos: en el original la mask-image de .completion-grid
   afecta también a los <span> hijos, que se difuminan hacia los bordes. */
.completion-scene::before,
.completion-scene::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	-webkit-mask-image: radial-gradient(circle, #000, transparent 68%);
	mask-image: radial-gradient(circle, #000, transparent 68%);
}

.completion-scene::before {
	background-image:
		linear-gradient(rgba(255, 255, 255, .039) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255, 255, 255, .039) 1px, transparent 1px);
	background-size: 48px 48px;
}

/* El núcleo de 8px está inscrito a 18px del borde del SVG de 44px, y
   background-position mide el porcentaje sobre (contenedor - imagen).
   La compensación es p x 44px - 18px, constante para cada punto. */
.completion-scene::after {
	background-repeat: no-repeat;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='9'/%3E%3C/filter%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824' opacity='.549' filter='url(%23b)'/%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='9'/%3E%3C/filter%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824' opacity='.549' filter='url(%23b)'/%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='9'/%3E%3C/filter%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824' opacity='.549' filter='url(%23b)'/%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='44' height='44'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='9'/%3E%3C/filter%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824' opacity='.549' filter='url(%23b)'/%3E%3Crect x='18' y='18' width='8' height='8' fill='%23f16824'/%3E%3C/svg%3E");
	background-position:
		left calc(12% - 12.72px) top calc(25% - 7px),
		right calc(17% - 10.52px) top calc(34% - 3.04px),
		left calc(27% - 6.12px) bottom calc(21% - 8.76px),
		right calc(8% - 14.48px) bottom calc(15% - 11.4px);
}

/* El punto de la línea de estado, que era <span></span> dentro del <p>. */
.completion-status::before {
	content: "";
	background: var(--orange);
	border-radius: 50%;
	width: 7px;
	height: 7px;
	flex: 0 0 auto;
	box-shadow: 0 0 0 4px rgba(241, 104, 36, .102);
}

/* Igual que en .profile-cta: el <a> del botón era hijo directo y ahora va
   dentro de un <p>, que sí recoge la regla de los párrafos. */
.completion-copy > p.completion-action {
	max-width: none;
	margin: 0;
}

/* ── Entornos de producción ─────────────────────────────────────────────── */

/* `.stage-window` era un <div> con un <img class="environment-photo"> dentro.
   Como bloque es el <figure> de wp:image, y la clase del bloque va al <figure>,
   no al <img>. Las reglas de .environment-photo se replican apuntando al <img>
   descendiente, que es estable frente a los reguardados del editor. */
.stage-window {
	margin: 0;
}

.stage-window img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: brightness(.82) saturate(.88) contrast(1.06);
	transition: transform .7s cubic-bezier(.2, .7, .2, 1), filter .45s;
}

.frame-1 .stage-window img { object-position: center 56%; }
.frame-2 .stage-window img { object-position: center 52%; }
.frame-3 .stage-window img { object-position: center 48%; }
.frame-4 .stage-window img { object-position: center 52%; }

@media (hover: hover) and (pointer: fine) {
	.environment-frame:hover .stage-window img {
		filter: brightness(.94) saturate(.94) contrast(1.04);
		transform: scale(1.025);
	}
}

/* La barra naranja inferior era <span class="environment-marker">. El ::after
   de .stage-window ya lo usa el degradado del tema, pero ::before está libre. */
.stage-window::before {
	content: "";
	position: absolute;
	z-index: 2;
	bottom: 0;
	left: 0;
	width: 34%;
	height: 2px;
	background: linear-gradient(90deg, var(--orange), rgba(241, 104, 36, 0));
}

/* Numeración de los pies. Sustituye a `.environment-caption > span`. */
.environment-reel {
	counter-reset: pp-frame;
}

.environment-caption::before {
	counter-increment: pp-frame;
	content: counter(pp-frame, decimal-leading-zero) / "";
	color: var(--orange);
	font: .62rem/1 monospace;
}

/* ── La cadena de señal ─────────────────────────────────────────────────── */

/* La espina vertical era <div class="chain-spine"><span></span></div>: una
   línea de 1px en var(--line) con un span naranja encima a height:100%, que la
   tapa por completo. El resultado visible es la línea naranja. */
.signal-chain::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 24%;
	width: 1px;
	background: var(--orange);
}

/* Numeración de los pasos. En el original el número iba concatenado dentro del
   propio texto de .step-label ("01 / Input"). Separarlo en un contador permite
   reordenar o duplicar un paso sin renumerar a mano.
   Aquí NO se silencia con / "": en el original el número forma parte del texto
   de la etiqueta y sí se anuncia. */
.signal-chain {
	counter-reset: pp-step;
}

.step-label-auto::before {
	counter-increment: pp-step;
	content: counter(pp-step, decimal-leading-zero) " / ";
}

/* El nodo llevaba <span> con el código y un <i> con el punto. El código es
   contenido (IN, MS, PX…), así que sigue siendo un bloque editable; el punto
   es decoración y pasa a ::before. */
.step-node .step-node-code {
	display: grid;
	place-items: center;
	width: 72px;
	height: 72px;
	margin: 0;
	background: var(--ink);
	border: 1px solid #3c3c39;
	color: var(--orange);
	letter-spacing: .15em;
	font: .7rem/1 monospace;
}

.step-node::before {
	content: "";
	position: absolute;
	left: calc(100% - 4px);
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--orange);
	box-shadow: 0 0 0 6px var(--ink), 0 0 18px rgba(241, 104, 36, .5);
}

/* Las tres barras de .step-geometry eran <span> de alturas 25/68/42 %.
   Un ::before del propio paso las dibuja como tres capas de fondo y además
   ocupa la celda 1/3 de la rejilla, que es donde estaba el div original. */
.system-step::before {
	content: "";
	/* El div original se estiraba en la celda (410px) y se centraba
	   verticalmente por el align-items:center del paso; solo las barras
	   ocupaban 65px desde la izquierda. Se reproduce igual: caja completa,
	   barras colocadas por background-position. */
	grid-area: 1 / 3;
	height: 70px;
	background-repeat: no-repeat;
	background-image:
		linear-gradient(#343431, #343431),
		linear-gradient(var(--orange), var(--orange)),
		linear-gradient(#343431, #343431);
	background-size: 20px 25%, 20px 68%, 20px 42%;
	background-position: left bottom, 25px bottom, 50px bottom;
}

/* `.system-step > :not(.step-node)` daba la animación de entrada a la
   geometría. Como pseudo-elemento ya no la alcanza. */
@supports (animation-timeline: view()) {
	.system-step::before {
		animation: reveal-up linear both;
		animation-timeline: view();
		animation-range: entry 8% cover 28%;
	}
}

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

/* Los overrides móviles del tema apuntan a `.chain-spine`, `.step-node span`,
   `.step-node i` y `.step-geometry`, que en el marcado de bloques ya no
   existen. Se replican sobre sus sustitutos. */
@media (width <= 900px) {
	.signal-chain::before {
		left: 1rem;
	}

	.step-node .step-node-code {
		width: 36px;
		height: 36px;
		font-size: .5rem;
	}

	.step-node::before {
		display: none;
	}

	/* En el original .step-geometry era el ÚLTIMO hijo, así que con
	   grid-area:auto caía en la última fila. Un ::before va primero en el
	   flujo, así que aquí hay que darle la fila explícitamente: quedan
	   etiqueta (1), h3 (2), copy (3) y geometría (4). */
	.system-step::before {
		grid-area: 4 / 1;
		height: 45px;
	}
}

@media (width <= 560px) {
	.signal-chain::before {
		left: .5rem;
	}
}

/* ── El equipo ──────────────────────────────────────────────────────────── */

/* En el SPA cada persona es un <a class="team-person"> que envuelve la tarjeta
   entera. Ningún bloque nativo produce eso, así que la tarjeta pasa a ser un
   <div> y el enlace vive dentro del <h3>, con texto real —el nombre— y su
   ::after estirado sobre toda la tarjeta.

   Frente a una capa superpuesta aparte: el enlace tiene nombre accesible
   propio (se anuncia «Bryan, enlace»), el foco de teclado funciona sin
   tabindex, y todo el contenido sigue siendo bloques editables.

   Contrapartida conocida: no se puede seleccionar texto sobre la tarjeta.
   Es el precio de cualquier tarjeta enteramente clicable.

   Todo va prefijado con div. para no tocar el marcado legado, donde
   .team-person es un <a>. */
div.team-person {
	position: relative;
}

div.team-person h3 a::after {
	content: "";
	position: absolute;
	inset: 0;
}

/* .person-signal era <span><i></i>01</span>, decorativo y aria-hidden.
   Pasa entero a ::before: el punto como degradado radial a la izquierda y el
   número como contador, para que reordenar tarjetas renumere solo. */
.team-line {
	counter-reset: pp-person;
}

div.team-person::before {
	counter-increment: pp-person;
	content: counter(pp-person, decimal-leading-zero);
	padding-left: calc(7px + .7rem);
	background: radial-gradient(circle at 3.5px 50%, var(--orange) 3.5px, transparent 3.5px) no-repeat;
	color: #a94b1c;
	font: .62rem/1 monospace;
	transition: color .25s;
}

/* La flecha, que era <span aria-hidden="true">↗</span> como último hijo. */
div.team-person::after {
	content: "↗";
	justify-self: end;
	font-size: 1.2rem;
}

/* Las iniciales sí son contenido, así que siguen siendo un bloque editable.
   Como <p>, `.team-person p` (0,1,1) las captura y gana a `.person-initials`
   (0,1,0): quedaban a 12.48px en vez de 115.2px. En el original eran un <span>
   y esa regla no las alcanzaba. Se repite la declaración con especificidad
   suficiente (0,2,1), más el margin que un <p> sí trae. */
div.team-person .person-initials {
	margin: 0;
	align-self: center;
	color: #c8c5be;
	font-size: clamp(5rem, 8vw, 9rem);
	font-weight: 700;
	line-height: .8;
	letter-spacing: -.08em;
	transition: color .25s;
}

/* Los estados. El original los colgaba de :focus-visible sobre el propio <a>;
   ahora el foco lo recibe el enlace interno, así que se usa :focus-within.
   El hover no cambia: apuntaba ya a .team-person y sigue apuntando ahí. */
div.team-person:focus-within {
	color: var(--white);
	background: #111;
}

div.team-person:focus-within p,
div.team-person:focus-within .person-initials {
	color: #e4e1da;
}

div.team-person:focus-within::before,
div.team-person:hover::before {
	color: #e4e1da;
}

div.team-person:focus-within h3 a:focus-visible::after {
	outline: 2px solid var(--orange);
	outline-offset: -4px;
}

/* Cuarta categoría de rotura otra vez: el override móvil del tema
   (`@media (width<=900px){.person-initials{font-size:6rem}}`) tiene menos
   especificidad que la contra-regla de arriba y perdía. Se repite aquí. */
@media (width <= 900px) {
	div.team-person .person-initials {
		font-size: 6rem;
	}
}


/* ── Media Server Architect (portada) ───────────────────────────────────── */

/* El panel de esquema llevaba tres <span> de ruta y tres <i> de puerto, todos
   decorativos. El ::after de .training-blueprint ya lo usa el marco interior
   del tema, así que las seis marcas van en ::before como capas de fondo:
   las rutas son líneas sólidas (linear-gradient) y los puertos usan el mismo
   SVG con feGaussianBlur que los puntos del cierre (box-shadow 15px =
   gaussiana de desviación 7.5). */
.training-blueprint::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	background-repeat: no-repeat;
	background-image:
		linear-gradient(var(--orange), var(--orange)),
		linear-gradient(var(--orange), var(--orange)),
		linear-gradient(var(--orange), var(--orange)),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='7.5'/%3E%3C/filter%3E%3Ccircle cx='19' cy='19' r='4' fill='%23f16824' opacity='.6' filter='url(%23b)'/%3E%3Ccircle cx='19' cy='19' r='4' fill='%23f16824'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='7.5'/%3E%3C/filter%3E%3Ccircle cx='19' cy='19' r='4' fill='%23f16824' opacity='.6' filter='url(%23b)'/%3E%3Ccircle cx='19' cy='19' r='4' fill='%23f16824'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38'%3E%3Cfilter id='b' x='-50%25' y='-50%25' width='200%25' height='200%25'%3E%3CfeGaussianBlur stdDeviation='7.5'/%3E%3C/filter%3E%3Ccircle cx='19' cy='19' r='4' fill='%23f16824' opacity='.6' filter='url(%23b)'/%3E%3Ccircle cx='19' cy='19' r='4' fill='%23f16824'/%3E%3C/svg%3E");
	background-size: 31% 1px, 30% 1px, 1px 80%, 38px 38px, 38px 38px, 38px 38px;
	/* Dos fórmulas distintas de compensación, porque background-position mide
	   el porcentaje sobre (contenedor - imagen):
	     · capa de tamaño porcentual s, posición deseada d  ->  p = d / (100 - s)
	     · capa de tamaño fijo iw, posición deseada d%      ->  calc(d% + d*iw)
	   Los puertos llevan además -15px, que es lo que el núcleo de 8px está
	   inscrito dentro del SVG de 38px. */
	background-position:
		left 13.0435%          top calc(49% + .49px),
		left 87.142857%        top calc(49% + .49px),
		left calc(50% + .5px)  top 40%,
		left calc(8% - 11.96px)   top calc(49% - .38px),
		right calc(8% - 11.96px)  top calc(49% - .38px),
		left 50%                  bottom calc(11% - 10.82px);
}

/* El núcleo: <div><span>MSA</span><i></i></div>. El texto es contenido, así
   que sigue siendo bloque; el marco interior pasa a ::before. */
.training-blueprint .blueprint-core {
	margin: 0;
}

.blueprint-core::before {
	content: "";
	position: absolute;
	inset: 14%;
	border: 1px solid #444;
}

/* `.training-lead > p:last-of-type` apuntaba al párrafo descriptivo, porque el
   enlace era un <a> suelto y no contaba como <p>. Al envolverlo, :last-of-type
   se desplaza al párrafo del enlace y el descriptivo pierde sus estilos.
   Se resuelve con clases explícitas en los dos. */
.training-lead > p.training-lead-copy {
	margin: 0;
	max-width: 680px;
	color: #50504c;
	font-size: clamp(1rem, 1.25vw, 1.2rem);
}

.training-lead > p.text-link-row {
	margin: 0;
	max-width: none;
	color: inherit;
	font-size: inherit;
}

/* El currículo. wp:list produce <ol class="wp-block-list"> con <li>, que es lo
   que el tema espera. El <span> del número pasa a contador y el <i> de la
   línea con punto a ::after, con las dos marcas como capas de fondo. */
.curriculum ol {
	counter-reset: pp-curriculum;
}

.curriculum li::before {
	counter-increment: pp-curriculum;
	content: counter(pp-curriculum, decimal-leading-zero);
	color: #ad4e1e;
	font: .62rem/1 monospace;
}

.curriculum li::after {
	content: "";
	align-self: center;
	height: 7px;
	background-repeat: no-repeat;
	background-image:
		linear-gradient(#aaa7a0, #aaa7a0),
		radial-gradient(circle at 3.5px 3.5px, var(--orange) 3.5px, transparent 3.5px);
	background-size: 100% 1px, 7px 7px;
	background-position: left center, right center;
}

/* ── Hero de portada ────────────────────────────────────────────────────── */

/* El punto del kicker era <span></span> dentro del párrafo. Comparte
   declaración con .completion-status span, que ya se sustituyó igual. */
.hero-kicker::before {
	content: "";
	background: var(--orange);
	border-radius: 50%;
	width: 7px;
	height: 7px;
	flex: 0 0 auto;
	box-shadow: 0 0 0 4px rgba(241, 104, 36, .102);
}

/* Los dos botones eran <a> hijos directos del flex. Como bloques van dentro
   de un <p>, que aporta el margen del navegador. */
.hero-actions > p {
	margin: 0;
}

/* Las dos líneas de la telemetría eran <i> que crecían para rellenar. Como
   bloque son wp:separator, igual que la señal del hero de perfil: es lo que
   realmente son y se ven en el editor. */
.hero-telemetry hr.telemetry-rule {
	flex: 1;
	height: 1px;
	border: 0;
	margin: 0;
	padding: 0;
	background: var(--line);
}

/* Los tres textos eran <span> y ahora son <p>. */
.hero-telemetry > p {
	margin: 0;
}
