/* ============ Tokens ============ */
:root {
  --color-brand: #552eff;
  --color-brand-dark: #113e9b;
  --color-brand-hover: #4322d6;
  --color-navy: #02015a;
  --color-navy-panel: #0b3e93;
  --color-text: #4e5774;
  --color-text-light: #989eb8;
  --color-lilac: #b19fff;
  --color-surface: #f3f7fb;
  --color-surface-alt: #ede9ff;
  --color-surface-alt-hover: #ddd6ff;
  --color-border: #989eb8;
  --color-white: #ffffff;

  --font-body: "Poppins", system-ui, sans-serif;

  --radius-sm: 5px;
  --radius-md: 10px;
  --radius-pill: 25px;

  --container-width: 1290px;
  --gap: 1.5rem;

  --shadow-card: 0 10px 30px rgba(2, 1, 90, 0.08);

  --header-height-mobile: 106px;
  --header-height-desktop: 119px;
}

/* ============ Reset ============ */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-white);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
img { max-width: 100%; display: block; }
ul, ol { list-style: none; margin: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
/* Medio sitio dispara sus clics desde <span role="button"> -- el codigo viejo lo hace asi para
   que el enlace de afiliado no salga en el HTML -- y sin esto el cursor no cambia y no parecen
   pulsables. */
[role="button"] { cursor: pointer; }
input, select { font: inherit; }
h1, h2, h3, p { margin: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 1rem; top: -3rem;
  background: var(--color-brand);
  color: var(--color-white);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-sm);
  z-index: 200;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 1rem; }

:focus-visible {
  outline: 3px solid var(--color-brand);
  outline-offset: 2px;
}

.container {
  width: min(var(--container-width), 100% - 2.5rem);
  margin-inline: auto;
}

#main, #categorias, #ranking, #guias, #acerca-de, #contacto {
  scroll-margin-top: var(--header-height-mobile);
}
@media (min-width: 960px) {
  #main, #categorias, #ranking, #guias, #acerca-de, #contacto {
    scroll-margin-top: var(--header-height-desktop);
  }
}

/* ============ Type & shared bits ============ */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--color-brand);
  font-weight: 500;
  font-size: 0.9375rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}
.eyebrow--light { color: var(--color-lilac); }

.section-title {
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 1.875rem);
  font-weight: 500;
  color: var(--color-navy);
  line-height: 1.3;
}
.section-title--light { color: var(--color-white); }

.section-lead,
.cta-banner__lead,
.about__text {
  font-size: 1.125rem;
  font-weight: 300;
}

.section-lead { margin-top: 0.75rem; }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.75rem;
}

.link-arrow {
  color: var(--color-brand);
  text-decoration: underline;
  font-size: 1rem;
  white-space: nowrap;
}

/* Cabecera apilada (seccion de guias): rotulo, titulo y parrafo a ancho completo, y el "ver
   todas" debajo, en su propia linea. */
.section-head--stacked { display: block; }
.section-head__more { display: inline-block; margin-top: 0.75rem; }

.text-accent { color: var(--color-brand); }

/* Card title role: hero panel, steps, category cards */
.hero__panel-title,
.steps__item h3,
.category-card__body h3 {
  font-size: 1.125rem;
  font-weight: 700;
}

section { padding-top: clamp(2.5rem, 1.5rem + 4vw, 5rem); }

/* Tooltip de Bootstrap (data-toggle="tooltip"): includes/validation_scripts.php:2111 llama a
   .tooltip() en todas las paginas, legacy y Twig, pero las paginas Twig solo cargan style-v2.css
   -- css/bootstrap.css no entra aqui -- asi que el marcado que Popper genera (.tooltip/.arrow/
   .tooltip-inner) llegaba sin una sola regla propia y se veia como texto suelto sin caja. Estas
   reglas son el mismo patron de Bootstrap 4 (mismas clases, misma estructura), solo con los
   colores de la marca en vez de los grises de fabrica. */
.tooltip {
  position: absolute;
  z-index: 1070;
  display: block;
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.8125rem;
  line-height: 1.4;
  white-space: normal;
  opacity: 0;
}
.tooltip.show { opacity: 1; }
.tooltip .arrow { position: absolute; display: block; width: 0.8rem; height: 0.4rem; }
.tooltip .arrow::before { position: absolute; content: ""; border-color: transparent; border-style: solid; }

.bs-tooltip-top, .bs-tooltip-auto[x-placement^="top"] { padding: 0.4rem 0; }
.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^="top"] .arrow { bottom: 0; }
.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before {
  top: 0; border-width: 0.4rem 0.4rem 0; border-top-color: var(--color-navy);
}

.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^="bottom"] { padding: 0.4rem 0; }
.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^="bottom"] .arrow { top: 0; }
.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
  bottom: 0; border-width: 0 0.4rem 0.4rem; border-bottom-color: var(--color-navy);
}

.bs-tooltip-right, .bs-tooltip-auto[x-placement^="right"] { padding: 0 0.4rem; }
.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^="right"] .arrow { left: 0; width: 0.4rem; height: 0.8rem; }
.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^="right"] .arrow::before {
  right: 0; border-width: 0.4rem 0.4rem 0.4rem 0; border-right-color: var(--color-navy);
}

.bs-tooltip-left, .bs-tooltip-auto[x-placement^="left"] { padding: 0 0.4rem; }
.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^="left"] .arrow { right: 0; width: 0.4rem; height: 0.8rem; }
.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^="left"] .arrow::before {
  left: 0; border-width: 0.4rem 0 0.4rem 0.4rem; border-left-color: var(--color-navy);
}

.tooltip-inner {
  max-width: 220px;
  padding: 0.45rem 0.75rem;
  color: var(--color-white);
  text-align: center;
  background-color: var(--color-navy);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
}

/* ============ Buttons ============ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius-md);
  font-weight: 400;
  font-size: 1rem;
  border: none;
  white-space: nowrap;
}
.btn--primary { background: var(--color-brand); color: var(--color-white); }
.btn--primary:hover { background: var(--color-brand-hover); }
.btn--outline { background: var(--color-white); color: var(--color-brand); border: 1px solid var(--color-surface-alt); }
.btn--white { background: var(--color-white); color: var(--color-brand); }
.btn--ghost { border: 1px solid var(--color-surface-alt); color: var(--color-brand); background: transparent; }
.btn--surface { background: var(--color-surface); color: var(--color-brand); }
.btn--sm { padding: 0.6rem 1.1rem; font-size: 0.9375rem; }

.tag {
  display: inline-block;
  padding: 0.3rem 0.75rem;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 400;
}
.tag--outline { background: var(--color-white); color: var(--color-brand); }
.tag--solid { background: var(--color-brand); color: var(--color-white); }
.tag--navy { background: var(--color-navy-panel); color: var(--color-white); }
.tag--white { background: var(--color-white); color: var(--color-navy-panel); }
.tag--blue { background: #5695ff; color: var(--color-white); }
.tag--green-soft { background: #aafadf; color: #007950; }
.tag--pink-soft { background: #ffedfd; color: #d520c1; }

/* ============ Header ============ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: url("../assets/images/hero-bg.svg?v=2") top / 100% auto no-repeat;
}

.topbar {
  background: var(--color-brand-dark); color: var(--color-white); font-size: 0.8125rem;
  max-height: 60px; opacity: 1; overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.2s ease;
}
.topbar__inner { display: flex; align-items: center; justify-content: center; gap: 1rem; padding-block: 0.6rem; }
.topbar__stats { display: none; gap: 1.5rem; }
.topbar__phone { white-space: nowrap; }

.navbar { background: none; position: relative; }
.navbar__inner { display: flex; align-items: center; gap: 1.5rem; padding-block: 0.85rem; transition: padding-block 0.2s ease; }
.site-header.is-compact .navbar__inner { padding-block: 0.5rem; }
.site-header.is-compact .topbar { max-height: 0; opacity: 0; }
.navbar__logo img { width: 132px; height: auto; }
.navbar__nav { display: none; margin-inline: auto; }
.navbar__nav ul { display: flex; gap: 2rem; }
.navbar__nav a { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 1rem; color: var(--color-white); }
.navbar__nav-chevron { width: 11px; height: 7px; transition: transform 0.15s ease; }
.navbar__nav a:hover .navbar__nav-chevron { transform: rotate(180deg); }
.navbar__cta { display: none; margin-left: auto; }

.navbar__dropdown { padding-bottom: 2.5rem; margin-bottom: -2.5rem; }

.mega-menu {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(6px);
  width: calc(100% - 2rem);
  display: grid;
  grid-template-columns: 337px 1fr;
  align-items: center;
  gap: 5rem;
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 2.5rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
  z-index: 50;
}
.navbar__dropdown:hover .mega-menu,
.navbar__dropdown:focus-within .mega-menu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

.mega-menu--no-promo { grid-template-columns: 1fr; }

.mega-menu__promo {
  position: relative;
  display: block;
  aspect-ratio: 337 / 290;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-brand);
}
.mega-menu__promo-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 70% 25%; opacity: 0.7; }
.mega-menu__promo::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(85, 46, 255, 0) 40%, var(--color-brand) 100%);
}
.mega-menu__promo-icon { position: absolute; top: 2.25rem; left: 1.25rem; z-index: 1; }
.mega-menu__promo p {
  position: absolute; left: 1.25rem; right: 1.25rem; bottom: 1.25rem;
  z-index: 1;
  color: var(--color-white);
  font-weight: 300;
  font-size: 1.5625rem;
  line-height: 1.3;
}

.mega-menu__groups { display: flex; flex-direction: column; gap: 1.1875rem; }
.mega-menu__label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-text);
}
.mega-menu__pills { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.mega-menu__pills a {
  display: inline-flex; align-items: center; gap: 0.4rem;
  background: var(--color-surface-alt);
  color: var(--color-brand);
  border-radius: var(--radius-md);
  padding: 0.6rem 0.85rem;
  font-size: 0.9375rem;
  white-space: nowrap;
}
.mega-menu__pills a:hover { background: var(--color-surface-alt-hover); }

.navbar__toggle {
  position: relative;
  margin-left: auto;
  background: none; border: none;
  width: 40px; height: 40px;
}
.navbar__toggle span {
  position: absolute;
  left: 50%;
  width: 22px; height: 2px;
  background: var(--color-white);
  transform: translateX(-50%);
  transition: transform 0.2s ease, opacity 0.2s ease, top 0.2s ease;
}
.navbar__toggle span:nth-child(1) { top: 12px; }
.navbar__toggle span:nth-child(2) { top: 19px; }
.navbar__toggle span:nth-child(3) { top: 26px; }

.navbar__toggle[aria-expanded="true"] span:nth-child(1) { top: 19px; transform: translateX(-50%) rotate(45deg); }
.navbar__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.navbar__toggle[aria-expanded="true"] span:nth-child(3) { top: 19px; transform: translateX(-50%) rotate(-45deg); }

.mobile-nav {
  background: var(--color-white);
  border-top: 1px solid transparent;
  padding-inline: 1.25rem;
  padding-block: 0;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.2s ease, padding-block 0.25s ease, border-color 0.25s ease;
}
/* Con los acordeones abiertos el panel pasa de largo los 400px que bastaban para cuatro
   titulos, asi que el tope es la pantalla menos la cabecera y lo que sobra se desplaza. */
.mobile-nav.is-open {
  border-top-color: var(--color-surface);
  padding-block: 1.25rem;
  max-height: calc(100vh - var(--header-height-mobile));
  overflow-y: auto;
  opacity: 1;
}
.mobile-nav a.btn { width: 100%; }
.mobile-nav[hidden] { display: none; }

.mobile-nav__sections { display: flex; flex-direction: column; margin-bottom: 1.25rem; }
.mobile-nav__section + .mobile-nav__section { border-top: 1px solid var(--color-surface); }
.mobile-nav__toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  width: 100%;
  padding-block: 0.9rem;
  background: none; border: none;
  font: inherit;
  color: var(--color-text);
  text-align: left;
}
.mobile-nav__chevron { flex: none; transition: transform 0.2s ease; }
.mobile-nav__toggle[aria-expanded="true"] .mobile-nav__chevron { transform: rotate(180deg); }
.mobile-nav__panel { display: flex; flex-direction: column; gap: 0.5rem; padding-bottom: 1rem; }
.mobile-nav__panel[hidden] { display: none; }
.mobile-nav__panel .mega-menu__label { margin-bottom: 0; }
.mobile-nav__panel .mega-menu__pills + .mega-menu__label { margin-top: 0.5rem; }

@media (min-width: 960px) {
  .topbar__inner { justify-content: space-between; }
  .topbar__stats { display: flex; }
  .navbar__nav { display: block; }
  .navbar__cta { display: inline-flex; }
  .navbar__toggle { display: none; }
  /* Si el visitante ensancha con el menu abierto, el desplegable se queda puesto: sin el
     hamburguesa ya no hay forma de cerrarlo, y con los acordeones ocupa media pantalla. */
  .mobile-nav { display: none; }
}

/* ============ Hero ============ */
.hero {
  padding-top: 2.5rem;
  background-color: var(--color-surface);
  background-image: url("../assets/images/hero-bg.svg?v=2");
  background-position: top;
  background-size: 100% auto;
  background-repeat: no-repeat;
  background-position-y: calc(var(--header-height-mobile) * -1);
}
/* --product es el hero de la ficha de empresa de la maqueta (softdoit-html/detalle_cliente.php),
   que aun no se ha migrado; --comparison el de la comparativa/sector/subcomparador. Comparten
   declaracion pero no nombre: cuando llegue la ficha, cada una podra moverse por su lado.
   La home no lleva ninguno de los dos y conserva su espaciado. */
.hero--product,
.hero--comparison { padding-bottom: 2rem; }

@media (min-width: 960px) {
  .hero { background-position-y: calc(var(--header-height-desktop) * -1); }
}
.hero__inner { display: grid; gap: 3rem; }

.hero__title { font-size: clamp(2rem, 1.5rem + 2.2vw, 3.125rem); font-weight: 500; color: var(--color-navy); line-height: 1.15; margin-block: 1.25rem; }
.hero__lead { font-size: clamp(1.125rem, 1rem + 0.6vw, 1.5625rem); font-weight: 300; }
.hero__lead strong { font-weight: 600; }
/* Intro plegable (comparador): el texto del CMS son varios parrafos.
   El desvanecido va con mask-image y no con un degradado de color: el hero tiene fondo
   degradado, asi que un fade a color plano se notaria. La mascara ademas disimula que el corte
   cae a media linea, que es inevitable con un max-height fijo y tipografia fluida. */
.hero__lead-text { overflow: hidden; max-height: 11.5rem; transition: max-height 0.3s ease; }
.hero__lead[data-collapse]:not(.is-expanded) .hero__lead-text {
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
}
.hero__lead[data-collapse].is-expanded .hero__lead-text { max-height: 200rem; }
.hero__lead-more { display: inline-block; margin-top: 0.75rem; background: none; border: none; font-size: 1rem; }

