/* =========================================================================
   assets/home.css — la portada publica.

   Aparte del CSS del panel a proposito: esto lo ve gente que no ha entrado
   nunca y no tiene por que descargar la hoja entera de la aplicacion.

   EL SISTEMA, en cuatro decisiones:

   1. UNA ESCALA, NO NUMEROS SUELTOS. Espaciado en pasos de 4 y tamanos de
      letra en una escala fija. Cuando cada seccion elige su propio numero,
      la pagina se ve "casi bien" en todas partes y bien en ninguna.

   2. EL RITMO VERTICAL ES EL DISENO. Las franjas respiran 96px en movil y
      hasta 140px en escritorio. Es lo que separa una pagina de producto de
      un documento: no son mas adornos, es mas aire.

   3. TRES TONOS DE FONDO Y NADA MAS. Blanco, gris muy claro y azul profundo,
      alternados. Es lo que parte la pagina en capitulos sin dibujar lineas.

   4. UNA SOLA COSA EN NEGRITA POR TITULAR. Los titulares van en peso ligero
      y solo la idea que importa va en <em>. El contraste de peso hace la
      jerarquia mejor que subir dos tamanos.

   Sin fuentes externas (regla 6.1): la escala esta afinada para la pila del
   sistema, que es lo que ya usa el panel.
   ========================================================================= */

