/* ==========================================================================
   Abitmedia — Estilos de página
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Hero / slider de portada
   La altura la marca el contenido; 'min-block-size' sólo evita que quede
   demasiado bajo en pantallas amplias, y se relaja en pantallas de poca altura.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(160deg, var(--color-header-deep) 0%, #0A1F6B 48%, var(--color-footer) 100%);
  color: #fff;
  isolation: isolate;

  /* La portada se ajusta a la PANTALLA: ocupa lo que queda de ventana por
     debajo del header (100svh — no 100vh: en móvil svh descuenta la barra del
     navegador y el hero no se sale por abajo).

     El clamp pone los dos topes: no baja de 28 rem en una ventana muy corta ni
     pasa de 48 rem en un monitor muy alto, donde un hero a pantalla completa
     dejaría el título flotando en medio de un vacío. En un monitor de 20"
     (1600 × 900) sale en torno a 730 px, que es justo la ventana visible.

     Va en la sección, no en su interior, para que los controles del slider
     entren en la cuenta. */
  min-block-size: clamp(28rem, calc(100svh - var(--header-min-h, 72px)), 48rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* --- Fondo tecnológico animado -------------------------------------------
   Cuatro capas ligeras, todas en CSS (sin canvas ni librerías): una cuadrícula
   en perspectiva, dos orbes de luz que derivan lentamente y un barrido muy
   tenue. Se mantienen DETRÁS del contenido, no capturan el puntero y conservan
   el azul rey como base. Es el mismo fondo en las dos diapositivas: no cambia
   bruscamente al pasar de una a otra. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;      /* nunca bloquea la interacción */
  contain: strict;           /* aísla el repintado: no afecta al resto */
}

/* Cuadrícula tecnológica */
.hero__grid {
  position: absolute;
  inset: -10% -10% -20%;
  background-image:
    linear-gradient(to right, rgba(255,255,255,.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.07) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(ellipse 85% 75% at 62% 28%, #000 10%, transparent 72%);
  mask-image: radial-gradient(ellipse 85% 75% at 62% 28%, #000 10%, transparent 72%);
  animation: hero-grid 32s linear infinite;
}
@keyframes hero-grid {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 64px 64px, 64px 64px; }
}

/* Orbes de luz: derivan muy despacio, sin parpadeos */
.hero__orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: .5;
}
.hero__orb--1 {
  inline-size: min(38rem, 62vw);
  aspect-ratio: 1;
  inset-block-start: -18%;
  inset-inline-end: -12%;
  background: radial-gradient(circle, rgba(45, 83, 230, .85), transparent 68%);
  animation: hero-orb-1 26s ease-in-out infinite alternate;
}
.hero__orb--2 {
  inline-size: min(28rem, 52vw);
  aspect-ratio: 1;
  inset-block-end: -22%;
  inset-inline-start: -10%;
  background: radial-gradient(circle, rgba(35, 169, 224, .55), transparent 70%);
  animation: hero-orb-2 34s ease-in-out infinite alternate;
}
@keyframes hero-orb-1 {
  from { transform: translate3d(0, 0, 0)         scale(1);    }
  to   { transform: translate3d(-4%, 5%, 0)      scale(1.12); }
}
@keyframes hero-orb-2 {
  from { transform: translate3d(0, 0, 0)         scale(1.08); }
  to   { transform: translate3d(6%, -4%, 0)      scale(1);    }
}

/* Barrido diagonal muy tenue: da sensación de dato en movimiento */
.hero__scan {
  position: absolute;
  inset: -50%;
  background: linear-gradient(115deg,
    transparent 42%,
    rgba(255, 255, 255, .05) 50%,
    transparent 58%);
  animation: hero-scan 18s linear infinite;
}
@keyframes hero-scan {
  from { transform: translate3d(-22%, -12%, 0); }
  to   { transform: translate3d(22%, 12%, 0);   }
}

/* --- Fondo propio de cada diapositiva -------------------------------------
   Las dos ilustraciones entregadas (comercio electrónico y aros de marca) son
   fondos completos: campo azul a la izquierda, donde va el texto, y el motivo
   a la derecha. Se encadenan por encima del degradado y por debajo del velo,
   y se funden al cambiar de diapositiva en lugar de saltar.

   Van a plena opacidad: ya no hay ninguna ilustración superpuesta, así que la
   propia imagen ES el hero. Lo que protege el texto es el velo de abajo. */
.hero__scene {
  position: absolute;
  inset: 0;
  opacity: 0;
  background-image: var(--scene);
  background-position: center right;
  background-size: cover;
  background-repeat: no-repeat;
  transition: opacity 1.1s var(--ease);
  will-change: opacity;
}
.hero__scene.is-active { opacity: 1; }

/* En vertical entra el encuadre de teléfono, que reparte el motivo de otra
   manera; si no se entregó, se reutiliza el ancho. */
@media (max-width: 760px) {
  .hero__scene {
    background-image: var(--scene-sm, var(--scene));
    background-position: center top;
  }
}

/* Velo sobre el fondo: garantiza el contraste del texto blanco en el lado
   izquierdo pase lo que pase con la ilustración. Se apoya en el borde del
   texto y deja intacto el lado del motivo. */
.hero__veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg,
      rgba(4, 10, 40, .62) 0%,
      rgba(4, 10, 40, .44) 34%,
      rgba(4, 10, 40, .12) 64%,
      rgba(4, 10, 40, 0) 100%);
}
@media (max-width: 760px) {
  .hero__veil {
    background: linear-gradient(180deg,
      rgba(4, 10, 40, .72) 0%,
      rgba(4, 10, 40, .48) 46%,
      rgba(4, 10, 40, .18) 100%);
  }
}

/* Con movimiento reducido el fondo se queda quieto, pero no desaparece:
   sigue aportando profundidad sin animación. */
@media (prefers-reduced-motion: reduce) {
  .hero__grid,
  .hero__orb,
  .hero__scan { animation: none; }
  .hero__scene { transition: none; }
}

.hero__viewport { position: relative; }

.hero__slide {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: clamp(var(--space-5), 4vw, var(--space-8));
  align-items: center;
  padding-block: clamp(2rem, 1.2rem + 3.4vw, 3.5rem);
}
/* Las diapositivas ocultas se apilan sin ocupar espacio ni recibir foco */
.hero__slide[hidden] { display: none !important; }

.hero__text { max-inline-size: 40rem; }
/* Sistema tipográfico ÚNICO para los títulos de las dos diapositivas: mismo
   tamaño, peso, interlineado, tracking, ancho máximo y espaciado inferior.
   Se declara aquí para que ni el h1 ni el <p role="heading"> hereden estilos
   distintos de sus etiquetas. */