.badge--pill {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: rgba(255,255,255,0.8);
  border-radius: var(--radius-pill);
  padding: 0.5rem 1rem;
  font-size: clamp(0.75rem, 0.65rem + 0.5vw, 0.9375rem);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-brand);
}

.hero__social-proof { display: flex; align-items: center; gap: 1rem; margin-top: 2rem; font-size: 1.125rem; color: var(--color-text-light); }
.hero__social-proof + .hero__social-proof { margin-top: 0.5rem; }

.hero__quick-links { margin-top: 3rem; margin-bottom: 40px; }

.hero__panel { background: var(--color-white); border-radius: var(--radius-md); box-shadow: var(--shadow-card); padding: 2rem 3rem; }
.hero__panel-title { color: var(--color-navy); margin-bottom: 1.25rem; }

.category-grid { display: grid; grid-template-columns: 1fr; gap: 0.75rem; }
.category-grid a {
  display: flex; align-items: center; gap: 0.6rem;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: 0.85rem 1rem;
  color: var(--color-brand);
  font-size: 1.125rem;
}
.category-grid a:hover { background: var(--color-surface-alt-hover); }

@media (min-width: 720px) {
  .category-grid { grid-template-columns: 1fr 1fr; }
}

.hero__panel .link-arrow { display: block; margin-top: 1.25rem; }

.hero__contact { display: flex; align-items: center; gap: 0.85rem; margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--color-surface); }
/* La foto es apaisada y la persona no esta en el centro: sin object-position el recorte
   circular cae sobre el hombro en vez de sobre la cara. */
.hero__avatar { border-radius: 50%; object-fit: cover; object-position: 62% center; width: 46px; height: 46px; }
.hero__contact p { font-size: 1.125rem; color: var(--color-navy); }
.hero__contact a { color: var(--color-brand); text-decoration: underline; }

@media (min-width: 1024px) {
  .hero__inner { grid-template-columns: 1.05fr 0.95fr; align-items: center; }
  .hero__inner--product { grid-template-columns: 2.8fr minmax(280px, 1fr); align-items: stretch; }
}

/* ============ Stats ============ */
.stats { padding-top: 5rem; margin-top: -1px; background: var(--color-surface); }
.stats:last-child { padding-bottom: 5rem; }
.stats__grid {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  padding: 1.75rem;
}
.stats__grid li { display: flex; align-items: center; gap: 0.85rem; }
.stats__grid strong { display: block; color: var(--color-brand); font-size: 1.5625rem; font-weight: 700; }
.stats__grid span { font-size: 1.125rem; font-weight: 300; }

.stats__icon { position: relative; display: inline-flex; flex-shrink: 0; width: 40px; height: 40px; isolation: isolate; }
.stats__icon::before {
  content: "";
  position: absolute;
  inset: -6.5px;
  background: url("../assets/icons/ellipse-glow.svg") center / contain no-repeat;
  z-index: -1;
}

@media (min-width: 720px) {
  .stats__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .stats__grid { grid-template-columns: repeat(4, 1fr); }
}

.stats__grid--footer { border: none; background: transparent; padding: 0; margin-block: 0; }

/* ============ Brands strip ============ */
.brands-strip { padding-top: 2.5rem; background: var(--color-surface); }
/* Solo donde la plantilla pide el modificador (la comparativa, entre el hero y la tabla). La
   home no lo pasa y conserva su espaciado.
   Va en padding y no en margin: la seccion siguiente (.ranking) trae margin-top: 80px, con el
   que un margin-bottom colapsaria -se quedaba en 80px y el modificador no hacia nada-. Ademas
   el fondo de la tira es el mismo que el del hero, asi que sin relleno inferior la tarjeta
   blanca terminaba justo en el borde de la banda y se leia como un corte. */
.brands-strip--spaced { padding-bottom: 2.5rem; }
.brands-strip__inner { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; background: var(--color-white); border-radius: var(--radius-md); padding: 1.75rem; }
.brands-strip__inner .eyebrow { justify-content: center; margin-bottom: 0; }
.brands-strip__logos { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 1.5rem; }

/* Los logotipos reales (logotipos/large-*) llegan a tamanos y proporciones dispares, asi que
   cada uno ocupa la misma caja y la imagen se escala dentro sin recortarse ni deformarse. */
.brands-strip__logo { flex: 0 0 auto; width: 160px; }
.brands-strip__link { display: block; }
.brands-strip__logo img { width: 100%; height: 60px; object-fit: contain; object-position: center; }

@media (min-width: 720px) {
  .brands-strip__inner { gap: 2rem; padding: 33px 56px; }
  .brands-strip__logos { gap: 3.5rem; }
  .brands-strip__logo { width: 180px; }
  .brands-strip__logo img { height: 70px; }
}

/* ============ Como funciona ============ */
.how-it-works {
  background: url("../assets/images/how-it-works-bg.svg") center / cover no-repeat, var(--color-navy);
  border-radius: var(--radius-md);
  width: min(var(--container-width), calc(100% - 2.5rem));
  margin-inline: auto;
  margin-top: 80px;
  margin-bottom: 5rem;
  padding-top: clamp(2rem, 1.25rem + 3vw, 4rem);
  padding-bottom: clamp(2rem, 1.25rem + 3vw, 4rem);
  text-align: center;
}
.how-it-works .container { max-width: calc(var(--container-width) - 2.5rem); }
.how-it-works .eyebrow { justify-content: center; }

.steps { display: grid; gap: 2rem; margin-top: 2.5rem; list-style: none; }
.steps__item {
  display: grid;
  grid-template-columns: 88px 1fr;
  column-gap: 1.25rem;
  align-items: start;
  position: relative;
  color: var(--color-white);
  text-align: left;
}
.steps__item h3 { grid-column: 2; margin-bottom: 0.5rem; }
.steps__item p { grid-column: 2; color: var(--color-text-light); font-size: 1rem; }
.steps__number {
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: center;
  width: 88px;
  height: auto;
}
.steps__arrow { display: none; }

@media (min-width: 900px) {
  .steps { grid-template-columns: 1fr auto 1fr auto 1fr; align-items: center; text-align: left; }
  .steps__arrow { display: flex; justify-content: center; align-self: center; }
}

/* ============ Carousels (categories & guides) ============ */
.categories { background: var(--color-surface); padding-bottom: 5rem; }
.filter-pills { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 2rem; }
.filter-pills--scroll { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 0.5rem; scrollbar-width: thin; }
.filter-pills__item {
  background: var(--color-surface);
  color: var(--color-brand);
  border: none;
  border-radius: var(--radius-pill);
  padding: 0.75rem 1.25rem;
  font-size: 1rem;
  white-space: nowrap;
}
.filter-pills__item.is-active { background: var(--color-brand); color: var(--color-white); }

.carousel {
  display: flex;
  gap: 1.5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 0.5rem;
  scrollbar-width: thin;
  overscroll-behavior-x: contain;
}
.filter-pills--scroll::-webkit-scrollbar,
.carousel::-webkit-scrollbar {
  height: 6px;
}
.carousel > li { scroll-snap-align: start; flex: 0 0 auto; }
/* display:flex gana al [hidden] del navegador: sin esto los tres ejes del carrusel se
   pintarian a la vez. */
.carousel[hidden] { display: none; }

.category-cards,
.guide-cards {
  margin: 0;
  padding-inline-start: max(1.25rem, calc((100vw - var(--container-width)) / 2));
  padding-inline-end: 1.25rem;
  scroll-padding-inline-start: max(1.25rem, calc((100vw - var(--container-width)) / 2));
}

.carousel-dots { display: flex; gap: 0.4rem; justify-content: flex-start; margin-top: 1.5rem; }
.carousel-dots span { width: 10px; height: 10px; border-radius: 50%; background: var(--color-text-light); }
.carousel-dots span.is-active { width: 48px; border-radius: 5px; background: var(--color-brand); }

.category-card {
  position: relative;
  width: min(80vw, 312px);
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.category-card > img:first-child { height: 100px; object-fit: cover; width: 100%; }
.category-card::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 100px;
  background: var(--color-brand);
  mix-blend-mode: multiply;
  opacity: 0.8;
  pointer-events: none;
}
.category-card__icon {
  position: absolute; top: 20px; left: 1.25rem; z-index: 1;
  width: 60px; height: 60px; border-radius: 15px;
  background: var(--color-white); box-shadow: var(--shadow-card);
  display: flex; align-items: center; justify-content: center;
}
/* Sin position aqui: el ::after de .category-card__link y la flecha se anclan a .category-card,
   que es lo que hace pulsable tambien la franja de la imagen. */
.category-card__body { padding: 15px 1.25rem 1.25rem; }
/* Los titulos de sector y necesidad son fichas SEO ("Software para gestion de residencias y
   centros de dia"), mucho mas largos que "ERP": se cortan a dos lineas y dejan libre la
   esquina de la flecha en vez de pasarle por debajo. */
.category-card__body h3 {
  color: var(--color-navy);
  padding-right: 3rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.category-card__body p { font-size: 1rem; margin-top: 0.5rem; }
/* Stretched link: el enlace del titulo estira su area pulsable sobre toda la tarjeta. El texto
   del <a> sigue siendo el titulo, asi que el foco de teclado y el nombre accesible no cambian. */
.category-card__link::after { content: ""; position: absolute; inset: 0; z-index: 2; }
.category-card:hover .category-card__link { text-decoration: underline; }
.category-card:hover .category-card__arrow { background: var(--color-surface-alt-hover); }
.category-card__arrow {
  position: absolute; right: 14px; bottom: 18px;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--color-surface-alt);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.category-card__arrow img { transform: rotate(-45deg); }

@media (min-width: 720px) {
  .category-card__arrow { width: 35px; height: 35px; }
}

.guide-card { width: min(85vw, 417px); background: var(--color-surface); border-radius: var(--radius-md); overflow: hidden; }
/* La tarjeta de guia no lleva foto (ver views/pages/home.twig): esta cabecera es el degradado que
   ocupa su sitio, con la altura que antes daba la imagen. */
.guide-card__media {
  position: relative;
  height: 200px;
  background: linear-gradient(135deg, var(--color-surface-alt) 0%, var(--color-lilac) 100%);
}
/* Cuatro variantes por posicion: doce tarjetas seguidas con el mismo degradado se leen como un
   error de carga. Ninguna oscurece lo bastante como para que la etiqueta blanca deje de leerse. */
.guide-card:nth-child(4n+2) .guide-card__media { background: linear-gradient(135deg, var(--color-surface) 0%, var(--color-surface-alt) 100%); }
.guide-card:nth-child(4n+3) .guide-card__media { background: linear-gradient(160deg, var(--color-lilac) 0%, var(--color-surface-alt) 100%); }
.guide-card:nth-child(4n) .guide-card__media { background: linear-gradient(200deg, var(--color-lilac) 0%, var(--color-surface) 100%); }
.guide-card__media .tag { position: absolute; top: 0; left: 0; margin: 0.75rem 0 0 0.75rem; background: var(--color-white); color: var(--color-brand); }
.guide-card__body { padding: 1.25rem; }
.guide-card h3 { font-size: 1.25rem; font-weight: 500; color: var(--color-navy); min-height: 3.2em; }
.guide-card__meta { display: flex; align-items: center; justify-content: space-between; margin-top: 1.75rem; font-size: 1rem; }

/* ============ Ranking ============ */
.ranking { padding-top: 0; }
#tabla-comparativa { margin-top: 80px; }
.ranking__filters { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 1.75rem; }
.select-pill {
  display: flex; align-items: center; gap: 0.5rem;
  background: var(--color-surface); border-radius: var(--radius-pill);
  padding: 0.15rem 0.5rem 0.15rem 1.25rem;
  color: var(--color-brand); font-size: 1rem;
}
.select-pill select {
  border: none; background: var(--color-brand); color: var(--color-white);
  border-radius: var(--radius-pill); padding: 0.65rem 1.1rem;
  flex: 1; min-width: 0;
}

@media (min-width: 720px) {
  .ranking__filters { flex-direction: row; flex-wrap: wrap; gap: 1rem; }
  .select-pill select { flex: none; min-width: 210px; }
}

.ranking__list { display: flex; flex-direction: column; gap: 1rem; }
.ranking__list--more { margin-top: 1rem; }
.ranking__row {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 1rem;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: 1.25rem;
}
.ranking__position { font-weight: 700; color: var(--color-navy); font-size: 1.125rem; }
.ranking__logo {
  grid-column: 2;
  width: 140px; height: 76px;
  background: var(--color-white); border-radius: var(--radius-md);
  padding: 1rem;
}
.ranking__logo img { width: 100%; height: 100%; object-fit: contain; }
/* Nombre de reserva: se ve solo cuando la casilla no tiene imagen (porque no hay logotipo en
   disco o porque el fichero no responde y el onerror lo retira). */
.ranking__logo-name {
  display: flex; align-items: center; justify-content: center;
  height: 100%;
  color: var(--color-navy); font-weight: 500; font-size: 0.9375rem;
  text-align: center; line-height: 1.2;
  overflow: hidden;
}
.ranking__logo:has(img) .ranking__logo-name { display: none; }
.ranking__info { grid-column: 1 / -1; }
.ranking__info h3 { font-size: 1.125rem; font-weight: 500; color: var(--color-navy); display: inline; margin-right: 0.5rem; }
.ranking__info .tag { margin-right: 0.4rem; }
.ranking__rating { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; font-size: 1rem; }
.ranking__rating strong { color: var(--color-navy); }

.star-rating { display: inline-flex; align-items: center; gap: 2px; }
.star-rating img { width: 16px; height: 16px; }
.star-rating--lg img { width: 20px; height: 20px; }
.ranking__consult { grid-column: 1 / -1; }
.ranking__actions { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 0.75rem; }
.ranking__actions .btn { width: 100%; }
.ranking__actions .btn img { transform: rotate(-45deg); }

@media (min-width: 720px) {
  .ranking__actions { flex-direction: row; }
  .ranking__actions .btn { flex: 1; width: auto; }
}

/* Filas del ranking de la home (las de la tabla comparativa no llevan posicion ni consulta y
   siguen con el reparto de arriba). En movil: posicion, logo y titulo en la primera linea; la
   valoracion en la segunda a lo ancho; consulta y boton juntos en la tercera. */
/* Cuatro columnas -- posicion, logo, resto y boton -- porque las dos lineas quieren repartos
   distintos: arriba manda el titulo y abajo la consulta. Anchos min-content/fijos y no auto: las
   celdas que cruzan varias columnas reparten su sobrante entre las auto, y asi el numero de
   posicion se hinchaba hasta 100px dejando el titulo en 126. */
.ranking__row--ranked { grid-template-columns: min-content 92px minmax(0, 1fr) auto; gap: 0.85rem 1rem; }
/* contents: el envoltorio desaparece y titulo y valoracion vuelven a ser celdas de la fila. */
.ranking__row--ranked .ranking__meta { display: contents; }
.ranking__row--ranked .ranking__logo { grid-column: 2; width: 92px; height: 58px; padding: 0.5rem; }
.ranking__row--ranked .ranking__info { grid-column: 3 / -1; }
.ranking__row--ranked .ranking__info h3 { display: block; margin-right: 0; }
/* Sin numero de fila explicito: cuando la solucion no tiene valoracion, la consulta y el boton
   suben solos a la linea que queda libre. */
.ranking__row--ranked .ranking__rating { grid-column: 1 / -1; margin-top: 0; }
.ranking__row--ranked .ranking__consult { grid-column: 1 / 4; }
.ranking__row--ranked .ranking__actions { grid-column: 4 / -1; flex-direction: row; justify-content: flex-end; }
.ranking__row--ranked .ranking__actions .btn { width: auto; }

@media (min-width: 960px) {
  /* Escritorio: una sola linea de celdas -- posicion, logo, titulo+valoracion juntos, consulta y
     boton --, todas centradas. El envoltorio deja de ser transparente aqui: con titulo y
     valoracion como celdas sueltas, la altura del logo se repartia entre sus dos filas y los
     separaba medio dedo. */
  .ranking__row--ranked { grid-template-columns: min-content 185px minmax(0, 1fr) auto auto; gap: 1.75rem; padding-inline: 2.5rem; }
  .ranking__row--ranked .ranking__meta { display: flex; flex-direction: column; gap: 0.4rem; grid-column: 3; }
  .ranking__row--ranked .ranking__logo { grid-column: 2; width: 185px; height: 96px; padding: 1rem; }
  .ranking__row--ranked .ranking__consult { grid-column: 4; }
  .ranking__row--ranked .ranking__actions { grid-column: 5; justify-content: flex-start; }
  /* El ranking de la home no pinta la consulta: sin retirar su pista quedan dos gaps seguidos
     -3,5rem- entre el titulo y el boton. */
  .ranking__row--ranked:not(:has(.ranking__consult)) { grid-template-columns: min-content 185px minmax(0, 1fr) auto; }
  .ranking__row--ranked:not(:has(.ranking__consult)) .ranking__actions { grid-column: 4; }
}

.ranking__more-wrap { position: relative; overflow: hidden; max-height: 130px; transition: max-height 0.3s ease; }
.ranking__more-wrap.is-expanded { max-height: 2000px; }
.ranking__fade {
  position: absolute; inset: auto 0 0 0; height: 130px;
  display: flex; align-items: flex-end; justify-content: center; padding-bottom: 1.5rem;
  background: linear-gradient(180deg, rgba(255,255,255,0), var(--color-white) 70%);
}
.ranking__more-wrap.is-expanded .ranking__fade { position: static; height: auto; background: none; margin-top: 1.5rem; padding-bottom: 0; }
.ranking__more { display: block; background: none; border: none; }

@media (min-width: 960px) {
  .ranking__row { grid-template-columns: auto 185px 1fr auto auto; gap: 1.75rem; padding-inline: 2.5rem; }
  .ranking__logo { grid-column: auto; width: 185px; height: 96px; }
  .ranking__info { grid-column: auto; }
  .ranking__consult { grid-column: auto; }
  .ranking__actions { grid-column: auto; }
}

/* ============ CTA banner ============ */
.cta-banner { margin-bottom: 5rem; }
.cta-banner__inner {
  background:
    linear-gradient(100deg, rgba(2,1,90,0.94) 30%, rgba(2,1,90,0.75) 60%, rgba(11,62,147,0.35)),
    url("../assets/images/cta-consultoria-2.webp") center / cover no-repeat;
  color: var(--color-white);
  border-radius: var(--radius-md);
  padding: clamp(2.5rem, 1.5rem + 4vw, 5rem) clamp(1.5rem, 1rem + 3vw, 5rem);
}
.cta-banner__lead { margin-top: 1.5rem; max-width: 34rem; }
.cta-banner__lead strong { font-weight: 600; }
.cta-banner__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; margin-top: 2rem; }
.cta-banner__phone strong { font-weight: 700; }

