/*
 * components.css — Tarjetas, formularios y componentes reutilizables
 * Depende de layout.css
 */

/* ── Clases utilitarias del editor ────────────────────────────────────────
   Se usan escribiéndolas en el campo "Clase CSS adicional" (panel Avanzado)
   de cualquier bloque en Gutenberg. Antes solo existían en editor.css (se
   veían bien al editar) y no tenían equivalente aquí — por eso desaparecían
   al publicar. Usadas ya en el patrón "Hero institucional" (.overline,
   .lead) y en "Sección de cifras" / "Grilla de tarjetas" (.card). */

/* Etiqueta chica sobre un título */
.overline {
    display: block;
    font-size: var(--ipg-text-xs);
    font-weight: var(--ipg-weight-bold);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ipg-color-accent);
    margin-bottom: var(--ipg-space-2);
}

/* Párrafo destacado bajo un título */
.lead {
    font-size: var(--ipg-text-xl);
    line-height: var(--ipg-leading-normal);
    color: var(--ipg-color-text-muted);
}

/* ── Aire del bloque de encabezado (etiqueta → título → bajada) ───────────
   Los tres son hermanos dentro de un grupo "constrained", así que WordPress
   les mete entre medio el blockGap del tema:
       :root :where(.is-layout-constrained) > * { margin-block-start: 24px }
   Veinticuatro píxeles separan bien dos secciones distintas, pero acá
   desarman lo que debería leerse como una sola unidad: la etiqueta quedaba
   flotando despegada de su título, y la bajada a la misma distancia que
   tendría un párrafo cualquiera.

   El prefijo :root sube la especificidad a (0,2,1) para ganarle a esa regla
   —que va en (0,1,0)— sin recurrir a !important.

   IMPORTANTE: un margen puesto desde el editor sigue mandando por encima de
   esto, porque WordPress lo serializa como estilo en línea. Por eso el
   control de Margen (bloque → panel Dimensiones) sirve para apretar o soltar
   una página en particular sin tocar el tema. */
:root .overline { margin-block-end: var(--ipg-space-2); }

:root .overline + h1,
:root .overline + h2,
:root .overline + h3,
:root .overline + .wp-block-heading { margin-block-start: var(--ipg-space-2); }

:root h1 + .lead,
:root h2 + .lead,
:root h3 + .lead,
:root .wp-block-heading + .lead { margin-block-start: var(--ipg-space-3); }

/* Tarjeta con borde y sombra (usada en patrones de columnas/grillas) */
.card {
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius);
    padding: var(--ipg-space-6);
    box-shadow: var(--ipg-shadow-sm);
}

/* Secciones con fondo de color */
.section-primary   { background-color: var(--ipg-color-primary); color: var(--ipg-color-text-inverted); padding: var(--ipg-space-16) var(--ipg-space-8); }
.section-secondary { background-color: var(--ipg-color-secondary); color: var(--ipg-color-text-inverted); padding: var(--ipg-space-16) var(--ipg-space-8); }
.section-light      { background-color: var(--ipg-color-surface); padding: var(--ipg-space-16) var(--ipg-space-8); }
.section-white       { background-color: var(--ipg-color-background); padding: var(--ipg-space-16) var(--ipg-space-8); }

/* Textos de color */
.text-primary   { color: var(--ipg-color-primary); }
.text-secondary { color: var(--ipg-color-secondary); }
.text-accent    { color: var(--ipg-color-accent); }
.text-muted     { color: var(--ipg-color-text-muted); }
.text-white     { color: var(--ipg-color-text-inverted); }
.text-center    { text-align: center; }

/* Tarjeta de noticia — sin borde: sobre el canvas gris de la página, la
   sombra sola ya define el borde de la tarjeta (igual que en la maqueta). */
.news-card {
    background: var(--ipg-color-background);
    border-radius: var(--ipg-radius-lg);
    overflow: hidden;
    box-shadow: var(--ipg-shadow-sm);
    transition: box-shadow var(--ipg-transition-fast),
                transform var(--ipg-transition-fast);
    display: flex;
    flex-direction: column;
}
.news-card:hover {
    box-shadow: var(--ipg-shadow-md);
    transform: translateY(-2px);
}
.news-card__image {
    position: relative;
    overflow: hidden;
}
.news-card__image img {
    display: block;
    width: 100%;
    height: auto;
    /* Caja 16:9 fija: todas las tarjetas de la grilla con la misma altura
       de foto. Antes era un alto fijo de 200px sobre una foto ya recortada
       a 4:3, un doble recorte que cortaba las cabezas. Una foto más
       alargada que 16:9 pierde solo un poco de los costados. */
    aspect-ratio: 16 / 9;
    object-fit: cover;
}
/* Overlay azul al pasar el cursor — pointer-events:none para que el link
   de abajo siga siendo clickeable a través del overlay. */
.news-card__image::before {
    content: '';
    position: absolute;
    inset: 0;
    background-color: var(--ipg-color-primary);
    opacity: 0;
    transition: opacity var(--ipg-transition-fast);
    pointer-events: none;
    z-index: 1;
}
.news-card:hover .news-card__image::before { opacity: 0.45; }
.news-card__badge {
    position: absolute;
    top: var(--ipg-space-3);
    left: var(--ipg-space-3);
    z-index: 2;
    background-color: var(--ipg-color-background);
    color: var(--ipg-color-text);
    padding: var(--ipg-space-1) var(--ipg-space-3);
    border-radius: var(--ipg-radius-full);
    font-size: var(--ipg-text-xs);
    font-weight: var(--ipg-weight-semibold);
    box-shadow: var(--ipg-shadow-sm);
}
.news-card__content {
    padding: var(--ipg-space-5);
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: var(--ipg-space-3);
}
.news-card__meta {
    display: flex;
    align-items: center;
    gap: var(--ipg-space-3);
    font-size: var(--ipg-text-xs);
    color: var(--ipg-color-text-muted);
}
.news-card__meta time { display: inline-flex; align-items: center; gap: var(--ipg-space-1); }
.news-card__category {
    background: var(--ipg-color-primary);
    color: #fff;
    padding: 2px var(--ipg-space-2);
    border-radius: var(--ipg-radius-full);
    font-weight: var(--ipg-weight-semibold);
}
.news-card__title {
    font-size: var(--ipg-text-lg);
    margin: 0;
}
.news-card__title a {
    color: var(--ipg-color-text);
    text-decoration: none;
}
.news-card__title a:hover { color: var(--ipg-color-primary); }
.news-card__summary,
.news-card__excerpt p {
    font-size: var(--ipg-text-sm);
    color: var(--ipg-color-text-muted);
    margin: 0;
}
.news-card .btn { margin-top: auto; align-self: flex-start; }

/* Tarjeta de noticia destacada (categoría "institucional") — imagen arriba
   igual que las demás, y la mitad de texto en azul sólido para resaltar
   comunicados institucionales en el listado (color plano, tal como en la
   maqueta — sin degradado). */
.news-card--featured .news-card__content {
    position: relative;
    overflow: hidden;
    background-color: var(--ipg-color-primary);
}
/* Anillo decorativo de fondo — presente en la maqueta, puramente
   ornamental (no es un ícono de contenido). */
.news-card--featured .news-card__content::before {
    content: '';
    position: absolute;
    top: var(--ipg-space-4);
    right: calc(var(--ipg-space-8) * -1);
    width: 140px;
    height: 140px;
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-radius: 50%;
    pointer-events: none;
}
.news-card--featured .news-card__meta,
.news-card--featured .news-card__title a,
.news-card--featured .news-card__summary,
.news-card--featured .news-card__excerpt p {
    color: var(--ipg-color-text-inverted);
}
.news-card--featured .news-card__title a:hover { opacity: 0.85; color: var(--ipg-color-text-inverted); }
.news-card--featured .news-card__category {
    background: rgba(255, 255, 255, 0.2);
}
.news-card--featured .btn--outline {
    color: var(--ipg-color-text-inverted);
    border-color: var(--ipg-color-text-inverted);
}
.news-card--featured .btn--outline:hover {
    background-color: var(--ipg-color-text-inverted);
    color: var(--ipg-color-primary);
}

/* Tarjeta de acceso destacado (portada) — imagen de fondo con overlay y texto */
.highlight-card {
    position: relative;
    display: block;
    border-radius: var(--ipg-radius-lg);
    overflow: hidden;
    min-height: 260px;
    height: 100%;
    text-decoration: none;
    isolation: isolate;
}
.highlight-card__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--ipg-transition-slow);
}
.highlight-card:hover .highlight-card__image { transform: scale(1.05); }
/* Tarjeta sin destino (el campo "Enlace" quedó vacío en el admin): se renderiza
   como <div> desde front-page.php. Sin el zoom al pasar el mouse, para no
   prometer un clic que no lleva a ninguna parte. */
.highlight-card--sin-enlace:hover .highlight-card__image { transform: none; }
.highlight-card__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.75) 100%);
}
/* Distintivo circular — presente en todas las tarjetas de acceso de la
   maqueta, uniforme (no depende de datos por tarjeta). */
.highlight-card__arrow {
    position: absolute;
    top: var(--ipg-space-4);
    right: var(--ipg-space-4);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.2);
    color: #fff;
    font-size: var(--ipg-text-base);
    backdrop-filter: blur(2px);
}
.highlight-card__content {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: var(--ipg-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-1);
}
.highlight-card__label {
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--ipg-text-xs);
    font-weight: var(--ipg-weight-semibold);
    letter-spacing: var(--ipg-tracking-wide);
    text-transform: uppercase;
}
.highlight-card__title {
    color: #fff;
    font-size: var(--ipg-text-xl);
    font-weight: var(--ipg-weight-bold);
}


/* Paginación */
.pagination {
    display: flex;
    justify-content: center;
    margin-top: var(--ipg-space-10);
}
.pagination .page-numbers {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-sm);
    margin: 0 2px;
    font-size: var(--ipg-text-sm);
    text-decoration: none;
    color: var(--ipg-color-text);
    transition: all var(--ipg-transition-fast);
}
.pagination .page-numbers.current,
.pagination .page-numbers:hover {
    background: var(--ipg-color-primary);
    border-color: var(--ipg-color-primary);
    color: #fff;
}

/* Archivo (listados de CPTs) */
.archive-header { margin-bottom: var(--ipg-space-10); }
.archive-title { font-size: var(--ipg-text-4xl); }

/* ── Tabs editables (patrón de bloque "Tabs editables") ──────────────────
   Componente reutilizable: navegación de pestañas + panel de contenido.
   Estructura (ver inc/block-patterns.php → ipg/tabs-editables):

   .ipg-tabs
     .ipg-tabs__nav
       .ipg-tabs__tab (.is-active)
         .ipg-tabs__tab-eyebrow
         .ipg-tabs__tab-title
     .ipg-tabs__panels
       .ipg-tabs__panel (.is-active)

   La interacción (mostrar/ocultar panel, roles ARIA) la agrega
   assets/js/main.js en tiempo de ejecución — no depende de atributos
   personalizados en el HTML de los bloques, para no romper la edición
   visual en Gutenberg. ───────────────────────────────────────────────── */
.ipg-tabs__nav {
    display: flex;
    flex-wrap: wrap;
    border-bottom: 1px solid var(--ipg-color-border);
}
.ipg-tabs__tab {
    flex: 1 1 200px;
    padding: var(--ipg-space-4) var(--ipg-space-6);
    background: var(--ipg-color-surface);
    border-right: 1px solid var(--ipg-color-border);
    border-bottom: 3px solid transparent;
    cursor: pointer;
    transition: background-color var(--ipg-transition-fast),
                color var(--ipg-transition-fast);
}
.ipg-tabs__tab:last-child {
    border-right: none;
}
.ipg-tabs__tab:hover {
    background: var(--ipg-color-surface-2);
}
.ipg-tabs__tab.is-active {
    background: var(--ipg-color-primary);
    border-bottom-color: var(--ipg-color-accent);
}
.ipg-tabs__tab:focus-visible {
    outline: 2px solid var(--ipg-color-accent);
    outline-offset: -2px;
}
.ipg-tabs__tab-eyebrow {
    margin: 0 0 var(--ipg-space-1);
    font-size: var(--ipg-text-xs);
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ipg-color-text-muted);
}
.ipg-tabs__tab.is-active .ipg-tabs__tab-eyebrow {
    color: rgba(255, 255, 255, .7);
}
.ipg-tabs__tab-title {
    margin: 0;
    font-weight: 700;
    line-height: 1.35;
    color: var(--ipg-color-text);
}
.ipg-tabs__tab.is-active .ipg-tabs__tab-title {
    color: var(--ipg-color-text-inverted);
}
.ipg-tabs__panels {
    padding: var(--ipg-space-8);
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-top: none;
}
.ipg-tabs__panel {
    display: none;
}
.ipg-tabs__panel.is-active {
    display: block;
}
.ipg-tabs__panel > *:last-child {
    margin-bottom: 0;
}
@media (max-width: 600px) {
    .ipg-tabs__tab {
        flex: 1 1 100%;
        border-right: none;
    }
    .ipg-tabs__panels {
        padding: var(--ipg-space-6) var(--ipg-space-4);
    }
}

/* ── Variante lateral: los títulos en una columna, la descripción al lado ──
   (patrón de bloque "Pestañas en dos columnas")

   Mismo componente y mismo JS que las pestañas horizontales; solo cambia la
   disposición. Sirve cuando los títulos son frases largas: en una fila
   horizontal cuatro títulos de ocho palabras se apretarían a tres líneas
   cada uno, mientras que en columna cada uno respira y además se ve el
   título elegido junto a su texto, no encima de él.

   Los grupos van con layout "default" (flujo), no "constrained": un grupo
   constrained le impone el ancho de lectura de WordPress a sus hijos, y eso
   es justo lo que rompe una disposición en dos columnas. ────────────────── */
.ipg-tabs--laterales {
    display: grid;
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    gap: var(--ipg-space-8);
    /* Tope propio en vez del ancho de lectura de WordPress: 320px de
       títulos + 32 de separación dejan ~690px de texto, que es el ancho
       cómodo de lectura. Sin tope, en un contenedor "Ancho" la descripción
       se estiraría a 1000px y costaría seguir el renglón. */
    max-width: min(1040px, 100%);
    margin-inline: auto;
    /* La columna de títulos se queda de su alto natural: sin esto se estira
       hasta igualar una descripción larga y el borde divisorio queda
       colgando bajo el último título. */
    align-items: start;
}

/* La columna de títulos */
.ipg-tabs--laterales .ipg-tabs__nav {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    border-bottom: none;
    border-right: 1px solid var(--ipg-color-border);
}
/* El `flex: 1 1 200px` de la versión horizontal aquí actuaría sobre el eje
   vertical y daría 200px de ALTO a cada título. */
.ipg-tabs--laterales .ipg-tabs__tab {
    flex: 0 0 auto;
    padding: var(--ipg-space-4) var(--ipg-space-5);
    background: transparent;
    border-right: none;
    border-bottom: 1px solid var(--ipg-color-border);
    /* La barra de selección pasa del borde inferior al lateral, que es
       donde la vista busca el activo en una lista vertical. */
    border-left: 3px solid transparent;
    text-align: left;
}
.ipg-tabs--laterales .ipg-tabs__tab:last-child {
    border-bottom: none;
}
.ipg-tabs--laterales .ipg-tabs__tab:hover {
    background: var(--ipg-color-surface);
}
.ipg-tabs--laterales .ipg-tabs__tab.is-active {
    background: var(--ipg-color-surface);
    border-left-color: var(--ipg-color-accent);
    border-bottom-color: var(--ipg-color-border);
}
/* En horizontal el activo se rellena de azul y el texto va en blanco; aquí
   el fondo es claro, así que hay que devolver los colores de texto. */
.ipg-tabs--laterales .ipg-tabs__tab.is-active .ipg-tabs__tab-eyebrow {
    color: var(--ipg-color-accent);
}
.ipg-tabs--laterales .ipg-tabs__tab.is-active .ipg-tabs__tab-title {
    color: var(--ipg-color-primary);
}

/* La columna de descripciones: sin caja propia, la separación ya la da el
   borde de la columna de títulos. */
.ipg-tabs--laterales .ipg-tabs__panels {
    padding: 0;
    background: transparent;
    border: none;
}

/* Bajo ~780px las dos columnas no caben: se apilan, títulos arriba y
   descripción abajo, y el separador vuelve a ser horizontal. */
@media (max-width: 782px) {
    .ipg-tabs--laterales {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--ipg-space-6);
    }
    .ipg-tabs--laterales .ipg-tabs__nav {
        border-right: none;
        border-bottom: 1px solid var(--ipg-color-border);
    }
}

/* Contra el margen de flujo del núcleo
       :root :where(.is-layout-flow) > * { margin-block-start: 24px }
   que se cuela entre el rótulo y el título de cada pestaña, y entre los
   bloques de un panel. Hay que anularlo en los CUATRO niveles: el propio
   componente, las dos columnas, y el interior de cada pestaña y panel.
   El prefijo :root iguala la especificidad de la regla del núcleo. */
:root .ipg-tabs--laterales > *,
:root .ipg-tabs--laterales .ipg-tabs__nav > *,
:root .ipg-tabs--laterales .ipg-tabs__panels > *,
:root .ipg-tabs--laterales .ipg-tabs__tab > *,
:root .ipg-tabs--laterales .ipg-tabs__panel > * { margin-block: 0; }
/* Repuesta la separación real que sí queremos: un respiro bajo el rótulo... */
:root .ipg-tabs--laterales .ipg-tabs__tab-eyebrow { margin-block-end: var(--ipg-space-1); }
/* ...y aire entre bloques cuando un panel tiene más de uno (párrafo + lista,
   texto + botón), que si no quedarían pegados. */
:root .ipg-tabs--laterales .ipg-tabs__panel > * + * { margin-block-start: var(--ipg-space-4); }
/* ── Ubicación de la sede (patrón "Grilla de sedes con ficha") ────────────

   El mapa es un iframe de Google y va con pointer-events: none a propósito.
   Dentro de una modal, un mapa arrastrable y con zoom se roba la rueda del
   mouse y cuesta salir de él; acá es una imagen viva, y el que manda es el
   enlace.

   Ese enlace se estira sobre todo el bloque con un ::after posicionado — la
   misma técnica del patrón "Accesos a secciones". Así sigue habiendo un
   solo enlace real en el HTML (bueno para lectores de pantalla y para
   buscadores, que leen "Ver la ubicación en Google Maps") pero el área
   clicable es el mapa entero, no solo el renglón de texto.

   Reemplaza a los botones "Abrir en Maps" y "Contactar esta sede": el mapa
   hace lo primero mostrando además dónde queda, y el correo y el teléfono
   ya están en la ficha, unas líneas más arriba. */
.ipg-sede__ubicacion {
    position: relative;
    margin-top: var(--ipg-space-6);
}
.ipg-sede__ubicacion-marco {
    display: block;
    width: 100%;
    /* "No tan grande, pero que se vea": alto suficiente para reconocer el
       sector sin que empuje la ficha fuera de la pantalla. */
    height: 200px;
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius);
    background-color: var(--ipg-color-surface);
    pointer-events: none;
}
.ipg-sede__ubicacion-enlace {
    margin: var(--ipg-space-3) 0 0;
    font-size: var(--ipg-text-sm);
    font-weight: var(--ipg-weight-semibold);
}
.ipg-sede__ubicacion-enlace a {
    color: var(--ipg-color-primary);
    text-decoration: none;
}
.ipg-sede__ubicacion-enlace a::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: var(--ipg-radius);
}
.ipg-sede__ubicacion:hover .ipg-sede__ubicacion-enlace a { text-decoration: underline; }
/* Al llegar por teclado el recuadro de foco tiene que verse sobre el mapa,
   no solo alrededor del renglón de texto. */
.ipg-sede__ubicacion-enlace a:focus-visible { outline: none; }
.ipg-sede__ubicacion-enlace a:focus-visible::after {
    outline: 2px solid var(--ipg-color-accent);
    outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════════════════════
   NOTICIA INDIVIDUAL — cuerpo + listado al costado
   (ver single-ipg_news.php)
   ══════════════════════════════════════════════════════════════════════════ */

/* Dos columnas: la noticia y, al costado, las más recientes.
   El tope de 1200px no es decorativo: deja la columna de lectura en ~840px,
   que es el contentSize que ya declara theme.json para el resto del sitio.
   Sin tope, en un monitor ancho el texto se estiraría a 1100px y costaría
   seguir el renglón.
   align-items: start es lo que permite que el costado quede pegajoso
   (sticky) al bajar: si se estirara al alto de la noticia no habría por
   dónde desplazarse. */
.news-single__layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 360px);
    gap: var(--ipg-space-10);
    align-items: start;
    max-width: min(1200px, 100%);
    margin-inline: auto;
    padding-block: var(--ipg-space-10);
}

/* ── La noticia ───────────────────────────────────────────────────────── */

/* Proporción fija en vez de altura automática: la portada mide siempre lo
   mismo tenga la foto que tenga, así el título no cambia de sitio de una
   noticia a otra. El encuadre lo hace object-fit, no el recorte subido. */
.news-single__media {
    margin: 0 0 var(--ipg-space-8);
    aspect-ratio: 16 / 9;
    overflow: hidden;
    border-radius: var(--ipg-radius-lg);
    box-shadow: var(--ipg-shadow-sm);
    background-color: var(--ipg-color-surface);
}
.news-single__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.news-single__title {
    font-size: clamp(1.875rem, 4vw, 2.75rem);
    line-height: 1.15;
    margin: 0 0 var(--ipg-space-4);
}
.news-header .news-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ipg-space-4);
    align-items: center;
    margin-bottom: var(--ipg-space-6);
    font-size: var(--ipg-text-sm);
    color: var(--ipg-color-text-muted);
}
/* La bajada abre la noticia, así que se distingue del cuerpo: algo más
   grande y con una barra del color institucional al costado.
   Va con .news-header delante porque la bajada es el último hijo del
   encabezado: `p:last-child` de base.css pesa más que una clase sola y le
   dejaba el margen inferior en 0, pegándola al primer párrafo. */
.news-header .news-single__summary {
    margin: 0 0 var(--ipg-space-8);
    font-size: var(--ipg-text-lg);
    line-height: var(--ipg-leading-loose);
    color: var(--ipg-color-text-muted);
    border-left: 4px solid var(--ipg-color-primary);
    padding-left: var(--ipg-space-4);
}
/* El cuerpo de la noticia ocupa su columna entera, pegado al mismo borde que
   la foto, el título y la bajada. La regla general de .entry-content
   (layout.css) topa cada bloque a --ipg-container-content (720px) y lo
   centra: pensada para páginas a lo ancho, acá la columna mide ~800px, así
   que el texto quedaba centrado dentro de ella y corrido ~40px a la derecha
   del título. El ancho de lectura ya lo pone .news-single__layout.
   Ancho y Pantalla completa también se anulan: en esta plantilla hay un
   costado, y un bloque a 100vw se le montaría encima. */
.entry-content.news-content > * {
    max-width: none;
    width: auto;
    margin-left: 0;
    margin-right: 0;
}
/* Texto justificado en la bajada y el cuerpo (criterio editorial del IPG
   para las noticias). Solo párrafos y listas: los títulos y los bloques con
   alineación propia (centrado, derecha) no se tocan.
   hyphens: auto es lo que hace aguantable el justificado en la columna
   angosta del teléfono: sin partir palabras, el navegador estira los
   espacios y abre "ríos" blancos en el renglón. Funciona porque WordPress
   emite lang="es-CL". */
.news-header .news-single__summary,
.news-content > p:not(.has-text-align-center):not(.has-text-align-right),
.news-content > :is(ul, ol) li {
    text-align: justify;
    hyphens: auto;
}
.news-single__source {
    margin-top: var(--ipg-space-8);
    padding-top: var(--ipg-space-4);
    border-top: 1px solid var(--ipg-color-border);
}
.news-single__source p {
    margin: 0;
    font-size: var(--ipg-text-sm);
    color: var(--ipg-color-text-muted);
}
.news-single__nav {
    margin-top: var(--ipg-space-10);
    padding-top: var(--ipg-space-6);
    border-top: 1px solid var(--ipg-color-border);
}
.news-single__nav-label {
    display: block;
    font-size: var(--ipg-text-xs);
    text-transform: uppercase;
    letter-spacing: var(--ipg-tracking-wide);
    color: var(--ipg-color-text-muted);
}

