/* ============================================================
   Self-hosted fonts (latin subset, woff2)

   Previously loaded from fonts.googleapis.com + fonts.gstatic.com,
   which cost two extra DNS+TLS handshakes to two third-party hosts
   and sent every visitor IP to Google. Files live in assets/fonts/.

   Only the weights the site actually uses are included:
     IBM Plex Sans  300 400 500 600 700
     Space Grotesk  600 700          (400/500 were never used)

   To add a weight later: download the woff2 from Google Fonts into
   assets/fonts/, add a block below, then run bump-version.py.
   ============================================================ */

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-300.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/space-grotesk-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/space-grotesk-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* ===== L2H — shared styles =====
   Extracted from index.html so every page shares one source of truth.
   Link it from each page's <helmet>:
     <link rel="stylesheet" href="/assets/l2h.css">
   Fonts (IBM Plex Sans + Space Grotesk) are still linked per-page in the
   helmet so the browser can preconnect early. */

:root {
  --l2h-bg: #111110;
  --l2h-fg: #F2F5FA;
  --l2h-accent: #E8E0D2; /* overridden at runtime by the home's applyVars() */
  --l2h-glow: 1;         /* 1 = ambient glows on, 0 = off */
}

html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--l2h-bg);
  font-family: 'IBM Plex Sans', sans-serif;
  color: var(--l2h-fg);
  -webkit-font-smoothing: antialiased;
}
* { box-sizing: border-box; }
a { color: var(--l2h-fg); text-decoration: none; }
a:hover { color: #F4F1EA; }
::selection { background: rgba(255,255,255,0.35); }

/* ===== ANIMATIONS ===== */
@keyframes l2hPulse { 0%,100% { opacity: .5; transform: scale(1); } 50% { opacity: 1; transform: scale(1.35); } }
@keyframes l2hFloat { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@keyframes l2hMarquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes l2hDrift { 0%,100% { transform: translate(0,0); opacity:.8; } 50% { transform: translate(30px,-20px); opacity:1; } }
@keyframes l2hIntroLetter { from { opacity: 0; transform: translateY(24px); filter: blur(8px); } to { opacity: 1; transform: translateY(0); filter: blur(0); } }
@keyframes l2hIntroGlow { 0% { opacity: 0; transform: translate(-50%,-50%) scale(0.6); } 60% { opacity: 1; } 100% { opacity: 0.9; transform: translate(-50%,-50%) scale(1); } }
@keyframes l2hIntroSub { from { opacity: 0; letter-spacing: 8px; } to { opacity: 1; letter-spacing: 4px; } }
@keyframes l2hIntroLine { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.l2h-carousel::-webkit-scrollbar { height: 6px; }
.l2h-carousel::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
/* Marca del hero: solo móvil (en escritorio manda la marca de agua) */
.l2h-hero-brand { display: none; }
.l2h-navburger { display: none; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: 50%; background: linear-gradient(180deg,rgba(255,255,255,0.14),rgba(255,255,255,0.04)); border: 1px solid rgba(255,255,255,0.18); color: #F2F5FA; font-size: 16px; cursor: pointer; }

/* ===== RESPONSIVE ===== */
@media (max-width: 900px) {
  .l2h-grid2, .l2h-grid-port { grid-template-columns: 1fr !important; }
  .l2h-grid4, .l2h-grid3 { grid-template-columns: 1fr 1fr !important; }
  .l2h-footer-grid { grid-template-columns: 1fr 1fr !important; gap: 32px !important; }
  /* Precios: quitar el "levantar" de la tarjeta destacada al apilar */
  .l2h-grid3 > * { transform: none !important; }
  /* Servicios y Stack: de órbita a lista apilada */
  .l2h-serv { min-height: 0 !important; display: flex !important; flex-direction: column !important; gap: 12px; }
  .l2h-serv .l2h-chip, .l2h-torbit .l2h-chip { position: static !important; transform: none !important; }
  .l2h-serv .l2h-chip span, .l2h-torbit .l2h-chip span { animation: none !important; }
  .l2h-torbit { position: static !important; height: auto !important; display: flex !important; flex-wrap: wrap; gap: 10px; justify-content: center; }
  .l2h-deco { display: none !important; }
  /* Hero: pasar a flujo normal ya desde tablet — con posición absoluta el
     titular y los CTAs se superponen entre ~720px y ~880px */
  .l2h-hero { display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important; gap: 24px !important; padding: 120px 32px !important; text-align: center; }
  /* relative + z-index para que el título/CTA queden por ENCIMA de la marca de agua */
  .l2h-hero-title, .l2h-hero-cta { position: relative !important; z-index: 2 !important; left: auto !important; right: auto !important; bottom: auto !important; max-width: none !important; }
  /* Marca de agua gigante "L2H": subirla y atenuarla para que no compita con
     el titular centrado (en desktop va de fondo, acá se cruzaba con el texto) */
  .l2h-hero-wm { align-items: flex-start !important; padding-top: 12vh; opacity: 0.35 !important; }
}
@media (max-width: 720px) {
  /* Nav: ocultar enlaces centrales, dejar logo + Cotizar */
  .l2h-navlinks { display: none !important; }
  /* En móvil el nav flotante va ABAJO para no tapar el kicker/título de las
     secciones (que arrancan cerca del borde superior en las páginas internas) */
  .l2h-nav { top: auto !important; bottom: 16px !important; gap: 14px !important; padding: 9px 10px 9px 18px !important; }
  /* El menú desplegable se abre hacia ARRIBA, por encima del nav inferior */
  .l2h-navmobile { top: auto !important; bottom: 84px !important; }
  /* Aire al final para que el nav flotante no tape el copyright del footer */
  footer { padding-bottom: 92px !important; }
  /* Hero: ocultar etiquetas de esquina, centrar titular y CTAs */
  .l2h-hero-corner { display: none !important; }
  .l2h-hero-title { max-width: none !important; text-align: center; }
  .l2h-hero-cta { justify-content: center !important; flex-wrap: wrap; }
  /* Titulares grandes */
  section h2, .l2h-hero + section h2 { font-size: 30px !important; }
  /* h1 de páginas internas (servicios, portafolio, nosotros, contacto, casos) —
     el hero de la home usa .l2h-hero-title h1, más específico, así que gana igual */
  h1 { font-size: 32px !important; }
  /* Contacto: formulario a una columna */
  .l2h-form { grid-template-columns: 1fr !important; }
  .l2h-form > * { grid-column: span 1 !important; }
  /* Menos padding en móvil */
  section { padding-left: 18px !important; padding-right: 18px !important; }
  .l2h-contact-card { padding: 32px 22px !important; }
  /* Card de servicio (servicios.html): menos padding y número más chico
     para que quepa cómodo junto al contenido en una columna angosta */
  .l2h-svc-card { padding: 28px 22px !important; }
  .l2h-svc-num { font-size: 64px !important; }
  .l2h-navburger { display: flex !important; }
  /* El nav va abajo en movil: el encabezado no necesita despejar nada arriba */
  .l2h-pagetop { padding-top: 44px !important; }
  /* 88vh (no 100vh): deja asomar la sección siguiente, que es la pista de que
     hay más abajo — mejor que una flecha, que chocaría con el nav inferior */
  .l2h-hero { display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important; gap: 22px !important; padding: 96px 20px !important; min-height: 88vh !important; }
  .l2h-hero-title, .l2h-hero-cta { position: relative !important; z-index: 2 !important; left: auto !important; right: auto !important; bottom: auto !important; }
  /* En teléfono se saca la marca de agua "L2H": deja el hero limpio */
  .l2h-hero-wm { display: none !important; }
  /* ...y en su lugar va el logotipo contenido, arriba del titular */
  .l2h-hero-brand { display: flex !important; flex-direction: column; align-items: center; gap: 13px; position: relative; z-index: 2; }
  /* 21px era tamaño de párrafo, no de titular principal */
  .l2h-hero-title h1 { font-size: 34px !important; }
  /* "¿Te suena esto?": carrusel horizontal en vez de 6 tarjetas apiladas.
     Los márgenes negativos lo sangran hasta el borde de la pantalla y el
     padding lateral mantiene la primera tarjeta alineada con el resto del
     contenido; el 86% de ancho deja ver un pedazo de la siguiente (pista
     visual de que se desliza). */
  .l2h-mscroll { display: flex !important; gap: 14px !important; margin-left: -18px !important; margin-right: -18px !important; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; padding: 0 18px 14px; scroll-padding-left: 18px; }
  .l2h-mscroll > * { flex: 0 0 86%; scroll-snap-align: start; }
  /* Proceso: el cubo 3D es decorativo y repite los nombres de los pasos —
     en teléfono costaba media pantalla de scroll, así que se saca */
  .l2h-proc-3d { display: none !important; }
  /* Miniaturas del portafolio: conservan su ancho (flex-shrink:0 en el HTML)
     y el riel se desliza, en vez de aplastarse hasta partir el título */
  .l2h-thumbs { overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 10px; }
  .l2h-thumbs > * { scroll-snap-align: start; }
  /* Planes: 320px fijos no dejaban ver el borde de la siguiente tarjeta y el
     texto quedaba angosto por el padding de escritorio. El scroll-padding evita
     que el encaje se coma el padding del riel al cargar. */
  .l2h-plan { flex-basis: 86% !important; padding: 28px 22px !important; }
  #precios .l2h-carousel { scroll-padding-left: 4px; }
  #precios button[aria-label="Anterior"], #precios button[aria-label="Siguiente"] { display: none !important; }
}
@media (max-width: 480px) {
  .l2h-grid4, .l2h-grid3, .l2h-footer-grid { grid-template-columns: 1fr !important; }
  .l2h-hero-title h1 { font-size: 30px !important; }
  h1 { font-size: 26px !important; }
  .l2h-svc-num { font-size: 52px !important; }
}

/* ===== SHARED PAGE HELPERS (nuevas páginas internas) ===== */
/* Contenedor estándar de secciones internas */
.l2h-wrap { max-width: 1180px; margin: 0 auto; }
/* Espaciado bajo el nav flotante para páginas sin hero full-screen */
.l2h-pagetop { padding-top: 132px; }
/* Eyebrow / kicker reutilizable */
.l2h-kicker { font-size: 12.5px; font-weight: 500; letter-spacing: 2px; text-transform: uppercase; color: var(--l2h-accent); }

/* ===== ENTRANCE ANIMATION =====
   Pure-CSS reveal for internal pages. Declarative (not JS touching the DOM),
   so the dc-runtime's React reconciliation never fights it: the node is
   created once, animates once, and re-renders reuse the node (stable key)
   without replaying it. Use class="reveal-up" (+ d1..d4 for a staggered
   delay). The home keeps its own JS-driven [data-reveal] logic. */
@keyframes l2hRevealUp {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
.reveal-up { animation: l2hRevealUp .7s cubic-bezier(.2,.7,.2,1) both; }
.reveal-up.d1 { animation-delay: .08s; }
.reveal-up.d2 { animation-delay: .16s; }
.reveal-up.d3 { animation-delay: .24s; }
.reveal-up.d4 { animation-delay: .32s; }
@media (prefers-reduced-motion: reduce) {
  .reveal-up, .reveal-up.d1, .reveal-up.d2, .reveal-up.d3, .reveal-up.d4 { animation: none; }
}