:root {
  /* ===================================================================
     CAPA 1 — PRIMITIVOS. El color, sin opinion sobre para que sirve.
     ===================================================================
     Aqui habia una sola capa plana: cada token guardaba su hex a pelo, y
     #ffffff estaba escrito CUATRO veces con cuatro nombres. Al mirar la
     paleta parecian cuatro colores parecidos; eran el mismo, repetido.

     Con dos capas, "el fondo" y "el texto sobre el boton" siguen siendo dos
     decisiones distintas —pueden separarse el dia que haga falta— pero
     mientras compartan color, lo comparten de verdad: se cambia --w y se
     mueven los cuatro a la vez. Es la arquitectura de tres capas
     (primitivo -> semantico -> componente); la tercera solo se anade si
     algun componente necesita salirse, y hoy ninguno lo necesita.

     Los nombres NO dicen para que sirven a proposito. Un primitivo llamado
     --fondo vuelve a atar el valor a un uso, que es justo lo que se quiere
     evitar. */
  --w:         #ffffff;
  --paper-50:  #f5f7fa;
  --navy-950:  #0b1b33;
  --navy-800:  #12294a;
  --navy-50:   #eef3fb;
  --navy-200:  #a8bcd8;
  --ink-950:   #101827;
  --ink-600:   #4a5260;
  --ink-500:   #6b7280;
  --ink-100:   #e4e8ee;
  --blue-600:  #2563eb;
  --blue-700:  #1d4ed8;
  --blue-200:  #bfdbfe;
  --blue-50:   #e8effd;
  /* #EA580C es el naranja del perfil de logistica, pero con blanco encima da
     3.56:1; este es el mismo tono un paso mas oscuro y da 5.18. */
  --orange-700: #c2410c;
  --orange-800: #9a3412;
  --orange-400: #fb923c;
  --orange-300: #fdba74;
  --orange-950: #2a1206;
  /* Los del modo oscuro. Viven aqui y no dentro del bloque de oscuro porque
     un primitivo es un color, no un tema: el tema decide CUALES se usan. */
  --carbon-950: #0f1115;
  --carbon-900: #161a21;
  --carbon-700: #232833;
  --carbon-100: #e8eaee;
  --carbon-300: #aab2bf;
  --carbon-400: #8a94a5;
  --navy-990:   #060c18;
  --navy-900:   #0d1b30;
  --blue-400:   #60a5fa;
  --blue-300:   #93c5fd;

  /* ===================================================================
     CAPA 2 — SEMANTICOS. Para que sirve cada color.
     ===================================================================
     Lo unico que se usa en las reglas. Si una regla escribe un primitivo,
     se ha saltado la capa que da el significado. */

  /* Superficie */
  --paper:     var(--w);
  --paper-2:   var(--paper-50);
  --deep:      var(--navy-950);
  --deep-2:    var(--navy-800);

  /* Tinta */
  --ink:       var(--ink-950);
  --ink-2:     var(--ink-600);
  --ink-3:     var(--ink-500);
  --on-deep:   var(--navy-50);
  --on-deep-2: var(--navy-200);

  /* Marca: el azul estructura la pagina —etiquetas, numeros, enlaces— pero
     NO es el color de la accion. */
  --brand:     var(--blue-600);
  --brand-ink: var(--blue-700);
  --brand-soft:var(--blue-50);
  --on-brand:  var(--w);

  /* La accion, y solo la accion. Un unico color para "lo que hay que pulsar"
     es lo que hace que se vea sin buscarlo. Cuando todo era azul, cuatro
     botones iguales se leian como cuatro veces el mismo ruido. */
  --act:       var(--orange-700);
  --act-ink:   var(--orange-800);
  --on-act:    var(--w);

  --line:      var(--ink-100);
  /* Los translucidos se derivan del primitivo en vez de escribir el rgba a
     mano: asi se ve de que color son y no hay que confiar en que los tres
     255 coincidan. color-mix ya se usa mas abajo, en la barra. */
  --line-deep: color-mix(in srgb, var(--w) 14%, transparent);

  /* Sobre la franja azul el tono no cambia con el modo del sistema —el azul
     profundo es azul profundo siempre—, asi que estos dos NO viven en el
     bloque de oscuro: son "el color que hace falta encima del azul".
     El naranja oscuro sobre azul da 3.4:1 y no vale para texto; este da 7.9. */
  --on-deep-max:  var(--w);
  --act-on-deep:  var(--orange-400);
  --act-on-deep-2:var(--orange-300);
  --info-on-deep: var(--blue-200);
  /* Lo que se apoya SOBRE el azul: una superficie y una linea mas viva que
     --line-deep para cuando el raton pasa por encima.

     Aqui habia DOS tokens de superficie, .08 y .06, que sobre el azul dan
     dE 1.9: el ojo no los distingue. No eran una decision, eran dos numeros
     parecidos escritos en dias distintos que yo convertí en tokens al pasar
     los literales a variables. Tokenizar un literal lo conserva, no lo
     valida. Se quedan en uno: si de verdad hicieran falta dos superficies,
     la diferencia tendria que verse. */
  --wash-deep:   color-mix(in srgb, var(--w) 8%, transparent);
  --line-deep-2: color-mix(in srgb, var(--w) 32%, transparent);

  /* La densidad de las texturas, en un sitio y no dentro de cuatro
     degradados. Se afinaron a ojo y hay que poder reafinarlas igual. */
  --tex-dot:       color-mix(in srgb, var(--ink-950) 32%, transparent);
  --tex-dot-deep:  color-mix(in srgb, var(--w) 30%, transparent);
  --tex-line:      color-mix(in srgb, var(--ink-950) 20%, transparent);
  --tex-line-deep: color-mix(in srgb, var(--w) 20%, transparent);

  /* Forma */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-pill: 999px;

  /* Profundidad. Cuatro niveles y ni uno mas, porque una sombra suelta en
     una regla es una sombra que nadie vuelve a igualar: habia dos tarjetas
     con la misma sombra escrita dos veces y dos botones con dos sombras
     casi iguales.

     Son sombras de foco corto y muy difuminadas (el desenfoque negativo las
     recoge): sobre fondo blanco una sombra ancha se lee como suciedad. */
  --shadow-sm:   0 1px 2px rgba(16,24,39,.06);
  --shadow-md:   0 6px 16px -10px rgba(16,24,39,.50);
  --shadow-lg:   0 10px 22px -10px rgba(16,24,39,.55);
  --shadow-card: 0 24px 48px -32px rgba(16,24,39,.35);
  /* El aro de foco. Uno solo, para que teclear se sienta igual en toda la
     pagina. */
  --ring:        0 0 0 3px var(--brand-soft);
  /* Sobre el azul, --brand-soft es un azul claro OPACO y el aro se veria
     como una banda pintada. Ahi el aro tiene que dejar ver el fondo. */
  --ring-deep:   0 0 0 3px rgba(96,165,250,.28);

  /* Escala tipografica. La cabecera de este archivo dice "una escala, no
     numeros sueltos" y el espaciado la cumplia; la letra no: habia quince
     tamanos distintos escritos a mano, varios separados por medio pixel.
     Medio pixel no es una decision, es un descuido que se copia. */
  --t-micro: 12.5px;   /* etiqueta de encima del titular */
  --t-xs:    13.5px;   /* notas, pies de imagen, pie de pagina */
  --t-sm:    14.5px;   /* texto de apoyo dentro de listas y menu */
  --t-base:  15.5px;   /* botones, campos, negritas de lista */
  --t-ui:    16px;     /* la marca de la barra */
  --t-body:  16.5px;   /* el parrafo de lectura */
  --t-lead:  18px;     /* el parrafo del hero */
  --t-h3:    19px;
  --t-h2:    clamp(24px, 3.4vw, 36px);
  --t-h1:    clamp(32px, 6vw, 56px);
  --t-figure: clamp(30px, 4vw, 42px);   /* los numeros grandes */
  --t-quote:  clamp(19px, 2.4vw, 26px);

  /* Espacio: pasos de 4 */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;
  --band-y: 72px;

  --shell: 1120px;
  /* Lo que mide la barra de arriba, que va fija. Sirve para que al pulsar un
     enlace del menu la seccion no aterrice DEBAJO de la barra: sin esto el
     navegador la deja pegada al borde y la barra le tapa el titular, que es
     justo la sensacion de "me manda un poco mas abajo". */
  --nav-h: 76px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --ease: cubic-bezier(.22, 1, .36, 1);
}

