/* MICHEMICAL DATALAB ACADEMY — V2 PREVIEW (aislado, NO productivo)
   ------------------------------------------------------------------------
   Archivo NUEVO, exclusivo de este preview. Academy es un proyecto/codebase separado de
   michemicaldatalab.com (subdominio propio, C:\MichemicalAcademy\, puerto 127.0.0.1:5601
   detrás de Caddy) — por eso NO se referencia ningún archivo del proyecto principal por ruta
   de disco/URL. Los valores de diseño (tokens, header, botón, grid, glow) están PORTADOS
   (copiados como texto, no enlazados) desde el sistema V2 real y aprobado en producción:

     C:\Users\Administrator\michemical-catalogo-web-con-imagenes\michemical-catalogo-web\
       public\home-v2.css   (:root tokens líneas 26-37, header líneas 108-153,
                              #pf-grid líneas 51-57, #pf-glow líneas 60-68)
       public\facturacion-v2.css (botón lima líneas 64-72: rgb(192,254,4)/rgb(170,238,0)/
                                   radius 6px/hover translateY(-1px))
       public\apis-v2.css   (patrón "SEGURIDAD 320px" línea 288: @media(max-width:400px)
                              oculta .pf-brandname — mismo fix reutilizado aquí)

   Las 4 fuentes (@font-face) fueron copiadas (no enlazadas) a este proyecto, en
   public/assets/fonts-v2/, verificadas SHA-256 idénticas al origen.

   Este archivo se carga JUNTO a /css/tokens.css, /css/academy.css, /css/components.css
   (y /css/auth.css en el login) — NO los reemplaza ni los modifica. Actúa como capa V2
   por encima, re-escribiendo SOLO layout/skin nuevo (clases av2-*) y el lenguaje de botón/
   header/grid, sin tocar ninguna regla real de auth/CSRF/roles/login.js. */

