/* ==========================================================================
   Centennial Media Holdings
   Dirección de arte adaptada de la plantilla Aivora: fondo casi negro azulado,
   verde menta como único acento, titulares en Sporting Grotesque con tracking
   muy negativo, y píldoras por todas partes.
   ========================================================================== */

/* ------------------------------------------------------- 1. Tipografías -- */
/* Sporting Grotesque: Lucas Le Bihan / Velvetyne, SIL OFL. La licencia va
   junto a los ficheros en assets/fonts/. */
@font-face {
  font-family: "Sporting Grotesque";
  src: url("../fonts/sporting-grotesque-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Sporting Grotesque";
  src: url("../fonts/sporting-grotesque-bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "DM Sans";
  src: url("../fonts/dm-sans-latin.woff2") format("woff2");
  font-weight: 100 1000; font-style: normal; font-display: swap;
}

/* ----------------------------------------------------------- 2. Tokens --- */
:root {
  /* Tema claro. Los nombres dicen el papel, no el color: cambiar de tema es
     redefinir esto y nada más. */
  --bg:        #eef2f8;   /* fondo de página */
  --surface:   #ffffff;   /* superficie elevada: tarjetas y paneles */
  --pill:      #e7ecf5;   /* píldoras de navegación */

  /* El menta es color de relleno. Como TEXTO sobre claro no llega a 2:1, así
     que todo lo que sea texto o trazo fino usa --mint-ink. */
  --mint:       #00d986;
  --mint-deep:  #00b06c;
  --mint-ink:   #05593a;
  /* Dos verdes, y no son intercambiables:
     --green      texto pequeño (rótulos, marcas de tiempo). Pasa AA:
                  6.16 sobre blanco, 4.99 sobre el azul, 5.26 sobre el menta.
     --green-head titulares. Es el verde del botón, elegido a propósito por
                  vistosidad. Como TEXTO da 2.83 sobre blanco y 2.29 sobre la
                  banda azul, por debajo del 3.0 que pide un titular grande.
                  No usarlo en nada por debajo de 24px. */
  --green:      #097043;
  --green-head: #01b06c;

  /* Azul marino muy oscuro, no negro. Contrasta igual (13:1 sobre blanco) pero
     tiene color, y eso es lo que impide que la página se lea gris. */
  --head:       #062138;
  --gray:       #3b4b5e;   /* cuerpo */
  --gray-dim:   #5a6a7e;   /* secundario */
  --fine:       #536274;   /* letra pequeña */

  /* La banda oscura. Una por página: es lo que da el salto de contraste. */
  --dark:       #062138;
  --on-dark:    #b9cbdc;
  --on-dark-dim:#8fa5bb;
  --line:       rgba(10, 15, 28, .13);
  --line-soft:  rgba(10, 15, 28, .07);
  --alert:      #c0392b;

  --display: "Sporting Grotesque", "Helvetica Neue", Arial, sans-serif;
  --body:    "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --easing: cubic-bezier(.67, .04, .3, .91);
  --page: 78rem;
  --text: 40rem;
}

/* ------------------------------------------------------------- 3. Base --- */
*, *::before, *::after { box-sizing: border-box; }

/* Sin scroll-behavior: smooth — en páginas largas Chrome abandona el scroll
   animado cuando las imágenes diferidas asientan y el salto no ocurre. */
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.75;
  letter-spacing: -.01em;
  color: var(--gray);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
[hidden] { display: none !important; }   /* tiene que ganar a cualquier display */

a { color: var(--head); text-decoration: none; }

h1, h2, h3, h4 {
  margin: 0 0 .5em;
  font-family: var(--display);
  font-weight: 400;
  color: var(--head);
  /* El tracking muy negativo es la firma de la plantilla. */
  letter-spacing: -.055em;
  line-height: 1.12;
}
h1 { font-size: clamp(2.6rem, 6vw, 4.5rem); }
h2 { font-size: clamp(2rem, 4.4vw, 3.4rem); }
h3 { font-size: 1.35rem; letter-spacing: -.035em; }
h4 { font-size: 1.05rem; letter-spacing: -.03em; }

p { margin: 0 0 1.2em; }

/* Titulares en degradado de verde a marino. Los dos extremos pasan AA por
   separado (6.16:1 y 16.38:1 sobre blanco), así que ningún punto del recorrido
   cae por debajo.

   Va dentro de @supports porque el fallback de `background-clip: text` es
   `color: transparent`, es decir, texto invisible. Sin la comprobación, un
   navegador que no lo soporte se queda sin titulares.

   Los h3 y h4 quedan en marino sólido: miden 20-22px, y por debajo de 24px
   AA exige 4.5:1, que este verde no da. La excepción es el titular de las
   tarjetas apiladas (41.6px) y la cifra del panel, que sí son texto grande. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  h1, h2, .stack__card h3, .metric__n strong {
    background-image: linear-gradient(168deg, var(--green-head) 0%, var(--head) 78%);
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
  }
  /* Los hijos con color propio no deben heredar el transparente. */
  h1 .flow__label, h2 .flow__label, h1 .btn, h2 .btn {
    -webkit-text-fill-color: initial;
  }
  /* Sobre la banda oscura el degradado se invierte. */
  .band--deep h1, .band--deep h2 {
    background-image: linear-gradient(168deg, var(--mint) 0%, #ffffff 58%);
    color: transparent;
  }
}

.wrap { width: 100%; max-width: var(--page); margin: 0 auto; padding: 0 1.5rem; }
.prose { max-width: var(--text); }
.prose h2 { margin-top: 2.5rem; }

.skip { position: absolute; left: -9999px; }
.skip:focus {
  left: 1rem; top: 1rem; z-index: 200;
  background: var(--mint); color: var(--head);
  padding: .7rem 1.2rem; border-radius: 999px; font-weight: 700;
}

::selection { background: var(--mint); color: var(--head); }

/* ------------------------------------------------------- 4. Superficies -- */
/* Cuatro superficies, no una. Con todo al mismo casi-negro la página se lee
   como un bloque continuo y no se distingue dónde acaba una sección y empieza
   otra. Cada variante tiene su papel y se alternan a propósito. */
.section { padding: 6rem 0; }

/* Base: lavado azul desde arriba. */
.band {
  position: relative;
  padding: 6rem 0;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(24, 43, 92, .06) 0%, rgba(24, 43, 92, 0) 62%),
    var(--surface);
  border-top: 1px solid var(--line-soft);
}

/* Elevada: azul claramente más presente. Para lo que tiene que destacar. */
.band--lift {
  background:
    radial-gradient(90% 100% at 70% 0%, rgba(46, 84, 150, .22) 0%, rgba(46, 84, 150, 0) 68%),
    radial-gradient(70% 90% at 10% 100%, rgba(30, 58, 110, .18) 0%, rgba(30, 58, 110, 0) 70%),
    #dfe8f7;
}

/* Teñida de menta. Se usa una sola vez: en cuanto se repite deja de marcar. */
.band--mint {
  background:
    radial-gradient(85% 110% at 20% 0%, rgba(0, 200, 140, .3) 0%, rgba(0, 200, 140, 0) 62%),
    radial-gradient(70% 90% at 90% 90%, rgba(0, 170, 130, .24) 0%, rgba(0, 170, 130, 0) 65%),
    #d6f4e6;
}
/* El tinte aclara el fondo lo justo para que el gris apagado caiga por debajo
   de AA. Sobre esta banda el texto secundario sube un escalón. */
.band--mint .fine { color: var(--gray); }

/* Profunda: por debajo del fondo base. Sirve de respiro entre dos con color. */
.band--deep {
  background:
    radial-gradient(110% 80% at 50% 100%, rgba(0, 217, 134, .14) 0%, rgba(0, 217, 134, 0) 62%),
    radial-gradient(90% 90% at 12% 0%, rgba(46, 96, 170, .34) 0%, rgba(46, 96, 170, 0) 66%),
    var(--dark);
  color: var(--on-dark);
}

/* Inversión dentro de la banda oscura. Todo lo que dentro asume fondo claro
   hay que darlo la vuelta aquí, o desaparece. */
.band--deep h3, .band--deep h4,
.band--deep b, .band--deep strong, .band--deep dd { color: #fff; }
/* Fallback si no hay background-clip: sin esto quedarían en el marino base. */
.band--deep h1, .band--deep h2 { color: #fff; }
.band--deep p, .band--deep li, .band--deep dt { color: var(--on-dark); }
.band--deep .fine, .band--deep .lede--right { color: var(--on-dark-dim); }
.band--deep .eyebrow, .band--deep .flow__label { color: var(--mint); }
.band--deep .steps article, .band--deep .cards article,
.band--deep .aside, .band--deep .row-item {
  background: rgba(255, 255, 255, .05);
  border-color: rgba(255, 255, 255, .14);
}
.band--deep .steps article:hover, .band--deep .cards article:hover,
.band--deep .row-item:hover { background: rgba(255, 255, 255, .09); }
.band--deep .steps .n, .band--deep .cards .n,
.band--deep .rows .row-item__n { color: var(--mint); }
.band--deep .aside .list li::before { color: var(--mint); }
.band--deep .aside .list li { border-color: rgba(255, 255, 255, .12); }
.band--deep .btn {
  color: #fff; background: rgba(255, 255, 255, .08);
  border-color: rgba(255, 255, 255, .24);
}
.band--deep .btn:hover { background: rgba(255, 255, 255, .14); }
.band--deep .btn--solid { color: var(--head); background: var(--mint); border-color: var(--mint); }
.band--deep .btn--solid::after { color: var(--mint); background: var(--head); }
.band--deep a { color: #fff; }
.band--deep .figure img { border-color: rgba(255, 255, 255, .16); }
.band--deep hr, .band--deep .aside h2, .band--deep .aside h3 { color: #fff; }

/* Cierre: la única banda donde el acento ocupa todo el ancho. Foto de fondo,
   baño de menta y filo grueso arriba. Si esto se replicara en otra sección
   dejaría de significar "aquí se acaba y aquí se actúa". */
.band--close {
  position: relative; isolation: isolate; overflow: hidden;
  padding: 7rem 0;
  text-align: center;
  border-top: 2px solid var(--mint);
}
.band--close__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  opacity: .6; filter: saturate(1.1) contrast(1.02);
}
.band--close::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(80% 120% at 50% 0%, rgba(0, 217, 134, .3) 0%, rgba(0, 217, 134, 0) 62%),
    radial-gradient(120% 100% at 50% 110%, rgba(0, 200, 140, .2) 0%, rgba(0, 200, 140, 0) 68%),
    linear-gradient(180deg, rgba(255, 255, 255, .88) 0%, rgba(255, 255, 255, .92) 100%);
}
/* Resplandor menta que late despacio bajo el titular. */
.band--close::after {
  content: ""; position: absolute; z-index: -1;
  top: 50%; left: 50%; translate: -50% -50%;
  width: 46rem; height: 24rem; border-radius: 50%;
  background: radial-gradient(circle, rgba(0, 217, 134, .22) 0%, transparent 68%);
  filter: blur(46px);
  will-change: opacity;
  animation: close-glow 7s ease-in-out infinite;
}
/* Solo opacidad. Animar `scale` sobre un elemento desenfocado obliga a
   rehacer el desenfoque en cada fotograma; la opacidad la resuelve el
   compositor sin volver a rasterizar. */
@keyframes close-glow {
  0%, 100% { opacity: .5; }
  50%      { opacity: 1; }
}
.band--close__inner { position: relative; }
.band--close .eyebrow { justify-content: center; }
.band--close h2 { max-width: 22ch; margin-inline: auto; }
.band--close .lede { margin-inline: auto; margin-bottom: 2.5rem; }
.band--tight { padding: 4.5rem 0; }

/* Filo de luz en el borde superior: marca dónde empieza cada banda. */
.band::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(0, 150, 105, .35) 50%, transparent);
}

/* --------------------------------------------------------- 5. Cabecera --- */
.masthead {
  position: sticky; top: 0; z-index: 90;
  padding: 1rem 0;
  background: rgba(255, 255, 255, .82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.masthead__inner { display: flex; align-items: center; gap: 1.5rem; }

/* Dos filas: el nombre arriba y la coletilla debajo, con el cuadrado abarcando
   las dos. En rejilla y no en flex porque el cuadrado es un ::before y tiene
   que ocupar ambas filas. */
.logo {
  display: grid; grid-template-columns: auto auto;
  align-items: center; column-gap: .55rem; row-gap: 0;
  font-family: var(--display); letter-spacing: -.045em;
  color: var(--head); white-space: nowrap;
}
.logo b { grid-column: 2; font-size: 1.35rem; font-weight: 400; line-height: 1.05; }
.logo__sub {
  grid-column: 2;
  font-size: .78rem; letter-spacing: -.01em; line-height: 1.25;
  color: #000;
}
.logo::before {
  content: ""; width: 1.4rem; height: 1.4rem; flex: none;
  grid-row: 1 / span 2; align-self: center;
  background: var(--mint);
  /* mismo chaflán que el favicon */
  clip-path: polygon(22% 0, 100% 0, 100% 78%, 78% 100%, 0 100%, 0 22%);
}

.masthead nav { margin-left: auto; }
.masthead nav ul {
  display: flex; flex-wrap: wrap; gap: .35rem;
  margin: 0; padding: 0; list-style: none;
}
/* Navegación en píldoras: la firma más reconocible de la plantilla. */
.masthead nav a {
  display: block; padding: .35rem 1.15rem;
  font-size: .9rem; font-weight: 500; color: var(--gray);
  border: 1px solid transparent; border-radius: 999px;
  transition: color .25s var(--easing), background-color .25s var(--easing),
              border-color .25s var(--easing);
}
.masthead nav a:hover { color: var(--head); background: var(--pill); border-color: var(--line); }
.masthead nav a[aria-current] { color: var(--head); background: var(--pill); border-color: var(--line); }

.menu-btn {
  display: none; margin-left: auto;
  padding: .45rem 1rem; font: inherit; font-size: .8rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--head); background: var(--mint);
  border: 0; border-radius: 999px; cursor: pointer;
}

/* ---------------------------------------------------------- 6. Botones --- */
/* Píldora con badge circular a la derecha, tal cual la plantilla. */
.btn {
  display: inline-flex; align-items: center; gap: .85rem;
  padding: .5rem .5rem .5rem 1.6rem;
  font-family: var(--body); font-size: .85rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--head);
  border: 1px solid var(--line); border-radius: 999px;
  transition: background-color .3s var(--easing), color .3s var(--easing),
              border-color .3s var(--easing);
}
.btn::after {
  content: "↗"; display: grid; place-items: center;
  width: 2.35rem; height: 2.35rem; flex: none;
  font-size: 1rem; line-height: 1;
  color: var(--head); background: var(--surface);
  border-radius: 50%;
  transition: transform .3s var(--easing), background-color .3s var(--easing),
              color .3s var(--easing);
}
.btn:hover { background: var(--pill); border-color: rgba(10, 15, 28, .3); }
.btn:hover::after { transform: rotate(45deg); }

.btn--solid { color: var(--head); background: var(--mint); border-color: var(--mint); }
.btn--solid::after { color: var(--mint); background: var(--head); }
.btn--solid:hover { background: var(--mint-deep); border-color: var(--mint-deep); }

/* ------------------------------------------------------ 7. Componentes --- */
/* Punto menta + rótulo: cada sección empieza igual. */
.eyebrow {
  display: inline-flex; align-items: center; gap: .55rem;
  margin: 0 0 1.2rem;
  font-size: .8rem; font-weight: 500; letter-spacing: 0;
  color: var(--gray);
}
.eyebrow::before {
  content: ""; width: .45rem; height: .45rem; border-radius: 50%;
  background: var(--mint); flex: none;
  box-shadow: 0 0 0 4px rgba(0, 176, 108, .3);
}

.lede { max-width: var(--text); font-size: 1.05rem; color: var(--gray); }
.fine { max-width: var(--text); font-size: .85rem; color: var(--gray-dim); }

.hero { padding: 7rem 0 5rem; position: relative; isolation: isolate; }
/* Lienzo de la constelación. No intercepta clics: el hero sigue siendo
   texto y botones. */
.hero__net {
  position: absolute; inset: 0; z-index: -1;
  width: 100%; height: 100%;
  pointer-events: none;
}
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(60% 70% at 78% 18%, rgba(0, 217, 134, .13) 0%, rgba(0, 217, 134, 0) 60%),
    radial-gradient(90% 90% at 15% 0%, rgba(30, 52, 110, .12) 0%, rgba(30, 52, 110, 0) 65%);
}
.hero h1 { max-width: 16ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin: 2rem 0 2.5rem; }