/* .about's own background is dark too, so its padding-top alone doesn't read as a visual gap after cta-banner */
.cta-banner + .about { margin-top: 2.5rem; }

/* ============ Trust ============ */
.trust { margin-bottom: 5rem; }
/* Solo en la home: anula el padding-top generico de section para que la tira quede pegada al cta-banner */
.trust--flush { padding-top: 0 !important; }
.trust__eyebrow { justify-content: center; }
.trust__title { text-align: center; max-width: 56rem; margin-inline: auto; }
.trust__logos { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 1.5rem; margin-top: 2.5rem; }
.trust__logo { height: 40px; width: auto; }

@media (min-width: 720px) {
  .trust__logos { gap: 2.5rem; }
}

/* ============ About ============ */
.about {
  background:
    linear-gradient(135deg, rgba(58,31,196,0.35), rgba(2,1,90,0.55) 65%),
    url("../assets/images/about-bg-acerca-de.webp") center / cover no-repeat;
  color: var(--color-white);
  padding-bottom: 5rem;
}
.about__inner { display: grid; gap: 3rem; }
.about__title, .about h2 { max-width: 32rem; }
.about__author { display: flex; align-items: center; gap: 1rem; margin-top: 2rem; }
.hero__panel .about__author { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--color-surface); }
/* Misma foto que .hero__avatar -y mismo recorte-: es apaisada y la persona no esta en el centro,
   asi que sin object-position el circulo cae sobre el hombro en vez de sobre la cara. */
.about__author img { border-radius: 50%; width: 60px; height: 60px; object-fit: cover; object-position: 62% center; }
/* Los dos textos van a 18px sin negrita (Figma 59:910 y 59:911); el <strong> se queda por
   semantica, no por peso. */
.about__author strong { display: block; font-size: 1.125rem; font-weight: 400; }
.about__author span { color: var(--color-lilac); font-size: 1.125rem; }
/* En el panel del hero el fondo es blanco, asi que ahi si valen los colores del diseño: navy
   para el nombre y --color-text-light (#989eb8) para el cargo. Sobre el fondo oscuro del bloque
   .about se conservan el blanco heredado y el lilac, que es lo unico que contrasta. */
.hero__panel .about__author strong { color: var(--color-navy); }
.hero__panel .about__author span { color: var(--color-text-light); }

.about__text { margin-bottom: 1.25rem; }

.newsletter {
  background: rgba(2, 1, 90, 0.6);
  border-radius: var(--radius-md);
  padding: 1.75rem;
  margin-top: 1.5rem;
  min-height: 22rem;
}
.newsletter__todo { color: var(--color-white); }
.newsletter h3 { font-size: clamp(1.5rem, 1.3rem + 0.8vw, 1.875rem); font-weight: 400; margin: 0.5rem 0; }
.newsletter__fields { display: grid; gap: 0.85rem; margin: 1.25rem 0; }
.newsletter__fields input {
  width: 100%; border: none; border-radius: var(--radius-md);
  padding: 0.85rem 1rem; background: rgba(255,255,255,0.9);
}
.newsletter__consent { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 1rem; margin-bottom: 1.25rem; }
.newsletter__consent a { text-decoration: underline; }
.newsletter__consent input { margin-top: 0.2rem; }