@media (min-width: 760px)  { :root { --band-y: 104px; } }
@media (min-width: 1080px) { :root { --band-y: 140px; } }

/* El tema oscuro NO toca los primitivos: solo re-apunta los semanticos. Es
   para lo que existe la segunda capa. Y asi se ve una cosa que la paleta
   plana escondia: el naranja de accion del modo oscuro y el naranja que se
   usa sobre la franja azul son EL MISMO --orange-400, no dos naranjas
   parecidos que alguien eligio dos veces. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: var(--carbon-950); --paper-2: var(--carbon-900);
    --deep: var(--navy-990);    --deep-2: var(--navy-900);
    --ink: var(--carbon-100);   --ink-2: var(--carbon-300); --ink-3: var(--carbon-400);
    --brand: var(--blue-400);   --brand-ink: var(--blue-300);
    --brand-soft: color-mix(in srgb, var(--blue-400) 14%, transparent);
    --on-brand: var(--navy-950);
    /* Sobre fondo oscuro el naranja se aclara y el texto encima se oscurece. */
    --act: var(--orange-400); --act-ink: var(--orange-300); --on-act: var(--orange-950);
    --line: var(--carbon-700);
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.65 var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* =======================================================  barra de arriba */
.nv {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.nv.stuck { border-bottom-color: var(--line); }
.nv-in {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--s3) var(--s5);
  display: flex; align-items: center; gap: var(--s5);
}
.nv-brand {
  display: inline-flex; align-items: center; gap: var(--s3);
  font-weight: 700; font-size: var(--t-ui); letter-spacing: -.01em;
  color: var(--ink); text-decoration: none; flex: 0 0 auto;
}
.nv-brand img { width: 36px; height: 36px; object-fit: contain; border-radius: var(--r-sm); }
.nv-links { display: flex; gap: var(--s5); margin-left: auto; }
.nv-links a {
  color: var(--ink-2); text-decoration: none; font-size: var(--t-sm); font-weight: 500;
  padding: var(--s2) 0; position: relative;
}
/* El subrayado crece desde el centro. Es la unica floritura de la barra y
   dura 180ms: se nota que responde, no se espera a que termine. */
.nv-links a::after {
  content: ""; position: absolute; left: 50%; right: 50%; bottom: 2px; height: 2px;
  background: var(--brand); border-radius: 2px; transition: left .18s var(--ease), right .18s var(--ease);
}
.nv-links a:hover { color: var(--ink); }
.nv-links a:hover::after { left: 0; right: 0; }
/* Con el teclado pasa lo mismo que con el raton, y ademas se ve el aro. La
   barra lleva backdrop-filter, asi que el contorno del navegador solo se
   distingue a medias: se pone uno propio. Iban sin el desde el principio y
   quien navega con el tabulador cruzaba el menu a ciegas. */
.nv-links a:focus-visible,
.nv-brand:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 3px;
  border-radius: var(--r-sm); color: var(--ink);
}
.nv-links a:focus-visible::after { left: 0; right: 0; }
.nv-actions { display: flex; align-items: center; gap: var(--s2); flex: 0 0 auto; }

@media (max-width: 759px) {
  .nv-links { display: none; }          /* el menu cabe en el cuerpo, no aqui */
  .nv-actions { margin-left: auto; }
  .nv-actions .hb-btn { min-height: 40px; padding: 0 var(--s4); font-size: var(--t-xs); }
  .nv-in { padding: var(--s3) var(--s4); gap: var(--s3); }
  .nv-brand span { display: none; }     /* el logo basta */
}

/* ============================================================== franjas */
.band { background: var(--paper); position: relative; }
.band-soft { background: var(--paper-2); }
.band-deep { background: var(--deep); color: var(--on-deep); }

/* ---- texturas --------------------------------------------------------
   Cuatro, contando "ninguna", y muy tenues a proposito. Las guias marcan
   brutalismo y skeuomorfismo como "no usar en sectores conservadores": esto
   es dinero de restaurantes. La textura tiene que notarse cuando la buscas
   y desaparecer cuando lees.

   Van en un ::before y no en el background de la franja para poder
   apagarlas de golpe y para que nunca tapen el texto. */