/* ── El listado del costado ───────────────────────────────────────────── */

/* Pegajoso al bajar: en una noticia larga el listado sigue a la vista en
   vez de quedar arriba del todo. El desfase deja libre la altura del
   header, que es fijo. */
.news-aside {
    position: sticky;
    top: calc(var(--ipg-header-height) + var(--ipg-space-6));
}
.news-aside__title {
    font-size: var(--ipg-text-lg);
    margin: 0 0 var(--ipg-space-4);
    padding-bottom: var(--ipg-space-3);
    border-bottom: 2px solid var(--ipg-color-primary);
}
.news-aside__list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.news-aside__item + .news-aside__item {
    border-top: 1px solid var(--ipg-color-border);
}
/* Miniatura a la izquierda y texto a la derecha. Con solo fecha y título el
   costado se leía como un índice; la foto y un asomo del contenido lo
   convierten en algo que invita a entrar, que es para lo que está. */
.news-aside__link {
    display: flex;
    gap: var(--ipg-space-3);
    align-items: flex-start;
    padding: var(--ipg-space-4) var(--ipg-space-3);
    /* La barra lateral marca el elemento apuntado, igual que en las
       pestañas laterales del tema. */
    border-left: 3px solid transparent;
    text-decoration: none;
    color: inherit;
    transition: background-color var(--ipg-transition-fast),
                border-color var(--ipg-transition-fast);
}
.news-aside__link:hover,
.news-aside__link:focus-visible {
    background-color: var(--ipg-color-surface);
    border-left-color: var(--ipg-color-accent);
}

/* flex-shrink: 0 para que la miniatura no se aplaste cuando el título es
   largo; el que cede es el texto, no la foto. */
.news-aside__media {
    flex: 0 0 80px;
    width: 80px;
    height: 80px;
    overflow: hidden;
    border-radius: var(--ipg-radius);
    background-color: var(--ipg-color-surface-2);
}
.news-aside__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Noticia sin imagen destacada: la caja se mantiene con un fondo neutro para
   que los títulos de la lista sigan alineados entre sí. */
.news-aside__media--empty { background-color: var(--ipg-color-surface-2); }

/* min-width: 0 deja que la columna de texto se encoja por debajo de su ancho
   mínimo de contenido; sin esto una palabra larga ensancha el flex y desborda
   la tarjeta en vez de partirse. */
.news-aside__text {
    flex: 1 1 auto;
    min-width: 0;
}
.news-aside__date {
    display: block;
    margin-bottom: var(--ipg-space-1);
    font-size: var(--ipg-text-xs);
    color: var(--ipg-color-text-muted);
}
.news-aside__headline {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    /* Dos líneas de título como máximo: con cinco noticias en el costado, un
       titular largo sin tope empujaría el resto fuera de la pantalla. */
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    font-size: var(--ipg-text-sm);
    font-weight: var(--ipg-weight-semibold);
    line-height: 1.35;
    color: var(--ipg-color-text);
}
.news-aside__excerpt {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    margin-top: var(--ipg-space-1);
    font-size: var(--ipg-text-xs);
    line-height: var(--ipg-leading-normal);
    color: var(--ipg-color-text-muted);
}
.news-aside__link:hover .news-aside__headline { color: var(--ipg-color-primary); }

.news-aside__all {
    display: inline-block;
    margin-top: var(--ipg-space-4);
    font-size: var(--ipg-text-sm);
    font-weight: var(--ipg-weight-semibold);
    color: var(--ipg-color-primary);
    text-decoration: none;
}
.news-aside__all:hover { text-decoration: underline; }

/* Bajo ~900px las dos columnas no caben: el listado pasa debajo de la
   noticia y deja de ser pegajoso (ahí ya no tiene junto a qué quedarse). */
@media (max-width: 900px) {
    .news-single__layout {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--ipg-space-8);
    }
    .news-aside {
        position: static;
        border-top: 1px solid var(--ipg-color-border);
        padding-top: var(--ipg-space-6);
    }
}

/* ── Variantes de botón Gutenberg ───────────────────────────────────────── */

/* Estilo por defecto del bloque botón = Acento (naranja) */
.wp-block-button__link {
    background-color: var(--ipg-color-accent);
    /* Marino, no blanco: ver la nota en base.css sobre .btn--accent. */
    color: var(--ipg-color-primary);
    font-weight: 600;
    border-radius: 4px;
    padding: 0.75rem 1.5rem;
    text-decoration: none;
    transition: background-color 0.2s ease;
}
.wp-block-button__link:hover {
    background-color: #1182B0;
    color: #ffffff;
}

/* Primario (azul) */
.wp-block-button.is-style-primary .wp-block-button__link {
    background-color: var(--ipg-color-primary);
    color: #ffffff;
    border: 2px solid var(--ipg-color-primary);
}
.wp-block-button.is-style-primary .wp-block-button__link:hover {
    background-color: var(--ipg-color-primary-dark);
    border-color: var(--ipg-color-primary-dark);
}

/* Outline (borde azul, fondo transparente)

   Los colores del tema son solo el PUNTO DE PARTIDA: valen mientras nadie
   haya elegido uno desde el editor.

   Antes iban con !important y eso los volvia inamovibles. Un boton outline
   sobre un hero marino salia marino sobre marino —invisible— y recien al
   pasar el mouse aparecia, en blanco, salido de la nada. Elegir "Blanco" en
   el panel no servia de nada: con especificidad (0,3,0) e !important, estas
   tres lineas le ganaban tanto a la clase .has-white-color que agrega
   WordPress como al border-color en linea del propio bloque.

   WordPress marca el bloque con .has-text-color y .has-border-color en
   cuanto se elige un color. Colgar el valor por defecto de un :not() de esas
   clases da el comportamiento correcto en los dos casos: manda el tema
   cuando no hay eleccion, manda la eleccion en cuanto la hay. */
.wp-block-button.is-style-outline .wp-block-button__link {
    border-style: solid;
    border-width: 2px;
}
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-background) {
    background-color: transparent;
}
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color) {
    color: var(--ipg-color-primary);
}
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-border-color) {
    border-color: var(--ipg-color-primary);
}

/* Hover. Sin color propio se rellena en marino con texto blanco, que es el
   comportamiento de siempre. Con un color elegido no se puede invertir a
   ciegas —rellenar de blanco un boton blanco lo haria desaparecer de nuevo,
   que es justo el problema que se esta arreglando—, asi que el fondo se tine
   con el color del propio boton: funciona igual sobre fondo claro y oscuro,
   sea cual sea el color. */
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color):hover {
    background-color: var(--ipg-color-primary);
    color: var(--ipg-color-text-inverted);
}
.wp-block-button.is-style-outline .wp-block-button__link.has-text-color:hover {
    background-color: color-mix(in srgb, currentColor 15%, transparent);
}

/* ── Responsive tarjetas (≤ 600px) ─────────────────────────────────────── */
@media (max-width: 600px) {
    .news-card__content { padding: var(--ipg-space-4); }
    .archive-title { font-size: var(--ipg-text-2xl); }
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO DE PÁGINA — cabecera única para todas las páginas internas.

   Comparte el lenguaje visual del hero de portada (.hero-slide en layout.css):
   misma píldora de etiqueta, mismo título de dos tonos, misma escala de tipo
   y mismo par de botones. Así una página interna se siente hermana del home
   y no de otro sitio.

   Dos variantes, un solo sistema:
     .ipg-page-hero              → fondo editable (color, degradado o imagen).
                              Se construye sobre el bloque Cover, así que el
                              editor cambia color/imagen desde el panel lateral
                              sin tocar código.
     .ipg-page-hero--split       → texto a un lado, imagen al otro (como el home).
                              Para páginas que ya tienen foto real.

   El color del texto lo define el bloque Cover (o la variante). Todo lo que
   depende de ese color usa currentColor, así el hero se lee bien tanto sobre
   fondo oscuro como claro sin clases extra.
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-page-hero__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--ipg-space-2);
    margin: 0 0 var(--ipg-space-4);
    padding: var(--ipg-space-1) var(--ipg-space-3);
    border-radius: var(--ipg-radius-full);
    font-size: var(--ipg-text-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    /* Celeste solido con letras blancas.

       Antes el fondo se derivaba del color del texto heredado
       (color-mix con currentColor). La idea era que funcionara sobre
       cualquier fondo sin una clase por variante, pero fallaba justo donde
       mas se usa: el patron pone el texto en blanco en el titulo y en la
       bajada, NO en la etiqueta, asi que esta heredaba el gris oscuro del
       body y quedaba oscuro sobre oscuro — invisible sobre un hero marino.

       Con un color propio ya no depende de lo que herede, y se ve igual
       sobre un hero marino, celeste, blanco o con foto.

       Va en accent-dark y no en el celeste brillante por contraste: blanco
       sobre #13B8E6 da 2.33:1 —ilegible— y sobre #1182B0 da 4.34:1. Sigue
       leyendose celeste, y ademas se distingue del titulo, que si usa el
       celeste brillante. */
    background-color: var(--ipg-color-accent-dark);
    color: var(--ipg-color-text-inverted);
}
.ipg-page-hero__eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentColor;
    flex-shrink: 0;
}

.ipg-page-hero__title {
    margin: 0 0 var(--ipg-space-4);
    font-size: clamp(1.875rem, 5vw, 3rem);
    font-weight: 800;
    line-height: 1.1;
    text-wrap: balance;
    color: inherit;
}

.ipg-page-hero__lead {
    margin: 0 0 var(--ipg-space-8);
    max-width: 54ch;
    font-size: var(--ipg-text-lg);
    line-height: 1.6;
    color: inherit;
    opacity: 0.9;
}

.ipg-page-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ipg-space-4);
}

/* Variante partida: texto + imagen, con la imagen estirada a la altura del
   texto (mismo criterio que .hero-slide__media en el home). */
.ipg-page-hero--split .ipg-page-hero__media {
    margin: 0;
    /* aspect-ratio, no min-height. Es la diferencia entre que la caja tenga
       una altura DEFINIDA o una que depende de su contenido.
       Con `min-height: 360px` la altura del figure seguia siendo "auto" a
       ojos de su hijo, asi que el `height: 100%` de la imagen no tenia
       contra que resolverse: caia a "auto", la imagen se quedaba en su alto
       natural y, cuando ese alto no llegaba al minimo, sobraba caja vacia
       debajo — el hueco que se veia bajo la foto.
       Con una proporcion fija la altura es definida, el height:100% resuelve
       y object-fit recorta. Efecto practico: sirve CUALQUIER imagen, sin
       tener que subirla a una medida exacta. */
    aspect-ratio: 4 / 3;
    /* Techo de altura: la imagen se adapta al hero, no al reves. Sin esto la
       proporcion manda y una columna ancha da una foto de 450px o mas, que
       estira el hero muy por encima de lo que pide el texto. Con el techo,
       object-fit: cover recorta un poco mas y el hero conserva su alto. */
    max-height: var(--ipg-hero-media-max, 380px);
    overflow: hidden;
    border-radius: var(--ipg-radius-lg);
    box-shadow: var(--ipg-shadow-md);
}
.ipg-page-hero--split .ipg-page-hero__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

@media (max-width: 782px) {
    .ipg-page-hero {
        min-height: 0 !important; /* el alto mínimo del Cover asfixia en móvil */
    }
    .ipg-page-hero--split .ipg-page-hero__media {
        aspect-ratio: 16 / 10;
    }
}


/* ── Puntas curvadas del hero ─────────────────────────────────────────────
   Solo las dos de abajo: arriba el hero va pegado al menu a proposito (ver
   .site-main.page-content en layout.css), y curvar ahi dejaria dos muescas
   del fondo entre la barra blanca y el hero.

   overflow: hidden hace falta de verdad, no es precaucion: en el patron
   "Hero de pagina" el fondo no es del propio bloque sino de un hijo
   —<span class="wp-block-cover__background">, que es como el bloque Portada
   pinta su color o su imagen—, y a un hijo el border-radius del padre no lo
   recorta. Sin esto, la curva se veria en el borde pero el color seguiria
   cuadrado. */
.ipg-page-hero {
    /* Las CUATRO esquinas. Antes solo iban las de abajo, y el banner se leia
       como una continuacion del menu en vez de una pieza con identidad
       propia. Ahora que se separa de los bordes (ver la regla de abajo) las
       de arriba tambien tienen borde que curvar. */
    border-radius: var(--ipg-radius-xl);
    overflow: hidden;
    /* Piso de altura. Sin el, el hero encoge cuando la pagina no lleva bajada:
       ese parrafo son tres lineas mas su margen, unos 118px, y el hero pasaba
       de ~455 a ~337px. Con el piso, quitar la bajada ya no cambia el tamano
       del bloque, solo deja mas aire alrededor del titulo.
       Incluye el relleno, porque el tema usa box-sizing: border-box. */
    min-height: var(--ipg-hero-min);
}

/* ── El banner, separado de los bordes de la pantalla ─────────────────────
   `.entry-content > .alignfull` lleva el bloque a 100vw, pegado a los dos
   bordes. Aca se le devuelven --ipg-marco por lado, asi el hero flota sobre
   el lienzo gris en vez de tocar el cristal.

   Se acota al hero y no se toca .alignfull en general a proposito: una
   franja de color a media pagina —un banner CTA, por ejemplo— sigue
   queriendo ir a sangre de verdad.

   La cuenta es la misma que ya usa .alignfull, corrida por el marco:
   50% es la mitad del contenedor y 50vw la mitad de la pantalla. */
:root .entry-content > .ipg-page-hero.alignfull {
    /* El ancho y los margenes laterales ya los pone .entry-content >
       .alignfull en layout.css, que ahora respeta --ipg-marco para todas
       las secciones a sangre. Aca queda solo lo propio del hero:

       separarlo del menu. Hay una regla en layout.css que hace justo lo
       contrario —.page-content .entry-content > :first-child se lleva un
       margen NEGATIVO de --ipg-shell-gutter— para pegar la primera seccion
       a la barra. Se escribio cuando el hero iba a sangre y pegarlo era lo
       correcto; ahora que flota, ese tiron lo dejaba tocando el menu por
       arriba mientras se separaba por los lados.
       Solo se anula para el hero: las demas secciones de primera linea
       siguen pegandose como antes. */
    margin-block-start: var(--ipg-marco-tope);
}

/* ── El contenido del hero, al ancho del sitio ────────────────────────────
   Este es el motivo de que el titulo saliera varado en mitad del banner.

   El hero es un grupo "constrained", asi que WordPress le impone a sus hijos
   el contentSize de theme.json: 860px, el ancho comodo para LEER un parrafo.
   Dentro de un banner de 1900px eso deja el texto empezando cerca del
   centro, a unos 530px del borde, sin relacion con donde empieza el logo ni
   el menu de arriba.

   Con el wideSize (1440px, el mismo --ipg-container-max que usan el header y
   el footer) el contenido del hero se alinea con el resto del sitio y el
   titulo se va hacia la izquierda, donde tiene que estar.

   El :where() de la regla de WordPress no suma especificidad, asi que su
   selector vale (0,1,0); el prefijo :root deja este en (0,2,0) y gana sin
   !important. Se cubren las dos formas del hero: el grupo con columnas
   ("Hero con imagen lateral") y el Cover ("Hero de pagina"), donde el layout
   vive en el contenedor interno. */
:root .ipg-page-hero > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
:root .ipg-page-hero .wp-block-cover__inner-container > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
    max-width: var(--ipg-container-max);
}

/* El piso solo sirve si el contenido se centra: si no, el titulo se queda
   arriba y todo el aire sobrante cae debajo, que se ve peor que el hero
   pequeno. La variante Cover ("Hero de pagina") ya lo hace por su cuenta
   —trae contentPosition en el propio bloque—, asi que esto es solo para la
   de imagen lateral, que es un grupo normal.
   Las reglas de layout de WordPress siguen funcionando: centran sus hijos con
   margin-inline auto, que en una columna flex hace exactamente lo mismo. */