.hero__title {
  margin: 0 0 var(--space-4);
  /* 18ch partía «Soluciones tecnológicas para impulsar tu comercio» en tres
     líneas. Con 26ch las dos diapositivas caben en dos, que es como se leen
     de un vistazo; `text-wrap: balance` reparte el texto entre ellas. */
  max-inline-size: 26ch;
  font-family: var(--font-sans);
  /* Misma escala tipográfica que los heros de las minilandings. */
  font-size: var(--text-4xl);
  font-weight: 400;
  /* Igual que h1/h2: interlineado suficiente para que las dos líneas no se
     toquen. Las dos diapositivas comparten el valor. */
  line-height: 1.04;
  letter-spacing: var(--tracking-tight);
  color: #fff;
  text-wrap: balance;
}
.hero__lead {
  font-size: var(--text-lg);
  color: rgba(255, 255, 255, .86);
  margin-block-end: var(--space-6);
  max-inline-size: 46ch;
}
.hero .chip { margin-block-end: var(--space-4); }

/* --- Tarjetas flotantes del hero -----------------------------------------
   Ocupan la columna que dejó libre la ilustración y son PROPIAS de cada
   diapositiva: cuatro en la primera (las cuatro soluciones) y tres en la
   segunda (las ideas fuerza de su título).

   Acabado LIQUID GLASS: vidrio ahumado sobre el hero. El tinte azul oscuro de
   la base es lo que garantiza la legibilidad —el texto va en blanco y detrás
   puede pasar tanto el campo oscuro de la ilustración como el resplandor del
   globo—, y encima se montan las cuatro señas del material:

     1. filo superior luminoso   inset 0 1px 0 rgba(255,255,255,.42)
     2. brillo interno difuso    inset 0 18px 30px -22px rgba(255,255,255,.55)
     3. reflejo especular        ::before, una diagonal muy tenue
     4. rebote de luz inferior   ::after, una línea clara en el canto de abajo

   El desenfoque va con saturate() para que el color que pasa por detrás no se
   apague, que es lo que distingue este acabado de un simple fondo translúcido.
   -------------------------------------------------------------------------- */
.hero__cards {
  position: relative;
  display: grid;
  gap: clamp(.6rem, 1.1vw, 1rem);
  margin: 0;
  padding: 0;
  list-style: none;
  justify-items: start;
  align-content: center;
  min-inline-size: 0;
}

.hero__card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: .75rem;

  /* ======================================================================
     CONFIGURAR AQUÍ EL TAMAÑO DE CADA HERO CARD

     · inline-size controla el ancho máximo de la tarjeta.
     · padding controla el espacio interno y, por tanto, su altura.
     · Para una altura fija opcional, agrega: block-size: 5rem;
     ====================================================================== */
  inline-size: min(100%, 10rem);
  padding: .7rem .9rem;
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: var(--radius);
  backdrop-filter: blur(10px) saturate(1.5);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  color: #fff;
  animation: hero-tag-float 6s cubic-bezier(.4, 0, .2, 1) infinite;
  will-change: transform;
}

/* Reflejo especular: una diagonal clarísima que recorre el vidrio. */
.hero__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(118deg,
    rgba(255, 255, 255, 0) 32%,
    rgba(255, 255, 255, .13) 48%,
    rgba(255, 255, 255, 0) 62%);
  pointer-events: none;
}
/* Rebote de luz en el canto inferior. */
.hero__card::after {
  content: "";
  position: absolute;
  inset-inline: 12%;
  inset-block-end: 0;
  block-size: 1px;
  z-index: -1;
  background: linear-gradient(90deg,
    transparent, rgba(255, 255, 255, .34), transparent);
  pointer-events: none;
}

/* ========================================================================
   CONFIGURAR AQUÍ LA POSICIÓN DE LAS HERO CARDS

   · margin-inline-start mueve cada tarjeta horizontalmente.
   · Aumenta el valor para desplazarla a la derecha.
   · Reduce el valor para desplazarla a la izquierda.
   · animation-delay sólo cambia el momento de la animación, no su posición.

   El bloque completo se alinea desde .hero__cards, unas líneas más arriba,
   mediante justify-items (horizontal) y align-content (vertical).
   ======================================================================== */
.hero__card:nth-child(1) { margin-inline-start: 0;                        animation-delay: 0s; }
.hero__card:nth-child(2) { margin-inline-start: clamp(20rem, 4.5vw, 3.5rem); animation-delay: -1.5s; }
.hero__card:nth-child(3) { margin-inline-start: clamp(.5rem, 2vw, 1.5rem);  animation-delay: -3s; }
.hero__card:nth-child(4) { margin-inline-start: clamp(18rem, 6vw, 4.5rem); animation-delay: -4.5s; }

/* Con cuatro tarjetas el bloque crece: se aprieta un poco para que siga
   entrando en el alto del hero sin empujarlo. */
.hero__cards[data-count="4"] { gap: clamp(.45rem, .8vw, .75rem); }
.hero__cards[data-count="4"] .hero__card { padding-block: .6rem; }

.hero__card-icon { flex: none; display: grid; place-items: center; }
.hero__card-icon img { inline-size: 38px; block-size: 38px; object-fit: contain; }
/* Los iconos temáticos ya traen su propia tile de color; sobre el vidrio
   pierden el borde para no dibujar un recuadro dentro de otro. */
.hero__card-icon .icon-tile { box-shadow: none; }

.hero__card-text { display: grid; gap: .1rem; min-inline-size: 0; }
.hero__card-text b {
  font-size: var(--text-sm);
  font-weight: 700;
  color: inherit;
  line-height: 1.25;
}
.hero__card-text small {
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, .82);
  line-height: 1.35;
}

@media (prefers-reduced-motion: reduce) {
  .hero__card { animation: none; }
}

/* Sin backdrop-filter el vidrio se quedaría en un velo plano: se compensa
   subiendo la opacidad del tinte, que es lo que sostiene el contraste. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero__card {
    background: linear-gradient(135deg, rgba(18, 32, 74, .86) 0%, rgba(8, 16, 44, .80) 100%);
  }
}

/* Por debajo del tramo de dos columnas el hero se apila y las tarjetas
   quedarían en una lista bajo los botones, alargando la portada justo cuando
   menos alto hay. Ahí desaparecen: las cuatro soluciones se presentan enteras
   en la sección siguiente. */
@media (max-width: 900px) {
  .hero__cards { display: none; }
}

.hero-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .16);
  backdrop-filter: blur(10px);
  box-shadow: 0 16px 40px rgba(2, 10, 34, .35);
}
.hero-tile:nth-child(odd) { transform: translateY(-.75rem); }
.hero-tile__name { font-weight: 700; font-size: var(--text-sm); color: #fff; }
.hero-tile__desc { font-size: var(--text-xs); color: rgba(255, 255, 255, .72); line-height: 1.45; }

/* Controles del slider */
.hero__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block-end: var(--space-6);
}
.hero__dots { display: flex; gap: .45rem; }
.hero__dot {
  inline-size: 42px;
  block-size: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
}
.hero__dot::before {
  content: "";
  inline-size: 2rem;
  block-size: 4px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .34);
  transition: background-color var(--duration) var(--ease), inline-size var(--duration) var(--ease);
}
.hero__dot[aria-selected="true"]::before { background: var(--color-cta); inline-size: 2.75rem; }
.hero__dot:hover::before { background: rgba(255, 255, 255, .6); }