.band[class*="tex-"] > .band-in { position: relative; z-index: 1; }
.band[class*="tex-"]::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
}

/* Puntos: papel de cuaderno tecnico. El mas discreto de los tres.

   Estuvieron en un ::before al 5% de opacidad y sobre blanco no se veian:
   quien elegia "Dot grid" no notaba que hubiera elegido nada, y un control
   que no se nota esta roto.

   Ahora el alfa va en el COLOR y no en la capa. Dos razones: la opacidad de
   la capa tambien apagaba la mascara de la reticula, y un punto opaco de
   1.2px se lee nitido donde una capa translucida se lee sucia.

   Sobre la lectura: el punto es oscuro pero cubre el 0.3% de la franja, asi
   que el fondo que hay debajo de una letra sigue siendo blanco a todos los
   efectos. Es una textura, no un color de fondo. Si algun dia se sube la
   densidad, esto deja de ser cierto y hay que medir el contraste otra vez. */
.tex-dots::before {
  background-image: radial-gradient(var(--tex-dot) 1.2px, transparent 1.2px);
  background-size: 20px 20px;
  opacity: 1;
}
.band-deep.tex-dots::before { background-image: radial-gradient(var(--tex-dot-deep) 1.2px, transparent 1.2px); }

/* Retícula: la misma idea, mas arquitectonica. Sus lineas son de 1px cada
   44, o sea que cubren mucho menos que los puntos: aguanta menos opacidad
   para pesar lo mismo. */
.tex-grid::before {
  background-image:
    linear-gradient(to right, var(--tex-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tex-line) 1px, transparent 1px);
  background-size: 44px 44px;
  opacity: 1;
  /* Se desvanece hacia abajo: una reticula que llega hasta el final se lee
     como un fallo de impresion, no como una decision. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 72%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 72%);
}
.band-deep.tex-grid::before {
  background-image:
    linear-gradient(to right, var(--tex-line-deep) 1px, transparent 1px),
    linear-gradient(to bottom, var(--tex-line-deep) 1px, transparent 1px);
}

/* Filo: una linea del color de accion arriba del todo. No es textura, es
   puntuacion: sirve para decir "aqui empieza algo distinto". */
.tex-edge::before {
  inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(to right, var(--act) 0, var(--act) 88px, transparent 88px);
}


.band-in {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--band-y) var(--s5);
  display: grid; grid-template-columns: repeat(12, 1fr);
  gap: var(--s7) var(--s5);
  align-items: start;
}
/* Dos franjas del MISMO tono no tienen frontera visible, asi que el relleno
   de abajo de una y el de arriba de la otra se leen como un agujero: ahi si
   se colapsa. Cuando el tono cambia, la frontera se ve y cada franja
   necesita su aire entero.

   Aqui habia un ".band + .band" a secas que se lo quitaba a todas, y por eso
   el bloque de cierre empezaba pegado al borde de su franja. */
.band-plain + .band-plain .band-in,
.band-soft  + .band-soft  .band-in,
.band-deep  + .band-deep  .band-in { padding-top: 0; }

/* La seccion lleva la clase hb-{tipo} —hb-steps, hb-stats, hb-form—, asi que
   NINGUN elemento de dentro puede llamarse igual que un tipo de bloque. El
   <ol> de los pasos se llamaba .hb-steps como su seccion, y el margen
   superior de la lista se lo llevaba tambien la seccion: dos bloques del
   mismo alto puestos al lado empezaban 24px desnivelados. Por eso las de
   dentro son .hb-feats, .hb-steplist, .hb-figures y .hbf. */
.hb {
  grid-column: span 12; min-width: 0;
  /* Los enlaces internos no deben dejar el inicio pegado a la barra. Este
     margen lo deja en el tercio superior: se reconoce de inmediato a que
     capitulo llegaste y aun queda contenido alrededor para dar contexto. */
  /* El titular aterriza justo debajo de la barra, con un respiro y no con
     medio pantallazo de la seccion anterior encima. Estuvo en 28vh: en una
     ventana normal eso dejaba 127px muertos bajo la barra, y al pulsar el
     menu parecia que te mandaba mas abajo de donde habias pedido. */
  scroll-margin-top: calc(var(--nav-h) + var(--s5));
}
.hb.w6 { grid-column: span 6; }
.hb.w4 { grid-column: span 4; }

