/* ===== TOKENS DE MARCA ===== */

/* Tokens de marca ImplusERP — sobreescribe las custom properties de Bastun.
   No se recompila Sass: Bastun ya expone su paleta como CSS custom
   properties en :root (ver docs/frontend/template-conversion.md Fase 3).

   Regla de esta hoja: ningún color de marca se escribe suelto fuera de
   este bloque :root. Todo lo demás en el archivo referencia estos tokens
   (con var() o color-mix()), nunca un hex/rgb literal nuevo. Si hace falta
   un tono que no existe todavía, se agrega acá con nombre, no se hardcodea
   donde se usa. */

:root {
    /* Coral vivo para uso puntual (íconos, checks, badges) — siempre sobre
       texto oscuro o fondo claro, nunca como fondo de texto blanco. */
    --primaryColor: #F0455E;
    --secondaryColor: #1F3380;
    --navyBlue: #16296B;
    /* Marino oscuro — confirmado contra el sitio real: es el --bodyBg que
       Bastun usa en su propio modo oscuro (.is_dark), no un valor inventado. */
    --navyBlue2: #0C0E2B;
    --blackColor: #05070D;
    --pinkcolor: #EEF0F5;
    /* Púrpura real del degradé original de Bastun (#00229E → #6E1299 →
       #FE0094) — antes este token decía "violet" pero valía lo mismo que
       --secondaryColor (un azul, no un púrpura). Sin uso en ningún lado
       del sitio hasta ahora, así que corregirlo no afecta nada existente.
       Uso puntual: acento que necesite distinguirse de la familia
       navy/coral del resto de la marca (ver hover de íconos de módulos). */
    --violet: #6E1299;
    --yellow: #F0455E;
    /* Texto secundario claro sobre fondo oscuro (placeholders, subtítulos) */
    --cloud: #C7CEDD;
    /* Coral oscurecido — solo para el extremo del degradé (ver abajo), no
       para uso directo. --primaryColor es el coral de marca real. */
    --coral-deep: #B8324A;

    /* El extremo del degradé usa --coral-deep en vez de --primaryColor:
       este gradiente carga texto blanco encima en botones, la cuña de
       copyright y la barra de stats — necesita quedar oscuro en todo su
       recorrido, no solo en el extremo navy.

       El degradé real de Bastun (#00229E → #6E1299 → #FE0094) se ve vivo
       porque sus tres paradas son igual de saturadas — nada de negro ni
       gris de por medio. Usar --navyBlue2 como primera parada (casi negro,
       pensado para fundirse con el footer/la cuña) aplanaba la primera
       mitad del degradé: --navyBlue2 y --secondaryColor son demasiado
       parecidos entre sí y no hay movimiento visible hasta el final.
       --navyBlue2 sigue siendo el color de la cuña (.copyright--2::before,
       ver más abajo) — no necesita coincidir con el inicio del degradé
       porque el CSS real de Bastun ya separa ambos con un borde blanco de
       5px (border-right en la cuña), igual que en la plantilla original.
       Acá el degradé arranca en --navyBlue (más saturado, con presencia de
       color real) y pasa por un punto medio mezclado matemáticamente entre
       --navyBlue y --coral-deep, para que el tono cambie de forma pareja
       en todo el recorrido en vez de quedarse plano hasta el tramo final. */
    --gradientColor: linear-gradient(90deg, var(--navyBlue) 0%, color-mix(in srgb, var(--navyBlue) 50%, var(--coral-deep) 50%) 50%, var(--coral-deep) 100%);
    --gradientColor2: linear-gradient(180deg, color-mix(in srgb, var(--navyBlue2) 0%, transparent) 0%, var(--navyBlue2) 100%);
    --gradientColor3: linear-gradient(90deg, var(--secondaryColor) 0%, color-mix(in srgb, white 0%, transparent) 100%);
}


/* ===== SISTEMA DE BOTONES ===== */

/* Sistema de botones (.default__button) — regla de uso, no cambia nada
   del CSS real, solo la documenta para que no se elija por instinto en
   cada sección nueva:

   .default__button (sin modificador)  → degradado de marca, texto blanco.
                                          Hover: se aclara (brightness). CTA
                                          principal en fondos oscuros
                                          (hero, footer).
   .default__button.btn__white         → blanco sólido, texto negro. Hover:
                                          outline blanco. Fondo oscuro
                                          (navbar).
   .default__button.btn__black         → negro sólido, texto blanco. Hover:
                                          outline negro. Fondo claro
                                          (Nosotros, Ventajas, Software).
   .default__button.btn__blue          → navy sólido, texto blanco. Hover:
                                          outline navy. Disponible en el CSS
                                          real, sin uso todavía en esta
                                          página.
   .default__button.btn__pink          → rosa claro sólido, texto negro.
                                          Hover: outline rosa. Disponible en
                                          el CSS real, sin uso todavía.

   Regla: fondo oscuro → btn__white o degradado simple; fondo claro →
   btn__black.

   Los botones "EMPEZAR" de pricing son un caso aparte a propósito: usan
   common__gradient__bg dentro de .pricing__single__button (rosa claro en
   reposo, revela el degradado en hover) — el mismo patrón de "claro →
   degradado al hover" que ya usan las cards de servicios, módulos y
   equipo en toda la página. No es un descuido, es la firma visual del
   CTA de precios, deliberadamente distinta del resto. */

/* .default__button.btn__black (CONOCER AL EQUIPO / CONOCER LA ASESORÍA /
   VER TODOS LOS MÓDULOS): por pedido explícito, invierte el mecanismo
   real de Bastun (relleno → outline en hover) a outline → relleno, que
   es lo que se prefirió. En reposo usa --navyBlue en vez de negro puro
   para que el botón se identifique como de marca antes de interactuar;
   en hover se llena con --gradientColor, el mismo que ya se reconoce en
   el resto del sitio (cards, círculos de flecha, botón EMPEZAR) — no
   introduce un color nuevo, solo reutiliza el lenguaje ya establecido.

   El degradado NO se anima directo en background: CSS no interpola entre
   background-image (que es lo que es un linear-gradient) — el navegador
   lo corta de golpe sin importar la duración de la transición, por más
   que el borde sí se desvanezca suave. Se usa la misma técnica que ya
   tiene el resto del sitio para esto (.common__gradient__bg::after): una
   capa ::after que solo cambia de opacity, eso sí es animable. Duración
   0.5s con la misma curva cubic-bezier que usa Bastun en sus propios
   reveals de degradado (.common__gradient__bg, .direction__btn::after),
   más larga que el 0.3s por defecto de .default__button, para que se
   sienta suave y no "de golpe". */