.hero__playpause {
  display: inline-grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .3);
  color: #fff;
  transition: background-color var(--duration) var(--ease);
}
.hero__playpause:hover { background: rgba(255, 255, 255, .16); }
.hero__playpause .glyph--play { display: none; }
.hero[data-playing="false"] .hero__playpause .glyph--play { display: block; }
.hero[data-playing="false"] .hero__playpause .glyph--pause { display: none; }

/* --------------------------------------------------------------------------
   2. Cabecera de página interior
   -------------------------------------------------------------------------- */

.page-hero {
  position: relative;
  overflow: hidden;
  color: #fff;
  isolation: isolate;

  /* Alto completo. Lo conservan SÓLO las páginas de servicios, que son las
     que traen ilustración. Las demás piden 'height' => 'short' al componente
     y caen en .page-hero--short (ver más abajo). */
  min-block-size: var(--hero-min-h);
  display: flex;
  flex-direction: column;
  justify-content: center;

  /* Degradado sutil hacia un tono más oscuro, más dos círculos de luz muy
     difuminados. Todo va en el propio background: se recorta solo con la caja
     y no necesita marcado adicional.

     La orientación NO es casual. El color de marca ocupa el lado derecho —el
     de la imagen— y el lado izquierdo, donde vive el texto, cae hacia el tono
     oscuro. Es lo que permite mantener #F56600 en TiendaMaker: sobre el naranja
     puro el texto blanco daría 3,1:1 (por debajo del 4,5:1 de AA), mientras que
     sobre el extremo oscuro supera holgadamente el umbral. */
  background:
    /* círculo de luz principal, arriba a la derecha. Apenas lleva blanco:
       lo justo para que se lea como un foco, sin desteñir el color de marca. */
    radial-gradient(circle at 80% 14%,
      color-mix(in srgb, var(--hero-color) 86%, #FFFFFF) 0%,
      color-mix(in srgb, var(--hero-color) 55%, transparent) 32%,
      transparent 56%),
    /* segundo glow, más abajo y más tenue */
    radial-gradient(circle at 97% 86%,
      color-mix(in srgb, var(--hero-color) 90%, #FFFFFF) 0%,
      color-mix(in srgb, var(--hero-color) 40%, transparent) 26%,
      transparent 52%),
    /* Degradado base. El color de marca se concentra en el último tramo —el
       lado de la imagen— y la columna del texto queda en el tono oscuro.
       Es lo que permite usar #F56600 tal cual: sobre el naranja puro el texto
       blanco da 3,1:1, por debajo del 4,5:1 que exige AA. */
    linear-gradient(112deg,
      color-mix(in srgb, var(--hero-color) 44%, #050A1E) 0%,
      color-mix(in srgb, var(--hero-color) 50%, #050A1E) 50%,
      color-mix(in srgb, var(--hero-color) 68%, #050A1E) 74%,
      var(--hero-color) 100%);
}

/* En una sola columna el texto ocupa todo el ancho y cruzaría el lado claro
   del degradado horizontal (el contraste caía a ~2,5:1). Aquí el degradado
   gira a vertical: oscuro arriba, donde va el texto; color de marca abajo,
   donde queda la imagen. */
@media (max-width: 860px) {
  .page-hero {
    background:
      radial-gradient(circle at 84% 86%,
        color-mix(in srgb, var(--hero-color) 60%, #FFFFFF) 0%,
        transparent 52%),
      linear-gradient(174deg,
        color-mix(in srgb, var(--hero-color) 52%, #050A1E) 0%,
        color-mix(in srgb, var(--hero-color) 64%, #050A1E) 58%,
        var(--hero-color) 100%);
  }
}

/* --- Fondo fotográfico opcional del hero --------------------------------- */
/* Va DEBAJO del degradado de marca y a opacidad baja: la imagen aporta
   textura, nunca contraste. Así el texto blanco conserva su ratio sea cual
   sea la foto que se entregue. La capa sólo existe si el archivo existe
   (lo decide page-hero.php), de modo que el hero nunca queda a medias. */
.page-hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--hero-image);
  background-position: var(--hero-image-pos, center);
  background-size: cover;
  background-repeat: no-repeat;
  opacity: .28;
  pointer-events: none;
}
@media (max-width: 860px) {
  .page-hero__backdrop {
    background-image: var(--hero-image-sm, var(--hero-image));
    background-position: var(--hero-image-sm-pos, center);
  }
}

/* Trama de puntos muy tenue sobre el lado de la imagen */
.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(rgba(255, 255, 255, .13) 1px, transparent 1px);
  background-size: 24px 24px;
  -webkit-mask-image: radial-gradient(ellipse 70% 80% at 78% 25%, #000, transparent 70%);
  mask-image: radial-gradient(ellipse 70% 80% at 78% 25%, #000, transparent 70%);
}
.page-hero .breadcrumbs a { color: rgba(255, 255, 255, .74); }
.page-hero .breadcrumbs a:hover { color: #fff; }
.page-hero .breadcrumbs [aria-current="page"] { color: #fff; }
.page-hero .breadcrumbs .sep { color: rgba(255, 255, 255, .4); }

.page-hero__inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
  gap: clamp(var(--space-5), 4vw, var(--space-7));
  align-items: center;
  padding-block: clamp(2rem, 1.2rem + 3.4vw, 3.75rem) clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
}

/* La imagen del hero no puede imponer el alto de la sección: se acota y se
   centra, conservando proporción (nunca se recorta ni se deforma). */
.page-hero__inner figure .media,
.page-hero__inner figure .media-placeholder {
  max-block-size: var(--hero-media-h);
  inline-size: auto;
  max-inline-size: 100%;
  margin-inline: auto;
}
.page-hero h1 { color: #fff; font-size: var(--text-4xl); margin-block-end: var(--space-4); }
.page-hero__lead {
  font-size: var(--text-lg);
  color: rgba(255, 255, 255, .86);
  max-inline-size: 52ch;
  margin-block-end: var(--space-6);
}
.page-hero__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-block-end: var(--space-5);
  padding: .6rem 1rem .6rem .6rem;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, .96);
  box-shadow: var(--shadow-md);
}
.page-hero__logo img { block-size: 30px; inline-size: auto; }

/* Tira de marcas aceptadas, bajo los botones del hero. Son logotipos de
   terceros: van tal cual, sin recolorear y sin cápsula. */
.page-hero__strip { margin: var(--space-6) 0 0; }
/* Se acota SÓLO el ancho: con max-inline-size y max-block-size a la vez el
   navegador resuelve el conflicto por el lado del alto y recortaba la última
   marca de la tira. Con una sola restricción la proporción se conserva sola. */
.page-hero__strip img {
  display: block;
  inline-size: min(100%, 27rem);
  block-size: auto;
}
.page-hero__logo .placeholder { inline-size: 9rem; }

/* Variante compacta, sin ilustración */
.page-hero--compact .page-hero__inner { grid-template-columns: 1fr; }
.page-hero--compact .page-hero__lead { max-inline-size: 60ch; }

/* Variante corta: mismo lenguaje visual, menos alto.
   La piden Quiénes somos, Alianzas comerciales, Seguridad de la información y
   Contacto. Las páginas de servicios NO la usan. */
.page-hero--short { min-block-size: var(--hero-min-h-short); }
.page-hero--short .page-hero__inner { padding-block: var(--space-5) var(--space-6); }
.page-hero--short h1 { font-size: var(--text-3xl); }


/* --- Etiquetas flotantes del hero ---------------------------------------- */
/* Tarjetas blancas apoyadas sobre la ilustración. El gesto es el mismo que
   usan las tarjetas del hero de Ventrix CRM: un vaivén de 8 px en 6 s, con
   las dos desfasadas entre sí (animation-delay negativo) para que nunca
   suban a la vez. El bloque global de prefers-reduced-motion de reset.css
   ya las detiene. */
/* La <figure> ocupaba todo el ancho de la columna mientras la imagen, más
   estrecha, quedaba centrada dentro: las etiquetas absolutas se anclaban a la
   caja y no a la ilustración. Con fit-content la figura se ciñe a la imagen y
   las etiquetas apoyan sobre su borde real. */
.page-hero__figure {
  position: relative;
  inline-size: fit-content;
  max-inline-size: 100%;
  margin-inline: auto;
  /* .media-frame recorta con overflow: hidden para redondear las capturas;
     aquí las etiquetas deben poder sobresalir del borde de la imagen. */
  overflow: visible;
}

.hero-tag {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin: 0;
  padding: .7rem .95rem;
  max-inline-size: min(64%, 17rem);
  border: 1px solid rgba(255, 255, 255, .75);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, .94);
  box-shadow: 0 16px 35px rgba(10, 18, 30, .22);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #232F3E;
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.3;
  text-wrap: balance;
  animation: hero-tag-float 6s cubic-bezier(.4, 0, .2, 1) infinite;
  will-change: transform;
}
/* Apoyadas en las esquinas opuestas de la ilustración, lo bastante abajo y
   arriba para no montarse sobre los elementos que la propia imagen ya lleva. */
.hero-tag--one { inset-inline-start: -1.1rem; inset-block-end: .9rem; }
.hero-tag--two { inset-inline-end: -1.4rem;   inset-block-start: -1.1rem; animation-delay: -3s; }

.hero-tag__check { display: grid; place-items: center; flex: none; color: #0F7A4A; }
.hero-tag__dot {
  flex: none;
  inline-size: .6rem;
  block-size: .6rem;
  border-radius: 50%;
  background: #17A65F;
  box-shadow: 0 0 0 4px rgba(23, 166, 95, .18);
}

@keyframes hero-tag-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}

/* En una columna la ilustración se estrecha: las etiquetas se pegan a los
   bordes y reducen su caja para no taparla. */
@media (max-width: 860px) {
  .hero-tag { padding: .5rem .7rem; font-size: var(--text-xs); max-inline-size: min(72%, 14rem); }
  .hero-tag--one { inset-inline-start: -.2rem; inset-block-end: -.5rem; }
  .hero-tag--two { inset-inline-end: -.2rem;   inset-block-start: -.5rem; }
}

/* --- Hero de TiendaMaker -------------------------------------------------- */
/* Réplica del fondo de tiendamaker.com: base #232F3E, dos orbes muy
   difuminados —naranja abajo a la derecha, violeta a la izquierda— y una
   retícula de 72 px que se desvanece hacia la derecha.

   En el original los orbes son dos <div> circulares con filter: blur(90px);
   aquí se resuelven como capas de background. El resultado medido es el
   mismo y evita un filtro a pantalla completa en cada repintado.

   Contraste: en el punto más naranja del orbe el fondo resultante es
   #964D1C y el texto blanco da 6,2:1; sobre la base #232F3E, 13,7:1. */
[data-solution="tiendamaker"] .page-hero {
  background:
    radial-gradient(circle 340px at calc(100% - 145px) calc(100% - 55px),
      rgba(245, 102, 0, .55) 0%,
      rgba(245, 102, 0, .50) 42%,
      rgba(245, 102, 0, 0)   100%),
    radial-gradient(circle 280px at -5px calc(20% + 175px),
      rgba(135, 62, 255, .24) 0%,
      rgba(135, 62, 255, .20) 40%,
      rgba(135, 62, 255, 0)   100%),
    #232F3E;
}

/* La trama de puntos general se sustituye por la retícula de líneas. */
[data-solution="tiendamaker"] .page-hero::before {
  opacity: .08;
  background-image:
    linear-gradient(rgba(255, 255, 255, .3) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .3) 1px, transparent 1px);
  background-size: 72px 72px;
  -webkit-mask-image: linear-gradient(to right, #000, transparent 72%);
  mask-image: linear-gradient(to right, #000, transparent 72%);
}

/* --------------------------------------------------------------------------
   3. Portada — bloques específicos
   -------------------------------------------------------------------------- */

/* --- Presentación: texto + anillos de marca ------------------------------
   El texto no llena el ancho del contenedor, así que la mitad derecha quedaba
   vacía. Los anillos la ocupan como motivo de marca; al ser decoración se
   pintan con máscara y toman el color de --rings-art, que tiene valor propio
   en claro y en oscuro. */
.intro-band {
  display: grid;
  gap: clamp(var(--space-5), 5vw, var(--space-8));
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  align-items: center;
}
.intro-band .section-head { margin-block-end: 0; }
.intro-rings {
  margin: 0;
  justify-self: center;
  inline-size: min(100%, 24rem);
  aspect-ratio: 639 / 674;
  background: var(--rings-art);
  -webkit-mask: url("../assets/images/anillos-abitmedia.webp") no-repeat center / contain;
  mask: url("../assets/images/anillos-abitmedia.webp") no-repeat center / contain;
  pointer-events: none;
}
/* Por debajo del punto en que la banda se apila, los anillos dejan de aportar
   y sólo alargarían la sección. */
@media (max-width: 760px) {
  .intro-rings { display: none; }
}

.intro-pillars {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  margin-block-start: var(--space-6);
}
.intro-pillar { display: flex; flex-direction: column; gap: var(--space-3); }
.intro-pillar h3 { font-size: var(--text-base); }
.intro-pillar p { font-size: var(--text-sm); color: var(--color-text-muted); }

.alliance-card {
  display: grid;
  gap: var(--space-4);
  align-content: start;
}
.alliance-card__logo {
  display: grid;
  place-items: center;
  /* Alto MÍNIMO, no fijo: el logotipo manda y nunca se recorta. */
  min-block-size: 7rem;
  padding: var(--space-5) var(--space-6);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
/* Con un logotipo real, la caja toma el color de fondo de esa marca
   (--alliance-bg). Los logotipos de Datafast y Deuna llegan en versión BLANCA:
   sobre blanco serían invisibles, así que necesitan su superficie de marca.
   Si algún aliado entrega su logotipo a color, basta con omitir 'brand_bg' en
   app/content/company.php y la caja vuelve a fondo blanco. */
.alliance-card__logo--image { background: var(--alliance-bg, #fff); }
/* El logotipo escala por su proporción intrínseca (no por object-fit), que es
   más predecible: se limita el ancho y el alto, y el navegador conserva la
   relación de aspecto. Así ningún logotipo se deforma ni se corta, y le queda
   un área de seguridad alrededor. */
.alliance-card__logo img {
  inline-size: auto;
  max-inline-size: min(100%, 15rem);
  block-size: auto;
  max-block-size: 3.75rem;
  object-fit: contain;
}
.alliance-card__wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-text-strong);
  font-size: var(--text-xl);
}
.alliance-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-block-start: auto;
  padding-block-start: var(--space-3);
}

/* --------------------------------------------------------------------------
   4. Mini landings de solución
   -------------------------------------------------------------------------- */

.solution-nav {
  position: sticky;
  top: var(--header-h, 72px);
  z-index: 80;
  background: color-mix(in srgb, var(--color-surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--color-border);
}
/* Enlaces a la izquierda, identidad de la solución a la derecha */
.solution-nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.solution-nav__list {
  display: flex;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  min-inline-size: 0;
}
.solution-nav__list::-webkit-scrollbar { display: none; }

/* Identidad de la solución: no es una pestaña. No es clicable, no recibe foco
   y se separa del grupo de enlaces con un filete. */
.solution-nav__brand {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex: none;
  margin: 0;
  padding-inline-start: var(--space-4);
  border-inline-start: 1px solid var(--color-border);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-strong);
  white-space: nowrap;
}
/* El recurso de marca va suelto: sin cápsula, sin fondo, sin filtros y con
   su propia área de seguridad. */
.solution-nav__brand-icon {
  display: grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  flex: none;
}
.solution-nav__brand-icon img { object-fit: contain; max-inline-size: 100%; max-block-size: 100%; }
.solution-nav__list a {
  display: inline-flex;
  align-items: center;
  min-block-size: 46px;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-muted);
  text-decoration: none;
  white-space: nowrap;
  border-block-end: 2px solid transparent;
}
.solution-nav__list a:hover { color: var(--brand); border-block-end-color: var(--brand-soft); }
.solution-nav__list a[aria-current="true"] { color: var(--brand); border-block-end-color: var(--brand); }

/* Listado de /soluciones: cuatro tarjetas con texto largo se leen mejor en
   2×2 que en una fila de tres más una suelta. */
.solutions-list {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
}

.modality-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}
.modality-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 980px) {
  .modality-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .modality-grid--4 { grid-template-columns: 1fr; }
}

.feature-grid {
  display: grid;
  gap: clamp(var(--space-4), 3vw, var(--space-6)) var(--space-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

.solution-cta {
  display: grid;
  gap: var(--space-5);
  padding: clamp(1.5rem, 1.1rem + 1.8vw, 2.5rem);
  border-radius: var(--radius-xl);
  background: var(--brand-soft);
  border: 1px solid color-mix(in srgb, var(--brand) 24%, transparent);
}
.solution-cta h2 { font-size: var(--text-2xl); }
.solution-cta p { color: var(--color-text-muted); max-inline-size: 52ch; }

/* Aplicación móvil dentro de la landing */
.app-promo {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  align-items: center;
  padding: clamp(1.25rem, 1rem + 1.4vw, 2rem);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}

/* La captura vertical de la aplicación disparaba el alto de la sección por
   encima de los 1.100 px. Se acota para que el bloque quede en ~500 px, sin
   recortar ni deformar la imagen: sólo se reduce su escala. */
/* Alto fijado del bloque de aplicación móvil: 500 px en escritorio.
   Es un MÍNIMO, no un alto rígido: en móvil el contenido se apila y la
   sección crece, de modo que nunca se recorta nada. */
.section--app {
  display: grid;
  align-content: center;
  min-block-size: 500px;
}
@media (max-width: 760px) {
  .section--app { min-block-size: 0; }
}

.app-promo .media,
.app-promo .media-placeholder {
  max-block-size: 18rem;
  inline-size: auto;
  max-inline-size: 100%;
  margin-inline: auto;
}

/* --- Slider vertical de mockups ------------------------------------------
   Dos capturas que se relevan en vertical: la que está en pantalla baja hasta
   salir por el borde inferior y la siguiente sube desde ese mismo borde para
   ocupar su sitio. Ambas se apilan en la misma celda del grid, así que el
   bloque conserva su alto aunque los mockups tengan proporciones distintas.
   -------------------------------------------------------------------------- */
.app-slider {
  position: relative;
  display: grid;
  justify-items: center;
}
.app-slider__stage {
  position: relative;
  inline-size: 100%;
  /* Alto fijo: es lo que impide que el bloque dé un salto al cambiar de
     mockup (el teléfono es 9:16 y la tableta 3:4). */
  block-size: clamp(16rem, 28vw, 26rem);
  /* La diapositiva que entra y la que sale viven fuera de la caja por abajo;
     el recorte es lo que hace que aparezcan y desaparezcan por ese borde. */
  overflow: hidden;
}
/* Posicionadas, no en flujo: así su alto es el del escenario y no al revés.
   Si se apilaran con grid, el alto de la fila lo acabaría fijando el mockup
   y el recorte no serviría de nada. */
.app-slider__slide {
  position: absolute;
  inset: 0;
  margin: 0;
  /* Estado de reposo = fuera de cuadro, por abajo. */
  transform: translateY(100%);
  opacity: 0;
  transition: transform .65s var(--ease), opacity .65s var(--ease);
}
/* La que entra espera a que la anterior termine de bajar: primero baja una,
   después sube la otra, que es como se lee la transición. */
.app-slider__slide[data-active] {
  transform: translateY(0);
  opacity: 1;
  transition-delay: .3s;
}
/* La caja la fija el escenario, no el archivo: las dos diapositivas ocupan
   exactamente la misma y `contain` encaja dentro cada mockup con su propia
   proporción. Sin esto el teléfono (9:16) se saldría del recorte.
   Se dimensiona con `inset`, no con porcentajes: un alto en % dentro de una
   caja que a su vez se mide por su contenido es circular y el navegador lo
   descarta, que es justo lo que dejaba al teléfono a tamaño natural. */
.app-promo .app-slider .media {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 100%;
  max-block-size: none;
  aspect-ratio: auto;
  object-fit: contain;
}

/* Control de pausa (WCAG 2.2.2). Se apoya en la esquina del bloque y sólo
   toma color al pasar por encima: no debe competir con el mockup. */
.app-slider__playpause {
  position: absolute;
  inset-block-end: 0;
  inset-inline-end: 0;
  display: inline-grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  transition: color var(--duration) var(--ease), border-color var(--duration) var(--ease);
}
.app-slider__playpause:hover {
  color: var(--brand);
  border-color: var(--brand);
}
.app-slider__playpause .glyph--play { display: none; }
.app-slider[data-playing="false"] .app-slider__playpause .glyph--play { display: block; }
.app-slider[data-playing="false"] .app-slider__playpause .glyph--pause { display: none; }

/* Sin animación no hay nada que relevar ni que pausar: se queda la primera. */
@media (prefers-reduced-motion: reduce) {
  .app-slider__slide { transition: none; }
}

/* --------------------------------------------------------------------------
   5. Recursos
   -------------------------------------------------------------------------- */

.api-card { border-block-start: 4px solid var(--brand); }
.api-card dl { display: grid; gap: var(--space-2); margin: 0; }
.api-card dt {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.api-card dd { margin: 0; font-size: var(--text-sm); }

.empty-state {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding: clamp(2rem, 1.4rem + 2.6vw, 3.5rem) var(--space-5);
  text-align: center;
  background: var(--color-surface);
  border: 1.5px dashed var(--color-border-strong);
  border-radius: var(--radius-xl);
}
.empty-state p { max-inline-size: 52ch; color: var(--color-text-muted); }

.plugin-table-wrap { overflow-x: auto; }
.plugin-table {
  inline-size: 100%;
  min-inline-size: 44rem;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.plugin-table th, .plugin-table td {
  padding: var(--space-3) var(--space-4);
  text-align: start;
  border-block-end: 1px solid var(--color-border);
  vertical-align: top;
}
.plugin-table th {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
  background: var(--color-surface-2);
}

.app-card { display: grid; gap: var(--space-5); }
/* Las capturas verticales de las aplicaciones no deben estirar la tarjeta */
.app-card .figure img { max-block-size: 32rem; inline-size: auto; margin-inline: auto; }
.app-card__head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.app-card__logo { block-size: 30px; inline-size: auto; }
.store-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* --------------------------------------------------------------------------
   6. Contacto y soporte
   -------------------------------------------------------------------------- */

.contact-layout {
  display: grid;
  gap: clamp(var(--space-5), 3vw, var(--space-7));
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  align-items: start;
}

.form-frame {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.form-frame__head { padding: var(--space-5) var(--space-5) 0; }
.form-frame__head p { color: var(--color-text-muted); font-size: var(--text-sm); margin-block-start: .4rem; }
.form-frame iframe {
  inline-size: 100%;
  /* El formulario externo supera los 700 px cuando muestra todos sus campos.
     El marco reserva el alto completo para que el desplazamiento lo controle
     la página y no aparezca un segundo scroll interno. */
  block-size: 62rem;
  border: 0;
  /* Sin scroll propio: quien se desplaza es la página, no el formulario. */
  overflow: hidden;
}

.channel-list { display: grid; gap: var(--space-3); }
.channel {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: var(--color-text);
  transition: border-color var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.channel:hover {
  border-color: color-mix(in srgb, var(--brand) 45%, var(--color-border));
  transform: translateY(-2px);
  color: var(--color-text);
}
.channel__body strong { display: block; color: var(--color-text-strong); font-size: var(--text-sm); }
.channel__body span { display: block; font-size: var(--text-xs); color: var(--color-text-muted); }
.channel__value { font-size: var(--text-sm); font-weight: 600; color: var(--brand); margin-block-start: .25rem; }

.support-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}
.support-card { scroll-margin-top: calc(var(--header-h, 72px) + var(--space-5)); }
.support-card--featured {
  border-color: color-mix(in srgb, var(--color-primary) 42%, var(--color-border));
  box-shadow: var(--shadow-sm);
}
.support-card__meta {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-text-strong);
  padding: .3rem .7rem;
  border-radius: var(--radius-full);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
}
.support-card__foot { margin-block-start: auto; padding-block-start: var(--space-3); }

/* --------------------------------------------------------------------------
   7. Blog (estado provisional) y 404
   -------------------------------------------------------------------------- */

.state-page {
  display: grid;
  /* La pista debe ceñirse al contenedor: con una pista 'auto' se dimensiona
     a max-content y desborda unos píxeles en pantallas estrechas. */
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  text-align: center;
  padding-block: clamp(3rem, 2rem + 6vw, 7rem);
  min-block-size: min(34rem, 58svh);
}
.state-page__inner { max-inline-size: 46rem; display: grid; justify-items: center; gap: var(--space-5); }
.state-page h1 { font-size: var(--text-4xl); }
.state-page p { color: var(--color-text-muted); font-size: var(--text-lg); }

.state-code {
  font-size: clamp(4rem, 2rem + 12vw, 8rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.05em;
  color: transparent;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-hover));
  -webkit-background-clip: text;
  background-clip: text;
}

.quick-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-block-start: var(--space-3);
}

/* --------------------------------------------------------------------------
   8. Empresa
   -------------------------------------------------------------------------- */

.mv-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}
.mv-card { min-block-size: 100%; }

/* --- Tira de retratos del equipo -----------------------------------------
   UNA SOLA FILA, siempre, y a TODO EL ANCHO DE LA VENTANA. La tira sale del
   contenedor de 1200 px (el marcado la saca de él en company.php) porque doce
   retratos dentro de esa caja obligaban a solaparlos, y en un monitor de 20"
   sobraba medio metro de margen a cada lado.

   El reparto lo hace una rejilla de doce columnas iguales: no hay solape
   posible y la separación es real en cualquier ancho. El diámetro se deduce de
   la columna, así que la fila se adapta sola de un teléfono a un monitor.

   El recurso de presentación sigue siendo la OPACIDAD, no el tamaño:
     · en reposo cada ficha vale lo que le asigna --weight, que la vista calcula
       con un seno sobre la fila (extremos 0,48 · centro 0,92);
     · --curve levanta el centro unos píxeles y dibuja una curva muy suave;
     · al señalar o enfocar una ficha, ESA recupera opacidad y color plenos y
       muestra su cargo; el resto se atenúa un poco más.
   -------------------------------------------------------------------------- */
.team-strip {
  /* Sin overflow ni máscara: eran lo que recortaba el cargo de los retratos de
     los extremos. La tira no desborda porque la rejilla nunca se sale de aquí. */
  inline-size: 100%;
  padding-inline: var(--gutter);
  margin-block-start: var(--space-7);
}

.team-row {
  --avatar: min(100%, 7.5rem);

  display: grid;
  /* Tantas columnas como retratos, todas iguales. La fila NUNCA se parte y las
     fichas NUNCA se montan: es la rejilla la que garantiza las dos cosas. */
  grid-template-columns: repeat(var(--team-count, 12), minmax(0, 1fr));
  gap: clamp(.25rem, .9vw, 1.5rem);
  justify-items: center;
  align-items: end;
  inline-size: 100%;
  max-inline-size: 120rem;
  margin: 0 auto;
  padding: 0 0 var(--space-6);
  list-style: none;
}

.team-row__item {
  position: relative;
  inline-size: var(--avatar);
  /* La curva se expresa en fracción del diámetro, no en píxeles fijos: así se
     ve igual de suave con retratos de 30 px que con los de 120 px. */
  margin-block-end: calc(var(--curve, 0) * var(--avatar) * .14);
  opacity: var(--weight, .6);
  transition: opacity var(--duration) var(--ease),
              transform var(--duration) var(--ease);
}

.team-row__item img {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-surface-2);
  box-shadow: 0 0 0 2px var(--color-background-2), var(--shadow-xs);
  /* Desaturado en reposo: la tira entra como una textura, no como doce caras
     compitiendo entre sí. */
  filter: grayscale(1) contrast(1.02);
  transition: filter var(--duration) var(--ease),
              box-shadow var(--duration) var(--ease);
}

/* --- El cargo -------------------------------------------------------------
   Sólo aparece cuando se pide. Se ancla al centro de su retrato, pero las dos
   fichas de cada extremo lo alinean por su borde: centrado se salía de la
   pantalla y el texto quedaba cortado. */
.team-row__role {
  position: absolute;
  inset-block-start: calc(100% + .55rem);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  inline-size: max-content;
  max-inline-size: 12rem;
  padding: .35rem .65rem;
  border-radius: var(--radius-sm);
  background: var(--color-text-strong);
  color: var(--color-surface);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  text-wrap: balance;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);
}
.team-row__item:nth-child(-n + 2) .team-row__role {
  left: 0;
  transform: translateX(0) translateY(4px);
  text-align: start;
}
.team-row__item:nth-last-child(-n + 2) .team-row__role {
  left: auto;
  right: 0;
  transform: translateX(0) translateY(4px);
  text-align: end;
}

/* --- El gesto -------------------------------------------------------------
   Con :has() el resto de la tira cede un punto de opacidad mientras una ficha
   está activa. Donde :has() no exista, la ficha activa sigue destacando por sí
   misma: el efecto se degrada, no se rompe. */
.team-row:has(.team-row__item:hover) .team-row__item,
.team-row:has(.team-row__item:focus-within) .team-row__item { opacity: calc(var(--weight, .6) * .7); }

.team-row .team-row__item:hover,
.team-row .team-row__item:focus-within {
  z-index: 2;
  opacity: 1;
  transform: translateY(-6px) scale(1.08);
}
.team-row__item:hover img,
.team-row__item:focus-within img {
  filter: grayscale(0);
  box-shadow: 0 0 0 3px var(--brand), var(--shadow-sm);
}
.team-row__item:hover .team-row__role,
.team-row__item:focus-within .team-row__role { opacity: 1; }
.team-row__item:hover .team-row__role,
.team-row__item:focus-within .team-row__role { transform: translateX(-50%) translateY(0); }
.team-row__item:nth-child(-n + 2):hover .team-row__role,
.team-row__item:nth-child(-n + 2):focus-within .team-row__role,
.team-row__item:nth-last-child(-n + 2):hover .team-row__role,
.team-row__item:nth-last-child(-n + 2):focus-within .team-row__role { transform: translateX(0) translateY(0); }

@media (max-width: 900px) {
  .team-row { --avatar: min(100%, 4.5rem); }
}

/* --- Teléfono --------------------------------------------------------------
   Doce columnas en 358 px dejan retratos de 27 px: una cara deja de
   reconocerse. Aquí la tira SIGUE SIENDO UNA SOLA FILA, pero se recorre
   lateralmente con el dedo, así que cada retrato conserva un tamaño legible y
   no falta nadie. El scroll es sólo suyo: la página no se mueve.

   El cargo no se muestra: el scroll horizontal recorta lo que sobresalga de la
   tira, y en táctil tampoco hay :hover. Sigue estando en el texto alternativo
   de cada retrato, que es de donde lo lee un lector de pantalla. */
@media (max-width: 700px) {
  .team-strip { padding-inline: 0; }
  .team-row {
    display: flex;
    gap: .55rem;
    justify-content: flex-start;
    inline-size: auto;
    padding-inline: var(--gutter);
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .team-row::-webkit-scrollbar { display: none; }
  .team-row__item {
    flex: 0 0 auto;
    inline-size: 4.25rem;
    scroll-snap-align: center;
  }
  .team-row__role { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .team-row__item,
  .team-row__item img,
  .team-row__role { transition: none; }
  .team-row .team-row__item:hover,
  .team-row .team-row__item:focus-within { transform: none; }
}

/* En táctil no hay :hover fiable: la tira se entrega ya legible, a plena
   opacidad y en color, y los cargos quedan en el texto alternativo. */
@media (hover: none) {
  .team-row__item { opacity: calc(var(--weight, .6) + .25); }
  .team-row__item img { filter: grayscale(.35); }
}

.prose { max-inline-size: 68ch; }
.prose > * + * { margin-block-start: var(--space-4); }
.prose h2 { margin-block-start: var(--space-7); }
.prose h3 { margin-block-start: var(--space-6); }
.prose p { color: var(--color-text-muted); }

/* Documentos legales publicados: dos columnas fijas con el mismo tratamiento
   de tarjeta oscura con imagen que misión y visión (.card--media-dark). */
.legal-cards {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.legal-card { min-block-size: 100%; }
.legal-card .card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  flex: 1;
}
/* El enlace lleva el ::after de .card__link: toda la tarjeta es clicable. */
.legal-card__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: auto;
  color: #8DCBFF;
  font-weight: 600;
  font-size: var(--text-sm);
  text-decoration: none;
}
.legal-card__cta svg { transition: transform var(--duration) var(--ease); }
.legal-card:hover .legal-card__cta { text-decoration: underline; }
.legal-card:hover .legal-card__cta svg { transform: translateX(2px); }

@media (max-width: 760px) {
  .legal-cards { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Documentos legales (privacidad, cookies)
   --------------------------------------------------------------------------
   Son textos largos que se leen a saltos: el índice acompaña la lectura fijo
   al costado y la columna de texto se mantiene en una medida cómoda. El
   contenido es jurídico y no se toca; aquí sólo se resuelve su presentación.
   -------------------------------------------------------------------------- */

.legal__grid {
  display: grid;
  /* minmax(0,1fr) y no 'auto': si no, la medida de 72ch del documento estira
     la columna y el móvil se desborda a lo ancho. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  align-items: start;
}

/* --- Índice --------------------------------------------------------------- */
.legal-index {
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
/* El resumen sólo es un control en móvil: en escritorio el índice está siempre
   desplegado y el elemento <details> se comporta como una caja normal. */
.legal-index__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  color: var(--color-text-strong);
}
.legal-index__summary::-webkit-details-marker { display: none; }
.legal-index__summary svg { transition: transform var(--duration) var(--ease); }
.legal-index[open] .legal-index__summary { margin-block-end: var(--space-4); }
.legal-index[open] .legal-index__summary svg { transform: rotate(90deg); }

/* En móvil el título del índice lo pone el propio <summary>; en escritorio,
   donde el summary se oculta, lo pone este rótulo. Nunca los dos. */
.legal-index__title { display: none; }
@media (min-width: 1024px) {
  .legal-index__title { display: block; }
}
.legal-index__title {
  margin: 0 0 var(--space-3);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.legal-index__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-1);
}
.legal-index__item a {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  border-inline-start: 2px solid transparent;
  color: var(--color-text-muted);
  text-decoration: none;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}
.legal-index__item a:hover,
.legal-index__item a:focus-visible {
  background: var(--color-surface);
  border-inline-start-color: var(--brand);
  color: var(--color-text-strong);
}
/* Los apartados 4.1, 6.1… cuelgan visualmente de su sección padre. */
.legal-index__item--n3 a {
  padding-inline-start: var(--space-5);
  font-size: var(--text-xs);
}

/* --- Documento ------------------------------------------------------------ */
.legal__doc { max-inline-size: 72ch; }
.legal__intro { color: var(--color-text-muted); }
.legal__section { scroll-margin-top: calc(var(--header-h, 72px) + var(--space-5)); }
.legal__section + .legal__section { margin-block-start: var(--space-7); }

.legal__doc h2 {
  margin-block-end: var(--space-4);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--color-border);
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  color: var(--color-text-strong);
}
.legal__doc h3 {
  margin-block-end: var(--space-3);
  font-size: var(--text-lg);
  color: var(--color-text-strong);
}
.legal__doc p { margin-block: 0 var(--space-4); color: var(--color-text-muted); }
.legal__doc ul,
.legal__doc ol { margin-block: 0 var(--space-4); padding-inline-start: var(--space-6); }
.legal__doc li { margin-block-end: var(--space-2); color: var(--color-text-muted); }
.legal__doc li::marker { color: var(--brand); }
.legal__doc :is(b, strong) { color: var(--color-text-strong); }
.legal__doc a { color: var(--brand); overflow-wrap: anywhere; }

/* Las tablas del documento llegan envueltas para poder desplazarse en móvil
   sin romper el ancho de la página. */
.legal-table { overflow-x: auto; margin-block-end: var(--space-4); }
.legal-table table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.legal-table :is(th, td) {
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  text-align: start;
  vertical-align: top;
  color: var(--color-text-muted);
}
.legal-table th { background: var(--color-surface-2); color: var(--color-text-strong); }

.legal__source {
  margin-block-start: var(--space-7);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--color-border);
  font-size: var(--text-sm);
}
.legal__source a { display: inline-flex; align-items: center; gap: var(--space-1); }

@media (min-width: 1024px) {
  .legal__grid { grid-template-columns: minmax(0, 17rem) minmax(0, 1fr); gap: var(--space-8); }
  .legal-index {
    position: sticky;
    top: calc(var(--header-h, 72px) + var(--space-5));
    max-block-size: calc(100vh - var(--header-h, 72px) - var(--space-8));
    overflow-y: auto;
  }
  .legal-index__summary { display: none; }
}

/* Los documentos legales se imprimen y se archivan: la versión impresa deja
   sólo el texto, con las direcciones de los enlaces visibles. */
@media print {
  .legal-index,
  .legal__source { display: none; }
  .legal__doc { max-inline-size: none; }
  .legal__section { break-inside: auto; }
  .legal__doc :is(h2, h3) { break-after: avoid; }
  .legal__doc a::after { content: " (" attr(href) ")"; font-size: .85em; word-break: break-all; }
}

/* --------------------------------------------------------------------------
   /dev/recursos — guía de revisión (sólo en desarrollo)
   -------------------------------------------------------------------------- */
.dev-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
}
.dev-grid--wide { grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); }

.dev-card {
  display: grid;
  gap: var(--space-3);
  justify-items: center;
  margin: 0;
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}
.dev-card figcaption { display: grid; gap: .3rem; justify-items: center; text-align: center; inline-size: 100%; }
.dev-card strong { font-size: var(--text-sm); color: var(--color-text-strong); word-break: break-all; }
.dev-card span { font-size: var(--text-xs); color: var(--color-text-muted); }
.dev-card code {
  font-size: 10.5px;
  color: var(--color-text-muted);
  word-break: break-all;
  background: var(--color-surface-2);
  padding: .15rem .35rem;
  border-radius: 5px;
}
.dev-origin { opacity: .85; }
.dev-meta { line-height: 1.35; }
.dev-card--media { justify-items: stretch; }
.dev-thumb {
  inline-size: 100%;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-2);
}
.dev-thumb .media, .dev-thumb .media-placeholder { inline-size: 100%; }
.chip--ok   { background: color-mix(in srgb, var(--color-success) 16%, transparent); color: var(--color-success); border-color: color-mix(in srgb, var(--color-success) 40%, transparent); }
.chip--warn { background: var(--color-warning-bg); color: var(--color-warning); border-color: color-mix(in srgb, var(--color-warning) 40%, transparent); }

/* Logotipo del hero SIN contenedor: sólo el recurso y su área de seguridad */
.page-hero__logo--bare {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-block-end: var(--space-5);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.page-hero__logo--bare img {
  /* Ancho DEFINIDO e igual en las cuatro mini landings, tomando como
     referencia el de Pagomedios (198 px). El alto lo determina la proporción
     de cada logotipo, así que ninguno se deforma ni se recorta.
     El ancho debe ser definido —no 'auto'— porque los logotipos SVG declaran
     viewBox pero no width/height y colapsarían a 0 dentro de un flex. */
  inline-size: 12.375rem;
  max-inline-size: 100%;
  block-size: auto;
  max-block-size: 3.5rem;
  flex: none;
  object-fit: contain;
  filter: none;
}

/* --------------------------------------------------------------------------
   Plugins de integración — cuatro columnas
   -------------------------------------------------------------------------- */
.plugin-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1100px) { .plugin-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .plugin-grid { grid-template-columns: 1fr; } }

.plugin-card { gap: var(--space-3); }
.plugin-card h3 { font-size: var(--text-base); }
.plugin-card p  { font-size: var(--text-sm); }

/* Contenedor uniforme: misma proporción en las cuatro tarjetas, imagen
   centrada y contenida, sin recortes, deformaciones ni filtros. */
.plugin-card__media {
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  overflow: hidden;
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  border: 1px solid var(--color-border);
}
.plugin-card__media img {
  inline-size: 82%;
  block-size: 82%;
  object-fit: contain;
  filter: none;
}

.plugin-card__req { margin-block-start: auto; }
.plugin-card__req h4 {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-block-end: .4rem;
}
.plugin-card__req ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .3rem; }
.plugin-card__req li {
  display: flex;
  gap: .4rem;
  align-items: flex-start;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.plugin-card__req .glyph { flex: none; margin-block-start: .15rem; color: var(--brand); }

.plugin-card__foot { margin-block-start: var(--space-3); display: grid; }
.plugin-card__foot .btn[disabled] { opacity: .6; }
.plugin-card__pending {
  margin-block-start: .5rem;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   Aplicaciones móviles — dos columnas
   -------------------------------------------------------------------------- */
.apps-grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}
/* Una sola columna cuando dos ya no se leen cómodamente */
@media (max-width: 980px) { .apps-grid { grid-template-columns: 1fr; } }

.app-card__shot { margin-block-start: var(--space-5); }
.app-card__shot .media { max-block-size: 26rem; inline-size: auto; margin-inline: auto; }