@font-face {
  font-family: "TikTok Sans Academy V2";
  src: url("/assets/fonts-v2/TikTokSans36pt-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist Mono Academy V2";
  src: url("/assets/fonts-v2/GeistMono-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist Mono Academy V2";
  src: url("/assets/fonts-v2/GeistMono-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Departure Mono Academy V2";
  src: url("/assets/fonts-v2/DepartureMono-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}

/* ============ ETAPA 3B — RESET DE CAJA (fix estructural, no visual) ============
   Auditoría local en navegador real detectó overflow horizontal móvil en Landing
   (.av2-product-card) y Login (.av2-login-card). Causa raíz confirmada al leer este
   archivo completo: NUNCA se portó el reset universal real de home-v2.css:39
   (`* { box-sizing: border-box; }`) al crear este archivo en la Etapa 2 — un vacío de
   ese trabajo previo, no algo introducido ahora. Sin él, cualquier elemento con `width`
   explícito (o "stretch" de grid/flex, que cuenta como width para box-sizing) + padding/
   border renderiza MÁS ANCHO que su contenedor: exactamente .av2-product-card (width:
   min(560px,100%) + padding + border, <900px), .av2-login-card (width:min(480px,100%) +
   border) y TODOS los campos/botones del form de login que son ítems de grid estirados
   (input/.av2-login-remember/.av2-btn.auth-submit tienen padding+border propios). Se
   añade el mismo reset EXACTO citado (universal, sin scope) porque así vive en la fuente
   real — no cambia el ancho de elementos con width:auto (la mayoría del layout desktop),
   así que 1440/1024/768 no deberían verse afectados visualmente; donde SÍ corrige algo
   (las cards con width fijo) el efecto es que la caja ahora mide EXACTAMENTE lo
   declarado, que es la corrección buscada, no un rediseño. */
* { box-sizing: border-box; }

/* ============ TOKENS V2 — valores EXACTOS de home-v2.css:26-37, sin redondear/adivinar.
   Con prefijo -av2 para no colisionar con --color-* de tokens.css (mismo criterio de
   scoping ya usado en facturacion-v2.css para evitar la colisión --ink/--muted/--line). ============ */
:root {
  --av2-ink: #0a0e14;
  --av2-muted: rgba(10,14,20,.62);
  --av2-accent: #2f80ed;
  --av2-accent-2: #00a6d6;
  --av2-line: rgba(10,14,20,.10);
  --av2-font-display: "TikTok Sans Academy V2", "Arial Black", sans-serif;
  --av2-font-mono: "Geist Mono Academy V2", ui-monospace, monospace;
  --av2-font-label: "Departure Mono Academy V2", ui-monospace, monospace;
}

/* ============ FONDO V2 — mismo degradé de home-v2.css:46 (body.pf), aplicado aquí solo a
   las páginas que cargan este archivo (no toca <body> del resto de Academy). ============ */
body.av2 {
  min-height: 100vh;
  color: var(--av2-ink);
  background: linear-gradient(160deg, #cfe8f8 0%, #e5f4fc 55%, #f1f9ff 100%);
  background-attachment: fixed;
}

/* ============ GRID DE FONDO — idéntico a #pf-grid de home-v2.css:51-57 (SVG generado por
   academy-v2.js, puramente visual, pointer-events:none, sin afectar login/formularios). ============ */
#pf-grid {
  position: fixed; inset: 0; z-index: 1;
  pointer-events: none;
  mix-blend-mode: difference;
}
#pf-grid path.pf-lines { stroke: rgba(255,255,255,.10); stroke-width: 1; fill: none; }
#pf-grid path.pf-cross { stroke: rgba(255,255,255,.25); stroke-width: 1; fill: none; }

/* ============ GLOW QUE SIGUE AL MOUSE — idéntico a #pf-glow de home-v2.css:60-68. ============ */
#pf-glow {
  position: fixed; top: 0; left: 0; z-index: 2;
  width: 560px; height: 560px;
  margin-left: -280px; margin-top: -280px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(47,128,237,.14) 0%, rgba(0,166,214,.06) 45%, transparent 72%);
  pointer-events: none;
  will-change: transform;
}

/* ============ ETAPA 5 — #pf-fluid: estela WebGL2 real del mouse, idéntica a Home ============
   Valores EXACTOS de home-v2.css:97-105 (#pf-fluid), sin aproximar ninguno: position:fixed;
   inset:0; z-index:9997 (por encima de header/grid/glow/contenido, igual que en Home — NO se
   reduce, el usuario pidió explícitamente el mismo z-index real); width/height:100vw/100vh
   (no 100%, evita la compresión ~1.04% del scrollbar, mismo motivo documentado en la fuente);
   pointer-events:none (el header y todo el contenido siguen siendo clickeables). El motor
   (home-v2-fluid.js, copiado byte a byte a public/js/home-v2-fluid.js, hash idéntico al
   origen) solo requiere #pf-fluid por id — sin más dependencias de markup/CSS. */
#pf-fluid {
  position: fixed; inset: 0; z-index: 9997;
  width: 100vw; height: 100vh;
  pointer-events: none;
}

/* ============ ETAPA 5 — STICKERS QUE CAEN, SOLO LOGIN (motor FINAL de Facturación) ============
   Contenedor/canvas EXACTOS de facturacion.html:63-64: #pfFooter (fuente real de showCnt) +
   canvas #pf-footer-decor dentro. .pf-footer-decor (el canvas): valores EXACTOS de
   home-v2.css:641 (position:absolute;inset:0;width/height:100%;display:block;pointer-events:
   none). .pf-footer-decor-wrap (el contenedor): mismo patrón real y ya aprobado de
   facturacion-v2.css:251-258 — oculto por defecto, y solo como overlay fijo de viewport
   completo (position:fixed;inset:0;pointer-events:none) mientras el body tiene la clase de
   login. Se reutiliza aquí el mismo scope ya usado para el fix del glow (body.av2-login) en
   vez de body.fe-auth-mode (clase que no existe en Academia) — mismo criterio de adaptación
   de scope ya aplicado en la Etapa 4, sin tocar el motor. */
.pf-footer-decor { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.pf-footer-decor-wrap { display: none; }
body.av2-login .pf-footer-decor-wrap {
  display: block;
  position: fixed;
  inset: 0;
  pointer-events: none;
}

/* ============ ETAPA 4 — PARTE C: #pf-glow EN LOGIN ============
   Auditoría: la posición inicial de #pf-glow (viewport-center, JS real de academy-v2.js —
   idéntico a home-v2.js/apis-v2.js/facturacion-v2.js Parte 2, sin cambios) solapa el
   contenido principal. Para LOGIN existe una referencia real EXACTA ya aprobada y en
   producción: facturacion-v2.css:228-233 (`body.fe-auth-mode { background:#fff; }
   body.fe-auth-mode #pf-glow { display:none; }`) — login de Facturación oculta el glow por
   completo y pasa a fondo blanco sólido, en vez de reposicionarlo. Se COPIA ese mismo
   comportamiento aquí, escopeado a una clase equivalente propia de Academia (body.av2-login,
   agregada en login-v2-preview.html) — sin inventar coordenadas. #pf-grid NO se toca (la
   misma referencia real tampoco lo hace: "#pf-grid y #pf-fluid NO se tocan, ninguno es
   celeste/azulado por sí mismo").
   Para LANDING (Parte C, hero con .av2-product-card vertical-centrada) NO existe una
   referencia real análoga en Home/Catálogo/APIs — ninguna de esas páginas tiene una card
   centrada verticalmente en el punto exacto donde nace el glow. Ver GLOW REQUIRES DESIGN
   DECISION en el reporte final: esta sub-parte NO se toca en esta etapa. */
body.av2-login {
  background: #fff;
}
body.av2-login #pf-glow {
  display: none;
}

/* ============ HEADER V2 — geometría idéntica a .pf-header/.pf-bar de home-v2.css:108-120,
   pero navegación adaptada a los links REALES de Academia (auditoría: NO existen enlaces a
   Catálogo/APIs/Facturación/Gratis en esta landing — solo "Conoce la Academia" (#experiencia)
   e "Ingresar" (/login), o en login: volver a michemicaldatalab.com). ============ */
.pf-header { position: fixed; top: 0; left: 0; right: 0; z-index: 50; pointer-events: none; }
.pf-bar {
  pointer-events: auto;
  margin: 12px 20px;
  padding: 18px 24px;
  border-radius: 16px;
  border: 1px solid rgba(10,14,20,.08);
  background: rgba(241,249,255,.68);
  backdrop-filter: blur(20px) saturate(1.7);
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  transition: background .4s, border-color .4s;
}
/* ============ ETAPA 4 — LOGO V2 REAL ============
   Auditoría local: el raster /assets/logo-md.png (471×171) se veía distinto/borroso frente
   al mark real de los módulos V2 (Home/Catálogo/APIs/Facturación), que NUNCA usan una imagen
   para el logo del header — usan el mark construido en HTML/CSS. Markup real confirmado
   leyendo public/index.html:76-78 del sitio principal:
     <a class="pf-brand" href="/"><span class="pf-mark">M|D</span>
       <span class="pf-brandname">MICHEMICALDATALAB</span></a>
   .pf-mark NUNCA existió en este archivo (vacío de la Etapa 2) — se agrega ahora con los
   valores EXACTOS de home-v2.css:122 (font-size 19px se deja SIN aproximar, tal cual la
   fuente real, no un valor recalculado para caber en el .pf-bar más compacto de Academia). */
.pf-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--av2-ink); }
.pf-mark { font-family: var(--av2-font-display); font-weight: 700; font-size: 19px; letter-spacing: -.02em; }
.pf-brandname { font-family: var(--av2-font-label); font-size: 11px; letter-spacing: .07em; text-transform: uppercase; opacity: .78; }
.pf-nav { display: flex; align-items: center; gap: 8px; list-style: none; margin: 0; padding: 0; }
.pf-nav a {
  position: relative;
  font-family: var(--av2-font-label); font-size: 14px; font-weight: 400; letter-spacing: 1.05px; text-transform: uppercase;
  color: var(--av2-ink); text-decoration: none; opacity: .96;
  -webkit-text-stroke: .6px currentColor;
  padding: 7px 14px; border-radius: 999px; transition: opacity .18s ease;
}
.pf-nav a:hover { opacity: 1; }
.pf-nav a::before {
  content: ""; position: absolute; inset: -0.15rem;
  border: 2px dotted transparent; border-radius: 2px;
  transition: border-color .2s; pointer-events: none;
}
.pf-nav a:hover::before { border-color: rgba(54,54,48,.32); }
.pf-actions { display: flex; align-items: center; gap: 12px; }
.pf-toggle { display: none; font-family: var(--av2-font-label); font-size: 18px; background: none; border: none; color: var(--av2-ink); cursor: pointer; }