/* Hero centrado. El resto de la página sigue alineada a la izquierda: el
   contraste entre ambos es parte del ritmo. */
.hero--center { text-align: center; }
.hero--center .eyebrow { justify-content: center; }
.hero--center h1 { max-width: 18ch; margin-left: auto; margin-right: auto; }
.hero--center .lede { margin-left: auto; margin-right: auto; }
.hero--center .hero__actions,
.hero--center .badges { justify-content: center; }

.badges { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; }
.badges li {
  padding: .35rem 1rem;
  font-size: .72rem; font-weight: 500; letter-spacing: .06em; text-transform: uppercase;
  color: var(--gray); background: var(--pill);
  border: 1px solid var(--line); border-radius: 999px;
}

/* Tarjetas numeradas. Un solo componente para pasos, capacidades y verticales. */
.steps, .cards { display: grid; gap: 1rem; margin: 2.5rem 0; }
.steps { grid-template-columns: repeat(2, 1fr); }
.cards, .cards--6 { grid-template-columns: repeat(3, 1fr); }

.steps article, .cards article {
  position: relative; padding: 2rem 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 1.25rem;
  transition: border-color .35s var(--easing), transform .35s var(--easing);
}
.steps article:hover, .cards article:hover {
  border-color: rgba(0, 176, 108, .55); transform: translateY(-3px);
}
.steps .n, .cards .n {
  display: block; margin-bottom: 1.5rem;
  font-family: var(--display); font-size: 1.6rem; letter-spacing: -.04em;
  color: var(--mint-ink);
}
.steps h3, .cards h3 { margin-bottom: .5rem; }
.steps p, .cards p { margin: 0; font-size: .95rem; line-height: 1.65; }