@media (min-width: 720px) {
  .newsletter__fields { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1024px) {
  .about__inner { grid-template-columns: 1fr 1fr; }
}

/* ============ Footer ============ */
.site-footer { background: var(--color-surface); padding-top: 2.5rem; }
.footer-bottom {
  background: url("../assets/images/footer-bg.svg") bottom / 100% auto no-repeat;
  padding-bottom: 2.5rem;
}
.footer-main { display: flex; flex-direction: column; gap: 1.5rem; margin-bottom: 2.5rem; }
.footer-main__brand p {
  margin-top: 1rem;
  font-size: clamp(1.375rem, 1.1rem + 1.2vw, 1.875rem);
  font-weight: 500;
  line-height: 1.35;
  color: var(--color-navy);
  max-width: 36rem;
}
.footer-main__social { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.footer-main__social .btn { height: 50px; padding-inline: 1.25rem; }
.footer-main__social a:not(.btn) {
  width: 50px; height: 50px; padding-inline: 0; border-radius: var(--radius-md);
  background: var(--color-white); display: flex; align-items: center; justify-content: center;
}

@media (min-width: 900px) {
  .footer-main { flex-direction: row; align-items: center; justify-content: space-between; }
}

.footer-columns {
  background: var(--color-white);
  border-radius: var(--radius-md);
  padding: 2rem;
  display: grid;
  gap: 2rem;
  margin-bottom: 2.5rem;
}
.footer-columns h3 { font-size: 0.9375rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--color-text); margin-bottom: 1rem; }
.footer-columns ul { display: flex; flex-direction: column; gap: 0.85rem; }
.footer-columns a:not(.btn) { color: var(--color-brand); font-size: 1rem; }
.footer-columns__contact { display: flex; flex-direction: column; gap: 0.85rem; align-items: flex-start; }

@media (min-width: 900px) {
  .footer-columns { grid-template-columns: repeat(3, 1fr); }
}

.footer-legal { display: flex; flex-direction: column; gap: 1rem; font-size: 0.875rem; }
.footer-legal p { color: var(--color-navy); }
.footer-legal ul { display: flex; flex-wrap: wrap; gap: 1.5rem; color: var(--color-white); }
.footer-legal a:hover { text-decoration: underline; }

@media (min-width: 900px) {
  .footer-legal { flex-direction: row; align-items: center; justify-content: space-between; }
}

/* ============ Ficha de cliente ============ */
.product-summary__top { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 1.25rem; margin-bottom: 1.5rem; }
.product-summary__logo {
  width: 280px;
  height: 185px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 1rem 1.5rem;
}
.product-summary__logo img { max-width: 100%; max-height: 100%; height: auto; width: auto; }
.product-summary__intro { flex: 1 1 320px; min-width: 0; }
.product-summary__badges { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.product-summary__badges .tag { font-size: 0.6875rem; }

.product-summary__rating {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  margin-top: 1.5rem;
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 1.25rem 1.5rem;
}
.product-summary__rating-label { color: var(--color-brand); font-weight: 500; font-size: 0.9375rem; letter-spacing: 0.09em; text-transform: uppercase; }
.product-summary__rating-score { color: var(--color-brand); font-weight: 700; font-size: 1.5625rem; }
.product-summary__rating .link-arrow { margin-left: auto; }

.product-summary__panel-actions { display: flex; flex-direction: column; gap: 0.75rem; margin-block: 1.5rem; }
/* Scoped here, not on the shared .btn: that base rule is used site-wide, so widening it would
   also push out every other button on already-reviewed pages. */
.product-summary__panel-actions .btn { width: 100%; padding-block: 1.1rem; gap: 0.75rem; }
.product-summary__panel-actions .btn img { flex-shrink: 0; }
.product-summary__panel-phone { font-size: 1.125rem; color: var(--color-navy); }
.product-summary__panel-phone a { color: var(--color-brand); text-decoration: underline; }

.product-detail { padding-top: 0; }

.product-tabs { display: flex; flex-wrap: wrap; gap: 1.5rem 2rem; margin-top: 2.5rem; border-bottom: 1px solid var(--color-surface-alt); }
.product-tabs__item {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding-bottom: 1.25rem;
  color: var(--color-brand);
  font-size: 1.125rem;
}
.product-tabs__item.is-active { color: var(--color-navy); font-weight: 700; border-bottom-color: var(--color-brand); }

.product-tabs__panel[hidden] { display: none; }

.product-detail__inner { display: grid; gap: 2rem; margin-top: 2rem; }
.product-detail__panel-inner { margin-top: 2rem; }
.product-detail__text { display: flex; flex-direction: column; gap: 1rem; }
.product-detail__text a { color: var(--color-brand); text-decoration: underline; }
.product-detail__quote { background: var(--color-surface); border-radius: var(--radius-md); padding: 2rem; }
.product-detail__quote-mark { display: block; height: 40px; overflow: hidden; color: var(--color-brand); font-size: 4rem; font-weight: 300; line-height: 1; margin-bottom: 0.25rem; }
.product-detail__quote p { font-size: 1.375rem; font-weight: 300; margin-bottom: 1.5rem; }

.advantages__cta { margin-top: 1.5rem; }

@media (min-width: 1024px) {
  .product-detail__inner { grid-template-columns: 1.3fr 1fr; align-items: start; }
}

.solutions__lead { margin-top: 1rem; }

.solution-card { background: var(--color-surface); border-radius: var(--radius-md); padding: 2rem; margin-top: 1.5rem; }
.solution-card__main { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2rem; }
.solution-card__text { flex: 1 1 480px; display: flex; flex-direction: column; gap: 1rem; }
.solution-card__text h3 { color: var(--color-navy); font-size: 1.125rem; font-weight: 500; }
.solution-card__actions { display: flex; flex-direction: column; gap: 0.75rem; flex: 0 0 auto; }
.solution-card__actions .btn img { transform: rotate(-45deg); }

.feature-pills { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.5rem; }
.feature-pills li {
  display: flex; align-items: center; gap: 0.4rem;
  background: var(--color-white);
  border-radius: var(--radius-sm);
  padding: 0.4rem 0.85rem;
  color: var(--color-brand);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ============ Ficha de cliente: funcionalidades de la solucion ============ */
/* .listoffeatures/.tip_feature is legacy markup from empresa::get_tips_solution()
   (panel/classes/empresa_data.php:5599), emitted |raw in views/partials/product-tabs.twig --
   captured, not rebuilt. Each row carries its own icon as a Font Awesome Pro "duotone" glyph
   (<i class="fad fa-check-circle text-success">, or fa-times-circle/text-danger), which a kit
   script inside footer_scripts_raw rewrites client-side into an inline
   <svg class="svg-inline--fa ... text-success/text-danger">. Neither .text-success nor
   .text-danger carries a colour anywhere on this page, and the duotone glyph's two paths both
   use fill="currentColor", so with none set it renders as a flat grey blob -- the unstyled page.
   Fixed the way the mockup already draws this exact included/excluded pattern
   (softdoit-html/detalle_cliente.php:166-175, feature-pills--included/--excluded): the real
   check-circle.svg/x-circle.svg assets, a solid-colour circle with a white glyph baked in, not a
   colour tinted onto the FA icon. The FA icon is hidden and the asset takes its place; which one
   is picked off whether the row's icon carries .text-success or .text-danger. */
.listoffeatures { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1.25rem; }
.tip_feature { display: flex; align-items: center; gap: 0.6rem; color: var(--color-navy); font-size: 0.9375rem; }
.tip_feature i, .tip_feature svg { display: none; }
.tip_feature::before {
  content: '';
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  background-size: contain;
  background-repeat: no-repeat;
  background-image: url('/assets/icons/check-circle.svg');
}
.tip_feature:has(.text-danger)::before { background-image: url('/assets/icons/x-circle.svg'); }

/* ============ Ficha de cliente: especificaciones ============ */
/* The vendor page's specification grid (views/partials/specs-grid.twig, inside the Descripcion
   tab -- views/pages/empresa.twig keeps a standalone .specs-section fallback for when that tab
   is absent). The legacy view drew it with .row > .col-12.col-sm-6.col-md-4.whitebg
   (templates/empresa.php:615-628), so this sheet carried nothing for it and the three columns
   stacked full width with no spacing.

   The three colours are NOT decoration. get_especificaciones_precios()/_tipos()/_desplegue()
   (panel/classes/empresa_data.php:1287-1366) print EVERY option a product could have and cross
   out the ones it does not offer, wrapping them in <span class="tipdisable"> with a
   fa-times-circle. With no colour, a crossed-out "Pago unico" reads exactly like an offered one:
   a false claim about a real company's product. The values are the legacy's own, from
   css/pagina2.css:2300-2311 (.whitebg i, .whitebg span.tipdisable, .whitebg span.tipdisable i) --
   a sheet NO Twig page loads, since views/partials/head.twig emits style-v2.css and nothing else,
   which is why they are ported here instead of copying the whitebg class into the template, where
   it would be inert. Scoped to .specs-grid__item so no other legacy tipdisable gets repainted.

   The `i` selectors are NOT enough on their own: the Font Awesome kit script
   (kit.fontawesome.com/111496d33e.js, loaded by footer_scripts_raw) replaces every
   <i class="fad ..."> with an inline <svg class="svg-inline--fa ..."> at runtime, so the
   original <i> is gone from the DOM by the time this paints and a plain `i` rule stops matching.
   Both the "fad" (duotone) svg's paths use fill="currentColor", so targeting the svg with `color`
   still works the same way the `i` rule would have. */
.specs-section { margin-top: 2.5rem; }
.specs-grid { display: grid; gap: 1.5rem; }
.specs-grid__item {
  background: var(--color-white);
  border: 1px solid var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: 1.5rem;
  line-height: 2;
}
.specs-grid__item i,
.specs-grid__item svg { color: #80bd43; }
.specs-grid__item .tipdisable { color: #cdcdcd; }
.specs-grid__item .tipdisable i,
.specs-grid__item .tipdisable svg { color: #ee5265; }

@media (min-width: 720px) {
  .specs-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .specs-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ============ Software ERP (category page) ============ */
.status-online { display: inline-flex; align-items: center; gap: 0.4rem; color: #00a323; font-size: 1rem; font-weight: 500; margin-top: 0.75rem; }

.quick-links-section { padding-top: 40px; padding-bottom: 40px; }
.related-topics .eyebrow { margin-bottom: 1.875rem; }

.quick-links-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  background: var(--color-white);
  border-radius: var(--radius-md);
  padding: 1.75rem 2rem;
}
.quick-links { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.quick-links__label { color: var(--color-navy); font-weight: 500; }
.quick-links-card .quick-links__label { color: var(--color-text); font-weight: 400; }
.quick-links-card .quick-links__label strong { font-weight: 700; }
.quick-links a {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: 0.75rem 1.25rem;
  color: var(--color-brand);
  font-size: 1.125rem;
}

.hero__sponsor { margin-top: 1.5rem; padding-bottom: 40px; }
.sponsor-banner { display: flex; flex-direction: column; align-items: center; gap: 1.25rem; background: var(--color-white); border-radius: var(--radius-md); padding: 1.75rem 3.5rem; text-align: center; }
.sponsor-banner__eyebrow { margin-bottom: 0; }
.sponsor-banner__logos { display: flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: 2rem; }
.sponsor-banner__logo { height: 32px; width: auto; }

@media (min-width: 720px) {
  .sponsor-banner { flex-direction: row; justify-content: flex-start; text-align: left; gap: 2rem; }
}

.ranking__meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem 1rem; color: var(--color-text-light); font-size: 1rem; margin-bottom: 1.5rem; }
.ranking__meta p { margin: 0; }
.ranking__meta strong { color: var(--color-navy); font-weight: 400; }

/* La tabla comparativa reparte la fila con .ranking__row--ranked, igual que el ranking de la
   home, desde que views/pages/comparison.twig pinta las filas con partials/ranking-row.twig.
   Aqui vivian ademas un grid-template-columns y un grid-column propios, de cuando la fila era una
   copia a mano con otras celdas: al ser posteriores en la hoja y de la misma especificidad le
   ganaban a --ranked, y dejaban la posicion en la pista de 185px reservada al logotipo (mas un
   padding lateral de 1.25rem contra los 2.5rem de la home). Retirados: la fila es la misma en las
   dos paginas y debe repartirse igual. */
.compare-table .tag { font-size: 0.75rem; }
.compare-table .ranking__price { font-size: 1rem; color: var(--color-text-light); }
.compare-table .ranking__price::before { content: "·"; margin-right: 0.5rem; }
.compare-table .ranking__price strong { color: var(--color-text); font-weight: 400; }

.erp-cta {
  position: relative;
  margin-block: 2.5rem;
  background:
    linear-gradient(100deg, rgba(2,1,90,0.94) 30%, rgba(2,1,90,0.75) 60%, rgba(11,62,147,0.35)),
    url("../assets/images/cta-erp-consultoria.webp") center / cover no-repeat;
  color: var(--color-white);
  border-radius: var(--radius-md);
  padding: clamp(2rem, 1.5rem + 2.5vw, 3.5rem) clamp(1.5rem, 1rem + 2vw, 3rem);
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.erp-cta__banner { max-width: 26rem; }
.erp-cta__title { font-size: clamp(1.375rem, 1.1rem + 1vw, 1.5625rem); font-weight: 700; }
.erp-cta__lead { margin-top: 1rem; }
.erp-cta__phone { margin-top: 1.5rem; }

.erp-cta__upsell {
  background: var(--color-white);
  color: var(--color-navy);
  border-radius: var(--radius-md);
  padding: 1.75rem;
  display: flex; flex-direction: column; gap: 1.25rem; align-items: flex-start;
}
.erp-cta__upsell h3 { font-size: 1.25rem; font-weight: 700; color: var(--color-brand); }

@media (min-width: 1024px) {
  .erp-cta { flex-direction: row; align-items: center; justify-content: space-between; }
  .erp-cta__upsell {
    position: absolute;
    top: 50%;
    right: clamp(1.5rem, 1rem + 2vw, 3rem);
    transform: translateY(-50%);
    width: 320px;
    border-radius: var(--radius-md) var(--radius-md) var(--radius-md) 48px;
    box-shadow: var(--shadow-card);
  }
}

.solution-index { background: var(--color-surface); border-radius: var(--radius-md); padding: 1.75rem 2rem; margin-top: 2.5rem; }
.solution-index h3 { color: var(--color-navy); font-size: 1.125rem; font-weight: 500; margin-bottom: 0.75rem; }

.solution-detail { background: var(--color-surface); border-radius: var(--radius-md); padding: 2rem; margin-top: 1.5rem; }
.solution-detail:last-of-type { margin-bottom: 80px; }
.solution-detail__header { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; justify-content: space-between; margin-bottom: 1.5rem; }
.solution-detail__identity { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; }
.solution-detail__logo {
  width: 140px; height: 76px;
  background: var(--color-white); border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-navy); font-weight: 700; text-align: center; padding: 0.5rem;
}
.solution-detail__logo img { max-width: 100%; max-height: 100%; }
.solution-detail__identity h3 { color: var(--color-navy); font-size: 1.125rem; font-weight: 500; }
.solution-detail__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.solution-detail__tags .tag { border-radius: var(--radius-pill); }
.solution-detail__actions { display: flex; gap: 0.75rem; flex-wrap: wrap; }

.solution-detail__body { display: grid; gap: 2rem; margin-top: 1.5rem; }
.solution-detail__text { display: flex; flex-direction: column; gap: 1.5rem; max-width: calc(100% - 100px); }
.solution-detail__block h4 { color: var(--color-brand); font-size: 0.9375rem; font-weight: 500; letter-spacing: 0.09em; text-transform: uppercase; margin-bottom: 0.75rem; }
.solution-detail__block ul { display: flex; flex-direction: column; gap: 0.5rem; }
.solution-detail__block li { padding-left: 1.25rem; position: relative; }
.solution-detail__block li::before { content: ""; position: absolute; left: 0; top: 0.55em; width: 6px; height: 6px; border-radius: 50%; background: var(--color-brand); }
.solution-detail__screenshot { background: var(--color-text-light); border-radius: var(--radius-md); aspect-ratio: 16 / 9; }

.solution-detail__footer { background: var(--color-white); border-radius: var(--radius-md); padding: 1.75rem; margin-top: 1.5rem; display: grid; gap: 1.5rem; }
.solution-detail__pros-cons { display: grid; gap: 1.5rem; }
.solution-detail__pros h4, .solution-detail__cons h4 { font-size: 1rem; font-weight: 500; margin-bottom: 0.75rem; }
.solution-detail__pros h4 { color: #00a323; }
.solution-detail__cons h4 { color: #eb5757; }
.solution-detail__pros ul, .solution-detail__cons ul { display: flex; flex-direction: column; gap: 0.6rem; }
.solution-detail__pros li, .solution-detail__cons li { display: flex; align-items: flex-start; gap: 0.6rem; }
.solution-detail__pros li img, .solution-detail__cons li img { flex: none; margin-top: 0.15rem; }
.solution-detail__rating { padding-top: 1.5rem; border-top: 1px solid var(--color-surface-alt); }
.solution-detail__rating-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.5rem; margin-top: 0.75rem; }
.solution-detail__rating-score { color: var(--color-brand); font-weight: 700; font-size: 1.5625rem; }
.solution-detail__rating-breakdown { display: flex; flex-wrap: wrap; gap: 0.4rem 1.25rem; font-size: 0.9375rem; }
.solution-detail__rating-breakdown strong { color: var(--color-brand); }
.solution-detail__footer-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; }

@media (min-width: 1024px) {
  .solution-detail__body { grid-template-columns: 1fr 260px; align-items: start; }
  .solution-detail__pros-cons { grid-template-columns: 1fr 1fr; }
}

.faq-section { background: var(--color-surface); padding-bottom: 80px; }
.faq { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 2rem; }
.faq__item { background: var(--color-white); border-radius: var(--radius-md); overflow: hidden; }
.faq__item > h3 { display: contents; }
.faq__question {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: none; border: none; text-align: left;
  padding: 1.25rem 1.5rem;
  color: var(--color-navy); font-size: 1.125rem; font-weight: 500;
}
.faq__question img { flex: none; transition: transform 0.2s ease; }
.faq__item.is-open .faq__question img { transform: rotate(180deg); }
.faq__answer { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; padding-inline: 1.5rem; }
.faq__answer p { padding-bottom: 1.5rem; color: var(--color-text); }
.faq__item.is-open .faq__answer { max-height: 20rem; }

/* ============ Migas de pan ============ */
/* Tambien las de views/pages/comparison.twig, que hasta ahora salian sin estilo (heredaban el
   reset: lista sin viñeta, en bloque y sin separadores). */
.breadcrumb { padding-top: 1.5rem; }
/* templates/list_breadcrumb.php casi siempre pinta <ol class="breadcrumb ..."> directo, sin div
   envolvente: el <ol> ES .breadcrumb, no un descendiente suyo. Sin este segundo selector la regla
   no se aplica nunca en ese caso y cada <li> queda como su propia fila (por la regla de abajo). */
.breadcrumb ol, ol.breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; font-size: 0.9375rem; }
.breadcrumb li { display: flex; align-items: center; gap: 0.5rem; color: var(--color-text-light); }
.breadcrumb li + li::before { content: "/"; color: var(--color-text-light); }
.breadcrumb a { color: var(--color-brand); }
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb [aria-current="page"] { color: var(--color-text-light); }

/* ============ Paginas de contenido basico (legales y corporativas) ============ */
.page-hero {
  padding-top: 0;
  /* Sin esto, el margen superior del primer hijo se escapa de la seccion (padding-top: 0, sin
     borde) y aparece como una franja blanca entre el menu y el fondo del hero: pasa en cuanto la
     pagina no abre con las migas, que eran las que cortaban ese colapso. */
  display: flow-root;
  padding-bottom: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  background-color: var(--color-surface);
  background-image: url("../assets/images/hero-bg.svg?v=2");
  background-position: top;
  background-size: 100% auto;
  background-repeat: no-repeat;
  background-position-y: calc(var(--header-height-mobile) * -1);
}
@media (min-width: 960px) {
  .page-hero { background-position-y: calc(var(--header-height-desktop) * -1); }
}
.page-hero .breadcrumb { padding-top: 2rem; }
/* El mismo aire por arriba cuando la pagina no abre con las migas sino con el rotulo, que sin esto
   queda pegado al menu (indice de reportajes). */
.page-hero .eyebrow { padding-top: 2rem; }
.page-hero__title {
  font-size: clamp(1.875rem, 1.4rem + 1.9vw, 2.5rem);
  font-weight: 500;
  color: var(--color-navy);
  line-height: 1.2;
  margin-block: 1.25rem;
}
.page-hero__lead { font-size: 1.125rem; font-weight: 300; }
.page-hero__lead a { color: var(--color-brand); text-decoration: underline; }
.page-hero__lead blockquote {
  margin: 1.25rem 0 0;
  padding-left: 1.25rem;
  border-left: 3px solid var(--color-brand);
  color: var(--color-navy);
}

.page-content { padding-bottom: 80px; }
.page-content__inner { display: grid; gap: 2.5rem; align-items: start; }

/* .page--gradient: 404 y baja de comunicaciones (StaticContentData) -- el mismo fondo de
   .page-hero, pero en el div que envuelve hero+content en vez de solo en el hero, para que no
   haya franja blanca en paginas cortas que no llegan a llenar la imagen. .page-hero/.page-content
   quedan sin fondo propio para no repetirla dos veces. */
.page--gradient {
  background-color: var(--color-surface);
  background-image: url("../assets/images/hero-bg.svg?v=2");
  background-position: top;
  background-size: 100% auto;
  background-repeat: no-repeat;
  background-position-y: calc(var(--header-height-mobile) * -1);
}
@media (min-width: 960px) {
  .page--gradient { background-position-y: calc(var(--header-height-desktop) * -1); }
}
.page--gradient .page-hero,
.page--gradient .page-content { background: none; }
.page--gradient .page-hero .container,
.page--gradient .page-content__inner { text-align: center; }
.page--gradient .page-hero__title { margin-top: 80px; }
/* .page-content__inner ya hereda text-align:center, pero .page-prose es donde vive el texto de
   verdad (content_html) -- explicito para no depender de que nada intermedio lo reescriba. Las
   imagenes son display:block (reset global), asi que text-align no las centra: hace falta margin
   aparte. */
.page--gradient .page-prose { text-align: center; }
/* La causa real de que no se viera centrado: a partir de 960px .page-content__inner reserva
   "minmax(0, 1fr) 300px" para la columna del indice (.page-toc), y .page-prose queda fijo en
   grid-column:1 -- sin indice esa columna se queda vacia y .page-prose ocupa solo la mitad
   izquierda, centrando el texto dentro de ESA mitad en vez de la pagina entera. Una sola columna
   aqui, sin la reserva del indice (que estas dos paginas no usan). */
.page--gradient .page-content__inner { grid-template-columns: 1fr; }
.page--gradient .page-prose img { margin-inline: auto; }

.page-toc__box {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: 1.25rem 1.5rem;
}
.page-toc__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  color: var(--color-navy);
  font-size: 1.125rem;
  font-weight: 500;
  cursor: pointer;
  /* El triangulo por defecto de <details> desentona con el resto de la maqueta; se sustituye
     por un chevron propio (list-style para Firefox, ::-webkit-details-marker para Chrome). */
  list-style: none;
}
.page-toc__title::-webkit-details-marker { display: none; }
.page-toc__title::after {
  content: "";
  flex: none;
  width: 10px; height: 10px;
  border-right: 2px solid var(--color-brand);
  border-bottom: 2px solid var(--color-brand);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.2s ease;
}
.page-toc__box[open] .page-toc__title::after { transform: rotate(-135deg) translate(-2px, -2px); }
.page-toc__list { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1rem; font-size: 0.9375rem; }
.page-toc__list a { color: var(--color-brand); }
.page-toc__list a:hover { text-decoration: underline; }
/* Los h3 del contenido cuelgan del h2 anterior: la sangria es lo que hace legible el indice
   cuando el editor mezcla los dos niveles. */
.page-toc__item--h3 { padding-left: 0.9rem; color: var(--color-text-light); }
.page-toc__item--h3 a { color: var(--color-text); }

/* Prosa del editor: el HTML llega con las etiquetas crudas (h2/h3/p/ul/table...), asi que aqui
   se deshace el reset global -- ul/ol sin viñeta, h1-h3/p sin margen -- para este contenedor y
   solo para el. */
.page-prose { font-size: 1.0625rem; }
.page-prose > *:first-child { margin-top: 0; }
.page-prose h2 {
  font-size: clamp(1.375rem, 1.15rem + 0.9vw, 1.625rem);
  font-weight: 500;
  color: var(--color-navy);
  line-height: 1.3;
  margin-top: 2.5rem;
  margin-bottom: 1rem;
  /* La cabecera es sticky: sin esto, saltar desde el indice deja el titulo debajo del menu. */
  scroll-margin-top: calc(var(--header-height-mobile) + 1rem);
}
.page-prose h3 {
  font-size: 1.25rem;
  font-weight: 500;
  color: var(--color-navy);
  margin-top: 2rem;
  margin-bottom: 0.75rem;
  scroll-margin-top: calc(var(--header-height-mobile) + 1rem);
}
.page-prose h4 { font-size: 1.0625rem; font-weight: 700; color: var(--color-navy); margin: 1.5rem 0 0.5rem; }
.page-prose p { margin-bottom: 1.25rem; }
.page-prose a { color: var(--color-brand); text-decoration: underline; }
.page-prose strong { font-weight: 600; color: var(--color-navy); }
.page-prose ul, .page-prose ol { margin: 0 0 1.25rem; padding-left: 1.5rem; }
.page-prose ul { list-style: disc; }
.page-prose ol { list-style: decimal; }
.page-prose li { margin-bottom: 0.5rem; }
.page-prose li::marker { color: var(--color-brand); }
.page-prose blockquote {
  margin: 1.5rem 0;
  padding: 1.25rem 1.5rem;
  background: var(--color-surface);
  border-left: 3px solid var(--color-brand);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  color: var(--color-navy);
}
.page-prose img { border-radius: var(--radius-md); margin: 1.5rem 0; }
.page-prose hr { border: none; border-top: 1px solid var(--color-surface-alt); margin: 2.5rem 0; }
/* El editor guarda tablas con anchos fijos: sin el contenedor con scroll propio, una tabla ancha
   empuja la pagina entera y aparece scroll horizontal en el body. */
.page-prose table { display: block; overflow-x: auto; width: 100%; border-collapse: collapse; margin: 1.5rem 0; }
.page-prose th, .page-prose td { border: 1px solid var(--color-surface-alt); padding: 0.75rem 1rem; text-align: left; }
.page-prose th { background: var(--color-surface); color: var(--color-navy); font-weight: 500; }
/* Restos de la rejilla vieja (.row/.col-*) que el editor sigue guardando dentro del contenido:
   en la maqueta v2 no existen como rejilla, asi que se dejan fluir en una sola columna. */
.page-prose .row, .page-prose [class^="col-"], .page-prose [class*=" col-"] { width: auto; margin: 0; padding: 0; }

@media (min-width: 960px) {
  .page-content__inner { grid-template-columns: minmax(0, 1fr) 300px; column-gap: 4rem; }
  .page-toc { grid-column: 2; grid-row: 1; position: sticky; top: calc(var(--header-height-desktop) + 1.5rem); }
  .page-prose { grid-column: 1; grid-row: 1; }
  .page-prose h2, .page-prose h3 { scroll-margin-top: calc(var(--header-height-desktop) + 1rem); }
}

/* ============ Listado de comparadores ============ */
/* El hero ya deja su propio padding-bottom, asi que aqui se recorta el padding-top generico de
   <section> para que el buscador no quede tan separado del titulo. */
.comparators-index { padding-top: clamp(1.5rem, 1.15rem + 1.4vw, 2.25rem); }
.comparators-index__search { position: relative; margin-bottom: 2.5rem; }
.comparators-index__search input {
  width: 100%;
  padding: 0.9rem 1.25rem;
  border: 1px solid var(--color-surface-alt);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-navy);
}
.comparators-index__search input::placeholder { color: var(--color-text-light); }

.comparators-index__group + .comparators-index__group { margin-top: 3rem; }
.comparators-index__group .section-lead { margin-bottom: 1.5rem; }

.comparators-index__list { display: grid; grid-template-columns: 1fr; gap: 0.75rem; }
.comparators-index__list a {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  height: 100%;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: 0.85rem 1rem;
  color: var(--color-brand);
}
.comparators-index__list a:hover { background: var(--color-surface-alt-hover); }
.comparators-index__name { flex: 1 1 auto; }
/* Los iconos de /public_images son SVG de trazo fino y tamanos dispares: la caja fija evita que
   cada tarjeta empiece su texto en un sitio distinto. */
.icon_type_of_software { flex: 0 0 24px; display: flex; align-items: center; justify-content: center; }
.icon_type_of_software img { width: 24px; height: 24px; object-fit: contain; }
/* Los subtipos cuelgan de un tipo principal (idmother>0): el bloque viejo los marcaba con esta
   misma clase, y aqui se distinguen con un fondo mas claro en vez de con sangria, que en una
   rejilla de varias columnas no se leeria. */
.list_types_of_software.subtype a { background: var(--color-surface); font-size: 0.9375rem; }
.list_types_of_software .tag { flex: 0 0 auto; font-size: 0.75rem; padding: 0.2rem 0.5rem; }
.populartrending { background: var(--color-surface); color: var(--color-brand); }

@media (min-width: 720px) {
  .comparators-index__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 960px) {
  .comparators-index__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .comparators-index__list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ============ Indice de reportajes ============ */
/* Mismo recorte del padding-top que el listado de comparadores: el hero ya deja el suyo debajo. */
.reports { padding-top: clamp(1.5rem, 1.15rem + 1.4vw, 2.25rem); padding-bottom: 80px; }
.reports__filters { margin-top: 1.5rem; }

.report-cards { display: grid; grid-template-columns: 1fr; gap: var(--gap); }
.report-card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  overflow: hidden;
}
/* La portada es la og:image de cada pieza y solo existe en el servidor de produccion: cuando falta
   -- y en local faltan todas -- queda el degradado, como en las tarjetas de guia de la home. */
.report-card__media {
  position: relative;
  display: block;
  height: 200px;
  background: linear-gradient(135deg, var(--color-surface-alt) 0%, var(--color-lilac) 100%);
}
.report-card:nth-child(4n+2) .report-card__media { background: linear-gradient(135deg, var(--color-surface) 0%, var(--color-surface-alt) 100%); }
.report-card:nth-child(4n+3) .report-card__media { background: linear-gradient(160deg, var(--color-lilac) 0%, var(--color-surface-alt) 100%); }
.report-card:nth-child(4n) .report-card__media { background: linear-gradient(200deg, var(--color-lilac) 0%, var(--color-surface) 100%); }
/* Las og son 600x337 y el hueco 200 de alto: se recortan por el centro en vez de deformarse. */
.report-card__media img { width: 100%; height: 100%; object-fit: cover; }

.report-card__tag { position: absolute; top: 0.75rem; left: 0.75rem; }
/* Los mismos seis colores con los que la hoja vieja distinguia los tipos del listado
   (.groupsolutions, .groupposts, .grouppodcast...). Lo unico que cambia es el color del texto: en
   los tres fondos claros pasa a azul marino, donde el blanco de la hoja vieja no llegaba a
   contrastar. */
.report-card__tag--solutions { background: #1bbeb2; color: var(--color-navy); }
.report-card__tag--posts { background: var(--color-brand); color: var(--color-white); }
.report-card__tag--theme { background: #e7c3ee; color: var(--color-navy); }
.report-card__tag--podcast { background: #ff2e49; color: var(--color-white); }
.report-card__tag--news { background: #ff862e; color: var(--color-navy); }
.report-card__tag--comparison,
.report-card__tag--alternatives { background: #4f5e70; color: var(--color-white); }

.report-card__body { padding: 1.25rem; }
.report-card__title { font-size: 1.125rem; font-weight: 500; line-height: 1.35; color: var(--color-navy); }
.report-card__title a:hover { color: var(--color-brand); }
/* Titulares y entradillas los escribe el panel y van de una linea a un parrafo entero: sin el
   recorte, una tarjeta triplica la altura de la fila en la que esta. */
.report-card__title,
.report-card__summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.report-card__title { -webkit-line-clamp: 3; }
.report-card__summary { -webkit-line-clamp: 3; margin-top: 0.6rem; font-size: 1rem; }
/* La entradilla llega envuelta en el <p> del panel: en linea para que el recorte cuente lineas y
   no un unico bloque hijo, que no recortaria nada. */
.report-card__summary > p { display: inline; margin: 0; }

.pagination { margin-top: 3rem; }
.pagination__list { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; }
.pagination__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding-inline: 0.6rem;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-brand);
}
a.pagination__item:hover { background: var(--color-surface-alt); }
.pagination__item.is-active { background: var(--color-brand); color: var(--color-white); }
.pagination__gap { display: inline-flex; align-items: center; height: 2.5rem; padding-inline: 0.3rem; color: var(--color-text-light); }
.pagination__item--arrow { font-size: 1.125rem; line-height: 1; }

@media (min-width: 720px) {
  .report-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1080px) {
  .report-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ============ Newsletter ============ */
/* No confundir con .newsletter, que es el hueco del formulario de Brevo dentro del bloque
   "Acerca de" de la home: ese es un panel sobre fondo oscuro y este es la pagina entera. */
.newsletter-hero { display: grid; gap: 2rem; align-items: center; }
.newsletter-hero__text { min-width: 0; }
.newsletter-hero__cta { margin-top: 1.75rem; }
/* El PNG es un movil a 750x1500: a ancho completo ocuparia dos pantallas de alto el solo. */
.newsletter-hero__mockup { width: 100%; max-width: 260px; height: auto; justify-self: center; }

.newsletter-benefits { padding-bottom: clamp(1rem, 0.5rem + 2vw, 2rem); }
.newsletter-benefits__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap);
  margin-top: 1.75rem;
}
.newsletter-benefits__item {
  position: relative;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: 1.5rem 1.5rem 1.5rem 3.5rem;
  font-size: 1.0625rem;
}
/* El check va como fondo y no como <img>: las vinetas salen de una clave del .po, asi que la
   plantilla pinta su texto y nada mas. */
.newsletter-benefits__item::before {
  content: "";
  position: absolute;
  left: 1.5rem; top: 1.6rem;
  width: 20px; height: 20px;
  background: url("../assets/icons/check-circle.svg") center / contain no-repeat;
}
.newsletter-benefits__item strong { color: var(--color-navy); font-weight: 600; }
.newsletter-benefits__fallback { margin-top: 1.75rem; }

.newsletter-samples { padding-top: clamp(1.5rem, 1.15rem + 1.4vw, 2.25rem); }
.newsletter-samples__list { display: grid; grid-template-columns: 1fr; gap: 0.75rem; margin-top: 1.75rem; }
.newsletter-samples__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: 100%;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: 0.95rem 1.25rem;
  color: var(--color-brand);
}
.newsletter-samples__link:hover { background: var(--color-surface-alt-hover); }
.newsletter-samples__link img { flex: none; }
.newsletter-samples__archive { margin-top: 1.75rem; font-size: 1.0625rem; }
.newsletter-samples__archive a { color: var(--color-brand); text-decoration: underline; }

.newsletter-signup { padding-bottom: 80px; }
.newsletter-signup__inner {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 1.2rem + 2.4vw, 3rem);
}
.newsletter-signup__icon { width: 48px; height: 48px; margin-bottom: 1rem; }
/* El hueco del embed de Brevo. Reserva alto para que la seccion no se vea vacia mientras el iframe
   no esta puesto, y para que ponerlo despues no desplace el pie de golpe. */
.newsletter-signup__embed { min-height: 18rem; margin-top: 2rem; }
.newsletter-signup__embed iframe { width: 100%; border: 0; }

@media (min-width: 720px) {
  .newsletter-benefits__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 960px) {
  .newsletter-hero { grid-template-columns: minmax(0, 1fr) 320px; gap: 3rem; }
  .newsletter-samples__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============ Opiniones y cierre de las paginas de contenido ============ */
/* El bloque de opiniones llega tal cual lo emite public_web::get_last_reviews(): marcado del
   sitio viejo, con su microformato de schema.org, que la maqueta v2 no tiene por que repintar.
   Lo que hay aqui es la traduccion de sus clases (.row/.col-*, .ficha_button, .ratingreview...)
   al lenguaje visual de la v2, todo dentro de .page-reviews para no tocar nada mas. */
.page-reviews { background: var(--color-surface); padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem); }
.page-reviews section { padding-top: 0; }
.page-reviews section + section { margin-top: 0.75rem; }
.page-reviews .row { display: grid; gap: 1.25rem; align-items: start; }
.page-reviews h2 {
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 1.875rem);
  font-weight: 500;
  color: var(--color-navy);
  margin-bottom: 1rem;
}
.page-reviews .ficha_button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-md);
  background: var(--color-white);
  border: 1px solid var(--color-surface-alt);
  color: var(--color-brand);
  font-size: 0.9375rem;
}
.page-reviews .ficha_button:hover { background: var(--color-surface-alt); }
/* "Valorar solucion": su modal (modal_select_solution_review) ya no se pinta, asi que el boton
   se oculta en vez de reescribir el HTML capturado de get_all_reviews() -- que lleva el
   microformato de schema.org y se toma tal cual, sin tocar. */
.page-reviews .main-review .allratings { display: none; }
/* Cada opinion es una tarjeta; la cabecera del bloque (.main-review) no.
   El gancho es .back-grey-content y no .backgreyreview: esa segunda clase solo la lleva una
   opinion de cada dos -- el rayado gris/blanco del bloque viejo --, asi que la mitad se quedaba
   sin tarjeta y, con ella, sin las dos columnas del media query. */
.page-reviews .back-grey-content:not(.main-review) .container {
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 1.25rem;
}
/* La nota de la opinion, delante del nombre: circulo con el numero, que es lo unico que da
   ese <span> (el detalle por criterio va en la columna de la derecha). */
.page-reviews .ratingreview {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.5rem;
  height: 2.5rem;
  margin-right: 0.75rem;
  vertical-align: middle;
  border-radius: 50%;
  background: var(--color-brand);
  color: var(--color-white);
  font-weight: 600;
}
.page-reviews .autorreview {
  color: var(--color-navy);
  font-weight: 600;
  font-size: 1.0625rem;
  text-transform: capitalize;
}
/* Cargo, empresa y fecha: la linea que sigue al nombre, en gris y mas pequena para que el
   nombre y el texto de la opinion sean lo que se lee primero. */
.page-reviews [itemprop="publisher"],
.page-reviews [itemscope] > em { color: var(--color-text-light); font-size: 0.9375rem; }
/* .spanreviews es un <div> en mitad de una frase: en bloque parte la linea en dos. */
.page-reviews .spanreviews { display: inline; }
.page-reviews .clear30, .page-reviews .clear5, .page-reviews .clear0 { display: none; }
.page-reviews a { color: var(--color-brand); }

/* El cuerpo de la opinion, separado de la ficha como cita. */
.page-reviews .reviewbody {
  margin-top: 0.85rem;
  padding: 0.85rem 1rem;
  border-left: 3px solid var(--color-surface-alt);
  background: var(--color-surface);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  color: var(--color-text);
}
/* Las preguntas del cuestionario, que el bloque viejo mete en la misma linea que la respuesta.
   Su <br> deja de hacer falta al pintarlas en bloque: solo abria una linea en blanco de mas. */
.page-reviews .questionreviewbody + br { display: none; }
.page-reviews .questionreviewbody {
  display: block;
  margin-bottom: 0.15rem;
  color: var(--color-text-light);
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* Sin margen propio: el <br>&nbsp;<br> con el que el bloque viejo separa la segunda pregunta ya
   deja el hueco, y sumar los dos abria un salto de tres lineas. */
.page-reviews .reviewbody .text-success { display: block; color: #007950; }

/* Las notas por criterio: barrating convierte cada <select> en .br-widget, pero su tema
   (css/themes/css-stars.css) depende de Font Awesome y de la hoja vieja, ninguna de las dos en
   la v2 -- los enlaces quedaban vacios. Se pintan aqui con el caracter de estrella. */
/* El <br> que el bloque viejo pone tras cada <select> es una fila mas de la rejilla: separaba
   los criterios con una linea en blanco entera. El hueco lo pone el gap. */
.page-reviews .allratings { display: grid; gap: 0.6rem; align-content: start; }
.page-reviews .allratings br { display: none; }
.page-reviews .title_rating {
  display: block;
  color: var(--color-navy);
  font-size: 0.875rem;
  font-weight: 500;
}
.page-reviews .br-widget { display: flex; gap: 0.15rem; }
.page-reviews .br-widget a { line-height: 1; text-decoration: none; }
.page-reviews .br-widget a::after { content: "\2605"; color: var(--color-surface-alt); font-size: 1.125rem; }
.page-reviews .br-widget a.br-selected::after { color: #ffb400; }
.page-reviews .br-widget .br-current-rating { display: none; }
/* readonly: barrating deja los <a> con href="#" y sin el atributo, asi que el cursor sigue
   diciendo que se pueden pulsar. */
.page-reviews .br-readonly a { cursor: default; pointer-events: none; }

/* La media del sitio, en la cabecera del bloque: la pinta jquery.rating con cinco <img>, y el
   reset de la maqueta (img { display: block }) las apilaba en vertical. */
.page-reviews #inputreview { display: flex; align-items: center; gap: 0.15rem; }
.page-reviews [itemprop="aggregateRating"] { margin-top: 0.5rem; color: var(--color-navy); }
.page-reviews [itemprop="ratingValue"], .page-reviews [itemprop="ratingCount"] { font-weight: 600; }

/* "Ver todas las opiniones": el pie del bloque, sin tarjeta. */
.page-reviews .greyback .container { background: none; box-shadow: none; padding: 0; text-align: center; }
.page-reviews .greyback .ficha_button { float: none !important; }

@media (min-width: 960px) {
  .page-reviews .main-review .row,
  .page-reviews .back-grey-content:not(.main-review) .row { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
  .page-reviews .allratings { padding-left: 1.5rem; border-left: 1px solid var(--color-surface-alt); }
}

.page-related { padding-bottom: 80px; }
.page-related__inner { display: grid; gap: 2.5rem; align-items: start; }
.page-related .btn { margin-bottom: 1.25rem; }

@media (min-width: 720px) {
  .page-related__inner { grid-template-columns: 1fr 1fr; }
}

/* ============ Cuerpo editorial del comparador (section.product-detail#guia) ============ */
/* El indice de contenidos y las fichas en profundidad por solucion llegan como HTML del CMS
   (tipoLEAD::get_HTML_page() + public_web::replace_ppc_links(), ver views/pages/comparison.twig).
   Ese HTML trae clases de Bootstrap 3/4 y clases propias del sitio viejo que esta hoja no
   define. No se reescribe -es contenido redactado a mano, por idioma, y lleva dentro los botones
   monetizados-: se traduce aqui al lenguaje de la maqueta.

   CADA SOLUCION SON DOS <section> HERMANAS, no una:
     .cms-content.noshadow  -> bloque "dos-columnas-imagen-derecha" del CMS: h3 con el nombre,
                               descripcion, Caracteristicas, Precios y la captura.
     .cms-content            -> bloque "libre" siguiente, donde replace_ppc_links() ha expandido
                               el token {LINK-<idempresa>}: Ventajas/Inconvenientes, valoracion
                               por criterio y los CTA.
   Las dos juntas son UN article.solution-detail de softdoit-html/erp.php:249-381. Por eso el par
   se cose visualmente con el selector adyacente de mas abajo, y la segunda hace de
   .solution-detail__footer (el panel blanco embutido). Se reutilizan los mismos valores y tokens
   que .solution-detail ya usa en esta hoja, para que las dos paginas envejezcan igual.

   TODO VA ACOTADO A .product-detail: son nombres genericos (.row, .col-*, .svg) que fuera de
   aqui pisarian el maquetado nuevo. */
.product-detail .container { display: block; }
/* Estas dos tienen que ganarle, y por eso van despues y con un selector mas especifico.
   `.product-detail .container` es (0,2,0) y pisa a dos reglas de la ficha que son (0,1,0) y (0,2,0):

   1. `.product-detail__inner` (linea 996), que es el grid de dos columnas del panel de descripcion
      -texto a la izquierda, cita a la derecha-. Aplastado a `block`, la cita cae debajo del texto.
   2. `.product-tabs__panel[hidden]` (linea 994). Sin esto, cuatro de los cinco paneles se quedaban
      visibles con `hidden` puesto y pulsar una pestana cambiaba la pastilla y nada mas. El de
      opiniones era el unico que funcionaba, porque es el unico que no lleva `.container`.

   El orden importa: `hidden` va el ultimo para que un panel oculto que ademas sea `__inner` siga
   oculto. */
.product-detail .product-detail__inner { display: grid; }
.product-detail .product-tabs__panel[hidden] { display: none; }

/* Indice de contenidos: mismo bloque .solution-index de la maqueta */
.product-detail .solution-index {
  background: var(--color-white); border-radius: var(--radius-md);
  padding: 0 2rem 1.75rem; margin-top: 40px;
}
/* El titulo que ComparisonData::extractSolutionsHeading() saca del cuerpo (Sergio,
   2026-08-19): llega como <h2> sin clase, mismo tratamiento que el resto de h2 de la pagina. */
.product-detail .solution-index h2 {
  font-size: 1.75rem;
  color: var(--color-navy);
  margin-bottom: 1rem;
}
.product-detail .indexlisth { list-style: none; margin: 0.75rem 0 0; padding: 0; }
.product-detail .indexlisth .indexlisth { margin: 0.35rem 0 0.35rem 1.25rem; }
.product-detail .indexlisth li { margin-bottom: 0.35rem; }
.product-detail .indexlisth a { color: var(--color-navy); }
.product-detail .indexlisth a:hover { color: var(--color-brand); text-decoration: underline; }
.product-detail .indexlisth a.subindex_table { color: var(--color-text); font-size: 0.9375rem; }

/* La tarjeta: cabecera y pie son dos secciones, con una sola caja alrededor */
.product-detail .cms-content {
  background: var(--color-surface); border-radius: var(--radius-md);
  padding: 2rem; margin-top: 1.5rem;
}
.product-detail .cms-content.noshadow { padding-bottom: 0; margin-bottom: 0; border-radius: var(--radius-md) var(--radius-md) 0 0; }
.product-detail .cms-content.noshadow + .cms-content { padding-top: 0; margin-top: 0; border-radius: 0 0 var(--radius-md) var(--radius-md); }
/* El pie: el panel blanco embutido de la maqueta (.solution-detail__footer) */
.product-detail .cms-content.noshadow + .cms-content > .container > .row > [class*="col-"] {
  background: var(--color-white); border-radius: var(--radius-md); padding: 1.75rem;
}

/* Cabecera de cada ficha (logotipo + "Visitar Web"), que inyecta
   ComparisonData::withSolutionHeaders() porque el bloque del CMS no la trae. La casilla del logo
   usa los mismos valores que .solution-detail__logo de la maqueta. */
.product-detail .solution-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 1rem; margin-bottom: 1.5rem;
}
.product-detail .solution-head__logo {
  width: 140px; height: 76px; flex: none;
  background: var(--color-white); border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center; padding: 0.5rem;
}
.product-detail .solution-head__logo img { max-width: 100%; max-height: 100%; border-radius: 0; }
.product-detail .solution-head__identity { flex: 1 1 12rem; min-width: 0; }
/* El h3 viene movido del cuerpo, asi que aqui se le quita el margen que traia de alli. */
.product-detail .solution-head__identity h3 { margin-bottom: 0.5rem; }
.product-detail .solution-head__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.product-detail .solution-head__tags .tag { border-radius: var(--radius-pill); }
.product-detail .solution-head__actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-left: auto; }
.product-detail .solution-head__actions .morebutton-link,
.product-detail .solution-head__actions .moreplusbutton-link { margin: 0; }

.product-detail .cms-content h2,
.product-detail .cms-content .softdoit-likeh2 { font-size: 1.75rem; color: var(--color-navy); margin-bottom: 1rem; }
.product-detail .cms-content h3 { color: var(--color-navy); font-size: 1.125rem; font-weight: 500; margin-bottom: 1rem; }
/* Los h4 del contenido ("Caracteristicas", "Precios", "Valoracion") son los rotulos de
   .solution-detail__block: brand, mayusculas y espaciados. */
.product-detail .cms-content h4 {
  color: var(--color-brand); font-size: 0.9375rem; font-weight: 500;
  letter-spacing: 0.09em; text-transform: uppercase; margin: 1.5rem 0 0.75rem;
}
.product-detail .cms-content p { margin-bottom: 1rem; }
/* Vinetas de punto, como .solution-detail__block li */
.product-detail .cms-content ul { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.product-detail .cms-content ol { margin: 0 0 1rem 1.25rem; }
.product-detail .cms-content ul li { padding-left: 1.25rem; position: relative; }
.product-detail .cms-content ul li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--color-brand);
}
.product-detail .softdoit-blue { color: var(--color-brand-dark); }
/* La captura de la ficha, en la columna derecha */
.product-detail img { max-width: 100%; height: auto; border-radius: var(--radius-md); }
/* .svg son los iconos inline (los corazones de la valoracion): sin acotar tamano ocupan el
   ancho entero de su columna, que es justo lo que pasaba. */
.product-detail img.svg { width: 1.125rem; height: 1.125rem; border-radius: 0; vertical-align: -0.15em; }
.product-detail .embed-responsive-16by9 { position: relative; padding-bottom: 56.25%; height: 0; }
.product-detail .embed-responsive-16by9 .embed-responsive-item {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
}
.product-detail .clear0 { height: 0; }
.product-detail .clear15 { height: 0.75rem; }

/* Rejilla minima de Bootstrap: el HTML del CMS la usa y esta hoja no la trae */
.product-detail .row { display: flex; flex-wrap: wrap; margin-inline: -0.75rem; }
.product-detail [class*="col-"] { padding-inline: 0.75rem; width: 100%; }
@media (min-width: 720px) {
  .product-detail .col-sm-6 { width: 50%; }
}
@media (min-width: 960px) {
  .product-detail .col-md-5 { width: 41.6667%; }
  .product-detail .col-md-6 { width: 50%; }
  .product-detail .col-md-7 { width: 58.3333%; }
}

/* Ventajas / Inconvenientes: dos columnas, verde y rojo como .solution-detail__pros/__cons.
   El !important pisa el margin-top negativo en linea que trae replace_ppc_links(). */
.product-detail .greyrow { margin: 0 0 1.5rem !important; }
.product-detail .greyrow h4 { margin-top: 0; font-size: 1rem; text-transform: none; letter-spacing: 0; }
.product-detail .greyrow .col-md-5 h4 { color: #00a323; }
.product-detail .greyrow .col-md-7 h4 { color: #eb5757; }
/* Un check verde por ventaja y una X roja por inconveniente, como la maqueta
   (softdoit-html/erp.php:339 y :347). Van de fondo en el ::before y no como <img>: el marcado de
   estas dos listas lo emite public_web::replace_ppc_links(), que comparte con la vista vieja, y
   no se toca. Los dos SVG ya vienen coloreados con el mismo verde y el mismo rojo que los
   rotulos de aqui arriba. */
.product-detail .greyrow ul li { padding-left: 1.75rem; }
.product-detail .greyrow ul li::before {
  width: 20px; height: 20px; top: 0.15em; border-radius: 0;
  background: center / contain no-repeat url("/assets/icons/check-circle.svg");
}
.product-detail .greyrow .col-md-7 ul li::before { background-image: url("/assets/icons/x-circle.svg"); }

/* Valoracion, como .solution-detail__rating de la maqueta (softdoit-html/erp.php:353-368):
   rotulo arriba y, debajo, TODO en una sola linea que envuelve -puntuacion general y luego el
   desglose por criterio separado por puntos-, en vez de la columna izquierda y la lista vertical
   que salian del marcado de replace_ppc_links(). */
.product-detail .softdoit-red { color: var(--color-brand); }
.product-detail .cms-content h4[id^="valorasolution"] {
  padding-top: 1.5rem; border-top: 1px solid var(--color-surface-alt);
}
.product-detail .cms-content h4[id^="valorasolution"] + .row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.25rem;
}
.product-detail .cms-content h4[id^="valorasolution"] + .row > [class*="col-"] { width: auto; flex: 0 0 auto; }
/* La celda de la nota general se queda en una linea: como item flex se encogia a su min-content
   y partia el icono del numero. */
.product-detail .cms-content h4[id^="valorasolution"] + .row .col-md-5 {
  display: flex; align-items: center; gap: 0.6rem; white-space: nowrap;
}
/* Las cinco estrellas que pone ComparisonData::withStarRating() en lugar del corazon. Van con
   ul.star-rating y no solo .star-rating: si no, las reglas genericas de .cms-content ul -que son
   mas especificas- las apilan en columna y les meten la vineta de punto. */
.product-detail .cms-content ul.star-rating {
  display: flex; flex-direction: row; gap: 0.15rem; list-style: none; margin: 0; padding: 0;
}
.product-detail .cms-content ul.star-rating li { padding: 0; margin: 0; }
.product-detail .cms-content ul.star-rating li::before { content: none; }
.product-detail .cms-content ul.star-rating img { border-radius: 0; }
.product-detail .cms-content h4[id^="valorasolution"] + .row .col-md-5 br { display: none; }
/* flex: none, si no el <span> de la nota se encoge a su min-content y deja el icono en una linea
   y el numero en la siguiente. */
.product-detail .cms-content h4[id^="valorasolution"] + .row .bigvalora {
  flex: none; display: inline-flex; align-items: center; gap: 0.35rem;
}
/* flex:1 1 0 + min-width:0 para que el desglose comparta linea con la nota y, si no cabe entero,
   envuelva DENTRO de su celda en vez de tirar la celda entera a la linea de abajo. */
.product-detail .cms-content h4[id^="valorasolution"] + .row .col-md-7 {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.9rem;
  flex: 1 1 0; min-width: 0;
}
/* "Puntuacion general" se oculta: es un segundo rotulo para lo mismo que ya dice el "Valoracion"
   de encima, y la maqueta no lo tiene. Es rotulo, no dato: la nota y los criterios siguen todos. */
.product-detail .paramvalora,
.product-detail .paramvalora + br { display: none; }
.product-detail .bigvalora { color: var(--color-brand); font-weight: 700; font-size: 1.5625rem; }
.product-detail .valorapuntua {
  display: flex; align-items: center; gap: 0.35rem;
  padding: 0; border: none; font-size: 0.9375rem;
}
/* El corazon se repite en cada criterio y la maqueta no lo lleva ahi -solo en la nota general-.
   Ademas es lo que hacia que el desglose no cupiese en la misma linea que la nota. Es decorativo:
   los cuatro llevan el mismo alt="Valoracion". */
.product-detail .valorapuntua > img.svg { display: none; }
/* El separador entre criterios, el mismo &middot; de la maqueta. */
.product-detail .valorapuntua + .valorapuntua::before { content: "·"; margin-right: 0.4rem; color: var(--color-text-light); }
.product-detail .pointdata { font-weight: 700; color: var(--color-brand); }

/* CTAs monetizados que inyecta replace_ppc_links(): mismo aspecto que los .btn de la maqueta */
.product-detail .morebutton-link,
.product-detail .morebutton-link-blue,
.product-detail .moreplusbutton-link {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  padding: 0.7rem 1.35rem; margin: 0.5rem 0.5rem 0 0;
  border-radius: var(--radius-md); font-size: 0.9375rem; cursor: pointer;
}
.product-detail .morebutton-link { background: var(--color-brand); color: var(--color-white); }
.product-detail .morebutton-link:hover { background: var(--color-brand-hover); }
.product-detail .morebutton-link-blue { background: var(--color-brand-dark); color: var(--color-white); }
.product-detail .moreplusbutton-link {
  background: transparent; color: var(--color-brand); border: 1px solid var(--color-brand);
}
.product-detail .moreplusbutton-link:hover { background: var(--color-surface-alt); }

/* ============ Indice de directorios ============ */
/* El cuerpo de esta pagina llega capturado de templates/directorio_fabricantes.php (ver el
   docblock de DirectoryData): son las fichas de pago y los 132 directorios con su buscador. Aqui
   se traducen sus clases al lenguaje de la v2, sin tocar su marcado. */
.directory-blocks section { padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem); }
.directory-blocks section + section { padding-top: 0; }
/* El primer bloque arranca justo debajo del hero: 40px de aire, no los 80 del clamp. */
.directory-blocks section.pvertical40 { padding-top: 2.5rem; }
.directory-blocks .directoriestitle {
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 1.875rem);
  font-weight: 500;
  color: var(--color-navy);
  margin-bottom: 0.75rem;
}
.directory-blocks .clear0, .directory-blocks .clear5, .directory-blocks .clear30 { display: none; }
/* :not(.btn) porque esta regla gana por especificidad a .btn--primary y dejaba el boton de la ficha
   con el texto del mismo color que su fondo. */
.directory-blocks a:not(.btn) { color: var(--color-brand); }

/* La hoja de Bootstrap no se carga en la v2, solo su JS: sin estas dos reglas el "ver listado
   completo" no esconde nada y los 124 directorios de mas salen abiertos de entrada. */
.directory-blocks .collapse:not(.show) { display: none; }
.directory-blocks .collapsing { position: relative; height: 0; overflow: hidden; transition: height 0.35s ease; }

/* Listado de directorios: el h2, el parrafo y el buscador ocupan la fila entera y los tipos caen
   en rejilla debajo. */
.directory-blocks .pvertical40 .col-12,
.directory-blocks #moremaindirectorycat.show {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 0.75rem;
  align-items: start;
}
.directory-blocks .pvertical40 .col-12 > h2,
.directory-blocks .pvertical40 .col-12 > p,
.directory-blocks .pvertical40 .col-12 > input,
.directory-blocks .pvertical40 .col-12 > .collapse,
.directory-blocks .pvertical40 .col-12 > .list_types_of_software_mb20 { grid-column: 1 / -1; }
.directory-blocks .searchfieldadv {
  width: 100%;
  padding: 0.9rem 1.25rem;
  border: 1px solid var(--color-surface-alt);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-navy);
  margin-bottom: 1rem;
}
.directory-blocks .list_types_of_software,
.directory-blocks .list_types_of_software_mb20 {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  height: 100%;
  padding: 0.85rem 1rem;
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  color: var(--color-brand);
  cursor: pointer;
}
.directory-blocks .list_types_of_software:hover,
.directory-blocks .list_types_of_software_mb20:hover { background: var(--color-surface-alt-hover); }
.directory-blocks .list_types_of_software_mb20 { justify-content: center; font-weight: 500; }
/* Font Awesome sustituye cada <i> por un <svg>, y el del "ver listado completo" viene a 3x. */
.directory-blocks .list_types_of_software_mb20 svg { width: 1.25rem; height: 1.25rem; }
.directory-blocks .icon_type_of_software { flex: 0 0 24px; display: flex; align-items: center; justify-content: center; }
.directory-blocks .icon_type_of_software img { width: 24px; height: 24px; object-fit: contain; }