/* ============ BOTÓN LIMA V2 — valores EXACTOS de facturacion-v2.css:64-72, sin adivinar. ============ */
.av2-btn {
  font-family: var(--av2-font-label); font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  min-height: 44px; padding: 0 20px; border-radius: 6px; border: 1px solid transparent;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  transition: background .2s ease, transform .15s ease, border-color .15s ease, color .15s ease;
}
.av2-btn:not(.secondary) { background: rgb(192, 254, 4); color: rgb(0, 0, 0); }
.av2-btn:not(.secondary):hover { background: rgb(170, 238, 0); transform: translateY(-1px); }
.av2-btn.secondary { background: transparent; color: var(--av2-ink); border-color: var(--av2-line); }
.av2-btn.secondary:hover { border-color: rgba(10,14,20,.28); transform: translateY(-1px); }
.av2-btn:focus-visible { outline: 2px solid rgb(192, 254, 4); outline-offset: 2px; }
.av2-btn.small { min-height: 38px; padding: 0 15px; font-size: 11px; }
.av2-btn.block { width: 100%; }

/* ============ SEGURIDAD 320px — mismo fix ya aprobado (apis-v2.css:288-290, catalogo-v2.css):
   a anchos muy pequeños se oculta el nombre de marca en texto, queda solo el logo.

   ETAPA 3B — botón "Ingresar" cortado a 320px (Landing): causa real confirmada leyendo este
   archivo — .pf-nav NUNCA colapsa (línea ~110: `display:flex` sin condición) y .pf-toggle
   NUNCA aparece (línea ~126: `display:none` sin condición), a diferencia del sistema real
   donde SÍ colapsan juntos por debajo de 1023px (home-v2.css:732-735: `.pf-nav{display:
   none} .pf-toggle{display:inline-flex}`). NO se copia el breakpoint 1023px literal: el nav
   real tiene 6 links y necesita colapsar mucho antes; el nav de Academia tiene un solo link
   corto ("Conoce la Academia") y la propia auditoría solo reportó el corte en 320px, no en
   768/1024/1440 (baseline que no debe cambiar) — se reutiliza el breakpoint YA EXISTENTE en
   este archivo (400px, mismo que ya oculta .pf-brandname) en vez de inventar uno nuevo.
   .av2-btn/.pf-toggle no tienen width explícito (auto), así que el reset de box-sizing de
   más arriba no libera espacio aquí — este colapso de nav es la corrección real y separada
   para este síntoma. Reducción de padding del bar en el mismo breakpoint: mismo principio
   que home-v2.css:733 (achicar el padding del header a la vez que se colapsa el nav), valor
   proporcional al padding base de este archivo (18px 24px, no el de home-v2.css), no una
   medida inventada al ojo. login-v2-preview.html no tiene #pfNav: esta regla no le afecta
   (0 cambio visual en su header, que la auditoría no reportó como roto). */