.default__button.btn__black {
    position: relative;
    z-index: 1;
    overflow: hidden;
    background: transparent;
    border: 1px solid var(--navyBlue);
    color: var(--navyBlue);
}
.default__button.btn__black::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--gradientColor);
    opacity: 0;
    transition: opacity 0.5s cubic-bezier(0.05, 0.2, 0.1, 1);
}
.default__button.btn__black:hover {
    border-color: transparent;
    color: var(--whiteColor);
}
.default__button.btn__black:hover::after {
    opacity: 1;
}


/* ===== HEADER / NAVBAR / PRELOADER ===== */

/* Navbar pinned-on-scroll, reemplaza el mecanismo real de Bastun
   (.header__sticky.sticky, ver inicio.html para el porqué). Antes eran
   dos background distintos apareciendo y desapareciendo a la vez (no
   animable, se cortaba de golpe); ahora son dos capas con opacity, que sí
   interpolan.

   Corrección: al principio se dejó la píldora boxed
   (.headerarea__main__wrapper--2) con su propio degradado siempre visible
   por debajo de la barra completa, asumiendo que el mismo color detrás la
   haría indistinguible — pero var(--gradientColor) se calcula sobre el
   ANCHO PROPIO de cada elemento (la píldora es angosta, ~1200px; la barra
   completa es el viewport entero), así que son dos degradados distintos
   escalados distinto, superpuestos donde coinciden — se nota como una
   diferencia de tono, no como un solo degradado continuo. Se resuelve con
   un crossfade real: la píldora se desvanece exactamente cuando la barra
   completa aparece, nunca las dos capas opacas a la vez. */
.headerarea--2::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--gradientColor);
    opacity: 0;
    transition: opacity 0.4s ease;
}
.headerarea--2.is-pinned {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    z-index: 99999;
    box-shadow: 0 6px 34px rgba(12, 14, 43, 0.25);
    transition: box-shadow 0.4s ease;
}
.headerarea--2.is-pinned::before {
    opacity: 1;
}
.headerarea--2.is-pinned .header__topbar {
    display: none;
}

.headerarea__main__wrapper--2 {
    background: none;
}
.headerarea__main__wrapper--2::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--gradientColor);
    opacity: 1;
    transition: opacity 0.4s ease;
}
.headerarea--2.is-pinned .headerarea__main__wrapper--2::before {
    opacity: 0;
}

/* #back__circle_loader (preloader) trae los colores del spinner
   hardcodeados en el CSS real (#465fe9 / #d5eaff, el azul de fábrica de
   Bastun) — se reemplazan por tokens de marca. */
#back__circle_loader {
    border-top-color: var(--navyBlue);
    border-right-color: var(--navyBlue);
    border-bottom-color: var(--cloud);
    border-left-color: var(--cloud);
}

/* Isotipo real (img/brand/isotipo_implusERP_blanco.svg) en el navbar,
   reemplazando el placeholder de 3 barras. .headerarea__logo real ya es
   flex (alinea el <a> verticalmente), pero no flexa sus hijos — hace
   falta acá para poner el isotipo y el texto en fila. Alto del isotipo
   (40px) calculado sobre el alto real de la fila del menu: 33px + 24px
   (line-height) + 37px de .headerarea__main__menu ul li a ≈ 94px de
   fila, el isotipo ocupa ~40% de eso. */
.headerarea__logo a {
    display: flex;
    align-items: center;
    gap: 12px;
}
.headerarea__logo__word {
    font-family: Arial, sans-serif;
    font-weight: 800;
    font-size: 24px;
    color: var(--whiteColor);
}
.headerarea__logo__accent {
    color: var(--primaryColor);
}

/* .header__topbar__left ul li no trae color propio en el CSS real (solo
   .header__topbar__right p lo tiene) — hereda el negro por defecto del
   body y desaparece sobre el hero oscuro, mismo patrón que ya vimos en el
   footer y el about__big__title. El ícono de icofont es una fuente, hereda
   el mismo color del texto sin regla aparte. */
.header__topbar__left ul li {
    color: var(--whiteColor);
}


/* ===== BREADCRUMB (compartido en todas las paginas) ===== */

/* .breadcrumbarea en el CSS real no trae background-size ni
   background-repeat — con la sección más alta que la imagen a su tamaño
   natural, se repetía en vertical. background-size:cover + no-repeat lo
   resuelve. */
.breadcrumbarea {
    background-size: cover;
    background-repeat: no-repeat;
}

/* El navbar flotante (topbar + fila de menú) mide ~150px de alto en
   páginas interiores. En vez de un padding-top fijo que solo empuja el
   título hacia abajo, se reserva ese espacio arriba y se centra
   verticalmente el contenido en lo que queda libre hasta el borde
   inferior — flex + align-items:center en vez de padding-bottom.
   min-height mantiene un alto total similar al que ya se había aprobado.
   Escopeado a desktop (≥1366px): en tablet/mobile el navbar flotante ya
   deja de ser position:absolute (headerarea__transparent cae a static en
   ≤991px), así que no necesita esta reserva de espacio. */
@media (min-width: 1366px) {
    .breadcrumbarea {
        padding-top: 150px;
        padding-bottom: 0;
        min-height: 400px;
        display: flex;
        align-items: center;
    }
}


/* ===== FOOTER / COPYRIGHT ===== */

/* footer__2 (la variante real que usa home-5) está diseñado para texto
   oscuro sobre fondo claro por defecto — Bastun solo lo invierte en su
   propio modo oscuro (.is_dark). Copiamos ese mecanismo real en vez de
   inventar uno propio: Bastun no mezcla la imagen del footer con un color
   en modo oscuro, directamente la quita (`background-image: none
   !important` en su .is_dark .footer__2) y deja ver el fondo plano de
   --bodyBg detrás. Acá el HTML ya no trae background inline (antes tenía
   la imagen), así que basta con un background-color plano acá. */
.footer__2 {
    background-color: var(--navyBlue2);
}
.footer__2 .footer__text p,
.footer__2 .footer__menu ul li a,
.footer__2 .footer__menu__title h6,
.footer__2 .footer__logo strong {
    color: var(--whiteColor);
}
/* .sidebar__post (ultimos articulos) reusado en la 4ta columna del footer:
   el h6 real no trae color propio (hereda texto oscuro pensado para el
   sidebar sobre fondo blanco) — blanco acá para leerse sobre el navy del
   footer. La fecha ya usa .text__gradient, que no depende del fondo. */