/* Pipeline: cinco estaciones unidas por una línea. */
.pipeline {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin: 2.5rem 0; padding: 0; list-style: none;
}
.pipeline li {
  position: relative; flex: 1 1 9rem; padding: 1.1rem 1.25rem;
  font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--head); background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; text-align: center;
}
.pipeline li::before {
  content: ""; position: absolute; left: .9rem; top: 50%;
  width: .4rem; height: .4rem; margin-top: -.2rem;
  background: var(--mint); border-radius: 50%;
}

.checks {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem 2rem;
  margin: 2rem 0; padding: 0; list-style: none;
}
.checks li { position: relative; padding-left: 1.6rem; font-size: .95rem; }
.checks li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .75rem; height: .75rem;
  border-left: 1.5px solid var(--mint); border-bottom: 1.5px solid var(--mint);
  transform: rotate(-45deg) translateY(-.1em);
}

.ctas { display: flex; flex-wrap: wrap; gap: 1.75rem; margin: 2rem 0 0; }
.ctas a {
  font-size: .9rem; font-weight: 500; color: var(--mint-ink);
  border-bottom: 1px solid rgba(0, 176, 108, .45); padding-bottom: .15rem;
  transition: border-color .25s var(--easing);
}
.ctas a:hover { border-color: var(--mint-ink); }

.page-head { padding: 7rem 0 4rem; }
.page-head h1 { max-width: 20ch; }

.contact dt {
  margin-top: 1.5rem; font-size: .75rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--mint-ink);
}
.contact dd { margin: .25rem 0 0; font-size: 1.05rem; color: var(--head); }
.contact address { font-style: normal; }
.doc-meta { font-size: .85rem; color: var(--gray-dim); }

/* Cinta en movimiento, del original. Se detiene con reduced-motion. */
/* Iba del mismo tono que la página y se perdía. Una franja oscura la separa
   sin añadir otro color: repite el marino del panel de operaciones. */