@media (max-width: 400px) {
  .pf-brandname { display: none; }
  .pf-nav { display: none; }
  .pf-toggle { display: inline-flex; }
  .pf-bar { padding: 14px 16px; }
}

/* ==========================================================================================
   LANDING — reconstrucción V2 del contenido REAL de public/index.html (3 secciones), mismo
   texto/orden/links/CTAs, sin inventar cursos/precios/videos/testimonios. La barra de
   progreso 72% (home-v2 real: academy.css:6 .home-product-progress span{width:72%}) se
   preserva como puramente decorativa, mismo valor exacto, sin conectar a backend.
   ========================================================================================== */
.av2-hero { position: relative; z-index: 5; padding: clamp(150px,18vw,190px) 20px clamp(56px,7vw,84px); }
.av2-hero-grid {
  display: grid; grid-template-columns: minmax(0,1.05fr) minmax(300px,.95fr);
  align-items: center; gap: clamp(28px,5vw,60px); max-width: 1320px; margin-inline: auto;
}
.av2-eyebrow {
  display: inline-flex; width: max-content; margin: 0 0 16px; padding: 7px 12px;
  border: 1px solid rgba(10,14,20,.14); border-radius: 999px; background: rgba(255,255,255,.7);
  font-family: var(--av2-font-label); font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--av2-ink);
}
.av2-hero-copy h1 {
  max-width: 720px; margin: 0; color: var(--av2-ink);
  font-family: var(--av2-font-display); font-weight: 700; font-size: clamp(2.4rem,5vw,4.2rem); line-height: .98; letter-spacing: -.03em;
}
/* ETAPA 4 — HERO TÍTULO COMPLETO EN NEGRO: el usuario quiere que "para aprender haciendo."
   herede el mismo negro que "Todo lo necesario" (el H1 padre, ya var(--av2-ink) real). Se
   neutraliza SOLO el color/stroke lima que este selector introducía — color:inherit toma el
   valor ya correcto del H1 sin hardcodear un segundo negro. DOM/tamaño/línea/posición del H1
   NO se tocan (ninguna otra propiedad de este selector cambia). */