.ipg-page-hero--split {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

@media (max-width: 782px) {
    /* En movil el contenido se apila y crece de por si; mantener 450px de
       piso dejaria un hero desproporcionado en pantallas cortas. */
    .ipg-page-hero {
        --ipg-hero-min: 300px;

        /* Titular del hero: 36px no alcanzan.

           Los títulos de página usan el tamaño 7xl, que ya baja a 36px en
           teléfono. Pero la caja del titular mide 278px y "Acompañamiento"
           a 36px necesita ~292px: no cabe por catorce píxeles. Y como
           WordPress le aplica `word-break: break-word` a todo lo que vive
           dentro de una columna, en vez de desbordarse la palabra se parte
           por la mitad — "Acompañamien / to Estudiantil".

           Se baja el preset SOLO dentro del hero, redefiniendo la variable
           en lugar de pelear con el `!important` que WordPress le pone a
           .has-7-xl-font-size. A 390px da ~31px, con los que la palabra
           más larga entra con holgura. */
        --wp--preset--font-size--7-xl: clamp(1.75rem, 8vw, 4.5rem);
        --wp--preset--font-size--6-xl: clamp(1.625rem, 7vw, 3.75rem);
    }

    /* Red de seguridad para un titular con una palabra aún más larga
       ("Internacionalización"): en vez de cortarla en cualquier letra, se
       parte por sílabas y con guion. El <html lang="es-CL"> que emite
       WordPress es lo que le permite al navegador silabear en español. */
    .ipg-page-hero__title {
        word-break: normal;
        hyphens: auto;
    }
}

/* ── Formas para la imagen del hero ───────────────────────────────────────
   Tres variantes que se eligen en el editor (panel derecho → Estilos), para
   que cada página decida cómo entra su imagen sin tocar código. Se registran
   en functions.php → ipg_register_block_styles().

   La caja de siempre (sin estilo elegido) queda como está: proporción 4/3,
   esquinas redondeadas, la foto recortada al centro.
   ────────────────────────────────────────────────────────────────────── */

/* ① Círculo — sirve cualquier foto rectangular, se recorta en redondo.
   Lleva un aro celeste separado del borde: da un respiro entre la foto y el
   fondo sin necesidad de sombra, que sobre un degradado claro se ensucia. */
.ipg-page-hero__media.is-style-ipg-circulo,
.wp-block-image.is-style-ipg-circulo {
    aspect-ratio: 1 / 1;
    max-height: var(--ipg-hero-media-max, 380px);
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 0 0 10px rgba(19, 184, 230, 0.16),
                0 18px 46px rgba(14, 30, 77, 0.20);
}
.is-style-ipg-circulo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ② Recorte sin fondo — la receta de las referencias: un disco de color
   detrás y la figura saliéndose por arriba.
   Necesita un PNG con fondo transparente. Con una foto rectangular se ve el
   rectángulo tapando el disco, por eso el nombre del estilo lo advierte.

   overflow: visible es lo que permite el desborde; object-fit: contain
   mantiene a la persona entera (cover la recortaría), y object-position
   bottom la apoya sobre el disco en vez de dejarla flotando. */
.ipg-page-hero__media.is-style-ipg-recorte,
.wp-block-image.is-style-ipg-recorte {
    aspect-ratio: 1 / 1;
    max-height: var(--ipg-hero-media-max, 380px);
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
    position: relative;
    display: grid;
    place-items: end center;
}
/* El disco. No llega a los bordes de la caja: ese margen es el sitio por
   donde la figura se asoma. */
.is-style-ipg-recorte::before {
    content: '';
    position: absolute;
    inset: 12% 8% 4%;
    border-radius: 50%;
    background: linear-gradient(150deg, #0E1E4D 0%, rgba(19, 184, 230, 0.85) 100%);
}
/* Trama de puntos, puramente decorativa — se dibuja con un degradado
   repetido en vez de una imagen, así no hay archivo que subir ni que se
   vea borroso en pantallas retina. */
.is-style-ipg-recorte::after {
    content: '';
    position: absolute;
    right: -1%;
    bottom: 6%;
    width: 32%;
    aspect-ratio: 1 / 1;
    background-image: radial-gradient(rgba(19, 184, 230, 0.55) 1.7px, transparent 1.8px);
    background-size: 13px 13px;
    z-index: 0;
    pointer-events: none;
}
.is-style-ipg-recorte img {
    position: relative;
    z-index: 1;
    grid-area: 1 / 1;
    width: 100%;
    /* Más alto que su caja: es el desborde. Modesto a propósito — el hero
       tiene padding, y pasarse haría que la figura chocara con el título. */
    height: 112%;
    object-fit: contain;
    object-position: bottom center;
    display: block;
}

/* ③ Desbordada — la foto rompe el encuadre y se va hacia el borde derecho
   de la pantalla, sin caja. Se difumina por la izquierda con una máscara,
   así el corte no es una línea recta sino una transición hacia el fondo.
   Solo en escritorio: en móvil la columna ya ocupa todo el ancho y el
   desborde no tendría hacia dónde ir. */
.wp-block-image.is-style-ipg-desborde {
    border-radius: var(--ipg-radius-lg) 0 0 var(--ipg-radius-lg);
    box-shadow: none;
    overflow: hidden;
}
@media (min-width: 783px) {
    .wp-block-image.is-style-ipg-desborde {
        margin-inline-end: calc(50% - 50vw);
        -webkit-mask-image: linear-gradient(95deg, transparent 0%, #000 18%);
        mask-image: linear-gradient(95deg, transparent 0%, #000 18%);
    }
}
.is-style-ipg-desborde img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}


/* ④ Difuminada — la foto se funde con el fondo por el borde que mira al
   texto, y NO se mueve de su sitio.

   Es la hermana de "Desbordada" para cuando la imagen vive dentro de una
   columna. Aquella difumina y ademas empuja la foto al borde de la pantalla
   con `margin-inline-end: calc(50% - 50vw)`; ese calculo solo sale bien si
   la imagen cuelga de un contenedor centrado en la pantalla. Dentro de una
   columna el 50% es la mitad de la COLUMNA, la resta se va a un margen
   negativo enorme y la foto arrastra al resto del bloque.

   Esta aplica la mascara y nada mas: sin margenes y sin unidades de
   viewport, asi que funciona igual en una columna, en un grupo o suelta en
   la pagina.

   DOS INTENSIDADES, no un control libre:
     "Difuminada"        — la foto solo pierde el canto (--ipg-fundido)
     "Difuminada amplia" — se disuelve dentro del texto (--ipg-fundido-amplio)
   Dos pasos con nombre siguen siendo un sistema; un deslizador por imagen
   acaba en veinte fundidos distintos que se leen como accidente.

   El selector [class*=] cubre las dos a la vez: comparten todo menos el
   ancho de la transicion, que cada estilo fija en --f. */
.wp-block-image[class*="is-style-ipg-fundido"] {
    --f: var(--ipg-fundido);
    box-shadow: none;
    background: none;
    overflow: visible;
}
.wp-block-image.is-style-ipg-fundido-amplio {
    --f: var(--ipg-fundido-amplio);
}

/* Por defecto se funde por la IZQUIERDA: es el caso habitual, la foto a la
   derecha del texto. La esquina de afuera se redondea; la del fundido no
   hace falta, porque ahi ya no hay canto que redondear. */
.wp-block-image[class*="is-style-ipg-fundido"] img {
    display: block;
    width: 100%;
    border-radius: 0 var(--ipg-radius-lg) var(--ipg-radius-lg) 0;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 var(--f));
            mask-image: linear-gradient(to right, transparent 0%, #000 var(--f));
}

/* Si la foto cae en la PRIMERA columna, el texto queda a su derecha: el
   fundido se voltea solo. Asi el mismo estilo sirve para los dos lados y
   quien edita no tiene que acordarse de elegir la variante correcta. */
.wp-block-columns > .wp-block-column:first-child .wp-block-image[class*="is-style-ipg-fundido"] img {
    border-radius: var(--ipg-radius-lg) 0 0 var(--ipg-radius-lg);
    -webkit-mask-image: linear-gradient(to left, transparent 0%, #000 var(--f));
            mask-image: linear-gradient(to left, transparent 0%, #000 var(--f));
}

/* "Difuminada por los dos lados" — se funde por izquierda Y por derecha, con
   un solo degradado de cuatro paradas: entra opaca a --f y vuelve a
   desvanecerse a esa misma distancia del otro extremo.

   El fundido de un lado deja el otro canto recto contra el fondo, y ese
   corte se nota. Aca no queda ninguno.

   Por eso mismo esta variante NO se voltea ni redondea esquinas: es
   simetrica, da igual en que columna caiga, y donde no hay canto no hay nada
   que redondear. Se repite el selector con :first-child solo para ganarle en
   especificidad a la regla de arriba. */
.wp-block-image.is-style-ipg-fundido-amplio img,
.wp-block-columns > .wp-block-column:first-child .wp-block-image.is-style-ipg-fundido-amplio img {
    border-radius: 0;
    -webkit-mask-image: linear-gradient(to right,
        transparent 0%, #000 var(--f),
        #000 calc(100% - var(--f)), transparent 100%);
            mask-image: linear-gradient(to right,
        transparent 0%, #000 var(--f),
        #000 calc(100% - var(--f)), transparent 100%);
}

/* "Flotante, sin difuminar" — la caja despegada del fondo y nada mas.

   Para cuando la foto tiene que verse entera: ningun borde se disuelve, solo
   se redondean las esquinas y se le pone la sombra. Es tambien la opcion
   segura cuando detras de la imagen no hay el mismo fondo que alrededor —
   ahi cualquier difuminado delata la costura (ver la nota de
   .ipg-tabs__panels mas abajo).

   Se repite el selector con :first-child para ganarle a la regla que voltea
   el fundido segun la columna, que si no reintroduciria la mascara. */
.wp-block-image.is-style-ipg-fundido-ninguno img,
.wp-block-columns > .wp-block-column:first-child .wp-block-image.is-style-ipg-fundido-ninguno img {
    border-radius: var(--ipg-radius-lg);
    -webkit-mask-image: none;
            mask-image: none;
}
.wp-block-image.is-style-ipg-fundido-ninguno {
    filter: drop-shadow(0 4px 10px rgba(14, 30, 77, 0.12))
            drop-shadow(0 22px 44px rgba(14, 30, 77, 0.24));
}

/* "Difuminada un lado, flotante" — un solo borde difuminado, y mas suave que
   el de la variante base; los otros tres SIN difuminar, pero despegados del
   fondo para que el corte no choque.

   El fundido, la esquina redondeada y el volteo segun la columna los hereda
   de las reglas de arriba: aqui solo cambia el ancho de la transicion y se
   suma la sombra.

   Dos decisiones sobre esa sombra, las dos obligadas:

   1) Es `filter: drop-shadow` y no `box-shadow`. box-shadow dibuja el
      rectangulo de la caja, asi que asomaria por el lado que justamente se
      esta difuminando. drop-shadow trabaja sobre el canal alfa, de modo que
      la sombra sigue la forma visible y se desvanece con el borde.

   2) Va en la FIGURA y no en la imagen. El orden de pintado es filtro y
      despues mascara: puesta en la img, la mascara recortaria su propia
      sombra y no se veria nada. En la figura, el filtro recibe la imagen ya
      enmascarada y la sombra sale correcta. */
.wp-block-image.is-style-ipg-fundido-suave {
    --f: var(--ipg-fundido-suave);
    /* Dos sombras encadenadas en vez de una. Una sola sombra grande se lee
       como una mancha; el par —una corta y densa justo debajo, otra ancha y
       tenue mas abajo— es como se comporta una sombra real y es lo que hace
       que la foto se despegue de verdad del fondo. */
    filter: drop-shadow(0 4px 10px rgba(14, 30, 77, 0.12))
            drop-shadow(0 22px 44px rgba(14, 30, 77, 0.24));
}

/* "Difuminada flotante" — se funde por los CUATRO bordes.

   Las otras dos dejan rectos los cantos que no difuminan: arriba, abajo y el
   lado contrario. Contra un fondo liso esos tres cortes se notan tanto como
   el que se quiso disolver, y la foto sigue leyendose como un rectangulo
   pegado encima. Aqui no queda ninguno: la foto no tiene caja, flota.

   Son dos mascaras —una horizontal y otra vertical— combinadas con
   mask-composite: intersect, que conserva solo lo que las dos dejan opaco.
   Asi las esquinas se funden dos veces y quedan mas suaves que los lados,
   que es justo lo que hace que no se lea como un rectangulo.

   El porcentaje es menor que en las otras variantes porque se gasta cuatro
   veces; ver la nota de --ipg-fundido-flotante en variables.css.

   Sin border-radius y sin sombra a proposito: donde el borde se disuelve no
   hay canto que redondear, y una sombra dibujaria el rectangulo duro que
   toda esta variante existe para evitar.

   Se repite el selector con :first-child solo para ganarle en especificidad
   a la regla que voltea el fundido de un lado. */
.wp-block-image.is-style-ipg-fundido-flotante {
    --f: var(--ipg-fundido-flotante);
}
.wp-block-image.is-style-ipg-fundido-flotante img,
.wp-block-columns > .wp-block-column:first-child .wp-block-image.is-style-ipg-fundido-flotante img {
    border-radius: 0;
    box-shadow: none;
    -webkit-mask-image:
        linear-gradient(to right,  transparent 0%, #000 var(--f), #000 calc(100% - var(--f)), transparent 100%),
        linear-gradient(to bottom, transparent 0%, #000 var(--f), #000 calc(100% - var(--f)), transparent 100%);
    -webkit-mask-composite: source-in;
            mask-image:
        linear-gradient(to right,  transparent 0%, #000 var(--f), #000 calc(100% - var(--f)), transparent 100%),
        linear-gradient(to bottom, transparent 0%, #000 var(--f), #000 calc(100% - var(--f)), transparent 100%);
            mask-composite: intersect;
}

/* La foto llega hasta abajo, al mismo nivel que el texto de al lado.

   Sin esto la imagen conserva su proporcion y termina donde termina la foto,
   dejando un hueco vacio debajo cuando la columna de texto es mas alta — que
   es casi siempre, porque el texto crece con el contenido y la foto no.

   No hay forma de arreglarlo desde el editor: la altura del texto es
   dinamica y el bloque Imagen solo ofrece alturas fijas, asi que cualquier
   numero que se ponga a mano deja de cuadrar en cuanto se edita el texto.

   Las columnas de WordPress ya se estiran a la misma altura entre si; lo que
   faltaba era que la imagen ocupara la suya. La columna pasa a ser un
   contenedor flex y la figura toma el alto sobrante; `object-fit: cover`
   recorta en vez de deformar la foto.

   El min-height va en la figura y no en la imagen: si fuera en la imagen,
   con una columna corta la foto se saldria de su caja en vez de empujarla. */
.wp-block-column:has(> .wp-block-image[class*="is-style-ipg-fundido"]) {
    display: flex;
    flex-direction: column;
}
.wp-block-column > .wp-block-image[class*="is-style-ipg-fundido"] {
    flex: 1;
    min-height: 260px;
    margin-block: 0;
}
.wp-block-column > .wp-block-image[class*="is-style-ipg-fundido"] img {
    height: 100%;
    object-fit: cover;
}

/* ── Difuminada dentro del "Hero con imagen lateral" ──────────────────────
   La imagen de ese hero trae proporcion fija (16/10), techo de altura
   (380px), esquinas y sombra: pensada para una foto que se lee como TARJETA
   dentro del banner.

   El fundido es lo contrario —una foto que se derrama hacia el texto, sin
   caja— asi que cuando se elige ese estilo hay que soltarle las tres cosas o
   quedan peleando: la proporcion fija impide que llene la columna, el techo
   la corta a 380px y la sombra dibuja el borde que el fundido quiere
   disolver.

   Es el unico sitio del tema donde un estilo de bloque pisa a un componente,
   y es a proposito: quien elige "Difuminada" esta pidiendo justamente que la
   foto deje de ser una tarjeta. */
.ipg-page-hero--split .ipg-page-hero__media[class*="is-style-ipg-fundido"] {
    aspect-ratio: auto;
    max-height: none;
    border-radius: 0;
    box-shadow: none;
}

/* En movil las columnas se apilan (781px es donde las parte WordPress). Un
   fundido lateral ahi ya no significa nada —no hay texto al lado— y solo
   recortaria un cuarto de la foto, asi que se retira y queda la caja limpia.
   La foto tambien recupera su proporcion: sin una columna hermana al lado,
   estirarla a lo alto no igualaria nada y solo la recortaria mas. */
@media (max-width: 781px) {
    /* Solo se retira el fundido de UN lado: sin texto al costado ya no
       significa nada. El de dos lados se queda — es simetrico y sigue
       evitando el canto recto, que se nota igual en un telefono. */
    .wp-block-image[class*="is-style-ipg-fundido"]:not(.is-style-ipg-fundido-amplio):not(.is-style-ipg-fundido-flotante) img,
    .wp-block-columns > .wp-block-column:first-child .wp-block-image[class*="is-style-ipg-fundido"]:not(.is-style-ipg-fundido-amplio):not(.is-style-ipg-fundido-flotante) img {
        border-radius: var(--ipg-radius-lg);
        -webkit-mask-image: none;
                mask-image: none;
    }
    .wp-block-column > .wp-block-image[class*="is-style-ipg-fundido"] {
        flex: none;
        min-height: 0;
    }
    .wp-block-column > .wp-block-image[class*="is-style-ipg-fundido"] img {
        height: auto;
    }
}

@media (max-width: 782px) {
    .ipg-page-hero__media.is-style-ipg-circulo,
    .ipg-page-hero__media.is-style-ipg-recorte { aspect-ratio: 1 / 1; }
}


/* ── La foto COMO fondo del hero ──────────────────────────────────────────
   Para cuando la imagen va de fondo del hero, sin una columna de imagen
   aparte. Tres tratamientos que se eligen en el editor (Estilos), definidos
   en functions.php -> ipg_register_block_styles().

   El problema que resuelven: una foto puesta de fondo tal cual compite con
   el titulo y lo deja ilegible — el texto cae sobre zonas claras y oscuras
   de la misma foto, asi que no hay color de texto que funcione en todas.

   Los tres ponen un velo entre la foto y el texto. Lo que cambia es la forma
   del velo: un lado, todo, o todo en oscuro.

   Como esta hecho: el velo es un ::after con z-index negativo, y el hero
   lleva `isolation: isolate` para crear su propio contexto de apilamiento.
   Asi el velo queda POR ENCIMA de la foto de fondo pero POR DEBAJO del
   texto, sin tener que envolver el contenido en un div extra ni tocar el
   marcado que ya esta publicado.
   ────────────────────────────────────────────────────────────────────── */

.ipg-page-hero.is-style-ipg-fondo-esquina,
.ipg-page-hero.is-style-ipg-fondo-esquina-marino,
.ipg-page-hero.is-style-ipg-fondo-esquina-celeste,
.ipg-page-hero.is-style-ipg-fondo-atenuado,
.ipg-page-hero.is-style-ipg-fondo-oscuro,
.wp-block-group.is-style-ipg-fondo-esquina,
.wp-block-group.is-style-ipg-fondo-esquina-marino,
.wp-block-group.is-style-ipg-fondo-esquina-celeste,
.wp-block-group.is-style-ipg-fondo-atenuado,
.wp-block-group.is-style-ipg-fondo-oscuro {
    position: relative;
    isolation: isolate;
    background-size: cover;
    /* Sin esto, en cuanto alguien cambia el tamano del fondo a "Fijo" desde el
       panel y elige una medida menor que el hero, la foto se repite en
       mosaico. Es justamente lo que hay que hacer para poder correr la imagen
       en horizontal —ver la nota de abajo—, asi que conviene que no tile. */
    background-repeat: no-repeat;
}
.is-style-ipg-fondo-esquina::after,
.is-style-ipg-fondo-esquina-marino::after,
.is-style-ipg-fondo-esquina-celeste::after,
.is-style-ipg-fondo-atenuado::after,
.is-style-ipg-fondo-oscuro::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    /* El velo sigue el radio del bloque, sea cual sea.

       Sin esto, poner esquinas redondeadas desde el editor no se veia: el
       velo es una capa cuadrada que cubre el bloque entero y pintaba sus
       propias esquinas rectas justo encima de las curvas. El radio SI estaba
       aplicado — lo tapaba el velo.

       `inherit` y no un valor fijo: asi vale igual con 4px que con 28px que
       sin radio, y no hay que acordarse de tocar esto al cambiarlo arriba.
       Se prefiere a poner overflow:hidden en el bloque, que ademas recortaria
       cualquier cosa que asome a proposito — una imagen "Desbordada", por
       ejemplo. */
    border-radius: inherit;
}

/* NOTA sobre el punto focal, que da la impresion de estar roto:
   con background-size: cover la imagen se escala hasta cubrir la caja, y por
   definicion UNO de los dos lados encaja exacto y el otro sobra. Solo se
   puede desplazar el lado que sobra.
   Cual sobra depende de las proporciones. El hero es una franja muy ancha
   (~4:1); una foto normal (~1.5:1) es proporcionalmente mucho mas alta, asi
   que al cubrir encaja de ancho y sobra de alto: solo se mueve arriba y
   abajo. Con una foto panoramica pasaria justo al reves.
   Para poder mover los dos ejes hay que salirse de "cubrir": en el panel,
   Fondo -> Tamano -> Fijo, y elegir una medida mayor que el hero. Entonces
   sobra por los dos lados y el punto focal responde en ambos. */

/* ① Foto a un lado — la foto se ancla a la derecha y se va disolviendo hacia
   la izquierda, que es donde vive el titulo. El texto queda sobre blanco
   limpio y la foto respira en su mitad, sin una linea de corte entre ambas.
   Los cuatro pasos del degradado no son decorativos: van opaco - opaco -
   medio - transparente para que la transicion sea larga y no se note el
   borde. Con dos pasos se ve una banda. */
.is-style-ipg-fondo-esquina,
.is-style-ipg-fondo-esquina-marino,
.is-style-ipg-fondo-esquina-celeste {
    background-position: right center;
}
.is-style-ipg-fondo-esquina::after {
    background: linear-gradient(
        90deg,
        #FFFFFF 0%,
        #FFFFFF var(--ipg-velo-solido),
        rgba(255, 255, 255, 0.72) calc((var(--ipg-velo-solido) + var(--ipg-velo-fin)) / 2),
        rgba(255, 255, 255, 0) var(--ipg-velo-fin)
    );
}

/* Las mismas dos variantes en los colores institucionales. Mantienen los
   cuatro pasos del degradado por el mismo motivo que la blanca: con dos se
   ve una banda de corte donde termina el color y empieza la foto.

   El color del TEXTO cambia con el velo y eso no es opcional: sobre el
   marino tiene que ir en blanco (16:1) y sobre el celeste en marino (6.88:1).
   Al reves —marino sobre marino, o blanco sobre celeste— el titulo
   desaparece. Por eso la etiqueta de cada estilo lo dice en el panel. */
.is-style-ipg-fondo-esquina-marino::after {
    background: linear-gradient(
        90deg,
        #0E1E4D 0%,
        #0E1E4D var(--ipg-velo-solido),
        rgba(14, 30, 77, 0.74) calc((var(--ipg-velo-solido) + var(--ipg-velo-fin)) / 2),
        rgba(14, 30, 77, 0) var(--ipg-velo-fin)
    );
}
.is-style-ipg-fondo-esquina-celeste::after {
    background: linear-gradient(
        90deg,
        #13B8E6 0%,
        #13B8E6 var(--ipg-velo-solido),
        rgba(19, 184, 230, 0.74) calc((var(--ipg-velo-solido) + var(--ipg-velo-fin)) / 2),
        rgba(19, 184, 230, 0) var(--ipg-velo-fin)
    );
}

/* ② Foto atenuada — la foto se mantiene a todo el ancho pero muy bajada de
   intensidad, como una textura. Sirve cuando la foto es el ambiente y no el
   protagonista. El texto sigue en marino. */
.is-style-ipg-fondo-atenuado::after {
    background: rgba(255, 255, 255, 0.80);
}

/* ③ Velo oscuro — la foto entera bajo un velo marino, para heroes con el
   texto en blanco. Es el unico de los tres pensado para texto claro.
   El degradado (mas oscuro abajo) ayuda a que los botones al pie tambien se
   despeguen, no solo el titulo. */
.is-style-ipg-fondo-oscuro::after {
    background: linear-gradient(
        180deg,
        rgba(14, 30, 77, 0.72) 0%,
        rgba(14, 30, 77, 0.86) 100%
    );
}

/* En movil la foto no puede quedarse en un lado: la columna ocupa todo el
   ancho y el titulo caeria encima de la parte con foto. El velo pasa a
   cubrir todo, como el atenuado. */
@media (max-width: 782px) {
    .is-style-ipg-fondo-esquina,
    .is-style-ipg-fondo-esquina-marino,
    .is-style-ipg-fondo-esquina-celeste {
        background-position: center;
    }
    /* Velos bastante opacos a proposito: en movil el texto cae sobre toda la
       foto, y no se sabe que foto sera. Un velo tenue funcionaria con una
       imagen clara y dejaria el titulo ilegible con otra. */
    .is-style-ipg-fondo-esquina::after {
        background: rgba(255, 255, 255, 0.86);
    }
    .is-style-ipg-fondo-esquina-marino::after {
        background: rgba(14, 30, 77, 0.86);
    }
    .is-style-ipg-fondo-esquina-celeste::after {
        background: rgba(19, 184, 230, 0.90);
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   SELECTOR DE SEDES — usa el mismo mecanismo de .ipg-tabs (nav horizontal +
   panel visible) definido arriba. Solo agrega estilos para el CONTENIDO de
   cada panel: la ficha de la sede (foto, datos, mapa).

   Estructura esperada dentro de cada .ipg-tabs__panel:
     .ipg-sede
       .ipg-sede__foto        (figure/imagen)
       .ipg-sede__info
         .ipg-sede__nombre    (heading)
         .ipg-sede__ficha
           .ipg-sede__fila × N
             .ipg-sede__label
             .ipg-sede__valor
         .ipg-sede__acciones  (botones)
       .ipg-sede__mapa        (placeholder de mapa embebido)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-sede {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
    gap: var(--ipg-space-10);
    align-items: start;
}
.ipg-sede__foto {
    margin: 0;
    border-radius: var(--ipg-radius-lg);
    overflow: hidden;
    background: var(--ipg-color-surface);
    aspect-ratio: 4 / 3;
}
.ipg-sede__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.ipg-sede__nombre {
    margin: 0 0 var(--ipg-space-4);
    color: var(--ipg-color-primary);
    font-size: var(--ipg-text-2xl);
    font-weight: 700;
}
.ipg-sede__ficha {
    border-top: 1px solid var(--ipg-color-border);
}
.ipg-sede__fila {
    display: flex;
    justify-content: space-between;
    gap: var(--ipg-space-4);
    padding: var(--ipg-space-3) 0;
    border-bottom: 1px solid var(--ipg-color-border);
}
.ipg-sede__label {
    margin: 0;
    flex: 0 0 auto;
    font-size: var(--ipg-text-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ipg-color-text-subtle);
}
.ipg-sede__valor {
    margin: 0;
    text-align: right;
    color: var(--ipg-color-text);
    font-weight: 600;
}
.ipg-sede__acciones {
    margin-top: var(--ipg-space-6);
}
.ipg-sede__mapa {
    grid-column: 1 / -1;
    margin-top: var(--ipg-space-2);
    padding: var(--ipg-space-10);
    text-align: center;
    background: var(--ipg-color-surface);
    border: 1px dashed var(--ipg-color-border-dark);
    border-radius: var(--ipg-radius);
    color: var(--ipg-color-text-subtle);
    font-size: var(--ipg-text-sm);
}
@media (max-width: 782px) {
    .ipg-sede {
        grid-template-columns: 1fr;
    }
    .ipg-sede__valor {
        text-align: left;
    }
    .ipg-sede__fila {
        flex-direction: column;
        gap: var(--ipg-space-1);
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   PASOS NUMERADOS — línea de tiempo vertical con un solo color de marcador
   (naranjo institucional), para reemplazar los círculos de color variable
   que hoy conviven en distintas páginas de proceso (Denuncias, Calidad).

   Estructura esperada:
     .ipg-steps
       .ipg-steps__item × N
         .ipg-steps__marker   (círculo con el número)
         .ipg-steps__body     (heading + párrafo)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-steps {
    display: flex;
    flex-direction: column;
}
.ipg-steps__item {
    position: relative;
    display: grid;
    grid-template-columns: 2.75rem 1fr;
    column-gap: var(--ipg-space-5);
    padding-bottom: var(--ipg-space-8);
}
.ipg-steps__item:last-child {
    padding-bottom: 0;
}
.ipg-steps__item:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 1.375rem;
    top: 2.75rem;
    bottom: 0;
    width: 2px;
    background: var(--ipg-color-border);
    transform: translateX(-1px);
}
.ipg-steps__marker {
    grid-column: 1;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--ipg-radius-full);
    background: var(--ipg-color-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}
.ipg-steps__marker p {
    margin: 0;
    color: var(--ipg-color-text-inverted);
    font-weight: 800;
    font-size: var(--ipg-text-lg);
}
.ipg-steps__body {
    grid-column: 2;
    padding-top: var(--ipg-space-1);
}
.ipg-steps__body h3,
.ipg-steps__body h4 {
    margin: 0 0 var(--ipg-space-1);
    color: var(--ipg-color-primary);
    font-size: var(--ipg-text-lg);
    font-weight: 700;
}
.ipg-steps__body p {
    margin: 0;
    color: var(--ipg-color-text-muted);
}
@media (max-width: 600px) {
    .ipg-steps__item {
        grid-template-columns: 2.25rem 1fr;
        column-gap: var(--ipg-space-4);
    }
    .ipg-steps__marker {
        width: 2.25rem;
        height: 2.25rem;
    }
    .ipg-steps__item:not(:last-child)::before {
        left: 1.125rem;
        top: 2.25rem;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   LÍNEA DE TIEMPO — hitos alternados a izquierda y derecha de un eje central.
   Es el patrón ya logrado en "Nuestra Historia" (1984→2025), reutilizable
   para cualquier contenido cronológico (fases del PED, hitos de acreditación).

   El zigzag NO es decorativo: alterna para que el ojo siga el eje y para que
   cada hito respire. En móvil colapsa a una sola columna con el eje a la
   izquierda, porque a un ancho de teléfono el zigzag se vuelve ilegible.

   Estructura:
     .ipg-timeline
       .ipg-timeline__item × N
         .ipg-timeline__year
         .ipg-timeline__body
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-timeline {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-8);
}
/* Eje central */
.ipg-timeline::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--ipg-color-border);
    transform: translateX(-1px);
}
.ipg-timeline__item {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ipg-space-10);
    align-items: center;
}
/* Punto sobre el eje */
.ipg-timeline__item::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--ipg-color-accent);
    border: 3px solid var(--ipg-color-background);
    transform: translate(-50%, -50%);
    z-index: 1;
}
.ipg-timeline__year {
    margin: 0;
    font-size: var(--ipg-text-4xl);
    font-weight: 800;
    line-height: 1;
    color: var(--ipg-color-primary);
    font-variant-numeric: tabular-nums;
}
.ipg-timeline__body {
    margin: 0;
    color: var(--ipg-color-text-muted);
}
/* Impares: año a la izquierda, texto a la derecha. Pares: al revés. */
.ipg-timeline__item:nth-child(odd) .ipg-timeline__year  { grid-column: 1; text-align: right; }
.ipg-timeline__item:nth-child(odd) .ipg-timeline__body  { grid-column: 2; }
.ipg-timeline__item:nth-child(even) .ipg-timeline__year { grid-column: 2; text-align: left; }
.ipg-timeline__item:nth-child(even) .ipg-timeline__body { grid-column: 1; text-align: right; }

@media (max-width: 782px) {
    .ipg-timeline::before { left: 6px; }
    .ipg-timeline__item {
        grid-template-columns: 1fr;
        gap: var(--ipg-space-2);
        padding-left: var(--ipg-space-8);
    }
    .ipg-timeline__item::before { left: 6px; top: 0.75rem; }
    .ipg-timeline__item:nth-child(odd) .ipg-timeline__year,
    .ipg-timeline__item:nth-child(even) .ipg-timeline__year,
    .ipg-timeline__item:nth-child(odd) .ipg-timeline__body,
    .ipg-timeline__item:nth-child(even) .ipg-timeline__body {
        grid-column: 1;
        text-align: left;
    }
    .ipg-timeline__year { font-size: var(--ipg-text-2xl); }
}

/* ══════════════════════════════════════════════════════════════════════════
   EQUIPO — grilla de personas con foto redonda, cargo y contacto.
   Para consejeros, autoridades o cualquier listado de personas.
   ═══════════════════════════════════════════════════════════════════════ */

/* Una sola regla cubre los dos escenarios de uso, sin container queries
   ni breakpoints de ventana: el ancho MÍNIMO de cada columna es el mayor
   entre 200px y "un cuarto del ancho real de la grilla".

   - Contenedor ancho (Directorio/Autoridades, 5-9 personas): el cuarto
     es mayor que 200px, así que manda el cuarto → exactamente 4 por
     fila. Con auto-fit puro entraban 6-7 y los nombres largos se
     partían en cuatro líneas.
   - Contenedor angosto (el patrón "Equipo de personas" insertado sin
     alinear a "Ancho", con 2-3 personas): el cuarto es menor que 200px,
     así que manda el mínimo → entran las columnas que quepan (3, 2 o 1)
     y se reparten TODO el ancho, sin columna vacía al costado.
   - El min(200px, 100%) evita que en pantallas muy angostas el mínimo
     de 200px desborde el contenedor.

   El intento anterior era container-type + @container sobre .ipg-team,
   pero un contenedor no puede consultar su PROPIO tamaño: la consulta
   nunca se aplicaba, quedaban las 4 columnas fijas y con 3 personas las
   tarjetas medían ~156px dejando una columna vacía a la derecha. */
.ipg-team {
    /* Se define aca, no solo en .ipg-person: una variable declarada en el
       hijo no la ve el padre, y la grilla la necesita para reservar el hueco
       de la foto que sobresale. .ipg-person la hereda.

       156px es ~46% del ancho maximo de tarjeta (340px), la misma proporcion
       que la referencia. Con 112 el retrato quedaba en un tercio y la tarjeta
       se veia vacia alrededor.

       El clamp no es adorno: cuando la tarjeta baja a su minimo (240px, en
       pantallas angostas o con muchas personas en fila), un circulo fijo de
       156px ocuparia dos tercios del ancho y no cabria el nombre. El valor
       medio, 46vw, solo llega a mandar en pantallas de menos de ~340px. */
    --ipg-person-foto: clamp(120px, 46vw, 156px);

    display: grid;
    /* Tope por TARJETA, no por grilla. Es lo que hace que el bloque se vea
       bien en cualquiera de las tres alineaciones de WordPress —que son solo
       tres y no dan un ancho intermedio—: pase lo que pase, una tarjeta nunca
       pasa de 340px ni baja de 240, y lo que sobra queda como aire a los
       lados en vez de estirar las tarjetas.
       auto-fit, no auto-fill: con tres personas se arman tres columnas, no
       cinco con dos vacias. */
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 340px));
    /* La separacion entre FILAS no puede ser la misma que entre columnas: el
       retrato de cada tarjeta sube media foto por encima de ella, asi que con
       16px se montaba sobre la tarjeta del renglon anterior y le tapaba el
       boton. Se reserva media foto mas el mismo respiro.
       No era solo cosa del movil: en escritorio, a partir de la cuarta
       persona, la segunda fila hacia exactamente lo mismo.
       El orden del atajo es fila y luego columna. */
    gap: calc(var(--ipg-person-foto) / 2 + var(--ipg-space-4)) var(--ipg-space-4);
    /* Sitio para la mitad de foto que sobresale de la primera fila. Sin esto
       la foto se saldria hacia arriba y se montaria sobre la bajada. */
    padding-top: calc(var(--ipg-person-foto) / 2);
    /* Las tarjetas se centran en vez de repartirse todo el ancho: con el tope
       de 340px por tarjeta, tres personas en un bloque "Ancho" ocupan ~1050px
       centrados y no 1440 estirados. */
    justify-content: center;
}
/* Columna flex (no bloque) para que, aunque una persona tenga el cargo
   o la unidad más largos que otra, el botón "Escribir" quede alineado
   abajo en todas las tarjetas de la fila. */
.ipg-person {
    /* Respaldo por si la tarjeta se usa suelta, fuera de .ipg-team, que es
       donde vive el valor de referencia. Cuatro reglas dependen de este
       numero —el hueco de la grilla, el relleno de la tarjeta, el tiron de la
       foto y el tamano del circulo—: por eso va en variable y no escrito
       cuatro veces. */
    --ipg-person-foto: clamp(120px, 46vw, 156px);

    display: flex;
    flex-direction: column;
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-lg);
    /* El relleno superior deja pasar la foto: la mitad de abajo del retrato
       cae dentro de la tarjeta y la de arriba queda fuera. */
    padding: calc(var(--ipg-person-foto) / 2 + var(--ipg-space-3)) var(--ipg-space-5) var(--ipg-space-6);
    /* El ritmo vertical lo lleva este gap, no la suma de margenes sueltos.
       Ver el reajuste de margenes justo debajo de la tarjeta. */
    gap: var(--ipg-space-3);
    text-align: center;
    box-shadow: var(--ipg-shadow-sm);
    transition: box-shadow var(--ipg-transition-fast),
                transform var(--ipg-transition-fast);
}
.ipg-person > .wp-block-buttons { margin-top: auto; }
.ipg-person:hover {
    box-shadow: var(--ipg-shadow-md);
    transform: translateY(-3px);
}
/* El retrato sale por arriba de la tarjeta.
   El tiron hacia arriba es el relleno superior MAS media foto. Ojo con esa
   suma: el relleno ya vale media foto mas un respiro, asi que el tiron
   completo equivale a una foto entera mas el respiro. Tirar solo lo que mide
   el relleno deja la foto justo en el borde, sin sobresalir nada.
   El aro blanco no es un borde sino una sombra solida: un borde se sumaria
   al ancho y descuadraria el circulo. */
/* WordPress inyecta 24px de margen superior a CADA hijo de un grupo en flujo.
   Dentro de la tarjeta eso se sumaba a los margenes propios de cada pieza —y
   en flex los margenes no se colapsan, se suman enteros—, asi que entre la
   linea de la ficha y el contacto quedaban 40px: 16 del margen inferior de la
   ficha mas 24 del inyectado.
   Se anula el margen superior de todos los hijos y el ritmo pasa a llevarlo
   el `gap` de la tarjeta, que es uno solo y se ve de un vistazo. El prefijo
   :root iguala la especificidad de la regla del nucleo. */
:root .ipg-person > * {
    margin-block-start: 0;
}

/* El prefijo :root y el hijo directo no son decorativos: suben la
   especificidad a 0-3-0 para ganarle a la regla que WordPress inyecta al
   final del <head>,

       :root :where(.is-layout-flow) > :first-child { margin-block-start: 0 }

   que vale 0-2-0. El retrato es el primer hijo de la tarjeta, asi que esa
   regla le ponia el margen superior en cero y anulaba el tiron: la foto
   caia dentro de la tarjeta, mas abajo que antes en vez de sobresalir.
   Es el mismo motivo por el que el resto del archivo usa el prefijo :root
   en los reajustes de margen. */
:root .ipg-person > .ipg-person__photo {
    margin: calc(-1 * (var(--ipg-person-foto) + var(--ipg-space-3))) auto var(--ipg-space-2);
}
.ipg-person__photo {
    width: var(--ipg-person-foto);
    height: var(--ipg-person-foto);
    flex: 0 0 auto;
    border-radius: 50%;
    overflow: hidden;
    background: var(--ipg-color-surface);
    box-shadow: 0 0 0 6px var(--ipg-color-background),
                0 10px 24px rgba(14, 30, 77, 0.16);
}
/* El tamaño lo manda el círculo, no la imagen. Los !important están para
   ganarle al estilo en línea que Gutenberg escribe si alguien redimensiona
   la foto desde el editor: sin esto, la imagen se sale del círculo. */
.ipg-person__photo img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover;
    display: block;
    border-radius: 50%;
}
.ipg-person__photo,
.ipg-person__photo.is-resized {
    max-width: var(--ipg-person-foto);
}
.ipg-person__role {
    margin: 0;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1.3;
    color: var(--ipg-color-accent);
}
.ipg-person__name {
    margin: 0;
    font-size: var(--ipg-text-lg);
    font-weight: 700;
    line-height: 1.3;
    color: var(--ipg-color-primary);
    text-wrap: balance;
}
/* Una linea separa los datos de la persona del bloque de contacto, como en
   la referencia: ayuda a leer la tarjeta en dos partes en vez de como un
   parrafo corrido. */
.ipg-person__detail {
    margin: 0;
    padding-bottom: var(--ipg-space-4);
    border-bottom: 1px solid var(--ipg-color-border);
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--ipg-color-text-muted);
}
.ipg-person__detail:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: none;
}


/* ── Texto con icono al lado ──────────────────────────────────────────────
   Estilos de parrafo que ponen un icono delante del texto: correo, telefono,
   ubicacion, WhatsApp. Se eligen en el editor (Estilos) y el parrafo se
   escribe normal — si el texto es un enlace, sigue siendo un enlace.

   El icono va como MASCARA y no como imagen de fondo. La diferencia importa:
   una imagen de fondo trae su color dentro del archivo y habria que generar
   una version por cada color del tema; una mascara recorta un bloque de
   `currentColor`, asi que el icono se pinta del mismo color que el texto que
   acompana y cambia solo si el parrafo va en marino, en blanco o en gris.

   Los SVG van incrustados en el propio CSS: nada que subir a la biblioteca,
   nada que se vea borroso en pantallas retina y ninguna peticion extra.
   ────────────────────────────────────────────────────────────────────── */
[class*="is-style-ipg-icono-"]::before {
    content: '';
    display: inline-block;
    /* em, no px: el icono crece y encoge con el texto que acompana. Ver
       --ipg-icono-tam en variables.css. */
    width: var(--ipg-icono-tam);
    height: var(--ipg-icono-tam);
    margin-inline-end: 0.4em;
    /* Baja el icono hasta la linea base optica del texto; sin esto queda
       flotando por encima. Va ligado al tamano: si el icono crece, tiene que
       bajar proporcionalmente o se despega de la linea. */
    vertical-align: calc(var(--ipg-icono-tam) * -0.22);
    background-color: currentColor;
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-size: contain;
            mask-size: contain;
}
/* El icono acompana al texto, no lo describe: un lector de pantalla ya lee
   "enlace: correo@ipg.cl". Al ser un ::before decorativo no se anuncia. */

.is-style-ipg-icono-correo::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='5' width='18' height='14' rx='2'/><path d='m3.6 6.6 8.4 5.9 8.4-5.9'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='5' width='18' height='14' rx='2'/><path d='m3.6 6.6 8.4 5.9 8.4-5.9'/></svg>");
}
.is-style-ipg-icono-telefono::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M6.2 3.5h3.1l1.6 3.9-2 1.2a12 12 0 0 0 5.5 5.5l1.2-2 3.9 1.6v3.1a1.7 1.7 0 0 1-1.9 1.7A16.6 16.6 0 0 1 4.5 5.4a1.7 1.7 0 0 1 1.7-1.9z'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M6.2 3.5h3.1l1.6 3.9-2 1.2a12 12 0 0 0 5.5 5.5l1.2-2 3.9 1.6v3.1a1.7 1.7 0 0 1-1.9 1.7A16.6 16.6 0 0 1 4.5 5.4a1.7 1.7 0 0 1 1.7-1.9z'/></svg>");
}
.is-style-ipg-icono-ubicacion::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 21s7-6 7-11a7 7 0 1 0-14 0c0 5 7 11 7 11z'/><circle cx='12' cy='10' r='2.5'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 21s7-6 7-11a7 7 0 1 0-14 0c0 5 7 11 7 11z'/><circle cx='12' cy='10' r='2.5'/></svg>");
}
.is-style-ipg-icono-whatsapp::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.2A8.8 8.8 0 0 0 4.4 16.4L3.4 20.6l4.3-1.1A8.8 8.8 0 1 0 12 3.2z'/><path d='M9.1 8.1c.2-.5.4-.5.6-.5h.5c.2 0 .4 0 .6.4l.8 1.9c.1.2 0 .4-.1.5l-.5.6c-.1.2-.3.3-.1.6a8 8 0 0 0 3.4 3c.3.1.4 0 .6-.2l.7-.9c.2-.2.3-.2.6-.1l1.8.9c.3.1.4.2.4.4a2 2 0 0 1-1.3 1.6c-.4.1-1 .2-2.9-.7a11 11 0 0 1-4.3-4.1c-.2-.3-.9-1.4-.9-2.6a2.6 2.6 0 0 1 .6-1.6z'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.2A8.8 8.8 0 0 0 4.4 16.4L3.4 20.6l4.3-1.1A8.8 8.8 0 1 0 12 3.2z'/><path d='M9.1 8.1c.2-.5.4-.5.6-.5h.5c.2 0 .4 0 .6.4l.8 1.9c.1.2 0 .4-.1.5l-.5.6c-.1.2-.3.3-.1.6a8 8 0 0 0 3.4 3c.3.1.4 0 .6-.2l.7-.9c.2-.2.3-.2.6-.1l1.8.9c.3.1.4.2.4.4a2 2 0 0 1-1.3 1.6c-.4.1-1 .2-2.9-.7a11 11 0 0 1-4.3-4.1c-.2-.3-.9-1.4-.9-2.6a2.6 2.6 0 0 1 .6-1.6z'/></svg>");
}