.ticker {
  overflow: hidden; padding: 1.35rem 0;
  background: linear-gradient(100deg, #054a2f 0%, #0a7a4c 48%, #06603c 100%);
  border-top: 1px solid rgba(255, 255, 255, .1);
  border-bottom: 1px solid rgba(255, 255, 255, .1);
}
.ticker__track {
  display: flex; gap: 3rem; width: max-content;
  animation: slide 38s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.ticker span {
  display: inline-flex; align-items: center; gap: 3rem;
  font-family: var(--display); font-size: 1.2rem; letter-spacing: -.035em;
  color: #fff; white-space: nowrap;
}
.ticker span::after { content: "✦"; color: #4fe6ab; font-size: .85rem; }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ------------------------------------------------------------ 8. Pie ----- */
.colophon {
  padding: 5rem 0 2.5rem;
  border-top: 1px solid var(--line-soft);
  background: radial-gradient(90% 120% at 50% 100%, rgba(24, 43, 92, .08) 0%, rgba(24, 43, 92, 0) 70%), var(--pill);
}

/* Marca ancha primero, luego tres columnas de enlaces. Se colapsa a dos y a
   una; la de marca ocupa el ancho entero mientras haya dos columnas. */
.colophon__grid {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1.25fr 1.15fr;
  gap: 2.5rem 3rem;
}
.colophon__brand .logo { margin-bottom: 1.25rem; display: inline-grid; }
.colophon__tagline {
  font-size: .9rem; line-height: 1.7; color: var(--gray);
  max-width: 34ch; margin-bottom: 1.5rem;
}
.colophon__contact { list-style: none; padding: 0; display: grid; gap: .4rem; }
.colophon__contact li { font-size: .85rem; color: var(--fine); }
.colophon__contact a { color: var(--gray); }
.colophon__contact a:hover { color: var(--mint-ink); }

.colophon__col h2 {
  font-family: var(--body);
  font-size: .95rem; font-weight: 700; color: var(--head);
  margin-bottom: 1.15rem;
}
.colophon__col ul { list-style: none; padding: 0; display: grid; gap: .65rem; }
.colophon__col a {
  font-size: .875rem; color: var(--gray);
  transition: color .2s var(--easing);
}
.colophon__col a:hover,
.colophon__col a:focus-visible { color: var(--mint-ink); }

.colophon__disclaimer {
  margin-top: 3rem; padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  font-size: .78rem; line-height: 1.7; color: var(--fine);
  max-width: 75ch;
}

.colophon__base {
  display: flex; flex-wrap: wrap; gap: .75rem 2rem;
  align-items: baseline; justify-content: space-between;
  margin-top: 1.5rem;
}
.colophon__legal { font-size: .78rem; line-height: 1.7; color: var(--fine); }
.colophon__fine { font-size: .78rem; }
.colophon__fine a { color: var(--fine); white-space: nowrap; }
.colophon__fine a:hover { color: var(--mint-ink); }

@media (max-width: 62rem) {
  .colophon__grid { grid-template-columns: 1fr 1fr; }
  .colophon__brand { grid-column: 1 / -1; }}
@media (max-width: 34rem) {
  .colophon__grid { grid-template-columns: 1fr; }}

/* ------------------------------------------- 8c. Paneles apilados -------- */
/* Adaptado del bloque de proyectos de Aivora: cada panel es sticky bajo la
   cabecera y el siguiente sube por encima. El apilado lo hace el scroll, no
   un temporizador, así que no hay nada que pausar ni que anunciar. */
/* UN solo elemento pegado con los tres paneles dentro. Con tres pegados
   hermanos, cada uno se suelta cuando el fondo del contenedor alcanza su
   propia caja —y ocupan sitios distintos del flujo—, así que salían
   escalonados: el tercero se quedaba solo al final. Con uno, se suelta una
   vez y las tres salen a la vez.

   El recorrido lo da la altura de .stack; el pegado, .stack__pin. */
.stack { position: relative; margin-top: 3rem; height: 260vh; }

/* Carril fuera del flujo. Con el paginador flotado, los paneles —que crean
   contexto de formato— se estrechaban para no solaparlo y el primero medía
   26px menos que los otros. */
.stack__rail {
  position: absolute; top: 0; right: -.5rem; bottom: 0;
  width: 2.1rem; pointer-events: none; z-index: 5;
}
.stack__pager {
  position: sticky; top: 45vh;
  margin: 0; padding: 0;
  list-style: none; display: grid; gap: .5rem;
}
.stack__pager li {
  display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem; border-radius: 50%;
  font-size: .8rem; font-variant-numeric: tabular-nums;
  color: var(--gray-dim);
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .94);
  transition: color .35s var(--easing), border-color .35s var(--easing);
}
.stack__pager li.is-at { color: var(--mint-ink); border-color: var(--mint-ink); }

.stack__pin {
  position: sticky; top: 5.5rem;
  height: 34rem;                 /* alto de la tarjeta más alta */
  /* Recorta lo que hay fuera del marco. Sin esto, la tarjeta que viene asoma
     por debajo mientras la anterior sigue colocada, y se ven dos a la vez.
     Con el recorte aparece solo al entrar en el marco y se posa encima. */
  overflow: hidden;
  border-radius: 1.25rem;
}

.stack__item {
  position: absolute; left: 0; right: 0; top: 0;
  min-height: 34rem;
  display: grid; align-items: start;
  padding: 3rem;
  border-radius: 1.25rem;
  overflow: hidden;
  isolation: isolate;
  /* Cada panel entra desde abajo y descansa un escalón más abajo que el
     anterior, para que se vea el canto del de detrás. */
  transform: translateY(var(--reposo, 0px));
}
.stack__item:nth-of-type(1) { --reposo: 0px;   z-index: 1; }
.stack__item:nth-of-type(2) { --reposo: 1.4rem; z-index: 2; }
.stack__item:nth-of-type(3) { --reposo: 2.8rem; z-index: 3; }

/* La entrada la mueve el scroll, en el compositor: sin JS por fotograma y por
   tanto sin los tirones que da calcular transforms a mano. */
@supports (animation-timeline: view()) {
  .stack { view-timeline-name: --baraja; view-timeline-axis: block; }
  .stack__item {
    /* Desacelera al llegar en vez de frenar en seco. */
    animation: baraja-entra cubic-bezier(.22, .61, .36, 1) both;
    animation-timeline: --baraja;
  }
  .stack__item:nth-of-type(1) { animation: none; }
  /* Tramos largos y casi pegados al final: la tarjeta tiene que recorrer algo
     parecido a lo que recorre el dedo o parece que salta. Con 24% del
     recorrido viajaba 640px mientras se hacían 173px de scroll —casi 4x— y
     luego sobraba un 44% sin que pasara nada, que era el arrastre al salir. */
  .stack__item:nth-of-type(2) { animation-range: contain 2% contain 45%; }
  .stack__item:nth-of-type(3) { animation-range: contain 46% contain 89%; }
}
/* El viaje va en % de la PROPIA tarjeta, no en vh: así siempre arranca justo
   por debajo del borde del marco y queda recortada, sea cual sea la ventana.
   Con `75vh` en un portátil de 650px el viaje (488px) se quedaba corto frente
   al marco (544px) y la tarjeta asomaba por abajo antes de tiempo. */
@keyframes baraja-entra {
  from { transform: translateY(104%); }
  to   { transform: translateY(var(--reposo)); }
}

.stack__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
/* Velo para que el texto no dependa de lo clara que sea la foto. */
.stack__item::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, rgba(255, 255, 255, .9) 0%, rgba(255, 255, 255, .45) 70%);
}

.stack__card {
  max-width: 40rem; padding: 2.5rem;
  /* Eran blur(28px) sobre 285k px², tres a la vez y solapándose al hacer
     scroll. Con la opacidad más alta el resultado es casi el mismo y no hay
     que releer el fondo. */
  background: rgba(255, 255, 255, .93);
  border: 1px solid var(--line);
  border-radius: 1rem;
}
.stack__n {
  margin: 0 0 .75rem;
  font-family: var(--display); font-size: .9rem;
  letter-spacing: .1em; color: var(--mint-ink);
}
.stack__card h3 { font-size: clamp(1.8rem, 3.4vw, 2.6rem); margin-bottom: .6rem; }
.stack__d { margin-bottom: 1.75rem; color: var(--gray); }

.stack__meta {
  display: flex; flex-wrap: wrap; gap: 1rem 3rem;
  margin: 0 0 1.75rem; padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.stack__meta dt {
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gray-dim); margin-bottom: .2rem;
}
.stack__meta dd { margin: 0; font-size: .95rem; color: var(--head); }
.stack__cta { margin: 0; }

/* En móvil el apilado sigue, pero más compacto. La fila de datos se oculta:
   se apila en cuatro líneas y suma ~165px, justo lo que impide que la tarjeta
   quepa entera en un teléfono. Sin ella pasa de 645px a 453px. */
@media (max-width: 52rem) {
  .stack__pager { display: none; }        /* se solaparía con la tarjeta */
  .stack { height: 230vh; }
  .stack__pin { top: 4.5rem; height: 30rem; }
  .stack__item { min-height: 30rem; padding: 1.5rem; }
  .stack__card { max-width: none; padding: 1.75rem; }
  .stack__meta { display: none; }
  .stack__item:nth-of-type(2) { --reposo: .9rem; }
  .stack__item:nth-of-type(3) { --reposo: 1.8rem; }
}