/* ============ Fichas de empresa del directorio ============ */
/* Copia de .ranking__row (la fila de la home) con nombre propio: el marcado que hay dentro no es
   el mismo -- aqui no hay posicion ni estrellas, y si descripcion, iconos de tipo y el boton que
   devuelve get_ppc_button() --, asi que compartir clases habria acabado en un juego de excepciones
   sobre la home. Ver views/partials/provider-row.twig. */
.provider-list { display: flex; flex-direction: column; gap: 1rem; }
.provider-row {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  align-items: center;
  gap: 0.85rem 1rem;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: 1.25rem;
}
.provider-row__logo {
  width: 92px; height: 58px;
  background: var(--color-white); border-radius: var(--radius-md);
  padding: 0.5rem;
}
.provider-row__logo img { width: 100%; height: 100%; object-fit: contain; }
/* El template envuelve algunos logotipos en .square/.square-content para cuadrarlos; aqui de eso
   ya se encarga la casilla. */
.provider-row__logo .square,
.provider-row__logo .square-content { width: 100%; height: 100%; padding: 0; }
.provider-row__logo a { display: block; width: 100%; height: 100%; }
.provider-row__meta { min-width: 0; }
.provider-row__name { font-size: 1.125rem; font-weight: 500; color: var(--color-navy); }
.provider-row__desc { margin-top: 0.4rem; color: var(--color-text); }
.provider-row__desc p:last-child { margin-bottom: 0; }
.provider-row__solutions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.85rem; }
.provider-row__solutions img { width: 22px; height: 22px; object-fit: contain; }
.provider-row__solutions p { display: inline-flex; align-items: center; gap: 0.35rem; margin: 0; color: var(--color-text-light); }
.provider-row__actions {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem;
  font-size: 0.9375rem; color: var(--color-text-light);
}
/* El boton de pago que llega de get_ppc_button() conserva sus clases de la web vieja -- moverle el
   marcado habria sido tocar el clic --, y aqui se le da el aspecto del .btn--primary de la maqueta,
   el mismo que luce el enlace a la ficha cuando no hay PPC. */