@media (max-width: 759px) {
  .hb.w6, .hb.w4 { grid-column: span 12; }
  .band-in { padding-left: var(--s4); padding-right: var(--s4); gap: var(--s6) var(--s4); }
}

/* ========================================================== tipografia */
.hb h1 {
  font-size: var(--t-h1); line-height: 1.08;
  letter-spacing: -.03em; font-weight: 300; margin: 0 0 var(--s4);
}
.hb h2 {
  font-size: var(--t-h2); line-height: 1.18;
  letter-spacing: -.02em; font-weight: 300; margin: 0 0 var(--s3);
}
.hb h3 { font-size: var(--t-h3); line-height: 1.35; letter-spacing: -.01em; font-weight: 700; margin: 0 0 var(--s2); }
/* El enfasis es lo que hace la jerarquia, no un tamano mas grande. */
.hb h1 em, .hb h2 em {
  font-style: normal; font-weight: 700; color: var(--ink);
  position: relative; white-space: nowrap;
}
.band-deep .hb h1 em, .band-deep .hb h2 em { color: var(--on-deep-max); }

/* El trazo bajo la palabra que importa.

   Esta es la unica marca de la pagina que no la pone un sistema: no es un
   subrayado recto de 1px, es una linea gruesa, con las puntas redondas y
   ligeramente inclinada, como pasada a mano por encima. Es lo que hace que
   la pagina parezca decidida por alguien y no generada.

   Va detras del texto (z-index -1) y no toca la caja: si se quita, no se
   mueve nada. */
.hb h1 em::after {
  content: ""; position: absolute; z-index: -1;
  left: -.06em; right: -.06em; bottom: .04em; height: .18em;
  background: var(--act);
  border-radius: .12em;
  opacity: .22;
  transform: rotate(-.5deg);
}
.band-deep .hb h1 em::after { opacity: .34; }

.hb p { margin: 0 0 var(--s3); color: var(--ink-2); max-width: 62ch; font-size: var(--t-body); }
.hb p:last-child { margin-bottom: 0; }

.hb-eyebrow {
  display: flex; align-items: center; gap: var(--s3);
  font-size: var(--t-micro); font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--brand-ink); margin: 0 0 var(--s4);
}
.hb-eyebrow i { display: block; width: 28px; height: 2px; background: var(--brand); border-radius: 2px; flex: 0 0 auto; }

/* La nota y el pie de imagen se escriben ".hb p.hb-note" y no ".hb-note" a
   secas, y no es manía: son <p> dentro de .hb, asi que ".hb p" (0,1,1) y
   ".hb-hero p" (0,2,0) les ganaban a ".hb-note" (0,1,0) en las TRES
   propiedades que declaran. En la portada publicada, "No payment needed!"
   se estaba pintando a 18px en --ink-2 y sin separacion: identico a un
   parrafo normal. Un componente que pierde contra la regla generica no es
   un componente, es una clase decorativa que no hace nada. */
.hb p.hb-note { font-size: var(--t-xs); color: var(--ink-3); margin-top: var(--s3); }
.hb p.hb-cap  { font-size: var(--t-xs); color: var(--ink-3); margin-top: var(--s2); }

/* ============================================================== bloques */
.hb-hero .hb-logo { width: min(120px, 30vw); height: auto; margin-bottom: var(--s5); display: block; }
.hb-hero p { font-size: var(--t-lead); }

.hb-feats { list-style: none; margin: var(--s5) 0 0; padding: 0; display: grid; gap: var(--s4); }
.hb-feats li { padding-left: var(--s6); position: relative; }
.hb-feats li::before {
  content: ""; position: absolute; left: 0; top: 8px;
  width: 18px; height: 18px; border-radius: var(--r-pill);
  background: var(--brand-soft);
  box-shadow: inset 0 0 0 2px var(--brand);
}
.hb-feats b { display: block; font-size: var(--t-base); }
.hb-feats span { display: block; color: var(--ink-2); font-size: var(--t-sm); }

.hb-figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s5); margin-top: var(--s5); }
.hb-figures div { padding-left: var(--s4); border-left: 2px solid var(--line); }
.hb-figures b { display: block; font-size: var(--t-figure); font-weight: 300; letter-spacing: -.03em; line-height: 1.1; }
.hb-figures span { display: block; font-size: var(--t-xs); color: var(--ink-3); margin-top: var(--s1); }