/* ── Los 14 iconos restantes ──────────────────────────────────────────────
   Mismo trazo que los cuatro originales —viewBox 24x24, stroke 1.8, puntas
   redondas— para que el conjunto se lea como una familia y no como iconos
   sueltos de sitios distintos.

   Todos van de mascara, asi que heredan el color del texto: el mismo icono
   sale marino en un titulo, blanco sobre un hero oscuro y gris en una bajada,
   sin una version por color.

   PARA AGREGAR OTRO: la regla aqui y su slug en $ipg_iconos (functions.php). */
.is-style-ipg-icono-documento::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/><path d='M14 3v5h5'/><path d='M9 13h6M9 17h6'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z'/><path d='M14 3v5h5'/><path d='M9 13h6M9 17h6'/></svg>");
}
.is-style-ipg-icono-calendario::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><rect x='3.5' y='5' width='17' height='15' rx='2'/><path d='M3.5 10h17M8 3v4M16 3v4'/><path d='M8 14h2M14 14h2M8 17h2M14 17h2'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><rect x='3.5' y='5' width='17' height='15' rx='2'/><path d='M3.5 10h17M8 3v4M16 3v4'/><path d='M8 14h2M14 14h2M8 17h2M14 17h2'/></svg>");
}
.is-style-ipg-icono-reloj::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='8.5'/><path d='M12 7v5.2l3.2 2'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='8.5'/><path d='M12 7v5.2l3.2 2'/></svg>");
}
.is-style-ipg-icono-check::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='8.5'/><path d='M8.2 12.3l2.6 2.6 5-5.4'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='8.5'/><path d='M8.2 12.3l2.6 2.6 5-5.4'/></svg>");
}
.is-style-ipg-icono-estrella::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.6l2.6 5.3 5.8.85-4.2 4.1 1 5.8-5.2-2.75L6.8 19.6l1-5.8-4.2-4.1 5.8-.85z'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.6l2.6 5.3 5.8.85-4.2 4.1 1 5.8-5.2-2.75L6.8 19.6l1-5.8-4.2-4.1 5.8-.85z'/></svg>");
}
.is-style-ipg-icono-escudo::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.2l7 2.6v5.3c0 4.4-2.9 8.2-7 9.7-4.1-1.5-7-5.3-7-9.7V5.8z'/><path d='M9.2 12.1l2 2 3.6-3.9'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.2l7 2.6v5.3c0 4.4-2.9 8.2-7 9.7-4.1-1.5-7-5.3-7-9.7V5.8z'/><path d='M9.2 12.1l2 2 3.6-3.9'/></svg>");
}
.is-style-ipg-icono-balanza::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4v16M7 20h10M12 6.5l6.5 1.6M12 6.5L5.5 8.1'/><path d='M2.6 13.4l2.9-5.3 2.9 5.3a2.9 2.9 0 0 1-5.8 0z'/><path d='M15.6 13.4l2.9-5.3 2.9 5.3a2.9 2.9 0 0 1-5.8 0z'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4v16M7 20h10M12 6.5l6.5 1.6M12 6.5L5.5 8.1'/><path d='M2.6 13.4l2.9-5.3 2.9 5.3a2.9 2.9 0 0 1-5.8 0z'/><path d='M15.6 13.4l2.9-5.3 2.9 5.3a2.9 2.9 0 0 1-5.8 0z'/></svg>");
}
.is-style-ipg-icono-idea::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M9.5 17.6h5M10 20.4h4'/><path d='M12 3.5a5.6 5.6 0 0 0-3.2 10.2c.5.4.8 1 .8 1.6v.3h4.8v-.3c0-.6.3-1.2.8-1.6A5.6 5.6 0 0 0 12 3.5z'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M9.5 17.6h5M10 20.4h4'/><path d='M12 3.5a5.6 5.6 0 0 0-3.2 10.2c.5.4.8 1 .8 1.6v.3h4.8v-.3c0-.6.3-1.2.8-1.6A5.6 5.6 0 0 0 12 3.5z'/></svg>");
}
.is-style-ipg-icono-personas::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.2'/><path d='M3.5 19.5a5.5 5.5 0 0 1 11 0'/><path d='M16 5.3a3.2 3.2 0 0 1 0 5.9'/><path d='M17.6 14.6a5.5 5.5 0 0 1 2.9 4.9'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><circle cx='9' cy='8' r='3.2'/><path d='M3.5 19.5a5.5 5.5 0 0 1 11 0'/><path d='M16 5.3a3.2 3.2 0 0 1 0 5.9'/><path d='M17.6 14.6a5.5 5.5 0 0 1 2.9 4.9'/></svg>");
}
.is-style-ipg-icono-birrete::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4L2 9l10 5 10-5-10-5z'/><path d='M6 11.5V16c0 1.7 2.7 3 6 3s6-1.3 6-3v-4.5'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4L2 9l10 5 10-5-10-5z'/><path d='M6 11.5V16c0 1.7 2.7 3 6 3s6-1.3 6-3v-4.5'/></svg>");
}
.is-style-ipg-icono-edificio::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 21V6a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v15'/><path d='M13 10h6a1 1 0 0 1 1 1v10'/><path d='M3 21h18'/><path d='M7 9h2M7 13h2M7 17h2M16 14h1M16 18h1'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 21V6a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v15'/><path d='M13 10h6a1 1 0 0 1 1 1v10'/><path d='M3 21h18'/><path d='M7 9h2M7 13h2M7 17h2M16 14h1M16 18h1'/></svg>");
}
.is-style-ipg-icono-libro::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 5.5A2.5 2.5 0 0 1 6.5 3H19v15H6.5A2.5 2.5 0 0 0 4 20.5z'/><path d='M4 20.5A2.5 2.5 0 0 1 6.5 18H19v3H6.5'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 5.5A2.5 2.5 0 0 1 6.5 3H19v15H6.5A2.5 2.5 0 0 0 4 20.5z'/><path d='M4 20.5A2.5 2.5 0 0 1 6.5 18H19v3H6.5'/></svg>");
}
.is-style-ipg-icono-descarga::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.5v11'/><path d='M8 11l4 4 4-4'/><path d='M4.5 19.5h15'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3.5v11'/><path d='M8 11l4 4 4-4'/><path d='M4.5 19.5h15'/></svg>");
}
.is-style-ipg-icono-alerta::before {
    -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4.2l8.5 15H3.5z'/><path d='M12 10.2v3.6'/><path d='M12 16.7h.01'/></svg>");
            mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M12 4.2l8.5 15H3.5z'/><path d='M12 10.2v3.6'/><path d='M12 16.7h.01'/></svg>");
}


/* ══════════════════════════════════════════════════════════════════════════
   VIDEO CON GLOBOS — los puntos clave como globos en una fila, y el video
   centrado debajo.

   Estructura esperada (ver el patron "Video con globos"):
     .ipg-globos
       .ipg-globo   x N
     .ipg-globos-video   (el embed, centrado)
   ═══════════════════════════════════════════════════════════════════════ */

/* auto-fit y no un numero fijo de columnas: la fila se adapta a cuantos
   globos haya —tres, cuatro o dos— sin tocar el CSS, y cuando dejan de caber
   pasan solos a una segunda fila en vez de encogerse hasta ser ilegibles. */
.ipg-globos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--ipg-space-4);
    align-items: start;
}
.ipg-globo {
    padding: var(--ipg-space-5);
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    /* Radio grande en tres esquinas y casi recto en la de abajo a la
       izquierda: es lo que hace que se lea como globo sin dibujar una cola
       con pseudo-elementos, que se descuadra en cuanto el texto cambia de
       alto. La esquina seca apunta hacia abajo, al video. */
    border-radius: var(--ipg-radius-xl) var(--ipg-radius-xl) var(--ipg-radius-xl) var(--ipg-radius-sm);
    box-shadow: var(--ipg-shadow-sm);
}
:root .ipg-globos > *,
:root .ipg-globo > * {
    margin-block: 0;
}
:root .ipg-globo > * + * {
    margin-block-start: var(--ipg-space-2);
}

/* El video, centrado y acotado: a todo el ancho del bloque quedaria
   desproporcionado frente a la fila de globos. */
.ipg-globos-video {
    max-width: 720px;
    margin-inline: auto;
    margin-block-start: var(--ipg-space-10);
}
/* El video se centra dentro de su caja.
   WordPress solo estira un embed a lo ancho cuando reconoce su proporcion y
   le pone una clase wp-embed-aspect-* (16:9, 4:3...). Con un video vertical o
   de proporcion rara no la pone, asi que el iframe se queda en su medida
   natural —500px en el caso que motivo esto— y, al ser de linea, se apoya a
   la izquierda de su contenedor.
   text-align centra el iframe porque es un elemento de linea; margin-inline
   auto no le haria nada. */
.ipg-globos-video .wp-block-embed__wrapper {
    text-align: center;
}
.ipg-globos-video iframe {
    /* El video llena el ancho de la caja en vez de quedarse en la medida que
       devuelve YouTube (500px). Con height: auto la altura sale de la
       proporcion, no del atributo del iframe.
       El 16/9 es un respaldo para el caso corriente; assets/js/main.js lee la
       proporcion real de cada video y la corrige si es otra —un vertical, por
       ejemplo—, que si no saldria con franjas negras arriba y abajo. */
    width: 100%;
    max-width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    border-radius: var(--ipg-radius-lg);
    display: block;
}