.provider-row__actions .ficha_button_click {
  display: inline-flex; align-items: center; gap: 0.5rem;
  background: var(--color-brand); color: var(--color-white);
  border-radius: var(--radius-md);
  padding: 0.7rem 1.35rem;
  font-size: 0.9375rem; cursor: pointer;
}
.provider-row__actions .ficha_button_click:hover { background: var(--color-brand-hover); }

@media (min-width: 960px) {
  /* Una sola linea, como la fila de la home: logo, texto y acciones. */
  .provider-row { grid-template-columns: 185px minmax(0, 1fr) auto; gap: 1.75rem; padding-inline: 2.5rem; }
  .provider-row__logo { width: 185px; height: 96px; padding: 1rem; }
  .provider-row__actions { grid-column: 3; flex-direction: column; align-items: flex-end; gap: 0.5rem; }
}

/* ============ Categoria de directorio (views/pages/directory-category.twig) ============ */
/* El bloque "Recursos sobre X" y el selector de tipo llegan capturados de
   templates/directorio_fabricantes.php dentro de DirectoryData::parseCategory() (mismo motivo que
   .directory-blocks): se traducen sus clases aqui sin tocar el marcado. .resources_block navega
   con su propio onclick, no con el <a> de dentro -- eso no se toca. */

/* El <i class="fa-sharp..."> depende de un kit de Font Awesome que ninguna pagina Twig carga (solo
   entra esta hoja, mismo caso que .tooltip mas arriba): sin fuente detras sale como una caja rota.
   Se oculta y el bloque se resuelve como pastilla clicable, con el lenguaje de .tag/.pagination__item. */