.footer__2 .sidebar__post__text h6 {
    color: var(--whiteColor);
}
.footer__logo__word {
    font-size: 20px;
}
/* .footer__logo real solo trae margin-bottom (bloque apilado) — con el
   isotipo delante del texto hace falta ponerlo en fila. El alto del
   isotipo acá (33px) esta escalado desde el del navbar (40px) en la
   misma proporcion que ya existe entre sus textos: 20px footer / 24px
   navbar (20/24 * 40 = 33.3). */
.footer__logo {
    display: flex;
    align-items: center;
    gap: 10px;
}
.footer__2 .footer__menu__title h6::after {
    background: var(--whiteColor);
}
.footer__2 .footer__menu ul li a:hover {
    color: var(--primaryColor);
}
.footer__2 .footer__input input {
    /* El CSS real de .footer__input pone fondo blanco (pensado para el
       footer__2 en modo claro) — con texto blanco encima era literalmente
       blanco sobre blanco. Fondo oscuro translúcido en su lugar. */
    background: color-mix(in srgb, var(--whiteColor) 8%, transparent);
    border-color: color-mix(in srgb, var(--whiteColor) 25%, transparent);
    color: var(--whiteColor);
}
.footer__2 .footer__input input::placeholder {
    color: var(--cloud);
}

/* .copyright--2::before (la cuña) usa var(--blackColor) en el CSS real de
   Bastun, que en su paleta original es un índigo casi negro muy cercano en
   tono a su propio --navyBlue2 — por eso la cuña se funde con el footer de
   arriba sin costura visible. Nuestro --blackColor (#05070D) es un negro
   neutro pensado para texto sobre fondo claro en el resto del sitio, y
   queda notoriamente más frío/oscuro que --navyBlue2 (#0C0E2B): cambiar el
   token global correría 186 usos de color de texto en todo el sitio, así
   que se sobreescribe solo la cuña para que combine con el footer. */
.copyright--2::before {
    background: var(--navyBlue2);
}

/* Newsletter compacto en la 1ra columna del footer: campo + boton
   circular con icono en una sola linea (en vez del boton "ENVIAR" real
   de Bastun, aparte y debajo del input) para ahorrar el alto que sobraba.
   .footer__input ya es real (fondo blanco, radio, alto 60px) — se extiende
   con este modificador en vez de reemplazarla. */
.footer__input--icon {
    position: relative;
}
.footer__input--icon input {
    padding-right: 60px;
}
.footer__input__submit {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border-radius: 100%;
    background: var(--gradientColor);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--whiteColor);
    font-size: 18px;
    transition: filter 0.3s ease;
}
.footer__input__submit:hover {
    filter: brightness(1.15);
    color: var(--whiteColor);
}
/* El titulo "SUSCRIBITE AL BOLETIN" queda a mitad de la 1ra columna
   (despues del logo/texto/iconos sociales), no al inicio como en el resto
   de columnas — .footer__menu__title solo trae margin-bottom real, hace
   falta separarlo tambien de lo que tiene arriba. */
.footer__newsletter__title {
    margin-top: 30px;
}


/* ===== COMPONENTE: HERO Y TITULOS FLOTANTES ===== */

/* .herobanner__img--2 (foto lateral del hero) trae en el CSS real
   position:absolute; top:0; right:0; max-width:50% — sin width explícito
   ni left, así que el box usa "shrink-to-fit": su ancho renderizado
   termina dependiendo del tamaño natural en píxeles de la imagen que
   traiga adentro (vía el img { width:100% } real), no de un 50% limpio
   del contenedor. Con la foto horizontal anterior el ancho natural
   coincidía casi por casualidad con ~50%; con una foto de otras
   proporciones (como la vertical actual) la columna renderiza más
   angosta de lo esperado — bug latente del CSS real, no algo que
   dependa de qué foto se use. Se fuerza width:50% explícito (además del
   bottom:0 ya agregado para el alto) para que el ancho de la columna
   quede fijo sin importar el tamaño natural de la imagen. Con
   height:100% + object-fit:cover en el img, cualquier foto que se use
   acá —horizontal o vertical— llena siempre la columna completa sin
   deformarse. */
.herobanner__img--2 {
    width: 50%;
    bottom: 0;
}
.herobanner__img--2 img {
    height: 100%;
    object-fit: cover;
}

/* Respaldo oscuro detrás del título fantasma sobre la foto. El div
   .about__big__title no tiene reglas propias en el CSS real y colapsa a
   alto 0 porque su único hijo (h1) es position:absolute — por eso el
   fondo hay que ponerlo directo en el h1, que sí tiene tamaño real.
   Sin esto, si la imagen no cubre todo el contenedor (viewports
   angostos), el texto blanco queda sobre el fondo claro de la sección
   y se pierde. */
.about__img__wrapper--2 {
    background: var(--navyBlue2);
    border-radius: var(--borderRadius);
    overflow: hidden;
}
/* .about__img__1 (fotos de "Nuestra oferta" en el Home y "Ventajas" en
   nosotros.html) no trae border-radius en el CSS real — esquinas
   cuadradas al lado del resto de tarjetas/imágenes redondeadas del sitio.
   Mismo var(--borderRadius) real (8px) que usa el resto del sitio, no un
   radio más grande — ya vimos en contacto.html que exagerarlo se ve mal.
   overflow:hidden en el wrapper de arriba para que la esquina navy de
   fondo no asome por detrás de la esquina redondeada de la imagen. */
.about__img__1 {
    border-radius: var(--borderRadius);
}
.about__big__title h1 {
    padding: 6px 14px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--navyBlue2) 45%, transparent);
}

/* "DIAN" no es un número de 2 cifras como el "29" original — reducir tamaño */
.about__number__inner span {
    font-size: 26px;
    line-height: 1.1;
}

/* Avatar circular con iniciales, reemplaza la foto de stock hasta tener fotos reales */
.team__member__img--initials {
    width: 96px;
    height: 96px;
    margin: 0 auto 24px;
    border-radius: 50%;
    background: var(--gradientColor);
    color: var(--whiteColor);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    font-weight: 700;
}


/* ===== COMPONENTE: SECCION "ABOUT" (reusada en Home/Nosotros/Soluciones) ===== */