/* ══════════════════════════════════════════════════════════════════════════
   CITA DESTACADA — frase institucional o testimonio, con atribución.
   Barra de acento a la izquierda en vez de comillas gigantes decorativas.
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-quote {
    border-left: 4px solid var(--ipg-color-accent);
    padding: var(--ipg-space-2) 0 var(--ipg-space-2) var(--ipg-space-6);
}
.ipg-quote__text {
    margin: 0 0 var(--ipg-space-3);
    font-size: var(--ipg-text-xl);
    font-weight: 600;
    line-height: 1.5;
    color: var(--ipg-color-primary);
    text-wrap: balance;
}
.ipg-quote__author {
    margin: 0;
    font-size: var(--ipg-text-sm);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ipg-color-text-subtle);
}

/* ══════════════════════════════════════════════════════════════════════════
   AVISO — bloque de alerta para plazos, suspensiones o información urgente.
   El color comunica el tipo; el ícono y el título lo repiten en texto, para
   que no dependa solo del color (accesibilidad).
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-notice {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--ipg-space-4);
    align-items: start;
    padding: var(--ipg-space-5) var(--ipg-space-6);
    border-radius: var(--ipg-radius);
    border-left: 4px solid var(--ipg-color-info);
    background: var(--ipg-color-info-bg);
}
.ipg-notice--warning { border-left-color: var(--ipg-color-warning); background: var(--ipg-color-warning-bg); }
.ipg-notice--success { border-left-color: var(--ipg-color-success); background: var(--ipg-color-success-bg); }
.ipg-notice--error   { border-left-color: var(--ipg-color-error);   background: var(--ipg-color-error-bg); }
.ipg-notice__icon {
    margin: 0;
    font-size: var(--ipg-text-2xl);
    line-height: 1.2;
}
.ipg-notice__title {
    margin: 0 0 var(--ipg-space-1);
    font-size: var(--ipg-text-base);
    font-weight: 700;
    color: var(--ipg-color-text);
}
.ipg-notice__body {
    margin: 0;
    color: var(--ipg-color-text-muted);
    font-size: var(--ipg-text-sm);
}

/* ══════════════════════════════════════════════════════════════════════════
   LOGOS — fila de convenios, acreditaciones o instituciones asociadas.
   En gris por defecto y a color al pasar el cursor: así la fila se lee como
   un conjunto y no como diez marcas compitiendo entre sí.
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--ipg-space-10);
}
.ipg-logos .wp-block-image {
    margin: 0;
}
.ipg-logos img {
    max-height: 56px;
    width: auto;
    filter: grayscale(1);
    opacity: 0.65;
    transition: filter var(--ipg-transition-fast),
                opacity var(--ipg-transition-fast);
}
.ipg-logos img:hover {
    filter: grayscale(0);
    opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
    .ipg-person,
    .ipg-logos img {
        transition: none;
    }
    .ipg-person:hover {
        transform: none;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   GRILLA DE SEDES CON FICHA EN MODAL — tarjetas con foto y nombre encima;
   al hacer clic se abre la ficha completa de esa sede.

   Estructura:
     .ipg-sedes
       .ipg-sedes__grid
         .ipg-sede-card × N
           .ipg-sede-card__media   (imagen)
           .ipg-sede-card__title   (nombre sobre la foto)
       .ipg-sedes__fichas
         .ipg-sede-ficha × N       (contenido que va a la modal)

   Punto clave: las fichas se ocultan SOLO cuando el JS confirma que puede
   abrirlas (clase .ipg-sedes--con-modal, que agrega main.js). Si el JS no
   corre o el navegador no soporta <dialog>, las fichas siguen visibles en la
   página. Nunca hay información que dependa de JavaScript para existir —
   importa para el buscador y para quien navegue sin scripts.
   ═══════════════════════════════════════════════════════════════════════ */

/* Las 6 sedes en una sola fila, sin desplazamiento lateral y sin saltar a
   una segunda línea.
   El patrón lleva la alineación nativa "Ancho" (alignwide), que en este tema
   equivale a 1440px — el mismo tope que usa la portada (--ipg-container-max),
   para que una página interna no tenga un ancho distinto al del inicio. Sin
   alineación, layout.css lo limitaría a 720px: por eso antes salía angosto.
   Bajo 1280px seis tarjetas quedarían demasiado angostas para leer el
   nombre, así que ahí sí pasan a dos filas de tres, y a dos por fila en
   celular. El padding vertical deja aire para que el hover levante la
   tarjeta sin que se corte. */
.ipg-sedes__grid {
    display: grid;
    /* auto-fit, no un número fijo de columnas: la fila se adapta a cuántas
       sedes haya y al ancho disponible. Con 6 sedes a ancho completo caben
       las 6 en una fila; si el bloque quedara angosto (por ejemplo sin la
       alineación "Ancho"), reparte en dos filas legibles en vez de encoger
       las tarjetas hasta hacerlas ilegibles. */
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--ipg-space-4);
    padding-block: var(--ipg-space-3) var(--ipg-space-4);
}
@media (max-width: 640px) {
    .ipg-sedes__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--ipg-space-3);
    }
}

.ipg-sede-card {
    position: relative;
    display: block;
    aspect-ratio: 3 / 4;
    border-radius: var(--ipg-radius-xl);
    overflow: hidden;
    cursor: pointer;
    /* Fondo oscuro de respaldo: si la foto todavía no está cargada o falla,
       la tarjeta sigue siendo visible y el nombre en blanco se lee igual.
       Sin esto, una imagen rota deja texto blanco sobre fondo blanco. */
    background-color: var(--ipg-color-primary-dark);
    box-shadow: var(--ipg-shadow);
    transition: box-shadow var(--ipg-transition-fast),
                transform var(--ipg-transition-fast);
}
.ipg-sede-card:hover,
.ipg-sede-card:focus-visible {
    box-shadow: var(--ipg-shadow-md);
    transform: translateY(-4px);
}
.ipg-sede-card:focus-visible {
    outline: 3px solid var(--ipg-color-accent);
    outline-offset: 3px;
}

.ipg-sede-card__media {
    margin: 0;
    position: absolute;
    inset: 0;
}
.ipg-sede-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--ipg-transition-slow);
}
.ipg-sede-card:hover .ipg-sede-card__media img {
    transform: scale(1.06);
}

/* Degradado para que el nombre se lea sobre cualquier foto */
.ipg-sede-card::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(17,23,41,0) 45%, rgba(17,23,41,0.85) 100%);
    pointer-events: none;
}

/* El tamaño escala con el ancho de pantalla: con seis tarjetas en fila cada
   una queda angosta, y un título fijo de 24px partiría los nombres largos
   ("Panguipulli") en demasiadas líneas. */
.ipg-sede-card__title {
    position: absolute;
    left: var(--ipg-space-4);
    right: var(--ipg-space-4);
    bottom: var(--ipg-space-4);
    margin: 0;
    z-index: 1;
    color: var(--ipg-color-text-inverted);
    font-size: clamp(1rem, 1.4vw, 1.35rem);
    font-weight: 800;
    line-height: 1.2;
    text-wrap: balance;
}

/* Las fichas solo se ocultan si el JS confirmó que puede abrirlas. */
.ipg-sedes--con-modal .ipg-sedes__fichas {
    display: none;
}
/* Sin JS: se ven como bloques normales, separados entre sí. */
.ipg-sedes__fichas > .ipg-sede-ficha + .ipg-sede-ficha {
    margin-top: var(--ipg-space-10);
    padding-top: var(--ipg-space-10);
    border-top: 1px solid var(--ipg-color-border);
}

/* ── Modal ─────────────────────────────────────────────────────────────── */

/* Centrada en pantalla, vertical y horizontalmente. El navegador centra un
   <dialog> solo en el eje horizontal; `inset: 0` + `margin: auto` lo fija
   también en el vertical, sin importar el alto del contenido. */
.ipg-modal {
    position: fixed;
    inset: 0;
    margin: auto;
    width: min(720px, calc(100vw - 2rem));
    max-height: min(85vh, 900px);
    padding: 0;
    border: none;
    border-radius: var(--ipg-radius-xl);
    background: var(--ipg-color-background);
    color: var(--ipg-color-text);
    box-shadow: 0 24px 64px rgba(17, 23, 41, 0.35);
    overflow: visible;
}
.ipg-modal::backdrop {
    background: rgba(17, 23, 41, 0.6);
}
.ipg-modal__cuerpo {
    padding: var(--ipg-space-10);
    max-height: min(85vh, 900px);
    overflow-y: auto;
    border-radius: inherit;
}
.ipg-modal__cerrar {
    position: absolute;
    top: var(--ipg-space-4);
    right: var(--ipg-space-4);
    /* Sin esto el botón desaparecía bajo el contenido al desplazar la ficha.
       No era falta de "estar encima" sino un empate: el botón es un elemento
       posicionado con z-index automático, y el mapa de la sede también
       (.ipg-sede__ubicacion es position: relative). Cuando dos posicionados
       empatan en z-index, gana el que va después en el DOM — y el JS inserta
       el botón ANTES del cuerpo (dialogo.append(cerrar, cuerpo)), así que
       perdía siempre.
       Un z-index explícito rompe el empate. Se usa el token en vez de un "1"
       suelto para que cualquier contenido que llegue a la ficha más adelante
       —una galería, un vídeo, otro mapa— tampoco pueda taparlo. Dentro de un
       <dialog> abierto con showModal() el valor solo compite con el contenido
       de la propia modal: el diálogo vive en la capa superior del navegador y
       abre su propio contexto de apilamiento. */
    z-index: var(--ipg-z-overlay);
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.75rem;
    line-height: 1;
    color: var(--ipg-color-text-muted);
    background: var(--ipg-color-surface);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-full);
    cursor: pointer;
    transition: background-color var(--ipg-transition-fast),
                color var(--ipg-transition-fast);
}
.ipg-modal__cerrar:hover {
    background: var(--ipg-color-primary);
    color: var(--ipg-color-text-inverted);
}
.ipg-modal__cerrar:focus-visible {
    outline: 3px solid var(--ipg-color-accent);
    outline-offset: 2px;
}

@media (max-width: 600px) {
    .ipg-modal__cuerpo { padding: var(--ipg-space-8) var(--ipg-space-5); }
    .ipg-sede-card__title { font-size: var(--ipg-text-xl); }
}

@media (prefers-reduced-motion: reduce) {
    .ipg-sede-card,
    .ipg-sede-card__media img {
        transition: none;
    }
    .ipg-sede-card:hover,
    .ipg-sede-card:focus-visible {
        transform: none;
    }
    .ipg-sede-card:hover .ipg-sede-card__media img {
        transform: none;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   CORRECCIONES DE LAYOUT DE WORDPRESS EN LOS COMPONENTES DEL TEMA

   1) Márgenes que WordPress agrega a los hijos
   Un grupo con layout "flujo" recibe la clase is-layout-flow, y el CSS del
   núcleo le pone margin-block-start a todos sus hijos MENOS al primero.
   Eso está pensado para contenido apilado, pero dentro de una grilla o un
   flex ese margen desplaza cada elemento dentro de su celda: la primera
   tarjeta queda más arriba que las demás, y las separaciones se suman al
   gap. Acá se anula, porque el espaciado ya lo define `gap`.

   2) Ancho de la grilla de sedes
   Sin alineación, layout.css limita cualquier bloque a 720px y las seis
   sedes no caben en una fila. Se le da el mismo tope que la portada
   (--ipg-container-max) aunque el bloque no tenga la alineación "Ancho"
   guardada — así una página ya armada no depende de recordar ese ajuste.
   Se excluyen alignwide/alignfull para no pisar la elección del editor.
   ═══════════════════════════════════════════════════════════════════════ */

/* El prefijo :root no es decorativo — iguala la especificidad de la regla
   que WordPress inyecta al final del <head>:
       :root :where(.is-layout-flow) > * { margin-block-start: 1.5rem }
   Sin ese prefijo, mi regla empata en especificidad y pierde por ir antes
   en el documento. Con él gana, y los componentes vuelven a espaciarse solo
   con `gap`. Este era el motivo de que las tarjetas del calendario salieran
   tres veces más altas de lo que miden sus contenidos. */
:root .ipg-sedes__grid > *,
:root .ipg-sede-card > *,
:root .ipg-team > *,
:root .ipg-timeline > *,
:root .ipg-timeline__item > *,
:root .ipg-steps > *,
:root .ipg-steps__item > *,
:root .ipg-logos > *,
:root .ipg-sede > *,
:root .ipg-notice > *,
:root .ipg-cal-list > *,
:root .ipg-cal-card > *,
:root .ipg-cal-card__date > *,
:root .ipg-cal-card__body > *,
:root .ipg-cal-card__tags > * {
    margin-block: 0;
}

.entry-content > .ipg-sedes:not(.alignwide):not(.alignfull) {
    max-width: var(--ipg-container-max);
}

/* Mismo caso que la grilla de sedes: el calendario vive en un grupo
   "constrained", así que WordPress le impone 860px a sus hijos y solo caben
   dos tarjetas por fila. Se libera el bloque de pestañas —donde vive la
   grilla— y el texto de arriba conserva su ancho de lectura. */
.entry-content > .ipg-cal:not(.alignwide):not(.alignfull) {
    max-width: var(--ipg-container-max);
}
/* Hay que liberar TODA la cadena, no solo el primer nivel: .ipg-cal y
   .ipg-tabs son grupos "constrained", así que cada uno le impone 860px a
   sus hijos. Con liberar solo .ipg-tabs, el tope reaparecía un nivel más
   abajo, en .ipg-tabs__panels, y las tarjetas quedaban de 154px. */
/* Techo de las liberaciones de ancho: --ipg-container-max en vez de `none`.

   Estas reglas existen para sacar al componente del ancho de lectura de
   860px que WordPress impone a los hijos de un grupo "constrained" — sin
   eso, seis tarjetas de sede no caben en una fila. Pero `none` las dejaba
   SIN NINGÚN tope, y ahí estaba el problema: poner la sección en "Pantalla
   completa" —lo único que estira el fondo de borde a borde— estiraba
   también el contenido a 100vw, y en un monitor ancho las tarjetas quedaban
   enormes.

   Con un techo igual al ancho del sitio, los dos modos hacen lo esperable:
     "Ancho"              → sección y contenido a 1440px (igual que antes)
     "Pantalla completa"  → fondo a sangre, contenido a 1440px centrado
   que es la combinación que casi siempre se quiere en una sección con
   fondo propio.

   Es un cambio inerte por debajo de 1440px: el techo solo llega a aplicar
   cuando la sección es más ancha que eso, o sea únicamente en "Pantalla
   completa" y en pantallas grandes. Nada de lo ya publicado se mueve. */
/* Las pestañas de mes comparten el ancho del resto del calendario.

   Antes este bloque se liberaba hasta --ipg-container-max (1440px) mientras
   el buscador, el título, la bajada y la grilla de tarjetas se quedaban en el
   ancho de lectura (860px). Resultado medido a 1512px de pantalla: la barra
   de meses ocupaba de 134px a 1378px y todo lo demás de 326px a 1186px, así
   que la pestaña del mes arrancaba casi 200px a la izquierda del título y de
   la primera tarjeta. Se leía como un elemento suelto, no como el control de
   la lista que tiene debajo.

   La liberación tenía sentido cuando la grilla de tarjetas también era ancha,
   pero eso ya se revirtió más abajo (.ipg-cal-list vuelve al ancho de
   lectura), así que lo único que quedaba estirado era la barra de meses.
   Ahora los cuatro elementos —buscador, encabezado, meses y tarjetas—
   comparten el mismo borde izquierdo y derecho. */
.ipg-cal > .ipg-tabs,
.ipg-tabs--meses {
    max-width: var(--wp--style--global--content-size, 860px);
    margin-inline: auto;
}
/* La grilla se alinea con el resto del calendario en vez de desbordarlo.
   Estaba en max-width: none —sin tope— así que se estiraba hasta el ancho
   del bloque (1440px) mientras el buscador, el título y las pestañas de mes
   se quedaban en el ancho de lectura que WordPress impone a los hijos de un
   grupo "constrained". Las tarjetas sobresalían por los dos lados y el
   conjunto se veía descuadrado.
   Se usa la variable del propio WordPress, no un 860 escrito a mano: es el
   mismo valor del que salen el buscador y las pestañas, así que si algún día
   cambia el contentSize de theme.json, las dos cosas se mueven juntas. */
.ipg-tabs--meses .ipg-tabs__panels,
.ipg-tabs--meses .ipg-tabs__panel,
.ipg-cal-list {
    max-width: var(--wp--style--global--content-size, 860px);
    margin-inline: auto;
}
/* Los hijos de una grilla necesitan min-width:0 para poder encogerse por
   debajo de su ancho mínimo de contenido; sin esto un título largo desborda
   la tarjeta en vez de partirse en varias líneas. */
.ipg-cal-card__body {
    min-width: 0;
}
.ipg-cal-card__title {
    overflow-wrap: break-word;
}

/* 3) La grilla, liberada del ancho de lectura
   WordPress aplica a los hijos de un grupo "constrained":
     .is-layout-constrained > :where(:not(.alignleft)…) { max-width: 860px }
   Ese tope (contentSize) existe para que un párrafo no se lea a lo ancho de
   toda la pantalla, y para el título y la bajada está bien — por eso se
   dejan como están. Pero a la fila de tarjetas la achicaba a 860px, donde
   solo caben cuatro. Solo la grilla se libera del tope; el texto conserva
   su ancho cómodo de lectura. */
.ipg-sedes > .ipg-sedes__grid {
    max-width: var(--ipg-container-max);
    margin-inline: auto;
}

/* ══════════════════════════════════════════════════════════════════════════
   CALENDARIO ACADÉMICO — actividades en tarjetas compactas, con buscador.

   Cada tarjeta trae la fecha a la izquierda sobre un fondo teñido del color
   de su tipo, y el detalle a la derecha. Se escanea de un vistazo; una tabla
   obliga a leer fila por fila y en celular no entra.

   El tinte se define como color explícito (--cal-tint) en vez de calcularlo
   con color-mix(): dos variables por tipo en lugar de una, a cambio de
   funcionar igual en cualquier navegador y de poder ajustar el tono a ojo
   sin depender de un porcentaje.

   Estructura:
     .ipg-cal                      (envoltorio — el JS le inyecta el buscador)
       .ipg-tabs.ipg-tabs--meses
         .ipg-tabs__panels
           .ipg-tabs__panel
             .ipg-cal-list         (grilla)
               .ipg-cal-card  (+ --feriado / --plazo / --evaluacion / --jornada)
                 .ipg-cal-card__date
                   .ipg-cal-card__month  ("DIC")
                   .ipg-cal-card__day    ("8")
                   .ipg-cal-card__range  ("8 → 14 dic")
                 .ipg-cal-card__body
                   .ipg-cal-card__title
                   .ipg-cal-card__tags
                     .ipg-tag (+ --estudiantes / --docentes / --comunidad)

   El color nunca es la única señal: el título y las etiquetas dicen en
   palabras de qué se trata y a quién aplica.
   ═══════════════════════════════════════════════════════════════════════ */

/* Buscador — lo inyecta assets/js/main.js, no vive en el patrón: es un
   control, no contenido editable. Si el JS no corre no aparece, y las
   tarjetas siguen todas visibles. */
.ipg-cal__search {
    position: relative;
    margin-bottom: var(--ipg-space-6);
}
.ipg-cal__search input {
    width: 100%;
    padding: var(--ipg-space-3) var(--ipg-space-5) var(--ipg-space-3) var(--ipg-space-12);
    font-size: var(--ipg-text-base);
    font-family: inherit;
    color: var(--ipg-color-text);
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-full);
    box-shadow: var(--ipg-shadow-sm);
}
.ipg-cal__search input::placeholder { color: var(--ipg-color-text-subtle); }
.ipg-cal__search input:focus {
    outline: none;
    border-color: var(--ipg-color-primary);
    box-shadow: 0 0 0 3px rgba(34, 84, 245, 0.18);
}
.ipg-cal__search::before {
    content: "";
    position: absolute;
    left: var(--ipg-space-5);
    top: 50%;
    width: 18px;
    height: 18px;
    transform: translateY(-50%);
    background-color: var(--ipg-color-text-subtle);
    -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222.2%22%20stroke-linecap%3D%22round%22%3E%3Ccircle%20cx%3D%2211%22%20cy%3D%2211%22%20r%3D%227%22/%3E%3Cpath%20d%3D%22M20%2020l-3.6-3.6%22/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222.2%22%20stroke-linecap%3D%22round%22%3E%3Ccircle%20cx%3D%2211%22%20cy%3D%2211%22%20r%3D%227%22/%3E%3Cpath%20d%3D%22M20%2020l-3.6-3.6%22/%3E%3C/svg%3E") center / contain no-repeat;
    pointer-events: none;
}
.ipg-cal__empty {
    margin: 0;
    padding: var(--ipg-space-10);
    text-align: center;
    color: var(--ipg-color-text-muted);
    background: var(--ipg-color-surface);
    border-radius: var(--ipg-radius-lg);
}

/* Grilla — tres por fila en escritorio.

   Eran cuatro, de cuando la grilla podía estirarse a 1440px. Hoy el calendario
   se queda en el ancho de lectura (860px), y ahí cuatro tarjetas dejan 159px
   de texto cada una: los títulos del calendario académico, que rondan los 60
   caracteres y llegan a 150, se partían en diez o doce líneas y alguna palabra
   larga ("retroalimentación") se cortaba a la mitad. Medido sobre las 163
   actividades de 2026: con cuatro columnas la tarjeta más alta mide 225px y el
   promedio 99px; con tres, 157px y 70px. */
.ipg-cal-list {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ipg-space-3);
    /* Cada tarjeta mide lo que mide su texto. Sin esto la grilla estira TODAS
       las de una fila a la altura de la más alta, así que una actividad de
       título largo dejaba a sus vecinas convertidas en cajas de color casi
       vacías. */
    align-items: start;
}
/* Los cortes que quedan son los que de verdad hacen falta, cuando las
   tarjetas dejan de caber. */
@media (max-width: 720px) { .ipg-cal-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .ipg-cal-list { grid-template-columns: 1fr; } }

.ipg-cal-card {
    --cal-color: #0E1E4D;
    --cal-tint:  #E8EEFE;
    /* Contexto de posicionamiento del enlace "Agregar a Google Calendar",
       que va anclado a la esquina superior derecha de la tarjeta. */
    position: relative;
    display: grid;
    grid-template-columns: 3.5rem 1fr;
    align-items: stretch;
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius);
    overflow: hidden;
    box-shadow: var(--ipg-shadow-sm);
    transition: box-shadow var(--ipg-transition-fast),
                transform var(--ipg-transition-fast),
                border-color var(--ipg-transition-fast);
}
/* Al pasar el cursor la tarjeta se levanta y toma el color de su tipo. */
.ipg-cal-card:hover {
    transform: translateY(-3px);
    border-color: var(--cal-color);
    box-shadow: var(--ipg-shadow-md);
}
.ipg-cal-card[hidden] { display: none; }

/* Tipos de actividad — se aplican en Ajustes → Avanzado → Clase CSS
   adicional de la tarjeta. Sin clase extra queda el azul institucional. */
.ipg-cal-card--feriado    { --cal-color: #C62828; --cal-tint: #FBE9E9; }
.ipg-cal-card--plazo      { --cal-color: #E65100; --cal-tint: #FDEEE2; }
.ipg-cal-card--evaluacion { --cal-color: #0E1E4D; --cal-tint: #E8EEFE; }
.ipg-cal-card--jornada    { --cal-color: #2E7D32; --cal-tint: #E7F3E8; }

.ipg-cal-card__date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    padding: var(--ipg-space-2) 4px;
    text-align: center;
    background: var(--cal-tint);
}
.ipg-cal-card__month {
    margin: 0;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1.2;
    color: var(--cal-color);
}
.ipg-cal-card__day {
    margin: 0;
    font-size: 1.125rem;
    font-weight: 800;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--cal-color);
}
.ipg-cal-card__range {
    margin: 0;
    font-size: 0.5625rem;
    line-height: 1.2;
    color: var(--ipg-color-text-subtle);
}

.ipg-cal-card__body {
    padding: var(--ipg-space-2) var(--ipg-space-3);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
}
.ipg-cal-card__title {
    margin: 0;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--ipg-color-text);
}
.ipg-cal-card__tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ipg-space-1);
}