.hb-steplist { list-style: none; counter-reset: paso; margin: var(--s5) 0 0; padding: 0; display: grid; gap: var(--s5); }
.hb-steplist li { counter-increment: paso; padding-left: var(--s8); position: relative; min-height: 40px; }
.hb-steplist li::before {
  content: counter(paso); position: absolute; left: 0; top: 0;
  width: 40px; height: 40px; border-radius: var(--r-pill);
  display: grid; place-items: center;
  background: var(--brand); color: var(--on-brand);
  font-weight: 700; font-size: var(--t-base);
}
.hb-steplist b { display: block; font-size: var(--t-ui); }
.hb-steplist span { display: block; color: var(--ink-2); font-size: var(--t-sm); }

.hb-quote blockquote {
  margin: 0; font-size: var(--t-quote); line-height: 1.4;
  font-weight: 300; letter-spacing: -.01em;
}
.hb-quote blockquote::before { content: "\201C"; color: var(--brand); }
.hb-quote blockquote::after  { content: "\201D"; color: var(--brand); }
.hb-quote cite { display: block; margin-top: var(--s4); font-style: normal; font-size: var(--t-sm); color: var(--ink-3); }

.hb-image img, .hb-media img {
  display: block; width: 100%; height: auto;
  border-radius: var(--r-md); border: 1px solid var(--line);
}
.hb-image_text { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: center; }
.hb-image_text.flip .hb-media { order: 2; }
@media (max-width: 759px) {
  .hb-image_text { grid-template-columns: 1fr; gap: var(--s5); }
  .hb-image_text.flip .hb-media { order: 0; }
}

/* El cierre. Las medidas cortas son lo que hace que un bloque de cierre se
   lea de un golpe: un titular de 20 caracteres por linea y un parrafo de 46
   no dan tiempo a distraerse. La justificacion ya no esta aqui, la decide
   quien edita. */
.hb-cta h2 { max-width: 20ch; }
.hb-cta p { max-width: 46ch; }
.hb-cta p.hb-note { margin-top: var(--s4); }
.hb-spacer { min-height: var(--s2); }
.hb-spacer hr { border: 0; border-top: 1px solid var(--line); margin: 0; }

/* ====================================================== el formulario
   Tres formas, un solo HTML. Lo que cambia entre 'card', 'split' y 'open' es
   donde se pone la caja y si tiene tarjeta, no lo que se pregunta: cinco
   campos, siempre los mismos.

   Las etiquetas van ENCIMA del campo y no dentro. Un placeholder que hace de
   etiqueta desaparece en cuanto escribes, y entonces el formulario a medio
   rellenar es una columna de cajas sin nombre: quien vuelve a revisarlo no
   sabe cual era cual. */
.hb-form .hbf-say { margin-bottom: var(--s6); }
.hb-form .hbf-say p:last-child { margin-bottom: 0; }

.hbf-grid { display: grid; grid-template-columns: 1fr; gap: var(--s4); }
.hbf-wide { grid-column: 1 / -1; }

.hbf-f { display: flex; flex-direction: column; gap: var(--s2); min-width: 0; }
.hbf-f label {
  font-size: var(--t-xs); font-weight: 600; color: var(--ink);
  display: flex; align-items: baseline; gap: var(--s1);
}
/* El asterisco no es decoracion, dice cual puedes saltarte. Va en el color de
   accion para que se vea sin leerlo. */
.hbf-f label i { font-style: normal; color: var(--act); font-weight: 700; }

.hbf-f input, .hbf-f textarea {
  width: 100%; font: inherit; font-size: var(--t-base); color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 0 var(--s4); min-height: 48px;
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.hbf-f textarea { padding: var(--s3) var(--s4); min-height: 112px; line-height: 1.55; resize: vertical; }
.hbf-f input::placeholder, .hbf-f textarea::placeholder { color: var(--ink-3); }
.hbf-f input:hover, .hbf-f textarea:hover { border-color: var(--ink-3); }
.hbf-f input:focus, .hbf-f textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: var(--ring);
}
/* :user-invalid y no :invalid: con :invalid un campo obligatorio se pinta en
   rojo antes de que nadie lo haya tocado, y la pagina te rine al llegar. */
.hbf-f input:user-invalid { border-color: var(--act); }

.hbf-go { margin-top: var(--s5); width: 100%; }
.hbf-go:disabled { cursor: wait; opacity: .72; transform: none; box-shadow: none; }
.hbf p.hb-note { margin-top: var(--s3); text-align: center; }

/* El cepo. Fuera de la pantalla, no oculto: display:none y hidden los
   rellenan igual, y entonces deja de servir para nada. */
.hbf-trap {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; opacity: 0;
}
.hb-form { position: relative; }

/* Confirmacion: texto breve junto al boton, no una tarjeta ni una franja.
   Si el navegador no ejecuta JS, .hbf-msg conserva exactamente esta misma
   presencia discreta despues del redirect de respaldo. */