/* .about__list ul li trae width:50% (grilla 2 columnas) desde el CSS real
   a partir de 1366px, pero el mismo componente ya cae a width:100% (una
   columna) en los breakpoints medianos y móviles — una sola columna ya es
   un patrón nativo de este componente, no algo inventado. Por pedido
   explícito se extiende también al desktop ancho, para que los 3 ítems
   queden uno debajo del otro siempre. */
.about__list ul li {
    width: 100%;
}

/* .about (Nosotros y Ventajas, mismo componente real reusado dos veces) no
   trae fondo propio en el CSS real — es transparente, deja ver el blanco
   del body. Su imagen (.about__img__wrapper--2) sí es navy, así que la
   caja se veía flotando sobre blanco sin ninguna transición. Se pinta la
   sección entera del mismo navy institucional del hero/footer para que la
   imagen se funda con el fondo. Esto obliga a re-colorear todo el texto
   de la columna derecha, que en el CSS real está pensado para fondo
   blanco (encabezados y textos en negro/gris). Los botones CONOCER AL
   EQUIPO / CONOCER LA ASESORÍA pasaron de btn__black a btn__white en el
   HTML — ya es la variante real correcta para fondo oscuro, sin necesitar
   overrides nuevos acá. */
.about {
    background: var(--navyBlue2);
}
.about .section__title__heading h3 {
    color: var(--whiteColor);
}
.about .text__gradient {
    /* El degradado como color de texto (background-clip:text) no
       funciona sobre fondo navy: el extremo navy del propio degradado se
       funde con el fondo y queda casi ilegible. Texto blanco sólido en su
       lugar, dentro de esta sección únicamente. */
    background: none;
    -webkit-text-fill-color: var(--whiteColor);
    color: var(--whiteColor);
}
.about .about__misson h6 {
    color: var(--whiteColor);
}
.about .about__misson h6:before {
    /* Subrayado decorativo, var(--blackColor) en el CSS real — invisible
       sobre navy (blackColor y navyBlue2 son casi el mismo tono). */
    background: var(--whiteColor);
}
.about .about__text__2 p {
    color: var(--cloud);
}
.about .about__text__2 p a {
    color: var(--whiteColor);
}
.about .about__inner--2 > p {
    color: var(--cloud);
}
.about .about__list ul li {
    color: var(--whiteColor);
}
/* Enlaces dentro del checklist (pilares Servicios/Software/Planes en el
   teaser de Soluciones del home): sin este override heredan
   var(--contentColor), un gris pensado para fondo claro, casi invisible
   sobre navy. El hover a var(--primaryColor) ya es el comportamiento
   global real (a:hover), no hace falta redeclararlo. */
.about .about__list ul li a {
    color: var(--whiteColor);
    font-weight: 700;
}

/* .about.ext-about (Soluciones teaser en el home, Ventajas en nosotros.html)
   vuelve a fondo claro — Fase 3 del backlog de diseño: el cierre del home
   apilaba 4 tramos oscuros seguidos (facts, este teaser, Cómo trabajamos,
   footer) sin ningún respiro claro entre Testimonios y el footer. Más
   específico que .about (2 clases vs 1), así que gana por cascada sin
   necesitar !important. Cada regla revierte al valor REAL de la plantilla
   (confirmado en style.css), no a un valor inventado. El bare .about
   (About/Quienes somos, sin ext-about) sigue navy sin cambios. */
.about.ext-about {
    background: var(--pinkcolor);
}
.about.ext-about .section__title__heading h3 {
    color: var(--blackColor);
}
.about.ext-about .text__gradient {
    background: var(--gradientColor);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}
.about.ext-about .about__inner--2 > p {
    color: var(--contentColor);
}
.about.ext-about .about__list ul li {
    color: var(--contentColor);
}
.about.ext-about .about__list ul li a {
    color: var(--navyBlue);
    font-weight: 700;
}

/* team__member__single (fila de equipo en el teaser de Nosotros del home,
   mismo componente real de #equipo en nosotros.html) no trae fondo propio
   — es transparente hasta el hover (common__gradient__bg::after entra en
   opacity:1 solo con :hover). Su texto por defecto usa --blackColor y
   --contentColor, pensados para fondo blanco: sobre el navy de .about
   quedan casi invisibles. El borderColor real (#eeeeee) sí se ve bien acá
   sin tocarlo, por ser claro. */
.about .team__member__name h6 a {
    color: var(--whiteColor);
}
.about .team__member__name p {
    color: var(--cloud);
}
/* Fase 3 del backlog de diseño: sin relleno propio, las 3 tarjetas de
   equipo se percibían como texto suelto flotando sobre el navy en vez de
   tarjetas reales — el borde claro por sí solo no bastaba para que se
   leyeran como superficies. Un relleno translúcido sutil les da peso sin
   competir con el fondo navy institucional. */
.about .team__member__single {
    background: rgba(255, 255, 255, 0.05);
}

/* .brand__roated (banda de logos justo antes de #nosotros) trae
   transform: skewY(1deg) + position:relative; top:-20px en el CSS real.
   El margin-top compensatorio que se probó primero solo cerraba el hueco
   vertical, pero el borde de la caja seguía inclinado — no calza con el
   borde recto de #nosotros y deja un sliver diagonal visible de todos
   modos. En la plantilla original es invisible porque .about también era
   blanco; con .about en navy, tanto el hueco como el sliver diagonal
   quedan expuestos. Se anula la inclinación de raíz (transform y top) en
   vez de parchar lo que produce — sin hueco que compensar, ya no hace
   falta el margin-top en #nosotros. */
.brand__roated {
    transform: none;
    top: 0;
}

/* CONOCER AL EQUIPO / CONOCER LA ASESORÍA: por pedido explícito, mismo
   mecanismo outline → degradado que ya se construyó para .btn__black
   (ver arriba), pero en blanco porque acá el fondo es navy. Scopeado a
   .about para no tocar btn__white en el navbar (HABLEMOS), que sigue
   usando el blanco relleno real de Bastun sin cambios. */
.about .default__button.btn__white {
    position: relative;
    z-index: 1;
    overflow: hidden;
    background: transparent;
    border: 1px solid var(--whiteColor);
    color: var(--whiteColor);
}
.about .default__button.btn__white::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--gradientColor);
    opacity: 0;
    transition: opacity 0.5s cubic-bezier(0.05, 0.2, 0.1, 1);
}
.about .default__button.btn__white:hover {
    border-color: transparent;
    color: var(--whiteColor);
}
.about .default__button.btn__white:hover::after {
    opacity: 1;
}