/* Esquinas redondeadas de las pestañas de mes.

   Venía puesta a mano en las dos páginas de calendario publicadas (border
   radius 15px en cada pestaña, desde Ajustes → Borde). Al pasar las pestañas
   a generarse solas ese ajuste por bloque ya no existe, así que se sube acá
   para que el calendario se siga viendo igual — y de paso queda igual en
   cualquier página nueva, en vez de depender de que alguien se acuerde de
   repetir el ajuste tres veces.

   15px y no un token del tema porque es el valor exacto que está publicado;
   cae entre --ipg-radius-lg (12px) y --ipg-radius-xl (16px). Si se decide
   alinearlo a un token, es un cambio de una línea acá y se aplica a todo. */
.ipg-tabs--meses .ipg-tabs__tab {
    border-radius: 15px;
}

/* Guardar en Google Calendar — un enlace por tarjeta.

   Es un icono y no un botón con texto porque la tarjeta mide poco más de
   200px de ancho: "Agregar a Google Calendar" ocuparía más espacio que el
   nombre de la actividad. El texto completo viaja en el aria-label, así que
   un lector de pantalla sí lo anuncia entero, con el título de la actividad
   dentro para poder distinguir un enlace de otro.

   No se oculta hasta el hover. En un celular no hay hover, y un enlace que
   solo aparece al pasar el mouse simplemente no existe para la mitad de los
   visitantes. Se queda tenue y se enciende al acercarse o al recibir el foco
   del teclado.

   26px de lado: por sobre los 24px mínimos de área táctil de la WCAG 2.2
   (criterio 2.5.8), que en una tarjeta de este tamaño es el piso real. */
.ipg-cal-card__add {
    position: absolute;
    top: 4px;
    right: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: var(--ipg-radius-sm);
    color: var(--cal-color);
    opacity: 0.38;
    transition: opacity var(--ipg-transition-fast),
                background-color var(--ipg-transition-fast);
}
.ipg-cal-card:hover .ipg-cal-card__add,
.ipg-cal-card__add:hover,
.ipg-cal-card__add:focus-visible {
    opacity: 1;
    background: var(--cal-tint);
}
.ipg-cal-card__add:focus-visible {
    outline: 2px solid var(--cal-color);
    outline-offset: -2px;
}
.ipg-cal-card__add svg {
    display: block;
}
/* Le abre paso al icono para que un título largo no pase por debajo.
   Va con :has() y no suelto en .ipg-cal-card__body para no meterle sangría
   sobrante a una tarjeta antigua escrita a mano, que no lleva el enlace. */
.ipg-cal-card:has(.ipg-cal-card__add) .ipg-cal-card__body {
    padding-right: 1.9rem;
}

/* Calendario sin actividades cargadas.

   Clase propia y no .ipg-cal__empty: ese elemento lo crea el buscador de
   main.js y lo muestra u oculta según la búsqueda. Compartir la clase
   dejaría dos mensajes distintos peleando por el mismo espacio. */
.ipg-cal__sin-datos {
    margin: 0;
    padding: var(--ipg-space-10);
    text-align: center;
    color: var(--ipg-color-text-muted);
    background: var(--ipg-color-surface);
    border-radius: var(--ipg-radius-lg);
}

/* Etiqueta de público — punto de color + texto. El punto da el golpe de
   color; el texto dice a quién aplica sin depender de ese color. */
.ipg-tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    padding: 1px 6px;
    border-radius: var(--ipg-radius-full);
    background: var(--ipg-color-surface);
    color: var(--ipg-color-text-muted);
    font-size: 0.625rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}
.ipg-tag::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}
.ipg-tag--estudiantes { background: #E7F3E8; color: #2E7D32; }
.ipg-tag--docentes    { background: #E8EEFE; color: #0E1E4D; }
.ipg-tag--comunidad   { background: #FDEEE2; color: #E65100; }
.ipg-tag--personal    { background: #F0F0F1; color: #50575E; }

/* Selector de meses — variante compacta de .ipg-tabs: doce pestañas no
   caben con el ancho mínimo de 200px del tabs normal. */
.ipg-tabs--meses .ipg-tabs__nav {
    flex-wrap: nowrap;
    overflow-x: auto;
    border-bottom: 1px solid var(--ipg-color-border);
}
.ipg-tabs--meses .ipg-tabs__tab {
    flex: 0 0 auto;
    min-width: 5.5rem;
    padding: var(--ipg-space-3) var(--ipg-space-4);
    text-align: center;
}
.ipg-tabs--meses .ipg-tabs__tab-title {
    font-size: var(--ipg-text-sm);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.ipg-tabs--meses .ipg-tabs__panels {
    padding: var(--ipg-space-6) 0 0;
    background: transparent;
    border: none;
}
/* Mientras se busca se muestran las coincidencias de todos los meses. */
.ipg-cal.is-searching .ipg-tabs__nav { display: none; }
.ipg-cal.is-searching .ipg-tabs__panel { display: block; }

@media (prefers-reduced-motion: reduce) {
    .ipg-cal-card { transition: none; }
    .ipg-cal-card:hover { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   TEXTO Y LISTA NUMERADA — bloque de dos columnas: a la izquierda el titular
   con su bajada y un botón; a la derecha un panel con pasos numerados.

   Sirve para cualquier contenido que sea una secuencia o un conjunto
   enumerable: el proceso de una denuncia, las etapas de admisión, los ejes
   de un plan. Que la lista viva en un panel aparte deja respirar al titular
   y evita el muro de texto.

   Los números los genera CSS con un contador, no se escriben a mano: al
   duplicar o borrar un ítem la numeración se corrige sola. Un número tipeado
   es un número que tarde o temprano queda desordenado.

   Estructura:
     .ipg-numlist
       .ipg-numlist__intro     (titular + bajada + botón)
       .ipg-numlist__panel
         .ipg-numlist__item × N
           .ipg-numlist__title   (h3 — mantiene el esquema de encabezados)
           (párrafos de descripción)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-numlist {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--ipg-space-12);
    /* start, no center: con muchos pasos el panel crece y el titular
       quedaría flotando al medio con un vacío arriba. Alineado al inicio,
       el titular arranca a la par del primer paso. */
    align-items: start;
}

.ipg-numlist__intro {
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-4);
}
/* Titular grande de peso mixto: lo normal en regular y lo que importa en
   negrita, marcado desde el editor con la barra de formato. */
.ipg-numlist__heading {
    margin: 0;
    font-size: clamp(1.75rem, 3.2vw, 2.5rem);
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--ipg-color-text);
    text-wrap: balance;
}
.ipg-numlist__heading strong,
.ipg-numlist__heading b {
    font-weight: 800;
    color: var(--ipg-color-primary);
}
.ipg-numlist__lead {
    margin: 0;
    max-width: 46ch;
    color: var(--ipg-color-text-muted);
    line-height: 1.6;
}

.ipg-numlist__panel {
    counter-reset: ipg-numlist;
    background: var(--ipg-color-surface);
    border-radius: var(--ipg-radius-lg);
    padding: var(--ipg-space-10);
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-6);
}

.ipg-numlist__item {
    counter-increment: ipg-numlist;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-1);
    padding-left: var(--ipg-space-5);
    /* La línea vertical acompaña todo el ítem: agrupa título y descripción
       como una unidad, y guía el ojo hacia abajo por la secuencia. */
    border-left: 2px solid var(--ipg-color-border);
}
/* El número, arriba y por fuera de la línea. */
.ipg-numlist__item::before {
    content: counter(ipg-numlist, decimal-leading-zero);
    margin-left: calc(var(--ipg-space-5) * -1);
    margin-bottom: var(--ipg-space-2);
    font-size: var(--ipg-text-xl);
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--ipg-color-text-subtle);
}
.ipg-numlist__title {
    margin: 0;
    font-size: var(--ipg-text-sm);
    font-weight: 700;
    line-height: 1.4;
    color: var(--ipg-color-text);
}
.ipg-numlist__item p {
    margin: 0;
    font-size: var(--ipg-text-sm);
    line-height: 1.6;
    color: var(--ipg-color-text-muted);
}

@media (max-width: 900px) {
    .ipg-numlist {
        grid-template-columns: 1fr;
        gap: var(--ipg-space-8);
    }
    .ipg-numlist__panel { padding: var(--ipg-space-6); }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-numlist > *,
:root .ipg-numlist__intro > *,
:root .ipg-numlist__panel > *,
:root .ipg-numlist__item > * { margin-block: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   PASOS EN FILA (patrón "Pasos en fila (proceso horizontal)")

   La misma secuencia que .ipg-numlist pero recorrida hacia el lado: las
   etapas van una junto a otra, unidas por una línea que entra en el hueco
   entre ellas. Sirve cuando lo que importa es ver el proceso completo de un
   vistazo; si cada etapa necesita más de dos o tres líneas, conviene el
   patrón de lista, que le da más ancho a cada una.

   Los números los genera un contador, no se escriben a mano: al duplicar o
   borrar una etapa la numeración se corrige sola.

   El carril tiene overflow-x propio en vez de apilarse en móvil. Es a
   propósito: apilar convertiría el patrón en el que ya existe, y lo que se
   pidió acá es justamente recorrer la información hacia el lado. En pantalla
   angosta se ve una etapa entera y asoma la siguiente — ese recorte es lo
   que avisa de que hay más al costado, sin necesidad de flechas.

   Estructura:
     .ipg-pasos-fila
       .ipg-pasos-fila__intro    (overline + titular + bajada)
       .ipg-pasos-fila__pista    (el carril que se desliza)
         .ipg-pasos-fila__paso × N
           .ipg-pasos-fila__titulo   (h3 — mantiene el esquema de encabezados)
           (párrafos de descripción)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-pasos-fila {
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-10);
}

.ipg-pasos-fila__intro {
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-4);
}
/* Mismo titular de peso mixto que el patrón de lista: lo normal en regular y
   lo que importa en negrita, marcado desde el editor. */
.ipg-pasos-fila__heading {
    margin: 0;
    font-size: clamp(1.75rem, 3.2vw, 2.5rem);
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--ipg-color-text);
    text-wrap: balance;
}
.ipg-pasos-fila__heading strong,
.ipg-pasos-fila__heading b {
    font-weight: 800;
    color: var(--ipg-color-primary);
}
.ipg-pasos-fila__lead {
    margin: 0;
    max-width: 60ch;
    color: var(--ipg-color-text-muted);
    line-height: 1.6;
}

/* El carril. grid-auto-flow: column deja que la cantidad de etapas la decida
   el contenido —no hay un número de columnas escrito en el CSS— y el minmax
   les pone un ancho mínimo legible: por debajo de eso el carril se desborda
   y se desliza, en vez de espachurrar los títulos. */
.ipg-pasos-fila__pista {
    --ipg-pasos-hueco: var(--ipg-space-8);

    display: grid;
    grid-auto-flow: column;
    /* 165px es el ancho al que seis etapas —el caso mas comun— todavia
       entran completas en un monitor, contando los huecos. Con 190px la
       sexta quedaba cortada al borde y parecia un error de maquetacion en
       vez de un carril que se desliza. Por debajo de ese ancho de pantalla
       si se desborda, que es justamente lo que se quiere. */
    grid-auto-columns: minmax(165px, 1fr);
    gap: var(--ipg-pasos-hueco);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    /* Aire para la barra de scroll: sin esto se dibuja encima del texto de
       la última línea de las etapas. */
    padding-bottom: var(--ipg-space-4);
    scrollbar-width: thin;
    scrollbar-color: var(--ipg-color-border) transparent;
}
.ipg-pasos-fila__pista::-webkit-scrollbar { height: 6px; }
.ipg-pasos-fila__pista::-webkit-scrollbar-track {
    background: var(--ipg-color-surface);
    border-radius: var(--ipg-radius-full);
}
.ipg-pasos-fila__pista::-webkit-scrollbar-thumb {
    background: var(--ipg-color-border);
    border-radius: var(--ipg-radius-full);
}
/* Cuando el JS detecta que el carril se desborda le da foco de teclado; el
   anillo tiene que verse, si no el foco existe pero no se nota. */
.ipg-pasos-fila__pista:focus-visible {
    outline: 3px solid var(--ipg-color-accent);
    outline-offset: 4px;
    border-radius: var(--ipg-radius);
}

.ipg-pasos-fila__paso {
    counter-increment: ipg-pasos-fila;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-1);
    /* Deja libre la franja de arriba donde va el número. */
    padding-top: 3.75rem;
    scroll-snap-align: start;
}
/* El contador se resetea en el carril y no en cada etapa. */
.ipg-pasos-fila__pista { counter-reset: ipg-pasos-fila; }

/* El número, en un círculo, arriba a la izquierda de su etapa. */
.ipg-pasos-fila__paso::before {
    content: counter(ipg-pasos-fila, decimal-leading-zero);
    position: absolute;
    top: 0;
    left: 0;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background-color: var(--ipg-color-info-bg);
    color: var(--ipg-color-primary);
    font-size: var(--ipg-text-sm);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
/* La línea que une una etapa con la siguiente. Arranca al borde del círculo
   y se mete en el hueco del grid (de ahí el right negativo), así el trazo no
   se corta entre columna y columna. La última no lleva: una línea que sale
   hacia la nada se lee como que falta un paso. */
.ipg-pasos-fila__paso::after {
    content: '';
    position: absolute;
    top: 21px;
    left: 52px;
    right: calc(var(--ipg-pasos-hueco) * -1);
    height: 2px;
    background-color: var(--ipg-color-border);
}
.ipg-pasos-fila__paso:last-child::after { display: none; }

.ipg-pasos-fila__titulo {
    margin: 0;
    font-size: var(--ipg-text-sm);
    font-weight: 700;
    line-height: 1.4;
    color: var(--ipg-color-text);
}
.ipg-pasos-fila__paso p {
    margin: 0;
    font-size: var(--ipg-text-sm);
    line-height: 1.6;
    color: var(--ipg-color-text-muted);
}

@media (max-width: 900px) {
    .ipg-pasos-fila { gap: var(--ipg-space-8); }
    /* Una etapa entera y un pedazo de la siguiente: ese recorte es lo que
       avisa de que hay mas al costado.

       El ancho va en vw y no en %. Dentro de un contenedor con scroll el
       tamano en linea es indefinido, asi que un porcentaje en
       grid-auto-columns no tiene contra que resolverse y las columnas se
       desplomaban a ~40px (medido). vw sí es una medida definida. */
    .ipg-pasos-fila__pista {
        --ipg-pasos-hueco: var(--ipg-space-6);
        grid-auto-columns: min(72vw, 320px);
        scroll-snap-type: x mandatory;
    }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-pasos-fila > *,
:root .ipg-pasos-fila__intro > *,
:root .ipg-pasos-fila__pista > *,
:root .ipg-pasos-fila__paso > * { margin-block: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   FORMULARIO CON GARANTÍAS — el formulario a un lado y, al otro, lo que la
   persona necesita saber justo antes de enviarlo.

   Las garantías (anonimato, confidencialidad, no represalias) suelen ponerse
   al principio de la página, tres pantallas más arriba. Acá van pegadas al
   formulario a propósito: es en el momento de escribir cuando alguien duda
   de si va a quedar expuesto.

   Estructura:
     .ipg-formsec
       .ipg-formsec__main    (encabezado + el formulario)
       .ipg-formsec__aside   (panel de garantías)
         .ipg-formsec__punto × N
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-formsec {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: var(--ipg-space-10);
    align-items: start;
}

.ipg-formsec__aside {
    background: var(--ipg-color-primary);
    color: var(--ipg-color-text-inverted);
    border-radius: var(--ipg-radius-lg);
    padding: var(--ipg-space-8);
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-5);
    /* Acompaña al formulario mientras se rellena: en uno largo, las
       garantías dejarían de verse justo cuando más pesan. */
    position: sticky;
    top: calc(var(--ipg-header-height) + var(--ipg-space-4));
}
.ipg-formsec__aside-titulo {
    margin: 0;
    font-size: var(--ipg-text-lg);
    font-weight: 700;
    color: var(--ipg-color-text-inverted);
}
.ipg-formsec__punto {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-left: var(--ipg-space-4);
    border-left: 2px solid rgba(255, 255, 255, 0.35);
}
.ipg-formsec__punto-titulo {
    margin: 0;
    font-size: var(--ipg-text-sm);
    font-weight: 700;
    color: var(--ipg-color-text-inverted);
}
.ipg-formsec__punto p {
    margin: 0;
    font-size: var(--ipg-text-sm);
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.85);
}

@media (max-width: 900px) {
    .ipg-formsec {
        grid-template-columns: 1fr;
        gap: var(--ipg-space-8);
    }
    /* En una columna el panel iría antes del formulario y empujaría el
       campo real fuera de pantalla; mejor que quede después, como cierre. */
    .ipg-formsec__aside {
        position: static;
        order: 2;
    }
    .ipg-formsec__main { order: 1; }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-formsec > *,
:root .ipg-formsec__main > *,
:root .ipg-formsec__aside > *,
:root .ipg-formsec__punto > * { margin-block: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   DOCUMENTO LEGAL CON ÍNDICE — política de privacidad, reglamentos, términos.

   Un documento legal se lee distinto a cualquier otra página: nadie lo lee
   de corrido. Se entra buscando una cosa ("¿qué hacen con mi correo?"), se
   lee ese párrafo y se sale. El diseño acompaña eso en vez de pelearlo:

   · Un resumen en lenguaje simple arriba, antes del texto formal. Es lo
     único que la mayoría va a leer, y también lo que un buscador o un
     asistente de IA cita cuando alguien pregunta.
   · Un índice al costado que queda fijo al hacer scroll, con la sección
     actual resaltada. El índice lo arma el JavaScript leyendo los títulos:
     al agregar o quitar una sección se actualiza solo.
   · Cada sección con su propio enlace, para poder mandar a alguien
     directo al punto que le importa.

   Estructura:
     .ipg-legal
       .ipg-legal__nav        (el JS le inyecta el índice)
       .ipg-legal__body
         .ipg-legal__resumen  (callout de lenguaje simple)
         h2 + párrafos × N    (las secciones)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-legal {
    display: grid;
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    gap: var(--ipg-space-12);
    align-items: start;
}

/* ── Índice ───────────────────────────────────────────────────────────── */
.ipg-legal__nav {
    position: sticky;
    top: calc(var(--ipg-header-height) + var(--ipg-space-5));
    max-height: calc(100vh - var(--ipg-header-height) - var(--ipg-space-10));
    overflow-y: auto;
}
.ipg-legal__nav-titulo {
    margin: 0 0 var(--ipg-space-3);
    font-size: var(--ipg-text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ipg-color-text-subtle);
}
.ipg-legal__nav ol {
    list-style: none;
    margin: 0;
    padding: 0;
    border-left: 2px solid var(--ipg-color-border);
}
.ipg-legal__nav li { margin: 0; }
.ipg-legal__nav a {
    display: block;
    padding: var(--ipg-space-2) var(--ipg-space-4);
    margin-left: -2px;
    border-left: 2px solid transparent;
    font-size: var(--ipg-text-sm);
    line-height: 1.4;
    color: var(--ipg-color-text-muted);
    text-decoration: none;
    transition: color var(--ipg-transition-fast),
                border-color var(--ipg-transition-fast);
}
.ipg-legal__nav a:hover {
    color: var(--ipg-color-text);
}
/* La sección en pantalla, resaltada. El borde acompaña al color: quien no
   distingue tonos igual ve qué ítem está activo. */
.ipg-legal__nav a.is-current {
    color: var(--ipg-color-primary);
    border-left-color: var(--ipg-color-primary);
    font-weight: 700;
}
.ipg-legal__nav a:focus-visible {
    outline: 2px solid var(--ipg-color-primary);
    outline-offset: -2px;
}

/* ── Resumen en lenguaje simple ───────────────────────────────────────── */
.ipg-legal__resumen {
    background: var(--ipg-color-info-bg);
    border-left: 4px solid var(--ipg-color-primary);
    border-radius: var(--ipg-radius);
    padding: var(--ipg-space-6) var(--ipg-space-8);
    margin-bottom: var(--ipg-space-10);
}
.ipg-legal__resumen-titulo {
    margin: 0 0 var(--ipg-space-4);
    font-size: var(--ipg-text-lg);
    font-weight: 700;
    color: var(--ipg-color-primary);
}
.ipg-legal__resumen ul {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-3);
}
.ipg-legal__resumen li {
    position: relative;
    padding-left: var(--ipg-space-6);
    font-size: var(--ipg-text-base);
    line-height: 1.55;
    color: var(--ipg-color-text);
}
.ipg-legal__resumen li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ipg-color-primary);
}

/* ── Cuerpo del documento ────────────────────────────────────────────────
   Ancho de lectura acotado: una línea de 1200px de texto legal es donde el
   ojo pierde el renglón al volver. */
.ipg-legal__body {
    max-width: 68ch;
}
.ipg-legal__body h2 {
    /* Deja aire bajo el header fijo al salta a una sección desde el índice. */
    scroll-margin-top: calc(var(--ipg-header-height) + var(--ipg-space-6));
    margin: var(--ipg-space-10) 0 var(--ipg-space-4);
    font-size: var(--ipg-text-xl);
    font-weight: 700;
    line-height: 1.3;
    color: var(--ipg-color-primary);
}
.ipg-legal__body h2:first-child { margin-top: 0; }
.ipg-legal__body p {
    margin: 0 0 var(--ipg-space-4);
    line-height: 1.7;
    color: var(--ipg-color-text-muted);
}
.ipg-legal__body a {
    color: var(--ipg-color-primary);
    text-decoration: underline;
}
.ipg-legal__meta {
    margin: 0 0 var(--ipg-space-6);
    font-size: var(--ipg-text-sm);
    color: var(--ipg-color-text-subtle);
}

@media (max-width: 900px) {
    .ipg-legal {
        grid-template-columns: 1fr;
        gap: var(--ipg-space-6);
    }
    /* En una columna el índice deja de ser útil como barra lateral: pasa a
       ser un bloque plegable arriba del texto. */
    .ipg-legal__nav {
        position: static;
        max-height: none;
        padding: var(--ipg-space-5);
        background: var(--ipg-color-surface);
        border-radius: var(--ipg-radius);
    }
    .ipg-legal__body { max-width: none; }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-legal > *,
:root .ipg-legal__body > *,
:root .ipg-legal__resumen > * { margin-block: 0; }
:root .ipg-legal__body > h2 { margin-block: var(--ipg-space-10) var(--ipg-space-4); }
:root .ipg-legal__body > p { margin-block: 0 var(--ipg-space-4); }

/* ══════════════════════════════════════════════════════════════════════════
   ACCESOS A SECCIONES — tarjetas que llevan a otras páginas.

   La tarjeta COMPLETA es el enlace, no un botón dentro de ella. El truco es
   estirar el enlace del título sobre toda la tarjeta con un ::after
   posicionado: sigue habiendo un solo enlace real en el HTML (bueno para
   lectores de pantalla y para buscadores, que leen "Nuestra Historia" y no
   "Ver más"), pero el área clicable pasa de un botón de 120px a la tarjeta
   entera.

   Eso resuelve el problema de fondo del diseño anterior: la tarjeta parecía
   clicable, invitaba a hacer clic, y solo respondía el botón.

   La flecha se desplaza al pasar el cursor. Es el único adorno, y comunica
   algo real: que esto lleva a otro lado.

   Estructura:
     .ipg-accesos
       .ipg-acceso × N
         .ipg-acceso__titulo   (h3 con el enlace dentro)
         .ipg-acceso__texto
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-accesos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--ipg-space-5);
}

.ipg-acceso {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-2);
    padding: var(--ipg-space-6) var(--ipg-space-6) var(--ipg-space-12);
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-lg);
    box-shadow: var(--ipg-shadow-sm);
    transition: border-color var(--ipg-transition-fast),
                box-shadow var(--ipg-transition-fast),
                transform var(--ipg-transition-fast);
}
.ipg-acceso:hover {
    border-color: var(--ipg-color-primary);
    box-shadow: var(--ipg-shadow-md);
    transform: translateY(-3px);
}
/* El foco se dibuja sobre la tarjeta, no sobre el texto del enlace: quien
   navega con teclado ve el mismo objeto que ve quien usa el mouse. */
.ipg-acceso:focus-within {
    border-color: var(--ipg-color-primary);
    outline: 3px solid var(--ipg-color-accent);
    outline-offset: 3px;
}

.ipg-acceso__titulo {
    margin: 0;
    font-size: var(--ipg-text-lg);
    font-weight: 700;
    line-height: 1.3;
    color: var(--ipg-color-primary);
}
.ipg-acceso__titulo a {
    color: inherit;
    text-decoration: none;
}
/* Acá está el truco: el enlace se estira sobre toda la tarjeta. */
.ipg-acceso__titulo a::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
}
.ipg-acceso__texto {
    margin: 0;
    font-size: var(--ipg-text-sm);
    line-height: 1.6;
    color: var(--ipg-color-text-muted);
}