.directory-category__resources .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding-block: 1.5rem;
}
.title-resources { font-size: 0.9375rem; color: var(--color-text); }
.title-resources strong a { color: var(--color-brand); text-decoration: underline; }
.resources_block {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.55rem 1.1rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  cursor: pointer;
}
.resources_block:hover { background: var(--color-surface-alt-hover); }
/* js/main-v2.js sustituye cada <i class="fa-..."> por un <svg> antes de pintar (mismo caso que
   .directory-blocks .list_types_of_software_mb20 svg), asi que este selector no suele encontrar
   un <i> vivo; se deja como red de seguridad si esa sustitucion no llega a correr (JS desactivado,
   fallo de carga del script). */
.resources_block i, .resources_block .clear0 { display: none; }
.resources_block .badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.375rem;
  height: 1.375rem;
  padding-inline: 0.3rem;
  border-radius: var(--radius-pill);
  background: var(--color-brand);
  color: var(--color-white);
  font-size: 0.8125rem;
  font-weight: 600;
}
.resources_block a { color: var(--color-brand); font-size: 0.9375rem; }

/* El <select> de cambio de categoria (.formdirectoryselector) llega igual, sin estilo de Bootstrap:
   mismo patron de .form-control que .contact-form/.guide-hero__lead, acotado a esta seccion para no
   afectar a otro .form-control del sitio. La rejilla de dos columnas es la misma minima de
   Bootstrap que ya se traduce en .product-detail .row/.col-md-6. */
.directory-category__selector .row { display: flex; flex-wrap: wrap; margin-inline: -0.75rem; }
.directory-category__selector .col-md-6 { padding-inline: 0.75rem; width: 100%; margin-bottom: 1rem; }
@media (min-width: 960px) {
  .directory-category__selector .col-md-6 { width: 50%; margin-bottom: 0; }
}
.directory-category__selector .filtro-contenidos p {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-light);
  margin-bottom: 0.5rem;
}
.directory-category__selector select.form-control {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-surface-alt);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-navy);
  font-size: 1rem;
}
/* footer_scripts_raw carga select2.min.js, que inicializa un widget Select2 sobre .desplegable1:
   sin la hoja de Select2 (que esta pagina no carga) su <span class="select2-container"> no sustituye
   al <select> nativo, se queda visible en texto plano y duplica la opcion seleccionada al lado del
   select ya estilado de arriba. Mismo patron que el icono de FA: se oculta lo roto, se deja lo que
   funciona -- el <select> nativo sigue siendo el que manda el onchange. */
.directory-category__selector .select2-container { display: none; }

/* Formulario de captacion de leads (#main_comparator), oculto a peticion de Sergio (2026-08-19),
   mismo criterio que .landing-comparador en views/pages/comparison.twig (decision del 2026-08-13):
   el marcado sigue en la pagina porque includes/validation_scripts.php busca sus id al cargarse
   (#main_comparator, #other_questions, #personal_data, #hidden_questions, #thanks_data...), asi que
   se esconde con CSS en vez de quitarse. Acotado a este wrapper -- no un ".landing-comparador"
   suelto -- para no afectar a comparison.twig, que ya gestiona su propia visibilidad. */
.directory-category__comparator { display: none; }

/* El panel del hero del comparador se alinea con el titular: su columna izquierda es mucho mas
   alta y centrado quedaba flotando a media pagina. En la home no aplica -- alli las dos columnas
   miden parecido y el centrado es el de la maqueta. */
.hero__panel--top { align-self: start; }
/* Las dos lineas de confianza, ahora bajo la entradilla del hero (antes iban dentro del panel):
   sin separador y algo mas grandes, que aqui no cierran una tarjeta sino la columna. */
.hero__proof { margin-top: 1.75rem; }
.hero__proof p { display: flex; align-items: center; gap: 0.5rem; color: var(--color-navy); }
.hero__proof p + p { margin-top: 0.6rem; }