/* ===== COMPONENTE: TESTIMONIOS ===== */

/* Carrusel de testimonios: usa la card real (.testimonial__2__single,
   fondo --pinkcolor) en vez del recuadro punteado anterior — un borde
   punteado se lee como "campo vacío/roto" en cualquier lenguaje de UI,
   justo lo contrario de lo que se quería comunicar. Los 6 testimonios son
   ficticios pero con tono creíble (nombre, cargo, foto) para que el
   diseño final se pueda aprobar sin el texto "contenido de ejemplo"
   rompiendo la ilusión — ver el comentario junto al carrusel en
   inicio.html con el recordatorio de reemplazarlos por casos reales
   antes de publicar. */
.testimonial__2__author__img img {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
}
/* .testimonial__text p trae de fábrica font-style:italic +
   text-decoration:underline + color:var(--contentColor) (gris con sesgo
   azulado) — itálica+subrayado+gris-azulado es, letra por letra, el
   patrón visual de un hipervínculo. Se quita el subrayado y se oscurece
   el color para que se lea como cita, no como link roto (hallazgo de la
   auditoría de diseño de esta sesión). */
.testimonial__text p {
    text-decoration: none;
    color: var(--blackColor);
}
/* Swiper ya iguala el alto de cada .swiper-slide (confirmado: los tres
   miden lo mismo), pero .testimonial__2__single no trae height propio en
   el CSS real — con citas de largo distinto, la card visible se queda en
   su alto de contenido natural dentro del slide ya-igual, mismo patrón
   que ya vimos en servicios y precios. height:100% + flex para que el
   contenido (cita arriba, separador + sector abajo) se reparta con el
   espacio extra en el medio, en vez de dejarlo muerto al final. */