/* Flecha abajo a la izquierda, alineada con el texto. */
.ipg-acceso::after {
    content: "";
    position: absolute;
    left: var(--ipg-space-6);
    bottom: var(--ipg-space-6);
    width: 26px;
    height: 14px;
    background-color: var(--ipg-color-primary);
    -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2026%2014%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M1%207h23M18%201l6%206-6%206%22/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2026%2014%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M1%207h23M18%201l6%206-6%206%22/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform var(--ipg-transition-fast);
    pointer-events: none;
}
.ipg-acceso:hover::after,
.ipg-acceso:focus-within::after {
    transform: translateX(6px);
}

@media (prefers-reduced-motion: reduce) {
    .ipg-acceso,
    .ipg-acceso::after { transition: none; }
    .ipg-acceso:hover { transform: none; }
    .ipg-acceso:hover::after,
    .ipg-acceso:focus-within::after { transform: none; }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-accesos > *,
:root .ipg-acceso > * { margin-block: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   ANCHOS: liberar los componentes del tope de lectura de WordPress

   WordPress impone a los hijos de todo grupo "constrained":
       .is-layout-constrained > :where(...) { max-width: 860px }
   Ese tope (contentSize) existe para que un párrafo no se lea a lo ancho de
   toda la pantalla, y para el texto está bien. Pero a una grilla o a un
   bloque de dos columnas lo achica sin motivo: con 860px caben tres
   tarjetas donde deberían caber cinco.

   Se libera solo el contenedor del componente; los párrafos y títulos que
   lo rodean conservan su ancho cómodo de lectura.

   El prefijo :root iguala la especificidad de la regla del núcleo (que usa
   :root :where(...)); sin él, mi regla empata y pierde por ir antes en el
   documento.
   ═══════════════════════════════════════════════════════════════════════ */

:root .ipg-accesos,
:root .ipg-numlist,
:root .ipg-pasos-fila,
:root .ipg-formsec,
:root .ipg-legal,
:root .ipg-team,
:root .ipg-timeline,
:root .ipg-logos {
    max-width: var(--ipg-container-max);
    margin-inline: auto;
}

/* ══════════════════════════════════════════════════════════════════════════
   ACCESO CON FOTO — versión compacta: foto de fondo, el nombre encima, y
   nada más. Va dentro de la misma grilla .ipg-accesos.

   Toma el lenguaje visual de las tarjetas de acceso destacado de la portada
   (.highlight-card): así una página interna no estrena un estilo propio
   para hacer lo mismo que ya hace el inicio.

   Sobre el apilado: la foto y el degradado van con z-index negativo dentro
   de un contexto aislado (isolation), en vez de poner el título en absoluto
   con z-index positivo. Suena rebuscado, pero es lo que permite que el
   enlace del título se estire sobre TODA la tarjeta: un ::after con inset:0
   se calcula contra el ancestro posicionado más cercano, y si el título
   estuviera posicionado, se calcularía contra el título — el clic en el
   centro caería en la foto, no en el enlace.

   Estructura:
     .ipg-accesos
       .ipg-acceso-foto × N
         .ipg-acceso-foto__media   (imagen)
         .ipg-acceso-foto__titulo  (h3 con el enlace dentro)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-acceso-foto {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    aspect-ratio: 4 / 3;
    padding: var(--ipg-space-5);
    border-radius: var(--ipg-radius-lg);
    overflow: hidden;
    /* Fondo de respaldo: si la foto no carga, el nombre en blanco se sigue
       leyendo en vez de quedar blanco sobre blanco. */
    background-color: var(--ipg-color-primary-dark);
    box-shadow: var(--ipg-shadow-sm);
    transition: box-shadow var(--ipg-transition-fast),
                transform var(--ipg-transition-fast);
}
.ipg-acceso-foto:hover {
    box-shadow: var(--ipg-shadow-md);
    transform: translateY(-3px);
}
.ipg-acceso-foto:focus-within {
    outline: 3px solid var(--ipg-color-accent);
    outline-offset: 3px;
}

.ipg-acceso-foto__media {
    margin: 0;
    position: absolute;
    inset: 0;
    z-index: -2;
}
.ipg-acceso-foto__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--ipg-transition-slow);
}
.ipg-acceso-foto:hover .ipg-acceso-foto__media img {
    transform: scale(1.06);
}

/* Degradado para que el nombre se lea sobre cualquier foto. */
.ipg-acceso-foto::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(180deg, rgba(17,23,41,0) 40%, rgba(17,23,41,0.85) 100%);
    pointer-events: none;
}

/* Sin position: es lo que permite que el enlace se estire sobre la tarjeta. */
.ipg-acceso-foto__titulo {
    margin: 0;
    font-size: var(--ipg-text-lg);
    font-weight: 800;
    line-height: 1.2;
    color: var(--ipg-color-text-inverted);
    text-wrap: balance;
}
.ipg-acceso-foto__titulo a {
    color: inherit;
    text-decoration: none;
}
.ipg-acceso-foto__titulo a::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
}

/* Distintivo con la flecha, arriba a la derecha — igual que en la portada. */
.ipg-acceso-foto::after {
    content: "";
    position: absolute;
    top: var(--ipg-space-4);
    right: var(--ipg-space-4);
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.9);
    background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23111729%22%20stroke-width%3D%222.2%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M7%2017L17%207M9%207h8v8%22/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 17px;
    transition: transform var(--ipg-transition-fast);
    pointer-events: none;
}
.ipg-acceso-foto:hover::after,
.ipg-acceso-foto:focus-within::after {
    transform: translate(2px, -2px);
}

@media (prefers-reduced-motion: reduce) {
    .ipg-acceso-foto,
    .ipg-acceso-foto__media img,
    .ipg-acceso-foto::after { transition: none; }
    .ipg-acceso-foto:hover { transform: none; }
    .ipg-acceso-foto:hover .ipg-acceso-foto__media img { transform: none; }
    .ipg-acceso-foto:hover::after,
    .ipg-acceso-foto:focus-within::after { transform: none; }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-acceso-foto > * { margin-block: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   EJES ESTRATÉGICOS — tarjetas numeradas, todas visibles a la vez.

   Alternativa a las pestañas para conjuntos cortos. Las pestañas sirven
   cuando cada panel es largo y mostrarlos todos sería un muro de texto;
   con cuatro descripciones de dos líneas, esconderlas detrás de un clic
   solo agrega trabajo y quita la posibilidad de compararlas de un vistazo
   — que es justo lo que alguien quiere hacer con un conjunto de ejes.

   La numeración la genera CSS con un contador: al reordenar o agregar un
   eje no hay que renumerar nada a mano.

   Estructura:
     .ipg-ejes
       .ipg-eje × N
         .ipg-eje__titulo   (h3)
         (párrafo de descripción)
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-ejes {
    counter-reset: ipg-eje;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: var(--ipg-space-5);
}

.ipg-eje {
    counter-increment: ipg-eje;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-3);
    padding: var(--ipg-space-6);
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-lg);
    /* Franja superior de color: identifica al eje sin necesidad de un ícono
       inventado para cada uno. */
    border-top: 3px solid var(--ipg-color-primary);
    box-shadow: var(--ipg-shadow-sm);
}
/* La etiqueta es un párrafo real del patrón (.ipg-eje__etiqueta) para que
   se pueda editar desde el editor: renombrarla a "Pilar 1", "Ámbito A" o
   lo que corresponda. Antes era un ::before con un contador CSS y quedaba
   fuera del alcance de Gutenberg. */
/* Selector con la clase del contenedor para ganarle en especificidad a
   `.ipg-eje p` (0-1-1), que si no impone el gris y el tamaño del cuerpo. */
.ipg-eje .ipg-eje__etiqueta {
    margin: 0;
    font-size: var(--ipg-text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ipg-color-accent);
}
/* Respaldo: si la tarjeta no trae etiqueta —contenido publicado antes de
   este cambio, o alguien que borró el párrafo a propósito— el contador
   sigue numerando sola la serie. */
.ipg-eje:not(:has(.ipg-eje__etiqueta))::before {
    content: "Eje " counter(ipg-eje);
    font-size: var(--ipg-text-xs);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ipg-color-accent);
}
.ipg-eje__titulo {
    margin: 0;
    font-size: var(--ipg-text-base);
    font-weight: 700;
    line-height: 1.35;
    color: var(--ipg-color-primary);
    text-wrap: balance;
}
.ipg-eje p {
    margin: 0;
    font-size: var(--ipg-text-sm);
    line-height: 1.6;
    color: var(--ipg-color-text-muted);
}

/* ══════════════════════════════════════════════════════════════════════════
   HITOS EN LÍNEA — versión horizontal y compacta de la línea de tiempo, para
   series cortas de fechas (la evolución de una política, las versiones de un
   documento, los años de acreditación).

   La línea de tiempo vertical (.ipg-timeline) sirve cuando cada hito tiene
   un párrafo. Cuando solo hay un año y tres palabras, ocupar media pantalla
   por hito es desperdiciar el espacio y esconder la progresión, que es
   justamente lo que se quiere mostrar.

   Estructura:
     .ipg-hitos
       .ipg-hito × N
         .ipg-hito__anio
         .ipg-hito__texto
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-hitos {
    position: relative;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(120px, 1fr);
    gap: var(--ipg-space-4);
    padding-top: var(--ipg-space-6);
    /* Se desplaza de lado si no caben: mejor eso que apretarlos hasta que
       el año no se lea. */
    overflow-x: auto;
}
/* El eje horizontal */
.ipg-hitos::before {
    content: "";
    position: absolute;
    top: 5px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--ipg-color-border);
}

.ipg-hito {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ipg-space-1);
}
.ipg-hito::before {
    content: "";
    position: absolute;
    top: calc(var(--ipg-space-6) * -1 + 1px);
    left: 0;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--ipg-color-accent);
    border: 3px solid var(--ipg-color-surface);
}
.ipg-hito__anio {
    margin: 0;
    font-size: var(--ipg-text-2xl);
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--ipg-color-primary);
}
.ipg-hito__texto {
    margin: 0;
    font-size: var(--ipg-text-sm);
    line-height: 1.45;
    color: var(--ipg-color-text-muted);
}
/* El último hito, destacado: es el vigente. */
.ipg-hito:last-child::before { background: var(--ipg-color-primary); }
.ipg-hito:last-child .ipg-hito__anio { color: var(--ipg-color-accent); }

@media (max-width: 600px) {
    .ipg-hitos {
        grid-auto-flow: row;
        grid-auto-columns: auto;
        padding-top: 0;
        padding-left: var(--ipg-space-6);
    }
    .ipg-hitos::before {
        top: 0;
        bottom: 0;
        left: 5px;
        right: auto;
        width: 2px;
        height: auto;
    }
    .ipg-hito::before { top: 6px; left: calc(var(--ipg-space-6) * -1 + 1px); }
}

/* Contra el margen de flujo del núcleo (:where(.is-layout-flow) > *). */
:root .ipg-ejes > *,
:root .ipg-eje > *,
:root .ipg-hitos > *,
:root .ipg-hito > * { margin-block: 0; }
/* Sin ancho propio: lo decide la alineación elegida en el editor (contenido
   860px / amplio 1440px / completo). Antes había acá un
   `:root .ipg-ejes, :root .ipg-hitos { max-width: 1440px }` que, por pesar
   más que las reglas de alineación del núcleo, dejaba la grilla siempre en
   1440px aunque se eligiera otra cosa. Los patrones traen "amplio" marcado,
   que es el ancho que tenían. */

/* ══════════════════════════════════════════════════════════════════════════
   TRAYECTORIA POR AÑOS — la línea de años arriba, el relato de uno a la vez
   debajo.

   Tercera forma de mostrar una cronología, para el caso que no resuelven las
   otras dos:
     · .ipg-timeline (vertical en zigzag) sirve con pocos hitos de texto
       medio; con nueve párrafos largos genera una página interminable.
     · .ipg-hitos (horizontal compacta) sirve cuando cada hito es un año y
       tres palabras; con párrafos no cabe.
   Acá el arco completo se ve de un vistazo en la franja de años, y el texto
   ocupa el ancho cómodo de una sola columna en vez de repartirse en dos.

   Usa el mecanismo de pestañas del tema (.ipg-tabs, ver assets/js/main.js),
   así que si el JS no corre se muestran todos los años seguidos: la historia
   se lee igual.

   Estructura:
     .ipg-tabs.ipg-tabs--anios
       .ipg-tabs__nav
         .ipg-tabs__tab × N   (con .ipg-tabs__tab-title = el año)
       .ipg-tabs__panels
         .ipg-tabs__panel × N
   ═══════════════════════════════════════════════════════════════════════ */

.ipg-tabs--anios .ipg-tabs__nav {
    position: relative;
    display: flex;
    flex-wrap: nowrap;
    gap: 0;
    overflow-x: auto;
    border-bottom: none;
    padding-top: var(--ipg-space-6);
    padding-bottom: var(--ipg-space-2);
    scrollbar-width: thin;
}
/* El eje que une los años: es lo que hace que se lea como una trayectoria
   y no como una fila de botones sueltos. */
.ipg-tabs--anios .ipg-tabs__nav::before {
    content: "";
    position: absolute;
    top: calc(var(--ipg-space-6) + 5px);
    left: 0;
    right: 0;
    height: 2px;
    background: var(--ipg-color-border);
}

.ipg-tabs--anios .ipg-tabs__tab {
    position: relative;
    flex: 1 0 auto;
    min-width: 5.5rem;
    padding: var(--ipg-space-4) var(--ipg-space-3) var(--ipg-space-2);
    background: transparent;
    border: none;
    text-align: center;
}
/* El punto sobre el eje */
.ipg-tabs--anios .ipg-tabs__tab::before {
    content: "";
    position: absolute;
    top: calc(var(--ipg-space-6) * -1 + 12px);
    left: 50%;
    width: 12px;
    height: 12px;
    margin-left: -6px;
    border-radius: 50%;
    background: var(--ipg-color-border);
    border: 3px solid var(--ipg-color-surface);
    transition: background-color var(--ipg-transition-fast),
                transform var(--ipg-transition-fast);
}
.ipg-tabs--anios .ipg-tabs__tab:hover::before {
    background: var(--ipg-color-primary-light);
}
/* El año activo: punto naranjo más grande y año en azul. Dos señales, no
   solo el color, para que se distinga sin depender de verlo. */
.ipg-tabs--anios .ipg-tabs__tab.is-active::before {
    background: var(--ipg-color-accent);
    transform: scale(1.35);
}
.ipg-tabs--anios .ipg-tabs__tab-title {
    font-size: var(--ipg-text-lg);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ipg-color-text-subtle);
    transition: color var(--ipg-transition-fast);
}
.ipg-tabs--anios .ipg-tabs__tab:hover .ipg-tabs__tab-title {
    color: var(--ipg-color-text);
}
.ipg-tabs--anios .ipg-tabs__tab.is-active .ipg-tabs__tab-title {
    color: var(--ipg-color-primary);
    font-size: var(--ipg-text-2xl);
}
.ipg-tabs--anios .ipg-tabs__tab:focus-visible {
    outline: 3px solid var(--ipg-color-accent);
    outline-offset: -3px;
    border-radius: var(--ipg-radius);
}

/* El relato */
.ipg-tabs--anios .ipg-tabs__panels {
    margin-top: var(--ipg-space-6);
    padding: var(--ipg-space-8) var(--ipg-space-10);
    background: var(--ipg-color-background);
    border: 1px solid var(--ipg-color-border);
    border-radius: var(--ipg-radius-lg);
}
.ipg-tabs--anios .ipg-tabs__panel > * {
    max-width: 70ch;
}
.ipg-tabs--anios .ipg-tabs__panel p {
    margin: 0 0 var(--ipg-space-4);
    line-height: 1.7;
    color: var(--ipg-color-text-muted);
}
.ipg-tabs--anios .ipg-tabs__panel p:last-child { margin-bottom: 0; }
/* Titular del año dentro del panel: repite el año en grande para que, al
   llegar desde un enlace o tras hacer scroll, se sepa qué se está leyendo. */
.ipg-tabs--anios .ipg-tabs__panel h3 {
    margin: 0 0 var(--ipg-space-3);
    font-size: var(--ipg-text-xl);
    font-weight: 700;
    color: var(--ipg-color-primary);
}

@media (max-width: 600px) {
    .ipg-tabs--anios .ipg-tabs__panels {
        padding: var(--ipg-space-6) var(--ipg-space-5);
    }
    .ipg-tabs--anios .ipg-tabs__tab.is-active .ipg-tabs__tab-title {
        font-size: var(--ipg-text-xl);
    }
}
@media (prefers-reduced-motion: reduce) {
    .ipg-tabs--anios .ipg-tabs__tab::before,
    .ipg-tabs--anios .ipg-tabs__tab-title { transition: none; }
}

:root .ipg-tabs--anios {
    max-width: var(--ipg-container-max);
    margin-inline: auto;
}


/* ═══════════════════════════════════════════════════════════════════════════
   HOVER — que la página responda al mouse

   DOS NIVELES, y la diferencia importa:

   1) Lo que SE PUEDE CLICAR —tarjetas de noticia, accesos, sedes, pestañas,
      botones, logos— ya se levanta con sombra, y eso se deja como está.
      Despegarse del papel es la señal universal de "esto responde si haces
      clic", y por eso NO se reparte al resto: una tarjeta que se levanta y
      no lleva a ninguna parte promete algo que no cumple, y el visitante
      termina haciendo clic en el vacío.

   2) Lo que solo SE LEE —línea de tiempo, pasos, ejes, hitos, avisos, citas,
      listas numeradas— recibe un gesto distinto: no se mueve ni se despega,
      pero aparece una sombra corta y su elemento de acento (el año, el
      número, el icono, el retrato) crece un punto. Se nota que la página
      está viva sin prometer un clic que no existe.

   El cursor tampoco cambia en el grupo 2, a propósito: `cursor: pointer`
   sobre algo que no es clicable es la misma promesa rota, dicha de otra
   forma.

   Todo pasa por --ipg-transition (250ms). La regla de prefers-reduced-motion
   de variables.css lo desactiva entero para quien lo pida, así que no hace
   falta contemplarlo aquí.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Bloques con borde neutro: el borde toma el celeste ───────────────────── */
/* La tarjeta de la "Grilla de tarjetas" se despega al pasar el mouse: sube,
   toma sombra y su borde pasa al celeste. Es la unica del grupo estatico que
   se levanta —el resto solo cambia de borde o de color—, por pedido expreso:
   en una grilla de tres, el movimiento es lo que separa la que se esta
   mirando de las otras dos. */
.card {
    transition: border-color var(--ipg-transition),
                box-shadow   var(--ipg-transition),
                transform    var(--ipg-transition);
}
.card:hover {
    border-color: var(--ipg-color-accent);
    box-shadow: var(--ipg-shadow-lg);
    transform: translateY(-6px);
}

/* Los ejes estratégicos llevan una franja marina arriba; esa es su acento. */
.ipg-eje {
    transition: border-top-color var(--ipg-transition),
                box-shadow       var(--ipg-transition);
}
.ipg-eje:hover {
    border-top-color: var(--ipg-color-accent);
    box-shadow: var(--ipg-shadow-sm);
}

/* ── Bloques sin borde, o con borde que SIGNIFICA algo ────────────────────
   El borde izquierdo de .ipg-notice codifica el tipo de aviso (error,
   éxito, advertencia, información) y el de .ipg-quote ya es el celeste:
   teñirlos al pasar el mouse borraría esa información. Reciben solo la
   sombra. */
.ipg-timeline__item,
.ipg-steps__item,
.ipg-hito,
.ipg-notice,
.ipg-quote {
    transition: box-shadow var(--ipg-transition);
}
.ipg-timeline__item:hover,
.ipg-steps__item:hover,
.ipg-hito:hover,
.ipg-notice:hover,
.ipg-quote:hover {
    box-shadow: var(--ipg-shadow-sm);
}

/* ── El elemento de acento crece un punto ─────────────────────────────────
   1.06 y no más: lo justo para que el ojo lo registre. Pasado ese punto
   deja de leerse como "está vivo" y empieza a leerse como un salto. */
.ipg-timeline__year,
.ipg-steps__marker,
.ipg-hito__anio,
.ipg-notice__icon {
    transition: transform var(--ipg-transition);
}
.ipg-timeline__item:hover .ipg-timeline__year,
.ipg-steps__item:hover .ipg-steps__marker,
.ipg-hito:hover .ipg-hito__anio,
.ipg-notice:hover .ipg-notice__icon {
    transform: scale(1.06);
}

/* ── Las pestañas ya cambiaban de fondo, pero de golpe ────────────────────
   Tenían el :hover sin transición, así que el color saltaba en un
   fotograma. Aquí solo se le pone tiempo al cambio que ya existía. */
.ipg-tabs__tab {
    transition: background-color var(--ipg-transition),
                border-color     var(--ipg-transition),
                color            var(--ipg-transition);
}


/* ── Cada punto de la lista numerada, como tarjeta ────────────────────────
   El item ya trae una linea vertical a la izquierda que agrupa titulo y
   descripcion. Al pasar el mouse esa linea se vuelve celeste, el fondo pasa
   a blanco sobre el gris del panel, aparece sombra y el bloque se corre a la
   derecha: el punto se despega de la lista y queda claro cual se esta
   mirando.

   El desplazamiento va en HORIZONTAL, no en vertical, y es deliberado:
   dentro de una lista, correrse hacia el lado se lee como "este es el que
   estoy leyendo"; hacia arriba se leeria como un boton, y estos puntos no
   llevan a ninguna parte.

   El relleno y el radio se declaran tambien en reposo —con el fondo
   transparente— para que la tarjeta aparezca sin que el texto salte de
   sitio. El gap del panel baja de 24 a 8px para compensar el alto que suma
   ese relleno: la lista ocupa mas o menos lo mismo que antes, pero ahora los
   puntos se leen como una pila de tarjetas. */
.ipg-numlist__panel {
    gap: var(--ipg-space-2);
}

.ipg-numlist__item {
    padding-block: var(--ipg-space-3);
    padding-right: var(--ipg-space-4);
    /* Solo las esquinas de la derecha: a la izquierda esta la linea vertical,
       que tiene que seguir siendo recta. */
    border-radius: 0 var(--ipg-radius) var(--ipg-radius) 0;
    background-color: transparent;
    transition: background-color var(--ipg-transition),
                border-color     var(--ipg-transition),
                box-shadow       var(--ipg-transition),
                transform        var(--ipg-transition);
}

.ipg-numlist__item:hover {
    background-color: var(--ipg-color-background);
    border-left-color: var(--ipg-color-accent);
    box-shadow: var(--ipg-shadow-md);
    transform: translateX(4px);
}

/* El numero pasa al celeste y el titulo al marino: el color acompana al
   movimiento en vez de dejarlo solo. */
.ipg-numlist__item::before,
.ipg-numlist__title {
    transition: color var(--ipg-transition);
}
.ipg-numlist__item:hover::before {
    color: var(--ipg-color-accent);
}
.ipg-numlist__item:hover .ipg-numlist__title {
    color: var(--ipg-color-primary);
}