/* Por debajo de 600px de alto, una tarjeta pegada más alta que la ventana
   atrapa su botón fuera de alcance. Ahí se deshace el apilado y quedan en
   lista. Lo mismo con movimiento reducido. */
@media (max-width: 52rem) and (max-height: 599px) {
  .stack { height: auto; }
  .stack__pin { position: static; height: auto; }
  .stack__item {
    position: relative; transform: none; animation: none;
    min-height: 0; margin-bottom: 1rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  .stack { height: auto; }
  .stack__pin { position: static; height: auto; }
  .stack__item {
    position: relative; transform: none; animation: none;
    min-height: 0; margin-bottom: 1rem;
  }
  .stack__pager { display: none; }
}

/* --------------------------------------------- 7a. Campaign command ------ */
.command {
  margin-top: 3rem; padding: 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line-soft); border-radius: 1.5rem;
  /* Dos capas: una corta que asienta el borde y otra larga y difusa que da
     la elevación. Con una sola sombra grande el panel parece despegado. */
  box-shadow:
    0 1px 2px rgba(6, 33, 56, .06),
    0 26px 60px -22px rgba(6, 33, 56, .3);
}
.command__top {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding-bottom: 1.5rem; border-bottom: 1px solid var(--line);
}
.command__top small {
  display: block; font-size: .7rem; font-weight: 500; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gray-dim);
}
.command__top b {
  font-family: var(--display); font-size: 1.35rem; font-weight: 400;
  letter-spacing: -.04em; color: var(--head);
}
/* Píldora de estado con el punto latiendo. */
.live {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .35rem 1rem; white-space: nowrap;
  font-size: .78rem; font-weight: 700; letter-spacing: .06em;
  color: var(--mint-ink); background: rgba(0, 217, 134, .12);
  border: 1px solid rgba(0, 176, 108, .45); border-radius: 999px;
}
.live::before {
  content: ""; width: .45rem; height: .45rem; border-radius: 50%;
  background: var(--mint-deep); animation: live-pulse 2.2s ease-in-out infinite;
}
@keyframes live-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 176, 108, .5); }
  70%      { box-shadow: 0 0 0 .55rem rgba(0, 176, 108, 0); }
}

.command__hero {
  display: grid; grid-template-columns: 1fr auto; gap: 2.5rem;
  align-items: center; padding: 2.5rem 0;
}
@media (max-width: 52rem) {
  .command__hero { grid-template-columns: 1fr; }}
.metric small {
  display: block; margin-bottom: .5rem;
  font-size: .72rem; font-weight: 500; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gray-dim);
}
.metric__n { display: flex; align-items: baseline; gap: .1rem; margin: 0 0 .6rem; }
.metric__n strong {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(3.5rem, 8vw, 5.5rem); line-height: 1;
  letter-spacing: -.06em; color: var(--head);
}
.metric__n i {
  font-style: normal; font-family: var(--display);
  font-size: 2rem; letter-spacing: -.04em; color: var(--mint-ink);
}
.metric > span { font-size: .9rem; color: var(--gray); }

/* --- cinta de registro (sustituye al radar) --- */
.ledger {
  width: 22rem; flex: none;
  border: 1px solid rgba(255, 255, 255, .14); border-radius: 1rem;
  background: linear-gradient(158deg, #075138 0%, #062138 68%);
  overflow: hidden;
}
.ledger__head {
  display: flex; justify-content: space-between;
  padding: .7rem 1rem; border-bottom: 1px solid rgba(255, 255, 255, .16);
  font-size: .68rem; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: #4fe6ab;
}
/* La ventana recorta la cinta y la difumina arriba y abajo, para que las
   filas entren y salgan en vez de cortarse en seco. */
.ledger__view {
  height: 13rem; overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 86%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 86%, transparent 100%);
}
.ledger__tape { animation: ledger-roll 26s linear infinite; }
@keyframes ledger-roll { to { transform: translateY(-50%); } }

.ledger__row {
  display: grid; grid-template-columns: 4.6rem 1fr auto;
  align-items: center; gap: .6rem;
  padding: .55rem 1rem; font-size: .78rem;
}
.ledger__row b {
  font-weight: 500; font-variant-numeric: tabular-nums;
  color: #4fe6ab;
}
.ledger__row span { color: #fff; }
.ledger__dot {
  width: .4rem; height: .4rem; border-radius: 50%; flex: none;
}
.ledger__dot--ok   { background: #4fe6ab; box-shadow: 0 0 8px rgba(79, 230, 171, .6); }
.ledger__dot--wait { background: #7aa7ff; }
.ledger__dot--hold { background: rgba(255, 255, 255, .42); }

@media (prefers-reduced-motion: reduce) {
  .ledger__tape { animation: none; }}
@media (max-width: 52rem) {
  .ledger { width: 100%; }}

/* Verde plano se leía como un bloque de color. El degradado hasta el marino
   le da profundidad y permite texto blanco: el extremo más claro (#075138) da
   9.36:1 con blanco, así que ningún punto del recorrido se queda corto.
   Sin hueco entre tarjetas: el degradado tiene que ser continuo, y la
   separación la hace una línea clara. */
.command__grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0;
  background: linear-gradient(118deg, #075138 0%, #06304a 52%, #062138 100%);
  border-radius: 1rem; overflow: hidden;
}
/* Relleno verde con texto oscuro encima, el mismo par que el botón.
   Sobre este verde el marino da 8.79:1 y el marino al 80% 5.01:1; por debajo
   de ese 80% se cae de AA, así que no bajar más el texto secundario. */
.cmd-card {
  padding: 1.35rem 1.25rem;
  background: transparent;
  border-left: 1px solid rgba(255, 255, 255, .14);
  transition: background-color .3s var(--easing);
}
.cmd-card:first-child { border-left: 0; }
.cmd-card:hover { background: rgba(255, 255, 255, .07); }
.cmd-card small {
  display: block; margin-bottom: .35rem;
  font-size: .68rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: #4fe6ab;
}
.cmd-card b {
  display: block; margin-bottom: .3rem;
  font-family: var(--display); font-size: 1.15rem; font-weight: 400;
  letter-spacing: -.04em; color: #fff;
}
.cmd-card span { font-size: .8rem; color: #bfc9d2; }

/* ------------------------------------------ 7a1. Fondos de subpágina ----- */
.page-head { position: relative; isolation: isolate; overflow: hidden; }
.page-head__bg {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  opacity: .55;
  filter: saturate(1.05) contrast(1.02);
}
/* Velo suficiente para leer el titular, no tanto como para borrar la imagen.
   El degradado vertical la funde con la sección siguiente. */
.page-head::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, .84) 74%, var(--bg) 100%),
    linear-gradient(90deg, rgba(255, 255, 255, .86) 0%, rgba(255, 255, 255, .3) 70%);
}

/* ------------------------------------------------- 7a2. Fotografía ------- *//* ------------------------------------------------- 7a2. Fotografía ------- */
/* Con fondo claro las fotos ya no hay que apagarlas: iban oscurecidas para no
   abrir un agujero blanco en una página casi negra. */
.figure { position: relative; margin: 2.5rem 0; isolation: isolate; }
.figure img {
  width: 100%; border-radius: 1.25rem; border: 1px solid var(--line);
  filter: contrast(1.02) saturate(.95);
}
.figure::after {
  content: ""; position: absolute; inset: 0; border-radius: 1.25rem;
  /* Solo un borde interior para asentar la foto sobre el blanco. */
  box-shadow: inset 0 0 0 1px rgba(10, 15, 28, .08);
  pointer-events: none;
}
.figure--tall img { max-height: 30rem; object-fit: cover; }

/* Banda a sangre: foto de fondo, titular encima. Rompe el muro de texto sin
   añadir otra sección de tarjetas. */
.media-band {
  position: relative; isolation: isolate;
  display: flex; align-items: center;
  min-height: 30rem; padding: 6rem 0;
  overflow: hidden;
  border-block: 1px solid var(--line-soft);
}
.media-band__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  /* La imagen es casi negra de origen; sobre claro se aclara mucho más y se
     apoya en el velo de abajo para que el titular oscuro se lea. */
  filter: brightness(2.5) saturate(.9);
}
.media-band::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(255, 255, 255, .92) 0%, rgba(255, 255, 255, .68) 42%, rgba(255, 255, 255, .25) 100%);
}
.media-band__inner { position: relative; }
.media-band .flow { max-width: 62%; }