.testimonial__2__single {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.testimonial__cta {
    margin-top: 40px;
}
.testimonial__cta p {
    color: var(--contentColor);
}
.testimonial__cta a {
    color: var(--primaryColor);
    font-weight: 700;
}


/* ===== COMPONENTE: TARJETAS CON CIRCULO DE ICONO (modulos de software + servicios) ===== */

/* Cards de módulo sin foto real: fondo de marca en vez de imagen de stock.
   min-height sube de 280 a 330 para darle espacio a project__text (la
   descripción real de cada módulo, agregada en la Fase 1 del backlog de
   contenido) sin que el card se vea apretado. */
.project__img--module {
    background: var(--gradientColor);
    min-height: 330px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 30px;
    border-radius: var(--borderRadius);
}
/* .project__heading--2 y .project__icon--2 son position:absolute en el CSS
   real (bottom:30px / bottom:40px), pensados para flotar sobre una foto de
   fondo real que ocupa toda la tarjeta. Acá no hay foto — es un fondo de
   degradado — y con project__text agregado en flujo normal, el título
   absoluto quedaba flotando encima de la descripción en vez de apilarse
   con ella (se veían superpuestos, ilegibles). Se vuelven position:static
   para que floten en el flujo normal del flex column de arriba: título →
   descripción → ícono, en ese orden, empujados al fondo del card por el
   justify-content:flex-end del contenedor. align-self:flex-end en el
   ícono para que quede a la derecha (como en el diseño real) en vez de
   ocupar todo el ancho de la columna. */
.project__img--module .project__heading--2 {
    position: static;
}
.project__img--module .project__text {
    margin-top: 12px;
    margin-bottom: 16px;
}
.project__img--module .project__text p {
    color: color-mix(in srgb, var(--whiteColor) 85%, transparent);
    font-size: 14.5px;
    line-height: 1.5;
}
.project__img--module .project__icon--2 {
    position: static;
    align-self: flex-end;
}

/* .service__single__wraper no trae altura propia en el CSS real, solo
   padding — Bootstrap ya iguala la altura de las columnas .col-xl-4 vía
   flexbox, pero la caja blanca visible (la que tiene el box-shadow) se
   queda en su alto de contenido natural dentro de esa columna ya-igual,
   así que con textos de largo distinto las tres cards visibles quedan de
   alturas distintas aunque sus columnas midan lo mismo. */
.service__single__wraper--2 {
    height: 100%;
}

/* Íconos de los 6 módulos de software (soluciones.html): el círculo
   .direction__btn real colorea su contenido vía SVG (svg path { stroke:
   ... }) — reglas que no aplican a un glifo de icofont, que se colorea
   con color, no stroke. Mismo z-index:99 que el SVG real. --violet
   (púrpura real del degradé original de Bastun, ver :root) resalta bien
   contra el círculo blanco, distinto a la familia navy/coral del resto
   de la marca.

   El trigger es .single__transform:hover (toda la tarjeta, el mismo
   wrapper real que ya hace el translateY(-10px) al pasar el mouse), no
   .direction__btn:hover — el círculo dejó de ser un link con propósito
   propio (todas las tarjetas apuntan al mismo contacto.html). Por pedido
   explícito, el único cambio en hover es color de ícono + un leve scale
   del círculo — el degradado real (::after, background:
   var(--gradientColor)) se deja apagado a propósito, no se revela. */
.direction__btn i {
    position: relative;
    z-index: 99;
    font-size: 24px;
    color: var(--blackColor);
    transition: var(--transition);
}
.direction__btn {
    transition: transform 0.3s ease;
}
.single__transform:hover .direction__btn {
    transform: scale(1.1);
}
.single__transform:hover .direction__btn i {
    color: var(--violet);
}
/* El degradado real (::after, background:var(--gradientColor)) se
   suprime siempre en los módulos, incluso si el mouse pasa justo sobre el
   círculo — si no, el fondo cambiaría solo en ese punto exacto y no en el
   resto de la tarjeta, inconsistente con "toda la tarjeta dispara lo
   mismo". Escopeado a .project__img--module para no tocar
   .direction__btn--2 de Servicios, que sí conserva su degradado real. */
.project__img--module .direction__btn:hover::after {
    opacity: 0;
}

/* Títulos de los 6 módulos: ya no son <a> — por pedido explícito, al no
   ser links con destino propio no tenía sentido que cambiaran de color en
   hover, y menos que fueran clicables. El color real (var(--whiteColor))
   estaba puesto en .project__heading--2 h3 a; sin el <a>, hay que ponerlo
   directo en el h3 para no perder el blanco sobre el fondo degradado. Sin
   :hover — ya no hay nada que cambie de color al pasar el mouse. */
.project__heading--2 h3 {
    color: var(--whiteColor);
}

/* .project__margin trae margenes laterales fijos en cada breakpoint
   (185px de escritorio hasta 15px en movil) pensados para que el fondo
   blanco "flote" dentro de la seccion. El usuario pidio que esta seccion
   fuera de lado a lado; al no llevar media query, esta regla gana sobre
   las 4 variantes de style.css en todos los anchos por orden de cascada.
   Tambien trae margin-top: -650px, pensado en la plantilla original para
   que la caja blanca flote sobre una foto de fondo alta. Aqui la seccion
   anterior (video/CTA de Servicios) mide ~550px, menos que el jalón de
   650px, así que tapaba contenido de Servicios — se anula por completo. */
.project__margin {
    margin-left: 0;
    margin-right: 0;
    margin-top: 0;
}

/* Circulos de icono en las 3 tarjetas de Servicios (soluciones.html):
   dejaron de ser link (direction__btn--2) y pasan al componente base
   .direction__btn, igual al de los modulos de software. En reposo el
   fondo es el degradado institucional e icono blanco; al hacer hover en
   cualquier parte del card (single__transform) el fondo pasa a blanco y
   el icono a --violet (mismo token que los modulos) — el ::after real
   (que revela el degradado solo con hover directo sobre el circulo) se
   suprime porque el fondo ya lo pone esta regla directamente, no ese
   pseudo-elemento. El escalado del circulo en hover ya viene de la
   regla general .single__transform:hover .direction__btn. */
.service__icon--2 .direction__btn {
    background: var(--gradientColor);
}
.service__icon--2 .direction__btn i {
    color: var(--whiteColor);
}
.single__transform:hover .service__icon--2 .direction__btn {
    background: var(--whiteColor);
}
.service__icon--2 .direction__btn:hover::after {
    opacity: 0;
}


/* ===== SOLUCIONES: PRECIOS Y TABLA COMPARATIVA ===== */

/* li { display: inline-block } es un reset global del CSS real (line ~204
   de style.css, pensado para menús horizontales) que no trae ancho fijo,
   así que .pricing__single__text ul li empaqueta cada ítem como si fuera
   texto en vez de ponerlo en su propia línea — frases cortas ("Gestión de
   inventarios", "Nómina y cartera") caben juntas en una línea, una más
   larga no cabe con nada, y el resultado es una cantidad de líneas
   distinta por card según el largo de cada texto, aunque las tres tengan
   3 ítems. .about__list no tiene este problema porque ya trae su propio
   width:50% explícito — esta lista no. Forzar display:block deja cada
   ítem en su propia línea siempre, sin depender del largo del texto ni
   del ancho del viewport. height:100% en el wrapper es un respaldo extra
   por si el contenido llegara a diferir en cantidad de ítems más
   adelante. */
.pricing__single__text ul li {
    display: block;
}
.pricing__gradient {
    height: 100%;
}

/* .pricing__single__button a usa --pinkcolor (#EEF0F5, casi blanco) tanto
   de fondo como de borde en el CSS real — sin contraste real hasta que
   .common__gradient__bg revela el degradado en hover. Para un CTA de
   pricing (la acción más importante de la página) depender del hover es
   un problema real: en móvil no existe hover, así que el botón se ve sin
   ninguna señal de que es clickeable. En vez de mantenerlo distinto del
   resto del sitio, se alinea con el patrón que ya usa .default__button
   sin modificador (degradado de marca, visible en reposo) en el hero y
   el footer — los otros dos puntos de CTA "principal" de la página. */
.pricing__single__button a {
    background: var(--gradientColor);
    color: var(--whiteColor);
    border-color: transparent;
}
.pricing__single__button a:hover {
    /* 115% quedaba casi imperceptible (feedback real de un usuario) — se
       sube a 150%, el mismo valor que .default__button:hover usa en el
       resto del sitio (hero, footer, navbar), más un levantamiento leve
       para que el cambio se note incluso si el brillo por sí solo pasa
       desapercibido. */
    filter: brightness(150%);
    transform: translateY(-3px);
}

/* Tabla comparativa de planes (Fase 1 del backlog de contenido, dentro de
   #planes en soluciones.html). Sin componente real de tabla en Bastun para
   apoyarse — mismo lenguaje visual que .pricing__single (fondo blanco,
   sombra suave, borderRadius) para que se sienta parte del mismo sistema. */
.table__wrap {
    background: var(--whiteColor);
    border-radius: var(--borderRadius);
    box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.05);
    /* padding-left/right/bottom en vez del shorthand "padding": el
       shorthand fija implícitamente padding-top también, y sin querer
       pisaba el padding-top:70px que pone sp_top_70 en el HTML (ganaba
       por cargar después en la cascada) — el padding interno real
       siempre fue 10px, no 70px. Con las propiedades largas, sp_top_70
       controla el top sin que esta regla lo toque. */
    padding-left: 30px;
    padding-right: 30px;
    padding-bottom: 10px;
    overflow-x: auto;
    /* La fila de tarjetas de precio y este wrap quedaban sin ningún
       margen entre sí — sp_top_70 es padding interno (empuja la tabla
       hacia abajo dentro de esta misma caja), no un espacio antes de la
       caja. margin-top real para separar visualmente la comparativa de
       las tarjetas de arriba. */
    margin-top: 60px;
}
.pricing__comparison__table {
    width: 100%;
    border-collapse: collapse;
    min-width: 600px;
}
.pricing__comparison__table th,
.pricing__comparison__table td {
    padding: 16px 12px;
    text-align: center;
    border-bottom: 1px solid var(--borderColor);
}
.pricing__comparison__table td {
    color: var(--contentColor);
}
.pricing__comparison__table th:first-child,
.pricing__comparison__table td:first-child {
    text-align: left;
    color: var(--blackColor);
    font-weight: 600;
}
.pricing__comparison__table thead th {
    background: var(--gradientColor);
    color: var(--whiteColor);
    font-weight: 700;
    font-size: 15px;
}
/* La primera celda del header no tiene titulo (encabeza la columna de
   nombres de caracteristica) — sin degrade ahi, solo en las 3 columnas
   de planes. */