/* ── Linea de tiempo: la fecha y el texto se despegan ─────────────────────
   Aqui no se puede hacer tarjeta del item completo como en la lista
   numerada: el item ocupa las dos columnas y el eje vertical le pasa por el
   medio, asi que una caja envolviendolo cruzaria la linea.

   Se tratan por separado las dos piezas que el item tiene:
     el AÑO  cambia de marino a celeste y crece un punto
     el TEXTO se vuelve tarjeta blanca con sombra
     el PUNTO del eje crece y le sale un halo

   El texto se aparta del eje, no se acerca: en un zigzag el movimiento hacia
   afuera se lee como que ese hito da un paso al frente. Por eso el sentido
   del desplazamiento cambia con la fila —el cuerpo va a la derecha del eje
   en las impares y a la izquierda en las pares. */
.ipg-timeline__body {
    padding: var(--ipg-space-3) var(--ipg-space-4);
    border-radius: var(--ipg-radius);
    background-color: transparent;
    transition: background-color var(--ipg-transition),
                box-shadow       var(--ipg-transition),
                transform        var(--ipg-transition);
}
.ipg-timeline__item:hover .ipg-timeline__body {
    background-color: var(--ipg-color-background);
    box-shadow: var(--ipg-shadow-md);
}
.ipg-timeline__item:nth-child(odd):hover .ipg-timeline__body  { transform: translateX(4px); }
.ipg-timeline__item:nth-child(even):hover .ipg-timeline__body { transform: translateX(-4px); }

/* El año: el color acompana al tamano. El scale ya venia de la tanda
   anterior de hovers; aqui se le suma el cambio de marino a celeste. */
.ipg-timeline__year {
    transition: color var(--ipg-transition),
                transform var(--ipg-transition);
}
.ipg-timeline__item:hover .ipg-timeline__year {
    color: var(--ipg-color-accent);
}

/* El punto del eje: crece y le sale un halo celeste. El halo se hace con
   box-shadow y no con un borde para que no empuje al resto. */
.ipg-timeline__item::before {
    transition: transform var(--ipg-transition),
                box-shadow var(--ipg-transition);
}
.ipg-timeline__item:hover::before {
    transform: translate(-50%, -50%) scale(1.25);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--ipg-color-accent) 28%, transparent);
}

/* En movil el zigzag se convierte en una sola columna pegada al eje: correr
   el texto hacia la izquierda lo metria dentro de la linea. Se queda quieto
   y le basta con la tarjeta. */
@media (max-width: 782px) {
    .ipg-timeline__item:nth-child(odd):hover .ipg-timeline__body,
    .ipg-timeline__item:nth-child(even):hover .ipg-timeline__body {
        transform: none;
    }
}


/* ── Hitos en linea: cada hito se despega ─────────────────────────────────
   Aqui SI se puede hacer tarjeta del hito completo —a diferencia de la linea
   de tiempo en zigzag—, porque cada hito es su propia columna y el eje corre
   por encima, no por el medio.

   El detalle que hay que cuidar es el punto del eje: es un ::before del
   propio hito, asi que al levantar la tarjeta el punto se iria con ella y se
   despegaria de la linea. Se resuelve con una contra-traslacion — el punto
   baja lo mismo que sube la tarjeta— y ademas crece y le sale un halo. La
   tarjeta se levanta, el punto se queda clavado en el eje.

   El relleno va tambien en reposo, con el fondo transparente, para que la
   tarjeta aparezca sin que el texto salte. Y como el punto se posiciona
   contra la caja de relleno, hay que correrlo esos mismos pixeles o dejaria
   de alinearse con el texto. */
.ipg-hitos {
    --ipg-hito-pad: var(--ipg-space-3);
}
.ipg-hito {
    padding: var(--ipg-hito-pad);
    border-radius: var(--ipg-radius);
    background-color: transparent;
    transition: background-color var(--ipg-transition),
                box-shadow       var(--ipg-transition),
                transform        var(--ipg-transition);
}
.ipg-hito::before {
    left: var(--ipg-hito-pad);
    transition: transform var(--ipg-transition),
                box-shadow var(--ipg-transition);
}

.ipg-hito:hover {
    background-color: var(--ipg-color-background);
    box-shadow: var(--ipg-shadow-md);
    transform: translateY(-4px);
}
/* El punto compensa el salto de la tarjeta y se queda sobre la linea. */
.ipg-hito:hover::before {
    transform: translateY(4px) scale(1.25);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--ipg-color-accent) 28%, transparent);
}
/* El ano al celeste y el texto al color principal: el contenido tambien
   responde, no solo la caja. */
.ipg-hito__anio,
.ipg-hito__texto {
    transition: color var(--ipg-transition);
}
.ipg-hito:hover .ipg-hito__anio  { color: var(--ipg-color-accent); }
.ipg-hito:hover .ipg-hito__texto { color: var(--ipg-color-text); }

/* Apilado: el eje pasa a la izquierda y el punto vive fuera del hito, asi
   que su desplazamiento se calcula desde ahi, sumandole el relleno. */
@media (max-width: 782px) {
    .ipg-hito::before {
        left: calc(var(--ipg-space-6) * -1 + 1px + var(--ipg-hito-pad));
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
   Lista dentro de un panel de pestañas: de muro de texto a rejilla de fichas

   El problema no era el contenido sino la forma: cuatro parrafos largos en
   una sola columna, uno debajo de otro, sin nada donde apoyar la vista. El
   ojo no encuentra por donde entrar y salta el bloque entero.

   La rejilla lo parte en fichas de dos columnas, y el <strong> con el que ya
   empieza cada punto —"Etica y valores aplicados:"— pasa a ser el titulo de
   su ficha en vez de un trozo mas de parrafo. Con eso se puede escanear la
   lista sin leerla.

   Todo esto se consigue SIN tocar el contenido: la lista sigue siendo un
   bloque de lista normal de WordPress, se sigue editando igual, y las
   paginas ya publicadas cambian solas. Se acota a `> ol` hijo directo del
   panel para no alcanzar a las listas que puedan ir dentro de otra cosa.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Cuando el panel lleva la rejilla de fichas, el contenedor suelta su caja
   blanca: si no, quedaba un blanco sobre otro blanco y las fichas dejaban de
   distinguirse. Ahora el lienzo de la pagina hace de fondo y cada ficha se
   recorta contra el.

   Se acota con :has() a los paneles que efectivamente traen la rejilla — los
   demas usos de .ipg-tabs (sedes, calendario, trayectoria) conservan su caja.
   Los valores son los mismos que ya usa .ipg-tabs--meses, para no inventar
   una tercera forma de quitar el marco. */
/* Y lo mismo cuando el panel contiene una foto "Difuminada", por un motivo
   distinto pero con el mismo remedio.

   Una mascara no pinta: vuelve transparente. Asi que el borde difuminado no
   se funde con "el fondo de la pagina", sino con lo que haya JUSTO detras —y
   aqui detras estaba este panel, blanco. La foto se desvanecia hacia blanco
   mientras alrededor la seccion era gris, y ese desajuste se leia como una
   franja blanca marcada al borde de la imagen: mas visible, no menos, que el
   corte recto que el fundido venia a disimular.

   Sin la caja blanca, la foto se funde con el gris del lienzo, que es contra
   lo que se la ve. */
.ipg-tabs__panels:has(> .ipg-tabs__panel > ol.wp-block-list),
.ipg-tabs__panels:has(.wp-block-image[class*="is-style-ipg-fundido"]) {
    background: transparent;
    border: none;
    padding: var(--ipg-space-6) 0 0;
}

.ipg-tabs__panel > ol.wp-block-list {
    counter-reset: ipg-panel;
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
    gap: var(--ipg-space-4);
}

.ipg-tabs__panel > ol.wp-block-list > li {
    counter-increment: ipg-panel;
    position: relative;
    overflow: hidden;
    margin: 0;
    padding: var(--ipg-space-5);
    background: var(--ipg-color-background);
    border-radius: var(--ipg-radius);
    border-left: 3px solid var(--ipg-color-border);
    font-size: var(--ipg-text-sm);
    line-height: 1.6;
    color: var(--ipg-color-text-muted);
    transition: background-color var(--ipg-transition),
                border-color     var(--ipg-transition),
                box-shadow       var(--ipg-transition),
                transform        var(--ipg-transition);
}

/* El numero, grande y desvaido, al fondo de la ficha. Da jerarquia y sentido
   de secuencia sin gastar una linea de texto. */
.ipg-tabs__panel > ol.wp-block-list > li::before {
    content: counter(ipg-panel, decimal-leading-zero);
    position: absolute;
    right: var(--ipg-space-2);
    bottom: -0.3em;
    font-size: var(--ipg-text-5xl);
    font-weight: 800;
    line-height: 1;
    color: var(--ipg-color-primary);
    opacity: 0.07;
    pointer-events: none;
    font-variant-numeric: tabular-nums;
    transition: color var(--ipg-transition), opacity var(--ipg-transition);
}

/* El "Titulo:" en negrita con el que ya empieza cada punto se convierte en
   el titulo de la ficha. No hay que reescribir nada: ya estaba ahi. */
.ipg-tabs__panel > ol.wp-block-list > li > strong {
    display: block;
    margin-bottom: var(--ipg-space-2);
    font-size: var(--ipg-text-base);
    line-height: 1.3;
    color: var(--ipg-color-primary);
}

/* La ficha ya es blanca en reposo, asi que el hover no puede distinguirse
   por el fondo: lo llevan la sombra, el borde y el salto. */
.ipg-tabs__panel > ol.wp-block-list > li:hover {
    border-left-color: var(--ipg-color-accent);
    box-shadow: var(--ipg-shadow-lg);
    transform: translateY(-4px);
}
.ipg-tabs__panel > ol.wp-block-list > li:hover::before {
    color: var(--ipg-color-accent);
    opacity: 0.2;
}

/* ── Entrada escalonada al cambiar de pestaña ─────────────────────────────
   Las fichas no aparecen de golpe: entran una detras de otra. Eso da la
   sensacion de que la pestaña "carga" y, de paso, guia el orden de lectura.

   El modo de relleno es `backwards` y NO `both`: con `both` el ultimo
   fotograma (transform: none) se queda pegado al elemento y anula el
   translateY del hover. Con `backwards` solo se aplica el estado inicial
   durante el retardo, y al terminar la ficha vuelve a sus estilos normales.

   La regla de prefers-reduced-motion de variables.css desactiva esto entero
   para quien lo pida. */
@keyframes ipg-panel-entra {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}
.ipg-tabs__panel.is-active > ol.wp-block-list > li {
    animation: ipg-panel-entra 380ms ease backwards;
}
.ipg-tabs__panel.is-active > ol.wp-block-list > li:nth-child(1) { animation-delay: 0ms; }
.ipg-tabs__panel.is-active > ol.wp-block-list > li:nth-child(2) { animation-delay: 70ms; }
.ipg-tabs__panel.is-active > ol.wp-block-list > li:nth-child(3) { animation-delay: 140ms; }
.ipg-tabs__panel.is-active > ol.wp-block-list > li:nth-child(4) { animation-delay: 210ms; }
.ipg-tabs__panel.is-active > ol.wp-block-list > li:nth-child(5) { animation-delay: 280ms; }
.ipg-tabs__panel.is-active > ol.wp-block-list > li:nth-child(6) { animation-delay: 350ms; }


/* ═══════════════════════════════════════════════════════════════════════════
   Pestañas laterales — mas cuerpo en las dos columnas

   Que estaba pasando. La pestaña activa se marcaba con un gris casi igual al
   del hover, asi que costaba saber cual estaba abierta; y el panel de la
   derecha no era nada — texto suelto flotando sobre el fondo. Las dos
   columnas se leian como dos listas sin relacion en vez de un componente.

   Que cambia:
     · la activa pasa a marino con texto blanco, como en las horizontales
     · el panel se vuelve tarjeta, con su numero grande de marca de agua
     · el panel entra deslizandose al cambiar de pestaña
     · se retira la linea divisoria: con la tarjeta ya sobra
   ═══════════════════════════════════════════════════════════════════════════ */

/* La divisoria vertical sobraba en cuanto el panel tiene caja propia: dos
   separadores para lo mismo. */
.ipg-tabs--laterales .ipg-tabs__nav {
    border-right: none;
}

.ipg-tabs--laterales .ipg-tabs__tab {
    border-left: 3px solid transparent;
    border-radius: var(--ipg-radius) 0 0 var(--ipg-radius);
    transition: background-color var(--ipg-transition),
                border-color     var(--ipg-transition),
                transform        var(--ipg-transition);
}
.ipg-tabs--laterales .ipg-tabs__tab:hover {
    background: var(--ipg-color-surface);
    transform: translateX(3px);
}

/* La activa, en marino. El gris anterior era casi el mismo que el del hover,
   asi que al pasar el mouse por otra pestaña parecia que se habia cambiado
   de seccion sin haber hecho clic. */
.ipg-tabs--laterales .ipg-tabs__tab.is-active,
.ipg-tabs--laterales .ipg-tabs__tab.is-active:hover {
    background: var(--ipg-color-primary);
    border-left-color: var(--ipg-color-accent);
    border-bottom-color: transparent;
    transform: none;
}
.ipg-tabs--laterales .ipg-tabs__tab.is-active .ipg-tabs__tab-title {
    color: var(--ipg-color-text-inverted);
}
.ipg-tabs--laterales .ipg-tabs__tab.is-active .ipg-tabs__tab-eyebrow {
    color: var(--ipg-color-accent);
}

/* ── El panel, con caja propia ───────────────────────────────────────────── */
.ipg-tabs--laterales .ipg-tabs__panel.is-active {
    position: relative;
    overflow: hidden;
    padding: var(--ipg-space-8);
    background: var(--ipg-color-background);
    border-radius: var(--ipg-radius-lg);
    box-shadow: var(--ipg-shadow-sm);
    animation: ipg-lateral-entra 420ms ease backwards;
}

/* El numero de la seccion, grande y desvaido al fondo. Da algo que mirar al
   espacio sobrante y ata el panel a la pestaña de la que salio.

   Va por :nth-child y no por un contador CSS: los paneles cerrados llevan
   display:none y los elementos sin caja no incrementan contadores, asi que
   el activo siempre habria dicho "01". */
.ipg-tabs--laterales .ipg-tabs__panel::before {
    position: absolute;
    right: var(--ipg-space-4);
    bottom: -0.3em;
    font-size: 7rem;
    font-weight: 800;
    line-height: 1;
    color: var(--ipg-color-primary);
    opacity: 0.06;
    pointer-events: none;
    font-variant-numeric: tabular-nums;
}
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(1)::before { content: '01'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(2)::before { content: '02'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(3)::before { content: '03'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(4)::before { content: '04'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(5)::before { content: '05'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(6)::before { content: '06'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(7)::before { content: '07'; }
.ipg-tabs--laterales .ipg-tabs__panel:nth-child(8)::before { content: '08'; }

/* Entra deslizandose desde la pestaña, no aparece de golpe: el movimiento
   dice de donde viene el contenido.
   `backwards` y no `both`, por lo mismo que en la rejilla de fichas — con
   `both` el ultimo fotograma se queda fijado y bloquea cualquier transform
   posterior. */
@keyframes ipg-lateral-entra {
    from { opacity: 0; transform: translateX(14px); }
    to   { opacity: 1; transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   FOTO DE FONDO SOLO EN ESCRITORIO — clase .ipg-foto-solo-escritorio

   Se pone a mano en el bloque (Ajustes → Avanzado → Clases CSS adicionales)
   cuando su fondo es una FOTO y encima va texto.

   El problema que resuelve: una caja con fondo en modo "Cubrir" cambia de
   proporcion con la pantalla. El banner "¿Necesitas orientacion?" de la
   portada, por ejemplo, va de 3,54:1 en un monitor a 0,53:1 en un telefono
   —casi siete veces—, asi que en el telefono el navegador tiene que ampliar
   la foto hasta que solo cabe un 15% de su ancho. El resultado es un primer
   plano de una cara justo debajo del texto: ilegible.

   Debajo de 900px, entonces, la foto se retira y queda el color de fondo.
   No es una perdida: a ese tamaño la foto ya no comunicaba nada, y el texto
   pasa a leerse sobre un fondo plano.

   El corte va en 900px y no en los 768px habituales del tema porque la foto
   deja de funcionar antes de llegar al breakpoint de movil: medido, a 834px
   de pantalla ya solo se ve un 36% de su ancho.

   Dos detalles de implementacion:

   - El !important es obligatorio. WordPress escribe background-image en el
     atributo style del bloque, y un estilo en linea le gana a cualquier hoja
     de estilos si no se marca.

   - El color de respaldo solo se aplica si el bloque NO trae uno propio
     (:not(.has-background), la clase que agrega WordPress cuando se elige un
     color en el panel). Sin ese respaldo el bloque quedaria transparente y el
     texto blanco desapareceria sobre el lienzo claro; y sin el :not, esta
     regla pisaria el color que se haya elegido a mano.

   No tiene contraparte en editor.css a proposito: las media queries de ese
   archivo responden al ancho real del navegador, no al del dispositivo que
   simula la vista previa de Gutenberg, asi que una copia aca se activaria
   cuando no corresponde. Para ver el efecto hay que mirar el sitio publicado.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
    .ipg-foto-solo-escritorio {
        background-image: none !important;
    }
    .ipg-foto-solo-escritorio:not(.has-background) {
        background-color: var(--ipg-color-primary);
    }
}


/* ══════════════════════════════════════════════════════════════════════════
   MÓVIL — TEXTO CLARO SOBRE FOTO

   En una sección de dos columnas con foto de fondo, el texto se escribe a un
   lado y la foto se encuadra para que ese lado quede despejado. Al apilarse
   las columnas en móvil, el texto se corre al centro y cae justo encima de
   lo que la foto tiene lleno — caras, normalmente. Deja de leerse, y no es
   un problema de tamaño sino de contraste.

   El velo se aplica solo donde puede pasar eso: una sección con imagen de
   fondo que además contiene texto blanco. Una sección con foto y texto
   oscuro no se toca (oscurecerla la empeoraría), y el hero de página tampoco,
   que ya trae su propio tratamiento de fondo.

   Es solo hasta 782px: en desktop el encuadre funciona y el velo apagaría
   una foto que hoy se ve bien.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 782px) {
    .wp-block-group[style*="background-image"]:not(.ipg-page-hero):has(.has-white-color) {
        position: relative;
        /* Crea contexto de apilamiento propio: así el z-index negativo del
           velo lo deja bajo el texto pero sobre la foto, sin escaparse a
           capas de más arriba de la página. */
        isolation: isolate;
    }
    .wp-block-group[style*="background-image"]:not(.ipg-page-hero):has(.has-white-color)::before {
        content: "";
        position: absolute;
        inset: 0;
        z-index: -1;
        border-radius: inherit;
        background: linear-gradient(
            180deg,
            rgba(9, 17, 40, 0.55) 0%,
            rgba(9, 17, 40, 0.78) 100%
        );
    }
}


/* ════════════════════════════════════════════════════════════════════════
   DOCUMENTO — ficha de un PDF institucional (single-ipg_document.php)

   Estructura:
     .ipg-doc
       .ipg-doc__header
         .ipg-doc__eyebrow    (tipo: Reglamento, Resolución…)
         .ipg-doc__title      (h1)
         .ipg-doc__meta       (año · PDF · peso)
         .ipg-doc__acciones   (descargar + abrir en pestaña nueva)
       .ipg-doc__descripcion  (opcional, el editor del post)
       .ipg-doc__visor        (<object> con el PDF)
   ════════════════════════════════════════════════════════════════════════ */

.ipg-doc {
    padding-block: var(--ipg-space-12) var(--ipg-space-16);
}

/* Ancho propio, ni el de artículo ni el del sitio completo.
   --ipg-container-content (720px) está pensado para prosa y deja el visor
   tan angosto que un reglamento se lee con lupa; --ipg-container-max
   (1440px) estira el título en una línea larguísima. 980px es el punto
   donde la página del PDF se ve cómoda y el encabezado sigue siendo legible. */
.ipg-doc__article {
    max-width: 980px;
    margin-inline: auto;
}

.ipg-doc__header {
    margin-bottom: var(--ipg-space-8);
}

/* Ficha en píldora, igual que .news-card__category, y NO como .overline.
   La overline del sitio pinta el texto en celeste sobre blanco: 2.33:1, por
   debajo del 4.5:1 que pide WCAG AA para texto pequeño — el propio
   variables.css lo advierte para los fondos de acento. Aquí el celeste
   pasaría a marcar el tipo de documento, que es justo el dato que alguien
   busca con la vista al llegar, así que va en blanco sobre marino (16:1). */
.ipg-doc__eyebrow {
    display: inline-block;
    margin: 0 0 var(--ipg-space-3);
    padding: 2px var(--ipg-space-3);
    border-radius: var(--ipg-radius-full);
    background: var(--ipg-color-primary);
    color: #fff;
    font-size: var(--ipg-text-xs);
    font-weight: var(--ipg-weight-semibold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.ipg-doc__title {
    /* Los títulos de reglamento son largos de verdad ("Protocolo de
       Investigación y Sanción del Acoso Sexual, Violencia y Discriminación
       de Género"). Escala fluida y balance para que no queden viudas ni se
       parta una palabra a la mitad en móvil. */
    margin: 0 0 var(--ipg-space-3);
    color: var(--ipg-color-primary);
    font-size: clamp(1.75rem, 4vw, 2.75rem);
    line-height: 1.15;
    text-wrap: balance;
    hyphens: auto;
}

.ipg-doc__meta {
    margin: 0 0 var(--ipg-space-6);
    color: var(--ipg-color-text-muted, #5a6478);
    font-size: var(--ipg-text-sm);
}

.ipg-doc__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ipg-space-3);
}

/* El botón principal lleva el peso del archivo dentro. Se atenúa para que
   el ojo lea primero la acción ("Descargar PDF") y el dato quede de apoyo. */
.ipg-doc__peso {
    font-weight: var(--ipg-weight-normal, 400);
    opacity: 0.8;
}

/* En móvil los dos botones ocupan el ancho completo y se apilan: puestos en
   fila quedaban en dos líneas partidas y con áreas táctiles muy angostas. */
@media (max-width: 480px) {
    .ipg-doc__acciones { flex-direction: column; }
    .ipg-doc__acciones .btn { width: 100%; }
}

.ipg-doc__descripcion {
    margin-bottom: var(--ipg-space-8);
}

/* ── Visor ──────────────────────────────────────────────────────────────
   Alto en vh y no en px: el visor debe caber en la pantalla junto con el
   encabezado, y una altura fija en píxeles o deja media pantalla vacía en
   un monitor grande o desborda en un portátil. El mínimo evita que en
   ventanas muy bajas quede una rendija ilegible. */
.ipg-doc__visor {
    display: block;
    width: 100%;
    height: clamp(420px, 78vh, 900px);
    border: 1px solid var(--ipg-color-border, #d9dee8);
    border-radius: var(--ipg-radius-lg);
    background-color: var(--ipg-color-surface, #f4f6fa);
}

/* En móvil el visor incrustado es poco más que una vista previa: se deja
   más bajo para no obligar a un scroll larguísimo hasta el pie de página,
   porque quien lea en serio va a usar "Abrir en una pestaña nueva". */
@media (max-width: 782px) {
    .ipg-doc__visor { height: clamp(320px, 60vh, 520px); }
}

/* ── Avisos ─────────────────────────────────────────────────────────────
   Dos casos: el navegador no sabe mostrar PDF (va dentro del <object>) y
   la entrada no tiene archivo cargado. Comparten aspecto a propósito: las
   dos son "aquí debería haber un documento y no lo hay". */
.ipg-doc__aviso {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ipg-space-4);
    padding: var(--ipg-space-8);
    border: 1px dashed var(--ipg-color-border, #d9dee8);
    border-radius: var(--ipg-radius-lg);
    background-color: var(--ipg-color-surface, #f4f6fa);
}

.ipg-doc__aviso p {
    margin: 0;
    color: var(--ipg-color-text-muted, #5a6478);
}

.ipg-doc__aviso-editor {
    font-size: var(--ipg-text-sm);
}