/* ============ Ficha de guia (views/pages/guide.twig) ============ */
/* Tambien la reutiliza views/pages/tip.twig: templates/tip.php es un calco de templates/guia.php,
   asi que su ficha comparte estas mismas clases en vez de duplicarlas.

   Todo lo que hay debajo de la portada llega capturado de templates/guia.php (o templates/tip.php):
   el cuestionario del comparador, los bloques del editor y los enlaces relacionados. Ese marcado
   trae clases de Bootstrap 3/4 y clases del sitio viejo que esta hoja no define; se traducen aqui,
   sin tocarlo, por lo mismo que en .product-detail: lleva dentro los destinos monetizados y las
   impresiones.

   TODO VA ACOTADO A .guide-blocks / .guide-hero: son nombres genericos (.row, .col-*, .container)
   que fuera de aqui pisarian el maquetado nuevo. */

/* La ficha del autor que el template escribe en la portada. */
.guide-hero__author { display: flex; align-items: center; gap: 0.85rem; margin-top: 1.5rem; }
.guide-hero__author .authorlayer { display: flex; align-items: center; gap: 0.85rem; }
.guide-hero__author .avatar { width: 60px; height: 60px; border-radius: 50%; object-fit: cover; flex: none; }
.guide-hero__author p { font-size: 0.9375rem; color: var(--color-text-light); margin: 0; }
.guide-hero__author a { color: var(--color-navy); font-weight: 500; }
.guide-hero__author a:hover { color: var(--color-brand); }

/* Entradilla: el parrafo del editor, su cita y el boton al comparador. */
.guide-hero__lead .container,
.guide-hero__lead .row,
.guide-hero__lead [class*="col-"] { display: block; width: auto; max-width: none; padding: 0; margin: 0; }
.guide-hero__lead .clear0, .guide-hero__lead .clear15, .guide-hero__lead .clear30 { display: none; }
.guide-hero__lead blockquote { margin-top: 1.5rem; }
/* Mismo boton que el "Habla con un experto" de la maqueta, en su propia linea: en el marcado viejo
   va suelto entre el texto y quedaba incrustado a media frase. */
.guide-hero__lead .topgotocomparator,
.guide-hero__lead .topgotocomparatorlanding {
  display: flex; width: fit-content; align-items: center; gap: 0.5rem;
  margin: 0 0 1.25rem;
  padding: 0.7rem 1.35rem;
  border: none; border-radius: var(--radius-md);
  background: var(--color-brand); color: var(--color-white);
  font-size: 0.9375rem; cursor: pointer;
}
.guide-hero__lead .topgotocomparator:hover,
.guide-hero__lead .topgotocomparatorlanding:hover { background: var(--color-brand-hover); }
.guide-hero__lead .topgotocomparator svg,
.guide-hero__lead .topgotocomparatorlanding svg { width: 1rem; height: 1rem; }
/* El rotulo viene partido en dos por un <br> que aqui no hace falta. */
.guide-hero__lead .topgotocomparator br,
.guide-hero__lead .topgotocomparatorlanding br { display: none; }

/* El cuestionario del comparador embebido: mismo criterio que en views/pages/comparison.twig -- el
   marcado se queda (dentro viven los id que includes/validation_scripts.php busca al cargarse:
   #main_comparator, #other_questions, #personal_data, #hidden_questions...) y solo deja de verse.
   Ojo, igual que alli: mientras este oculto, gotoComparator_blur() -- el boton de la entradilla --
   lleva a una seccion que no se ve. */
.guide-blocks #home_comparador_wrap { display: none; }
.guide-blocks .landing-comparador { min-height: 0; }

/* Cuerpo del editor. */
.guide-blocks { padding-bottom: 80px; }
/* Ancho de lectura: el contenedor de la maqueta llega a 1200px, que para un texto seguido son
   lineas de mas de 150 caracteres. */
.guide-blocks .container { display: block; max-width: 860px; }
.guide-blocks section { padding-top: 2.5rem; }
.guide-blocks .cms-content { font-size: 1.0625rem; }
.guide-blocks .cms-content h2,
.guide-blocks .cms-content .softdoit-likeh2 {
  font-size: clamp(1.375rem, 1.15rem + 0.9vw, 1.625rem);
  font-weight: 500; color: var(--color-navy); line-height: 1.3;
  margin-bottom: 1rem;
  scroll-margin-top: calc(var(--header-height-mobile) + 1rem);
}
.guide-blocks .cms-content h3 {
  font-size: 1.25rem; font-weight: 500; color: var(--color-navy);
  margin: 2rem 0 0.75rem;
  scroll-margin-top: calc(var(--header-height-mobile) + 1rem);
}
.guide-blocks .cms-content h4 { font-size: 1.0625rem; font-weight: 700; color: var(--color-navy); margin: 1.5rem 0 0.5rem; }
.guide-blocks .cms-content p { margin-bottom: 1.25rem; }
.guide-blocks .cms-content a { color: var(--color-brand); text-decoration: underline; }
.guide-blocks .cms-content ul { list-style: none; margin: 0 0 1.25rem; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.guide-blocks .cms-content ol { margin: 0 0 1.25rem 1.25rem; }
.guide-blocks .cms-content ul li { padding-left: 1.25rem; position: relative; }
.guide-blocks .cms-content ul li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--color-brand);
}
.guide-blocks img { max-width: 100%; height: auto; border-radius: var(--radius-md); }
.guide-blocks .embed-responsive-16by9 { position: relative; padding-bottom: 56.25%; height: 0; }
.guide-blocks .embed-responsive-16by9 .embed-responsive-item { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.guide-blocks blockquote {
  margin: 1.5rem 0; padding-left: 1.25rem;
  border-left: 3px solid var(--color-brand);
  color: var(--color-navy);
}
.guide-blocks .clear0, .guide-blocks .clear5, .guide-blocks .clear15, .guide-blocks .clear30 { display: none; }

/* Indice de contenidos del editor, en la caja gris del indice de la maqueta. */
.guide-blocks .index_content {
  background: var(--color-surface); border-radius: var(--radius-md);
  padding: 1.5rem 1.75rem;
}
.guide-blocks .cms-content .indexlisth {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 0.6rem;
  font-size: 0.9375rem;
}
/* Sin la vineta de punto de .cms-content ul: aqui las lineas son un indice, no una enumeracion. */
.guide-blocks .cms-content .indexlisth li { padding-left: 0; }
.guide-blocks .cms-content .indexlisth li::before { content: none; }
.guide-blocks .cms-content .indexlisth .indexlisth { margin: 0.6rem 0 0 1.25rem; }
.guide-blocks .cms-content .indexlisth a { color: var(--color-brand); text-decoration: none; }
.guide-blocks .cms-content .indexlisth a:hover { text-decoration: underline; }
.guide-blocks .cms-content .indexlisth a.subindex_table { color: var(--color-text); }

/* Rejilla minima de Bootstrap: el HTML del editor la usa y esta hoja no la trae. */
.guide-blocks .row { display: flex; flex-wrap: wrap; margin-inline: -0.75rem; }
.guide-blocks [class*="col-"] { padding-inline: 0.75rem; width: 100%; }
@media (min-width: 720px) {
  .guide-blocks .col-sm-6 { width: 50%; }
}
@media (min-width: 960px) {
  .guide-blocks .col-md-4 { width: 33.3333%; }
  .guide-blocks .col-md-5 { width: 41.6667%; }
  .guide-blocks .col-md-6 { width: 50%; }
  .guide-blocks .col-md-7 { width: 58.3333%; }
  .guide-blocks .col-md-8 { width: 66.6667%; }
}

/* El bloque de enlaces con el que cierra la guia: el editor los deja sueltos dentro de un <p>,
   uno detras de otro y pegados al rotulo. Aqui son pastillas, como el resto de la maqueta. */
.guide-blocks .has_links_buttons p { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
.guide-blocks .has_links_buttons .softdoit-likeh2 { flex: 1 0 100%; }
.guide-blocks .has_links_buttons p a {
  display: inline-flex; align-items: center;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-md);
  background: var(--color-surface-alt); color: var(--color-brand);
  text-decoration: none;
}
.guide-blocks .has_links_buttons p a:hover { background: var(--color-surface-alt-hover); }

/* Guias de captacion (guia_lead_generation=1): la portada trae el formulario del lead magnet, que
   postea saveMagnet() a includes/save_magnet.php. El marcado es el del template -- sus id son los
   que busca ese script --, aqui solo se le da el aspecto de la maqueta. */
.guide-hero__lead .landingpostmagnet { margin: 1.5rem 0; max-width: 32rem; }
.guide-hero__lead .landingpostmagnet .form-group { margin-bottom: 0.85rem; }
.guide-hero__lead .landingpostmagnet label { display: block; margin-bottom: 0.35rem; font-size: 0.9375rem; color: var(--color-navy); }
.guide-hero__lead .landingpostmagnet .form-control {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-surface-alt);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-navy);
}
/* La casilla legal: en linea con su texto, que lleva dentro el enlace al aviso de privacidad. */
.guide-hero__lead .landingpostmagnet .agreestyle label {
  display: block; font-size: 0.875rem; color: var(--color-text-light);
}
.guide-hero__lead .landingpostmagnet .agreestyle input { margin-right: 0.5rem; }
.guide-hero__lead .landingpostmagnet #savemagnetBtn {
  margin-top: 0.5rem;
  padding: 0.7rem 1.35rem;
  border: none; border-radius: var(--radius-md);
  background: var(--color-brand); color: var(--color-white);
  font-size: 0.9375rem; cursor: pointer;
}
.guide-hero__lead .landingpostmagnet #savemagnetBtn:hover { background: var(--color-brand-hover); }
/* La portada de las guias de captacion es una imagen de fondo con una capa por encima; en la v2 el
   hero ya tiene la suya, asi que la capa sobra y la imagen se queda como ilustracion. */
.guide-hero__lead .semitransparentlayer { display: none; }
.guide-hero__lead .featured_image { background-size: cover; background-position: center; border-radius: var(--radius-md); }

/* Rejilla de soluciones de las guias con lista fija (guia_idlist>0): la escribe
   fixed_list::get_html_list() y llega capturada, con sus setimpact() y sus clickPPC() dentro. La
   vista de comparativa la repinta a partir de datos (ver ComparisonData); aqui no se toca -- son
   otras 84 guias con listas distintas --, solo se le da forma legible. */
/* Este bloque va mas ancho que el texto: es una tabla de seis columnas, no prosa. Se le da el
   ancho del contenedor de la maqueta en vez del de lectura. */
.guide-blocks .landing-comparador .list_element_block {
  width: min(var(--container-width), 100% - 2.5rem);
  margin-inline: auto;
}
.guide-blocks .landing-comparador .row.newtoplist { margin-inline: 0; }
.guide-blocks .table-responsive { overflow-x: auto; margin: 1.5rem 0; }
.guide-blocks table.topsolutionstable {
  width: 100%; border-collapse: collapse;
  font-size: 0.9375rem;
}
.guide-blocks table.topsolutionstable th,
.guide-blocks table.topsolutionstable td {
  padding: 0.85rem 0.75rem;
  border-bottom: 1px solid var(--color-surface-alt);
  vertical-align: middle;
  text-align: left;
}
.guide-blocks table.topsolutionstable th { color: var(--color-navy); font-weight: 500; white-space: nowrap; }
.guide-blocks table.topsolutionstable img { max-width: 120px; }
/* Cada celda de "Mas info" trae dos o tres enlaces seguidos sin separacion: el de la solucion, el
   del descuento y el del comparador. Son los que cobran el clic, asi que se separan, no se tocan. */
/* La columna "Mas info" trae el boton de pago (span.whybutton_*, que lleva el clickPPC) y debajo
   el enlace al comparador, los dos sin separacion. Se apilan; el boton, con el aspecto de la
   maqueta. */
.guide-blocks table.topsolutionstable td center { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; }
.guide-blocks table.topsolutionstable td a,
.guide-blocks table.topsolutionstable td .nodecora { color: var(--color-brand); }
.guide-blocks table.topsolutionstable td [class*="whybutton"] {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-md);
  background: var(--color-brand); color: var(--color-white);
  cursor: pointer; white-space: nowrap;
}
.guide-blocks table.topsolutionstable td [class*="whybutton"]:hover { background: var(--color-brand-hover); }
.guide-blocks table.topsolutionstable td .altlinkppc { font-size: 0.875rem; }

/* Los iconos inline del contenido (.svg) vienen sin tamano y ocupan el ancho de su columna: el
   mismo caso que ya se corrige en .product-detail. */
.guide-blocks img.svg { width: 1.125rem; height: 1.125rem; border-radius: 0; vertical-align: -0.15em; }
/* Los patrocinadores de la guia (nexo_guia_empresa): sus logos llevan get_empresa_linkto() dentro,
   asi que solo se les da sitio y alineacion. */
.guide-blocks .featured-main-providers,
.guide-hero__lead .featured-main-providers {
  display: flex; flex-direction: column; align-items: center; gap: 0.75rem;
  margin: 1.5rem auto;
}
.guide-blocks .featured-main-providers .title-providers,
.guide-hero__lead .featured-main-providers .title-providers { font-size: 0.9375rem; color: var(--color-text-light); }
.guide-blocks .featured-main-providers ul.providers,
.guide-hero__lead .featured-main-providers ul.providers {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 1rem;
  list-style: none; margin: 0; padding: 0;
}
.guide-blocks .featured-main-providers ul.providers li::before,
.guide-hero__lead .featured-main-providers ul.providers li::before { content: none; }
.guide-blocks .featured-main-providers img,
.guide-hero__lead .featured-main-providers img { max-height: 60px; width: auto; }

/* ============ Pagina de contacto ============ */
.contact-section { padding-bottom: 80px; }
.contact-section__grid { display: grid; gap: var(--gap); align-items: start; }

.contact-form .form-group { margin-bottom: 1rem; }
.contact-form label { display: block; margin-bottom: 0.35rem; font-size: 0.9375rem; color: var(--color-navy); }
.contact-form .form-control {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--color-surface-alt);
  border-radius: var(--radius-md);
  background: var(--color-white);
  color: var(--color-navy);
}
.contact-form textarea.form-control { resize: vertical; }
.contact-form__agree label { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.875rem; color: var(--color-text-light); font-weight: 400; }
.contact-form__agree input { margin-top: 0.2rem; }
.contact-form__agree a { color: var(--color-brand); text-decoration: underline; }
.contact-form__submit { text-align: right; }

.contact-sidebar {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
}
.contact-sidebar__phone { font-size: 1.0625rem; color: var(--color-navy); }
.contact-sidebar__phone a { color: var(--color-brand); text-decoration: underline; }
.contact-sidebar__address { margin-top: 1.25rem; font-size: 0.9375rem; }
.contact-sidebar__social { margin-top: 1.5rem; }
.contact-sidebar__social strong { color: var(--color-navy); }
.contact-sidebar__social-links { display: flex; gap: 0.75rem; margin-top: 0.75rem; }

@media (min-width: 960px) {
  .contact-section__grid { grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr); gap: 3rem; }
}