.pricing__comparison__table thead th:first-child {
    background: transparent;
    border-top-left-radius: var(--borderRadius);
}
.pricing__comparison__table thead th:last-child {
    border-top-right-radius: var(--borderRadius);
}
.pricing__comparison__table td i.icofont-check {
    color: var(--primaryColor);
    font-size: 18px;
}
/* Columna de "Gestión y Control": es el plan con el badge de destacado en
   las tarjetas de arriba (pricing__special). Se tiñe con --pinkcolor para
   que la tabla siga comunicando "este es el recomendado" igual que las
   tarjetas, sin tocar el header (que ya lleva el degradé parejo). */
.pricing__comparison__table tbody td:nth-child(3) {
    background: var(--pinkcolor);
}
.pricing__comparison__table__price td {
    border-bottom: none;
    border-top: 2px solid var(--primaryColor);
    font-weight: 700;
    color: var(--secondaryColor);
    padding-top: 20px;
}
.pricing__comparison__table__price td:first-child {
    /* La regla generica ".pricing__comparison__table td:first-child" (mas
       especifica que ".pricing__comparison__table__price td") fija
       color: var(--blackColor) en la primera columna de toda la tabla y
       le ganaba a esta fila por especificidad, dejando "Precio" en negro
       mientras las 3 celdas de precio si quedaban en navy. Se repite el
       color aqui, con un selector igual de especifico, para que "Precio"
       tambien quede en navy. */
    font-weight: 700;
    color: var(--secondaryColor);
}


/* ===== SOLUCIONES: DIFERENCIADORES, FAQ Y CTA ===== */

/* service__features__icon (diferenciadores en soluciones.html) espera una
   <img> en el CSS real; acá lleva un glifo de icofont en su lugar. El color
   ya lo hereda de --primaryColor (regla real, vía color: currentColor del
   glifo) — solo hace falta el tamaño de fuente. */
.service__features__icon i {
    font-size: 34px;
}

/* FAQ (acordeón real de faq.php, sin la barra lateral de búsqueda/categorías
   ni accordion__img — son solo preguntas y respuestas de texto). El
   Bootstrap real del proyecto no tiene el tema de marca aplicado a sus
   variables --bs-accordion-*, así que el estado activo por defecto es azul
   Bootstrap genérico. Se sobreescriben esas custom properties (mismo
   mecanismo que usa el CSS real) para que el acordeón use los tokens de
   ImplusERP en vez del azul de fábrica. */
.faq__accordion .accordion {
    --bs-accordion-active-bg: var(--pinkcolor);
    --bs-accordion-active-color: var(--navyBlue);
    --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23F0455E'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
    --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23F0455E'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}
.faq__accordion .accordion-button {
    font-weight: 700;
    color: var(--blackColor);
}
.faq__accordion .accordion-body p {
    color: var(--contentColor);
}

/* CTA tras el FAQ de soluciones.html: reusa el componente real .cta__area
   (home-4-digital-agency.php) pero sin su ilustracion/iconos flotantes
   decorativos (mismo criterio de Fase 3: sin garabatos). El margin-bottom
   real de .cta__area solo existe para dejarle espacio a esa ilustracion
   que sobresale por debajo (cta__area__img, position absolute, bottom:
   -445px) — al no usarla, ese margen queda como hueco vacio antes del
   footer y hay que anularlo. */
.cta__area {
    margin-bottom: 0;
}
.cta__area .section__title__text p {
    color: var(--whiteColor);
}


/* ===== CONTACTO ===== */

/* contacto.html: .contact__img img real solo trae width:100%, sin alto ni
   object-fit — con una foto horizontal nueva quedaba mucho más baja que la
   columna del formulario de al lado. Altura fija calculada desde los
   valores reales del formulario (paddings + alto de inputs/textarea/botón
   ≈ 650-680px) menos el alto real de contact__info (≈330px) y su
   margin-bottom (30px), para que las dos columnas terminen a la misma
   altura. object-fit:cover para que cualquier foto que se use acá quede
   recortada limpia a esa altura, sin depender de su proporción natural.
   Sin border-radius propio en el CSS real tampoco — esquinas cuadradas al
   lado de tarjetas redondeadas. Mismo var(--borderRadius) real (8px) que
   el resto del sitio, no un radio inventado más grande — el primer intento
   (20px) se veía exagerado frente a cómo luce la plantilla real. */
.contact__img img {
    height: 300px;
    object-fit: cover;
    border-radius: var(--borderRadius);
}

/* contacto.html: el énfasis se movió del borde exterior del card a los
   campos — el usuario no interactúa con el contenedor, interactúa con los
   inputs. El borde coral de 2px del primer intento quedó revertido a algo
   sutil, coherente con el tono navy de los campos de abajo, sin competir
   por atención. */
.contact__input__wrapper {
    border: 1px solid color-mix(in srgb, var(--navyBlue) 15%, var(--borderColor));
}

/* contacto.html: .contact__common__input real usa border-color:
   var(--borderColor) (#eeeeee) y background:white — casi cero contraste
   contra el fondo blanco de .contact__input__wrapper, así que los campos
   no se distinguían como casillas. Fondo con tinte sutil (--pinkcolor, ya
   usado en otras superficies claras del sitio) + borde navy diluido para
   que cada campo se lea como tal, más un estado :focus en coral para dar
   feedback claro de cuál campo está activo. */
.contact__common__input {
    background: var(--pinkcolor);
    border-color: color-mix(in srgb, var(--navyBlue) 25%, white);
}
.contact__common__input:focus {
    border-color: var(--primaryColor);
    outline: none;
}

/* contacto.html: el checkbox de consentimiento va en su propia fila (es
   el primer clic del flujo). La segunda fila junta captcha + botón de
   enviar en dos columnas — captcha a la izquierda, botón a la derecha —
   porque son el segundo y tercer clic del mismo paso de verificación y
   quedan visualmente a la misma altura en vez de una fila más debajo de
   otra. Turnstile en data-size="flexible" (se ajusta al ancho de
   .contact__verify__captcha, ~65px de alto) en vez de "compact"
   (130x120, se veía como un cuadrado desbalanceado frente al botón
   ancho) — así el widget queda rectangular, con proporciones parecidas
   a las del botón. flex-wrap conserva el apilado (captcha arriba, botón
   abajo) en mobile sin comprimir ninguno de los dos. */
.contact__verify__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    margin-bottom: 10px;
}
.contact__verify__captcha {
    flex: 1 1 260px;
}
.contact__verify__row .contact__button {
    flex: 0 0 auto;
    margin: 0;
}

/* Sin esto, el atributo :disabled del botón de enviar (activo mientras
   no se acepten términos y se resuelva el captcha) no tenía ningún
   feedback visual — se veía igual de "clicable" deshabilitado que
   habilitado, y el usuario no podía saber que le faltaba un paso. */