.hbf-msg, .hbf-feedback {
  margin: var(--s3) 0 0; min-height: 1.5em;
  font-size: var(--t-sm); line-height: 1.5; color: var(--ink-2);
}
.hbf-msg.is-ok, .hbf-feedback.is-ok { color: var(--brand-ink); }
.hbf-msg.is-err, .hbf-feedback.is-err { color: var(--act-ink); }

/* ---- forma 1: la tarjeta, sola en medio de la franja --------------- */
.fv-card .hbf-say { max-width: 46ch; }
.fv-card .hbf-box {
  max-width: 560px; text-align: left;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s6);
  box-shadow: var(--shadow-card);
}

/* ---- forma 2: las palabras al lado -------------------------------- */
.fv-split { display: grid; grid-template-columns: 1fr; gap: var(--s6); align-items: start; }
.fv-split .hbf-say { margin-bottom: 0; }
.fv-split .hbf-box {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s6);
  box-shadow: var(--shadow-card);
}

/* ---- forma 3: sin tarjeta ------------------------------------------ */
.fv-open .hbf-box { max-width: 720px; }
.fv-open .hbf-f input, .fv-open .hbf-f textarea { background: transparent; }
.fv-open .hbf-go { width: auto; min-width: 220px; }

@media (min-width: 620px) {
  .fv-card .hbf-grid, .fv-open .hbf-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 860px) {
  .fv-split { grid-template-columns: 1fr 1fr; gap: var(--s8); }
  .fv-split .hbf-say { padding-top: var(--s2); }
}
@media (max-width: 619px) {
  .fv-card .hbf-box, .fv-split .hbf-box { padding: var(--s5); }
}

/* ========================================================= justificacion
   Izquierda, centro y derecha, y lo elige quien edita en vez de venir
   cableado por tipo de bloque. Antes .hb-hero y .hb-cta traian
   text-align:center escrito en la hoja: se veian centrados y no habia forma
   de moverlos.

   Va DESPUES de tipografia a proposito. ".hb p" pesa lo mismo que
   ".al-center p", asi que gana el que venga despues; si esto estuviera
   arriba, un parrafo centrado seguiria pegado a la izquierda de su caja.

   Por dentro, las listas y los numeros NO se centran nunca: una lista con
   vinetas y el texto centrado deja el ojo sin margen desde donde volver, y
   se lee peor cuanto mas larga es. Se mueve el bloque, no sus renglones. */
.al-center { text-align: center; }
.al-center h1, .al-center h2, .al-center h3,
.al-center p, .al-center .hb-note, .al-center .hb-cap,
.al-center img, .al-center .hbf-say, .al-center .hbf-box {
  margin-left: auto; margin-right: auto;
}
.al-center .hb-eyebrow { justify-content: center; }

.al-end { text-align: right; }
.al-end h1, .al-end h2, .al-end h3,
.al-end p, .al-end .hb-note, .al-end .hb-cap,
.al-end img, .al-end .hbf-say, .al-end .hbf-box {
  margin-left: auto; margin-right: 0;
}
.al-end .hb-eyebrow { justify-content: flex-end; }

.al-start .hbf-box { margin-left: 0; margin-right: auto; }

.al-center .hb-feats, .al-center .hb-steplist, .al-center .hb-figures,
.al-end .hb-feats, .al-end .hb-steplist, .al-end .hb-figures { text-align: left; }

/* Aqui hubo un .hb-acts para poner dos botones dentro de un bloque. No se
   usa: las dos acciones —entrar y darse de alta— viven en la barra de
   arriba, que es donde las busca la gente, y un bloque sigue teniendo una
   sola llamada. Se borra en vez de dejarlo comentado (regla 5.5). */

/* =============================================================== botones */
/* Hasta el formulario, TODOS los botones de la portada eran <a>. El de
   enviar es un <button> de verdad —tiene que enviar— y un <button> llega
   con su propio borde, su propio fondo y su propia tipografia del sistema.
   Por eso se veia distinto del resto: no era otro estilo, era el navegador
   poniendo el suyo debajo. Aqui se quita, y asi los dos son el mismo boton. */