/* ---------------------------------------------- 7b. Titular fluido ------- */
/* El recurso característico de Aivora: la etiqueta, una píldora gráfica y a
   veces el botón van dentro del titular, en línea con las palabras. Es lo que
   evita que todas las secciones parezcan la misma. */
.flow {
  /* Reparte las líneas en vez de llenar la primera hasta el borde. Sin esto,
     una palabra corta detrás del pill se queda huérfana al final de la línea,
     que es lo que hacía que estos titulares se leyeran torcidos. */
  text-wrap: balance;
  max-width: 22ch; margin: 0 0 1.5rem;
  font-size: clamp(2rem, 4.6vw, 3.6rem); line-height: 1.18;
}
.flow { max-width: none; }
.flow__label {
  display: inline-flex; align-items: center; gap: .5rem;
  margin-right: .9rem; vertical-align: middle;
  font-family: var(--body); font-size: .8rem; font-weight: 500;
  letter-spacing: 0; color: var(--gray); white-space: nowrap;
}
.flow__label::before {
  content: ""; width: .45rem; height: .45rem; border-radius: 50%;
  background: var(--mint); box-shadow: 0 0 0 4px rgba(0, 176, 108, .3);
}
.inline-btn {
  vertical-align: middle; margin-left: .5rem;
  font-size: .78rem; padding: .35rem .35rem .35rem 1.2rem;
}
.inline-btn::after { width: 1.9rem; height: 1.9rem; font-size: .85rem; }
/* El párrafo tras un titular fluido va desplazado a la derecha: rompe la
   alineación única a la izquierda que hacía todo tan plano. */
.lede--right { margin-left: auto; margin-right: 0; text-align: left; }

/* ---------------------------------------------------- 7c. Órbita --------- */
.tech-split {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center;
}
.tech-split__copy .flow { margin-bottom: 1.5rem; }
.tech-split__copy .lede { margin-bottom: 2rem; }

.orbit {
  position: relative; aspect-ratio: 1; width: 100%; max-width: 34rem;
  margin-inline: auto; isolation: isolate;
}

/* Anillos punteados girando en sentidos opuestos. */
.orbit__ring {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  border: 1px dashed rgba(30, 60, 120, .22); border-radius: 50%;
}
.orbit__ring--out { width: 88%; height: 88%; animation: orbit-cw 64s linear infinite; }
.orbit__ring--in  { width: 56%; height: 56%; animation: orbit-ccw 44s linear infinite; }
@keyframes orbit-cw  { to { rotate: 360deg; } }
@keyframes orbit-ccw { to { rotate: -360deg; } }

/* Punto viajero sobre el anillo exterior. */
.orbit__trace {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  width: 88%; height: 88%;
  animation: orbit-cw 18s linear infinite;
}
.orbit__trace i {
  position: absolute; top: -.35rem; left: 50%; margin-left: -.35rem;
  width: .7rem; height: .7rem; border-radius: 50%;
  background: var(--mint); box-shadow: 0 0 14px rgba(0, 176, 108, .55);
}

/* Hub central, con halo que respira. */
.orbit__hub {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  display: grid; place-content: center; text-align: center;
  width: 38%; height: 38%; border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, rgba(0, 217, 134, .28) 0%, var(--surface) 68%);
  border: 1px solid rgba(0, 176, 108, .5);
}
/* El halo va en un anillo aparte que escala y se desvanece. Animar box-shadow
   repinta el elemento en cada fotograma; escala y opacidad las resuelve el
   compositor sin tocar el píxel. */