.default__button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    filter: none;
}


/* ===== MODULO DE BLOG ===== */

/* Modulo de Blog (data/blog.json + js/blog.js). #articleBody recibe el
   "body" del post ya con <p>/<ul>/<blockquote> sueltos, sin los divs reales
   .blog__details__text/.blog__details__list que los envuelven en la
   plantilla original — se replica el mismo espaciado directo sobre los
   hijos para no obligar a que cada body del JSON repita esos wrappers. */
#articleBody > p {
    margin-bottom: 30px;
}
#articleBody > ul {
    margin-bottom: 25px;
}
#articleBody > ul li {
    position: relative;
    padding-left: 20px;
    margin-bottom: 5px;
}
#articleBody > ul li::before {
    position: absolute;
    content: "";
    height: 8px;
    width: 8px;
    background: var(--contentColor);
    border-radius: 100%;
    top: 13px;
    left: 0;
}
/* El buscador del sidebar traia el icono de lupa en verde hardcodeado
   (#1C5C05, color de otro demo de Bastun) — se recolorea a un token real. */
.sidebar__search__button svg path {
    fill: var(--primaryColor);
}
/* Encabezado dinamico de las paginas de busqueda/tag/categoria (lo pone
   js/blog.js segun el filtro activo), y el encabezado principal de
   Soluciones (#solucionesMainHeading) — ambos pasaron de <h3> a <h1> por
   ser la única fuente de ese texto en la página (antes no había ningún
   <h1> real ahí). style.css solo define tipografía para
   `.section__title__heading h3`, así que se repite acá por ID para no
   perder el estilo al cambiar de tag ni tocar la regla compartida con h3
   (usada en otras secciones del sitio). */
#blogFilterHeading,
#solucionesMainHeading {
    margin-bottom: 30px;
    color: var(--blackColor);
    text-align: center;
    font-size: 37px;
    font-weight: 700;
    line-height: 50px;
}
@media (min-width: 992px) and (max-width: 1365px) {
    #blogFilterHeading,
    #solucionesMainHeading {
        font-size: 29px;
        line-height: 45px;
    }
}
@media (min-width: 768px) and (max-width: 991px) {
    #blogFilterHeading,
    #solucionesMainHeading {
        font-size: 27px;
        line-height: 37px;
    }
}
@media (max-width: 767px) {
    #blogFilterHeading,
    #solucionesMainHeading {
        font-size: 24px;
        line-height: 36px;
    }
}
/* El título real del artículo pasó de <h4> a <h1> (era el único h1 que le
   faltaba a esta página — el h2 del breadcrumb arriba es decorativo, igual
   en todas las páginas públicas). style.css solo define tipografía para
   `.blog__details__heading h4`; se repite acá para h1 sin tocar esa regla
   compartida. */
.blog__details__heading h1 {
    font-size: 26px;
    font-weight: 700;
}
@media (max-width: 767px) {
    .blog__details__heading h1 {
        font-size: 20px;
    }
}
/* Sin componente real de "sin resultados" en Bastun — placeholder simple
   para cuando una busqueda/tag/categoria no encuentra articulos. */
.empty__state {
    padding: 60px 20px;
    text-align: center;
    color: var(--contentColor);
}

/* Las 3 reglas reales de abajo (.sidebar__post__img, .blog__4__img img,
   .blog__details__img img) no traen ancho/alto propio porque las imagenes
   de ejemplo de Bastun ya venian pre-recortadas al tamano exacto que cada
   componente esperaba. Las fotos reales de Pexels que usa el modulo de
   Blog son fotos completas sin recortar — sin estas reglas, el navegador
   las muestra a su tamano natural completo (hasta 940px de ancho),
   rompiendo el layout del sidebar y de las tarjetas. */
.sidebar__post__img {
    width: 80px;
    height: 80px;
    flex-shrink: 0;
    overflow: hidden;
    border-radius: var(--borderRadius);
}
.sidebar__post__img img {
    width: 80px;
    height: 80px;
    object-fit: cover;
}
.blog__4__img {
    overflow: hidden;
    border-radius: var(--borderRadius);
}
.blog__4__img img {
    height: 220px;
    object-fit: cover;
}
.blog__details__img {
    overflow: hidden;
    border-radius: var(--borderRadius);
}
.blog__details__img img {
    width: 100%;
    height: 420px;
    object-fit: cover;
}
/* <blockquote> generado por IA dentro del cuerpo del artículo: mismo
   lenguaje visual que .blog__details__text--2 (fondo claro, borde de
   acento) pero sin el gradiente de fondo — usa --pinkcolor (el mismo de
   las cards de testimonio y el wrapper de la imagen destacada) con un
   borde izquierdo coral para que se distinga como cita sin competir con
   el contenido principal. font-style: italic + color: --blackColor es
   el mismo par que .testimonial__text p (ver más arriba en esta hoja). */
#articleBody > blockquote {
    margin: 30px 0;
    padding: 20px 24px;
    background: var(--pinkcolor);
    border-left: 4px solid var(--primaryColor);
    border-radius: var(--borderRadius);
    font-style: italic;
    color: var(--blackColor);
}

/* .blog__details__category / .blog__details__tags: no son clases reales de
   Bastun, mismo espaciado que .blog__details__text para no romper el ritmo
   vertical del resto del detalle. .blog__details__tags reusa .sidebar__tag
   (con su margin-bottom:20px por li) asi que solo necesita separarse del
   bloque de arriba. */
.blog__details__category {
    margin-bottom: 20px;
}
.blog__details__tags {
    margin-bottom: 30px;
}

/* Tarjetas de blog con igual alto (listado #blogGrid y teaser de 3 en el
   home #homeBlogTeaser): .row de Bootstrap ya estira las columnas parejo
   (align-items:stretch por defecto), pero .blog__4__single no llenaba esa
   altura y el boton quedaba a distinta altura segun el largo del extracto
   de cada post real (a diferencia del lorem ipsum de la plantilla
   original, que siempre media lo mismo). */
#blogGrid > [class*="col-"],
#homeBlogTeaser > [class*="col-"] {
    display: flex;
}
#blogGrid .blog__4__single,
#homeBlogTeaser .blog__4__single {
    display: flex;
    flex-direction: column;
    width: 100%;
}
#blogGrid .blog__4__text,
#homeBlogTeaser .blog__4__text {
    flex: 1;
}