.av2-hero-copy h1 strong { color: inherit; font: inherit; }
.av2-hero-copy > p:not(.av2-eyebrow) {
  max-width: 560px; margin: 20px 0 0; color: var(--av2-muted);
  font-family: var(--av2-font-mono); font-weight: 500; font-size: clamp(15px,1.3vw,17px); line-height: 1.6;
}
.av2-hero-actions { display: flex; gap: 12px; margin-top: 26px; flex-wrap: wrap; }

.av2-product-card {
  position: relative; padding: clamp(24px,3vw,32px); overflow: hidden;
  border: 1px solid rgba(255,255,255,.85); border-radius: 22px;
  background: rgba(255,255,255,.86); backdrop-filter: blur(16px) saturate(140%);
  box-shadow: 0 26px 72px rgba(10,14,20,.10);
}
.av2-product-brand { display: flex; align-items: center; gap: 12px; }
.av2-logo-box {
  flex: 0 0 48px; width: 48px; height: 48px; display: grid; place-items: center;
  border: 1px solid var(--av2-line); border-radius: 14px; background: #fff; overflow: hidden; padding: 4px;
}
.av2-logo-box img { width: 40px; height: 40px; object-fit: contain; }
.av2-product-brand small { display: block; color: var(--av2-muted); font-family: var(--av2-font-label); font-size: 10px; font-weight: 700; letter-spacing: .1em; }
.av2-product-brand strong { display: block; color: var(--av2-ink); font-family: var(--av2-font-display); font-weight: 700; font-size: 17px; }
.av2-product-card h2 { margin: 22px 0 8px; color: var(--av2-ink); font-family: var(--av2-font-display); font-weight: 700; font-size: clamp(24px,2.4vw,32px); line-height: 1.05; }
.av2-product-card > p { margin: 0; color: var(--av2-muted); font-family: var(--av2-font-mono); font-size: 14px; line-height: 1.6; }
.av2-progress { height: 8px; margin-top: 22px; overflow: hidden; border-radius: 99px; background: rgba(10,14,20,.08); }
.av2-progress span { display: block; width: 72%; height: 100%; border-radius: inherit; background: rgb(192,254,4); }
.av2-progress-points { display: flex; justify-content: space-between; gap: 8px; margin-top: 10px; color: var(--av2-muted); font-family: var(--av2-font-label); font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }

.av2-capabilities { position: relative; padding: 24px 20px 72px; }
.av2-capabilities::before { content:""; position:absolute; inset:0; z-index:0; background:#fbfaf4; pointer-events:none; }
.av2-capabilities-inner { position: relative; z-index: 4; max-width: 1320px; margin-inline: auto; }
.av2-section-head { max-width: 680px; margin-bottom: 24px; }
.av2-section-head h2 { margin: 7px 0 8px; color: var(--av2-ink); font-family: var(--av2-font-display); font-weight: 700; font-size: clamp(26px,3vw,38px); line-height: 1.08; letter-spacing: -.02em; }
.av2-section-head p { margin: 0; color: var(--av2-muted); font-family: var(--av2-font-mono); font-size: 14px; line-height: 1.6; }
.av2-feature-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 16px; }
.av2-feature-grid article {
  min-height: 216px; display: flex; flex-direction: column; align-items: flex-start; padding: 22px;
  border: 1px solid var(--av2-line); border-radius: 18px; background: rgba(255,255,255,.92);
  box-shadow: 0 16px 40px rgba(10,14,20,.06); transition: transform .2s ease, box-shadow .2s ease;
}
.av2-feature-grid article:hover { transform: translateY(-3px); box-shadow: 0 20px 48px rgba(10,14,20,.10); }
.av2-feature-icon { flex: 0 0 64px; width: 64px; height: 64px; display: grid; place-items: center; margin-bottom: 16px; border: 1px solid var(--av2-line); border-radius: 16px; background: rgba(47,128,237,.06); }
.av2-feature-icon img { width: 56px; height: 56px; object-fit: contain; }
.av2-feature-grid h3 { margin: 0 0 6px; color: var(--av2-ink); font-family: var(--av2-font-display); font-weight: 700; font-size: 18px; }
.av2-feature-grid p { margin: 0; color: var(--av2-muted); font-family: var(--av2-font-mono); font-size: 13px; line-height: 1.55; }