.orbit__hub::after {
  content: ""; position: absolute; inset: -1px;
  border-radius: 50%; border: 1px solid rgba(0, 176, 108, .45);
  animation: hub-breathe 5.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes hub-breathe {
  0%, 100% { opacity: .55; scale: 1; }
  50%      { opacity: 0;   scale: 1.18; }
}
.orbit__hub strong {
  display: block; font-family: var(--display); font-weight: 400;
  font-size: 1.15rem; letter-spacing: -.04em; color: var(--head);
}
.orbit__hub span { font-size: .78rem; color: var(--mint-ink); }

/* Satélites. No giran: hay que poder leerlos. */
.orbit__node {
  position: absolute; translate: -50% -50%;
  padding: .7rem 1.1rem; text-align: center; white-space: nowrap;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: .85rem;
  /* Sin backdrop-filter: iba con animación encima, y rehacer el desenfoque
     cada fotograma por 6px sobre un fondo casi liso no compensa. */
  animation: node-float 7s ease-in-out infinite;
  transition: border-color .3s var(--easing), transform .3s var(--easing);
}
.orbit__node:hover { border-color: rgba(0, 176, 108, .6); }
.orbit__node strong {
  display: block; font-size: .92rem; font-weight: 700; color: var(--head);
}
.orbit__node span { font-size: .78rem; color: var(--gray); }
@keyframes node-float {
  0%, 100% { translate: -50% -50%; }
  50%      { translate: -50% calc(-50% - .45rem); }
}

/* Seis posiciones alrededor del hub, como en el original. */
.orbit__node--n1 { top: 14%; left: 26%; animation-delay: -0.0s; }
.orbit__node--n2 { top: 12%; left: 78%; animation-delay: -1.2s; }
.orbit__node--n3 { top: 46%; left: 13%; animation-delay: -2.4s; }
.orbit__node--n4 { top: 52%; left: 87%; animation-delay: -3.6s; }
.orbit__node--n5 { top: 82%; left: 28%; animation-delay: -4.8s; }
.orbit__node--n6 { top: 86%; left: 72%; animation-delay: -6.0s; }

/* ------------------------------------------- 7d. Paneles que se abren ---- */
/* Columnas con el rótulo en vertical, como el acordeón de servicios del
   original. Se abren al pasar por encima o al enfocar con teclado. */
.panels { display: flex; gap: .5rem; margin: 3rem 0 1.5rem; min-height: 26rem; }
.panel-v {
  position: relative; flex: 1 1 0; min-width: 0;
  padding: 1.75rem 1.25rem;
  /* Cerrada: un lavado verde muy tenue desde abajo, para que la columna no sea
     un rectángulo blanco más. */
  background:
    linear-gradient(180deg, rgba(0, 217, 134, 0) 45%, rgba(0, 217, 134, .1) 100%),
    var(--surface);
  border: 1px solid var(--line); border-radius: 1.25rem;
  overflow: hidden; cursor: default;
  isolation: isolate;
  transition: flex-grow .55s var(--easing), border-color .45s var(--easing);
}
/* Abierta: el mismo degradado verde-marino del panel de operaciones, con el
   texto en claro. Es lo que convierte el acordeón en algo que se ve, no en
   seis rectángulos con un tinte. El extremo más claro (#075138) da 9.36:1 con
   blanco, así que ningún punto del recorrido se queda corto. */
.panel-v::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(155deg, #075138 0%, #06304a 55%, #062138 100%);
  opacity: 0;
  transition: opacity .45s var(--easing);
}
.panel-v:hover, .panel-v:focus-visible {
  flex-grow: 4; border-color: transparent;
  outline: none;
}
.panel-v:hover::before, .panel-v:focus-visible::before { opacity: 1; }
.panel-v:hover .panel-v__n, .panel-v:focus-visible .panel-v__n { color: #4fe6ab; }
.panel-v:hover .panel-v__t, .panel-v:focus-visible .panel-v__t { color: #fff; }
.panel-v:hover .panel-v__d, .panel-v:focus-visible .panel-v__d { color: #cfd9e2; }
.panel-v__n {
  display: block; font-family: var(--display); font-size: 1.1rem;
  letter-spacing: -.04em; color: var(--mint-ink);
  transition: color .45s var(--easing);
}
/* Título y descripción van juntos en un bloque anclado abajo. Antes cada uno
   tenía su propio `bottom` fijo: la descripción crecía hacia arriba según su
   largo y se comía la separación con el título, así que el hueco cambiaba de
   una columna a otra. Agrupados, la separación es un margen y es constante. */
.panel-v__body {
  position: absolute; left: 1.4rem; right: 1.4rem; bottom: 1.4rem;
}
/* El rótulo gira 90° mientras está cerrado y vuelve a la horizontal al abrir. */
.panel-v__t {
  margin: 0; font-size: 1.3rem; white-space: nowrap;
  transform-origin: left bottom; transform: rotate(-90deg);
  transition: transform .55s var(--easing), color .45s var(--easing);
}
.panel-v:hover .panel-v__t, .panel-v:focus-visible .panel-v__t { transform: rotate(0deg); }
/* Cerrada, la descripción sale del flujo para que el bloque mida solo el
   rótulo; si no, empujaría el rótulo girado hacia arriba. */
.panel-v__d {
  position: absolute; left: 0; right: 0; top: 100%;
  margin: .8rem 0 0; font-size: .92rem; line-height: 1.6;
  opacity: 0;
  transition: opacity .4s var(--easing) .12s;
}
.panel-v:hover .panel-v__d, .panel-v:focus-visible .panel-v__d {
  position: static; opacity: 1;
}

/* ------------------------------------------------- 7e. Línea de tiempo --- */
.tl {
  position: relative; display: flex; flex-wrap: wrap; gap: 0;
  margin: 3rem 0 1.5rem; padding: 0; list-style: none;
}
.tl::before {
  content: ""; position: absolute; left: 0; right: 0; top: 1.15rem; height: 1px;
  background: linear-gradient(90deg, var(--mint), rgba(0, 176, 108, .25));
}
.tl li { position: relative; flex: 1 1 0; min-width: 8rem; padding-top: 3rem; }
.tl__n {
  position: absolute; top: 0; left: 0;
  display: grid; place-items: center; width: 2.3rem; height: 2.3rem;
  font-family: var(--display); font-size: .85rem; letter-spacing: -.03em;
  color: var(--head); background: var(--mint); border-radius: 50%;
}
.tl__t {
  display: block; font-size: .8rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--head);
}

/* ----------------------------------------------- 7f. Filas numeradas ----- */
.rows { margin: 3rem 0 0; border-top: 1px solid var(--line); }
.row-item {
  display: grid; grid-template-columns: 6rem 18rem 1fr; gap: 2rem; align-items: baseline;
  padding: 2rem 0; border-bottom: 1px solid var(--line);
  transition: background-color .3s var(--easing);
}
.row-item:hover { background: var(--bg); }
.row-item__n { font-family: var(--display); font-size: 2rem; letter-spacing: -.05em; color: var(--mint-ink); }
.row-item h3 { margin: 0; font-size: 1.4rem; }
.row-item p { margin: 0; font-size: .95rem; }
/* La tarjeta tiene dos márgenes automáticos (bajo el icono y sobre el enlace)
   y se reparten el hueco sobrante. Con párrafos de distinto largo los titulares
   dejan de alinearse, así que el párrafo reserva cuatro líneas. */

/* ------------------------------------------------ 8b. Dos columnas ------- */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) 22rem; gap: 3.5rem; align-items: start; }
/* Un ítem de rejilla tiene min-width:auto, así que se niega a bajar de su
   ancho mínimo de contenido y desborda la página en móvil estrecho. */
.grid-2 > * { min-width: 0; }
.col-main > div + div { margin-top: 3rem; }
.col-main h2 { font-size: clamp(1.7rem, 3vw, 2.3rem); }

.aside {
  position: sticky; top: 6rem;
  padding: 2rem 1.75rem;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 1.25rem;
}
.aside h2 { font-size: 1.35rem; letter-spacing: -.035em; }
.aside h3 {
  margin-top: 1.75rem; font-family: var(--body); font-size: .75rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--mint-ink);
}
.aside p { font-size: .92rem; line-height: 1.65; }
.aside__cta { margin-top: 1.75rem; margin-bottom: 0; }
.aside__cta .btn { width: 100%; justify-content: space-between; }

.list { margin: 0; padding: 0; list-style: none; }
.list li {
  position: relative; padding: .55rem 0 .55rem 1.35rem; font-size: .92rem;
  border-bottom: 1px solid var(--line-soft);
}
.list li:last-child { border-bottom: 0; }
.list li::before {
  content: ""; position: absolute; left: 0; top: 1.15em;
  width: .4rem; height: .4rem; border-radius: 50%; background: var(--mint);
}

/* ------------------------------------------------------- 8c. Panel ------- */
/* El "campaign command" del original: una rejilla de estados, no un gráfico. */
/* Fondo blanco: el panel deja de flotar sobre el gris y se sostiene con la
   sombra, no con el contraste de fondo. Llevaba padding-top: 0 de cuando
   continuaba el hero sin costura; siendo ya una banda propia, necesita aire. */
.panel-section { background: var(--surface); }
.panel {
  padding: 1.75rem;
  background: linear-gradient(180deg, rgba(0, 217, 134, .09) 0%, rgba(255, 255, 255, 0) 100%);
  border: 1px solid var(--line); border-radius: 1.5rem;
}
.panel__title {
  margin: 0 0 1.5rem; font-size: .72rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--mint-ink);
}
.panel__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); }
.stat { padding: 1.25rem; background: var(--bg); }
.stat__k {
  display: block; margin-bottom: .4rem; font-size: .7rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gray-dim);
}
.stat__v { display: block; font-family: var(--display); font-size: 1.3rem; letter-spacing: -.04em; color: var(--head); }

/* ---------------------------------------------------- 8d. Tecnología ----- */
.tech { display: flex; flex-wrap: wrap; gap: .6rem; margin: 2.5rem 0 0; padding: 0; list-style: none; }
.tech li {
  padding: 1rem 1.4rem; font-size: .85rem; color: var(--gray);
  background: var(--surface); border: 1px solid var(--line); border-radius: 1rem;
}
.tech span { display: block; font-family: var(--display); font-size: 1.05rem; letter-spacing: -.035em; color: var(--head); }