.hb-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 50px; padding: 0 var(--s6); border-radius: var(--r-pill);
  font-family: inherit; font-size: var(--t-base); font-weight: 600; line-height: 1;
  text-align: center; text-decoration: none; white-space: nowrap;
  border: 0; background: none; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  transition: transform .16s var(--ease), box-shadow .16s var(--ease), background .16s var(--ease);
}
.hb-primary { background: var(--act); color: var(--on-act); box-shadow: var(--shadow-md); }
.hb-primary:hover { background: var(--act-ink); transform: translateY(-1px); box-shadow: var(--shadow-lg); }
.hb-ghost {
  min-height: 42px; padding: 0 var(--s5); font-size: var(--t-sm);
  border: 1px solid var(--line); color: var(--ink); background: transparent;
}
.hb-ghost:hover { border-color: var(--brand); color: var(--brand-ink); }
.band-deep .hb-ghost { border-color: var(--line-deep); color: var(--on-deep); }
.hb-btn:active { transform: translateY(1px); }
.hb-primary:focus-visible { outline-color: var(--act); }
.hb-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }

/* ================================================================== pie */
.home-foot {
  border-top: 1px solid var(--line);
  background: var(--paper);
}
.home-foot-in {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--s6) var(--s5);
  display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap;
  font-size: var(--t-xs); color: var(--ink-3);
}
.home-foot-in .hb-btn { margin-left: auto; }

/* ============================================== el tono oscuro, al final
   Va despues de tipografia y de bloques a proposito, y con un selector mas
   especifico: con .band-deep p a secas perdia contra .hb p, que viene
   despues, y el parrafo salia gris oscuro sobre azul oscuro. */
.band-deep .hb h1, .band-deep .hb h2, .band-deep .hb h3 { color: var(--on-deep); }
.band-deep .hb h1 em, .band-deep .hb h2 em { color: var(--on-deep-max); }
.band-deep .hb p { color: var(--on-deep-2); }
/* Con (0,2,0) esta regla habia quedado POR DEBAJO de .hb p.hb-note y la
   nota sobre azul se habria pintado en --ink-3: gris oscuro sobre azul
   oscuro. Subir la especificidad de un componente obliga a revisar todo lo
   que lo pintaba desde fuera. */
.band-deep .hb p.hb-note, .band-deep .hb p.hb-cap { color: var(--on-deep-2); }
.band-deep .hb-feats span, .band-deep .hb-steplist span { color: var(--on-deep-2); }
.band-deep .hb-figures span { color: var(--on-deep-2); }
.band-deep .hb-eyebrow { color: var(--on-deep-2); }
.band-deep .hb-eyebrow i { background: var(--on-deep-2); }
.band-deep .hb-feats li::before { background: var(--wash-deep); box-shadow: inset 0 0 0 2px var(--brand); }
.band-deep hr, .band-deep .hb-figures div { border-color: var(--line-deep); }
.band-deep .hb-quote cite { color: var(--on-deep-2); }

/* El formulario sobre azul. La tarjeta blanca de la forma 'card' aqui seria
   un folio pegado en la pared: se usa el azul de un paso mas claro, que es el
   mismo recurso que separa la barra de arriba del cuerpo. */
.band-deep .fv-card .hbf-box, .band-deep .fv-split .hbf-box {
  background: var(--deep-2); border-color: var(--line-deep); box-shadow: none;
}
.band-deep .hbf-f label { color: var(--on-deep); }
/* El naranja oscuro sobre azul oscuro da 3.4:1 y este asterisco es texto.
   El mismo tono un paso mas claro da 7.9:1. */
.band-deep .hbf-f label i { color: var(--act-on-deep); }
.band-deep .hbf-f input, .band-deep .hbf-f textarea {
  background: var(--wash-deep); border-color: var(--line-deep); color: var(--on-deep);
}
.band-deep .hbf-f input::placeholder, .band-deep .hbf-f textarea::placeholder { color: var(--on-deep-2); }
.band-deep .hbf-f input:hover, .band-deep .hbf-f textarea:hover { border-color: var(--line-deep-2); }
.band-deep .hbf-f input:focus, .band-deep .hbf-f textarea:focus {
  border-color: var(--brand); box-shadow: var(--ring-deep);
}
.band-deep .hbf-msg, .band-deep .hbf-feedback { color: var(--on-deep-2); }
.band-deep .hbf-msg.is-ok, .band-deep .hbf-feedback.is-ok { color: var(--info-on-deep); }
.band-deep .hbf-msg.is-err, .band-deep .hbf-feedback.is-err { color: var(--act-on-deep-2); }

/* ====================================================== aparicion al bajar
   Un solo efecto en toda la pagina, y suave: sube 14px y aparece. Mas de un
   efecto compitiendo es lo que hace que una pagina se sienta inquieta.
   Sin JS los bloques se ven igual: el estado de partida solo se aplica si
   el script llega a marcar el documento. */
[data-reveal] { opacity: 1; }
.js-reveal [data-reveal] {
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.js-reveal [data-reveal].seen { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js-reveal [data-reveal] { opacity: 1; transform: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important; transition-duration: .01ms !important;
  }
}