.av2-cta {
  max-width: 1320px; margin: 0 auto 64px; padding: 20px; padding-inline: clamp(20px, 4vw, 32px);
  display: flex; align-items: center; justify-content: space-between; gap: 22px; flex-wrap: wrap;
  border-radius: 22px; background: var(--av2-ink); color: #fff;
}
.av2-cta .av2-eyebrow { border-color: rgba(255,255,255,.25); background: rgba(255,255,255,.1); color: #fff; }
.av2-cta h2 { margin: 0 0 5px; font-family: var(--av2-font-display); font-weight: 700; font-size: clamp(22px,2.6vw,30px); }
.av2-cta p { margin: 0; opacity: .82; font-family: var(--av2-font-mono); font-size: 14px; }

.av2-footer { border-top: 1px solid var(--av2-line); background: rgba(255,255,255,.6); }
.av2-footer-inner {
  max-width: 1320px; margin-inline: auto; min-height: 68px; padding: 14px 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  color: var(--av2-muted); font-family: var(--av2-font-label); font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}

@media (max-width: 900px) {
  .av2-hero-grid { grid-template-columns: minmax(0, 1fr); }
  .av2-product-card { width: min(560px,100%); margin-inline: auto; }
  .av2-feature-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 640px) {
  .av2-hero { padding-top: clamp(128px,26vw,160px); }
  .av2-feature-grid { grid-template-columns: 1fr; }
  .av2-cta { flex-direction: column; align-items: flex-start; }
  .av2-cta .av2-btn { width: 100%; }
  .av2-footer-inner { flex-direction: column; text-align: center; justify-content: center; }
}

/* ==========================================================================================
   LOGIN — skin V2 del formulario REAL (src/views/login.html), mismos IDs/name/hooks exactos
   que consume public/js/login.js (sin tocarlo, sin duplicar su lógica). Reemplaza SOLO el
   canvas decorativo antiguo (login-background.js, #logo-bg) por el grid/glow V2 — ese script
   no es requerido por login.js (no comparte ningún hook) y se documenta su exclusión en el
   HTML del preview. El robot/burbuja de bienvenida (login-mascot.js, #academy-welcome-lottie)
   SÍ se conserva: es una función real, no decorativa nueva.
   ========================================================================================== */
.av2-login-stage { position: relative; z-index: 2; min-height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; padding: clamp(120px,16vw,150px) 20px 60px; }
/* ============ ETAPA 4 — PARTE E: CARD DEL LOGIN, VALORES REALES DE FACTURACIÓN ============
   "COPIAR ESTILO, NO FUNCIONALIDAD" — IDs/hooks/login.js sin tocar (ver abajo). Valores
   leídos en el CÓDIGO REAL de Facturación, no aproximados:
   - Card base: styles.css:2783 (.fe-auth-card, width:min(500px,100%)) sin cambios de V2.
   - Card V2: facturacion-v2.css:184-189 (body.fe-auth-mode .fe-auth-card) — fondo blanco
     sólido, borde var(--line), radius 18px, sin sombra. El backdrop-filter/box-shadow del
     panel radial de styles.css:2791-2792 NO se anulan explícitamente en la fuente real, pero
     quedan sin efecto visible detrás de un fondo ya opaco — se omiten aquí por la misma
     razón (fondo opaco), no se inventa nada nuevo.
   - Form padding: styles.css:2803 (.fe-login-form--compact, clamp(24px,4vw,32px)).
   - Título: facturacion-v2.css:117-124 (body.fe-auth-mode .fe-login-brand h2) — 25.6px/800/
     line-height normal/letter-spacing -.64px/font-display. */
.av2-login-card {
  position: relative; isolation: isolate; width: min(500px,100%); margin: auto;
  border: 1px solid var(--av2-line); border-radius: 18px;
  background: #fff;
  box-shadow: none;
}
.av2-login-card form { position: relative; z-index: 4; display: grid; gap: 14px; padding: clamp(24px,4vw,32px); }
.av2-login-title { text-align: center; margin-bottom: 2px; }
.av2-login-title .av2-eyebrow { justify-content: center; margin: 0 auto 10px; }
.av2-login-title h1 { margin: 0; color: var(--av2-ink); font-family: var(--av2-font-display); font-weight: 800; font-size: 25.6px; line-height: normal; letter-spacing: -.64px; }
.av2-login-title > p:last-child { margin: 8px 0 0; color: var(--av2-muted); font-family: var(--av2-font-mono); font-size: 13px; }
/* facturacion-v2.css:129-136 (.form-label span): weight 400 (no 700), letter-spacing .1em
   (no .05em), color var(--muted) (no --ink). Se aplica al label completo (mismo criterio ya
   usado antes en este archivo), el input conserva sus propias reglas de fuente más abajo. */
.av2-form-label { display: grid; gap: 7px; color: var(--av2-muted); font-family: var(--av2-font-label); font-size: 11px; font-weight: 400; letter-spacing: .1em; text-transform: uppercase; }
/* facturacion-v2.css:142-154 (.form-control / .form-control:focus) + styles.css:2836
   (min-height:58px, base sin cambio de V2): font-mono/weight 500, fondo rgba(255,255,255,.7)
   → focus rgba(255,255,255,.9), borde var(--line) → focus lima, radius 10px (no 12px). */
.av2-form-label > input,
.av2-form-label .av2-password-field > input {
  min-height: 58px; min-width: 0; border: 1px solid var(--av2-line); border-radius: 10px;
  background: rgba(255,255,255,.7); color: var(--av2-ink); padding: 0 16px;
  font-family: var(--av2-font-mono); font-weight: 500; font-size: 14px; outline: none;
  box-shadow: none;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.av2-form-label .av2-password-field > input { padding-right: 52px; }
.av2-form-label input:focus { background: rgba(255,255,255,.9); border-color: rgb(192,254,4); box-shadow: 0 0 0 3px rgba(192,254,4,.35); }
.av2-password-field { position: relative; display: block; }
.av2-password-toggle {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 0; border-radius: 10px; background: transparent; color: var(--av2-muted); cursor: pointer;
}
.av2-password-toggle:hover { background: rgba(10,14,20,.06); color: var(--av2-ink); }
.av2-password-toggle svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; }
/* facturacion-v2.css:169-179 (.fe-login-remember / span): fondo rgba(255,255,255,.5), borde
   var(--line), radius 10px (no 12px); span: mono/13px/color var(--ink) (no weight 600). */
.av2-login-remember {
  min-height: 46px; display: flex; align-items: center; gap: 10px; padding: 0 14px;
  border: 1px solid var(--av2-line); border-radius: 10px; background: rgba(255,255,255,.5);
  box-shadow: none;
  font-family: var(--av2-font-mono); font-size: 13px; color: var(--av2-ink); cursor: pointer;
}
.av2-login-remember input { width: 17px; height: 17px; accent-color: rgb(192,254,4); }
.av2-login-card .av2-btn.auth-submit { width: 100%; min-height: 48px; }
.av2-form-message { min-height: 20px; margin: 0; color: #b42318; font-family: var(--av2-font-mono); font-size: 12px; font-weight: 700; }
.av2-form-message:empty { display: none; }

.av2-welcome-character { position: absolute; right: -220px; top: 50%; z-index: 3; width: 210px; pointer-events: none; transform: translateY(-50%); }
.av2-welcome-lottie, .av2-welcome-character img { display: block; width: 210px; height: auto; filter: drop-shadow(0 22px 34px rgba(10,14,20,.15)); }
.av2-welcome-lottie:empty { display: none; }
.av2-welcome-fallback[hidden] { display: none; }
/* facturacion-v2.css:194-199 (.fe-welcome-bubble): mono/weight 500/color var(--ink)/borde
   var(--line)/sin sombra — SIN tocar texto/tamaño/posición (misma regla que la fuente real
   respeta: "auditoría no midió una reposición justificada"). */
.av2-welcome-bubble {
  position: absolute; left: 150px; top: 6px; width: 152px; padding: 10px 12px;
  border: 1px solid var(--av2-line); border-radius: 18px 18px 18px 6px; background: #fff;
  box-shadow: none; color: var(--av2-ink);
  font-family: var(--av2-font-mono); font-size: 12px; font-weight: 500;
}
@media (max-width: 1180px) {
  .av2-welcome-character { right: -170px; width: 170px; }
  .av2-welcome-lottie, .av2-welcome-character img { width: 170px; }
  .av2-welcome-bubble { display: none; }
}
@media (max-width: 960px) { .av2-welcome-character { display: none; } }
@media (max-width: 430px) {
  .av2-login-stage { padding-top: 118px; }
  .av2-login-card { border-radius: 18px; }
}