/* ---------------------------------------------------- 8e. Formulario ----- */
.form .field { margin-bottom: 1.25rem; }
.form label {
  display: block; margin-bottom: .45rem; font-size: .75rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gray);
}
.req { color: var(--mint-ink); }

/* Casilla de consentimiento. La etiqueta de un campo normal va en versalitas
   con tracking; una frase de consentimiento así es ilegible y además tiene que
   leerse como lo que es: el texto exacto que la persona acepta. Por eso esta
   etiqueta anula `.form label` entera en vez de heredarla. */
.field--check { margin-top: .4rem; }
.form .check {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: .7rem; align-items: start;
  margin: 0; padding: .95rem 1.05rem;
  border: 1px solid var(--line); border-radius: .85rem;
  background: var(--surface);
  font-size: .86rem; font-weight: 400; line-height: 1.6;
  letter-spacing: normal; text-transform: none; color: var(--body);
  cursor: pointer;
}
.form .check input[type="checkbox"] {
  width: 1.05rem; height: 1.05rem; margin: .25rem 0 0; padding: 0;
  accent-color: var(--green); cursor: pointer;
}
.form .check b, .form .check strong { color: var(--head); }
.form .check:has(input:focus-visible) { outline: 2px solid var(--green); outline-offset: 2px; }
.form input, .form select, .form textarea {
  width: 100%; padding: .85rem 1rem;
  font: inherit; font-size: .95rem; color: var(--head);
  background: var(--surface); border: 1px solid var(--line); border-radius: .75rem;
  transition: border-color .25s var(--easing), background-color .25s var(--easing);
}
.form textarea { resize: vertical; }
.form input:focus, .form select:focus, .form textarea:focus {
  outline: none; border-color: var(--mint-ink); background: rgba(0, 217, 134, .08);
}
/* Fuera de pantalla, no display:none: un bot que lea el CSS descarta lo
   oculto, y un lector de pantalla no llega aquí porque el bloque es
   aria-hidden y el campo no es enfocable. */
.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form .actions { margin: 1.75rem 0 1rem; }
.form__error {
  margin: 0; padding: .85rem 1rem;
  font-size: .9rem; color: var(--alert);
  background: rgba(192, 57, 43, .07);
  border: 1px solid rgba(192, 57, 43, .28); border-radius: .75rem;
}
.form__done {
  padding: 2.25rem;
  background: var(--surface);
  border: 1px solid var(--line); border-left: 3px solid var(--mint);
  border-radius: 1rem;
}
.form__done h2 { font-size: clamp(1.6rem, 3vw, 2.1rem); margin-bottom: .75rem; }
.form__done p { margin-bottom: 1rem; }
.form__done p:last-child { margin-bottom: 0; }
.form button.btn { cursor: pointer; font-family: var(--body); }

/* ------------------------------------------- 9. Contenido pendiente ------ */
.todo {
  background: rgba(255, 193, 7, .22); color: #6b4e00;
  padding: 0 .25em; border-radius: .2em;
  box-shadow: inset 0 0 0 1px rgba(180, 130, 0, .45);
}

/* Datos provisionales. Subrayado punteado: se localizan de un vistazo sin
   estropear la maqueta, que es justo para lo que se han puesto. Quitar la
   regla no los hace reales; deploy.sh los sigue contando. */
[data-sample] {
  text-decoration: underline dotted rgba(140, 100, 0, .6);
  text-underline-offset: .22em;
}

/* --------------------------------------------------- 10. Revelado -------- */
/* Entrada al aparecer en pantalla, una vez por elemento. Sin JS, o con
   reduced-motion, todo queda visible: nunca se oculta contenido de verdad. */
.reveal { opacity: 0; transform: translateY(18px); }
html.js .reveal { transition: opacity .7s var(--easing), transform .7s var(--easing); }
.reveal.is-in, html:not(.js) .reveal { opacity: 1; transform: none; }

/* -------------------------------------------------- 11. Responsive ------- */
@media (max-width: 62rem) {
  .cards, .cards--6 { grid-template-columns: repeat(2, 1fr); }
  .tech-split { grid-template-columns: 1fr; gap: 3rem; }
  .command__grid { grid-template-columns: repeat(2, 1fr); }
  .panels { flex-wrap: wrap; min-height: 0; }
  .panel-v { flex: 1 1 30%; min-height: 20rem; }
  .row-item { grid-template-columns: 4rem 1fr; }
  .row-item p { grid-column: 2; }
  .band, .section { padding: 4.5rem 0; }
  .grid-2 { grid-template-columns: 1fr; gap: 2.5rem; }
  .aside { position: static; }
  .panel__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 48rem) {
  .menu-btn { display: block; }
  .masthead nav { order: 3; width: 100%; margin-left: 0; display: none; }
  .masthead nav.is-open { display: block; }
  .masthead nav ul { flex-direction: column; gap: .25rem; padding-top: .75rem; }
  .masthead nav a { padding: .6rem 1rem; }
  .steps, .cards, .cards--6, .checks { grid-template-columns: 1fr; }
  /* Los paneles se apilan y quedan abiertos: girar el rótulo en móvil no
     aporta nada y complica la lectura. */
  .panels { flex-direction: column; min-height: 0; }
  .panel-v { min-height: 0; padding-bottom: 1.5rem; }
  .panel-v__t { position: static; transform: none; margin: .5rem 0 .4rem; white-space: normal; }
  .panel-v:hover .panel-v__t, .panel-v:focus-visible .panel-v__t { bottom: auto; }
  .panel-v__d { position: static; opacity: 1; transform: none; }
  .row-item { grid-template-columns: 1fr; gap: .5rem; }
  .flow { font-size: clamp(1.8rem, 7vw, 2.4rem); }
  .band--close { padding: 4.5rem 0; }
  .media-band { min-height: 0; padding: 3.5rem 0; }
  .media-band .flow { max-width: none; }
  /* En estrecho el diagrama se apretuja: pasa a lista de tarjetas. */
  .orbit { aspect-ratio: auto; max-width: none; display: grid;
           grid-template-columns: repeat(2, 1fr); gap: .75rem; }
  .orbit__ring, .orbit__trace { display: none; }
  .orbit__hub { position: static; translate: none; width: auto; height: auto;
                grid-column: 1 / -1; padding: 1.25rem; border-radius: 1rem;
                animation: none; }
  /* El hub pasa a static y su anillo, que es absolute, se escaparía al
     contenedor de la órbita. Además en móvil el hub deja de ser redondo
     y un aro circular alrededor no tiene sentido. */
  .orbit__hub::after { display: none; }
  .orbit__node { position: static; translate: none; animation: none; white-space: normal; }
  .command__hero { grid-template-columns: 1fr; justify-items: stretch; }
  .command__grid { grid-template-columns: 1fr; }
  .figure--tall img { max-height: 18rem; }
  .inline-btn { display: inline-flex; margin: .6rem 0 0; }
  .grid-2 { grid-template-columns: 1fr; gap: 2.5rem; }
  .aside { position: static; }
  .panel__grid { grid-template-columns: 1fr; }
  .pipeline li { flex-basis: 100%; }
  .hero { padding: 4rem 0 3rem; }
  .page-head { padding: 4rem 0 2.5rem; }}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .ledger__tape, .live::before, .band--close::after,
  .orbit__ring, .orbit__trace, .orbit__hub, .orbit__node { animation: none !important; }
  .reveal { opacity: 1; transform: none; }}